diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart index 51ae79a348..40a291ae0b 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 Logger logger, + required super.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 eba8d3875c..da4bee85b6 100644 --- a/packages/flutter_tools/lib/src/base/dds.dart +++ b/packages/flutter_tools/lib/src/base/dds.dart @@ -4,112 +4,328 @@ import 'dart:async'; -import 'package:dds/dds.dart' as dds; import 'package:meta/meta.dart'; -import 'common.dart'; -import 'context.dart'; +import '../artifacts.dart'; +import '../convert.dart'; +import '../device.dart'; +import '../globals.dart' as globals; import 'io.dart' as io; import 'logger.dart'; -// TODO(fujino): This should be direct injected, rather than mutable global state. -@visibleForTesting -Future Function( - Uri remoteVmServiceUri, { - bool enableAuthCodes, - bool ipv6, +/// 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, - List cachedUserTags, - dds.UriConverter? uriConverter, -}) ddsLauncherCallback = dds.DartDevelopmentService.startDartDevelopmentService; + 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', + if (google3WorkspaceRoot != null) + '--google3-workspace-root=$google3WorkspaceRoot', + 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; +} /// Helper class to launch a [dds.DartDevelopmentService]. Allows for us to /// mock out this functionality for testing purposes. -class DartDevelopmentService { - dds.DartDevelopmentService? _ddsInstance; +class DartDevelopmentService with DartDevelopmentServiceLocalOperationsMixin { + DartDevelopmentService({required Logger logger}) : _logger = logger; - Uri? get uri => _ddsInstance?.uri ?? _existingDdsUri; + DartDevelopmentServiceInstance? _ddsInstance; + + Uri? get uri => _ddsInstance?.serviceUri ?? _existingDdsUri; Uri? _existingDdsUri; Future get done => _completer.future; final Completer _completer = Completer(); + final Logger _logger; + + @override Future startDartDevelopmentService( Uri vmServiceUri, { - required Logger logger, - int? hostPort, - bool? ipv6, + int? ddsPort, bool? disableServiceAuthCodes, + bool? ipv6, + bool enableDevTools = true, 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: hostPort ?? 0, + host: ((ipv6 ?? false) + ? io.InternetAddress.loopbackIPv6 + : io.InternetAddress.loopbackIPv4) + .host, + port: ddsPort ?? 0, ); - logger.printTrace( + _logger.printTrace( 'Launching a Dart Developer Service (DDS) instance at $ddsUri, ' 'connecting to VM service at $vmServiceUri.', ); - try { - _ddsInstance = await ddsLauncherCallback( - 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); - } - } + 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( + '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); + } + completeFuture(); rethrow; } } - Future shutdown() async => _ddsInstance?.shutdown(); - - void setExternalDevToolsUri(Uri uri) { - _ddsInstance?.setExternalDevToolsUri(uri); - } + 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, + }); + + /// 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, + ); } diff --git a/packages/flutter_tools/lib/src/commands/attach.dart b/packages/flutter_tools/lib/src/commands/attach.dart index 404b116c9d..1fac03a7fd 100644 --- a/packages/flutter_tools/lib/src/commands/attach.dart +++ b/packages/flutter_tools/lib/src/commands/attach.dart @@ -361,7 +361,6 @@ 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, @@ -403,7 +402,6 @@ 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); @@ -462,6 +460,9 @@ 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 @@ -472,7 +473,6 @@ 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,7 +482,6 @@ known, it can be explicitly provided to attach via the command-line, e.g. flutterDevices, target: targetFile, debuggingOptions: debuggingOptions, - ipv6: usesIpv6, ); } @@ -506,7 +505,6 @@ class HotRunnerFactory { String? packagesFilePath, String? dillOutputPath, bool stayResident = true, - bool ipv6 = false, FlutterProject? flutterProject, String? nativeAssetsYamlFile, required HotRunnerNativeAssetsBuilder? nativeAssetsBuilder, @@ -521,7 +519,6 @@ 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 4f1991aa97..6749b988fe 100644 --- a/packages/flutter_tools/lib/src/commands/daemon.dart +++ b/packages/flutter_tools/lib/src/commands/daemon.dart @@ -664,11 +664,9 @@ 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)) { @@ -699,7 +697,6 @@ class AppDomain extends Domain { flutterProject: flutterProject, target: target, debuggingOptions: options, - ipv6: ipv6, stayResident: true, urlTunneller: options.webEnableExposeUrl! ? daemon.daemonDomain.exposeUrl : null, machine: machine, @@ -717,7 +714,6 @@ class AppDomain extends Domain { applicationBinary: applicationBinary, projectRootPath: projectRootPath, dillOutputPath: dillOutputPath, - ipv6: ipv6, hostIsIde: true, machine: machine, analytics: globals.analytics, @@ -729,7 +725,6 @@ class AppDomain extends Domain { target: target, debuggingOptions: options, applicationBinary: applicationBinary, - ipv6: ipv6, machine: machine, ); } @@ -743,7 +738,6 @@ class AppDomain extends Domain { return runner.run( connectionInfoCompleter: connectionInfoCompleter, appStartedCompleter: appStartedCompleter, - enableDevTools: enableDevTools, route: route, ); }, @@ -1008,7 +1002,6 @@ 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); @@ -1196,7 +1189,6 @@ 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 { @@ -1244,23 +1236,33 @@ 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 device.dds.uri?.toString(); + return { + 'ddsUri': device.dds.uri?.toString(), + }; } /// Starts DDS for the device. @@ -1272,19 +1274,7 @@ class DeviceDomain extends Domain { throw DaemonException("device '$deviceId' not found"); } - 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)); + device.dds.shutdown(); } @override diff --git a/packages/flutter_tools/lib/src/commands/drive.dart b/packages/flutter_tools/lib/src/commands/drive.dart index be6b19c74a..4365d31ba2 100644 --- a/packages/flutter_tools/lib/src/commands/drive.dart +++ b/packages/flutter_tools/lib/src/commands/drive.dart @@ -274,7 +274,6 @@ class DriveCommand extends RunCommandBase { buildInfo, device, debuggingOptions, - ipv6 ?? false, applicationBinary: applicationBinary, route: route, userIdentifier: userIdentifier, @@ -295,7 +294,6 @@ 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 c46524bad5..c8920f2a8c 100644 --- a/packages/flutter_tools/lib/src/commands/run.dart +++ b/packages/flutter_tools/lib/src/commands/run.dart @@ -354,6 +354,9 @@ 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), ); } } @@ -702,7 +705,6 @@ 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, @@ -712,7 +714,6 @@ class RunCommand extends RunCommandBase { flutterDevices.single, target: targetFile, flutterProject: flutterProject, - ipv6: ipv6, debuggingOptions: await createDebuggingOptions(webMode), stayResident: stayResident, fileSystem: globals.fs, @@ -731,7 +732,6 @@ class RunCommand extends RunCommandBase { applicationBinary: applicationBinaryPath == null ? null : globals.fs.file(applicationBinaryPath), - ipv6: ipv6 ?? false, stayResident: stayResident, ); } @@ -776,9 +776,7 @@ 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) { @@ -866,7 +864,6 @@ 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 482557aa46..459adcc001 100644 --- a/packages/flutter_tools/lib/src/commands/test.dart +++ b/packages/flutter_tools/lib/src/commands/test.dart @@ -16,6 +16,7 @@ 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'; @@ -411,6 +412,7 @@ 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, ); @@ -599,7 +601,6 @@ 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 3a9ee366e3..25980ab7d3 100644 --- a/packages/flutter_tools/lib/src/custom_devices/custom_device.dart +++ b/packages/flutter_tools/lib/src/custom_devices/custom_device.dart @@ -352,7 +352,6 @@ 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; @@ -377,7 +376,7 @@ class CustomDeviceAppSession { logReader, portForwarder: _device._config.usesPortForwarding ? _device.portForwarder : null, logger: _logger, - ipv6: ipv6, + ipv6: debuggingOptions.ipv6, ); // We need to make the discovery listen to the logReader before the logReader @@ -439,7 +438,7 @@ class CustomDeviceAppSession { class CustomDevice extends Device { CustomDevice({ required CustomDeviceConfig config, - required Logger logger, + required super.logger, required ProcessManager processManager, }) : _config = config, _logger = logger, @@ -789,7 +788,6 @@ 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 1044ab2cae..a7579bdd08 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 Logger logger, + required super.logger, required ProcessManager processManager, required FileSystem fileSystem, required OperatingSystemUtils operatingSystemUtils, @@ -114,7 +114,6 @@ abstract class DesktopDevice extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, - bool ipv6 = false, String? userIdentifier, }) async { if (!prebuiltApplication) { @@ -158,7 +157,7 @@ abstract class DesktopDevice extends Device { final ProtocolDiscovery vmServiceDiscovery = ProtocolDiscovery.vmService(_deviceLogReader, devicePort: debuggingOptions.deviceVmServicePort, hostPort: debuggingOptions.hostVmServicePort, - ipv6: ipv6, + ipv6: debuggingOptions.ipv6, logger: _logger, ); try { diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart index 35cc939656..7c4f32dfa5 100644 --- a/packages/flutter_tools/lib/src/device.dart +++ b/packages/flutter_tools/lib/src/device.dart @@ -603,10 +603,11 @@ 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; @@ -733,7 +734,7 @@ abstract class Device { DevicePortForwarder? get portForwarder; /// Get the DDS instance for this device. - final DartDevelopmentService dds = DartDevelopmentService(); + final DartDevelopmentService dds; /// Clear the device's logs. void clearLogs(); @@ -778,7 +779,6 @@ abstract class Device { required DebuggingOptions debuggingOptions, Map platformArgs, bool prebuiltApplication = false, - bool ipv6 = false, String? userIdentifier, }); @@ -1007,7 +1007,11 @@ class DebuggingOptions { this.enableEmbedderApi = false, this.usingCISystem = false, this.debugLogsDirectoryPath, - }) : debuggingEnabled = true, + this.enableDevTools = true, + this.ipv6 = false, + this.google3WorkspaceRoot, + this.printDtd = false, + }) : debuggingEnabled = true, webRenderer = webRenderer ?? WebRendererMode.getDefault(useWasm: webUseWasm); DebuggingOptions.disabled(this.buildInfo, { @@ -1065,6 +1069,10 @@ class DebuggingOptions { nullAssertions = false, nativeNullAssertions = false, serveObservatory = false, + enableDevTools = false, + ipv6 = false, + google3WorkspaceRoot = null, + printDtd = false, webRenderer = webRenderer ?? WebRendererMode.getDefault(useWasm: webUseWasm); DebuggingOptions._({ @@ -1123,6 +1131,10 @@ 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; @@ -1167,6 +1179,10 @@ 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. /// @@ -1220,7 +1236,6 @@ class DebuggingOptions { EnvironmentType environmentType, String? route, Map platformArgs, { - bool ipv6 = false, DeviceConnectionInterface interfaceType = DeviceConnectionInterface.attached, bool isCoreDevice = false, }) { @@ -1326,6 +1341,10 @@ class DebuggingOptions { 'enableEmbedderApi': enableEmbedderApi, 'usingCISystem': usingCISystem, 'debugLogsDirectoryPath': debugLogsDirectoryPath, + 'enableDevTools': enableDevTools, + 'ipv6': ipv6, + 'google3WorkspaceRoot': google3WorkspaceRoot, + 'printDtd': printDtd, }; static DebuggingOptions fromJson(Map json, BuildInfo buildInfo) => @@ -1385,6 +1404,10 @@ 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 b3340db461..82bd4bad4d 100644 --- a/packages/flutter_tools/lib/src/drive/drive_service.dart +++ b/packages/flutter_tools/lib/src/drive/drive_service.dart @@ -4,7 +4,6 @@ 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'; @@ -12,6 +11,7 @@ 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,8 +65,7 @@ abstract class DriverService { Future start( BuildInfo buildInfo, Device device, - DebuggingOptions debuggingOptions, - bool ipv6, { + DebuggingOptions debuggingOptions, { File? applicationBinary, String? route, String? userIdentifier, @@ -79,7 +78,6 @@ abstract class DriverService { Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions, - bool ipv6, ); /// Start the test file with the provided [arguments] and [environment], returning @@ -148,8 +146,7 @@ class FlutterDriverService extends DriverService { Future start( BuildInfo buildInfo, Device device, - DebuggingOptions debuggingOptions, - bool ipv6, { + DebuggingOptions debuggingOptions, { File? applicationBinary, String? route, String? userIdentifier, @@ -199,7 +196,6 @@ class FlutterDriverService extends DriverService { result.vmServiceUri!, device, debuggingOptions, - ipv6, ); } @@ -208,7 +204,6 @@ class FlutterDriverService extends DriverService { Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions, - bool ipv6, ) async { Uri uri; if (vmServiceUri.scheme == 'ws') { @@ -222,15 +217,12 @@ class FlutterDriverService extends DriverService { _device = device; if (debuggingOptions.enableDds) { try { - await device.dds.startDartDevelopmentService( + await device.dds.startDartDevelopmentServiceFromDebuggingOptions( uri, - hostPort: debuggingOptions.ddsPort, - ipv6: ipv6, - disableServiceAuthCodes: debuggingOptions.disableServiceAuthCodes, - logger: _logger, + debuggingOptions: debuggingOptions, ); _vmServiceUri = device.dds.uri.toString(); - } on dds.DartDevelopmentServiceException { + } on 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 b7989cc129..d7194f3476 100644 --- a/packages/flutter_tools/lib/src/drive/web_driver_service.dart +++ b/packages/flutter_tools/lib/src/drive/web_driver_service.dart @@ -55,8 +55,7 @@ class WebDriverService extends DriverService { Future start( BuildInfo buildInfo, Device device, - DebuggingOptions debuggingOptions, - bool ipv6, { + DebuggingOptions debuggingOptions, { File? applicationBinary, String? route, String? userIdentifier, @@ -72,7 +71,6 @@ class WebDriverService extends DriverService { _residentRunner = webRunnerFactory!.createWebRunner( flutterDevice, target: mainPath, - ipv6: ipv6, debuggingOptions: buildInfo.isRelease ? DebuggingOptions.disabled( buildInfo, @@ -234,7 +232,7 @@ class WebDriverService extends DriverService { } @override - Future reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions, bool ipv6) async { + Future reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions) 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 bb7ffdb0d9..4e7ffe89b0 100644 --- a/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart +++ b/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart @@ -58,10 +58,9 @@ Future _kDefaultDartDevelopmentServiceStarter( ) async { await device.dds.startDartDevelopmentService( vmServiceUri, - hostPort: 0, - ipv6: true, + ddsPort: 0, disableServiceAuthCodes: disableServiceAuthCodes, - logger: globals.logger, + ipv6: true, ); } @@ -212,7 +211,7 @@ class FuchsiaDevices extends PollingDeviceDiscovery { _logger.printError('Failed to resolve host for Fuchsia device `$name`'); return null; } - return FuchsiaDevice(resolvedHost, name: name); + return FuchsiaDevice(resolvedHost, name: name, logger: _logger); } @override @@ -220,7 +219,7 @@ class FuchsiaDevices extends PollingDeviceDiscovery { } class FuchsiaDevice extends Device { - FuchsiaDevice(super.id, {required this.name}) + FuchsiaDevice(super.id, {required this.name, required super.logger}) : super( platformType: PlatformType.fuchsia, category: null, @@ -295,7 +294,6 @@ 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 4baceaacd7..554abf65e6 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 Logger logger, + required super.logger, }) : _sdkVersion = sdkVersion, _iosDeploy = iosDeploy, @@ -470,7 +470,6 @@ class IOSDevice extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, - bool ipv6 = false, String? userIdentifier, @visibleForTesting Duration? discoveryTimeout, @visibleForTesting ShutdownHooks? shutdownHooks, @@ -524,7 +523,6 @@ class IOSDevice extends Device { EnvironmentType.physical, route, platformArgs, - ipv6: ipv6, interfaceType: connectionInterface, isCoreDevice: isCoreDevice, ); @@ -541,7 +539,6 @@ class IOSDevice extends Device { bundle: bundle, debuggingOptions: debuggingOptions, launchArguments: launchArguments, - ipv6: ipv6, uninstallFirst: debuggingOptions.uninstallFirst, ); } @@ -619,7 +616,6 @@ class IOSDevice extends Device { localUri = await _discoverDartVMForCoreDevice( debuggingOptions: debuggingOptions, packageId: packageId, - ipv6: ipv6, vmServiceDiscovery: vmServiceDiscovery, ); } else if (isWirelesslyConnected) { @@ -651,7 +647,7 @@ class IOSDevice extends Device { localUri = await MDnsVmServiceDiscovery.instance!.getVMServiceUriForLaunch( packageId, this, - usesIpv6: ipv6, + usesIpv6: debuggingOptions.ipv6, deviceVmservicePort: serviceURL.port, useDeviceIPAsHost: true, ); @@ -673,7 +669,6 @@ class IOSDevice extends Device { bundle: bundle, debuggingOptions: debuggingOptions, launchArguments: launchArguments, - ipv6: ipv6, uninstallFirst: false, skipInstall: true, ); @@ -728,7 +723,6 @@ 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 { @@ -775,7 +769,7 @@ class IOSDevice extends Device { final Future vmUrlFromMDns = MDnsVmServiceDiscovery.instance!.getVMServiceUriForLaunch( packageId, this, - usesIpv6: ipv6, + usesIpv6: debuggingOptions.ipv6, useDeviceIPAsHost: isWirelesslyConnected, ); @@ -814,7 +808,6 @@ class IOSDevice extends Device { required Directory bundle, required DebuggingOptions debuggingOptions, required List launchArguments, - required bool ipv6, required bool uninstallFirst, bool skipInstall = false, }) { @@ -845,7 +838,7 @@ class IOSDevice extends Device { portForwarder: isWirelesslyConnected ? null : portForwarder, hostPort: debuggingOptions.hostVmServicePort, devicePort: debuggingOptions.deviceVmServicePort, - ipv6: ipv6, + ipv6: debuggingOptions.ipv6, logger: _logger, ); } diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart index fb255f8406..97d61857ca 100644 --- a/packages/flutter_tools/lib/src/ios/simulators.dart +++ b/packages/flutter_tools/lib/src/ios/simulators.dart @@ -90,6 +90,7 @@ class IOSSimulatorUtils { name: name, simControl: _simControl, simulatorCategory: device.category, + logger: _simControl._logger, ); }).whereType().toList(); } @@ -356,6 +357,7 @@ class IOSSimulator extends Device { required this.name, required this.simulatorCategory, required SimControl simControl, + required super.logger, }) : _simControl = simControl, super( category: Category.mobile, @@ -472,7 +474,6 @@ class IOSSimulator extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, - bool ipv6 = false, String? userIdentifier, }) async { if (!prebuiltApplication && package is BuildableIOSApp) { @@ -501,7 +502,7 @@ class IOSSimulator extends Device { if (debuggingOptions.debuggingEnabled) { vmServiceDiscovery = ProtocolDiscovery.vmService( getLogReader(app: package), - ipv6: ipv6, + ipv6: debuggingOptions.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 332e964ce0..c212a0ed63 100644 --- a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart +++ b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart @@ -50,7 +50,6 @@ class DwdsWebRunnerFactory extends WebRunnerFactory { String? target, required bool stayResident, required FlutterProject flutterProject, - required bool? ipv6, required DebuggingOptions debuggingOptions, UrlTunneller? urlTunneller, required Logger logger, @@ -65,7 +64,6 @@ class DwdsWebRunnerFactory extends WebRunnerFactory { target: target, flutterProject: flutterProject, debuggingOptions: debuggingOptions, - ipv6: ipv6, stayResident: stayResident, urlTunneller: urlTunneller, machine: machine, @@ -89,7 +87,6 @@ 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, @@ -97,6 +94,7 @@ 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, @@ -108,7 +106,6 @@ class ResidentWebRunner extends ResidentRunner { [device], target: target ?? fileSystem.path.join('lib', 'main.dart'), debuggingOptions: debuggingOptions, - ipv6: ipv6, stayResident: stayResident, machine: machine, devtoolsHandler: devtoolsHandler, @@ -195,6 +192,7 @@ 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(); @@ -247,7 +245,6 @@ 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( @@ -368,7 +365,6 @@ 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) { @@ -476,6 +472,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.'); + unawaited(residentDevtoolsHandler!.hotRestart(flutterDevices)); // Don't track restart times for dart2js builds or web-server devices. @@ -603,7 +600,6 @@ 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) { @@ -682,13 +678,14 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive). } }); } - if (enableDevTools) { - // The method below is guaranteed never to return a failing future. - unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools( - devToolsServerAddress: debuggingOptions.devToolsServerAddress, - flutterDevices: flutterDevices, - )); - } + } + // 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 (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 235d01383d..e371569c73 100644 --- a/packages/flutter_tools/lib/src/macos/macos_ipad_device.dart +++ b/packages/flutter_tools/lib/src/macos/macos_ipad_device.dart @@ -99,7 +99,6 @@ 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 71eba1fcb1..2577a29e60 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 Logger logger, + required super.logger, required FileSystem fileSystem, required Artifacts artifacts, required File previewBinary, @@ -170,7 +170,6 @@ class PreviewDevice extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, - bool ipv6 = false, String? userIdentifier, }) async { final Directory assetDirectory = _fileSystem.systemTempDirectory @@ -214,7 +213,7 @@ class PreviewDevice extends Device { final ProtocolDiscovery vmServiceDiscovery = ProtocolDiscovery.vmService(_logReader, devicePort: debuggingOptions.deviceVmServicePort, hostPort: debuggingOptions.hostVmServicePort, - ipv6: ipv6, + ipv6: debuggingOptions.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 c286ce2545..4163beb02e 100644 --- a/packages/flutter_tools/lib/src/proxied_devices/devices.dart +++ b/packages/flutter_tools/lib/src/proxied_devices/devices.dart @@ -19,6 +19,7 @@ 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'; @@ -175,7 +176,7 @@ class ProxiedDevice extends Device { required this.supportsScreenshot, required this.supportsFastStart, required bool supportsHardwareRendering, - required Logger logger, + required super.logger, FileTransfer fileTransfer = const FileTransfer(), }): _deltaFileTransfer = deltaFileTransfer, _enableDdsProxy = enableDdsProxy, @@ -334,7 +335,6 @@ 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': ipv6, + 'ipv6': debuggingOptions.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 implements DartDevelopmentService { +class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMixin implements DartDevelopmentService { ProxiedDartDevelopmentService( this.connection, this.deviceId, { @@ -756,10 +756,11 @@ class ProxiedDartDevelopmentService implements DartDevelopmentService { required ProxiedPortForwarder proxiedPortForwarder, required ProxiedPortForwarder devicePortForwarder, @visibleForTesting DartDevelopmentService? localDds, - }) : _logger = logger, + }) : + _logger = logger, _proxiedPortForwarder = proxiedPortForwarder, _devicePortForwarder = devicePortForwarder, - _localDds = localDds ?? DartDevelopmentService(); + _localDds = localDds ?? DartDevelopmentService(logger: logger); final String deviceId; @@ -776,10 +777,9 @@ class ProxiedDartDevelopmentService implements DartDevelopmentService { /// 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,11 +792,14 @@ class ProxiedDartDevelopmentService implements DartDevelopmentService { @override Future startDartDevelopmentService( Uri vmServiceUri, { - required Logger logger, - int? hostPort, + FlutterDevice? device, + int? ddsPort, 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 @@ -805,18 +808,24 @@ class ProxiedDartDevelopmentService implements DartDevelopmentService { _proxiedPortForwarder.originalRemotePort(vmServiceUri.port) ?? _devicePortForwarder.originalRemotePort(vmServiceUri.port); - if (remoteVMServicePort == null) { - _logger.printTrace('VM service port is not a forwarded port. Start DDS locally.'); + Future startLocalDds() async { _ddsStartedLocally = true; await _localDds.startDartDevelopmentService( vmServiceUri, - logger: logger, - hostPort: hostPort, + ddsPort: ddsPort, ipv6: ipv6, disableServiceAuthCodes: disableServiceAuthCodes, cacheStartupProfile: cacheStartupProfile, + enableDevTools: enableDevTools, + google3WorkspaceRoot: google3WorkspaceRoot, + devToolsServerAddress: devToolsServerAddress, ); 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; } @@ -835,11 +844,19 @@ class ProxiedDartDevelopmentService implements DartDevelopmentService { // Ignore if we did not receive any event from the server. }, )); - remoteUriStr = _cast(await connection.sendRequest(method, { - 'deviceId': deviceId, - 'vmServiceUri': remoteVMServiceUri.toString(), - 'disableServiceAuthCodes': disableServiceAuthCodes, - })); + final Object? response = await connection.sendRequest(method, { + 'deviceId': deviceId, + 'vmServiceUri': remoteVMServiceUri.toString(), + 'disableServiceAuthCodes': disableServiceAuthCodes, + }); + + if (response is Map) { + remoteUriStr = response['ddsUri'] as String?; + } else { + // For backwards compatibility in google3. + // TODO(bkonyi): remove once a newer version of the flutter_tool is rolled out. + remoteUriStr = _cast(response); + } } on String catch (e) { if (!e.contains(method)) { rethrow; @@ -850,16 +867,7 @@ class ProxiedDartDevelopmentService implements DartDevelopmentService { if (remoteUriStr == null) { _logger.printTrace('Remote daemon cannot start DDS. Start a local DDS instead.'); - _ddsStartedLocally = true; - await _localDds.startDartDevelopmentService( - vmServiceUri, - logger: logger, - hostPort: hostPort, - ipv6: ipv6, - disableServiceAuthCodes: disableServiceAuthCodes, - cacheStartupProfile: cacheStartupProfile, - ); - unawaited(_localDds.done.then(_completer.complete)); + await startLocalDds(); return; } @@ -869,7 +877,7 @@ class ProxiedDartDevelopmentService implements DartDevelopmentService { final Uri remoteUri = Uri.parse(remoteUriStr); final int localPort = await _proxiedPortForwarder.forward( remoteUri.port, - hostPort: hostPort, + hostPort: ddsPort, ipv6: ipv6, ); @@ -885,7 +893,7 @@ class ProxiedDartDevelopmentService implements DartDevelopmentService { @override Future shutdown() async { if (_ddsStartedLocally) { - await _localDds.shutdown(); + _localDds.shutdown(); _ddsStartedLocally = false; } else { await connection.sendRequest('device.shutdownDartDevelopmentService', { @@ -893,14 +901,6 @@ class ProxiedDartDevelopmentService implements DartDevelopmentService { }); } } - - @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 d304451db7..ae5f2b2a84 100644 --- a/packages/flutter_tools/lib/src/resident_devtools_handler.dart +++ b/packages/flutter_tools/lib/src/resident_devtools_handler.dart @@ -2,6 +2,10 @@ // 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'; @@ -110,18 +114,6 @@ 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( @@ -214,10 +206,12 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler { }, ); } on Exception catch (e) { - _logger.printError( - 'Failed to set DevTools server address: $e. Deep links to' - ' DevTools will not show in Flutter errors.', - ); + if (!_shutdown) { + _logger.printError( + 'Failed to set DevTools server address: $e. Deep links to' + ' DevTools will not show in Flutter errors.', + ); + } } } @@ -266,11 +260,13 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler { }, ); } on Exception catch (e) { - _logger.printError(e.toString()); - _logger.printError( - 'Failed to set vm service URI: $e. Deep links to DevTools' - ' will not show in Flutter errors.', - ); + 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.', + ); + } } } @@ -308,10 +304,10 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler { @override Future shutdown() async { - if (_devToolsLauncher == null || _shutdown || !_served) { + _shutdown = true; + if (_devToolsLauncher == null || !_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 1af14acbb8..209b0bd081 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart @@ -4,7 +4,6 @@ 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; @@ -15,6 +14,7 @@ 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,13 +252,9 @@ 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; @@ -270,11 +266,11 @@ class FlutterDevice { isWaitingForVm = true; bool existingDds = false; FlutterVmService? service; - if (enableDds) { + if (debuggingOptions.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', st); + completer.completeError('failed to connect to $vmServiceUri $e', st); } } // First check if the VM service is actually listening on vmServiceUri as @@ -286,7 +282,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'); + completer.completeError('failed to connect to $vmServiceUri $exception'); } return; } @@ -295,17 +291,13 @@ 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.startDartDevelopmentService( + await device!.dds.startDartDevelopmentServiceFromDebuggingOptions( vmServiceUri, - hostPort: ddsPort, - ipv6: ipv6, - disableServiceAuthCodes: disableServiceAuthCodes, - logger: globals.logger, - cacheStartupProfile: cacheStartupProfile, + debuggingOptions: debuggingOptions, ); - } on dds.DartDevelopmentServiceException catch (e, st) { + } on DartDevelopmentServiceException catch (e, st) { if (!allowExistingDdsInstance || - (e.errorCode != dds.DartDevelopmentServiceException.existingDdsInstanceError)) { + (e.errorCode != DartDevelopmentServiceException.existingDdsInstanceError)) { handleError(e, st); return; } else { @@ -326,7 +318,7 @@ class FlutterDevice { service = await Future.any( >[ connectToVmService( - enableDds ? (device!.dds.uri ?? vmServiceUri!): vmServiceUri!, + debuggingOptions.enableDds ? (device!.dds.uri ?? vmServiceUri!): vmServiceUri!, reloadSources: reloadSources, restart: restart, compileExpression: compileExpression, @@ -343,7 +335,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'); + completer.completeError('failed to connect to $vmServiceUri $exception'); } return; } @@ -472,7 +464,6 @@ class FlutterDevice { platformArgs: platformArgs, route: route, prebuiltApplication: prebuiltMode, - ipv6: hotRunner.ipv6!, userIdentifier: userIdentifier, ); @@ -538,7 +529,6 @@ class FlutterDevice { platformArgs: platformArgs, route: route, prebuiltApplication: prebuiltMode, - ipv6: coldRunner.ipv6!, userIdentifier: userIdentifier, ); @@ -648,6 +638,7 @@ 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 @@ -1096,7 +1087,6 @@ abstract class ResidentRunner extends ResidentHandlers { required this.target, required this.debuggingOptions, String? projectRootPath, - this.ipv6, this.stayResident = true, this.hotMode = true, String? dillOutputPath, @@ -1119,6 +1109,7 @@ 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); } @@ -1136,7 +1127,6 @@ 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; @@ -1148,6 +1138,7 @@ 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; @@ -1228,7 +1219,6 @@ abstract class ResidentRunner extends ResidentHandlers { Future run({ Completer? connectionInfoCompleter, Completer? appStartedCompleter, - bool enableDevTools = false, String? route, }); @@ -1240,7 +1230,6 @@ abstract class ResidentRunner extends ResidentHandlers { Completer? connectionInfoCompleter, Completer? appStartedCompleter, bool allowExistingDdsInstance = false, - bool enableDevTools = false, bool needsFullRestart = true, }); @@ -1306,19 +1295,21 @@ 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 - await shutdownDartDevelopmentService(); + shutdownDartDevelopmentService(); } @override Future detach() async { + // TODO(bkonyi): remove when ready to serve DevTools from DDS. await residentDevtoolsHandler!.shutdown(); await stopEchoingDeviceLog(); await preExit(); - await shutdownDartDevelopmentService(); + shutdownDartDevelopmentService(); appFinished(); } @@ -1328,12 +1319,10 @@ abstract class ResidentRunner extends ResidentHandlers { ); } - Future shutdownDartDevelopmentService() async { - await Future.wait( - flutterDevices.map>( - (FlutterDevice? device) => device?.device?.dds.shutdown() ?? Future.value() - ) - ); + void shutdownDartDevelopmentService() { + for (final FlutterDevice device in flutterDevices) { + device.device?.dds.shutdown(); + } } @protected @@ -1402,18 +1391,14 @@ 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(); @@ -1503,7 +1488,8 @@ abstract class ResidentRunner extends ResidentHandlers { bool get reportedDebuggers => _reportedDebuggers; bool _reportedDebuggers = false; - void printDebuggerList({ bool includeVmService = true, bool includeDevtools = true }) { + void printDebuggerList({bool includeVmService = true, bool includeDevtools = true}) { + // TODO(bkonyi): update this logic when ready to serve DevTools from DDS. final DevToolsServerAddress? devToolsServerAddress = residentDevtoolsHandler!.activeDevToolsServer; if (!residentDevtoolsHandler!.readyToAnnounce) { includeDevtools = false; @@ -1956,6 +1942,7 @@ 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 63ac8dc2d7..e54adcc4c2 100644 --- a/packages/flutter_tools/lib/src/run_cold.dart +++ b/packages/flutter_tools/lib/src/run_cold.dart @@ -21,7 +21,6 @@ class ColdRunner extends ResidentRunner { this.traceStartup = false, this.awaitFirstFrameWhenTracing = true, this.applicationBinary, - bool super.ipv6 = false, super.stayResident, super.machine, super.devtoolsHandler, @@ -47,7 +46,6 @@ class ColdRunner extends ResidentRunner { Future run({ Completer? connectionInfoCompleter, Completer? appStartedCompleter, - bool enableDevTools = false, String? route, }) async { try { @@ -78,18 +76,18 @@ class ColdRunner extends ResidentRunner { } } - 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 (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 (flutterDevices.first.vmServiceUris != null) { @@ -142,7 +140,6 @@ class ColdRunner extends ResidentRunner { Completer? connectionInfoCompleter, Completer? appStartedCompleter, bool allowExistingDdsInstance = false, - bool enableDevTools = false, bool needsFullRestart = true, }) async { _didAttach = true; @@ -166,18 +163,8 @@ class ColdRunner extends ResidentRunner { } } - 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 (debuggingEnabled && debuggingOptions.serveObservatory) { + await enableObservatory(); } appStartedCompleter?.complete(); @@ -202,13 +189,12 @@ class ColdRunner extends ResidentRunner { for (final FlutterDevice? flutterDevice in flutterDevices) { 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 d79a01daac..2684e093b5 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -86,7 +86,6 @@ class HotRunner extends ResidentRunner { super.projectRootPath, super.dillOutputPath, super.stayResident, - bool super.ipv6 = false, super.machine, super.devtoolsHandler, StopwatchFactory stopwatchFactory = const StopwatchFactory(), @@ -228,7 +227,6 @@ class HotRunner extends ResidentRunner { Completer? connectionInfoCompleter, Completer? appStartedCompleter, bool allowExistingDdsInstance = false, - bool enableDevTools = false, bool needsFullRestart = true, }) async { _didAttach = true; @@ -253,7 +251,8 @@ class HotRunner extends ResidentRunner { await enableObservatory(); } - if (enableDevTools) { + // 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, @@ -362,7 +361,6 @@ class HotRunner extends ResidentRunner { Future run({ Completer? connectionInfoCompleter, Completer? appStartedCompleter, - bool enableDevTools = false, String? route, }) async { await _calculateTargetPlatform(); @@ -470,7 +468,6 @@ class HotRunner extends ResidentRunner { return attach( connectionInfoCompleter: connectionInfoCompleter, appStartedCompleter: appStartedCompleter, - enableDevTools: enableDevTools, needsFullRestart: false, ); } @@ -790,7 +787,11 @@ 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 da635715c6..4249210c53 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 specified, "--$kDevToolsServerAddress" is ignored.' + 'If "--no-$kEnableDevTools" is 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 50783f8435..798e129794 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart @@ -414,6 +414,7 @@ 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 68648b3525..3cd32358cc 100644 --- a/packages/flutter_tools/lib/src/test/flutter_platform.dart +++ b/packages/flutter_tools/lib/src/test/flutter_platform.dart @@ -6,7 +6,6 @@ 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'; @@ -70,7 +69,6 @@ FlutterPlatform installHook({ Device? integrationTestDevice, String? integrationTestUserIdentifier, TestTimeRecorder? testTimeRecorder, - UriConverter? uriConverter, TestCompilerNativeAssetsBuilder? nativeAssetsBuilder, BuildInfo? buildInfo, }) { @@ -102,7 +100,6 @@ FlutterPlatform installHook({ integrationTestDevice: integrationTestDevice, integrationTestUserIdentifier: integrationTestUserIdentifier, testTimeRecorder: testTimeRecorder, - uriConverter: uriConverter, nativeAssetsBuilder: nativeAssetsBuilder, buildInfo: buildInfo, ); @@ -309,7 +306,6 @@ class FlutterPlatform extends PlatformPlugin { this.integrationTestDevice, this.integrationTestUserIdentifier, this.testTimeRecorder, - this.uriConverter, this.nativeAssetsBuilder, this.buildInfo, }); @@ -331,9 +327,6 @@ 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 @@ -462,7 +455,6 @@ 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 e019556ee6..1cb717e60b 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,7 +43,6 @@ 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()); @@ -64,8 +63,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(); @@ -170,16 +169,16 @@ class FlutterTesterTestDevice extends TestDevice { debuggingOptions.hostVmServicePort == detectedUri.port); Uri? forwardingUri; - DartDevelopmentService? dds; if (debuggingOptions.enableDds) { logger.printTrace('test $id: Starting Dart Development Service'); - dds = await startDds( + + await _ddsLauncher.startDartDevelopmentServiceFromDebuggingOptions( detectedUri, - uriConverter: uriConverter, + debuggingOptions: debuggingOptions, ); - forwardingUri = dds.uri; - logger.printTrace('test $id: Dart Development Service started at ${dds.uri}, forwarding to VM service at ${dds.remoteVmServiceUri}.'); + forwardingUri = _ddsLauncher.uri; + logger.printTrace('test $id: Dart Development Service started at $forwardingUri, forwarding to VM service at $detectedUri.'); } else { forwardingUri = detectedUri; } @@ -201,7 +200,7 @@ class FlutterTesterTestDevice extends TestDevice { if (debuggingOptions.startPaused && !machine!) { logger.printStatus('The Dart VM service is listening on $forwardingUri'); - await _startDevTools(forwardingUri, dds); + await _startDevTools(forwardingUri, _ddsLauncher); logger.printStatus(''); logger.printStatus('The test process has been started. Set any relevant breakpoints and then resume the test in the debugger.'); } @@ -248,28 +247,6 @@ 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 @@ -285,6 +262,7 @@ 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...'); @@ -297,10 +275,6 @@ 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 fa0aff8969..7bbadbb918 100644 --- a/packages/flutter_tools/lib/src/test/runner.dart +++ b/packages/flutter_tools/lib/src/test/runner.dart @@ -40,7 +40,6 @@ abstract class FlutterTestRunner { String? tags, String? excludeTags, bool enableVmService = false, - bool ipv6 = false, bool machine = false, String? precompiledDillPath, Map? precompiledDillFiles, @@ -108,7 +107,6 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner { String? tags, String? excludeTags, bool enableVmService = false, - bool ipv6 = false, bool machine = false, String? precompiledDillPath, Map? precompiledDillFiles, @@ -239,7 +237,7 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner { ..addAll(testFiles.map((Uri uri) => uri.toString())); final InternetAddressType serverType = - ipv6 ? InternetAddressType.IPv6 : InternetAddressType.IPv4; + debuggingOptions.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 8c895e4aed..40d83e79ab 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 Logger logger, + required super.logger, required FileSystem fileSystem, required Artifacts artifacts, }) : _processManager = processManager, @@ -135,7 +135,6 @@ class FlutterTesterDevice extends Device { required DebuggingOptions debuggingOptions, Map platformArgs = const {}, bool prebuiltApplication = false, - bool ipv6 = false, String? userIdentifier, }) async { final BuildInfo buildInfo = debuggingOptions.buildInfo; @@ -193,7 +192,7 @@ class FlutterTesterDevice extends Device { getLogReader(), hostPort: debuggingOptions.hostVmServicePort, devicePort: debuggingOptions.deviceVmServicePort, - ipv6: ipv6, + ipv6: debuggingOptions.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 8969fa50ea..ef729796b4 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 Logger logger, + required super.logger, }) : _fileSystem = fileSystem, _logger = logger, super( @@ -124,7 +124,6 @@ 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 @@ -382,7 +381,7 @@ String parseVersionForWindows(String input) { /// A special device type to allow serving for arbitrary browsers. class WebServerDevice extends Device { WebServerDevice({ - required Logger logger, + required super.logger, }) : _logger = logger, super( 'web-server', @@ -460,7 +459,6 @@ 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 475a3ef5fc..af7424a3b7 100644 --- a/packages/flutter_tools/lib/src/web/web_runner.dart +++ b/packages/flutter_tools/lib/src/web/web_runner.dart @@ -26,7 +26,6 @@ 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 dfd23e70cd..33e2414922 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 = Signals.test(); + signals = FakeSignals(); processInfo = FakeProcessInfo(); testDeviceManager = TestDeviceManager(logger: logger); }); @@ -802,6 +802,13 @@ 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 { @@ -1394,11 +1401,14 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService @override Future startDartDevelopmentService( Uri vmServiceUri, { - required Logger logger, - int? hostPort, + int? ddsPort, + FlutterDevice? device, 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 d930dfe674..a672732f55 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/daemon_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/daemon_test.dart @@ -701,7 +701,8 @@ void main() { final DaemonMessage startResponse = await broadcastOutput.firstWhere(_notEvent); expect(startResponse.data['id'], 0); expect(startResponse.data['error'], isNull); - final String? ddsUri = startResponse.data['result'] as String?; + final Map? result = startResponse.data['result'] as Map?; + final String? ddsUri = result!['ddsUri'] as String?; expect(ddsUri, fakeDdsUri.toString()); expect(device.dds.startCalled, true); expect(device.dds.startDisableServiceAuthCodes, false); @@ -1246,11 +1247,14 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService @override Future startDartDevelopmentService( Uri vmServiceUri, { - required Logger logger, - int? hostPort, + int? ddsPort, + FlutterDevice? device, bool? ipv6, bool? disableServiceAuthCodes, + bool enableDevTools = false, bool cacheStartupProfile = false, + String? google3WorkspaceRoot, + Uri? devToolsServerAddress, }) async { startCalled = true; startVMServiceUri = vmServiceUri; 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 50ffec8db5..e0517d855c 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, bool ipv6) async { } + Future reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions) 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, bool ipv6) async { } + Future reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions) 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 509ea1efc7..b9550ecd97 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart @@ -1544,16 +1544,13 @@ class CapturingAppDomain extends AppDomain { String? projectRootPath, String? packagesFilePath, String? dillOutputPath, - bool ipv6 = false, String? isolateFilter, bool machine = true, String? userIdentifier, - bool enableDevTools = true, - String? flavor, - HotRunnerNativeAssetsBuilder? nativeAssetsBuilder, + required HotRunnerNativeAssetsBuilder? nativeAssetsBuilder, }) async { this.userIdentifier = userIdentifier; - this.enableDevTools = enableDevTools; + enableDevTools = options.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 e16015ee4c..4ef1666aed 100644 --- a/packages/flutter_tools/test/general.shard/cold_test.dart +++ b/packages/flutter_tools/test/general.shard/cold_test.dart @@ -213,13 +213,9 @@ class TestFlutterDevice extends FlutterDevice { GetSkSLMethod? getSkSLMethod, FlutterProject? flutterProject, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, - bool enableDds = true, - bool cacheStartupProfile = false, - bool disableServiceAuthCodes = false, + required DebuggingOptions debuggingOptions, int? hostVmServicePort, - int? ddsPort, - bool? ipv6 = false, - bool allowExistingDdsInstance = false, + required bool allowExistingDdsInstance, }) 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 c1a62a17ca..8f7bf36193 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 2952af5378..50e560c16a 100644 --- a/packages/flutter_tools/test/general.shard/devtools_launcher_test.dart +++ b/packages/flutter_tools/test/general.shard/devtools_launcher_test.dart @@ -33,6 +33,8 @@ 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, @@ -49,6 +51,7 @@ 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(); @@ -95,6 +98,7 @@ 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, @@ -120,6 +124,7 @@ 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', ], @@ -151,6 +156,7 @@ 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', []), @@ -176,6 +182,7 @@ 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 c2c114cbb9..a461db6431 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), true), + () => driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: 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), true), + () async => driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: 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), true); + await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: 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), true); + await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: 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), true); + await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: 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), true); + await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, enableDds: false, ipv6: 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), true); + await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: 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), true); + await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)); await driverService.stop(writeSkslOnExit: fileSystem.file('out.json')); expect(device.didStopApp, true); @@ -327,7 +327,6 @@ void main() { Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), device, DebuggingOptions.enabled(BuildInfo.debug), - false, ); await driverService.stop(); }); @@ -351,7 +350,6 @@ void main() { Uri.parse('ws://127.0.0.1:63426/1UasC_ihpXY=/ws/'), device, DebuggingOptions.enabled(BuildInfo.debug), - false, ); await driverService.stop(); }); @@ -375,7 +373,6 @@ void main() { Uri.parse('ws://127.0.0.1:63426/1UasC_ihpXY=/ws'), device, DebuggingOptions.enabled(BuildInfo.debug), - false, ); await driverService.stop(); }); @@ -399,7 +396,6 @@ void main() { Uri.parse('ws://127.0.0.1:63426/wsasC_ihpXY=/ws'), device, DebuggingOptions.enabled(BuildInfo.debug), - false, ); await driverService.stop(); }); @@ -416,7 +412,6 @@ void main() { Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), device, DebuggingOptions.enabled(BuildInfo.debug), - false, ); await driverService.stop(); }); @@ -540,7 +535,9 @@ class FakeDevice extends Fake implements Device { } } -class FakeDartDevelopmentService extends Fake implements DartDevelopmentService { +class FakeDartDevelopmentService extends Fake + with DartDevelopmentServiceLocalOperationsMixin + implements DartDevelopmentService { bool started = false; bool disposed = false; @@ -550,11 +547,14 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService @override Future startDartDevelopmentService( Uri vmServiceUri, { - required Logger logger, - int? hostPort, + FlutterDevice? device, + int? ddsPort, 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 47fd1645b7..8854e2c7a6 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), true); + await service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: 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), true); + await service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, webLaunchUrl: testUrl, ipv6: 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), true), + service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, webLaunchUrl: invalidTestUrl, ipv6: 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), true), + service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: 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 60a6b1610f..ed4fa844a2 100644 --- a/packages/flutter_tools/test/general.shard/flutter_platform_test.dart +++ b/packages/flutter_tools/test/general.shard/flutter_platform_test.dart @@ -102,7 +102,6 @@ void main() { platformPluginRegistration: (FlutterPlatform platform) { capturedPlatform = platform; }, - uriConverter: (String input) => '$input/test', ); expect(identical(capturedPlatform, flutterPlatform), equals(true)); @@ -119,7 +118,6 @@ 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 adf6c44037..7a52bf22af 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,7 +48,6 @@ void main() { processManager: processManager, enableVmService: enableVmService, dartEntrypointArgs: dartEntrypointArgs, - uriConverter: (String input) => '$input/converted', enableImpeller: enableImpeller, ); @@ -198,6 +197,7 @@ void main() { }); group('DDS', () { + late DDSLauncherCallback originalDdsLauncher; setUp(() { processManager = FakeProcessManager.list([ const FakeCommand( @@ -221,26 +221,30 @@ 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('sets up UriConverter from context', () async { - await device.start('example.dill'); - await device.vmServiceUri; - - final FakeDartDevelopmentService dds = (device as TestFlutterTesterDevice).dds - as FakeDartDevelopmentService; - final String? result = dds - .uriConverter - ?.call('test'); - expect(result, 'test/converted'); + final Uri? uri = await (device as TestFlutterTesterDevice).vmServiceUri; + expect(uri!.port, 1234); }); }); } @@ -255,7 +259,6 @@ class TestFlutterTesterDevice extends FlutterTesterTestDevice { required super.processManager, required super.enableVmService, required List dartEntrypointArgs, - required UriConverter uriConverter, required bool enableImpeller, }) : super( id: 999, @@ -279,27 +282,7 @@ 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( @@ -319,18 +302,6 @@ 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 e9e24d7b4d..18e1a03fee 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,6 +9,7 @@ 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'; @@ -38,6 +39,7 @@ void main() { late FakeProcessManager fakeSuccessfulProcessManager; late FakeProcessManager fakeFailedProcessManagerForHostAddress; late File sshConfig; + final Logger logger = FakeLogger(); setUp(() { memoryFileSystem = MemoryFileSystem.test(); @@ -114,7 +116,7 @@ void main() { required BuildMode mode, }) async { const String appName = 'app_name'; - final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123'); + final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123', logger: logger); globals.fs.directory('fuchsia').createSync(recursive: true); final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync(); pubspecFile.writeAsStringSync('name: $appName'); @@ -186,7 +188,7 @@ void main() { 'start and stop prebuilt in release mode fails without session', () async { const String appName = 'app_name'; - final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123'); + final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123', logger: logger); globals.fs.directory('fuchsia').createSync(recursive: true); final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync(); pubspecFile.writeAsStringSync('name: $appName'); @@ -216,7 +218,7 @@ void main() { testUsingContext('start and stop prebuilt in release mode with session', () async { const String appName = 'app_name'; - final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123'); + final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123', logger: logger); globals.fs.directory('fuchsia').createSync(recursive: true); final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync(); pubspecFile.writeAsStringSync('name: $appName'); @@ -409,7 +411,7 @@ void main() { }); testUsingContext('fail when cant get host address', () async { - expect(() async => FuchsiaDeviceWithFakeDiscovery('123').hostAddress, + expect(() async => FuchsiaDeviceWithFakeDiscovery('123', logger: logger).hostAddress, throwsToolExit(message: 'Failed to get local address, aborting.')); }, overrides: { Artifacts: () => artifacts, @@ -479,7 +481,7 @@ Process _createFakeProcess({ } class FuchsiaDeviceWithFakeDiscovery extends FuchsiaDevice { - FuchsiaDeviceWithFakeDiscovery(super.id, {super.name = ''}); + FuchsiaDeviceWithFakeDiscovery(super.id, {super.name = '', required super.logger}); @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 b68c2a4abe..90a849b664 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,6 +26,7 @@ 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; @@ -58,6 +59,7 @@ void main() { late MemoryFileSystem memoryFileSystem; late File sshConfig; late FakeProcessManager processManager; + final Logger logger = FakeLogger(); setUp(() { memoryFileSystem = MemoryFileSystem.test(); @@ -68,7 +70,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); + final FuchsiaDevice device = FuchsiaDevice(deviceId, name: name, logger: logger); expect(device.id, deviceId); expect(device.name, name); @@ -77,7 +79,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); + final FuchsiaDevice device = FuchsiaDevice(deviceId, name: name, logger: logger); expect(device.supportsRuntimeMode(BuildMode.debug), true); expect(device.supportsRuntimeMode(BuildMode.profile), true); @@ -157,7 +159,7 @@ void main() { testUsingContext('disposing device disposes the portForwarder', () async { final FakePortForwarder portForwarder = FakePortForwarder(); - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); device.portForwarder = portForwarder; await device.dispose(); @@ -165,7 +167,7 @@ void main() { }); testWithoutContext('default capabilities', () async { - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FlutterProject project = FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory); memoryFileSystem.directory('fuchsia').createSync(recursive: true); @@ -178,13 +180,13 @@ void main() { }); test('is ephemeral', () { - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); expect(device.ephemeral, true); }); testWithoutContext('supported for project', () async { - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FlutterProject project = FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory); memoryFileSystem.directory('fuchsia').createSync(recursive: true); @@ -194,7 +196,7 @@ void main() { }); testWithoutContext('not supported for project', () async { - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FlutterProject project = FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory); memoryFileSystem.file('pubspec.yaml').createSync(); @@ -204,7 +206,7 @@ void main() { testUsingContext('targetPlatform does not throw when sshConfig is missing', () async { - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); expect(await device.targetPlatform, TargetPlatform.fuchsia_arm64); }, overrides: { @@ -219,7 +221,7 @@ void main() { stdout: 'aarch64', )); - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); expect(await device.targetPlatform, TargetPlatform.fuchsia_arm64); }, overrides: { FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), @@ -233,7 +235,7 @@ void main() { stdout: 'x86_64', )); - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); expect(await device.targetPlatform, TargetPlatform.fuchsia_x64); }, overrides: { FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), @@ -254,7 +256,7 @@ void main() { 'fe80::8c6c:2fff:fe3d:c5e1%ethp0003 50666 fe80::5054:ff:fe63:5e7a%ethp0003 22', )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'device', logger: logger); expect(await device.hostAddress, 'fe80::8c6c:2fff:fe3d:c5e1%25ethp0003'); }, overrides: { FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), @@ -275,7 +277,7 @@ void main() { exitCode: 1, )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'device', logger: logger); await expectLater(() => device.hostAddress, throwsToolExit()); }, overrides: { FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), @@ -295,7 +297,7 @@ void main() { ], )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'device', logger: logger); expect(() async => device.hostAddress, throwsToolExit()); }, overrides: { FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), @@ -307,6 +309,7 @@ void main() { group('displays friendly error when', () { late File artifactFile; late FakeProcessManager processManager; + final Logger logger = FakeLogger(); setUp(() { processManager = FakeProcessManager.empty(); @@ -323,7 +326,7 @@ void main() { 'find /hub -name vmservice-port' ], )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'device', logger: logger); await expectLater( device.servicePorts, @@ -352,6 +355,7 @@ void main() { late FakeProcessManager processManager; late File ffx; late File sshConfig; + final Logger logger = FakeLogger(); setUp(() { processManager = FakeProcessManager.empty(); @@ -374,7 +378,7 @@ void main() { stdout: exampleUtcLogs, completer: lock, )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester'); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); final DeviceLogReader reader = device.getLogReader(app: FuchsiaModulePackage(name: 'example_app')); final List logLines = []; @@ -411,7 +415,7 @@ void main() { stdout: exampleUtcLogs, completer: lock, )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester'); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); final DeviceLogReader reader = device.getLogReader(app: FuchsiaModulePackage(name: 'example_app')); final List logLines = []; @@ -446,7 +450,7 @@ void main() { stdout: exampleUtcLogs, completer: lock, )); - final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester'); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); final DeviceLogReader reader = device.getLogReader(); final List logLines = []; reader.logLines.listen((String line) { @@ -475,13 +479,14 @@ 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'); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); expect(device.supportsScreenshot, true); }, overrides: { Platform: () => FakePlatform(), @@ -489,7 +494,7 @@ void main() { }); testUsingContext('is not supported on Windows', () { - final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester'); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); expect(device.supportsScreenshot, false); }, overrides: { @@ -500,7 +505,7 @@ void main() { }); test("takeScreenshot throws if file isn't .ppm", () async { - final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester'); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); await expectLater( () => device.takeScreenshot(globals.fs.file('file.invalid')), throwsA(isA().having( @@ -518,7 +523,7 @@ void main() { '0.0.0.0', 'screencap > /tmp/screenshot.ppm', ], exitCode: 1, stderr: '')); - final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester'); + final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester', logger: logger); await expectLater( () => device.takeScreenshot(globals.fs.file('file.ppm')), @@ -540,7 +545,7 @@ void main() { }); testUsingContext('takeScreenshot throws if scp failed', () async { - final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester'); + final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester', logger: logger); processManager.addCommand(const FakeCommand( command: [ 'ssh', @@ -593,7 +598,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'); + final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester', logger: logger); processManager.addCommand(const FakeCommand( command: [ 'ssh', @@ -642,7 +647,7 @@ void main() { }, testOn: 'posix'); testUsingContext('takeScreenshot returns', () async { - final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester'); + final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester', logger: logger); processManager.addCommand(const FakeCommand( command: [ 'ssh', @@ -688,6 +693,7 @@ void main() { group('portForwarder', () { late FakeProcessManager processManager; late File sshConfig; + final Logger logger = FakeLogger(); setUp(() { processManager = FakeProcessManager.empty(); @@ -697,7 +703,7 @@ void main() { testUsingContext( '`unforward` prints stdout and stderr if ssh command failed', () async { - final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester'); + final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); processManager.addCommand(const FakeCommand( command: [ 'ssh', @@ -861,6 +867,7 @@ void main() { group('sdkNameAndVersion: ', () { late File sshConfig; late FakeProcessManager processManager; + final Logger logger = FakeLogger(); setUp(() { sshConfig = MemoryFileSystem.test().file('ssh_config') @@ -869,7 +876,7 @@ void main() { }); testUsingContext('does not throw on non-existent ssh config', () async { - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); expect(await device.sdkNameAndVersion, equals('Fuchsia')); }, overrides: { @@ -887,7 +894,7 @@ void main() { '123', 'cat /pkgfs/packages/build-info/0/data/version' ], stdout: 'version')); - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); expect(await device.sdkNameAndVersion, equals('Fuchsia version')); }, overrides: { @@ -907,7 +914,7 @@ void main() { ], exitCode: 1, )); - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); expect(await device.sdkNameAndVersion, equals('Fuchsia')); }, overrides: { @@ -927,7 +934,7 @@ void main() { 'cat /pkgfs/packages/build-info/0/data/version' ], )); - final FuchsiaDevice device = FuchsiaDevice('123', name: 'device'); + final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); expect(await device.sdkNameAndVersion, equals('Fuchsia')); }, overrides: { @@ -1041,11 +1048,14 @@ class FakeDartDevelopmentService extends Fake @override Future startDartDevelopmentService( Uri vmServiceUri, { - required Logger logger, - int? hostPort, + FlutterDevice? device, + int? ddsPort, 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 30d2c5fc9b..39f0aa0da5 100644 --- a/packages/flutter_tools/test/general.shard/hot_shared.dart +++ b/packages/flutter_tools/test/general.shard/hot_shared.dart @@ -150,12 +150,10 @@ class TestFlutterDevice extends FlutterDevice { GetSkSLMethod? getSkSLMethod, FlutterProject? flutterProject, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, - bool disableServiceAuthCodes = false, - bool enableDds = true, - bool cacheStartupProfile = false, - bool? ipv6 = false, + required DebuggingOptions debuggingOptions, int? hostVmServicePort, - int? ddsPort, + bool? ipv6 = false, + bool enableDevTools = false, 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 35f06af00f..469f6dc974 100644 --- a/packages/flutter_tools/test/general.shard/hot_test.dart +++ b/packages/flutter_tools/test/general.shard/hot_test.dart @@ -137,8 +137,7 @@ void main() { ..writeAsStringSync('\n'); final FakeDevice device = FakeDevice(); final List devices = [ - FlutterDevice(device, generator: residentCompiler, buildInfo: BuildInfo.debug, developmentShaderCompiler: const FakeShaderCompiler()) - ..devFS = FakeDevFs(), + FakeFlutterDevice(device), ]; final OperationResult result = await HotRunner( devices, @@ -146,7 +145,6 @@ 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 ce27d1bc9c..30d419303e 100644 --- a/packages/flutter_tools/test/general.shard/ios/simulators_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/simulators_test.dart @@ -37,6 +37,7 @@ void main() { late FakePlatform osx; late FileSystemUtils fsUtils; late MemoryFileSystem fileSystem; + final Logger logger = FakeLogger(); setUp(() { osx = FakePlatform( @@ -62,6 +63,7 @@ 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); @@ -87,6 +89,7 @@ void main() { name: 'iPhone 11', simControl: FakeSimControl(), simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-14-4', + logger: logger, ); expect(simulator.supportsRuntimeMode(BuildMode.debug), true); @@ -113,6 +116,7 @@ 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: { @@ -130,6 +134,7 @@ 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: { @@ -154,6 +159,7 @@ void main() { name: 'iPhone SE', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simControl: simControl, + logger: logger, ); expect(await device.sdkMajorVersion, 11); @@ -165,6 +171,7 @@ void main() { name: 'iPhone SE', simulatorCategory: 'iOS 11.2', simControl: simControl, + logger: logger, ); expect(await device.sdkMajorVersion, 11); @@ -176,6 +183,7 @@ void main() { name: 'iPhone SE', simulatorCategory: 'iOS 11.2', simControl: simControl, + logger: logger, ); expect(device.category, Category.mobile); @@ -195,6 +203,7 @@ void main() { name: 'Apple TV', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.tvOS-14-5', + logger: logger, ); expect(simulator.isSupported(), false); }, overrides: { @@ -209,6 +218,7 @@ void main() { name: 'Apple Watch', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.watchOS-8-0', + logger: logger, ).isSupported(), false); }, overrides: { Platform: () => osx, @@ -222,6 +232,7 @@ void main() { name: 'iPad 2', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', + logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -235,6 +246,7 @@ void main() { name: 'iPad Retina', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', + logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -248,6 +260,7 @@ void main() { name: 'iPhone 5', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', + logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -261,6 +274,7 @@ void main() { name: 'iPhone 5s', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', + logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -274,6 +288,7 @@ void main() { name: 'iPhone SE', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', + logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -287,6 +302,7 @@ void main() { name: 'iPhone 7 Plus', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', + logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -300,6 +316,7 @@ void main() { name: 'iPhone X', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', + logger: logger, ).isSupported(), true); }, overrides: { Platform: () => osx, @@ -337,6 +354,7 @@ 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'); @@ -360,6 +378,7 @@ void main() { name: 'iPhone SE', simulatorCategory: 'iOS 9.3', simControl: simControl, + logger: logger, ); fakeProcessManager.addCommand(const FakeCommand(command: [ 'tail', @@ -387,6 +406,7 @@ 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 ' @@ -421,6 +441,7 @@ 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 ' @@ -485,6 +506,7 @@ 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), @@ -520,6 +542,7 @@ 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), @@ -568,6 +591,7 @@ 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), @@ -640,6 +664,7 @@ 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), @@ -683,6 +708,7 @@ 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), @@ -824,6 +850,7 @@ 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); @@ -908,6 +935,7 @@ 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); @@ -1086,6 +1114,7 @@ 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'); @@ -1115,6 +1144,7 @@ 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; @@ -1146,6 +1176,7 @@ 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'); @@ -1218,6 +1249,7 @@ 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'); @@ -1268,6 +1300,7 @@ flutter: name: 'iPhone 11', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', + logger: logger, ); expect(simulator.isSupportedForProject(flutterProject), true); }, overrides: { @@ -1288,6 +1321,7 @@ flutter: name: 'iPhone 11', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', + logger: logger, ); expect(simulator.isSupportedForProject(flutterProject), true); }, overrides: { @@ -1306,6 +1340,7 @@ flutter: name: 'iPhone 11', simControl: simControl, simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', + logger: logger, ); expect(simulator.isSupportedForProject(flutterProject), false); }, overrides: { @@ -1320,6 +1355,7 @@ 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 8efd65c203..a24f3fa513 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,6 +17,7 @@ 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'; @@ -644,9 +645,8 @@ void main() { final Future startFuture = dds.startDartDevelopmentService( Uri.parse('http://127.0.0.1:100/fake'), disableServiceAuthCodes: true, - hostPort: 150, + ddsPort: 150, ipv6: false, - logger: bufferLogger, ); final DaemonMessage startMessage = await broadcastOutput.first; @@ -658,7 +658,9 @@ void main() { 'disableServiceAuthCodes': true, }); - serverDaemonConnection.sendResponse(startMessage.data['id']!, 'http://127.0.0.1:300/remote'); + serverDaemonConnection.sendResponse( startMessage.data['id']!, const { + 'ddsUri': 'http://127.0.0.1:300/remote', + }); await startFuture; expect(portForwarder.receivedLocalForwardedPort, 100); @@ -701,9 +703,8 @@ void main() { final Future startFuture = dds.startDartDevelopmentService( Uri.parse('http://127.0.0.1:100/fake'), disableServiceAuthCodes: true, - hostPort: 150, + ddsPort: 150, ipv6: false, - logger: bufferLogger, ); final DaemonMessage startMessage = await broadcastOutput.first; @@ -715,7 +716,9 @@ void main() { 'disableServiceAuthCodes': true, }); - serverDaemonConnection.sendResponse(startMessage.data['id']!, 'http://127.0.0.1:300/remote'); + serverDaemonConnection.sendResponse(startMessage.data['id']!, { + 'ddsUri': 'http://127.0.0.1:300/remote', + }); await startFuture; expect(portForwarder.receivedLocalForwardedPort, 100); @@ -758,9 +761,8 @@ void main() { await dds.startDartDevelopmentService( Uri.parse('http://127.0.0.1:100/fake'), disableServiceAuthCodes: true, - hostPort: 150, + ddsPort: 150, ipv6: false, - logger: bufferLogger, ); expect(localDds.startCalled, true); @@ -797,9 +799,8 @@ void main() { final Future startFuture = dds.startDartDevelopmentService( Uri.parse('http://127.0.0.1:100/fake'), disableServiceAuthCodes: true, - hostPort: 150, + ddsPort: 150, ipv6: false, - logger: bufferLogger, ); expect(localDds.startCalled, false); @@ -1178,11 +1179,14 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService @override Future startDartDevelopmentService( Uri vmServiceUri, { - required Logger logger, - int? hostPort, + FlutterDevice? device, + int? ddsPort, bool? ipv6, bool? disableServiceAuthCodes, + bool enableDevTools = false, bool cacheStartupProfile = false, + String? google3WorkspaceRoot, + Uri? devToolsServerAddress, }) async { startCalled = true; startUri = vmServiceUri; 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 fb2c724240..d25d9134fd 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,12 +469,14 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService @override Future startDartDevelopmentService( - Uri observatoryUri, { - required Logger logger, - int? hostPort, - bool? ipv6, + Uri vmServiceUri, { + int? ddsPort, bool? disableServiceAuthCodes, + bool? ipv6, + bool enableDevTools = true, bool cacheStartupProfile = false, + String? google3WorkspaceRoot, + Uri? devToolsServerAddress, }) async { started = true; } @@ -483,7 +485,4 @@ 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 c6da20415e..f078cb0696 100644 --- a/packages/flutter_tools/test/general.shard/resident_runner_helpers.dart +++ b/packages/flutter_tools/test/general.shard/resident_runner_helpers.dart @@ -4,7 +4,6 @@ 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'; @@ -151,11 +150,16 @@ const FakeVmServiceRequest evictShader = FakeVmServiceRequest( } ); +const DartDevelopmentServiceInstance fakeDartDevelopmentServiceInstance = ( + process: null, + serviceUri: null, + devToolsUri: null, + dtdUri: null, +); + final Uri testUri = Uri.parse('foo://bar'); -// This implements [dds.DartDevelopmentService], not the [DartDevelopmentService] -// interface from package:flutter_tools. -class FakeDartDevelopmentService extends Fake implements dds.DartDevelopmentService { +class FakeDartDevelopmentService extends Fake with DartDevelopmentServiceLocalOperationsMixin implements DartDevelopmentService { @override Future get done => Future.value(); @@ -163,21 +167,15 @@ class FakeDartDevelopmentService extends Fake implements dds.DartDevelopmentServ Uri? get uri => null; } -class FakeDartDevelopmentServiceException implements dds.DartDevelopmentServiceException { +class FakeDartDevelopmentServiceException implements DartDevelopmentServiceException { FakeDartDevelopmentServiceException({this.message = defaultMessage}); @override - final int errorCode = dds.DartDevelopmentServiceException.existingDdsInstanceError; + final int errorCode = 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 { @@ -272,13 +270,10 @@ 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? ipv6 = false, + bool allowExistingDdsInstance = false, }) async { } @override @@ -317,16 +312,13 @@ 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, - int? hostVmServicePort, - int? ddsPort, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, + required DebuggingOptions debuggingOptions, + int? hostVmServicePort, + bool? ipv6 = false, bool allowExistingDdsInstance = false, }) async { } @@ -435,7 +427,7 @@ class FakeDevice extends Fake implements Device { String get name => 'FakeDevice'; @override - late DartDevelopmentService dds; + late DartDevelopmentService dds = FakeDartDevelopmentService(); @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 7c1a8b899e..b0f4f8623e 100644 --- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart @@ -4,12 +4,10 @@ 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; @@ -65,8 +63,8 @@ void main() { stayResident: false, debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), target: 'main.dart', + analytics: fakeAnalytics, devtoolsHandler: createNoOpHandler, - analytics: globals.analytics, ); }, overrides: { Analytics: () => FakeAnalytics(), @@ -90,7 +88,6 @@ void main() { final Future result = residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, ); final Future connectionInfo = futureConnectionInfo.future; @@ -122,7 +119,7 @@ void main() { ); flutterDevice.generator = residentCompiler; - expect(await residentRunner.run(enableDevTools: true), 0); + expect(await residentRunner.run(), 0); expect(residentCompiler.didSuppressErrors, true); expect(fakeVmServiceHost?.hasRemainingExpectations, false); })); @@ -216,7 +213,7 @@ void main() { ); flutterDevice.generator = residentCompiler; - expect(await residentRunner.run(enableDevTools: true), 0); + expect(await residentRunner.run(), 0); expect(residentCompiler.didSuppressErrors, false); expect(fakeVmServiceHost?.hasRemainingExpectations, false); })); @@ -279,7 +276,6 @@ void main() { final Future result = residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, ); final Future connectionInfo = futureConnectionInfo.future; @@ -301,7 +297,6 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, )); await futureAppStart.future; flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, ''); @@ -343,7 +338,6 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, )); await futureAppStart.future; @@ -389,7 +383,6 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, )); await futureAppStart.future; flutterDevice.reportError = vm_service.RPCError('something bad happened', kIsolateReloadBarred, ''); @@ -433,13 +426,15 @@ 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' - )), - devtoolsHandler: createNoOpHandler, + debuggingOptions: DebuggingOptions.enabled( + const BuildInfo( + BuildMode.debug, '', treeShakeIcons: false, extraFrontEndOptions: [ + '--enable-experiment=non-nullable', + ], + packageConfigPath: '.dart_tool/package_config.json', + ), + enableDevTools: false, + ), analytics: fakeAnalytics, ); final Completer futureConnectionInfo = Completer.sync(); @@ -447,7 +442,6 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, )); await futureAppStart.future; flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, ''); @@ -512,7 +506,6 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, )); await futureAppStart.future; flutterDevice.report = UpdateFSReport(success: true); @@ -570,7 +563,6 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, )); await futureAppStart.future; flutterDevice.report = UpdateFSReport(success: true, invalidatedSourcesCount: 1); @@ -634,7 +626,6 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, )); await futureAppStart.future; flutterDevice.report = UpdateFSReport(success: true, invalidatedSourcesCount: 1); @@ -694,7 +685,6 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, )); await futureAppStart.future; @@ -785,7 +775,6 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, )); await futureAppStart.future; @@ -847,7 +836,6 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, )); final OperationResult result = await residentRunner.restart(fullRestart: true); @@ -937,7 +925,6 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, )); final OperationResult result = await residentRunner.restart(fullRestart: true); @@ -1058,7 +1045,6 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, )); await residentRunner.restart(fullRestart: true); @@ -1078,7 +1064,6 @@ void main() { unawaited(residentRunner.attach( appStartedCompleter: futureAppStart, connectionInfoCompleter: futureConnectionInfo, - enableDevTools: true, )); await futureAppStart.future; flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, ''); @@ -1521,7 +1506,7 @@ flutter: flutterDevice, ], stayResident: false, - debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'), + debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo', enableDevTools: false), target: 'main.dart', devtoolsHandler: createNoOpHandler, ); @@ -1571,7 +1556,7 @@ flutter: analytics: fakeAnalytics, ); - await residentRunner.run(enableDevTools: true); + await residentRunner.run(); expect(fakeVmServiceHost?.hasRemainingExpectations, false); expect(await globals.fs.file('foo').readAsString(), testUri.toString()); @@ -1602,7 +1587,7 @@ flutter: ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); - await residentRunner.run(enableDevTools: true); + await residentRunner.run(); expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill')).readAsString(), 'ABC'); })); @@ -1633,7 +1618,7 @@ flutter: ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); - await residentRunner.run(enableDevTools: true); + await residentRunner.run(); expect(await globals.fs.file(globals.fs.path.join( 'build', '187ef4436122d1cc2f40dc2b92f0eba0.cache.dill')).readAsString(), 'ABC'); @@ -1665,7 +1650,7 @@ flutter: ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); - await residentRunner.run(enableDevTools: true); + await residentRunner.run(); expect(await globals.fs.file(globals.fs.path.join( 'build', 'cache.dill')).readAsString(), 'ABC'); @@ -1689,7 +1674,7 @@ flutter: ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); - await residentRunner.run(enableDevTools: true); + await residentRunner.run(); expect(await globals.fs.file(globals.fs.path.join( 'build', 'cache.dill.track.dill')).readAsString(), 'ABC'); @@ -1714,7 +1699,7 @@ flutter: ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); - await residentRunner.run(enableDevTools: true); + await residentRunner.run(); expect(globals.fs.file(globals.fs.path.join('build', 'cache.dill')), isNot(exists)); })); @@ -1743,7 +1728,7 @@ flutter: ); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); - await residentRunner.run(enableDevTools: true); + await residentRunner.run(); expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill.track.dill')).readAsString(), 'ABC'); })); @@ -1786,7 +1771,7 @@ flutter: analytics: fakeAnalytics, ); - await residentRunner.run(enableDevTools: true); + await residentRunner.run(); expect(testLogger.errorText, contains('Failed to write vmservice-out-file at foo')); expect(fakeVmServiceHost?.hasRemainingExpectations, false); @@ -1805,11 +1790,11 @@ flutter: ], stayResident: false, debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'), - target: 'main.dart', devtoolsHandler: createNoOpHandler, + target: 'main.dart', ); - await residentRunner.run(enableDevTools: true); + await residentRunner.run(); expect(await globals.fs.file('foo').readAsString(), testUri.toString()); expect(fakeVmServiceHost?.hasRemainingExpectations, false); @@ -1975,61 +1960,19 @@ 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(); - ddsLauncherCallback = (Uri uri, {bool enableAuthCodes = true, bool ipv6 = false, Uri? serviceUri, List cachedUserTags = const [], dds.UriConverter? uriConverter}) { - throw dds.DartDevelopmentServiceException.existingDdsInstance( + ..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( 'Existing DDS at http://localhost/existingDdsInMessage.', ddsUri: Uri.parse('http://localhost/existingDdsInField'), ); @@ -2040,7 +1983,10 @@ flutter: ); final Completer done = Completer(); unawaited(runZonedGuarded( - () => flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete()), + () => flutterDevice.connect( + allowExistingDdsInstance: true, + debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), + ).then((_) => done.complete()), (_, __) => done.complete(), )); await done.future; @@ -2052,41 +1998,7 @@ flutter: CompileExpression? compileExpression, GetSkSLMethod? getSkSLMethod, FlutterProject? flutterProject, - 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, + PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, io.CompressionOptions? compression, Device? device, required Logger logger, @@ -2096,23 +2008,34 @@ flutter: testUsingContext('Host VM service ipv6 defaults', () => testbed.run(() async { fakeVmServiceHost = FakeVmServiceHost(requests: []); final FakeDevice device = FakeDevice() - ..dds = DartDevelopmentService(); + ..dds = DartDevelopmentService(logger: testLogger); final Completerdone = Completer(); - ddsLauncherCallback = (Uri uri, {bool enableAuthCodes = true, bool ipv6 = false, Uri? serviceUri, List cachedUserTags = const [], dds.UriConverter? uriConverter}) async { + ddsLauncherCallback = (Uri uri, + {bool enableDevTools = false, + bool enableAuthCodes = true, + bool ipv6 = false, Uri? serviceUri, + List cachedUserTags = const [], + String? google3WorkspaceRoot, + Uri? devToolsServerAddress, + }) 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 FakeDartDevelopmentService(); + return fakeDartDevelopmentServiceInstance; }; final TestFlutterDevice flutterDevice = TestFlutterDevice( device, vmServiceUris: Stream.value(testUri), ); - await flutterDevice.connect(allowExistingDdsInstance: true, ipv6: true, disableServiceAuthCodes: true); + await flutterDevice.connect( + allowExistingDdsInstance: true, + debuggingOptions: DebuggingOptions.enabled( + BuildInfo.debug, disableServiceAuthCodes: true, ipv6: true, + ) + ); await done.future; }, overrides: { VMServiceConnector: () => (Uri httpUri, { @@ -2128,67 +2051,25 @@ 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(); + ..dds = DartDevelopmentService(logger: testLogger); ddsLauncherCallback = ( Uri uri, { + bool enableDevTools = false, bool enableAuthCodes = false, bool ipv6 = false, Uri? serviceUri, List cachedUserTags = const [], - dds.UriConverter? uriConverter, + String? google3WorkspaceRoot, + Uri? devToolsServerAddress, }) { 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( @@ -2198,7 +2079,10 @@ flutter: bool caught = false; final Completerdone = Completer(); runZonedGuarded(() { - flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete()); + flutterDevice.connect( + allowExistingDdsInstance: true, + debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, enableDevTools: false), + ).then((_) => done.complete()); }, (Object e, StackTrace st) { expect(e, isA()); expect((e as StateError).message, contains('No URI')); @@ -2236,6 +2120,7 @@ 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 131734100c..10f5bd1d67 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,7 +50,6 @@ void main() { mockFlutterDevice, flutterProject: project, debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), - ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), @@ -81,7 +80,6 @@ void main() { mockFlutterDevice, flutterProject: project, debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), - ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), @@ -107,7 +105,6 @@ void main() { mockFlutterDevice, flutterProject: project, debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), - ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), @@ -132,7 +129,6 @@ void main() { mockFlutterDevice, flutterProject: project, debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), - ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), @@ -162,7 +158,6 @@ void main() { mockFlutterDevice, flutterProject: project, debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), - ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), systemClock: SystemClock.fixed(DateTime(0, 0, 0)), 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 34ef199025..563b0eac30 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,7 +162,6 @@ void main() { flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), - ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, @@ -195,7 +194,6 @@ void main() { FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, startPaused: true), - ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, @@ -215,7 +213,6 @@ void main() { flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), - ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, @@ -229,7 +226,6 @@ void main() { flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile), - ipv6: true, fileSystem: fileSystem, logger: BufferLogger.test(), usage: globals.flutterUsage, @@ -362,13 +358,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); @@ -389,13 +385,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); @@ -591,12 +587,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()); @@ -1012,7 +1008,7 @@ void main() { testUsingContext('cleanup of resources is safe to call multiple times', () async { final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice); - mockDevice.dds = DartDevelopmentService(); + mockDevice.dds = DartDevelopmentService(logger: test_fakes.FakeLogger()); fakeVmServiceHost = FakeVmServiceHost(requests: [ ...kAttachExpectations, ]); @@ -1115,12 +1111,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 = @@ -1164,12 +1160,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 = @@ -1206,13 +1202,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. @@ -1410,7 +1406,6 @@ 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()), @@ -1719,13 +1714,11 @@ 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 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 30ea65af5a..6e6f8b4624 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,6 +191,7 @@ 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 ba43d15f31..b2c5486490 100644 --- a/packages/flutter_tools/test/general.shard/terminal_handler_test.dart +++ b/packages/flutter_tools/test/general.shard/terminal_handler_test.dart @@ -7,6 +7,7 @@ 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'; @@ -25,6 +26,7 @@ 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', @@ -1308,11 +1310,13 @@ 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; @@ -1332,6 +1336,9 @@ 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) { @@ -1339,7 +1346,6 @@ 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 4f6ab9e329..5586244327 100644 --- a/packages/flutter_tools/test/src/fake_devices.dart +++ b/packages/flutter_tools/test/src/fake_devices.dart @@ -9,6 +9,8 @@ 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 = [ @@ -129,6 +131,7 @@ 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 ff6f6deebc..cc6d456b44 100644 --- a/packages/flutter_tools/test/src/fakes.dart +++ b/packages/flutter_tools/test/src/fakes.dart @@ -741,6 +741,12 @@ 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');