Unverified Commit 37eec862 authored by Danny Tuppeny's avatar Danny Tuppeny Committed by GitHub

Allow web server device to use extension if started with --start-paused (#44263)

* Allow web server device to use extension if started with --start-paused

* Fix comment

* Remove browser-launch option that allowed using Chrome without launching Chrome

The web-server device should now be used if you don't want to launch a browser.

* Add tests for WebServerDevice with --start-paused

* Fixes from rebase

* More fixes from rebase

* Fix from rebase

* Fix condition for page refresh in non-debug builds

* Make dwds conditions match with a new getter

* Add missing .device
parent 92e9f5f1
...@@ -96,12 +96,15 @@ abstract class ResidentWebRunner extends ResidentRunner { ...@@ -96,12 +96,15 @@ abstract class ResidentWebRunner extends ResidentRunner {
// Only the debug builds of the web support the service protocol. // Only the debug builds of the web support the service protocol.
@override @override
bool get supportsServiceProtocol => bool get supportsServiceProtocol => isRunningDebug && deviceIsDebuggable;
isRunningDebug && device.device is! WebServerDevice;
@override @override
bool get debuggingEnabled => bool get debuggingEnabled => isRunningDebug && deviceIsDebuggable;
isRunningDebug && device.device is! WebServerDevice;
/// WebServer device is debuggable when running with --start-paused.
bool get deviceIsDebuggable => device.device is! WebServerDevice || debuggingOptions.startPaused;
bool get _enableDwds => debuggingEnabled;
WebFs _webFs; WebFs _webFs;
ConnectionResult _connectionResult; ConnectionResult _connectionResult;
...@@ -602,14 +605,14 @@ class _DwdsResidentWebRunner extends ResidentWebRunner { ...@@ -602,14 +605,14 @@ class _DwdsResidentWebRunner extends ResidentWebRunner {
initializePlatform: debuggingOptions.initializePlatform, initializePlatform: debuggingOptions.initializePlatform,
hostname: debuggingOptions.hostname, hostname: debuggingOptions.hostname,
port: debuggingOptions.port, port: debuggingOptions.port,
skipDwds: device.device is WebServerDevice || !debuggingOptions.buildInfo.isDebug, skipDwds: !_enableDwds,
dartDefines: dartDefines, dartDefines: dartDefines,
); );
// When connecting to a browser, update the message with a seemsSlow notification // When connecting to a browser, update the message with a seemsSlow notification
// to handle the case where we fail to connect. // to handle the case where we fail to connect.
buildStatus.stop(); buildStatus.stop();
statusActive = false; statusActive = false;
if (debuggingOptions.browserLaunch && supportsServiceProtocol) { if (supportsServiceProtocol) {
buildStatus = logger.startProgress( buildStatus = logger.startProgress(
'Attempting to connect to browser instance..', 'Attempting to connect to browser instance..',
timeout: const Duration(seconds: 30), timeout: const Duration(seconds: 30),
...@@ -624,8 +627,9 @@ class _DwdsResidentWebRunner extends ResidentWebRunner { ...@@ -624,8 +627,9 @@ class _DwdsResidentWebRunner extends ResidentWebRunner {
'uri': _webFs.uri, 'uri': _webFs.uri,
}, },
); );
if (supportsServiceProtocol) { if (_enableDwds) {
_connectionResult = await _webFs.connect(debuggingOptions); final bool useDebugExtension = device.device is WebServerDevice && debuggingOptions.startPaused;
_connectionResult = await _webFs.connect(useDebugExtension);
unawaited(_connectionResult.debugConnection.onDone.whenComplete(_cleanupAndExit)); unawaited(_connectionResult.debugConnection.onDone.whenComplete(_cleanupAndExit));
} }
if (statusActive) { if (statusActive) {
...@@ -741,7 +745,7 @@ class _DwdsResidentWebRunner extends ResidentWebRunner { ...@@ -741,7 +745,7 @@ class _DwdsResidentWebRunner extends ResidentWebRunner {
} }
} }
// Allows browser refresh hot restart on non-debug builds. // Allows browser refresh hot restart on non-debug builds.
if (device is ChromeDevice && debuggingOptions.browserLaunch) { if (device.device is ChromeDevice && !isRunningDebug) {
try { try {
final Chrome chrome = await ChromeLauncher.connectedInstance; final Chrome chrome = await ChromeLauncher.connectedInstance;
final ChromeTab chromeTab = await chrome.chromeConnection.getTab((ChromeTab chromeTab) { final ChromeTab chromeTab = await chrome.chromeConnection.getTab((ChromeTab chromeTab) {
......
...@@ -33,7 +33,6 @@ import '../bundle.dart'; ...@@ -33,7 +33,6 @@ import '../bundle.dart';
import '../cache.dart'; import '../cache.dart';
import '../dart/package_map.dart'; import '../dart/package_map.dart';
import '../dart/pub.dart'; import '../dart/pub.dart';
import '../device.dart';
import '../globals.dart'; import '../globals.dart';
import '../platform_plugins.dart'; import '../platform_plugins.dart';
import '../plugins.dart'; import '../plugins.dart';
...@@ -131,12 +130,12 @@ class WebFs { ...@@ -131,12 +130,12 @@ class WebFs {
/// Connect and retrieve the [DebugConnection] for the current application. /// Connect and retrieve the [DebugConnection] for the current application.
/// ///
/// Only calls [AppConnection.runMain] on the subsequent connections. /// Only calls [AppConnection.runMain] on the subsequent connections.
Future<ConnectionResult> connect(DebuggingOptions debuggingOptions) { Future<ConnectionResult> connect(bool useDebugExtension) {
final Completer<ConnectionResult> firstConnection = Completer<ConnectionResult>(); final Completer<ConnectionResult> firstConnection = Completer<ConnectionResult>();
_connectedApps = _dwds.connectedApps.listen((AppConnection appConnection) async { _connectedApps = _dwds.connectedApps.listen((AppConnection appConnection) async {
final DebugConnection debugConnection = debuggingOptions.browserLaunch final DebugConnection debugConnection = useDebugExtension
? await _dwds.debugConnection(appConnection) ? await (_cachedExtensionFuture ??= _dwds.extensionDebugConnections.stream.first)
: await (_cachedExtensionFuture ??= _dwds.extensionDebugConnections.stream.first); : await _dwds.debugConnection(appConnection);
if (!firstConnection.isCompleted) { if (!firstConnection.isCompleted) {
firstConnection.complete(ConnectionResult(appConnection, debugConnection)); firstConnection.complete(ConnectionResult(appConnection, debugConnection));
} else { } else {
......
...@@ -321,7 +321,6 @@ class RunCommand extends RunCommandBase { ...@@ -321,7 +321,6 @@ class RunCommand extends RunCommandBase {
initializePlatform: boolArg('web-initialize-platform'), initializePlatform: boolArg('web-initialize-platform'),
hostname: featureFlags.isWebEnabled ? stringArg('web-hostname') : '', hostname: featureFlags.isWebEnabled ? stringArg('web-hostname') : '',
port: featureFlags.isWebEnabled ? stringArg('web-port') : '', port: featureFlags.isWebEnabled ? stringArg('web-port') : '',
browserLaunch: featureFlags.isWebEnabled ? boolArg('web-browser-launch') : null,
vmserviceOutFile: stringArg('vmservice-out-file'), vmserviceOutFile: stringArg('vmservice-out-file'),
); );
} }
......
...@@ -506,7 +506,6 @@ class DebuggingOptions { ...@@ -506,7 +506,6 @@ class DebuggingOptions {
this.initializePlatform = true, this.initializePlatform = true,
this.hostname, this.hostname,
this.port, this.port,
this.browserLaunch = true,
this.vmserviceOutFile, this.vmserviceOutFile,
}) : debuggingEnabled = true; }) : debuggingEnabled = true;
...@@ -524,7 +523,6 @@ class DebuggingOptions { ...@@ -524,7 +523,6 @@ class DebuggingOptions {
verboseSystemLogs = false, verboseSystemLogs = false,
hostVmServicePort = null, hostVmServicePort = null,
deviceVmServicePort = null, deviceVmServicePort = null,
browserLaunch = true,
vmserviceOutFile = null; vmserviceOutFile = null;
final bool debuggingEnabled; final bool debuggingEnabled;
...@@ -547,7 +545,6 @@ class DebuggingOptions { ...@@ -547,7 +545,6 @@ class DebuggingOptions {
final int deviceVmServicePort; final int deviceVmServicePort;
final String port; final String port;
final String hostname; final String hostname;
final bool browserLaunch;
/// A file where the vmservice uri should be written after the application is started. /// A file where the vmservice uri should be written after the application is started.
final String vmserviceOutFile; final String vmserviceOutFile;
......
...@@ -150,14 +150,6 @@ abstract class FlutterCommand extends Command<void> { ...@@ -150,14 +150,6 @@ abstract class FlutterCommand extends Command<void> {
'will select a random open port on the host.', 'will select a random open port on the host.',
hide: hide, hide: hide,
); );
argParser.addFlag('web-browser-launch',
defaultsTo: true,
negatable: true,
help: 'Whether to automatically launch browsers for web devices '
'that do so. Setting this to true allows using the Dart debug extension '
'on Chrome and other browsers which support extensions.',
hide: hide,
);
} }
void usesTargetOption() { void usesTargetOption() {
......
...@@ -134,16 +134,13 @@ class ChromeDevice extends Device { ...@@ -134,16 +134,13 @@ class ChromeDevice extends Device {
// See [ResidentWebRunner.run] in flutter_tools/lib/src/resident_web_runner.dart // See [ResidentWebRunner.run] in flutter_tools/lib/src/resident_web_runner.dart
// for the web initialization and server logic. // for the web initialization and server logic.
final String url = platformArgs['uri'] as String; final String url = platformArgs['uri'] as String;
if (debuggingOptions.browserLaunch) { _chrome = await chromeLauncher.launch(url,
_chrome = await chromeLauncher.launch(url, dataDir: fs.currentDirectory
dataDir: fs.currentDirectory .childDirectory('.dart_tool')
.childDirectory('.dart_tool') .childDirectory('chrome-device'));
.childDirectory('chrome-device'));
logger.sendEvent('app.webLaunchUrl', <String, dynamic>{'url': url, 'launched': true}); logger.sendEvent('app.webLaunchUrl', <String, dynamic>{'url': url, 'launched': true});
} else {
printStatus('Waiting for connection from Dart debug extension at $url', emphasis: true);
logger.sendEvent('app.webLaunchUrl', <String, dynamic>{'url': url, 'launched': false});
}
return LaunchResult.succeeded(observatoryUri: null); return LaunchResult.succeeded(observatoryUri: null);
} }
...@@ -253,7 +250,11 @@ class WebServerDevice extends Device { ...@@ -253,7 +250,11 @@ class WebServerDevice extends Device {
bool ipv6 = false, bool ipv6 = false,
}) async { }) async {
final String url = platformArgs['uri'] as String; final String url = platformArgs['uri'] as String;
printStatus('$mainPath is being served at $url', emphasis: true); if (debuggingOptions.startPaused) {
printStatus('Waiting for connection from Dart debug extension at $url', emphasis: true);
} else {
printStatus('$mainPath is being served at $url', emphasis: true);
}
logger.sendEvent('app.webLaunchUrl', <String, dynamic>{'url': url, 'launched': false}); logger.sendEvent('app.webLaunchUrl', <String, dynamic>{'url': url, 'launched': false});
return LaunchResult.succeeded(observatoryUri: null); return LaunchResult.succeeded(observatoryUri: null);
} }
......
...@@ -130,7 +130,7 @@ void main() { ...@@ -130,7 +130,7 @@ void main() {
when(mockWipConnection.debugger).thenReturn(mockWipDebugger); when(mockWipConnection.debugger).thenReturn(mockWipDebugger);
} }
test('runner with web server device does not support debugging', () => testbed.run(() async { test('runner with web server device does not support debugging without --start-paused', () => testbed.run(() {
when(mockFlutterDevice.device).thenReturn(WebServerDevice()); when(mockFlutterDevice.device).thenReturn(WebServerDevice());
final ResidentRunner profileResidentWebRunner = DwdsWebRunnerFactory().createWebRunner( final ResidentRunner profileResidentWebRunner = DwdsWebRunnerFactory().createWebRunner(
mockFlutterDevice, mockFlutterDevice,
...@@ -144,7 +144,6 @@ void main() { ...@@ -144,7 +144,6 @@ void main() {
expect(profileResidentWebRunner.debuggingEnabled, false); expect(profileResidentWebRunner.debuggingEnabled, false);
when(mockFlutterDevice.device).thenReturn(MockChromeDevice()); when(mockFlutterDevice.device).thenReturn(MockChromeDevice());
expect(residentWebRunner.debuggingEnabled, true); expect(residentWebRunner.debuggingEnabled, true);
})); }));
...@@ -161,6 +160,45 @@ void main() { ...@@ -161,6 +160,45 @@ void main() {
expect(didSkipDwds, true); expect(didSkipDwds, true);
})); }));
test('runner with web server device supports debugging with --start-paused', () => testbed.run(() {
when(mockFlutterDevice.device).thenReturn(WebServerDevice());
final ResidentRunner profileResidentWebRunner = DwdsWebRunnerFactory().createWebRunner(
mockFlutterDevice,
flutterProject: FlutterProject.current(),
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, startPaused: true),
ipv6: true,
stayResident: true,
dartDefines: <String>[],
);
expect(profileResidentWebRunner.debuggingEnabled, true);
}));
test('runner with web server device uses debug extension with --start-paused', () => testbed.run(() async {
_setupMocks();
when(mockFlutterDevice.device).thenReturn(WebServerDevice());
final BufferLogger bufferLogger = logger;
final ResidentWebRunner runner = DwdsWebRunnerFactory().createWebRunner(
mockFlutterDevice,
flutterProject: FlutterProject.current(),
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, startPaused: true),
ipv6: true,
stayResident: true,
dartDefines: <String>[],
);
final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
unawaited(runner.run(
connectionInfoCompleter: connectionInfoCompleter,
));
await connectionInfoCompleter.future;
// Check connect() was told to use the debug extension.
verify(mockWebFs.connect(true)).called(1);
// And ensure the debug services was started.
expect(bufferLogger.statusText, contains('Debug service listening on'));
}));
test('profile does not supportsServiceProtocol', () => testbed.run(() { test('profile does not supportsServiceProtocol', () => testbed.run(() {
when(mockFlutterDevice.device).thenReturn(mockChromeDevice); when(mockFlutterDevice.device).thenReturn(mockChromeDevice);
......
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