From 7cdc23b3e1bae2bc7bc2d1f34773eaa3629d4fcc Mon Sep 17 00:00:00 2001 From: "auto-submit[bot]" <98614782+auto-submit[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 19:55:18 +0000 Subject: [PATCH] Reverts "Launch DDS from Dart SDK and prepare to serve DevTools from DDS (#146593)" (#151781) Reverts: flutter/flutter#146593 Initiated by: zanderso Reason for reverting: Consistently failing `Windows_android native_assets_android` as in https://ci.chromium.org/ui/p/flutter/builders/prod/Windows_android%20native_assets_android/2533/overview Original PR Author: bkonyi Reviewed By: {christopherfujino, kenzieschmoll} This change reverts the following previous change: This change is a major step towards moving away from shipping DDS via Pub. The first component of this PR is the move away from importing package:dds to launch DDS. Instead, DDS is launched out of process using the `dart development-service` command shipped with the Dart SDK. This makes Flutter's handling of DDS consistent with the standalone Dart VM. The second component of this PR is the initial work to prepare for the removal of instances of DevTools being served manually by the flutter_tool, instead relying on DDS to serve DevTools. This will be consistent with how the standalone Dart VM serves DevTools, tying the DevTools lifecycle to a live DDS instance. This will allow for the removal of much of the logic needed to properly manage the lifecycle of the DevTools server in a future PR. Also, by serving DevTools from DDS, users will no longer need to forward a secondary port in remote workflows as DevTools will be available on the DDS port. There's two remaining circumstances that will prevent us from removing DevtoolsRunner completely: - The daemon's `devtools.serve` endpoint - `flutter drive`'s `--profile-memory` flag used for recording memory profiles This PR also includes some refactoring around `DebuggingOptions` to reduce the number of debugging related arguments being passed as parameters adjacent to a `DebuggingOptions` instance. --- .../lib/src/android/android_device.dart | 2 +- packages/flutter_tools/lib/src/base/dds.dart | 363 ++++-------------- .../lib/src/commands/attach.dart | 9 +- .../lib/src/commands/daemon.dart | 41 +- .../flutter_tools/lib/src/commands/drive.dart | 2 + .../flutter_tools/lib/src/commands/run.dart | 9 +- .../flutter_tools/lib/src/commands/test.dart | 3 +- .../lib/src/custom_devices/custom_device.dart | 6 +- .../flutter_tools/lib/src/desktop_device.dart | 5 +- packages/flutter_tools/lib/src/device.dart | 33 +- .../lib/src/drive/drive_service.dart | 20 +- .../lib/src/drive/web_driver_service.dart | 6 +- .../lib/src/fuchsia/fuchsia_device.dart | 10 +- .../flutter_tools/lib/src/ios/devices.dart | 15 +- .../flutter_tools/lib/src/ios/simulators.dart | 5 +- .../lib/src/isolated/resident_web_runner.dart | 31 +- .../lib/src/macos/macos_ipad_device.dart | 1 + .../flutter_tools/lib/src/preview_device.dart | 5 +- .../lib/src/proxied_devices/devices.dart | 94 ++--- .../lib/src/resident_devtools_handler.dart | 42 +- .../lib/src/resident_runner.dart | 95 ++--- packages/flutter_tools/lib/src/run_cold.dart | 44 ++- packages/flutter_tools/lib/src/run_hot.dart | 11 +- .../lib/src/runner/flutter_command.dart | 2 +- .../src/runner/flutter_command_runner.dart | 1 - .../lib/src/test/flutter_platform.dart | 8 + .../lib/src/test/flutter_tester_device.dart | 52 ++- .../flutter_tools/lib/src/test/runner.dart | 4 +- .../lib/src/tester/flutter_tester.dart | 5 +- .../flutter_tools/lib/src/web/web_device.dart | 6 +- .../flutter_tools/lib/src/web/web_runner.dart | 1 + .../commands.shard/hermetic/attach_test.dart | 16 +- .../commands.shard/hermetic/daemon_test.dart | 27 +- .../commands.shard/hermetic/drive_test.dart | 4 +- .../commands.shard/hermetic/run_test.dart | 7 +- .../test/general.shard/cold_test.dart | 8 +- .../test/general.shard/device_test.dart | 2 +- .../general.shard/devtools_launcher_test.dart | 7 - .../drive/drive_service_test.dart | 32 +- .../drive/web_driver_service_test.dart | 8 +- .../general.shard/flutter_platform_test.dart | 2 + .../flutter_tester_device_test.dart | 67 +++- .../fuchsia/fuchsia_device_start_test.dart | 12 +- .../fuchsia/fuchsia_device_test.dart | 72 ++-- .../test/general.shard/hot_shared.dart | 12 +- .../test/general.shard/hot_test.dart | 4 +- .../general.shard/ios/simulators_test.dart | 36 -- .../proxied_devices/proxied_devices_test.dart | 38 +- .../resident_devtools_handler_test.dart | 13 +- .../resident_runner_helpers.dart | 58 ++- .../general.shard/resident_runner_test.dart | 241 +++++++++--- .../resident_web_runner_cold_test.dart | 9 +- .../resident_web_runner_test.dart | 31 +- .../runner/flutter_command_runner_test.dart | 1 - .../general.shard/terminal_handler_test.dart | 20 +- .../flutter_tools/test/src/fake_devices.dart | 3 - packages/flutter_tools/test/src/fakes.dart | 6 - 57 files changed, 747 insertions(+), 920 deletions(-) diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart index 40a291ae0b33..51ae79a34820 100644 --- a/packages/flutter_tools/lib/src/android/android_device.dart +++ b/packages/flutter_tools/lib/src/android/android_device.dart @@ -59,7 +59,7 @@ class AndroidDevice extends Device { this.productID, required this.modelID, this.deviceCodeName, - required super.logger, + required Logger logger, required ProcessManager processManager, required Platform platform, required AndroidSdk androidSdk, diff --git a/packages/flutter_tools/lib/src/base/dds.dart b/packages/flutter_tools/lib/src/base/dds.dart index f1be2faf10bf..eba8d3875c99 100644 --- a/packages/flutter_tools/lib/src/base/dds.dart +++ b/packages/flutter_tools/lib/src/base/dds.dart @@ -4,333 +4,112 @@ import 'dart:async'; +import 'package:dds/dds.dart' as dds; import 'package:meta/meta.dart'; -import '../artifacts.dart'; -import '../convert.dart'; -import '../device.dart'; -import '../globals.dart' as globals; +import 'common.dart'; +import 'context.dart'; import 'io.dart' as io; import 'logger.dart'; -/// A representation of the current DDS state including: -/// -/// - The process the external DDS instance is running in -/// - The service URI DDS is being served on -/// - The URI DevTools is being served on, if applicable -/// - The URI DTD is being served on, if applicable -typedef DartDevelopmentServiceInstance = ({ - io.Process? process, - Uri? serviceUri, - Uri? devToolsUri, - Uri? dtdUri, -}); - -/// The default DDSLauncherCallback used to spawn DDS. -Future defaultStartDartDevelopmentService( - Uri remoteVmServiceUri, { - required bool enableAuthCodes, - required bool ipv6, - required bool enableDevTools, - required List cachedUserTags, - Uri? serviceUri, - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, -}) async { - final String exe = globals.artifacts!.getArtifactPath( - Artifact.engineDartBinary, - ); - final io.Process process = await io.Process.start( - exe, - [ - 'development-service', - '--vm-service-uri=$remoteVmServiceUri', - if (serviceUri != null) ...[ - '--bind-address=${serviceUri.host}', - '--bind-port=${serviceUri.port}', - ], - if (!enableAuthCodes) '--disable-service-auth-codes', - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // if (enableDevTools) '--serve-devtools', - if (google3WorkspaceRoot != null) - '--google3-workspace-root=$google3WorkspaceRoot', - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // if (devToolsServerAddress != null) - // '--devtools-server-address=$devToolsServerAddress', - for (final String tag in cachedUserTags) '--cached-user-tags=$tag', - ], - ); - final Completer completer = - Completer(); - late StreamSubscription stderrSub; - stderrSub = process.stderr - .transform(utf8.decoder) - .transform(json.decoder) - .listen((Object? result) { - if (result - case { - 'state': 'started', - 'ddsUri': final String ddsUriStr, - }) { - final Uri ddsUri = Uri.parse(ddsUriStr); - final String? devToolsUriStr = result['devToolsUri'] as String?; - final Uri? devToolsUri = - devToolsUriStr == null ? null : Uri.parse(devToolsUriStr); - final String? dtdUriStr = - (result['dtd'] as Map?)?['uri'] as String?; - final Uri? dtdUri = dtdUriStr == null ? null : Uri.parse(dtdUriStr); - - completer.complete(( - process: process, - serviceUri: ddsUri, - devToolsUri: devToolsUri, - dtdUri: dtdUri, - )); - } else if (result - case { - 'state': 'error', - 'error': final String error, - }) { - final Map? exceptionDetails = - result['ddsExceptionDetails'] as Map?; - completer.completeError( - exceptionDetails != null - ? DartDevelopmentServiceException.fromJson(exceptionDetails) - : StateError(error), - ); - } else { - throw StateError('Unexpected result from DDS: $result'); - } - stderrSub.cancel(); - }); - return completer.future; -} - -typedef DDSLauncherCallback = Future Function( - Uri remoteVmServiceUri, { - required bool enableAuthCodes, - required bool ipv6, - required bool enableDevTools, - required List cachedUserTags, - Uri? serviceUri, - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, -}); - // TODO(fujino): This should be direct injected, rather than mutable global state. -/// Used by tests to override the DDS spawn behavior for mocking purposes. @visibleForTesting -DDSLauncherCallback ddsLauncherCallback = defaultStartDartDevelopmentService; - -/// Thrown by DDS during initialization failures, unexpected connection issues, -/// and when attempting to spawn DDS when an existing DDS instance exists. -class DartDevelopmentServiceException implements Exception { - factory DartDevelopmentServiceException.fromJson(Map json) { - if (json - case { - 'error_code': final int errorCode, - 'message': final String message, - 'uri': final String? uri - }) { - return switch (errorCode) { - existingDdsInstanceError => - DartDevelopmentServiceException.existingDdsInstance( - message, - ddsUri: Uri.parse(uri!), - ), - failedToStartError => DartDevelopmentServiceException.failedToStart(), - connectionError => - DartDevelopmentServiceException.connectionIssue(message), - _ => throw StateError( - 'Invalid DartDevelopmentServiceException error_code: $errorCode', - ), - }; - } - throw StateError('Invalid DartDevelopmentServiceException JSON: $json'); - } - - /// Thrown when `DartDeveloperService.startDartDevelopmentService` is called - /// and the target VM service already has a Dart Developer Service instance - /// connected. - factory DartDevelopmentServiceException.existingDdsInstance( - String message, { - Uri? ddsUri, - }) { - return ExistingDartDevelopmentServiceException._( - message, - ddsUri: ddsUri, - ); - } - - /// Thrown when the connection to the remote VM service terminates unexpectedly - /// during Dart Development Service startup. - factory DartDevelopmentServiceException.failedToStart() { - return DartDevelopmentServiceException._( - failedToStartError, - 'Failed to start Dart Development Service', - ); - } - - /// Thrown when a connection error has occurred after startup. - factory DartDevelopmentServiceException.connectionIssue(String message) { - return DartDevelopmentServiceException._(connectionError, message); - } - - DartDevelopmentServiceException._(this.errorCode, this.message); - - /// Set when `DartDeveloperService.startDartDevelopmentService` is called and - /// the target VM service already has a Dart Developer Service instance - /// connected. - static const int existingDdsInstanceError = 1; - - /// Set when the connection to the remote VM service terminates unexpectedly - /// during Dart Development Service startup. - static const int failedToStartError = 2; - - /// Set when a connection error has occurred after startup. - static const int connectionError = 3; - - @override - String toString() => 'DartDevelopmentServiceException: $message'; - - final int errorCode; - final String message; -} - -/// Thrown when attempting to start a new DDS instance when one already exists. -class ExistingDartDevelopmentServiceException - extends DartDevelopmentServiceException { - ExistingDartDevelopmentServiceException._( - String message, { - this.ddsUri, - }) : super._( - DartDevelopmentServiceException.existingDdsInstanceError, - message, - ); - - /// The URI of the existing DDS instance, if available. - /// - /// This URI is the base HTTP URI such as `http://127.0.0.1:1234/AbcDefg=/`, - /// not the WebSocket URI (which can be obtained by mapping the scheme to - /// `ws` (or `wss`) and appending `ws` to the path segments). - final Uri? ddsUri; -} +Future Function( + Uri remoteVmServiceUri, { + bool enableAuthCodes, + bool ipv6, + Uri? serviceUri, + List cachedUserTags, + dds.UriConverter? uriConverter, +}) ddsLauncherCallback = dds.DartDevelopmentService.startDartDevelopmentService; /// Helper class to launch a [dds.DartDevelopmentService]. Allows for us to /// mock out this functionality for testing purposes. -class DartDevelopmentService with DartDevelopmentServiceLocalOperationsMixin { - DartDevelopmentService({required Logger logger}) : _logger = logger; - - DartDevelopmentServiceInstance? _ddsInstance; +class DartDevelopmentService { + dds.DartDevelopmentService? _ddsInstance; - Uri? get uri => _ddsInstance?.serviceUri ?? _existingDdsUri; + Uri? get uri => _ddsInstance?.uri ?? _existingDdsUri; Uri? _existingDdsUri; Future get done => _completer.future; final Completer _completer = Completer(); - final Logger _logger; - - @override Future startDartDevelopmentService( Uri vmServiceUri, { - int? ddsPort, - bool? disableServiceAuthCodes, + required Logger logger, + int? hostPort, bool? ipv6, - bool enableDevTools = true, + bool? disableServiceAuthCodes, bool cacheStartupProfile = false, - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, }) async { - assert(_ddsInstance == null); final Uri ddsUri = Uri( scheme: 'http', - host: ((ipv6 ?? false) - ? io.InternetAddress.loopbackIPv6 - : io.InternetAddress.loopbackIPv4) - .host, - port: ddsPort ?? 0, + host: ((ipv6 ?? false) ? io.InternetAddress.loopbackIPv6 : io.InternetAddress.loopbackIPv4).host, + port: hostPort ?? 0, ); - _logger.printTrace( + logger.printTrace( 'Launching a Dart Developer Service (DDS) instance at $ddsUri, ' 'connecting to VM service at $vmServiceUri.', ); - void completeFuture() { - if (!_completer.isCompleted) { - _completer.complete(); - } - } - try { _ddsInstance = await ddsLauncherCallback( - vmServiceUri, - serviceUri: ddsUri, - enableAuthCodes: disableServiceAuthCodes != true, - ipv6: ipv6 ?? false, - enableDevTools: enableDevTools, - // Enables caching of CPU samples collected during application startup. - cachedUserTags: cacheStartupProfile - ? const ['AppStartUp'] - : const [], - google3WorkspaceRoot: google3WorkspaceRoot, - devToolsServerAddress: devToolsServerAddress, - ); - final io.Process? process = _ddsInstance?.process; - - // Complete the future if the DDS process is null, which happens in - // testing. - if (process != null) { - unawaited(process.exitCode.whenComplete(completeFuture)); - } - } on DartDevelopmentServiceException catch (e) { - _logger.printTrace('Warning: Failed to start DDS: ${e.message}'); - if (e is ExistingDartDevelopmentServiceException) { - _existingDdsUri = e.ddsUri; - } else { - _logger.printError( + vmServiceUri, + serviceUri: ddsUri, + enableAuthCodes: disableServiceAuthCodes != true, + ipv6: ipv6 ?? false, + // Enables caching of CPU samples collected during application startup. + cachedUserTags: cacheStartupProfile ? const ['AppStartUp'] : const [], + uriConverter: context.get(), + ); + unawaited(_ddsInstance?.done.whenComplete(() { + if (!_completer.isCompleted) { + _completer.complete(); + } + })); + logger.printTrace('DDS is listening at ${_ddsInstance?.uri}.'); + } on dds.DartDevelopmentServiceException catch (e) { + logger.printTrace('Warning: Failed to start DDS: ${e.message}'); + if (e.errorCode == dds.DartDevelopmentServiceException.existingDdsInstanceError) { + try { + // First try to use the new field to avoid parsing from the message. + _existingDdsUri = e is dds.ExistingDartDevelopmentServiceException ? e.ddsUri : null; + + // Otherwise, fall back to parsing from the exception (old DDS). + // This is not completely reliable which is why the new field above + // was added. + if (_existingDdsUri == null) { + String parsedUrl = e.message.split(' ').firstWhere((String e) => e.startsWith('http')); + // Trim trailing full stops from the message. + // https://github.com/flutter/flutter/issues/118609. + if (parsedUrl.endsWith('.')) { + parsedUrl = parsedUrl.substring(0, parsedUrl.length - 1); + } + _existingDdsUri ??= Uri.parse(parsedUrl); + } + } on StateError { + if (e.message.contains('Existing VM service clients prevent DDS from taking control.')) { + throwToolExit('${e.message}. Please rebuild your application with a newer version of Flutter.'); + } + logger.printError( 'DDS has failed to start and there is not an existing DDS instance ' 'available to connect to. Please file an issue at https://github.com/flutter/flutter/issues ' - 'with the following error message:\n\n ${e.message}.'); - // DDS was unable to start for an unknown reason. Raise a StateError - // so it can be reported by the crash reporter. - throw StateError(e.message); + 'with the following error message:\n\n ${e.message}.' + ); + // DDS was unable to start for an unknown reason. Raise a StateError + // so it can be reported by the crash reporter. + throw StateError(e.message); + } + } + if (!_completer.isCompleted) { + _completer.complete(); } - completeFuture(); rethrow; } } - void shutdown() => _ddsInstance?.process?.kill(); -} - -/// Contains common functionality that can be used with any implementation of -/// [DartDevelopmentService]. -mixin DartDevelopmentServiceLocalOperationsMixin { - Future startDartDevelopmentService( - Uri vmServiceUri, { - int? ddsPort, - bool? disableServiceAuthCodes, - bool? ipv6, - bool enableDevTools = true, - bool cacheStartupProfile = false, - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, - }); + Future shutdown() async => _ddsInstance?.shutdown(); - /// A convenience method used to create a [DartDevelopmentService] instance - /// from a [DebuggingOptions] instance. - Future startDartDevelopmentServiceFromDebuggingOptions( - Uri vmServiceUri, { - required DebuggingOptions debuggingOptions, - }) => - startDartDevelopmentService( - vmServiceUri, - ddsPort: debuggingOptions.ddsPort, - disableServiceAuthCodes: debuggingOptions.disableServiceAuthCodes, - ipv6: debuggingOptions.ipv6, - enableDevTools: debuggingOptions.enableDevTools, - cacheStartupProfile: debuggingOptions.cacheStartupProfile, - google3WorkspaceRoot: debuggingOptions.google3WorkspaceRoot, - devToolsServerAddress: debuggingOptions.devToolsServerAddress, - ); + void setExternalDevToolsUri(Uri uri) { + _ddsInstance?.setExternalDevToolsUri(uri); + } } diff --git a/packages/flutter_tools/lib/src/commands/attach.dart b/packages/flutter_tools/lib/src/commands/attach.dart index 1fac03a7fd37..404b116c9d58 100644 --- a/packages/flutter_tools/lib/src/commands/attach.dart +++ b/packages/flutter_tools/lib/src/commands/attach.dart @@ -361,6 +361,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. connectionInfoCompleter: connectionInfoCompleter, appStartedCompleter: appStartedCompleter, allowExistingDdsInstance: true, + enableDevTools: boolArg(FlutterCommand.kEnableDevTools), ); }, device, @@ -402,6 +403,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. result = await runner.attach( appStartedCompleter: onAppStart, allowExistingDdsInstance: true, + enableDevTools: boolArg(FlutterCommand.kEnableDevTools), ); if (result != 0) { throwToolExit(null, exitCode: result); @@ -460,9 +462,6 @@ known, it can be explicitly provided to attach via the command-line, e.g. serveObservatory: serveObservatory, usingCISystem: usingCISystem, debugLogsDirectoryPath: debugLogsDirectoryPath, - enableDevTools: boolArg(FlutterCommand.kEnableDevTools), - ipv6: usesIpv6, - printDtd: boolArg(FlutterGlobalOptions.kPrintDtd, global: true), ); return buildInfo.isDebug @@ -473,6 +472,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. packagesFilePath: globalResults![FlutterGlobalOptions.kPackagesOption] as String?, projectRootPath: stringArg('project-root'), dillOutputPath: stringArg('output-dill'), + ipv6: usesIpv6, flutterProject: flutterProject, nativeAssetsYamlFile: stringArg(FlutterOptions.kNativeAssetsYamlFile), nativeAssetsBuilder: _nativeAssetsBuilder, @@ -482,6 +482,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. flutterDevices, target: targetFile, debuggingOptions: debuggingOptions, + ipv6: usesIpv6, ); } @@ -505,6 +506,7 @@ class HotRunnerFactory { String? packagesFilePath, String? dillOutputPath, bool stayResident = true, + bool ipv6 = false, FlutterProject? flutterProject, String? nativeAssetsYamlFile, required HotRunnerNativeAssetsBuilder? nativeAssetsBuilder, @@ -519,6 +521,7 @@ class HotRunnerFactory { projectRootPath: projectRootPath, dillOutputPath: dillOutputPath, stayResident: stayResident, + ipv6: ipv6, nativeAssetsYamlFile: nativeAssetsYamlFile, nativeAssetsBuilder: nativeAssetsBuilder, analytics: analytics, diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart index 48b1c1dba87c..4f1991aa9737 100644 --- a/packages/flutter_tools/lib/src/commands/daemon.dart +++ b/packages/flutter_tools/lib/src/commands/daemon.dart @@ -664,9 +664,11 @@ class AppDomain extends Domain { String? projectRootPath, String? packagesFilePath, String? dillOutputPath, + bool ipv6 = false, String? isolateFilter, bool machine = true, String? userIdentifier, + bool enableDevTools = true, required HotRunnerNativeAssetsBuilder? nativeAssetsBuilder, }) async { if (!await device.supportsRuntimeMode(options.buildInfo.mode)) { @@ -697,6 +699,7 @@ class AppDomain extends Domain { flutterProject: flutterProject, target: target, debuggingOptions: options, + ipv6: ipv6, stayResident: true, urlTunneller: options.webEnableExposeUrl! ? daemon.daemonDomain.exposeUrl : null, machine: machine, @@ -714,6 +717,7 @@ class AppDomain extends Domain { applicationBinary: applicationBinary, projectRootPath: projectRootPath, dillOutputPath: dillOutputPath, + ipv6: ipv6, hostIsIde: true, machine: machine, analytics: globals.analytics, @@ -725,6 +729,7 @@ class AppDomain extends Domain { target: target, debuggingOptions: options, applicationBinary: applicationBinary, + ipv6: ipv6, machine: machine, ); } @@ -738,6 +743,7 @@ class AppDomain extends Domain { return runner.run( connectionInfoCompleter: connectionInfoCompleter, appStartedCompleter: appStartedCompleter, + enableDevTools: enableDevTools, route: route, ); }, @@ -1002,6 +1008,7 @@ class DeviceDomain extends Domain { registerHandler('takeScreenshot', takeScreenshot); registerHandler('startDartDevelopmentService', startDartDevelopmentService); registerHandler('shutdownDartDevelopmentService', shutdownDartDevelopmentService); + registerHandler('setExternalDevToolsUriForDartDevelopmentService', setExternalDevToolsUriForDartDevelopmentService); registerHandler('getDiagnostics', getDiagnostics); registerHandler('startVMServiceDiscoveryForAttach', startVMServiceDiscoveryForAttach); registerHandler('stopVMServiceDiscoveryForAttach', stopVMServiceDiscoveryForAttach); @@ -1189,6 +1196,7 @@ class DeviceDomain extends Domain { route: _getStringArg(args, 'route'), platformArgs: castStringKeyedMap(args['platformArgs']) ?? const {}, prebuiltApplication: _getBoolArg(args, 'prebuiltApplication') ?? false, + ipv6: _getBoolArg(args, 'ipv6') ?? false, userIdentifier: _getStringArg(args, 'userIdentifier'), ); return { @@ -1236,36 +1244,23 @@ class DeviceDomain extends Domain { } /// Starts DDS for the device. - Future> startDartDevelopmentService(Map args) async { + Future startDartDevelopmentService(Map args) async { final String? deviceId = _getStringArg(args, 'deviceId', required: true); final bool? disableServiceAuthCodes = _getBoolArg(args, 'disableServiceAuthCodes'); final String vmServiceUriStr = _getStringArg(args, 'vmServiceUri', required: true)!; - final bool enableDevTools = _getBoolArg(args, 'enableDevTools') ?? false; - final String? devToolsServerAddressStr = _getStringArg(args, 'devToolsServerAddress'); final Device? device = await daemon.deviceDomain._getDevice(deviceId); if (device == null) { throw DaemonException("device '$deviceId' not found"); } - Uri? devToolsServerAddress; - if (devToolsServerAddressStr != null) { - devToolsServerAddress = Uri.parse(devToolsServerAddressStr); - } - await device.dds.startDartDevelopmentService( Uri.parse(vmServiceUriStr), + logger: globals.logger, disableServiceAuthCodes: disableServiceAuthCodes, - enableDevTools: enableDevTools, - devToolsServerAddress: devToolsServerAddress, ); unawaited(device.dds.done.whenComplete(() => sendEvent('device.dds.done.$deviceId'))); - return { - 'ddsUri': device.dds.uri?.toString(), - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // 'devToolsUri': device.dds.devToolsUri?.toString(), - // 'dtdUri': device.dds.dtdUri?.toString(), - }; + return device.dds.uri?.toString(); } /// Starts DDS for the device. @@ -1277,7 +1272,19 @@ class DeviceDomain extends Domain { throw DaemonException("device '$deviceId' not found"); } - device.dds.shutdown(); + await device.dds.shutdown(); + } + + Future setExternalDevToolsUriForDartDevelopmentService(Map args) async { + final String? deviceId = _getStringArg(args, 'deviceId', required: true); + final String uri = _getStringArg(args, 'uri', required: true)!; + + final Device? device = await daemon.deviceDomain._getDevice(deviceId); + if (device == null) { + throw DaemonException("device '$deviceId' not found"); + } + + device.dds.setExternalDevToolsUri(Uri.parse(uri)); } @override diff --git a/packages/flutter_tools/lib/src/commands/drive.dart b/packages/flutter_tools/lib/src/commands/drive.dart index 4365d31ba22f..be6b19c74a27 100644 --- a/packages/flutter_tools/lib/src/commands/drive.dart +++ b/packages/flutter_tools/lib/src/commands/drive.dart @@ -274,6 +274,7 @@ class DriveCommand extends RunCommandBase { buildInfo, device, debuggingOptions, + ipv6 ?? false, applicationBinary: applicationBinary, route: route, userIdentifier: userIdentifier, @@ -294,6 +295,7 @@ class DriveCommand extends RunCommandBase { uri, device, debuggingOptions, + ipv6 ?? false, ); } diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart index c8920f2a8c9b..c46524bad512 100644 --- a/packages/flutter_tools/lib/src/commands/run.dart +++ b/packages/flutter_tools/lib/src/commands/run.dart @@ -354,9 +354,6 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment enableEmbedderApi: enableEmbedderApi, usingCISystem: usingCISystem, debugLogsDirectoryPath: debugLogsDirectoryPath, - enableDevTools: boolArg(FlutterCommand.kEnableDevTools), - ipv6: boolArg(FlutterCommand.ipv6Flag), - printDtd: boolArg(FlutterGlobalOptions.kPrintDtd, global: true), ); } } @@ -705,6 +702,7 @@ class RunCommand extends RunCommandBase { projectRootPath: stringArg('project-root'), dillOutputPath: stringArg('output-dill'), stayResident: stayResident, + ipv6: ipv6 ?? false, analytics: globals.analytics, nativeAssetsYamlFile: stringArg(FlutterOptions.kNativeAssetsYamlFile), nativeAssetsBuilder: _nativeAssetsBuilder, @@ -714,6 +712,7 @@ class RunCommand extends RunCommandBase { flutterDevices.single, target: targetFile, flutterProject: flutterProject, + ipv6: ipv6, debuggingOptions: await createDebuggingOptions(webMode), stayResident: stayResident, fileSystem: globals.fs, @@ -732,6 +731,7 @@ class RunCommand extends RunCommandBase { applicationBinary: applicationBinaryPath == null ? null : globals.fs.file(applicationBinaryPath), + ipv6: ipv6 ?? false, stayResident: stayResident, ); } @@ -776,7 +776,9 @@ class RunCommand extends RunCommandBase { projectRootPath: stringArg('project-root'), packagesFilePath: globalResults![FlutterGlobalOptions.kPackagesOption] as String?, dillOutputPath: stringArg('output-dill'), + ipv6: ipv6 ?? false, userIdentifier: userIdentifier, + enableDevTools: boolArg(FlutterCommand.kEnableDevTools), nativeAssetsBuilder: _nativeAssetsBuilder, ); } on Exception catch (error) { @@ -864,6 +866,7 @@ class RunCommand extends RunCommandBase { try { final int? result = await runner.run( appStartedCompleter: appStartedTimeRecorder, + enableDevTools: stayResident && boolArg(FlutterCommand.kEnableDevTools), route: route, ); handler?.stop(); diff --git a/packages/flutter_tools/lib/src/commands/test.dart b/packages/flutter_tools/lib/src/commands/test.dart index 459adcc001f4..482557aa4604 100644 --- a/packages/flutter_tools/lib/src/commands/test.dart +++ b/packages/flutter_tools/lib/src/commands/test.dart @@ -16,7 +16,6 @@ import '../globals.dart' as globals; import '../native_assets.dart'; import '../project.dart'; import '../runner/flutter_command.dart'; -import '../runner/flutter_command_runner.dart'; import '../test/coverage_collector.dart'; import '../test/event_printer.dart'; import '../test/runner.dart'; @@ -412,7 +411,6 @@ class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts { enableImpeller: ImpellerStatus.fromBool(argResults!['enable-impeller'] as bool?), debugLogsDirectoryPath: debugLogsDirectoryPath, webRenderer: webRenderer, - printDtd: boolArg(FlutterGlobalOptions.kPrintDtd, global: true), webUseWasm: useWasm, webUseLocalCanvaskit: true, ); @@ -601,6 +599,7 @@ class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts { excludeTags: excludeTags, watcher: watcher, enableVmService: collector != null || startPaused || enableVmService, + ipv6: ipv6, machine: machine, updateGoldens: boolArg('update-goldens'), concurrency: jobs, diff --git a/packages/flutter_tools/lib/src/custom_devices/custom_device.dart b/packages/flutter_tools/lib/src/custom_devices/custom_device.dart index 25980ab7d3ff..3a9ee366e372 100644 --- a/packages/flutter_tools/lib/src/custom_devices/custom_device.dart +++ b/packages/flutter_tools/lib/src/custom_devices/custom_device.dart @@ -352,6 +352,7 @@ class CustomDeviceAppSession { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, + bool ipv6 = false, String? userIdentifier }) async { final bool traceStartup = platformArgs['trace-startup'] as bool? ?? false; @@ -376,7 +377,7 @@ class CustomDeviceAppSession { logReader, portForwarder: _device._config.usesPortForwarding ? _device.portForwarder : null, logger: _logger, - ipv6: debuggingOptions.ipv6, + ipv6: ipv6, ); // We need to make the discovery listen to the logReader before the logReader @@ -438,7 +439,7 @@ class CustomDeviceAppSession { class CustomDevice extends Device { CustomDevice({ required CustomDeviceConfig config, - required super.logger, + required Logger logger, required ProcessManager processManager, }) : _config = config, _logger = logger, @@ -788,6 +789,7 @@ class CustomDevice extends Device { debuggingOptions: debuggingOptions, platformArgs: platformArgs, prebuiltApplication: prebuiltApplication, + ipv6: ipv6, userIdentifier: userIdentifier, ); } diff --git a/packages/flutter_tools/lib/src/desktop_device.dart b/packages/flutter_tools/lib/src/desktop_device.dart index a7579bdd0852..1044ab2caec0 100644 --- a/packages/flutter_tools/lib/src/desktop_device.dart +++ b/packages/flutter_tools/lib/src/desktop_device.dart @@ -26,7 +26,7 @@ abstract class DesktopDevice extends Device { DesktopDevice(super.id, { required PlatformType super.platformType, required super.ephemeral, - required super.logger, + required Logger logger, required ProcessManager processManager, required FileSystem fileSystem, required OperatingSystemUtils operatingSystemUtils, @@ -114,6 +114,7 @@ abstract class DesktopDevice extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, + bool ipv6 = false, String? userIdentifier, }) async { if (!prebuiltApplication) { @@ -157,7 +158,7 @@ abstract class DesktopDevice extends Device { final ProtocolDiscovery vmServiceDiscovery = ProtocolDiscovery.vmService(_deviceLogReader, devicePort: debuggingOptions.deviceVmServicePort, hostPort: debuggingOptions.hostVmServicePort, - ipv6: debuggingOptions.ipv6, + ipv6: ipv6, logger: _logger, ); try { diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart index 7c4f32dfa508..35cc939656bc 100644 --- a/packages/flutter_tools/lib/src/device.dart +++ b/packages/flutter_tools/lib/src/device.dart @@ -603,11 +603,10 @@ String getNameForDeviceConnectionInterface(DeviceConnectionInterface connectionI /// the host operating system in the case of Flutter Desktop. abstract class Device { Device(this.id, { - required Logger logger, required this.category, required this.platformType, required this.ephemeral, - }) : dds = DartDevelopmentService(logger: logger); + }); final String id; @@ -734,7 +733,7 @@ abstract class Device { DevicePortForwarder? get portForwarder; /// Get the DDS instance for this device. - final DartDevelopmentService dds; + final DartDevelopmentService dds = DartDevelopmentService(); /// Clear the device's logs. void clearLogs(); @@ -779,6 +778,7 @@ abstract class Device { required DebuggingOptions debuggingOptions, Map platformArgs, bool prebuiltApplication = false, + bool ipv6 = false, String? userIdentifier, }); @@ -1007,11 +1007,7 @@ class DebuggingOptions { this.enableEmbedderApi = false, this.usingCISystem = false, this.debugLogsDirectoryPath, - this.enableDevTools = true, - this.ipv6 = false, - this.google3WorkspaceRoot, - this.printDtd = false, - }) : debuggingEnabled = true, + }) : debuggingEnabled = true, webRenderer = webRenderer ?? WebRendererMode.getDefault(useWasm: webUseWasm); DebuggingOptions.disabled(this.buildInfo, { @@ -1069,10 +1065,6 @@ class DebuggingOptions { nullAssertions = false, nativeNullAssertions = false, serveObservatory = false, - enableDevTools = false, - ipv6 = false, - google3WorkspaceRoot = null, - printDtd = false, webRenderer = webRenderer ?? WebRendererMode.getDefault(useWasm: webUseWasm); DebuggingOptions._({ @@ -1131,10 +1123,6 @@ class DebuggingOptions { required this.enableEmbedderApi, required this.usingCISystem, required this.debugLogsDirectoryPath, - required this.enableDevTools, - required this.ipv6, - required this.google3WorkspaceRoot, - required this.printDtd, }); final bool debuggingEnabled; @@ -1179,10 +1167,6 @@ class DebuggingOptions { final bool enableEmbedderApi; final bool usingCISystem; final String? debugLogsDirectoryPath; - final bool enableDevTools; - final bool ipv6; - final String? google3WorkspaceRoot; - final bool printDtd; /// Whether the tool should try to uninstall a previously installed version of the app. /// @@ -1236,6 +1220,7 @@ class DebuggingOptions { EnvironmentType environmentType, String? route, Map platformArgs, { + bool ipv6 = false, DeviceConnectionInterface interfaceType = DeviceConnectionInterface.attached, bool isCoreDevice = false, }) { @@ -1341,10 +1326,6 @@ class DebuggingOptions { 'enableEmbedderApi': enableEmbedderApi, 'usingCISystem': usingCISystem, 'debugLogsDirectoryPath': debugLogsDirectoryPath, - 'enableDevTools': enableDevTools, - 'ipv6': ipv6, - 'google3WorkspaceRoot': google3WorkspaceRoot, - 'printDtd': printDtd, }; static DebuggingOptions fromJson(Map json, BuildInfo buildInfo) => @@ -1404,10 +1385,6 @@ class DebuggingOptions { enableEmbedderApi: (json['enableEmbedderApi'] as bool?) ?? false, usingCISystem: (json['usingCISystem'] as bool?) ?? false, debugLogsDirectoryPath: json['debugLogsDirectoryPath'] as String?, - enableDevTools: (json['enableDevTools'] as bool?) ?? true, - ipv6: (json['ipv6'] as bool?) ?? false, - google3WorkspaceRoot: json['google3WorkspaceRoot'] as String?, - printDtd: (json['printDtd'] as bool?) ?? false, ); } diff --git a/packages/flutter_tools/lib/src/drive/drive_service.dart b/packages/flutter_tools/lib/src/drive/drive_service.dart index 82bd4bad4d53..b3340db461fe 100644 --- a/packages/flutter_tools/lib/src/drive/drive_service.dart +++ b/packages/flutter_tools/lib/src/drive/drive_service.dart @@ -4,6 +4,7 @@ import 'dart:async'; +import 'package:dds/dds.dart' as dds; import 'package:file/file.dart'; import 'package:meta/meta.dart'; import 'package:package_config/package_config_types.dart'; @@ -11,7 +12,6 @@ import 'package:vm_service/vm_service.dart' as vm_service; import '../application_package.dart'; import '../base/common.dart'; -import '../base/dds.dart'; import '../base/logger.dart'; import '../base/process.dart'; import '../build_info.dart'; @@ -65,7 +65,8 @@ abstract class DriverService { Future start( BuildInfo buildInfo, Device device, - DebuggingOptions debuggingOptions, { + DebuggingOptions debuggingOptions, + bool ipv6, { File? applicationBinary, String? route, String? userIdentifier, @@ -78,6 +79,7 @@ abstract class DriverService { Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions, + bool ipv6, ); /// Start the test file with the provided [arguments] and [environment], returning @@ -146,7 +148,8 @@ class FlutterDriverService extends DriverService { Future start( BuildInfo buildInfo, Device device, - DebuggingOptions debuggingOptions, { + DebuggingOptions debuggingOptions, + bool ipv6, { File? applicationBinary, String? route, String? userIdentifier, @@ -196,6 +199,7 @@ class FlutterDriverService extends DriverService { result.vmServiceUri!, device, debuggingOptions, + ipv6, ); } @@ -204,6 +208,7 @@ class FlutterDriverService extends DriverService { Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions, + bool ipv6, ) async { Uri uri; if (vmServiceUri.scheme == 'ws') { @@ -217,12 +222,15 @@ class FlutterDriverService extends DriverService { _device = device; if (debuggingOptions.enableDds) { try { - await device.dds.startDartDevelopmentServiceFromDebuggingOptions( + await device.dds.startDartDevelopmentService( uri, - debuggingOptions: debuggingOptions, + hostPort: debuggingOptions.ddsPort, + ipv6: ipv6, + disableServiceAuthCodes: debuggingOptions.disableServiceAuthCodes, + logger: _logger, ); _vmServiceUri = device.dds.uri.toString(); - } on DartDevelopmentServiceException { + } on dds.DartDevelopmentServiceException { // If there's another flutter_tools instance still connected to the target // application, DDS will already be running remotely and this call will fail. // This can be ignored to continue to use the existing remote DDS instance. diff --git a/packages/flutter_tools/lib/src/drive/web_driver_service.dart b/packages/flutter_tools/lib/src/drive/web_driver_service.dart index d7194f347602..b7989cc1292b 100644 --- a/packages/flutter_tools/lib/src/drive/web_driver_service.dart +++ b/packages/flutter_tools/lib/src/drive/web_driver_service.dart @@ -55,7 +55,8 @@ class WebDriverService extends DriverService { Future start( BuildInfo buildInfo, Device device, - DebuggingOptions debuggingOptions, { + DebuggingOptions debuggingOptions, + bool ipv6, { File? applicationBinary, String? route, String? userIdentifier, @@ -71,6 +72,7 @@ class WebDriverService extends DriverService { _residentRunner = webRunnerFactory!.createWebRunner( flutterDevice, target: mainPath, + ipv6: ipv6, debuggingOptions: buildInfo.isRelease ? DebuggingOptions.disabled( buildInfo, @@ -232,7 +234,7 @@ class WebDriverService extends DriverService { } @override - Future reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions) async { + Future reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions, bool ipv6) async { throwToolExit('--use-existing-app is not supported with flutter web driver'); } } diff --git a/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart b/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart index 4e7ffe89b018..bb7ffdb0d9cc 100644 --- a/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart +++ b/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart @@ -58,9 +58,10 @@ Future _kDefaultDartDevelopmentServiceStarter( ) async { await device.dds.startDartDevelopmentService( vmServiceUri, - ddsPort: 0, - disableServiceAuthCodes: disableServiceAuthCodes, + hostPort: 0, ipv6: true, + disableServiceAuthCodes: disableServiceAuthCodes, + logger: globals.logger, ); } @@ -211,7 +212,7 @@ class FuchsiaDevices extends PollingDeviceDiscovery { _logger.printError('Failed to resolve host for Fuchsia device `$name`'); return null; } - return FuchsiaDevice(resolvedHost, name: name, logger: _logger); + return FuchsiaDevice(resolvedHost, name: name); } @override @@ -219,7 +220,7 @@ class FuchsiaDevices extends PollingDeviceDiscovery { } class FuchsiaDevice extends Device { - FuchsiaDevice(super.id, {required this.name, required super.logger}) + FuchsiaDevice(super.id, {required this.name}) : super( platformType: PlatformType.fuchsia, category: null, @@ -294,6 +295,7 @@ class FuchsiaDevice extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, + bool ipv6 = false, String? userIdentifier, }) async { if (await isSession) { diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart index 554abf65e66b..4baceaacd78e 100644 --- a/packages/flutter_tools/lib/src/ios/devices.dart +++ b/packages/flutter_tools/lib/src/ios/devices.dart @@ -272,7 +272,7 @@ class IOSDevice extends Device { required IOSCoreDeviceControl coreDeviceControl, required XcodeDebug xcodeDebug, required IProxy iProxy, - required super.logger, + required Logger logger, }) : _sdkVersion = sdkVersion, _iosDeploy = iosDeploy, @@ -470,6 +470,7 @@ class IOSDevice extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, + bool ipv6 = false, String? userIdentifier, @visibleForTesting Duration? discoveryTimeout, @visibleForTesting ShutdownHooks? shutdownHooks, @@ -523,6 +524,7 @@ class IOSDevice extends Device { EnvironmentType.physical, route, platformArgs, + ipv6: ipv6, interfaceType: connectionInterface, isCoreDevice: isCoreDevice, ); @@ -539,6 +541,7 @@ class IOSDevice extends Device { bundle: bundle, debuggingOptions: debuggingOptions, launchArguments: launchArguments, + ipv6: ipv6, uninstallFirst: debuggingOptions.uninstallFirst, ); } @@ -616,6 +619,7 @@ class IOSDevice extends Device { localUri = await _discoverDartVMForCoreDevice( debuggingOptions: debuggingOptions, packageId: packageId, + ipv6: ipv6, vmServiceDiscovery: vmServiceDiscovery, ); } else if (isWirelesslyConnected) { @@ -647,7 +651,7 @@ class IOSDevice extends Device { localUri = await MDnsVmServiceDiscovery.instance!.getVMServiceUriForLaunch( packageId, this, - usesIpv6: debuggingOptions.ipv6, + usesIpv6: ipv6, deviceVmservicePort: serviceURL.port, useDeviceIPAsHost: true, ); @@ -669,6 +673,7 @@ class IOSDevice extends Device { bundle: bundle, debuggingOptions: debuggingOptions, launchArguments: launchArguments, + ipv6: ipv6, uninstallFirst: false, skipInstall: true, ); @@ -723,6 +728,7 @@ class IOSDevice extends Device { /// Wireless devices require using the device IP as the host. Future _discoverDartVMForCoreDevice({ required String packageId, + required bool ipv6, required DebuggingOptions debuggingOptions, ProtocolDiscovery? vmServiceDiscovery, }) async { @@ -769,7 +775,7 @@ class IOSDevice extends Device { final Future vmUrlFromMDns = MDnsVmServiceDiscovery.instance!.getVMServiceUriForLaunch( packageId, this, - usesIpv6: debuggingOptions.ipv6, + usesIpv6: ipv6, useDeviceIPAsHost: isWirelesslyConnected, ); @@ -808,6 +814,7 @@ class IOSDevice extends Device { required Directory bundle, required DebuggingOptions debuggingOptions, required List launchArguments, + required bool ipv6, required bool uninstallFirst, bool skipInstall = false, }) { @@ -838,7 +845,7 @@ class IOSDevice extends Device { portForwarder: isWirelesslyConnected ? null : portForwarder, hostPort: debuggingOptions.hostVmServicePort, devicePort: debuggingOptions.deviceVmServicePort, - ipv6: debuggingOptions.ipv6, + ipv6: ipv6, logger: _logger, ); } diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart index 97d61857caf4..fb255f840674 100644 --- a/packages/flutter_tools/lib/src/ios/simulators.dart +++ b/packages/flutter_tools/lib/src/ios/simulators.dart @@ -90,7 +90,6 @@ class IOSSimulatorUtils { name: name, simControl: _simControl, simulatorCategory: device.category, - logger: _simControl._logger, ); }).whereType().toList(); } @@ -357,7 +356,6 @@ class IOSSimulator extends Device { required this.name, required this.simulatorCategory, required SimControl simControl, - required super.logger, }) : _simControl = simControl, super( category: Category.mobile, @@ -474,6 +472,7 @@ class IOSSimulator extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, + bool ipv6 = false, String? userIdentifier, }) async { if (!prebuiltApplication && package is BuildableIOSApp) { @@ -502,7 +501,7 @@ class IOSSimulator extends Device { if (debuggingOptions.debuggingEnabled) { vmServiceDiscovery = ProtocolDiscovery.vmService( getLogReader(app: package), - ipv6: debuggingOptions.ipv6, + ipv6: ipv6, hostPort: debuggingOptions.hostVmServicePort, devicePort: debuggingOptions.deviceVmServicePort, logger: globals.logger, diff --git a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart index 52d8368a6994..332e964ce035 100644 --- a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart +++ b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart @@ -50,6 +50,7 @@ class DwdsWebRunnerFactory extends WebRunnerFactory { String? target, required bool stayResident, required FlutterProject flutterProject, + required bool? ipv6, required DebuggingOptions debuggingOptions, UrlTunneller? urlTunneller, required Logger logger, @@ -64,6 +65,7 @@ class DwdsWebRunnerFactory extends WebRunnerFactory { target: target, flutterProject: flutterProject, debuggingOptions: debuggingOptions, + ipv6: ipv6, stayResident: stayResident, urlTunneller: urlTunneller, machine: machine, @@ -87,6 +89,7 @@ class ResidentWebRunner extends ResidentRunner { bool stayResident = true, bool machine = false, required this.flutterProject, + required bool? ipv6, required DebuggingOptions debuggingOptions, required FileSystem fileSystem, required Logger logger, @@ -94,7 +97,6 @@ class ResidentWebRunner extends ResidentRunner { required Usage usage, required Analytics analytics, UrlTunneller? urlTunneller, - // TODO(bkonyi): remove when ready to serve DevTools from DDS. ResidentDevtoolsHandlerFactory devtoolsHandler = createDefaultHandler, }) : _fileSystem = fileSystem, _logger = logger, @@ -106,6 +108,7 @@ class ResidentWebRunner extends ResidentRunner { [device], target: target ?? fileSystem.path.join('lib', 'main.dart'), debuggingOptions: debuggingOptions, + ipv6: ipv6, stayResident: stayResident, machine: machine, devtoolsHandler: devtoolsHandler, @@ -192,7 +195,6 @@ class ResidentWebRunner extends ResidentRunner { if (_exited) { return; } - // TODO(bkonyi): remove when ready to serve DevTools from DDS. await residentDevtoolsHandler!.shutdown(); await _stdOutSub?.cancel(); await _stdErrSub?.cancel(); @@ -245,6 +247,7 @@ class ResidentWebRunner extends ResidentRunner { Future run({ Completer? connectionInfoCompleter, Completer? appStartedCompleter, + bool enableDevTools = false, // ignored, we don't yet support devtools for web String? route, }) async { final ApplicationPackage? package = await ApplicationPackageFactory.instance!.getPackageForPlatform( @@ -365,6 +368,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive). return attach( connectionInfoCompleter: connectionInfoCompleter, appStartedCompleter: appStartedCompleter, + enableDevTools: enableDevTools, ); }); } on WebSocketException catch (error, stackTrace) { @@ -472,14 +476,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive). final Duration elapsed = _systemClock.now().difference(start); final String elapsedMS = getElapsedAsMilliseconds(elapsed); _logger.printStatus('Restarted application in $elapsedMS.'); - - // TODO(bkonyi): replace with code below when ready to serve DevTools from DDS. unawaited(residentDevtoolsHandler!.hotRestart(flutterDevices)); - /* - for (final FlutterDevice? device in flutterDevices) { - unawaited(device?.handleHotRestart()); - } - */ // Don't track restart times for dart2js builds or web-server devices. if (debuggingOptions.buildInfo.isDebug && deviceIsDebuggable) { @@ -606,6 +603,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive). Completer? connectionInfoCompleter, Completer? appStartedCompleter, bool allowExistingDdsInstance = false, + bool enableDevTools = false, // ignored, we don't yet support devtools for web bool needsFullRestart = true, }) async { if (_chromiumLauncher != null) { @@ -684,14 +682,13 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive). } }); } - } - // TODO(bkonyi): remove when ready to serve DevTools from DDS. - if (debuggingOptions.enableDevTools) { - // The method below is guaranteed never to return a failing future. - unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools( - devToolsServerAddress: debuggingOptions.devToolsServerAddress, - flutterDevices: flutterDevices, - )); + if (enableDevTools) { + // The method below is guaranteed never to return a failing future. + unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools( + devToolsServerAddress: debuggingOptions.devToolsServerAddress, + flutterDevices: flutterDevices, + )); + } } if (websocketUri != null) { if (debuggingOptions.vmserviceOutFile != null) { diff --git a/packages/flutter_tools/lib/src/macos/macos_ipad_device.dart b/packages/flutter_tools/lib/src/macos/macos_ipad_device.dart index e371569c73b7..235d01383d56 100644 --- a/packages/flutter_tools/lib/src/macos/macos_ipad_device.dart +++ b/packages/flutter_tools/lib/src/macos/macos_ipad_device.dart @@ -99,6 +99,7 @@ class MacOSDesignedForIPadDevice extends DesktopDevice { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, + bool ipv6 = false, String? userIdentifier, }) async { // Only attaching to a running app launched from Xcode is supported. diff --git a/packages/flutter_tools/lib/src/preview_device.dart b/packages/flutter_tools/lib/src/preview_device.dart index 2577a29e607b..71eba1fcb133 100644 --- a/packages/flutter_tools/lib/src/preview_device.dart +++ b/packages/flutter_tools/lib/src/preview_device.dart @@ -95,7 +95,7 @@ class PreviewDeviceDiscovery extends PollingDeviceDiscovery { class PreviewDevice extends Device { PreviewDevice({ required ProcessManager processManager, - required super.logger, + required Logger logger, required FileSystem fileSystem, required Artifacts artifacts, required File previewBinary, @@ -170,6 +170,7 @@ class PreviewDevice extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, + bool ipv6 = false, String? userIdentifier, }) async { final Directory assetDirectory = _fileSystem.systemTempDirectory @@ -213,7 +214,7 @@ class PreviewDevice extends Device { final ProtocolDiscovery vmServiceDiscovery = ProtocolDiscovery.vmService(_logReader, devicePort: debuggingOptions.deviceVmServicePort, hostPort: debuggingOptions.hostVmServicePort, - ipv6: debuggingOptions.ipv6, + ipv6: ipv6, logger: _logger, ); try { diff --git a/packages/flutter_tools/lib/src/proxied_devices/devices.dart b/packages/flutter_tools/lib/src/proxied_devices/devices.dart index 897c4efa7ce1..c286ce2545f8 100644 --- a/packages/flutter_tools/lib/src/proxied_devices/devices.dart +++ b/packages/flutter_tools/lib/src/proxied_devices/devices.dart @@ -19,7 +19,6 @@ import '../device.dart'; import '../device_port_forwarder.dart'; import '../device_vm_service_discovery_for_attach.dart'; import '../project.dart'; -import '../resident_runner.dart'; import 'debounce_data_stream.dart'; import 'file_transfer.dart'; @@ -176,7 +175,7 @@ class ProxiedDevice extends Device { required this.supportsScreenshot, required this.supportsFastStart, required bool supportsHardwareRendering, - required super.logger, + required Logger logger, FileTransfer fileTransfer = const FileTransfer(), }): _deltaFileTransfer = deltaFileTransfer, _enableDdsProxy = enableDdsProxy, @@ -335,6 +334,7 @@ class ProxiedDevice extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, + bool ipv6 = false, String? userIdentifier, }) async { final Map result = _cast>(await connection.sendRequest('device.startApp', { @@ -345,7 +345,7 @@ class ProxiedDevice extends Device { 'debuggingOptions': debuggingOptions.toJson(), 'platformArgs': platformArgs, 'prebuiltApplication': prebuiltApplication, - 'ipv6': debuggingOptions.ipv6, + 'ipv6': ipv6, 'userIdentifier': userIdentifier, })); final bool started = _cast(result['started']); @@ -748,7 +748,7 @@ Future _defaultCreateServerSocket(Logger logger, int? hostPort, bo /// There are a lot of communications between DDS and the VM service on the /// device. When using proxied device, starting DDS remotely helps reduces the /// amount of data transferred with the remote daemon, hence improving latency. -class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMixin implements DartDevelopmentService { +class ProxiedDartDevelopmentService implements DartDevelopmentService { ProxiedDartDevelopmentService( this.connection, this.deviceId, { @@ -756,11 +756,10 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi required ProxiedPortForwarder proxiedPortForwarder, required ProxiedPortForwarder devicePortForwarder, @visibleForTesting DartDevelopmentService? localDds, - }) : - _logger = logger, + }) : _logger = logger, _proxiedPortForwarder = proxiedPortForwarder, _devicePortForwarder = devicePortForwarder, - _localDds = localDds ?? DartDevelopmentService(logger: logger); + _localDds = localDds ?? DartDevelopmentService(); final String deviceId; @@ -777,9 +776,10 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi /// It forwards a port on the remotely connected device, to the remote host, then to the local host. final ProxiedPortForwarder _devicePortForwarder; + Uri? _localUri; + @override Uri? get uri => _ddsStartedLocally ? _localDds.uri : _localUri; - Uri? _localUri; @override Future get done => _completer.future; @@ -792,14 +792,11 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi @override Future startDartDevelopmentService( Uri vmServiceUri, { - FlutterDevice? device, - int? ddsPort, + required Logger logger, + int? hostPort, bool? ipv6, bool? disableServiceAuthCodes, - bool enableDevTools = false, bool cacheStartupProfile = false, - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, }) async { // Locate the original VM service port on the remote daemon. // A proxied device has two PortForwarder. Check both to determine which @@ -808,26 +805,18 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi _proxiedPortForwarder.originalRemotePort(vmServiceUri.port) ?? _devicePortForwarder.originalRemotePort(vmServiceUri.port); - Future startLocalDds() async { + if (remoteVMServicePort == null) { + _logger.printTrace('VM service port is not a forwarded port. Start DDS locally.'); _ddsStartedLocally = true; await _localDds.startDartDevelopmentService( vmServiceUri, - ddsPort: ddsPort, + logger: logger, + hostPort: hostPort, ipv6: ipv6, disableServiceAuthCodes: disableServiceAuthCodes, cacheStartupProfile: cacheStartupProfile, - enableDevTools: enableDevTools, - google3WorkspaceRoot: google3WorkspaceRoot, - devToolsServerAddress: devToolsServerAddress, ); - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // unawaited(_localDds.invokeServiceExtensions(device)); unawaited(_localDds.done.then(_completer.complete)); - } - - if (remoteVMServicePort == null) { - _logger.printTrace('VM service port is not a forwarded port. Start DDS locally.'); - await startLocalDds(); return; } @@ -846,33 +835,11 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi // Ignore if we did not receive any event from the server. }, )); - final Object? response = await connection.sendRequest(method, { - 'deviceId': deviceId, - 'vmServiceUri': remoteVMServiceUri.toString(), - 'disableServiceAuthCodes': disableServiceAuthCodes, - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // 'enableDevTools': enableDevTools, - // if (devToolsServerAddress != null) 'devToolsServerAddress': devToolsServerAddress.toString(), - }); - - if (response is Map) { - remoteUriStr = response['ddsUri'] as String?; - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - /* - final String? devToolsUriStr = response['devToolsUri'] as String?; - if (devToolsUriStr != null) { - _remoteDevToolsUri = Uri.parse(devToolsUriStr); - } - final String? dtdUriStr = response['dtdUri'] as String?; - if (dtdUriStr != null) { - _remoteDtdUri = Uri.parse(dtdUriStr); - } - */ - } else { - // For backwards compatibility in google3. - // TODO(bkonyi): remove once a newer version of the flutter_tool is rolled out. - remoteUriStr = _cast(response); - } + remoteUriStr = _cast(await connection.sendRequest(method, { + 'deviceId': deviceId, + 'vmServiceUri': remoteVMServiceUri.toString(), + 'disableServiceAuthCodes': disableServiceAuthCodes, + })); } on String catch (e) { if (!e.contains(method)) { rethrow; @@ -883,7 +850,16 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi if (remoteUriStr == null) { _logger.printTrace('Remote daemon cannot start DDS. Start a local DDS instead.'); - await startLocalDds(); + _ddsStartedLocally = true; + await _localDds.startDartDevelopmentService( + vmServiceUri, + logger: logger, + hostPort: hostPort, + ipv6: ipv6, + disableServiceAuthCodes: disableServiceAuthCodes, + cacheStartupProfile: cacheStartupProfile, + ); + unawaited(_localDds.done.then(_completer.complete)); return; } @@ -893,7 +869,7 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi final Uri remoteUri = Uri.parse(remoteUriStr); final int localPort = await _proxiedPortForwarder.forward( remoteUri.port, - hostPort: ddsPort, + hostPort: hostPort, ipv6: ipv6, ); @@ -909,7 +885,7 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi @override Future shutdown() async { if (_ddsStartedLocally) { - _localDds.shutdown(); + await _localDds.shutdown(); _ddsStartedLocally = false; } else { await connection.sendRequest('device.shutdownDartDevelopmentService', { @@ -917,6 +893,14 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi }); } } + + @override + void setExternalDevToolsUri(Uri uri) { + connection.sendRequest('device.setExternalDevToolsUriForDartDevelopmentService', { + 'deviceId': deviceId, + 'uri': uri.toString(), + }); + } } class ProxiedVMServiceDiscoveryForAttach extends VMServiceDiscoveryForAttach { diff --git a/packages/flutter_tools/lib/src/resident_devtools_handler.dart b/packages/flutter_tools/lib/src/resident_devtools_handler.dart index ae5f2b2a840a..d304451db724 100644 --- a/packages/flutter_tools/lib/src/resident_devtools_handler.dart +++ b/packages/flutter_tools/lib/src/resident_devtools_handler.dart @@ -2,10 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(bkonyi): remove this file when ready to serve DevTools from DDS. -// -// See https://github.com/flutter/flutter/issues/150044 - import 'dart:async'; import 'package:browser_launcher/browser_launcher.dart'; @@ -114,6 +110,18 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler { return; } + final Uri? devToolsUrl = _devToolsLauncher.devToolsUrl; + if (devToolsUrl != null) { + for (final FlutterDevice? device in flutterDevices) { + if (device == null) { + continue; + } + // Notify the DDS instances that there's a DevTools instance available so they can correctly + // redirect DevTools related requests. + device.device?.dds.setExternalDevToolsUri(devToolsUrl); + } + } + Future callServiceExtensions() async { final List devicesWithExtension = await _devicesWithExtensions(flutterDevices); await Future.wait( @@ -206,12 +214,10 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler { }, ); } on Exception catch (e) { - if (!_shutdown) { - _logger.printError( - 'Failed to set DevTools server address: $e. Deep links to' - ' DevTools will not show in Flutter errors.', - ); - } + _logger.printError( + 'Failed to set DevTools server address: $e. Deep links to' + ' DevTools will not show in Flutter errors.', + ); } } @@ -260,13 +266,11 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler { }, ); } on Exception catch (e) { - if (!_shutdown) { - _logger.printError(e.toString()); - _logger.printError( - 'Failed to set vm service URI: $e. Deep links to DevTools' - ' will not show in Flutter errors.', - ); - } + _logger.printError(e.toString()); + _logger.printError( + 'Failed to set vm service URI: $e. Deep links to DevTools' + ' will not show in Flutter errors.', + ); } } @@ -304,10 +308,10 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler { @override Future shutdown() async { - _shutdown = true; - if (_devToolsLauncher == null || !_served) { + if (_devToolsLauncher == null || _shutdown || !_served) { return; } + _shutdown = true; _readyToAnnounce = false; await _devToolsLauncher.close(); } diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index b8e084222840..1af14acbb84e 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart @@ -4,6 +4,7 @@ import 'dart:async'; +import 'package:dds/dds.dart' as dds; import 'package:meta/meta.dart'; import 'package:package_config/package_config.dart'; import 'package:vm_service/vm_service.dart' as vm_service; @@ -14,7 +15,6 @@ import 'asset.dart'; import 'base/command_help.dart'; import 'base/common.dart'; import 'base/context.dart'; -import 'base/dds.dart'; import 'base/file_system.dart'; import 'base/io.dart' as io; import 'base/logger.dart'; @@ -252,9 +252,13 @@ class FlutterDevice { CompileExpression? compileExpression, GetSkSLMethod? getSkSLMethod, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, - required DebuggingOptions debuggingOptions, int? hostVmServicePort, + int? ddsPort, + bool disableServiceAuthCodes = false, + bool cacheStartupProfile = false, + bool enableDds = true, required bool allowExistingDdsInstance, + bool ipv6 = false, }) { final Completer completer = Completer(); late StreamSubscription subscription; @@ -266,11 +270,11 @@ class FlutterDevice { isWaitingForVm = true; bool existingDds = false; FlutterVmService? service; - if (debuggingOptions.enableDds) { + if (enableDds) { void handleError(Exception e, StackTrace st) { globals.printTrace('Fail to connect to service protocol: $vmServiceUri: $e'); if (!completer.isCompleted) { - completer.completeError('failed to connect to $vmServiceUri $e', st); + completer.completeError('failed to connect to $vmServiceUri', st); } } // First check if the VM service is actually listening on vmServiceUri as @@ -282,7 +286,7 @@ class FlutterDevice { } on Exception catch (exception) { globals.printTrace('Fail to connect to service protocol: $vmServiceUri: $exception'); if (!completer.isCompleted && !_isListeningForVmServiceUri!) { - completer.completeError('failed to connect to $vmServiceUri $exception'); + completer.completeError('failed to connect to $vmServiceUri'); } return; } @@ -291,13 +295,17 @@ class FlutterDevice { // (e.g., failure to bind to a port, failure to connect to the VM service, // attaching to a VM service with existing clients, etc.). try { - await device!.dds.startDartDevelopmentServiceFromDebuggingOptions( + await device!.dds.startDartDevelopmentService( vmServiceUri, - debuggingOptions: debuggingOptions, + hostPort: ddsPort, + ipv6: ipv6, + disableServiceAuthCodes: disableServiceAuthCodes, + logger: globals.logger, + cacheStartupProfile: cacheStartupProfile, ); - } on DartDevelopmentServiceException catch (e, st) { + } on dds.DartDevelopmentServiceException catch (e, st) { if (!allowExistingDdsInstance || - (e.errorCode != DartDevelopmentServiceException.existingDdsInstanceError)) { + (e.errorCode != dds.DartDevelopmentServiceException.existingDdsInstanceError)) { handleError(e, st); return; } else { @@ -318,7 +326,7 @@ class FlutterDevice { service = await Future.any( >[ connectToVmService( - debuggingOptions.enableDds ? (device!.dds.uri ?? vmServiceUri!): vmServiceUri!, + enableDds ? (device!.dds.uri ?? vmServiceUri!): vmServiceUri!, reloadSources: reloadSources, restart: restart, compileExpression: compileExpression, @@ -335,7 +343,7 @@ class FlutterDevice { } on Exception catch (exception) { globals.printTrace('Fail to connect to service protocol: $vmServiceUri: $exception'); if (!completer.isCompleted && !_isListeningForVmServiceUri!) { - completer.completeError('failed to connect to $vmServiceUri $exception'); + completer.completeError('failed to connect to $vmServiceUri'); } return; } @@ -345,22 +353,6 @@ class FlutterDevice { globals.printTrace('Successfully connected to service protocol: $vmServiceUri'); vmService = service; - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - /* - if (debuggingOptions.enableDds && !existingDds) { - // Don't await this as service extensions won't return if the target - // isolate is paused on start. - unawaited(device!.dds.invokeServiceExtensions(this)); - } - if (existingDds && debuggingOptions.devToolsServerAddress != null) { - // Don't await this as service extensions won't return if the target - // isolate is paused on start. - unawaited(device!.dds.maybeCallDevToolsUriServiceExtension( - device: this, - uri: debuggingOptions.devToolsServerAddress, - )); - } - */ (await device!.getLogReader(app: package)).connectedVMService = vmService; completer.complete(); await subscription.cancel(); @@ -480,6 +472,7 @@ class FlutterDevice { platformArgs: platformArgs, route: route, prebuiltApplication: prebuiltMode, + ipv6: hotRunner.ipv6!, userIdentifier: userIdentifier, ); @@ -545,6 +538,7 @@ class FlutterDevice { platformArgs: platformArgs, route: route, prebuiltApplication: prebuiltMode, + ipv6: coldRunner.ipv6!, userIdentifier: userIdentifier, ); @@ -616,13 +610,6 @@ class FlutterDevice { await generator?.reject(); } } - - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - /* - Future handleHotRestart() async { - await device?.dds.handleHotRestart(this); - } - */ } /// A subset of the [ResidentRunner] for delegating to attached flutter devices. @@ -661,7 +648,6 @@ abstract class ResidentHandlers { /// Whether all of the connected devices support hot reload. bool get canHotReload; - // TODO(bkonyi): remove when ready to serve DevTools from DDS. ResidentDevtoolsHandler? get residentDevtoolsHandler; @protected @@ -1110,6 +1096,7 @@ abstract class ResidentRunner extends ResidentHandlers { required this.target, required this.debuggingOptions, String? projectRootPath, + this.ipv6, this.stayResident = true, this.hotMode = true, String? dillOutputPath, @@ -1132,7 +1119,6 @@ abstract class ResidentRunner extends ResidentHandlers { if (!artifactDirectory.existsSync()) { artifactDirectory.createSync(recursive: true); } - // TODO(bkonyi): remove when ready to serve DevTools from DDS. _residentDevtoolsHandler = devtoolsHandler(DevtoolsLauncher.instance, this, globals.logger); } @@ -1150,6 +1136,7 @@ abstract class ResidentRunner extends ResidentHandlers { @override final bool stayResident; + final bool? ipv6; final String? _dillOutputPath; /// The parent location of the incremental artifacts. final Directory artifactDirectory; @@ -1161,7 +1148,6 @@ abstract class ResidentRunner extends ResidentHandlers { final CommandHelp commandHelp; final bool machine; - // TODO(bkonyi): remove when ready to serve DevTools from DDS. @override ResidentDevtoolsHandler? get residentDevtoolsHandler => _residentDevtoolsHandler; ResidentDevtoolsHandler? _residentDevtoolsHandler; @@ -1242,6 +1228,7 @@ abstract class ResidentRunner extends ResidentHandlers { Future run({ Completer? connectionInfoCompleter, Completer? appStartedCompleter, + bool enableDevTools = false, String? route, }); @@ -1253,6 +1240,7 @@ abstract class ResidentRunner extends ResidentHandlers { Completer? connectionInfoCompleter, Completer? appStartedCompleter, bool allowExistingDdsInstance = false, + bool enableDevTools = false, bool needsFullRestart = true, }); @@ -1318,21 +1306,19 @@ abstract class ResidentRunner extends ResidentHandlers { @override Future exit() async { _exited = true; - // TODO(bkonyi): remove when ready to serve DevTools from DDS. await residentDevtoolsHandler!.shutdown(); await stopEchoingDeviceLog(); await preExit(); await exitApp(); // calls appFinished - shutdownDartDevelopmentService(); + await shutdownDartDevelopmentService(); } @override Future detach() async { - // TODO(bkonyi): remove when ready to serve DevTools from DDS. await residentDevtoolsHandler!.shutdown(); await stopEchoingDeviceLog(); await preExit(); - shutdownDartDevelopmentService(); + await shutdownDartDevelopmentService(); appFinished(); } @@ -1342,10 +1328,12 @@ abstract class ResidentRunner extends ResidentHandlers { ); } - void shutdownDartDevelopmentService() { - for (final FlutterDevice device in flutterDevices) { - device.device?.dds.shutdown(); - } + Future shutdownDartDevelopmentService() async { + await Future.wait( + flutterDevices.map>( + (FlutterDevice? device) => device?.device?.dds.shutdown() ?? Future.value() + ) + ); } @protected @@ -1414,14 +1402,18 @@ abstract class ResidentRunner extends ResidentHandlers { // Listen for service protocol connection to close. for (final FlutterDevice? device in flutterDevices) { await device!.connect( - debuggingOptions: debuggingOptions, reloadSources: reloadSources, restart: restart, compileExpression: compileExpression, + enableDds: debuggingOptions.enableDds, + ddsPort: debuggingOptions.ddsPort, allowExistingDdsInstance: allowExistingDdsInstance, hostVmServicePort: debuggingOptions.hostVmServicePort, getSkSLMethod: getSkSLMethod, printStructuredErrorLogMethod: printStructuredErrorLog, + ipv6: ipv6 ?? false, + disableServiceAuthCodes: debuggingOptions.disableServiceAuthCodes, + cacheStartupProfile: debuggingOptions.cacheStartupProfile, ); await device.vmService!.getFlutterViews(); @@ -1511,8 +1503,7 @@ abstract class ResidentRunner extends ResidentHandlers { bool get reportedDebuggers => _reportedDebuggers; bool _reportedDebuggers = false; - void printDebuggerList({bool includeVmService = true, bool includeDevtools = true}) { - // TODO(bkonyi): update this logic when ready to serve DevTools from DDS. + void printDebuggerList({ bool includeVmService = true, bool includeDevtools = true }) { final DevToolsServerAddress? devToolsServerAddress = residentDevtoolsHandler!.activeDevToolsServer; if (!residentDevtoolsHandler!.readyToAnnounce) { includeDevtools = false; @@ -1825,13 +1816,6 @@ class TerminalHandler { case 'v': case 'V': return residentRunner.residentDevtoolsHandler!.launchDevToolsInBrowser(flutterDevices: residentRunner.flutterDevices); - // TODO(bkonyi): uncomment and replace above line when ready to serve DevTools from DDS. - /* - return residentRunner.flutterDevices.fold( - true, - (bool s, FlutterDevice? device) => s && device!.device!.dds.launchDevToolsInBrowser(device), - ); - */ case 'w': case 'W': return residentRunner.debugDumpApp(); @@ -1972,7 +1956,6 @@ abstract class DevtoolsLauncher { @protected set dtdUri(Uri? value) => _dtdUri = value; - // TODO(bkonyi): remove when ready to serve DevTools from DDS. /// Whether to print the Dart Tooling Daemon URI. /// /// This will always return false when there is not a DTD instance being diff --git a/packages/flutter_tools/lib/src/run_cold.dart b/packages/flutter_tools/lib/src/run_cold.dart index 0302f32fc2d6..63ac8dc2d77a 100644 --- a/packages/flutter_tools/lib/src/run_cold.dart +++ b/packages/flutter_tools/lib/src/run_cold.dart @@ -21,6 +21,7 @@ class ColdRunner extends ResidentRunner { this.traceStartup = false, this.awaitFirstFrameWhenTracing = true, this.applicationBinary, + bool super.ipv6 = false, super.stayResident, super.machine, super.devtoolsHandler, @@ -46,6 +47,7 @@ class ColdRunner extends ResidentRunner { Future run({ Completer? connectionInfoCompleter, Completer? appStartedCompleter, + bool enableDevTools = false, String? route, }) async { try { @@ -76,18 +78,18 @@ class ColdRunner extends ResidentRunner { } } - if (debuggingEnabled && debuggingOptions.serveObservatory) { - await enableObservatory(); - } - - // TODO(bkonyi): remove when ready to serve DevTools from DDS. - if (debuggingEnabled && debuggingOptions.enableDevTools) { - // The method below is guaranteed never to return a failing future. - unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools( - devToolsServerAddress: debuggingOptions.devToolsServerAddress, - flutterDevices: flutterDevices, - isStartPaused: debuggingOptions.startPaused, - )); + if (debuggingEnabled) { + if (enableDevTools) { + // The method below is guaranteed never to return a failing future. + unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools( + devToolsServerAddress: debuggingOptions.devToolsServerAddress, + flutterDevices: flutterDevices, + isStartPaused: debuggingOptions.startPaused, + )); + } + if (debuggingOptions.serveObservatory) { + await enableObservatory(); + } } if (flutterDevices.first.vmServiceUris != null) { @@ -140,6 +142,7 @@ class ColdRunner extends ResidentRunner { Completer? connectionInfoCompleter, Completer? appStartedCompleter, bool allowExistingDdsInstance = false, + bool enableDevTools = false, bool needsFullRestart = true, }) async { _didAttach = true; @@ -163,8 +166,18 @@ class ColdRunner extends ResidentRunner { } } - if (debuggingEnabled && debuggingOptions.serveObservatory) { - await enableObservatory(); + if (debuggingEnabled) { + if (enableDevTools) { + // The method below is guaranteed never to return a failing future. + unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools( + devToolsServerAddress: debuggingOptions.devToolsServerAddress, + flutterDevices: flutterDevices, + isStartPaused: debuggingOptions.startPaused, + )); + } + if (debuggingOptions.serveObservatory) { + await enableObservatory(); + } } appStartedCompleter?.complete(); @@ -190,11 +203,12 @@ class ColdRunner extends ResidentRunner { await flutterDevice!.device!.dispose(); } + await residentDevtoolsHandler!.shutdown(); await stopEchoingDeviceLog(); } @override - void printHelp({required bool details}) { + void printHelp({ required bool details }) { globals.printStatus('Flutter run key commands.'); if (details) { printHelpDetails(); diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index 2684e093b560..d79a01daacea 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -86,6 +86,7 @@ class HotRunner extends ResidentRunner { super.projectRootPath, super.dillOutputPath, super.stayResident, + bool super.ipv6 = false, super.machine, super.devtoolsHandler, StopwatchFactory stopwatchFactory = const StopwatchFactory(), @@ -227,6 +228,7 @@ class HotRunner extends ResidentRunner { Completer? connectionInfoCompleter, Completer? appStartedCompleter, bool allowExistingDdsInstance = false, + bool enableDevTools = false, bool needsFullRestart = true, }) async { _didAttach = true; @@ -251,8 +253,7 @@ class HotRunner extends ResidentRunner { await enableObservatory(); } - // TODO(bkonyi): remove when ready to serve DevTools from DDS. - if (debuggingOptions.enableDevTools) { + if (enableDevTools) { // The method below is guaranteed never to return a failing future. unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools( devToolsServerAddress: debuggingOptions.devToolsServerAddress, @@ -361,6 +362,7 @@ class HotRunner extends ResidentRunner { Future run({ Completer? connectionInfoCompleter, Completer? appStartedCompleter, + bool enableDevTools = false, String? route, }) async { await _calculateTargetPlatform(); @@ -468,6 +470,7 @@ class HotRunner extends ResidentRunner { return attach( connectionInfoCompleter: connectionInfoCompleter, appStartedCompleter: appStartedCompleter, + enableDevTools: enableDevTools, needsFullRestart: false, ); } @@ -787,11 +790,7 @@ class HotRunner extends ResidentRunner { if (!silent) { globals.printStatus('Restarted application in ${getElapsedAsMilliseconds(timer.elapsed)}.'); } - // TODO(bkonyi): remove when ready to serve DevTools from DDS. unawaited(residentDevtoolsHandler!.hotRestart(flutterDevices)); - // for (final FlutterDevice? device in flutterDevices) { - // unawaited(device?.handleHotRestart()); - // } return result; } final OperationResult result = await _hotReloadHelper( diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index 8fa6f854291f..e4e474ab6e8e 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -489,7 +489,7 @@ abstract class FlutterCommand extends Command { defaultsTo: true, help: 'Enable (or disable, with "--no-$kEnableDevTools") the launching of the ' 'Flutter DevTools debugger and profiler. ' - 'If "--no-$kEnableDevTools" is specified, "--$kDevToolsServerAddress" is ignored.' + 'If specified, "--$kDevToolsServerAddress" is ignored.' ); argParser.addOption( kDevToolsServerAddress, diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart index 798e129794f2..50783f843510 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart @@ -414,7 +414,6 @@ class FlutterCommandRunner extends CommandRunner { throwToolExit('The "--machine" flag is only valid with the "--version" flag or the "analyze --suggestions" command.', exitCode: 2); } - // TODO(bkonyi): can this be removed and passed solely via DebuggingOptions? final bool shouldPrintDtdUri = topLevelResults[FlutterGlobalOptions.kPrintDtd] as bool? ?? false; DevtoolsLauncher.instance!.printDtdUri = shouldPrintDtdUri; diff --git a/packages/flutter_tools/lib/src/test/flutter_platform.dart b/packages/flutter_tools/lib/src/test/flutter_platform.dart index 3cd32358cc4e..68648b352539 100644 --- a/packages/flutter_tools/lib/src/test/flutter_platform.dart +++ b/packages/flutter_tools/lib/src/test/flutter_platform.dart @@ -6,6 +6,7 @@ import 'dart:async'; +import 'package:dds/dds.dart'; import 'package:meta/meta.dart'; import 'package:package_config/package_config.dart'; import 'package:stream_channel/stream_channel.dart'; @@ -69,6 +70,7 @@ FlutterPlatform installHook({ Device? integrationTestDevice, String? integrationTestUserIdentifier, TestTimeRecorder? testTimeRecorder, + UriConverter? uriConverter, TestCompilerNativeAssetsBuilder? nativeAssetsBuilder, BuildInfo? buildInfo, }) { @@ -100,6 +102,7 @@ FlutterPlatform installHook({ integrationTestDevice: integrationTestDevice, integrationTestUserIdentifier: integrationTestUserIdentifier, testTimeRecorder: testTimeRecorder, + uriConverter: uriConverter, nativeAssetsBuilder: nativeAssetsBuilder, buildInfo: buildInfo, ); @@ -306,6 +309,7 @@ class FlutterPlatform extends PlatformPlugin { this.integrationTestDevice, this.integrationTestUserIdentifier, this.testTimeRecorder, + this.uriConverter, this.nativeAssetsBuilder, this.buildInfo, }); @@ -327,6 +331,9 @@ class FlutterPlatform extends PlatformPlugin { final TestCompilerNativeAssetsBuilder? nativeAssetsBuilder; final BuildInfo? buildInfo; + // This can be used by internal projects that require custom logic for converting package: URIs to local paths. + final UriConverter? uriConverter; + /// The device to run the test on for Integration Tests. /// /// If this is null, the test will run as a regular test with the Flutter @@ -455,6 +462,7 @@ class FlutterPlatform extends PlatformPlugin { icudtlPath: icudtlPath, compileExpression: _compileExpressionService, fontConfigManager: _fontConfigManager, + uriConverter: uriConverter, ); } diff --git a/packages/flutter_tools/lib/src/test/flutter_tester_device.dart b/packages/flutter_tools/lib/src/test/flutter_tester_device.dart index 5e3f2a291b3d..e019556ee623 100644 --- a/packages/flutter_tools/lib/src/test/flutter_tester_device.dart +++ b/packages/flutter_tools/lib/src/test/flutter_tester_device.dart @@ -5,12 +5,12 @@ import 'dart:async'; import 'dart:io' as io; // flutter_ignore: dart_io_import; +import 'package:dds/dds.dart'; import 'package:meta/meta.dart'; import 'package:process/process.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:vm_service/vm_service.dart' as vm_service; -import '../base/dds.dart'; import '../base/file_system.dart'; import '../base/io.dart'; import '../base/logger.dart'; @@ -43,6 +43,7 @@ class FlutterTesterTestDevice extends TestDevice { required this.icudtlPath, required this.compileExpression, required this.fontConfigManager, + required this.uriConverter, }) : assert(!debuggingOptions.startPaused || enableVmService), _gotProcessVmServiceUri = enableVmService ? Completer() : (Completer()..complete()); @@ -63,8 +64,8 @@ class FlutterTesterTestDevice extends TestDevice { final String? icudtlPath; final CompileExpression? compileExpression; final FontConfigManager fontConfigManager; + final UriConverter? uriConverter; - late final DartDevelopmentService _ddsLauncher = DartDevelopmentService(logger: logger); final Completer _gotProcessVmServiceUri; final Completer _exitCode = Completer(); @@ -169,20 +170,16 @@ class FlutterTesterTestDevice extends TestDevice { debuggingOptions.hostVmServicePort == detectedUri.port); Uri? forwardingUri; - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // Uri? devToolsUri; + DartDevelopmentService? dds; if (debuggingOptions.enableDds) { logger.printTrace('test $id: Starting Dart Development Service'); - - await _ddsLauncher.startDartDevelopmentServiceFromDebuggingOptions( + dds = await startDds( detectedUri, - debuggingOptions: debuggingOptions, + uriConverter: uriConverter, ); - forwardingUri = _ddsLauncher.uri; - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // devToolsUri = _ddsLauncher.devToolsUri; - logger.printTrace('test $id: Dart Development Service started at $forwardingUri, forwarding to VM service at $detectedUri.'); + forwardingUri = dds.uri; + logger.printTrace('test $id: Dart Development Service started at ${dds.uri}, forwarding to VM service at ${dds.remoteVmServiceUri}.'); } else { forwardingUri = detectedUri; } @@ -204,11 +201,7 @@ class FlutterTesterTestDevice extends TestDevice { if (debuggingOptions.startPaused && !machine!) { logger.printStatus('The Dart VM service is listening on $forwardingUri'); - await _startDevTools(forwardingUri, _ddsLauncher); - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // if (devToolsUri != null) { - // logger.printStatus('The Flutter DevTools debugger and profiler is available at: $devToolsUri'); - // } + await _startDevTools(forwardingUri, dds); logger.printStatus(''); logger.printStatus('The test process has been started. Set any relevant breakpoints and then resume the test in the debugger.'); } @@ -255,6 +248,28 @@ class FlutterTesterTestDevice extends TestDevice { throw TestDeviceException(_getExitCodeMessage(exitCode), StackTrace.current); } + Uri get _ddsServiceUri { + return Uri( + scheme: 'http', + host: (host!.type == InternetAddressType.IPv6 ? + InternetAddress.loopbackIPv6 : + InternetAddress.loopbackIPv4 + ).host, + port: debuggingOptions.hostVmServicePort ?? 0, + ); + } + + @visibleForTesting + @protected + Future startDds(Uri uri, {UriConverter? uriConverter}) { + return DartDevelopmentService.startDartDevelopmentService( + uri, + serviceUri: _ddsServiceUri, + enableAuthCodes: !debuggingOptions.disableServiceAuthCodes, + ipv6: host!.type == InternetAddressType.IPv6, + uriConverter: uriConverter, + ); + } @visibleForTesting @protected @@ -270,7 +285,6 @@ class FlutterTesterTestDevice extends TestDevice { ); } - // TODO(bkonyi): remove when ready to serve DevTools from DDS. Future _startDevTools(Uri forwardingUri, DartDevelopmentService? dds) async { _devToolsLauncher = DevtoolsLauncher.instance; logger.printTrace('test $id: Serving DevTools...'); @@ -283,6 +297,10 @@ class FlutterTesterTestDevice extends TestDevice { await _devToolsLauncher?.ready; logger.printTrace('test $id: DevTools is being served at ${devToolsServerAddress.uri}'); + // Notify the DDS instance that there's a DevTools instance available so it can correctly + // redirect DevTools related requests. + dds?.setExternalDevToolsUri(devToolsServerAddress.uri!); + final Uri devToolsUri = devToolsServerAddress.uri!.replace( // Use query instead of queryParameters to avoid unnecessary encoding. query: 'uri=$forwardingUri', diff --git a/packages/flutter_tools/lib/src/test/runner.dart b/packages/flutter_tools/lib/src/test/runner.dart index 7bbadbb9185d..fa0aff896942 100644 --- a/packages/flutter_tools/lib/src/test/runner.dart +++ b/packages/flutter_tools/lib/src/test/runner.dart @@ -40,6 +40,7 @@ abstract class FlutterTestRunner { String? tags, String? excludeTags, bool enableVmService = false, + bool ipv6 = false, bool machine = false, String? precompiledDillPath, Map? precompiledDillFiles, @@ -107,6 +108,7 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner { String? tags, String? excludeTags, bool enableVmService = false, + bool ipv6 = false, bool machine = false, String? precompiledDillPath, Map? precompiledDillFiles, @@ -237,7 +239,7 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner { ..addAll(testFiles.map((Uri uri) => uri.toString())); final InternetAddressType serverType = - debuggingOptions.ipv6 ? InternetAddressType.IPv6 : InternetAddressType.IPv4; + ipv6 ? InternetAddressType.IPv6 : InternetAddressType.IPv4; final loader.FlutterPlatform platform = loader.installHook( testWrapper: testWrapper, diff --git a/packages/flutter_tools/lib/src/tester/flutter_tester.dart b/packages/flutter_tools/lib/src/tester/flutter_tester.dart index 40d83e79abe9..8c895e4aed56 100644 --- a/packages/flutter_tools/lib/src/tester/flutter_tester.dart +++ b/packages/flutter_tools/lib/src/tester/flutter_tester.dart @@ -46,7 +46,7 @@ class FlutterTesterDevice extends Device { FlutterTesterDevice(super.id, { required ProcessManager processManager, required FlutterVersion flutterVersion, - required super.logger, + required Logger logger, required FileSystem fileSystem, required Artifacts artifacts, }) : _processManager = processManager, @@ -135,6 +135,7 @@ class FlutterTesterDevice extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, + bool ipv6 = false, String? userIdentifier, }) async { final BuildInfo buildInfo = debuggingOptions.buildInfo; @@ -192,7 +193,7 @@ class FlutterTesterDevice extends Device { getLogReader(), hostPort: debuggingOptions.hostVmServicePort, devicePort: debuggingOptions.deviceVmServicePort, - ipv6: debuggingOptions.ipv6, + ipv6: ipv6, logger: _logger, ); _logReader.initializeProcess(_process!); diff --git a/packages/flutter_tools/lib/src/web/web_device.dart b/packages/flutter_tools/lib/src/web/web_device.dart index ef729796b484..8969fa50ea8d 100644 --- a/packages/flutter_tools/lib/src/web/web_device.dart +++ b/packages/flutter_tools/lib/src/web/web_device.dart @@ -38,7 +38,7 @@ abstract class ChromiumDevice extends Device { required String name, required this.chromeLauncher, required FileSystem fileSystem, - required super.logger, + required Logger logger, }) : _fileSystem = fileSystem, _logger = logger, super( @@ -124,6 +124,7 @@ abstract class ChromiumDevice extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, + bool ipv6 = false, String? userIdentifier, }) async { // See [ResidentWebRunner.run] in flutter_tools/lib/src/resident_web_runner.dart @@ -381,7 +382,7 @@ String parseVersionForWindows(String input) { /// A special device type to allow serving for arbitrary browsers. class WebServerDevice extends Device { WebServerDevice({ - required super.logger, + required Logger logger, }) : _logger = logger, super( 'web-server', @@ -459,6 +460,7 @@ class WebServerDevice extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, + bool ipv6 = false, String? userIdentifier, }) async { final String? url = platformArgs['uri'] as String?; diff --git a/packages/flutter_tools/lib/src/web/web_runner.dart b/packages/flutter_tools/lib/src/web/web_runner.dart index af7424a3b71e..475a3ef5fc60 100644 --- a/packages/flutter_tools/lib/src/web/web_runner.dart +++ b/packages/flutter_tools/lib/src/web/web_runner.dart @@ -26,6 +26,7 @@ abstract class WebRunnerFactory { String? target, required bool stayResident, required FlutterProject flutterProject, + required bool? ipv6, required DebuggingOptions debuggingOptions, UrlTunneller? urlTunneller, required Logger logger, diff --git a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart index 33e241492264..dfd23e70cde2 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart @@ -73,7 +73,7 @@ void main() { artifacts = Artifacts.test(fileSystem: testFileSystem); stdio = FakeStdio(); terminal = FakeTerminal(); - signals = FakeSignals(); + signals = Signals.test(); processInfo = FakeProcessInfo(); testDeviceManager = TestDeviceManager(logger: logger); }); @@ -802,13 +802,6 @@ void main() { ProcessManager: () => FakeProcessManager.any(), Logger: () => logger, DeviceManager: () => testDeviceManager, - MDnsVmServiceDiscovery: () => MDnsVmServiceDiscovery( - mdnsClient: FakeMDnsClient([], >{}), - preliminaryMDnsClient: FakeMDnsClient([], >{}), - logger: logger, - flutterUsage: TestUsage(), - analytics: const NoOpAnalytics(), - ), }); testUsingContext('exits when vm-service-port is specified and debug-port is not', () async { @@ -1401,14 +1394,11 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService @override Future startDartDevelopmentService( Uri vmServiceUri, { - int? ddsPort, - FlutterDevice? device, + required Logger logger, + int? hostPort, bool? ipv6, bool? disableServiceAuthCodes, - bool enableDevTools = false, bool cacheStartupProfile = false, - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, }) async {} @override diff --git a/packages/flutter_tools/test/commands.shard/hermetic/daemon_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/daemon_test.dart index 42ef168caacd..d930dfe674ab 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/daemon_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/daemon_test.dart @@ -695,22 +695,17 @@ void main() { 'deviceId': 'device', 'disableServiceAuthCodes': false, 'vmServiceUri': 'http://fake_uri/auth_code', - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // 'enableDevTools': true, }, })); final Stream broadcastOutput = daemonStreams.outputs.stream.asBroadcastStream(); final DaemonMessage startResponse = await broadcastOutput.firstWhere(_notEvent); expect(startResponse.data['id'], 0); expect(startResponse.data['error'], isNull); - final Map? result = startResponse.data['result'] as Map?; - final String? ddsUri = result!['ddsUri'] as String?; + final String? ddsUri = startResponse.data['result'] as String?; expect(ddsUri, fakeDdsUri.toString()); expect(device.dds.startCalled, true); expect(device.dds.startDisableServiceAuthCodes, false); expect(device.dds.startVMServiceUri, Uri.parse('http://fake_uri/auth_code')); - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // expect(device.dds.enableDevTools, true); // dds.done event should be sent to the client. ddsDoneCompleter.complete(); @@ -1241,8 +1236,6 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService bool? startDisableServiceAuthCodes; bool shutdownCalled = false; - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // bool enableDevTools = false; @override late Future done; @@ -1250,32 +1243,18 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService @override Uri? uri; - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - /* - @override - Uri? devToolsUri; - - @override - Uri? dtdUri; - */ - @override Future startDartDevelopmentService( Uri vmServiceUri, { - int? ddsPort, - FlutterDevice? device, + required Logger logger, + int? hostPort, bool? ipv6, bool? disableServiceAuthCodes, - bool enableDevTools = false, bool cacheStartupProfile = false, - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, }) async { startCalled = true; startVMServiceUri = vmServiceUri; startDisableServiceAuthCodes = disableServiceAuthCodes; - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // this.enableDevTools = enableDevTools; } @override diff --git a/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart index e0517d855cb6..50ffec8db54f 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/drive_test.dart @@ -640,7 +640,7 @@ class NeverEndingDriverService extends Fake implements DriverService { final void Function() callback; @override - Future reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions) async { } + Future reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions, bool ipv6) async { } @override Future startTest( @@ -670,7 +670,7 @@ class FailingFakeFlutterDriverFactory extends Fake implements FlutterDriverFacto class FailingFakeDriverService extends Fake implements DriverService { @override - Future reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions) async { } + Future reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions, bool ipv6) async { } @override Future startTest( diff --git a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart index b9550ecd97c1..509ea1efc705 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart @@ -1544,13 +1544,16 @@ class CapturingAppDomain extends AppDomain { String? projectRootPath, String? packagesFilePath, String? dillOutputPath, + bool ipv6 = false, String? isolateFilter, bool machine = true, String? userIdentifier, - required HotRunnerNativeAssetsBuilder? nativeAssetsBuilder, + bool enableDevTools = true, + String? flavor, + HotRunnerNativeAssetsBuilder? nativeAssetsBuilder, }) async { this.userIdentifier = userIdentifier; - enableDevTools = options.enableDevTools; + this.enableDevTools = enableDevTools; throwToolExit(''); } } diff --git a/packages/flutter_tools/test/general.shard/cold_test.dart b/packages/flutter_tools/test/general.shard/cold_test.dart index 4ef1666aed44..e16015ee4cba 100644 --- a/packages/flutter_tools/test/general.shard/cold_test.dart +++ b/packages/flutter_tools/test/general.shard/cold_test.dart @@ -213,9 +213,13 @@ class TestFlutterDevice extends FlutterDevice { GetSkSLMethod? getSkSLMethod, FlutterProject? flutterProject, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, - required DebuggingOptions debuggingOptions, + bool enableDds = true, + bool cacheStartupProfile = false, + bool disableServiceAuthCodes = false, int? hostVmServicePort, - required bool allowExistingDdsInstance, + int? ddsPort, + bool? ipv6 = false, + bool allowExistingDdsInstance = false, }) async { throw exception; } diff --git a/packages/flutter_tools/test/general.shard/device_test.dart b/packages/flutter_tools/test/general.shard/device_test.dart index 8f7bf361937d..c1a62a17cac1 100644 --- a/packages/flutter_tools/test/general.shard/device_test.dart +++ b/packages/flutter_tools/test/general.shard/device_test.dart @@ -932,13 +932,13 @@ void main() { testWithoutContext('Get launch arguments for physical device with iPv6 network connection', () { final DebuggingOptions original = DebuggingOptions.enabled( BuildInfo.debug, - ipv6: true, ); final List launchArguments = original.getIOSLaunchArguments( EnvironmentType.physical, null, {}, + ipv6: true, interfaceType: DeviceConnectionInterface.wireless, ); diff --git a/packages/flutter_tools/test/general.shard/devtools_launcher_test.dart b/packages/flutter_tools/test/general.shard/devtools_launcher_test.dart index 50e560c16aa5..2952af5378dc 100644 --- a/packages/flutter_tools/test/general.shard/devtools_launcher_test.dart +++ b/packages/flutter_tools/test/general.shard/devtools_launcher_test.dart @@ -33,8 +33,6 @@ void main() { 'Artifact.engineDartBinary', 'devtools', '--no-launch-browser', - // TODO(bkonyi): does this need to be removed? - // '--print-dtd', ], stdout: 'Serving DevTools at http://127.0.0.1:9100.\n', completer: completer, @@ -51,7 +49,6 @@ void main() { expect(launcher.printDtdUri, false); }); - // TODO(bkonyi): this test can be removed when DevTools is served from DDS. testWithoutContext('DevtoolsLauncher saves the Dart Tooling Daemon uri', () async { final (BufferLogger logger, Artifacts artifacts) = getTestState(); final Completer completer = Completer(); @@ -98,7 +95,6 @@ Serving DevTools at http://127.0.0.1:9100. 'Artifact.engineDartBinary', 'devtools', '--no-launch-browser', - // '--print-dtd', ], stdout: 'Serving DevTools at http://127.0.0.1:9100.\n', completer: completer, @@ -124,7 +120,6 @@ Serving DevTools at http://127.0.0.1:9100. 'Artifact.engineDartBinary', 'devtools', '--no-launch-browser', - // '--print-dtd', '--vm-uri=localhost:8181/abcdefg', '--profile-memory=foo', ], @@ -156,7 +151,6 @@ Serving DevTools at http://127.0.0.1:9100. 'Artifact.engineDartBinary', 'devtools', '--no-launch-browser', - // '--print-dtd', '--vm-uri=http://127.0.0.1:1234/abcdefg', ], exception: ProcessException('pub', []), @@ -182,7 +176,6 @@ Serving DevTools at http://127.0.0.1:9100. 'Artifact.engineDartBinary', 'devtools', '--no-launch-browser', - // '--print-dtd', ], stdout: 'Serving DevTools at http://127.0.0.1:9100.\n', completer: completer, diff --git a/packages/flutter_tools/test/general.shard/drive/drive_service_test.dart b/packages/flutter_tools/test/general.shard/drive/drive_service_test.dart index a461db64318f..c2c114cbb92f 100644 --- a/packages/flutter_tools/test/general.shard/drive/drive_service_test.dart +++ b/packages/flutter_tools/test/general.shard/drive/drive_service_test.dart @@ -93,7 +93,7 @@ void main() { final Device device = FakeDevice(LaunchResult.failed()); expect( - () => driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)), + () => driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true), throwsToolExit(message: 'Application failed to start. Will not run test. Quitting.'), ); }); @@ -118,7 +118,7 @@ void main() { ))..failOnce = true; await expectLater( - () async => driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)), + () async => driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true), returnsNormally, ); }); @@ -142,7 +142,7 @@ void main() { vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), )); - await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)); + await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true); final int testResult = await driverService.startTest( 'foo.test', ['--enable-experiment=non-nullable'], @@ -173,7 +173,7 @@ void main() { vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), )); - await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)); + await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true); final int testResult = await driverService.startTest( 'foo.test', ['--enable-experiment=non-nullable'], @@ -205,7 +205,7 @@ void main() { vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), )); - await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)); + await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true); final int testResult = await driverService.startTest( 'foo.test', ['--enable-experiment=non-nullable'], @@ -237,7 +237,7 @@ void main() { final FakeDartDevelopmentService dds = device.dds as FakeDartDevelopmentService; expect(dds.started, false); - await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, enableDds: false, ipv6: true)); + await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, enableDds: false), true); expect(dds.started, false); final int testResult = await driverService.startTest( @@ -261,7 +261,7 @@ void main() { vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), )); - await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)); + await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true); await driverService.stop(); expect(device.didStopApp, true); @@ -293,7 +293,7 @@ void main() { vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), )); - await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)); + await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true); await driverService.stop(writeSkslOnExit: fileSystem.file('out.json')); expect(device.didStopApp, true); @@ -327,6 +327,7 @@ void main() { Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), device, DebuggingOptions.enabled(BuildInfo.debug), + false, ); await driverService.stop(); }); @@ -350,6 +351,7 @@ void main() { Uri.parse('ws://127.0.0.1:63426/1UasC_ihpXY=/ws/'), device, DebuggingOptions.enabled(BuildInfo.debug), + false, ); await driverService.stop(); }); @@ -373,6 +375,7 @@ void main() { Uri.parse('ws://127.0.0.1:63426/1UasC_ihpXY=/ws'), device, DebuggingOptions.enabled(BuildInfo.debug), + false, ); await driverService.stop(); }); @@ -396,6 +399,7 @@ void main() { Uri.parse('ws://127.0.0.1:63426/wsasC_ihpXY=/ws'), device, DebuggingOptions.enabled(BuildInfo.debug), + false, ); await driverService.stop(); }); @@ -412,6 +416,7 @@ void main() { Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), device, DebuggingOptions.enabled(BuildInfo.debug), + false, ); await driverService.stop(); }); @@ -535,9 +540,7 @@ class FakeDevice extends Fake implements Device { } } -class FakeDartDevelopmentService extends Fake - with DartDevelopmentServiceLocalOperationsMixin - implements DartDevelopmentService { +class FakeDartDevelopmentService extends Fake implements DartDevelopmentService { bool started = false; bool disposed = false; @@ -547,14 +550,11 @@ class FakeDartDevelopmentService extends Fake @override Future startDartDevelopmentService( Uri vmServiceUri, { - FlutterDevice? device, - int? ddsPort, + required Logger logger, + int? hostPort, bool? ipv6, bool? disableServiceAuthCodes, - bool enableDevTools = false, bool cacheStartupProfile = false, - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, }) async { started = true; } diff --git a/packages/flutter_tools/test/general.shard/drive/web_driver_service_test.dart b/packages/flutter_tools/test/general.shard/drive/web_driver_service_test.dart index 8854e2c7a628..47fd1645b723 100644 --- a/packages/flutter_tools/test/general.shard/drive/web_driver_service_test.dart +++ b/packages/flutter_tools/test/general.shard/drive/web_driver_service_test.dart @@ -248,7 +248,7 @@ void main() { testUsingContext('WebDriverService starts and stops an app', () async { final WebDriverService service = setUpDriverService(); final FakeDevice device = FakeDevice(); - await service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)); + await service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true); await service.stop(); expect(FakeResidentRunner.instance.callLog, [ 'run', @@ -263,7 +263,7 @@ void main() { final WebDriverService service = setUpDriverService(); final FakeDevice device = FakeDevice(); const String testUrl = 'http://localhost:1234/test'; - await service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, webLaunchUrl: testUrl, ipv6: true)); + await service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, webLaunchUrl: testUrl), true); await service.stop(); expect(service.webUri, Uri.parse(testUrl)); }, overrides: { @@ -275,7 +275,7 @@ void main() { final FakeDevice device = FakeDevice(); const String invalidTestUrl = '::INVALID_URL::'; await expectLater( - service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, webLaunchUrl: invalidTestUrl, ipv6: true)), + service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, webLaunchUrl: invalidTestUrl), true), throwsA(isA()), ); }, overrides: { @@ -286,7 +286,7 @@ void main() { final WebDriverService service = setUpDriverService(); final Device device = FakeDevice(); await expectLater( - service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)), + service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true), throwsA('This is a test error'), ); }, overrides: { diff --git a/packages/flutter_tools/test/general.shard/flutter_platform_test.dart b/packages/flutter_tools/test/general.shard/flutter_platform_test.dart index ed4fa844a210..60a6b1610fba 100644 --- a/packages/flutter_tools/test/general.shard/flutter_platform_test.dart +++ b/packages/flutter_tools/test/general.shard/flutter_platform_test.dart @@ -102,6 +102,7 @@ void main() { platformPluginRegistration: (FlutterPlatform platform) { capturedPlatform = platform; }, + uriConverter: (String input) => '$input/test', ); expect(identical(capturedPlatform, flutterPlatform), equals(true)); @@ -118,6 +119,7 @@ void main() { expect(flutterPlatform.updateGoldens, equals(true)); expect(flutterPlatform.testAssetDirectory, '/build/test'); expect(flutterPlatform.icudtlPath, equals('ghi')); + expect(flutterPlatform.uriConverter?.call('hello'), 'hello/test'); }); }); diff --git a/packages/flutter_tools/test/general.shard/flutter_tester_device_test.dart b/packages/flutter_tools/test/general.shard/flutter_tester_device_test.dart index 7a52bf22af04..adf6c4403767 100644 --- a/packages/flutter_tools/test/general.shard/flutter_tester_device_test.dart +++ b/packages/flutter_tools/test/general.shard/flutter_tester_device_test.dart @@ -4,8 +4,8 @@ import 'dart:async'; +import 'package:dds/dds.dart'; import 'package:file/memory.dart'; -import 'package:flutter_tools/src/base/dds.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/logger.dart'; @@ -48,6 +48,7 @@ void main() { processManager: processManager, enableVmService: enableVmService, dartEntrypointArgs: dartEntrypointArgs, + uriConverter: (String input) => '$input/converted', enableImpeller: enableImpeller, ); @@ -197,7 +198,6 @@ void main() { }); group('DDS', () { - late DDSLauncherCallback originalDdsLauncher; setUp(() { processManager = FakeProcessManager.list([ const FakeCommand( @@ -221,30 +221,26 @@ void main() { ), ]); device = createDevice(enableVmService: true); - originalDdsLauncher = ddsLauncherCallback; - ddsLauncherCallback = (Uri remoteVmServiceUri, { - required bool enableAuthCodes, - required bool ipv6, - required bool enableDevTools, - required List cachedUserTags, - Uri? serviceUri, - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, - }) async { - return (process: null, serviceUri: Uri.parse('http://localhost:1234'), devToolsUri: null, dtdUri: null); - }; }); - tearDown(() { - ddsLauncherCallback = originalDdsLauncher; + testUsingContext('skips setting VM Service port and uses the input port for DDS instead', () async { + await device.start('example.dill'); + await device.vmServiceUri; + + final Uri uri = await (device as TestFlutterTesterDevice).ddsServiceUriFuture(); + expect(uri.port, 1234); }); - testUsingContext('skips setting VM Service port and uses the input port for DDS instead', () async { + testUsingContext('sets up UriConverter from context', () async { await device.start('example.dill'); await device.vmServiceUri; - final Uri? uri = await (device as TestFlutterTesterDevice).vmServiceUri; - expect(uri!.port, 1234); + final FakeDartDevelopmentService dds = (device as TestFlutterTesterDevice).dds + as FakeDartDevelopmentService; + final String? result = dds + .uriConverter + ?.call('test'); + expect(result, 'test/converted'); }); }); } @@ -259,6 +255,7 @@ class TestFlutterTesterDevice extends FlutterTesterTestDevice { required super.processManager, required super.enableVmService, required List dartEntrypointArgs, + required UriConverter uriConverter, required bool enableImpeller, }) : super( id: 999, @@ -282,7 +279,27 @@ class TestFlutterTesterDevice extends FlutterTesterTestDevice { icudtlPath: null, compileExpression: null, fontConfigManager: FontConfigManager(), + uriConverter: uriConverter, ); + late DartDevelopmentService dds; + + final Completer _ddsServiceUriCompleter = Completer(); + + Future ddsServiceUriFuture() => _ddsServiceUriCompleter.future; + + @override + Future startDds( + Uri uri, { + UriConverter? uriConverter, + }) async { + _ddsServiceUriCompleter.complete(uri); + dds = FakeDartDevelopmentService( + Uri.parse('http://localhost:${debuggingOptions.hostVmServicePort}'), + Uri.parse('http://localhost:8080'), + uriConverter: uriConverter, + ); + return dds; + } @override Future connectToVmServiceImpl( @@ -302,6 +319,18 @@ class TestFlutterTesterDevice extends FlutterTesterTestDevice { Future> get remoteChannel async => StreamChannelController().foreign; } +class FakeDartDevelopmentService extends Fake implements DartDevelopmentService { + FakeDartDevelopmentService(this.uri, this.original, {this.uriConverter}); + + final Uri original; + final UriConverter? uriConverter; + + @override + final Uri uri; + + @override + Uri get remoteVmServiceUri => original; +} class FakeHttpServer extends Fake implements HttpServer { @override int get port => 0; diff --git a/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_start_test.dart b/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_start_test.dart index 18e1a03feee9..e9e24d7b4d59 100644 --- a/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_start_test.dart +++ b/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_start_test.dart @@ -9,7 +9,6 @@ import 'package:file/memory.dart'; import 'package:flutter_tools/src/artifacts.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/io.dart'; -import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/os.dart'; import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/build_info.dart'; @@ -39,7 +38,6 @@ void main() { late FakeProcessManager fakeSuccessfulProcessManager; late FakeProcessManager fakeFailedProcessManagerForHostAddress; late File sshConfig; - final Logger logger = FakeLogger(); setUp(() { memoryFileSystem = MemoryFileSystem.test(); @@ -116,7 +114,7 @@ void main() { required BuildMode mode, }) async { const String appName = 'app_name'; - final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123', logger: logger); + final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123'); globals.fs.directory('fuchsia').createSync(recursive: true); final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync(); pubspecFile.writeAsStringSync('name: $appName'); @@ -188,7 +186,7 @@ void main() { 'start and stop prebuilt in release mode fails without session', () async { const String appName = 'app_name'; - final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123', logger: logger); + final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123'); globals.fs.directory('fuchsia').createSync(recursive: true); final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync(); pubspecFile.writeAsStringSync('name: $appName'); @@ -218,7 +216,7 @@ void main() { testUsingContext('start and stop prebuilt in release mode with session', () async { const String appName = 'app_name'; - final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123', logger: logger); + final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123'); globals.fs.directory('fuchsia').createSync(recursive: true); final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync(); pubspecFile.writeAsStringSync('name: $appName'); @@ -411,7 +409,7 @@ void main() { }); testUsingContext('fail when cant get host address', () async { - expect(() async => FuchsiaDeviceWithFakeDiscovery('123', logger: logger).hostAddress, + expect(() async => FuchsiaDeviceWithFakeDiscovery('123').hostAddress, throwsToolExit(message: 'Failed to get local address, aborting.')); }, overrides: { Artifacts: () => artifacts, @@ -481,7 +479,7 @@ Process _createFakeProcess({ } class FuchsiaDeviceWithFakeDiscovery extends FuchsiaDevice { - FuchsiaDeviceWithFakeDiscovery(super.id, {super.name = '', required super.logger}); + FuchsiaDeviceWithFakeDiscovery(super.id, {super.name = ''}); @override FuchsiaIsolateDiscoveryProtocol getIsolateDiscoveryProtocol( diff --git a/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_test.dart b/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_test.dart index 90a849b664e9..b68c2a4abeff 100644 --- a/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_test.dart +++ b/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_test.dart @@ -26,7 +26,6 @@ import 'package:flutter_tools/src/fuchsia/fuchsia_sdk.dart'; import 'package:flutter_tools/src/fuchsia/fuchsia_workflow.dart'; import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/project.dart'; -import 'package:flutter_tools/src/resident_runner.dart'; import 'package:flutter_tools/src/vmservice.dart'; import 'package:test/fake.dart'; import 'package:vm_service/vm_service.dart' as vm_service; @@ -59,7 +58,6 @@ void main() { late MemoryFileSystem memoryFileSystem; late File sshConfig; late FakeProcessManager processManager; - final Logger logger = FakeLogger(); setUp(() { memoryFileSystem = MemoryFileSystem.test(); @@ -70,7 +68,7 @@ void main() { testWithoutContext('stores the requested id and name', () { const String deviceId = 'e80::0000:a00a:f00f:2002/3'; const String name = 'halfbaked'; - final FuchsiaDevice device = FuchsiaDevice(deviceId, name: name, logger: logger); + final FuchsiaDevice device = FuchsiaDevice(deviceId, name: name); expect(device.id, deviceId); expect(device.name, name); @@ -79,7 +77,7 @@ void main() { testWithoutContext('supports all runtime modes besides jitRelease', () { const String deviceId = 'e80::0000:a00a:f00f:2002/3'; const String name = 'halfbaked'; - final FuchsiaDevice device = FuchsiaDevice(deviceId, name: name, logger: logger); + final FuchsiaDevice device = FuchsiaDevice(deviceId, name: name); expect(device.supportsRuntimeMode(BuildMode.debug), true); expect(device.supportsRuntimeMode(BuildMode.profile), true); @@ -159,7 +157,7 @@ void main() { testUsingContext('disposing device disposes the portForwarder', () async { final FakePortForwarder portForwarder = FakePortForwarder(); - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); device.portForwarder = portForwarder; await device.dispose(); @@ -167,7 +165,7 @@ void main() { }); testWithoutContext('default capabilities', () async { - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); final FlutterProject project = FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory); memoryFileSystem.directory('fuchsia').createSync(recursive: true); @@ -180,13 +178,13 @@ void main() { }); test('is ephemeral', () { - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); expect(device.ephemeral, true); }); testWithoutContext('supported for project', () async { - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); final FlutterProject project = FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory); memoryFileSystem.directory('fuchsia').createSync(recursive: true); @@ -196,7 +194,7 @@ void main() { }); testWithoutContext('not supported for project', () async { - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); final FlutterProject project = FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory); memoryFileSystem.file('pubspec.yaml').createSync(); @@ -206,7 +204,7 @@ void main() { testUsingContext('targetPlatform does not throw when sshConfig is missing', () async { - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); expect(await device.targetPlatform, TargetPlatform.fuchsia_arm64); }, overrides: { @@ -221,7 +219,7 @@ void main() { stdout: 'aarch64', )); - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); expect(await device.targetPlatform, TargetPlatform.fuchsia_arm64); }, overrides: { FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), @@ -235,7 +233,7 @@ void main() { stdout: 'x86_64', )); - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); expect(await device.targetPlatform, TargetPlatform.fuchsia_x64); }, overrides: { FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), @@ -256,7 +254,7 @@ void main() { 'fe80::8c6c:2fff:fe3d:c5e1%ethp0003 50666 fe80::5054:ff:fe63:5e7a%ethp0003 22', )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'device'); expect(await device.hostAddress, 'fe80::8c6c:2fff:fe3d:c5e1%25ethp0003'); }, overrides: { FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), @@ -277,7 +275,7 @@ void main() { exitCode: 1, )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'device'); await expectLater(() => device.hostAddress, throwsToolExit()); }, overrides: { FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), @@ -297,7 +295,7 @@ void main() { ], )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'device'); expect(() async => device.hostAddress, throwsToolExit()); }, overrides: { FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), @@ -309,7 +307,6 @@ void main() { group('displays friendly error when', () { late File artifactFile; late FakeProcessManager processManager; - final Logger logger = FakeLogger(); setUp(() { processManager = FakeProcessManager.empty(); @@ -326,7 +323,7 @@ void main() { 'find /hub -name vmservice-port' ], )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'device'); await expectLater( device.servicePorts, @@ -355,7 +352,6 @@ void main() { late FakeProcessManager processManager; late File ffx; late File sshConfig; - final Logger logger = FakeLogger(); setUp(() { processManager = FakeProcessManager.empty(); @@ -378,7 +374,7 @@ void main() { stdout: exampleUtcLogs, completer: lock, )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester'); final DeviceLogReader reader = device.getLogReader(app: FuchsiaModulePackage(name: 'example_app')); final List logLines = []; @@ -415,7 +411,7 @@ void main() { stdout: exampleUtcLogs, completer: lock, )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester'); final DeviceLogReader reader = device.getLogReader(app: FuchsiaModulePackage(name: 'example_app')); final List logLines = []; @@ -450,7 +446,7 @@ void main() { stdout: exampleUtcLogs, completer: lock, )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester'); final DeviceLogReader reader = device.getLogReader(); final List logLines = []; reader.logLines.listen((String line) { @@ -479,14 +475,13 @@ void main() { group('screenshot', () { late FakeProcessManager processManager; - final Logger logger = FakeLogger(); setUp(() { processManager = FakeProcessManager.empty(); }); testUsingContext('is supported on posix platforms', () { - final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester'); expect(device.supportsScreenshot, true); }, overrides: { Platform: () => FakePlatform(), @@ -494,7 +489,7 @@ void main() { }); testUsingContext('is not supported on Windows', () { - final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester'); expect(device.supportsScreenshot, false); }, overrides: { @@ -505,7 +500,7 @@ void main() { }); test("takeScreenshot throws if file isn't .ppm", () async { - final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester'); await expectLater( () => device.takeScreenshot(globals.fs.file('file.invalid')), throwsA(isA().having( @@ -523,7 +518,7 @@ void main() { '0.0.0.0', 'screencap > /tmp/screenshot.ppm', ], exitCode: 1, stderr: '')); - final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester'); await expectLater( () => device.takeScreenshot(globals.fs.file('file.ppm')), @@ -545,7 +540,7 @@ void main() { }); testUsingContext('takeScreenshot throws if scp failed', () async { - final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester'); processManager.addCommand(const FakeCommand( command: [ 'ssh', @@ -598,7 +593,7 @@ void main() { testUsingContext( "takeScreenshot prints error if can't delete file from device", () async { - final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester'); processManager.addCommand(const FakeCommand( command: [ 'ssh', @@ -647,7 +642,7 @@ void main() { }, testOn: 'posix'); testUsingContext('takeScreenshot returns', () async { - final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester'); processManager.addCommand(const FakeCommand( command: [ 'ssh', @@ -693,7 +688,6 @@ void main() { group('portForwarder', () { late FakeProcessManager processManager; late File sshConfig; - final Logger logger = FakeLogger(); setUp(() { processManager = FakeProcessManager.empty(); @@ -703,7 +697,7 @@ void main() { testUsingContext( '`unforward` prints stdout and stderr if ssh command failed', () async { - final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester'); processManager.addCommand(const FakeCommand( command: [ 'ssh', @@ -867,7 +861,6 @@ void main() { group('sdkNameAndVersion: ', () { late File sshConfig; late FakeProcessManager processManager; - final Logger logger = FakeLogger(); setUp(() { sshConfig = MemoryFileSystem.test().file('ssh_config') @@ -876,7 +869,7 @@ void main() { }); testUsingContext('does not throw on non-existent ssh config', () async { - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); expect(await device.sdkNameAndVersion, equals('Fuchsia')); }, overrides: { @@ -894,7 +887,7 @@ void main() { '123', 'cat /pkgfs/packages/build-info/0/data/version' ], stdout: 'version')); - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); expect(await device.sdkNameAndVersion, equals('Fuchsia version')); }, overrides: { @@ -914,7 +907,7 @@ void main() { ], exitCode: 1, )); - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); expect(await device.sdkNameAndVersion, equals('Fuchsia')); }, overrides: { @@ -934,7 +927,7 @@ void main() { 'cat /pkgfs/packages/build-info/0/data/version' ], )); - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); expect(await device.sdkNameAndVersion, equals('Fuchsia')); }, overrides: { @@ -1048,14 +1041,11 @@ class FakeDartDevelopmentService extends Fake @override Future startDartDevelopmentService( Uri vmServiceUri, { - FlutterDevice? device, - int? ddsPort, + required Logger logger, + int? hostPort, bool? ipv6, bool? disableServiceAuthCodes, bool cacheStartupProfile = false, - bool enableDevTools = false, - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, }) async {} @override diff --git a/packages/flutter_tools/test/general.shard/hot_shared.dart b/packages/flutter_tools/test/general.shard/hot_shared.dart index b0bdfe8e0003..30d2c5fc9b29 100644 --- a/packages/flutter_tools/test/general.shard/hot_shared.dart +++ b/packages/flutter_tools/test/general.shard/hot_shared.dart @@ -128,10 +128,6 @@ class FakeFlutterDevice extends Fake implements FlutterDevice { required PackageConfig packageConfig, }) => updateDevFSReportCallback(); - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // @override - // Future handleHotRestart() async {} - @override TargetPlatform? get targetPlatform => device._targetPlatform; } @@ -154,10 +150,12 @@ class TestFlutterDevice extends FlutterDevice { GetSkSLMethod? getSkSLMethod, FlutterProject? flutterProject, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, - required DebuggingOptions debuggingOptions, - int? hostVmServicePort, + bool disableServiceAuthCodes = false, + bool enableDds = true, + bool cacheStartupProfile = false, bool? ipv6 = false, - bool enableDevTools = false, + int? hostVmServicePort, + int? ddsPort, bool allowExistingDdsInstance = false, }) async { throw exception; diff --git a/packages/flutter_tools/test/general.shard/hot_test.dart b/packages/flutter_tools/test/general.shard/hot_test.dart index 469f6dc97461..35f06af00faf 100644 --- a/packages/flutter_tools/test/general.shard/hot_test.dart +++ b/packages/flutter_tools/test/general.shard/hot_test.dart @@ -137,7 +137,8 @@ void main() { ..writeAsStringSync('\n'); final FakeDevice device = FakeDevice(); final List devices = [ - FakeFlutterDevice(device), + FlutterDevice(device, generator: residentCompiler, buildInfo: BuildInfo.debug, developmentShaderCompiler: const FakeShaderCompiler()) + ..devFS = FakeDevFs(), ]; final OperationResult result = await HotRunner( devices, @@ -145,6 +146,7 @@ void main() { target: 'main.dart', devtoolsHandler: createNoOpHandler, analytics: fakeAnalytics, + ).restart(fullRestart: true); expect(result.isOk, false); expect(result.message, 'setupHotRestart failed'); diff --git a/packages/flutter_tools/test/general.shard/ios/simulators_test.dart b/packages/flutter_tools/test/general.shard/ios/simulators_test.dart index 26d82f81fdc6..1a9d5eec3fd3 100644 --- a/packages/flutter_tools/test/general.shard/ios/simulators_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/simulators_test.dart @@ -37,7 +37,6 @@ void main() { late FakePlatform osx; late FileSystemUtils fsUtils; late MemoryFileSystem fileSystem; - final Logger logger = FakeLogger(); setUp(() { osx = FakePlatform( @@ -63,7 +62,6 @@ void main() { name: 'iPhone 11', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-14-4', - logger: logger, ); final DevicePortForwarder portForwarder = simulator.portForwarder; await portForwarder.forward(123); @@ -89,7 +87,6 @@ void main() { name: 'iPhone 11', simControl: FakeSimControl(), simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-14-4', - logger: logger, ); expect(simulator.supportsRuntimeMode(BuildMode.debug), true); @@ -116,7 +113,6 @@ void main() { name: 'iPhone 11', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-14-4', - logger: logger, ); expect(simulator.logFilePath, '/foo/bar/Library/Logs/CoreSimulator/123/system.log'); }, overrides: { @@ -134,7 +130,6 @@ void main() { name: 'iPhone 11', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-14-4', - logger: logger, ); expect(simulator.logFilePath, '/baz/qux/456/system.log'); }, overrides: { @@ -159,7 +154,6 @@ void main() { name: 'iPhone SE', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simControl: simControl, - logger: logger, ); expect(await device.sdkMajorVersion, 11); @@ -171,7 +165,6 @@ void main() { name: 'iPhone SE', simulatorCategory: 'iOS 11.2', simControl: simControl, - logger: logger, ); expect(await device.sdkMajorVersion, 11); @@ -183,7 +176,6 @@ void main() { name: 'iPhone SE', simulatorCategory: 'iOS 11.2', simControl: simControl, - logger: logger, ); expect(device.category, Category.mobile); @@ -203,7 +195,6 @@ void main() { name: 'Apple TV', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.tvOS-14-5', - logger: logger, ); expect(simulator.isSupported(), false); }, overrides: { @@ -218,7 +209,6 @@ void main() { name: 'Apple Watch', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.watchOS-8-0', - logger: logger, ).isSupported(), false); }, overrides: { Platform: () => osx, @@ -232,7 +222,6 @@ void main() { name: 'iPad 2', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', - logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -246,7 +235,6 @@ void main() { name: 'iPad Retina', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', - logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -260,7 +248,6 @@ void main() { name: 'iPhone 5', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', - logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -274,7 +261,6 @@ void main() { name: 'iPhone 5s', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', - logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -288,7 +274,6 @@ void main() { name: 'iPhone SE', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', - logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -302,7 +287,6 @@ void main() { name: 'iPhone 7 Plus', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', - logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -316,7 +300,6 @@ void main() { name: 'iPhone X', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', - logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -354,7 +337,6 @@ void main() { name: 'iPhone SE', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', - logger: logger, ); final File screenshot = MemoryFileSystem.test().file('screenshot.png'); @@ -378,7 +360,6 @@ void main() { name: 'iPhone SE', simulatorCategory: 'iOS 9.3', simControl: simControl, - logger: logger, ); fakeProcessManager.addCommand(const FakeCommand(command: [ 'tail', @@ -406,7 +387,6 @@ void main() { name: 'iPhone SE', simulatorCategory: 'iOS 11.0', simControl: simControl, - logger: logger, ); const String expectedPredicate = 'eventType = logEvent AND ' 'processImagePath ENDSWITH "My Super Awesome App" AND ' @@ -441,7 +421,6 @@ void main() { name: 'iPhone SE', simulatorCategory: 'iOS 11.0', simControl: simControl, - logger: logger, ); const String expectedPredicate = 'eventType = logEvent AND ' '(senderImagePath ENDSWITH "/Flutter" OR senderImagePath ENDSWITH "/libswiftCore.dylib" OR processImageUUID == senderImageUUID) AND ' @@ -506,7 +485,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' name: 'iPhone 11', simulatorCategory: 'iOS 10.0', simControl: simControl, - logger: logger, ); final DeviceLogReader logReader = device.getLogReader( app: await BuildableIOSApp.fromProject(mockIosProject, null), @@ -542,7 +520,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' name: 'iPhone 11', simulatorCategory: 'iOS 10.3', simControl: simControl, - logger: logger, ); final DeviceLogReader logReader = device.getLogReader( app: await BuildableIOSApp.fromProject(mockIosProject, null), @@ -591,7 +568,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' name: 'iPhone 11', simulatorCategory: 'iOS 10.3', simControl: simControl, - logger: logger, ); final DeviceLogReader logReader = device.getLogReader( app: await BuildableIOSApp.fromProject(mockIosProject, null), @@ -664,7 +640,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' name: 'iPhone 11', simulatorCategory: 'iOS 11.0', simControl: simControl, - logger: logger, ); final DeviceLogReader logReader = device.getLogReader( app: await BuildableIOSApp.fromProject(mockIosProject, null), @@ -708,7 +683,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' name: 'iPhone 11', simulatorCategory: 'iOS 11.0', simControl: simControl, - logger: logger, ); final DeviceLogReader logReader = device.getLogReader( app: await BuildableIOSApp.fromProject(mockIosProject, null), @@ -850,7 +824,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' name: 'Testo', simulatorCategory: 'NaN', simControl: simControl, - logger: logger, ); expect(await iosSimulatorA.sdkMajorVersion, 11); @@ -935,7 +908,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' name: 'Testo', simulatorCategory: 'NaN', simControl: simControl, - logger: logger, ); expect(await iosSimulator.stopApp(null), isFalse); @@ -1114,7 +1086,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' name: 'iPhone SE', simulatorCategory: 'iOS 11.2', simControl: simControl, - logger: logger, ); testPlistParser.setProperty('CFBundleIdentifier', 'correct'); @@ -1144,7 +1115,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' name: 'iPhone SE', simulatorCategory: 'iOS 11.2', simControl: simControl, - logger: logger, ); final Directory mockDir = globals.fs.currentDirectory; @@ -1176,7 +1146,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' name: 'iPhone SE', simulatorCategory: 'iOS 11.2', simControl: simControl, - logger: logger, ); testPlistParser.setProperty('CFBundleIdentifier', 'correct'); @@ -1249,7 +1218,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text''' name: 'iPhone SE', simulatorCategory: 'iOS 11.2', simControl: simControl, - logger: logger, ); testPlistParser.setProperty('CFBundleIdentifier', 'correct'); @@ -1300,7 +1268,6 @@ flutter: name: 'iPhone 11', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', - logger: logger, ); expect(simulator.isSupportedForProject(flutterProject), true); }, overrides: { @@ -1321,7 +1288,6 @@ flutter: name: 'iPhone 11', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', - logger: logger, ); expect(simulator.isSupportedForProject(flutterProject), true); }, overrides: { @@ -1340,7 +1306,6 @@ flutter: name: 'iPhone 11', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', - logger: logger, ); expect(simulator.isSupportedForProject(flutterProject), false); }, overrides: { @@ -1355,7 +1320,6 @@ flutter: name: 'iPhone 11', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', - logger: logger, ); expect(simulator.createDevFSWriter(null, ''), isA()); diff --git a/packages/flutter_tools/test/general.shard/proxied_devices/proxied_devices_test.dart b/packages/flutter_tools/test/general.shard/proxied_devices/proxied_devices_test.dart index 98bfc545993b..8efd65c20387 100644 --- a/packages/flutter_tools/test/general.shard/proxied_devices/proxied_devices_test.dart +++ b/packages/flutter_tools/test/general.shard/proxied_devices/proxied_devices_test.dart @@ -17,7 +17,6 @@ import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/device_vm_service_discovery_for_attach.dart'; import 'package:flutter_tools/src/proxied_devices/devices.dart'; import 'package:flutter_tools/src/proxied_devices/file_transfer.dart'; -import 'package:flutter_tools/src/resident_runner.dart'; import 'package:test/fake.dart'; import '../../src/common.dart'; @@ -645,8 +644,9 @@ void main() { final Future startFuture = dds.startDartDevelopmentService( Uri.parse('http://127.0.0.1:100/fake'), disableServiceAuthCodes: true, - ddsPort: 150, + hostPort: 150, ipv6: false, + logger: bufferLogger, ); final DaemonMessage startMessage = await broadcastOutput.first; @@ -656,13 +656,9 @@ void main() { 'deviceId': 'test_id', 'vmServiceUri': 'http://127.0.0.1:200/fake', 'disableServiceAuthCodes': true, - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // 'enableDevTools': false, }); - serverDaemonConnection.sendResponse( startMessage.data['id']!, const { - 'ddsUri': 'http://127.0.0.1:300/remote', - }); + serverDaemonConnection.sendResponse(startMessage.data['id']!, 'http://127.0.0.1:300/remote'); await startFuture; expect(portForwarder.receivedLocalForwardedPort, 100); @@ -705,8 +701,9 @@ void main() { final Future startFuture = dds.startDartDevelopmentService( Uri.parse('http://127.0.0.1:100/fake'), disableServiceAuthCodes: true, - ddsPort: 150, + hostPort: 150, ipv6: false, + logger: bufferLogger, ); final DaemonMessage startMessage = await broadcastOutput.first; @@ -716,13 +713,9 @@ void main() { 'deviceId': 'test_id', 'vmServiceUri': 'http://127.0.0.1:200/fake', 'disableServiceAuthCodes': true, - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // 'enableDevTools': false, }); - serverDaemonConnection.sendResponse(startMessage.data['id']!, { - 'ddsUri': 'http://127.0.0.1:300/remote', - }); + serverDaemonConnection.sendResponse(startMessage.data['id']!, 'http://127.0.0.1:300/remote'); await startFuture; expect(portForwarder.receivedLocalForwardedPort, 100); @@ -765,8 +758,9 @@ void main() { await dds.startDartDevelopmentService( Uri.parse('http://127.0.0.1:100/fake'), disableServiceAuthCodes: true, - ddsPort: 150, + hostPort: 150, ipv6: false, + logger: bufferLogger, ); expect(localDds.startCalled, true); @@ -803,8 +797,9 @@ void main() { final Future startFuture = dds.startDartDevelopmentService( Uri.parse('http://127.0.0.1:100/fake'), disableServiceAuthCodes: true, - ddsPort: 150, + hostPort: 150, ipv6: false, + logger: bufferLogger, ); expect(localDds.startCalled, false); @@ -815,8 +810,6 @@ void main() { 'deviceId': 'test_id', 'vmServiceUri': 'http://127.0.0.1:200/fake', 'disableServiceAuthCodes': true, - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // 'enableDevTools': false, }); serverDaemonConnection.sendErrorResponse(startMessage.data['id']!, 'command not understood: device.startDartDevelopmentService', StackTrace.current); @@ -1185,14 +1178,11 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService @override Future startDartDevelopmentService( Uri vmServiceUri, { - FlutterDevice? device, - int? ddsPort, + required Logger logger, + int? hostPort, bool? ipv6, bool? disableServiceAuthCodes, - bool enableDevTools = false, bool cacheStartupProfile = false, - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, }) async { startCalled = true; startUri = vmServiceUri; @@ -1200,10 +1190,6 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService @override Future shutdown() async => shutdownCalled = true; - - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // @override - // Future invokeServiceExtensions(FlutterDevice? device) async {} } class FakePrebuiltApplicationPackage extends Fake implements PrebuiltApplicationPackage { diff --git a/packages/flutter_tools/test/general.shard/resident_devtools_handler_test.dart b/packages/flutter_tools/test/general.shard/resident_devtools_handler_test.dart index d25d9134fd24..fb2c7242401a 100644 --- a/packages/flutter_tools/test/general.shard/resident_devtools_handler_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_devtools_handler_test.dart @@ -469,14 +469,12 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService @override Future startDartDevelopmentService( - Uri vmServiceUri, { - int? ddsPort, - bool? disableServiceAuthCodes, + Uri observatoryUri, { + required Logger logger, + int? hostPort, bool? ipv6, - bool enableDevTools = true, + bool? disableServiceAuthCodes, bool cacheStartupProfile = false, - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, }) async { started = true; } @@ -485,4 +483,7 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService Future shutdown() async { disposed = true; } + + @override + void setExternalDevToolsUri(Uri uri) {} } diff --git a/packages/flutter_tools/test/general.shard/resident_runner_helpers.dart b/packages/flutter_tools/test/general.shard/resident_runner_helpers.dart index b8b6e4d9725e..c6da20415e37 100644 --- a/packages/flutter_tools/test/general.shard/resident_runner_helpers.dart +++ b/packages/flutter_tools/test/general.shard/resident_runner_helpers.dart @@ -4,6 +4,7 @@ import 'dart:async'; +import 'package:dds/dds.dart' as dds; import 'package:flutter_tools/src/application_package.dart'; import 'package:flutter_tools/src/asset.dart'; import 'package:flutter_tools/src/base/dds.dart'; @@ -150,44 +151,33 @@ const FakeVmServiceRequest evictShader = FakeVmServiceRequest( } ); -const DartDevelopmentServiceInstance fakeDartDevelopmentServiceInstance = ( - process: null, - serviceUri: null, - devToolsUri: null, - dtdUri: null, -); - final Uri testUri = Uri.parse('foo://bar'); -class FakeDartDevelopmentService extends Fake with DartDevelopmentServiceLocalOperationsMixin implements DartDevelopmentService { +// This implements [dds.DartDevelopmentService], not the [DartDevelopmentService] +// interface from package:flutter_tools. +class FakeDartDevelopmentService extends Fake implements dds.DartDevelopmentService { @override Future get done => Future.value(); @override Uri? get uri => null; - - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS> - /* - @override - Uri? get devToolsUri => null; - - @override - Uri? get dtdUri => null; - - @override - Future handleHotRestart(FlutterDevice? device) async {} - */ } -class FakeDartDevelopmentServiceException implements DartDevelopmentServiceException { +class FakeDartDevelopmentServiceException implements dds.DartDevelopmentServiceException { FakeDartDevelopmentServiceException({this.message = defaultMessage}); @override - final int errorCode = DartDevelopmentServiceException.existingDdsInstanceError; + final int errorCode = dds.DartDevelopmentServiceException.existingDdsInstanceError; @override final String message; static const String defaultMessage = 'A DDS instance is already connected at http://localhost:8181'; + + @override + Map toJson() => { + 'error_code': errorCode, + 'message': message, + }; } class TestFlutterDevice extends FlutterDevice { @@ -282,10 +272,13 @@ class FakeFlutterDevice extends Fake implements FlutterDevice { GetSkSLMethod? getSkSLMethod, FlutterProject? flutterProject, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, - required DebuggingOptions debuggingOptions, int? hostVmServicePort, - bool? ipv6 = false, - bool allowExistingDdsInstance = false, + int? ddsPort, + bool disableServiceAuthCodes = false, + bool enableDds = true, + bool cacheStartupProfile = false, + required bool allowExistingDdsInstance, + bool ipv6 = false, }) async { } @override @@ -310,10 +303,6 @@ class FakeFlutterDevice extends Fake implements FlutterDevice { @override Future updateReloadStatus(bool wasReloadSuccessful) async { } - - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // @override - // Future handleHotRestart() async {} } class FakeDelegateFlutterDevice extends FlutterDevice { @@ -328,13 +317,16 @@ class FakeDelegateFlutterDevice extends FlutterDevice { Future connect({ ReloadSources? reloadSources, Restart? restart, + bool enableDds = true, + bool cacheStartupProfile = false, + bool disableServiceAuthCodes = false, + bool ipv6 = false, CompileExpression? compileExpression, GetSkSLMethod? getSkSLMethod, FlutterProject? flutterProject, - PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, - required DebuggingOptions debuggingOptions, int? hostVmServicePort, - bool? ipv6 = false, + int? ddsPort, + PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, bool allowExistingDdsInstance = false, }) async { } @@ -443,7 +435,7 @@ class FakeDevice extends Fake implements Device { String get name => 'FakeDevice'; @override - late DartDevelopmentService dds = FakeDartDevelopmentService(); + late DartDevelopmentService dds; @override Future dispose() async { diff --git a/packages/flutter_tools/test/general.shard/resident_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_runner_test.dart index b0f4f8623ee2..7c1a8b899ebf 100644 --- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart @@ -4,10 +4,12 @@ import 'dart:async'; +import 'package:dds/dds.dart' as dds; import 'package:file/memory.dart'; import 'package:file_testing/file_testing.dart'; import 'package:flutter_tools/src/artifacts.dart'; import 'package:flutter_tools/src/base/command_help.dart'; +import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/dds.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/io.dart' as io; @@ -63,8 +65,8 @@ void main() { stayResident: false, debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', - analytics: fakeAnalytics, devtoolsHandler: createNoOpHandler, + analytics: globals.analytics, ); }, overrides: { Analytics: () => FakeAnalytics(), @@ -88,6 +90,7 @@ void main() { final Future result = residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, ); final Future connectionInfo = futureConnectionInfo.future; @@ -119,7 +122,7 @@ void main() { ); flutterDevice.generator = residentCompiler; - expect(await residentRunner.run(), 0); + expect(await residentRunner.run(enableDevTools: true), 0); expect(residentCompiler.didSuppressErrors, true); expect(fakeVmServiceHost?.hasRemainingExpectations, false); })); @@ -213,7 +216,7 @@ void main() { ); flutterDevice.generator = residentCompiler; - expect(await residentRunner.run(), 0); + expect(await residentRunner.run(enableDevTools: true), 0); expect(residentCompiler.didSuppressErrors, false); expect(fakeVmServiceHost?.hasRemainingExpectations, false); })); @@ -276,6 +279,7 @@ void main() { final Future result = residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, ); final Future connectionInfo = futureConnectionInfo.future; @@ -297,6 +301,7 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, )); await futureAppStart.future; flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, ''); @@ -338,6 +343,7 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, )); await futureAppStart.future; @@ -383,6 +389,7 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, )); await futureAppStart.future; flutterDevice.reportError = vm_service.RPCError('something bad happened', kIsolateReloadBarred, ''); @@ -426,15 +433,13 @@ void main() { ], stayResident: false, target: 'main.dart', - debuggingOptions: DebuggingOptions.enabled( - const BuildInfo( - BuildMode.debug, '', treeShakeIcons: false, extraFrontEndOptions: [ - '--enable-experiment=non-nullable', - ], - packageConfigPath: '.dart_tool/package_config.json', - ), - enableDevTools: false, - ), + debuggingOptions: DebuggingOptions.enabled(const BuildInfo( + BuildMode.debug, '', treeShakeIcons: false, extraFrontEndOptions: [ + '--enable-experiment=non-nullable', + ], + packageConfigPath: '.dart_tool/package_config.json' + )), + devtoolsHandler: createNoOpHandler, analytics: fakeAnalytics, ); final Completer futureConnectionInfo = Completer.sync(); @@ -442,6 +447,7 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, )); await futureAppStart.future; flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, ''); @@ -506,6 +512,7 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, )); await futureAppStart.future; flutterDevice.report = UpdateFSReport(success: true); @@ -563,6 +570,7 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, )); await futureAppStart.future; flutterDevice.report = UpdateFSReport(success: true, invalidatedSourcesCount: 1); @@ -626,6 +634,7 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, )); await futureAppStart.future; flutterDevice.report = UpdateFSReport(success: true, invalidatedSourcesCount: 1); @@ -685,6 +694,7 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, )); await futureAppStart.future; @@ -775,6 +785,7 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, )); await futureAppStart.future; @@ -836,6 +847,7 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, )); final OperationResult result = await residentRunner.restart(fullRestart: true); @@ -925,6 +937,7 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, )); final OperationResult result = await residentRunner.restart(fullRestart: true); @@ -1045,6 +1058,7 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, )); await residentRunner.restart(fullRestart: true); @@ -1064,6 +1078,7 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, + enableDevTools: true, )); await futureAppStart.future; flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, ''); @@ -1506,7 +1521,7 @@ flutter: flutterDevice, ], stayResident: false, - debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo', enableDevTools: false), + debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'), target: 'main.dart', devtoolsHandler: createNoOpHandler, ); @@ -1556,7 +1571,7 @@ flutter: analytics: fakeAnalytics, ); - await residentRunner.run(); + await residentRunner.run(enableDevTools: true); expect(fakeVmServiceHost?.hasRemainingExpectations, false); expect(await globals.fs.file('foo').readAsString(), testUri.toString()); @@ -1587,7 +1602,7 @@ flutter: ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); - await residentRunner.run(); + await residentRunner.run(enableDevTools: true); expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill')).readAsString(), 'ABC'); })); @@ -1618,7 +1633,7 @@ flutter: ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); - await residentRunner.run(); + await residentRunner.run(enableDevTools: true); expect(await globals.fs.file(globals.fs.path.join( 'build', '187ef4436122d1cc2f40dc2b92f0eba0.cache.dill')).readAsString(), 'ABC'); @@ -1650,7 +1665,7 @@ flutter: ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); - await residentRunner.run(); + await residentRunner.run(enableDevTools: true); expect(await globals.fs.file(globals.fs.path.join( 'build', 'cache.dill')).readAsString(), 'ABC'); @@ -1674,7 +1689,7 @@ flutter: ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); - await residentRunner.run(); + await residentRunner.run(enableDevTools: true); expect(await globals.fs.file(globals.fs.path.join( 'build', 'cache.dill.track.dill')).readAsString(), 'ABC'); @@ -1699,7 +1714,7 @@ flutter: ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); - await residentRunner.run(); + await residentRunner.run(enableDevTools: true); expect(globals.fs.file(globals.fs.path.join('build', 'cache.dill')), isNot(exists)); })); @@ -1728,7 +1743,7 @@ flutter: ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); - await residentRunner.run(); + await residentRunner.run(enableDevTools: true); expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill.track.dill')).readAsString(), 'ABC'); })); @@ -1771,7 +1786,7 @@ flutter: analytics: fakeAnalytics, ); - await residentRunner.run(); + await residentRunner.run(enableDevTools: true); expect(testLogger.errorText, contains('Failed to write vmservice-out-file at foo')); expect(fakeVmServiceHost?.hasRemainingExpectations, false); @@ -1790,11 +1805,11 @@ flutter: ], stayResident: false, debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'), - devtoolsHandler: createNoOpHandler, target: 'main.dart', + devtoolsHandler: createNoOpHandler, ); - await residentRunner.run(); + await residentRunner.run(enableDevTools: true); expect(await globals.fs.file('foo').readAsString(), testUri.toString()); expect(fakeVmServiceHost?.hasRemainingExpectations, false); @@ -1960,19 +1975,61 @@ flutter: ProcessManager: () => FakeProcessManager.any(), }); + testUsingContext('Handle existing VM service clients DDS error', () => testbed.run(() async { + fakeVmServiceHost = FakeVmServiceHost(requests: []); + final FakeDevice device = FakeDevice() + ..dds = DartDevelopmentService(); + ddsLauncherCallback = (Uri uri, {bool enableAuthCodes = true, bool ipv6 = false, Uri? serviceUri, List cachedUserTags = const [], dds.UriConverter? uriConverter}) { + expect(uri, Uri(scheme: 'foo', host: 'bar')); + expect(enableAuthCodes, isTrue); + expect(ipv6, isFalse); + expect(serviceUri, Uri(scheme: 'http', host: '127.0.0.1', port: 0)); + expect(cachedUserTags, isEmpty); + expect(uriConverter, isNull); + throw FakeDartDevelopmentServiceException(message: + 'Existing VM service clients prevent DDS from taking control.', + ); + }; + final TestFlutterDevice flutterDevice = TestFlutterDevice( + device, + vmServiceUris: Stream.value(testUri), + ); + bool caught = false; + final Completerdone = Completer(); + runZonedGuarded(() { + flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete()); + }, (Object e, StackTrace st) { + expect(e, isA()); + expect((e as ToolExit).message, + contains('Existing VM service clients prevent DDS from taking control.', + )); + done.complete(); + caught = true; + }); + await done.future; + if (!caught) { + fail('Expected ToolExit to be thrown.'); + } + }, overrides: { + VMServiceConnector: () => (Uri httpUri, { + ReloadSources? reloadSources, + Restart? restart, + CompileExpression? compileExpression, + GetSkSLMethod? getSkSLMethod, + FlutterProject? flutterProject, + PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, + io.CompressionOptions? compression, + Device? device, + required Logger logger, + }) async => FakeVmServiceHost(requests: []).vmService, + })); + testUsingContext('Uses existing DDS URI from exception field', () => testbed.run(() async { fakeVmServiceHost = FakeVmServiceHost(requests: []); final FakeDevice device = FakeDevice() - ..dds = DartDevelopmentService(logger: testLogger); - ddsLauncherCallback = (Uri uri, - {bool enableDevTools = false, - bool enableAuthCodes = true, - bool ipv6 = false, Uri? serviceUri, - List cachedUserTags = const [], - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, - }) { - throw DartDevelopmentServiceException.existingDdsInstance( + ..dds = DartDevelopmentService(); + ddsLauncherCallback = (Uri uri, {bool enableAuthCodes = true, bool ipv6 = false, Uri? serviceUri, List cachedUserTags = const [], dds.UriConverter? uriConverter}) { + throw dds.DartDevelopmentServiceException.existingDdsInstance( 'Existing DDS at http://localhost/existingDdsInMessage.', ddsUri: Uri.parse('http://localhost/existingDdsInField'), ); @@ -1983,10 +2040,7 @@ flutter: ); final Completer done = Completer(); unawaited(runZonedGuarded( - () => flutterDevice.connect( - allowExistingDdsInstance: true, - debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), - ).then((_) => done.complete()), + () => flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete()), (_, __) => done.complete(), )); await done.future; @@ -1998,7 +2052,41 @@ flutter: CompileExpression? compileExpression, GetSkSLMethod? getSkSLMethod, FlutterProject? flutterProject, - PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, + PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, + io.CompressionOptions? compression, + Device? device, + required Logger logger, + }) async => FakeVmServiceHost(requests: []).vmService, + })); + + testUsingContext('Falls back to existing DDS URI from exception message', () => testbed.run(() async { + fakeVmServiceHost = FakeVmServiceHost(requests: []); + final FakeDevice device = FakeDevice() + ..dds = DartDevelopmentService(); + ddsLauncherCallback = (Uri uri, {bool enableAuthCodes = true, bool ipv6 = false, Uri? serviceUri, List cachedUserTags = const [], dds.UriConverter? uriConverter}) { + throw dds.DartDevelopmentServiceException.existingDdsInstance( + 'Existing DDS at http://localhost/existingDdsInMessage.', + ); + }; + final TestFlutterDevice flutterDevice = TestFlutterDevice( + device, + vmServiceUris: Stream.value(testUri), + ); + final Completerdone = Completer(); + unawaited(runZonedGuarded( + () => flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete()), + (_, __) => done.complete(), + )); + await done.future; + expect(device.dds.uri, Uri.parse('http://localhost/existingDdsInMessage')); + }, overrides: { + VMServiceConnector: () => (Uri httpUri, { + ReloadSources? reloadSources, + Restart? restart, + CompileExpression? compileExpression, + GetSkSLMethod? getSkSLMethod, + FlutterProject? flutterProject, + PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, io.CompressionOptions? compression, Device? device, required Logger logger, @@ -2008,34 +2096,23 @@ flutter: testUsingContext('Host VM service ipv6 defaults', () => testbed.run(() async { fakeVmServiceHost = FakeVmServiceHost(requests: []); final FakeDevice device = FakeDevice() - ..dds = DartDevelopmentService(logger: testLogger); + ..dds = DartDevelopmentService(); final Completerdone = Completer(); - ddsLauncherCallback = (Uri uri, - {bool enableDevTools = false, - bool enableAuthCodes = true, - bool ipv6 = false, Uri? serviceUri, - List cachedUserTags = const [], - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, - }) async { + ddsLauncherCallback = (Uri uri, {bool enableAuthCodes = true, bool ipv6 = false, Uri? serviceUri, List cachedUserTags = const [], dds.UriConverter? uriConverter}) async { expect(uri, Uri(scheme: 'foo', host: 'bar')); expect(enableAuthCodes, isFalse); expect(ipv6, isTrue); expect(serviceUri, Uri(scheme: 'http', host: '::1', port: 0)); expect(cachedUserTags, isEmpty); + expect(uriConverter, isNull); done.complete(); - return fakeDartDevelopmentServiceInstance; + return FakeDartDevelopmentService(); }; final TestFlutterDevice flutterDevice = TestFlutterDevice( device, vmServiceUris: Stream.value(testUri), ); - await flutterDevice.connect( - allowExistingDdsInstance: true, - debuggingOptions: DebuggingOptions.enabled( - BuildInfo.debug, disableServiceAuthCodes: true, ipv6: true, - ) - ); + await flutterDevice.connect(allowExistingDdsInstance: true, ipv6: true, disableServiceAuthCodes: true); await done.future; }, overrides: { VMServiceConnector: () => (Uri httpUri, { @@ -2051,25 +2128,67 @@ flutter: }) async => FakeVmServiceHost(requests: []).vmService, })); + testUsingContext('Context includes URI converter', () => testbed.run(() async { + fakeVmServiceHost = FakeVmServiceHost(requests: []); + final FakeDevice device = FakeDevice() + ..dds = DartDevelopmentService(); + final Completerdone = Completer(); + ddsLauncherCallback = ( + Uri uri, { + bool enableAuthCodes = false, + bool ipv6 = false, + Uri? serviceUri, + List cachedUserTags = const [], + dds.UriConverter? uriConverter, + }) async { + expect(uri, Uri(scheme: 'foo', host: 'bar')); + expect(enableAuthCodes, isFalse); + expect(ipv6, isTrue); + expect(serviceUri, Uri(scheme: 'http', host: '::1', port: 0)); + expect(cachedUserTags, isEmpty); + expect(uriConverter, isNotNull); + done.complete(); + return FakeDartDevelopmentService(); + }; + final TestFlutterDevice flutterDevice = TestFlutterDevice( + device, + vmServiceUris: Stream.value(testUri), + ); + await flutterDevice.connect(allowExistingDdsInstance: true, ipv6: true, disableServiceAuthCodes: true); + await done.future; + }, overrides: { + VMServiceConnector: () => (Uri httpUri, { + ReloadSources? reloadSources, + Restart? restart, + CompileExpression? compileExpression, + GetSkSLMethod? getSkSLMethod, + FlutterProject? flutterProject, + PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, + io.CompressionOptions compression = io.CompressionOptions.compressionDefault, + Device? device, + required Logger logger, + }) async => FakeVmServiceHost(requests: []).vmService, + dds.UriConverter: () => (String uri) => 'test', + })); + testUsingContext('Failed DDS start outputs error message', () => testbed.run(() async { // See https://github.com/flutter/flutter/issues/72385 for context. final FakeDevice device = FakeDevice() - ..dds = DartDevelopmentService(logger: testLogger); + ..dds = DartDevelopmentService(); ddsLauncherCallback = ( Uri uri, { - bool enableDevTools = false, bool enableAuthCodes = false, bool ipv6 = false, Uri? serviceUri, List cachedUserTags = const [], - String? google3WorkspaceRoot, - Uri? devToolsServerAddress, + dds.UriConverter? uriConverter, }) { expect(uri, Uri(scheme: 'foo', host: 'bar')); expect(enableAuthCodes, isTrue); expect(ipv6, isFalse); expect(serviceUri, Uri(scheme: 'http', host: '127.0.0.1', port: 0)); expect(cachedUserTags, isEmpty); + expect(uriConverter, isNull); throw FakeDartDevelopmentServiceException(message: 'No URI'); }; final TestFlutterDevice flutterDevice = TestFlutterDevice( @@ -2079,10 +2198,7 @@ flutter: bool caught = false; final Completerdone = Completer(); runZonedGuarded(() { - flutterDevice.connect( - allowExistingDdsInstance: true, - debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, enableDevTools: false), - ).then((_) => done.complete()); + flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete()); }, (Object e, StackTrace st) { expect(e, isA()); expect((e as StateError).message, contains('No URI')); @@ -2120,7 +2236,6 @@ flutter: expect(() => nextPlatform('unknown'), throwsAssertionError); }); - // TODO(bkonyi): remove when ready to serve DevTools from DDS. testUsingContext('cleanupAtFinish shuts down resident devtools handler', () => testbed.run(() async { residentRunner = HotRunner( [ diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart index 96881920a123..131734100ca2 100644 --- a/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart @@ -50,6 +50,7 @@ void main() { mockFlutterDevice, flutterProject: project, debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), + ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), @@ -80,6 +81,7 @@ void main() { mockFlutterDevice, flutterProject: project, debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), + ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), @@ -105,6 +107,7 @@ void main() { mockFlutterDevice, flutterProject: project, debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), + ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), @@ -129,6 +132,7 @@ void main() { mockFlutterDevice, flutterProject: project, debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), + ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), @@ -158,6 +162,7 @@ void main() { mockFlutterDevice, flutterProject: project, debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), + ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), @@ -240,8 +245,4 @@ class FakeFlutterDevice extends Fake implements FlutterDevice { @override FlutterVmService? vmService; - - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // @override - // Future handleHotRestart() async {} } diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart index c175539951cc..34ef199025b5 100644 --- a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart @@ -162,6 +162,7 @@ void main() { flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), + ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, @@ -194,6 +195,7 @@ void main() { FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, startPaused: true), + ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, @@ -213,6 +215,7 @@ void main() { flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), + ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, @@ -226,6 +229,7 @@ void main() { flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile), + ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, @@ -358,13 +362,13 @@ void main() { flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), + ipv6: true, stayResident: false, fileSystem: fileSystem, logger: logger, usage: globals.flutterUsage, analytics: globals.analytics, systemClock: globals.systemClock, - devtoolsHandler: createNoOpHandler, ); expect(await residentWebRunner.run(), 0); @@ -385,13 +389,13 @@ void main() { flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), + ipv6: true, stayResident: false, fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, analytics: globals.analytics, systemClock: globals.systemClock, - devtoolsHandler: createNoOpHandler, ); expect(await residentWebRunner.run(), 0); @@ -587,12 +591,12 @@ void main() { FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, startPaused: true), + ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, analytics: globals.analytics, systemClock: globals.systemClock, - devtoolsHandler: createNoOpHandler, ); fakeVmServiceHost = FakeVmServiceHost(requests: kAttachExpectations.toList()); @@ -1008,7 +1012,7 @@ void main() { testUsingContext('cleanup of resources is safe to call multiple times', () async { final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice); - mockDevice.dds = DartDevelopmentService(logger: test_fakes.FakeLogger()); + mockDevice.dds = DartDevelopmentService(); fakeVmServiceHost = FakeVmServiceHost(requests: [ ...kAttachExpectations, ]); @@ -1111,12 +1115,12 @@ void main() { flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), + ipv6: true, fileSystem: fileSystem, logger: logger, usage: globals.flutterUsage, analytics: globals.analytics, systemClock: globals.systemClock, - devtoolsHandler: createNoOpHandler, ); final Completer connectionInfoCompleter = @@ -1160,12 +1164,12 @@ void main() { flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), + ipv6: true, fileSystem: fileSystem, logger: logger, usage: globals.flutterUsage, analytics: globals.analytics, systemClock: globals.systemClock, - devtoolsHandler: createNoOpHandler, ); final Completer connectionInfoCompleter = @@ -1202,13 +1206,13 @@ void main() { flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), + ipv6: true, stayResident: false, fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, analytics: globals.analytics, systemClock: globals.systemClock, - devtoolsHandler: createNoOpHandler, ); // Create necessary files. @@ -1406,6 +1410,7 @@ ResidentRunner setUpResidentRunner( FlutterProject.fromDirectoryTest(globals.fs.currentDirectory), debuggingOptions: debuggingOptions ?? DebuggingOptions.enabled(BuildInfo.debug), + ipv6: true, usage: globals.flutterUsage, analytics: globals.analytics, systemClock: systemClock ?? SystemClock.fixed(DateTime.now()), @@ -1714,11 +1719,13 @@ class FakeFlutterDevice extends Fake implements FlutterDevice { GetSkSLMethod? getSkSLMethod, FlutterProject? flutterProject, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, - required DebuggingOptions debuggingOptions, int? hostVmServicePort, + int? ddsPort, + bool disableServiceAuthCodes = false, + bool enableDds = true, + bool cacheStartupProfile = false, + required bool allowExistingDdsInstance, bool? ipv6 = false, - bool enableDevTools = false, - bool allowExistingDdsInstance = false, }) async {} @override @@ -1744,10 +1751,6 @@ class FakeFlutterDevice extends Fake implements FlutterDevice { @override Future updateReloadStatus(bool wasReloadSuccessful) async {} - - // TODO(bkonyi): uncomment when ready to serve DevTools from DDS. - // @override - // Future handleHotRestart() async {} } class FakeShaderCompiler implements DevelopmentShaderCompiler { diff --git a/packages/flutter_tools/test/general.shard/runner/flutter_command_runner_test.dart b/packages/flutter_tools/test/general.shard/runner/flutter_command_runner_test.dart index 6e6f8b462497..30ea65af5af6 100644 --- a/packages/flutter_tools/test/general.shard/runner/flutter_command_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/runner/flutter_command_runner_test.dart @@ -191,7 +191,6 @@ void main() { Analytics: () => fakeAnalytics, }); - // TODO(bkonyi): remove when ready to serve DevTools from DDS. group('${FlutterGlobalOptions.kPrintDtd} flag', () { testUsingContext('sets DevtoolsLauncher.printDtdUri to false when not present', () async { final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner; diff --git a/packages/flutter_tools/test/general.shard/terminal_handler_test.dart b/packages/flutter_tools/test/general.shard/terminal_handler_test.dart index e9232691e8fd..ba43d15f3112 100644 --- a/packages/flutter_tools/test/general.shard/terminal_handler_test.dart +++ b/packages/flutter_tools/test/general.shard/terminal_handler_test.dart @@ -7,7 +7,6 @@ import 'dart:async'; import 'package:file/file.dart'; import 'package:file/memory.dart'; import 'package:file_testing/file_testing.dart'; -import 'package:flutter_tools/src/base/dds.dart'; import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/signals.dart'; @@ -26,7 +25,6 @@ import 'package:vm_service/vm_service.dart' as vm_service; import '../src/common.dart'; import '../src/fake_vm_services.dart'; -import '../src/fakes.dart'; final vm_service.Isolate fakeUnpausedIsolate = vm_service.Isolate( id: '1', @@ -834,20 +832,8 @@ void main() { final FakeResidentDevtoolsHandler devtoolsHandler = runner.residentDevtoolsHandler as FakeResidentDevtoolsHandler; expect(devtoolsHandler.calledLaunchDevToolsInBrowser, isFalse); - // TODO(bkonyi): uncomment these checks and remove existing checks when ready to - // serve DevTools from DDS. - /* - for (final FlutterDevice? device in runner.flutterDevices) { - expect(device!.device!.dds.calledLaunchDevToolsInBrowser, isFalse); - } - */ await terminalHandler.processTerminalInput('v'); expect(devtoolsHandler.calledLaunchDevToolsInBrowser, isTrue); - /* - for (final FlutterDevice? device in runner.flutterDevices) { - expect(device!.device!.dds.calledLaunchDevToolsInBrowser, isTrue); - } - */ }); testWithoutContext('w,W - debugDumpApp without service protocol is skipped', () async { @@ -1322,13 +1308,11 @@ class FakeResidentRunner extends ResidentHandlers { return OperationResult(reloadExitCode, '', fatal: fatalReloadError); } - // TODO(bkonyi): remove when ready to serve DevTools from DDS. @override ResidentDevtoolsHandler get residentDevtoolsHandler => _residentDevtoolsHandler; final ResidentDevtoolsHandler _residentDevtoolsHandler = FakeResidentDevtoolsHandler(); } -// TODO(bkonyi): remove when ready to serve DevTools from DDS. class FakeResidentDevtoolsHandler extends Fake implements ResidentDevtoolsHandler { bool calledLaunchDevToolsInBrowser = false; @@ -1348,9 +1332,6 @@ class FakeDevice extends Fake implements Device { @override String get name => 'Fake Device'; - @override - DartDevelopmentService dds = DartDevelopmentService(logger: FakeLogger()); - @override Future takeScreenshot(File file) async { if (!supportsScreenshot) { @@ -1358,6 +1339,7 @@ class FakeDevice extends Fake implements Device { } file.writeAsBytesSync([1, 2, 3, 4]); } + } TerminalHandler setUpTerminalHandler(List requests, { diff --git a/packages/flutter_tools/test/src/fake_devices.dart b/packages/flutter_tools/test/src/fake_devices.dart index 558624432709..4f6ab9e329ed 100644 --- a/packages/flutter_tools/test/src/fake_devices.dart +++ b/packages/flutter_tools/test/src/fake_devices.dart @@ -9,8 +9,6 @@ import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/project.dart'; -import 'fakes.dart'; - /// A list of fake devices to test JSON serialization /// (`Device.toJson()` and `--machine` flag for `devices` command) List fakeDevices = [ @@ -131,7 +129,6 @@ class FakeDevice extends Device { platformType: type, category: Category.mobile, ephemeral: ephemeral, - logger: FakeLogger(), ); final bool _isSupported; diff --git a/packages/flutter_tools/test/src/fakes.dart b/packages/flutter_tools/test/src/fakes.dart index cc6d456b441b..ff6f6deebc5c 100644 --- a/packages/flutter_tools/test/src/fakes.dart +++ b/packages/flutter_tools/test/src/fakes.dart @@ -741,12 +741,6 @@ class FakeDevtoolsLauncher extends Fake implements DevtoolsLauncher { } } -/// A fake [Logger] that throws the [Invocation] for any method call. -class FakeLogger implements Logger { - @override - dynamic noSuchMethod(Invocation invocation) => throw invocation; // ignore: only_throw_errors -} - class ClosedStdinController extends Fake implements StreamSink> { @override Future addStream(Stream> stream) async => throw const SocketException('Bad pipe');