Unverified Commit fef9d4d7 authored by Zachary Anderson's avatar Zachary Anderson Committed by GitHub

[flutter_tools] Launch DevTools with 'v' (#53902)

parent caeaac77
...@@ -140,6 +140,12 @@ class CommandHelp { ...@@ -140,6 +140,12 @@ class CommandHelp {
'debugDumpRenderTree', 'debugDumpRenderTree',
); );
CommandHelpOption _v;
CommandHelpOption get v => _v ??= _makeOption(
'v',
'Launch DevTools.',
);
CommandHelpOption _w; CommandHelpOption _w;
CommandHelpOption get w => _w ??= _makeOption( CommandHelpOption get w => _w ??= _makeOption(
'w', 'w',
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'dart:async'; import 'dart:async';
import 'package:devtools_server/devtools_server.dart' as devtools_server;
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'application_package.dart'; import 'application_package.dart';
...@@ -650,6 +651,8 @@ abstract class ResidentRunner { ...@@ -650,6 +651,8 @@ abstract class ResidentRunner {
final CommandHelp commandHelp; final CommandHelp commandHelp;
io.HttpServer _devtoolsServer;
bool _exited = false; bool _exited = false;
Completer<int> _finished = Completer<int>(); Completer<int> _finished = Completer<int>();
bool hotMode; bool hotMode;
...@@ -769,12 +772,14 @@ abstract class ResidentRunner { ...@@ -769,12 +772,14 @@ abstract class ResidentRunner {
Future<void> exit() async { Future<void> exit() async {
_exited = true; _exited = true;
await shutdownDevtools();
await stopEchoingDeviceLog(); await stopEchoingDeviceLog();
await preExit(); await preExit();
await exitApp(); await exitApp();
} }
Future<void> detach() async { Future<void> detach() async {
await shutdownDevtools();
await stopEchoingDeviceLog(); await stopEchoingDeviceLog();
await preExit(); await preExit();
appFinished(); appFinished();
...@@ -982,6 +987,31 @@ abstract class ResidentRunner { ...@@ -982,6 +987,31 @@ abstract class ResidentRunner {
} }
} }
Future<void> launchDevTools() async {
try {
assert(supportsServiceProtocol);
_devtoolsServer ??= await devtools_server.serveDevTools(
enableStdinCommands: false,
);
await devtools_server.launchDevTools(
<String, dynamic>{
'reuseWindows': true,
},
flutterDevices.first.vmService.httpAddress,
'http://${_devtoolsServer.address.host}:${_devtoolsServer.port}',
false, // headless mode,
false, // machine mode
);
} on Exception catch (e, st) {
globals.printTrace('Failed to launch DevTools: $e\n$st');
}
}
Future<void> shutdownDevtools() async {
await _devtoolsServer?.close();
_devtoolsServer = null;
}
Future<void> _serviceProtocolDone(dynamic object) async { Future<void> _serviceProtocolDone(dynamic object) async {
globals.printTrace('Service protocol connection closed.'); globals.printTrace('Service protocol connection closed.');
} }
...@@ -1064,6 +1094,7 @@ abstract class ResidentRunner { ...@@ -1064,6 +1094,7 @@ abstract class ResidentRunner {
if (supportsCanvasKit){ if (supportsCanvasKit){
commandHelp.k.print(); commandHelp.k.print();
} }
commandHelp.v.print();
// `P` should precede `a` // `P` should precede `a`
commandHelp.P.print(); commandHelp.P.print();
commandHelp.a.print(); commandHelp.a.print();
...@@ -1299,6 +1330,12 @@ class TerminalHandler { ...@@ -1299,6 +1330,12 @@ class TerminalHandler {
return true; return true;
} }
return false; return false;
case 'v':
if (residentRunner.supportsServiceProtocol) {
await residentRunner.launchDevTools();
return true;
}
return false;
case 'w': case 'w':
case 'W': case 'W':
if (residentRunner.supportsServiceProtocol) { if (residentRunner.supportsServiceProtocol) {
......
...@@ -66,6 +66,7 @@ void _testMessageLength({ ...@@ -66,6 +66,7 @@ void _testMessageLength({
expect(commandHelp.r.toString().length, lessThanOrEqualTo(expectedWidth)); expect(commandHelp.r.toString().length, lessThanOrEqualTo(expectedWidth));
expect(commandHelp.s.toString().length, lessThanOrEqualTo(expectedWidth)); expect(commandHelp.s.toString().length, lessThanOrEqualTo(expectedWidth));
expect(commandHelp.t.toString().length, lessThanOrEqualTo(expectedWidth)); expect(commandHelp.t.toString().length, lessThanOrEqualTo(expectedWidth));
expect(commandHelp.v.toString().length, lessThanOrEqualTo(expectedWidth));
expect(commandHelp.w.toString().length, lessThanOrEqualTo(expectedWidth)); expect(commandHelp.w.toString().length, lessThanOrEqualTo(expectedWidth));
expect(commandHelp.z.toString().length, lessThanOrEqualTo(expectedWidth)); expect(commandHelp.z.toString().length, lessThanOrEqualTo(expectedWidth));
} }
...@@ -95,6 +96,7 @@ void main() { ...@@ -95,6 +96,7 @@ void main() {
expect(commandHelp.r.toString(), startsWith('\x1B[1mr\x1B[22m')); expect(commandHelp.r.toString(), startsWith('\x1B[1mr\x1B[22m'));
expect(commandHelp.s.toString(), startsWith('\x1B[1ms\x1B[22m')); expect(commandHelp.s.toString(), startsWith('\x1B[1ms\x1B[22m'));
expect(commandHelp.t.toString(), startsWith('\x1B[1mt\x1B[22m')); expect(commandHelp.t.toString(), startsWith('\x1B[1mt\x1B[22m'));
expect(commandHelp.v.toString(), startsWith('\x1B[1mv\x1B[22m'));
expect(commandHelp.w.toString(), startsWith('\x1B[1mw\x1B[22m')); expect(commandHelp.w.toString(), startsWith('\x1B[1mw\x1B[22m'));
expect(commandHelp.z.toString(), startsWith('\x1B[1mz\x1B[22m')); expect(commandHelp.z.toString(), startsWith('\x1B[1mz\x1B[22m'));
}); });
...@@ -170,6 +172,7 @@ void main() { ...@@ -170,6 +172,7 @@ void main() {
expect(commandHelp.r.toString(), equals('\x1B[1mr\x1B[22m Hot reload. $fire$fire$fire')); expect(commandHelp.r.toString(), equals('\x1B[1mr\x1B[22m Hot reload. $fire$fire$fire'));
expect(commandHelp.s.toString(), equals('\x1B[1ms\x1B[22m Save a screenshot to flutter.png.')); expect(commandHelp.s.toString(), equals('\x1B[1ms\x1B[22m Save a screenshot to flutter.png.'));
expect(commandHelp.t.toString(), equals('\x1B[1mt\x1B[22m Dump rendering tree to the console. \x1B[1;30m(debugDumpRenderTree)\x1B[39m')); expect(commandHelp.t.toString(), equals('\x1B[1mt\x1B[22m Dump rendering tree to the console. \x1B[1;30m(debugDumpRenderTree)\x1B[39m'));
expect(commandHelp.v.toString(), equals('\x1B[1mv\x1B[22m Launch DevTools.'));
expect(commandHelp.w.toString(), equals('\x1B[1mw\x1B[22m Dump widget hierarchy to the console. \x1B[1;30m(debugDumpApp)\x1B[39m')); expect(commandHelp.w.toString(), equals('\x1B[1mw\x1B[22m Dump widget hierarchy to the console. \x1B[1;30m(debugDumpApp)\x1B[39m'));
expect(commandHelp.z.toString(), equals('\x1B[1mz\x1B[22m Toggle elevation checker.')); expect(commandHelp.z.toString(), equals('\x1B[1mz\x1B[22m Toggle elevation checker.'));
}); });
...@@ -195,6 +198,7 @@ void main() { ...@@ -195,6 +198,7 @@ void main() {
expect(commandHelp.r.toString(), equals('r Hot reload. $fire$fire$fire')); expect(commandHelp.r.toString(), equals('r Hot reload. $fire$fire$fire'));
expect(commandHelp.s.toString(), equals('s Save a screenshot to flutter.png.')); expect(commandHelp.s.toString(), equals('s Save a screenshot to flutter.png.'));
expect(commandHelp.t.toString(), equals('t Dump rendering tree to the console. (debugDumpRenderTree)')); expect(commandHelp.t.toString(), equals('t Dump rendering tree to the console. (debugDumpRenderTree)'));
expect(commandHelp.v.toString(), equals('v Launch DevTools.'));
expect(commandHelp.w.toString(), equals('w Dump widget hierarchy to the console. (debugDumpApp)')); expect(commandHelp.w.toString(), equals('w Dump widget hierarchy to the console. (debugDumpApp)'));
expect(commandHelp.z.toString(), equals('z Toggle elevation checker.')); expect(commandHelp.z.toString(), equals('z Toggle elevation checker.'));
}); });
......
...@@ -406,6 +406,7 @@ void main() { ...@@ -406,6 +406,7 @@ void main() {
commandHelp.p, commandHelp.p,
commandHelp.o, commandHelp.o,
commandHelp.z, commandHelp.z,
commandHelp.v,
commandHelp.P, commandHelp.P,
commandHelp.a, commandHelp.a,
'An Observatory debugger and profiler on null is available at: null', 'An Observatory debugger and profiler on null is available at: null',
......
...@@ -364,6 +364,13 @@ void main() { ...@@ -364,6 +364,13 @@ void main() {
verifyNever(mockResidentRunner.debugDumpSemanticsTreeInInverseHitTestOrder()); verifyNever(mockResidentRunner.debugDumpSemanticsTreeInInverseHitTestOrder());
}); });
testUsingContext('v - launchDevTools', () async {
when(mockResidentRunner.supportsServiceProtocol).thenReturn(true);
await terminalHandler.processTerminalInput('v');
verify(mockResidentRunner.launchDevTools()).called(1);
});
testUsingContext('w,W - debugDumpApp with service protocol', () async { testUsingContext('w,W - debugDumpApp with service protocol', () async {
await terminalHandler.processTerminalInput('w'); await terminalHandler.processTerminalInput('w');
await terminalHandler.processTerminalInput('W'); await terminalHandler.processTerminalInput('W');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment