Reverts "Launch DDS from Dart SDK and prepare to serve DevTools from DDS (#146593)" (#151781)

Reverts: flutter/flutter#146593
Initiated by: zanderso
Reason for reverting: Consistently failing `Windows_android native_assets_android` as in https://ci.chromium.org/ui/p/flutter/builders/prod/Windows_android%20native_assets_android/2533/overview 
Original PR Author: bkonyi

Reviewed By: {christopherfujino, kenzieschmoll}

This change reverts the following previous change:
This change is a major step towards moving away from shipping DDS via Pub.

The first component of this PR is the move away from importing package:dds to launch DDS. Instead, DDS is launched out of process using the `dart development-service` command shipped with the Dart SDK. This makes Flutter's handling of DDS consistent with the standalone Dart VM.

The second component of this PR is the initial work to prepare for the removal of instances of DevTools being served manually by the flutter_tool, instead relying on DDS to serve DevTools. This will be consistent with how the standalone Dart VM serves DevTools, tying the DevTools lifecycle to a live DDS instance. This will allow for the removal of much of the logic needed to properly manage the lifecycle of the DevTools server in a future PR. Also, by serving DevTools from DDS, users will no longer need to forward a secondary port in remote workflows as DevTools will be available on the DDS port.

There's two remaining circumstances that will prevent us from removing DevtoolsRunner completely:

 - The daemon's `devtools.serve` endpoint
 - `flutter drive`'s `--profile-memory` flag used for recording memory profiles

This PR also includes some refactoring around `DebuggingOptions` to reduce the number of debugging related arguments being passed as parameters adjacent to a `DebuggingOptions` instance.
This commit is contained in:
auto-submit[bot] 2024-07-15 19:55:18 +00:00 committed by GitHub
parent f023430859
commit 7cdc23b3e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
57 changed files with 752 additions and 925 deletions

View File

@ -59,7 +59,7 @@ class AndroidDevice extends Device {
this.productID, this.productID,
required this.modelID, required this.modelID,
this.deviceCodeName, this.deviceCodeName,
required super.logger, required Logger logger,
required ProcessManager processManager, required ProcessManager processManager,
required Platform platform, required Platform platform,
required AndroidSdk androidSdk, required AndroidSdk androidSdk,

View File

@ -4,333 +4,112 @@
import 'dart:async'; import 'dart:async';
import 'package:dds/dds.dart' as dds;
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import '../artifacts.dart'; import 'common.dart';
import '../convert.dart'; import 'context.dart';
import '../device.dart';
import '../globals.dart' as globals;
import 'io.dart' as io; import 'io.dart' as io;
import 'logger.dart'; import 'logger.dart';
/// A representation of the current DDS state including:
///
/// - The process the external DDS instance is running in
/// - The service URI DDS is being served on
/// - The URI DevTools is being served on, if applicable
/// - The URI DTD is being served on, if applicable
typedef DartDevelopmentServiceInstance = ({
io.Process? process,
Uri? serviceUri,
Uri? devToolsUri,
Uri? dtdUri,
});
/// The default DDSLauncherCallback used to spawn DDS.
Future<DartDevelopmentServiceInstance> defaultStartDartDevelopmentService(
Uri remoteVmServiceUri, {
required bool enableAuthCodes,
required bool ipv6,
required bool enableDevTools,
required List<String> 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,
<String>[
'development-service',
'--vm-service-uri=$remoteVmServiceUri',
if (serviceUri != null) ...<String>[
'--bind-address=${serviceUri.host}',
'--bind-port=${serviceUri.port}',
],
if (!enableAuthCodes) '--disable-service-auth-codes',
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// if (enableDevTools) '--serve-devtools',
if (google3WorkspaceRoot != null)
'--google3-workspace-root=$google3WorkspaceRoot',
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// if (devToolsServerAddress != null)
// '--devtools-server-address=$devToolsServerAddress',
for (final String tag in cachedUserTags) '--cached-user-tags=$tag',
],
);
final Completer<DartDevelopmentServiceInstance> completer =
Completer<DartDevelopmentServiceInstance>();
late StreamSubscription<Object?> 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<String, Object?>?)?['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<String, Object?>? exceptionDetails =
result['ddsExceptionDetails'] as Map<String, Object?>?;
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<DartDevelopmentServiceInstance> Function(
Uri remoteVmServiceUri, {
required bool enableAuthCodes,
required bool ipv6,
required bool enableDevTools,
required List<String> cachedUserTags,
Uri? serviceUri,
String? google3WorkspaceRoot,
Uri? devToolsServerAddress,
});
// TODO(fujino): This should be direct injected, rather than mutable global state. // 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 @visibleForTesting
DDSLauncherCallback ddsLauncherCallback = defaultStartDartDevelopmentService; Future<dds.DartDevelopmentService> Function(
Uri remoteVmServiceUri, {
/// Thrown by DDS during initialization failures, unexpected connection issues, bool enableAuthCodes,
/// and when attempting to spawn DDS when an existing DDS instance exists. bool ipv6,
class DartDevelopmentServiceException implements Exception { Uri? serviceUri,
factory DartDevelopmentServiceException.fromJson(Map<String, Object?> json) { List<String> cachedUserTags,
if (json dds.UriConverter? uriConverter,
case { }) ddsLauncherCallback = dds.DartDevelopmentService.startDartDevelopmentService;
'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 /// Helper class to launch a [dds.DartDevelopmentService]. Allows for us to
/// mock out this functionality for testing purposes. /// mock out this functionality for testing purposes.
class DartDevelopmentService with DartDevelopmentServiceLocalOperationsMixin { class DartDevelopmentService {
DartDevelopmentService({required Logger logger}) : _logger = logger; dds.DartDevelopmentService? _ddsInstance;
DartDevelopmentServiceInstance? _ddsInstance; Uri? get uri => _ddsInstance?.uri ?? _existingDdsUri;
Uri? get uri => _ddsInstance?.serviceUri ?? _existingDdsUri;
Uri? _existingDdsUri; Uri? _existingDdsUri;
Future<void> get done => _completer.future; Future<void> get done => _completer.future;
final Completer<void> _completer = Completer<void>(); final Completer<void> _completer = Completer<void>();
final Logger _logger;
@override
Future<void> startDartDevelopmentService( Future<void> startDartDevelopmentService(
Uri vmServiceUri, { Uri vmServiceUri, {
int? ddsPort, required Logger logger,
bool? disableServiceAuthCodes, int? hostPort,
bool? ipv6, bool? ipv6,
bool enableDevTools = true, bool? disableServiceAuthCodes,
bool cacheStartupProfile = false, bool cacheStartupProfile = false,
String? google3WorkspaceRoot,
Uri? devToolsServerAddress,
}) async { }) async {
assert(_ddsInstance == null);
final Uri ddsUri = Uri( final Uri ddsUri = Uri(
scheme: 'http', scheme: 'http',
host: ((ipv6 ?? false) host: ((ipv6 ?? false) ? io.InternetAddress.loopbackIPv6 : io.InternetAddress.loopbackIPv4).host,
? io.InternetAddress.loopbackIPv6 port: hostPort ?? 0,
: io.InternetAddress.loopbackIPv4)
.host,
port: ddsPort ?? 0,
); );
_logger.printTrace( logger.printTrace(
'Launching a Dart Developer Service (DDS) instance at $ddsUri, ' 'Launching a Dart Developer Service (DDS) instance at $ddsUri, '
'connecting to VM service at $vmServiceUri.', 'connecting to VM service at $vmServiceUri.',
); );
void completeFuture() { 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 <String>['AppStartUp'] : const <String>[],
uriConverter: context.get<dds.UriConverter>(),
);
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);
}
}
if (!_completer.isCompleted) { if (!_completer.isCompleted) {
_completer.complete(); _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 <String>['AppStartUp']
: const <String>[],
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; rethrow;
} }
} }
void shutdown() => _ddsInstance?.process?.kill(); Future<void> shutdown() async => _ddsInstance?.shutdown();
}
/// Contains common functionality that can be used with any implementation of void setExternalDevToolsUri(Uri uri) {
/// [DartDevelopmentService]. _ddsInstance?.setExternalDevToolsUri(uri);
mixin DartDevelopmentServiceLocalOperationsMixin { }
Future<void> 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<void> 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,
);
} }

View File

@ -361,6 +361,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
connectionInfoCompleter: connectionInfoCompleter, connectionInfoCompleter: connectionInfoCompleter,
appStartedCompleter: appStartedCompleter, appStartedCompleter: appStartedCompleter,
allowExistingDdsInstance: true, allowExistingDdsInstance: true,
enableDevTools: boolArg(FlutterCommand.kEnableDevTools),
); );
}, },
device, device,
@ -402,6 +403,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
result = await runner.attach( result = await runner.attach(
appStartedCompleter: onAppStart, appStartedCompleter: onAppStart,
allowExistingDdsInstance: true, allowExistingDdsInstance: true,
enableDevTools: boolArg(FlutterCommand.kEnableDevTools),
); );
if (result != 0) { if (result != 0) {
throwToolExit(null, exitCode: result); throwToolExit(null, exitCode: result);
@ -460,9 +462,6 @@ known, it can be explicitly provided to attach via the command-line, e.g.
serveObservatory: serveObservatory, serveObservatory: serveObservatory,
usingCISystem: usingCISystem, usingCISystem: usingCISystem,
debugLogsDirectoryPath: debugLogsDirectoryPath, debugLogsDirectoryPath: debugLogsDirectoryPath,
enableDevTools: boolArg(FlutterCommand.kEnableDevTools),
ipv6: usesIpv6,
printDtd: boolArg(FlutterGlobalOptions.kPrintDtd, global: true),
); );
return buildInfo.isDebug return buildInfo.isDebug
@ -473,6 +472,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
packagesFilePath: globalResults![FlutterGlobalOptions.kPackagesOption] as String?, packagesFilePath: globalResults![FlutterGlobalOptions.kPackagesOption] as String?,
projectRootPath: stringArg('project-root'), projectRootPath: stringArg('project-root'),
dillOutputPath: stringArg('output-dill'), dillOutputPath: stringArg('output-dill'),
ipv6: usesIpv6,
flutterProject: flutterProject, flutterProject: flutterProject,
nativeAssetsYamlFile: stringArg(FlutterOptions.kNativeAssetsYamlFile), nativeAssetsYamlFile: stringArg(FlutterOptions.kNativeAssetsYamlFile),
nativeAssetsBuilder: _nativeAssetsBuilder, nativeAssetsBuilder: _nativeAssetsBuilder,
@ -482,6 +482,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
flutterDevices, flutterDevices,
target: targetFile, target: targetFile,
debuggingOptions: debuggingOptions, debuggingOptions: debuggingOptions,
ipv6: usesIpv6,
); );
} }
@ -505,6 +506,7 @@ class HotRunnerFactory {
String? packagesFilePath, String? packagesFilePath,
String? dillOutputPath, String? dillOutputPath,
bool stayResident = true, bool stayResident = true,
bool ipv6 = false,
FlutterProject? flutterProject, FlutterProject? flutterProject,
String? nativeAssetsYamlFile, String? nativeAssetsYamlFile,
required HotRunnerNativeAssetsBuilder? nativeAssetsBuilder, required HotRunnerNativeAssetsBuilder? nativeAssetsBuilder,
@ -519,6 +521,7 @@ class HotRunnerFactory {
projectRootPath: projectRootPath, projectRootPath: projectRootPath,
dillOutputPath: dillOutputPath, dillOutputPath: dillOutputPath,
stayResident: stayResident, stayResident: stayResident,
ipv6: ipv6,
nativeAssetsYamlFile: nativeAssetsYamlFile, nativeAssetsYamlFile: nativeAssetsYamlFile,
nativeAssetsBuilder: nativeAssetsBuilder, nativeAssetsBuilder: nativeAssetsBuilder,
analytics: analytics, analytics: analytics,

View File

@ -664,9 +664,11 @@ class AppDomain extends Domain {
String? projectRootPath, String? projectRootPath,
String? packagesFilePath, String? packagesFilePath,
String? dillOutputPath, String? dillOutputPath,
bool ipv6 = false,
String? isolateFilter, String? isolateFilter,
bool machine = true, bool machine = true,
String? userIdentifier, String? userIdentifier,
bool enableDevTools = true,
required HotRunnerNativeAssetsBuilder? nativeAssetsBuilder, required HotRunnerNativeAssetsBuilder? nativeAssetsBuilder,
}) async { }) async {
if (!await device.supportsRuntimeMode(options.buildInfo.mode)) { if (!await device.supportsRuntimeMode(options.buildInfo.mode)) {
@ -697,6 +699,7 @@ class AppDomain extends Domain {
flutterProject: flutterProject, flutterProject: flutterProject,
target: target, target: target,
debuggingOptions: options, debuggingOptions: options,
ipv6: ipv6,
stayResident: true, stayResident: true,
urlTunneller: options.webEnableExposeUrl! ? daemon.daemonDomain.exposeUrl : null, urlTunneller: options.webEnableExposeUrl! ? daemon.daemonDomain.exposeUrl : null,
machine: machine, machine: machine,
@ -714,6 +717,7 @@ class AppDomain extends Domain {
applicationBinary: applicationBinary, applicationBinary: applicationBinary,
projectRootPath: projectRootPath, projectRootPath: projectRootPath,
dillOutputPath: dillOutputPath, dillOutputPath: dillOutputPath,
ipv6: ipv6,
hostIsIde: true, hostIsIde: true,
machine: machine, machine: machine,
analytics: globals.analytics, analytics: globals.analytics,
@ -725,6 +729,7 @@ class AppDomain extends Domain {
target: target, target: target,
debuggingOptions: options, debuggingOptions: options,
applicationBinary: applicationBinary, applicationBinary: applicationBinary,
ipv6: ipv6,
machine: machine, machine: machine,
); );
} }
@ -738,6 +743,7 @@ class AppDomain extends Domain {
return runner.run( return runner.run(
connectionInfoCompleter: connectionInfoCompleter, connectionInfoCompleter: connectionInfoCompleter,
appStartedCompleter: appStartedCompleter, appStartedCompleter: appStartedCompleter,
enableDevTools: enableDevTools,
route: route, route: route,
); );
}, },
@ -1002,6 +1008,7 @@ class DeviceDomain extends Domain {
registerHandler('takeScreenshot', takeScreenshot); registerHandler('takeScreenshot', takeScreenshot);
registerHandler('startDartDevelopmentService', startDartDevelopmentService); registerHandler('startDartDevelopmentService', startDartDevelopmentService);
registerHandler('shutdownDartDevelopmentService', shutdownDartDevelopmentService); registerHandler('shutdownDartDevelopmentService', shutdownDartDevelopmentService);
registerHandler('setExternalDevToolsUriForDartDevelopmentService', setExternalDevToolsUriForDartDevelopmentService);
registerHandler('getDiagnostics', getDiagnostics); registerHandler('getDiagnostics', getDiagnostics);
registerHandler('startVMServiceDiscoveryForAttach', startVMServiceDiscoveryForAttach); registerHandler('startVMServiceDiscoveryForAttach', startVMServiceDiscoveryForAttach);
registerHandler('stopVMServiceDiscoveryForAttach', stopVMServiceDiscoveryForAttach); registerHandler('stopVMServiceDiscoveryForAttach', stopVMServiceDiscoveryForAttach);
@ -1189,6 +1196,7 @@ class DeviceDomain extends Domain {
route: _getStringArg(args, 'route'), route: _getStringArg(args, 'route'),
platformArgs: castStringKeyedMap(args['platformArgs']) ?? const <String, Object>{}, platformArgs: castStringKeyedMap(args['platformArgs']) ?? const <String, Object>{},
prebuiltApplication: _getBoolArg(args, 'prebuiltApplication') ?? false, prebuiltApplication: _getBoolArg(args, 'prebuiltApplication') ?? false,
ipv6: _getBoolArg(args, 'ipv6') ?? false,
userIdentifier: _getStringArg(args, 'userIdentifier'), userIdentifier: _getStringArg(args, 'userIdentifier'),
); );
return <String, Object?>{ return <String, Object?>{
@ -1236,36 +1244,23 @@ class DeviceDomain extends Domain {
} }
/// Starts DDS for the device. /// Starts DDS for the device.
Future<Map<String, Object?>> startDartDevelopmentService(Map<String, Object?> args) async { Future<String?> startDartDevelopmentService(Map<String, Object?> args) async {
final String? deviceId = _getStringArg(args, 'deviceId', required: true); final String? deviceId = _getStringArg(args, 'deviceId', required: true);
final bool? disableServiceAuthCodes = _getBoolArg(args, 'disableServiceAuthCodes'); final bool? disableServiceAuthCodes = _getBoolArg(args, 'disableServiceAuthCodes');
final String vmServiceUriStr = _getStringArg(args, 'vmServiceUri', required: true)!; 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); final Device? device = await daemon.deviceDomain._getDevice(deviceId);
if (device == null) { if (device == null) {
throw DaemonException("device '$deviceId' not found"); throw DaemonException("device '$deviceId' not found");
} }
Uri? devToolsServerAddress;
if (devToolsServerAddressStr != null) {
devToolsServerAddress = Uri.parse(devToolsServerAddressStr);
}
await device.dds.startDartDevelopmentService( await device.dds.startDartDevelopmentService(
Uri.parse(vmServiceUriStr), Uri.parse(vmServiceUriStr),
logger: globals.logger,
disableServiceAuthCodes: disableServiceAuthCodes, disableServiceAuthCodes: disableServiceAuthCodes,
enableDevTools: enableDevTools,
devToolsServerAddress: devToolsServerAddress,
); );
unawaited(device.dds.done.whenComplete(() => sendEvent('device.dds.done.$deviceId'))); unawaited(device.dds.done.whenComplete(() => sendEvent('device.dds.done.$deviceId')));
return <String, Object?>{ return device.dds.uri?.toString();
'ddsUri': device.dds.uri?.toString(),
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// 'devToolsUri': device.dds.devToolsUri?.toString(),
// 'dtdUri': device.dds.dtdUri?.toString(),
};
} }
/// Starts DDS for the device. /// Starts DDS for the device.
@ -1277,7 +1272,19 @@ class DeviceDomain extends Domain {
throw DaemonException("device '$deviceId' not found"); throw DaemonException("device '$deviceId' not found");
} }
device.dds.shutdown(); await device.dds.shutdown();
}
Future<void> setExternalDevToolsUriForDartDevelopmentService(Map<String, Object?> args) async {
final String? deviceId = _getStringArg(args, 'deviceId', required: true);
final String uri = _getStringArg(args, 'uri', required: true)!;
final Device? device = await daemon.deviceDomain._getDevice(deviceId);
if (device == null) {
throw DaemonException("device '$deviceId' not found");
}
device.dds.setExternalDevToolsUri(Uri.parse(uri));
} }
@override @override

View File

@ -274,6 +274,7 @@ class DriveCommand extends RunCommandBase {
buildInfo, buildInfo,
device, device,
debuggingOptions, debuggingOptions,
ipv6 ?? false,
applicationBinary: applicationBinary, applicationBinary: applicationBinary,
route: route, route: route,
userIdentifier: userIdentifier, userIdentifier: userIdentifier,
@ -294,6 +295,7 @@ class DriveCommand extends RunCommandBase {
uri, uri,
device, device,
debuggingOptions, debuggingOptions,
ipv6 ?? false,
); );
} }

View File

@ -354,9 +354,6 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
enableEmbedderApi: enableEmbedderApi, enableEmbedderApi: enableEmbedderApi,
usingCISystem: usingCISystem, usingCISystem: usingCISystem,
debugLogsDirectoryPath: debugLogsDirectoryPath, debugLogsDirectoryPath: debugLogsDirectoryPath,
enableDevTools: boolArg(FlutterCommand.kEnableDevTools),
ipv6: boolArg(FlutterCommand.ipv6Flag),
printDtd: boolArg(FlutterGlobalOptions.kPrintDtd, global: true),
); );
} }
} }
@ -705,6 +702,7 @@ class RunCommand extends RunCommandBase {
projectRootPath: stringArg('project-root'), projectRootPath: stringArg('project-root'),
dillOutputPath: stringArg('output-dill'), dillOutputPath: stringArg('output-dill'),
stayResident: stayResident, stayResident: stayResident,
ipv6: ipv6 ?? false,
analytics: globals.analytics, analytics: globals.analytics,
nativeAssetsYamlFile: stringArg(FlutterOptions.kNativeAssetsYamlFile), nativeAssetsYamlFile: stringArg(FlutterOptions.kNativeAssetsYamlFile),
nativeAssetsBuilder: _nativeAssetsBuilder, nativeAssetsBuilder: _nativeAssetsBuilder,
@ -714,6 +712,7 @@ class RunCommand extends RunCommandBase {
flutterDevices.single, flutterDevices.single,
target: targetFile, target: targetFile,
flutterProject: flutterProject, flutterProject: flutterProject,
ipv6: ipv6,
debuggingOptions: await createDebuggingOptions(webMode), debuggingOptions: await createDebuggingOptions(webMode),
stayResident: stayResident, stayResident: stayResident,
fileSystem: globals.fs, fileSystem: globals.fs,
@ -732,6 +731,7 @@ class RunCommand extends RunCommandBase {
applicationBinary: applicationBinaryPath == null applicationBinary: applicationBinaryPath == null
? null ? null
: globals.fs.file(applicationBinaryPath), : globals.fs.file(applicationBinaryPath),
ipv6: ipv6 ?? false,
stayResident: stayResident, stayResident: stayResident,
); );
} }
@ -776,7 +776,9 @@ class RunCommand extends RunCommandBase {
projectRootPath: stringArg('project-root'), projectRootPath: stringArg('project-root'),
packagesFilePath: globalResults![FlutterGlobalOptions.kPackagesOption] as String?, packagesFilePath: globalResults![FlutterGlobalOptions.kPackagesOption] as String?,
dillOutputPath: stringArg('output-dill'), dillOutputPath: stringArg('output-dill'),
ipv6: ipv6 ?? false,
userIdentifier: userIdentifier, userIdentifier: userIdentifier,
enableDevTools: boolArg(FlutterCommand.kEnableDevTools),
nativeAssetsBuilder: _nativeAssetsBuilder, nativeAssetsBuilder: _nativeAssetsBuilder,
); );
} on Exception catch (error) { } on Exception catch (error) {
@ -864,6 +866,7 @@ class RunCommand extends RunCommandBase {
try { try {
final int? result = await runner.run( final int? result = await runner.run(
appStartedCompleter: appStartedTimeRecorder, appStartedCompleter: appStartedTimeRecorder,
enableDevTools: stayResident && boolArg(FlutterCommand.kEnableDevTools),
route: route, route: route,
); );
handler?.stop(); handler?.stop();

View File

@ -16,7 +16,6 @@ import '../globals.dart' as globals;
import '../native_assets.dart'; import '../native_assets.dart';
import '../project.dart'; import '../project.dart';
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
import '../runner/flutter_command_runner.dart';
import '../test/coverage_collector.dart'; import '../test/coverage_collector.dart';
import '../test/event_printer.dart'; import '../test/event_printer.dart';
import '../test/runner.dart'; import '../test/runner.dart';
@ -412,7 +411,6 @@ class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts {
enableImpeller: ImpellerStatus.fromBool(argResults!['enable-impeller'] as bool?), enableImpeller: ImpellerStatus.fromBool(argResults!['enable-impeller'] as bool?),
debugLogsDirectoryPath: debugLogsDirectoryPath, debugLogsDirectoryPath: debugLogsDirectoryPath,
webRenderer: webRenderer, webRenderer: webRenderer,
printDtd: boolArg(FlutterGlobalOptions.kPrintDtd, global: true),
webUseWasm: useWasm, webUseWasm: useWasm,
webUseLocalCanvaskit: true, webUseLocalCanvaskit: true,
); );
@ -601,6 +599,7 @@ class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts {
excludeTags: excludeTags, excludeTags: excludeTags,
watcher: watcher, watcher: watcher,
enableVmService: collector != null || startPaused || enableVmService, enableVmService: collector != null || startPaused || enableVmService,
ipv6: ipv6,
machine: machine, machine: machine,
updateGoldens: boolArg('update-goldens'), updateGoldens: boolArg('update-goldens'),
concurrency: jobs, concurrency: jobs,

View File

@ -352,6 +352,7 @@ class CustomDeviceAppSession {
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
Map<String, Object?> platformArgs = const <String, Object>{}, Map<String, Object?> platformArgs = const <String, Object>{},
bool prebuiltApplication = false, bool prebuiltApplication = false,
bool ipv6 = false,
String? userIdentifier String? userIdentifier
}) async { }) async {
final bool traceStartup = platformArgs['trace-startup'] as bool? ?? false; final bool traceStartup = platformArgs['trace-startup'] as bool? ?? false;
@ -376,7 +377,7 @@ class CustomDeviceAppSession {
logReader, logReader,
portForwarder: _device._config.usesPortForwarding ? _device.portForwarder : null, portForwarder: _device._config.usesPortForwarding ? _device.portForwarder : null,
logger: _logger, logger: _logger,
ipv6: debuggingOptions.ipv6, ipv6: ipv6,
); );
// We need to make the discovery listen to the logReader before the logReader // We need to make the discovery listen to the logReader before the logReader
@ -438,7 +439,7 @@ class CustomDeviceAppSession {
class CustomDevice extends Device { class CustomDevice extends Device {
CustomDevice({ CustomDevice({
required CustomDeviceConfig config, required CustomDeviceConfig config,
required super.logger, required Logger logger,
required ProcessManager processManager, required ProcessManager processManager,
}) : _config = config, }) : _config = config,
_logger = logger, _logger = logger,
@ -788,6 +789,7 @@ class CustomDevice extends Device {
debuggingOptions: debuggingOptions, debuggingOptions: debuggingOptions,
platformArgs: platformArgs, platformArgs: platformArgs,
prebuiltApplication: prebuiltApplication, prebuiltApplication: prebuiltApplication,
ipv6: ipv6,
userIdentifier: userIdentifier, userIdentifier: userIdentifier,
); );
} }

View File

@ -26,7 +26,7 @@ abstract class DesktopDevice extends Device {
DesktopDevice(super.id, { DesktopDevice(super.id, {
required PlatformType super.platformType, required PlatformType super.platformType,
required super.ephemeral, required super.ephemeral,
required super.logger, required Logger logger,
required ProcessManager processManager, required ProcessManager processManager,
required FileSystem fileSystem, required FileSystem fileSystem,
required OperatingSystemUtils operatingSystemUtils, required OperatingSystemUtils operatingSystemUtils,
@ -114,6 +114,7 @@ abstract class DesktopDevice extends Device {
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
Map<String, dynamic> platformArgs = const <String, dynamic>{}, Map<String, dynamic> platformArgs = const <String, dynamic>{},
bool prebuiltApplication = false, bool prebuiltApplication = false,
bool ipv6 = false,
String? userIdentifier, String? userIdentifier,
}) async { }) async {
if (!prebuiltApplication) { if (!prebuiltApplication) {
@ -157,7 +158,7 @@ abstract class DesktopDevice extends Device {
final ProtocolDiscovery vmServiceDiscovery = ProtocolDiscovery.vmService(_deviceLogReader, final ProtocolDiscovery vmServiceDiscovery = ProtocolDiscovery.vmService(_deviceLogReader,
devicePort: debuggingOptions.deviceVmServicePort, devicePort: debuggingOptions.deviceVmServicePort,
hostPort: debuggingOptions.hostVmServicePort, hostPort: debuggingOptions.hostVmServicePort,
ipv6: debuggingOptions.ipv6, ipv6: ipv6,
logger: _logger, logger: _logger,
); );
try { try {

View File

@ -603,11 +603,10 @@ String getNameForDeviceConnectionInterface(DeviceConnectionInterface connectionI
/// the host operating system in the case of Flutter Desktop. /// the host operating system in the case of Flutter Desktop.
abstract class Device { abstract class Device {
Device(this.id, { Device(this.id, {
required Logger logger,
required this.category, required this.category,
required this.platformType, required this.platformType,
required this.ephemeral, required this.ephemeral,
}) : dds = DartDevelopmentService(logger: logger); });
final String id; final String id;
@ -734,7 +733,7 @@ abstract class Device {
DevicePortForwarder? get portForwarder; DevicePortForwarder? get portForwarder;
/// Get the DDS instance for this device. /// Get the DDS instance for this device.
final DartDevelopmentService dds; final DartDevelopmentService dds = DartDevelopmentService();
/// Clear the device's logs. /// Clear the device's logs.
void clearLogs(); void clearLogs();
@ -779,6 +778,7 @@ abstract class Device {
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
Map<String, Object?> platformArgs, Map<String, Object?> platformArgs,
bool prebuiltApplication = false, bool prebuiltApplication = false,
bool ipv6 = false,
String? userIdentifier, String? userIdentifier,
}); });
@ -1007,11 +1007,7 @@ class DebuggingOptions {
this.enableEmbedderApi = false, this.enableEmbedderApi = false,
this.usingCISystem = false, this.usingCISystem = false,
this.debugLogsDirectoryPath, this.debugLogsDirectoryPath,
this.enableDevTools = true, }) : debuggingEnabled = true,
this.ipv6 = false,
this.google3WorkspaceRoot,
this.printDtd = false,
}) : debuggingEnabled = true,
webRenderer = webRenderer ?? WebRendererMode.getDefault(useWasm: webUseWasm); webRenderer = webRenderer ?? WebRendererMode.getDefault(useWasm: webUseWasm);
DebuggingOptions.disabled(this.buildInfo, { DebuggingOptions.disabled(this.buildInfo, {
@ -1069,10 +1065,6 @@ class DebuggingOptions {
nullAssertions = false, nullAssertions = false,
nativeNullAssertions = false, nativeNullAssertions = false,
serveObservatory = false, serveObservatory = false,
enableDevTools = false,
ipv6 = false,
google3WorkspaceRoot = null,
printDtd = false,
webRenderer = webRenderer ?? WebRendererMode.getDefault(useWasm: webUseWasm); webRenderer = webRenderer ?? WebRendererMode.getDefault(useWasm: webUseWasm);
DebuggingOptions._({ DebuggingOptions._({
@ -1131,10 +1123,6 @@ class DebuggingOptions {
required this.enableEmbedderApi, required this.enableEmbedderApi,
required this.usingCISystem, required this.usingCISystem,
required this.debugLogsDirectoryPath, required this.debugLogsDirectoryPath,
required this.enableDevTools,
required this.ipv6,
required this.google3WorkspaceRoot,
required this.printDtd,
}); });
final bool debuggingEnabled; final bool debuggingEnabled;
@ -1179,10 +1167,6 @@ class DebuggingOptions {
final bool enableEmbedderApi; final bool enableEmbedderApi;
final bool usingCISystem; final bool usingCISystem;
final String? debugLogsDirectoryPath; 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. /// Whether the tool should try to uninstall a previously installed version of the app.
/// ///
@ -1236,6 +1220,7 @@ class DebuggingOptions {
EnvironmentType environmentType, EnvironmentType environmentType,
String? route, String? route,
Map<String, Object?> platformArgs, { Map<String, Object?> platformArgs, {
bool ipv6 = false,
DeviceConnectionInterface interfaceType = DeviceConnectionInterface.attached, DeviceConnectionInterface interfaceType = DeviceConnectionInterface.attached,
bool isCoreDevice = false, bool isCoreDevice = false,
}) { }) {
@ -1341,10 +1326,6 @@ class DebuggingOptions {
'enableEmbedderApi': enableEmbedderApi, 'enableEmbedderApi': enableEmbedderApi,
'usingCISystem': usingCISystem, 'usingCISystem': usingCISystem,
'debugLogsDirectoryPath': debugLogsDirectoryPath, 'debugLogsDirectoryPath': debugLogsDirectoryPath,
'enableDevTools': enableDevTools,
'ipv6': ipv6,
'google3WorkspaceRoot': google3WorkspaceRoot,
'printDtd': printDtd,
}; };
static DebuggingOptions fromJson(Map<String, Object?> json, BuildInfo buildInfo) => static DebuggingOptions fromJson(Map<String, Object?> json, BuildInfo buildInfo) =>
@ -1404,10 +1385,6 @@ class DebuggingOptions {
enableEmbedderApi: (json['enableEmbedderApi'] as bool?) ?? false, enableEmbedderApi: (json['enableEmbedderApi'] as bool?) ?? false,
usingCISystem: (json['usingCISystem'] as bool?) ?? false, usingCISystem: (json['usingCISystem'] as bool?) ?? false,
debugLogsDirectoryPath: json['debugLogsDirectoryPath'] as String?, 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,
); );
} }

View File

@ -4,6 +4,7 @@
import 'dart:async'; import 'dart:async';
import 'package:dds/dds.dart' as dds;
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:package_config/package_config_types.dart'; import 'package:package_config/package_config_types.dart';
@ -11,7 +12,6 @@ import 'package:vm_service/vm_service.dart' as vm_service;
import '../application_package.dart'; import '../application_package.dart';
import '../base/common.dart'; import '../base/common.dart';
import '../base/dds.dart';
import '../base/logger.dart'; import '../base/logger.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../build_info.dart'; import '../build_info.dart';
@ -65,7 +65,8 @@ abstract class DriverService {
Future<void> start( Future<void> start(
BuildInfo buildInfo, BuildInfo buildInfo,
Device device, Device device,
DebuggingOptions debuggingOptions, { DebuggingOptions debuggingOptions,
bool ipv6, {
File? applicationBinary, File? applicationBinary,
String? route, String? route,
String? userIdentifier, String? userIdentifier,
@ -78,6 +79,7 @@ abstract class DriverService {
Uri vmServiceUri, Uri vmServiceUri,
Device device, Device device,
DebuggingOptions debuggingOptions, DebuggingOptions debuggingOptions,
bool ipv6,
); );
/// Start the test file with the provided [arguments] and [environment], returning /// Start the test file with the provided [arguments] and [environment], returning
@ -146,7 +148,8 @@ class FlutterDriverService extends DriverService {
Future<void> start( Future<void> start(
BuildInfo buildInfo, BuildInfo buildInfo,
Device device, Device device,
DebuggingOptions debuggingOptions, { DebuggingOptions debuggingOptions,
bool ipv6, {
File? applicationBinary, File? applicationBinary,
String? route, String? route,
String? userIdentifier, String? userIdentifier,
@ -196,6 +199,7 @@ class FlutterDriverService extends DriverService {
result.vmServiceUri!, result.vmServiceUri!,
device, device,
debuggingOptions, debuggingOptions,
ipv6,
); );
} }
@ -204,6 +208,7 @@ class FlutterDriverService extends DriverService {
Uri vmServiceUri, Uri vmServiceUri,
Device device, Device device,
DebuggingOptions debuggingOptions, DebuggingOptions debuggingOptions,
bool ipv6,
) async { ) async {
Uri uri; Uri uri;
if (vmServiceUri.scheme == 'ws') { if (vmServiceUri.scheme == 'ws') {
@ -217,12 +222,15 @@ class FlutterDriverService extends DriverService {
_device = device; _device = device;
if (debuggingOptions.enableDds) { if (debuggingOptions.enableDds) {
try { try {
await device.dds.startDartDevelopmentServiceFromDebuggingOptions( await device.dds.startDartDevelopmentService(
uri, uri,
debuggingOptions: debuggingOptions, hostPort: debuggingOptions.ddsPort,
ipv6: ipv6,
disableServiceAuthCodes: debuggingOptions.disableServiceAuthCodes,
logger: _logger,
); );
_vmServiceUri = device.dds.uri.toString(); _vmServiceUri = device.dds.uri.toString();
} on DartDevelopmentServiceException { } on dds.DartDevelopmentServiceException {
// If there's another flutter_tools instance still connected to the target // If there's another flutter_tools instance still connected to the target
// application, DDS will already be running remotely and this call will fail. // 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. // This can be ignored to continue to use the existing remote DDS instance.

View File

@ -55,7 +55,8 @@ class WebDriverService extends DriverService {
Future<void> start( Future<void> start(
BuildInfo buildInfo, BuildInfo buildInfo,
Device device, Device device,
DebuggingOptions debuggingOptions, { DebuggingOptions debuggingOptions,
bool ipv6, {
File? applicationBinary, File? applicationBinary,
String? route, String? route,
String? userIdentifier, String? userIdentifier,
@ -71,6 +72,7 @@ class WebDriverService extends DriverService {
_residentRunner = webRunnerFactory!.createWebRunner( _residentRunner = webRunnerFactory!.createWebRunner(
flutterDevice, flutterDevice,
target: mainPath, target: mainPath,
ipv6: ipv6,
debuggingOptions: buildInfo.isRelease ? debuggingOptions: buildInfo.isRelease ?
DebuggingOptions.disabled( DebuggingOptions.disabled(
buildInfo, buildInfo,
@ -232,7 +234,7 @@ class WebDriverService extends DriverService {
} }
@override @override
Future<void> reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions) async { Future<void> reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions, bool ipv6) async {
throwToolExit('--use-existing-app is not supported with flutter web driver'); throwToolExit('--use-existing-app is not supported with flutter web driver');
} }
} }

View File

@ -58,9 +58,10 @@ Future<void> _kDefaultDartDevelopmentServiceStarter(
) async { ) async {
await device.dds.startDartDevelopmentService( await device.dds.startDartDevelopmentService(
vmServiceUri, vmServiceUri,
ddsPort: 0, hostPort: 0,
disableServiceAuthCodes: disableServiceAuthCodes,
ipv6: true, ipv6: true,
disableServiceAuthCodes: disableServiceAuthCodes,
logger: globals.logger,
); );
} }
@ -211,7 +212,7 @@ class FuchsiaDevices extends PollingDeviceDiscovery {
_logger.printError('Failed to resolve host for Fuchsia device `$name`'); _logger.printError('Failed to resolve host for Fuchsia device `$name`');
return null; return null;
} }
return FuchsiaDevice(resolvedHost, name: name, logger: _logger); return FuchsiaDevice(resolvedHost, name: name);
} }
@override @override
@ -219,7 +220,7 @@ class FuchsiaDevices extends PollingDeviceDiscovery {
} }
class FuchsiaDevice extends Device { class FuchsiaDevice extends Device {
FuchsiaDevice(super.id, {required this.name, required super.logger}) FuchsiaDevice(super.id, {required this.name})
: super( : super(
platformType: PlatformType.fuchsia, platformType: PlatformType.fuchsia,
category: null, category: null,
@ -294,6 +295,7 @@ class FuchsiaDevice extends Device {
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
Map<String, Object?> platformArgs = const <String, Object?>{}, Map<String, Object?> platformArgs = const <String, Object?>{},
bool prebuiltApplication = false, bool prebuiltApplication = false,
bool ipv6 = false,
String? userIdentifier, String? userIdentifier,
}) async { }) async {
if (await isSession) { if (await isSession) {

View File

@ -272,7 +272,7 @@ class IOSDevice extends Device {
required IOSCoreDeviceControl coreDeviceControl, required IOSCoreDeviceControl coreDeviceControl,
required XcodeDebug xcodeDebug, required XcodeDebug xcodeDebug,
required IProxy iProxy, required IProxy iProxy,
required super.logger, required Logger logger,
}) })
: _sdkVersion = sdkVersion, : _sdkVersion = sdkVersion,
_iosDeploy = iosDeploy, _iosDeploy = iosDeploy,
@ -470,6 +470,7 @@ class IOSDevice extends Device {
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
Map<String, Object?> platformArgs = const <String, Object?>{}, Map<String, Object?> platformArgs = const <String, Object?>{},
bool prebuiltApplication = false, bool prebuiltApplication = false,
bool ipv6 = false,
String? userIdentifier, String? userIdentifier,
@visibleForTesting Duration? discoveryTimeout, @visibleForTesting Duration? discoveryTimeout,
@visibleForTesting ShutdownHooks? shutdownHooks, @visibleForTesting ShutdownHooks? shutdownHooks,
@ -523,6 +524,7 @@ class IOSDevice extends Device {
EnvironmentType.physical, EnvironmentType.physical,
route, route,
platformArgs, platformArgs,
ipv6: ipv6,
interfaceType: connectionInterface, interfaceType: connectionInterface,
isCoreDevice: isCoreDevice, isCoreDevice: isCoreDevice,
); );
@ -539,6 +541,7 @@ class IOSDevice extends Device {
bundle: bundle, bundle: bundle,
debuggingOptions: debuggingOptions, debuggingOptions: debuggingOptions,
launchArguments: launchArguments, launchArguments: launchArguments,
ipv6: ipv6,
uninstallFirst: debuggingOptions.uninstallFirst, uninstallFirst: debuggingOptions.uninstallFirst,
); );
} }
@ -616,6 +619,7 @@ class IOSDevice extends Device {
localUri = await _discoverDartVMForCoreDevice( localUri = await _discoverDartVMForCoreDevice(
debuggingOptions: debuggingOptions, debuggingOptions: debuggingOptions,
packageId: packageId, packageId: packageId,
ipv6: ipv6,
vmServiceDiscovery: vmServiceDiscovery, vmServiceDiscovery: vmServiceDiscovery,
); );
} else if (isWirelesslyConnected) { } else if (isWirelesslyConnected) {
@ -647,7 +651,7 @@ class IOSDevice extends Device {
localUri = await MDnsVmServiceDiscovery.instance!.getVMServiceUriForLaunch( localUri = await MDnsVmServiceDiscovery.instance!.getVMServiceUriForLaunch(
packageId, packageId,
this, this,
usesIpv6: debuggingOptions.ipv6, usesIpv6: ipv6,
deviceVmservicePort: serviceURL.port, deviceVmservicePort: serviceURL.port,
useDeviceIPAsHost: true, useDeviceIPAsHost: true,
); );
@ -669,6 +673,7 @@ class IOSDevice extends Device {
bundle: bundle, bundle: bundle,
debuggingOptions: debuggingOptions, debuggingOptions: debuggingOptions,
launchArguments: launchArguments, launchArguments: launchArguments,
ipv6: ipv6,
uninstallFirst: false, uninstallFirst: false,
skipInstall: true, skipInstall: true,
); );
@ -723,6 +728,7 @@ class IOSDevice extends Device {
/// Wireless devices require using the device IP as the host. /// Wireless devices require using the device IP as the host.
Future<Uri?> _discoverDartVMForCoreDevice({ Future<Uri?> _discoverDartVMForCoreDevice({
required String packageId, required String packageId,
required bool ipv6,
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
ProtocolDiscovery? vmServiceDiscovery, ProtocolDiscovery? vmServiceDiscovery,
}) async { }) async {
@ -769,7 +775,7 @@ class IOSDevice extends Device {
final Future<Uri?> vmUrlFromMDns = MDnsVmServiceDiscovery.instance!.getVMServiceUriForLaunch( final Future<Uri?> vmUrlFromMDns = MDnsVmServiceDiscovery.instance!.getVMServiceUriForLaunch(
packageId, packageId,
this, this,
usesIpv6: debuggingOptions.ipv6, usesIpv6: ipv6,
useDeviceIPAsHost: isWirelesslyConnected, useDeviceIPAsHost: isWirelesslyConnected,
); );
@ -808,6 +814,7 @@ class IOSDevice extends Device {
required Directory bundle, required Directory bundle,
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
required List<String> launchArguments, required List<String> launchArguments,
required bool ipv6,
required bool uninstallFirst, required bool uninstallFirst,
bool skipInstall = false, bool skipInstall = false,
}) { }) {
@ -838,7 +845,7 @@ class IOSDevice extends Device {
portForwarder: isWirelesslyConnected ? null : portForwarder, portForwarder: isWirelesslyConnected ? null : portForwarder,
hostPort: debuggingOptions.hostVmServicePort, hostPort: debuggingOptions.hostVmServicePort,
devicePort: debuggingOptions.deviceVmServicePort, devicePort: debuggingOptions.deviceVmServicePort,
ipv6: debuggingOptions.ipv6, ipv6: ipv6,
logger: _logger, logger: _logger,
); );
} }

View File

@ -90,7 +90,6 @@ class IOSSimulatorUtils {
name: name, name: name,
simControl: _simControl, simControl: _simControl,
simulatorCategory: device.category, simulatorCategory: device.category,
logger: _simControl._logger,
); );
}).whereType<IOSSimulator>().toList(); }).whereType<IOSSimulator>().toList();
} }
@ -357,7 +356,6 @@ class IOSSimulator extends Device {
required this.name, required this.name,
required this.simulatorCategory, required this.simulatorCategory,
required SimControl simControl, required SimControl simControl,
required super.logger,
}) : _simControl = simControl, }) : _simControl = simControl,
super( super(
category: Category.mobile, category: Category.mobile,
@ -474,6 +472,7 @@ class IOSSimulator extends Device {
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
Map<String, Object?> platformArgs = const <String, Object?>{}, Map<String, Object?> platformArgs = const <String, Object?>{},
bool prebuiltApplication = false, bool prebuiltApplication = false,
bool ipv6 = false,
String? userIdentifier, String? userIdentifier,
}) async { }) async {
if (!prebuiltApplication && package is BuildableIOSApp) { if (!prebuiltApplication && package is BuildableIOSApp) {
@ -502,7 +501,7 @@ class IOSSimulator extends Device {
if (debuggingOptions.debuggingEnabled) { if (debuggingOptions.debuggingEnabled) {
vmServiceDiscovery = ProtocolDiscovery.vmService( vmServiceDiscovery = ProtocolDiscovery.vmService(
getLogReader(app: package), getLogReader(app: package),
ipv6: debuggingOptions.ipv6, ipv6: ipv6,
hostPort: debuggingOptions.hostVmServicePort, hostPort: debuggingOptions.hostVmServicePort,
devicePort: debuggingOptions.deviceVmServicePort, devicePort: debuggingOptions.deviceVmServicePort,
logger: globals.logger, logger: globals.logger,

View File

@ -50,6 +50,7 @@ class DwdsWebRunnerFactory extends WebRunnerFactory {
String? target, String? target,
required bool stayResident, required bool stayResident,
required FlutterProject flutterProject, required FlutterProject flutterProject,
required bool? ipv6,
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
UrlTunneller? urlTunneller, UrlTunneller? urlTunneller,
required Logger logger, required Logger logger,
@ -64,6 +65,7 @@ class DwdsWebRunnerFactory extends WebRunnerFactory {
target: target, target: target,
flutterProject: flutterProject, flutterProject: flutterProject,
debuggingOptions: debuggingOptions, debuggingOptions: debuggingOptions,
ipv6: ipv6,
stayResident: stayResident, stayResident: stayResident,
urlTunneller: urlTunneller, urlTunneller: urlTunneller,
machine: machine, machine: machine,
@ -87,6 +89,7 @@ class ResidentWebRunner extends ResidentRunner {
bool stayResident = true, bool stayResident = true,
bool machine = false, bool machine = false,
required this.flutterProject, required this.flutterProject,
required bool? ipv6,
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
required FileSystem fileSystem, required FileSystem fileSystem,
required Logger logger, required Logger logger,
@ -94,7 +97,6 @@ class ResidentWebRunner extends ResidentRunner {
required Usage usage, required Usage usage,
required Analytics analytics, required Analytics analytics,
UrlTunneller? urlTunneller, UrlTunneller? urlTunneller,
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
ResidentDevtoolsHandlerFactory devtoolsHandler = createDefaultHandler, ResidentDevtoolsHandlerFactory devtoolsHandler = createDefaultHandler,
}) : _fileSystem = fileSystem, }) : _fileSystem = fileSystem,
_logger = logger, _logger = logger,
@ -106,6 +108,7 @@ class ResidentWebRunner extends ResidentRunner {
<FlutterDevice>[device], <FlutterDevice>[device],
target: target ?? fileSystem.path.join('lib', 'main.dart'), target: target ?? fileSystem.path.join('lib', 'main.dart'),
debuggingOptions: debuggingOptions, debuggingOptions: debuggingOptions,
ipv6: ipv6,
stayResident: stayResident, stayResident: stayResident,
machine: machine, machine: machine,
devtoolsHandler: devtoolsHandler, devtoolsHandler: devtoolsHandler,
@ -192,7 +195,6 @@ class ResidentWebRunner extends ResidentRunner {
if (_exited) { if (_exited) {
return; return;
} }
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
await residentDevtoolsHandler!.shutdown(); await residentDevtoolsHandler!.shutdown();
await _stdOutSub?.cancel(); await _stdOutSub?.cancel();
await _stdErrSub?.cancel(); await _stdErrSub?.cancel();
@ -245,6 +247,7 @@ class ResidentWebRunner extends ResidentRunner {
Future<int> run({ Future<int> run({
Completer<DebugConnectionInfo>? connectionInfoCompleter, Completer<DebugConnectionInfo>? connectionInfoCompleter,
Completer<void>? appStartedCompleter, Completer<void>? appStartedCompleter,
bool enableDevTools = false, // ignored, we don't yet support devtools for web
String? route, String? route,
}) async { }) async {
final ApplicationPackage? package = await ApplicationPackageFactory.instance!.getPackageForPlatform( final ApplicationPackage? package = await ApplicationPackageFactory.instance!.getPackageForPlatform(
@ -365,6 +368,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
return attach( return attach(
connectionInfoCompleter: connectionInfoCompleter, connectionInfoCompleter: connectionInfoCompleter,
appStartedCompleter: appStartedCompleter, appStartedCompleter: appStartedCompleter,
enableDevTools: enableDevTools,
); );
}); });
} on WebSocketException catch (error, stackTrace) { } on WebSocketException catch (error, stackTrace) {
@ -472,14 +476,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
final Duration elapsed = _systemClock.now().difference(start); final Duration elapsed = _systemClock.now().difference(start);
final String elapsedMS = getElapsedAsMilliseconds(elapsed); final String elapsedMS = getElapsedAsMilliseconds(elapsed);
_logger.printStatus('Restarted application in $elapsedMS.'); _logger.printStatus('Restarted application in $elapsedMS.');
// TODO(bkonyi): replace with code below when ready to serve DevTools from DDS.
unawaited(residentDevtoolsHandler!.hotRestart(flutterDevices)); unawaited(residentDevtoolsHandler!.hotRestart(flutterDevices));
/*
for (final FlutterDevice? device in flutterDevices) {
unawaited(device?.handleHotRestart());
}
*/
// Don't track restart times for dart2js builds or web-server devices. // Don't track restart times for dart2js builds or web-server devices.
if (debuggingOptions.buildInfo.isDebug && deviceIsDebuggable) { if (debuggingOptions.buildInfo.isDebug && deviceIsDebuggable) {
@ -606,6 +603,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
Completer<DebugConnectionInfo>? connectionInfoCompleter, Completer<DebugConnectionInfo>? connectionInfoCompleter,
Completer<void>? appStartedCompleter, Completer<void>? appStartedCompleter,
bool allowExistingDdsInstance = false, bool allowExistingDdsInstance = false,
bool enableDevTools = false, // ignored, we don't yet support devtools for web
bool needsFullRestart = true, bool needsFullRestart = true,
}) async { }) async {
if (_chromiumLauncher != null) { if (_chromiumLauncher != null) {
@ -684,14 +682,13 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
} }
}); });
} }
} if (enableDevTools) {
// TODO(bkonyi): remove when ready to serve DevTools from DDS. // The method below is guaranteed never to return a failing future.
if (debuggingOptions.enableDevTools) { unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools(
// The method below is guaranteed never to return a failing future. devToolsServerAddress: debuggingOptions.devToolsServerAddress,
unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools( flutterDevices: flutterDevices,
devToolsServerAddress: debuggingOptions.devToolsServerAddress, ));
flutterDevices: flutterDevices, }
));
} }
if (websocketUri != null) { if (websocketUri != null) {
if (debuggingOptions.vmserviceOutFile != null) { if (debuggingOptions.vmserviceOutFile != null) {

View File

@ -99,6 +99,7 @@ class MacOSDesignedForIPadDevice extends DesktopDevice {
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
Map<String, Object?> platformArgs = const <String, Object>{}, Map<String, Object?> platformArgs = const <String, Object>{},
bool prebuiltApplication = false, bool prebuiltApplication = false,
bool ipv6 = false,
String? userIdentifier, String? userIdentifier,
}) async { }) async {
// Only attaching to a running app launched from Xcode is supported. // Only attaching to a running app launched from Xcode is supported.

View File

@ -95,7 +95,7 @@ class PreviewDeviceDiscovery extends PollingDeviceDiscovery {
class PreviewDevice extends Device { class PreviewDevice extends Device {
PreviewDevice({ PreviewDevice({
required ProcessManager processManager, required ProcessManager processManager,
required super.logger, required Logger logger,
required FileSystem fileSystem, required FileSystem fileSystem,
required Artifacts artifacts, required Artifacts artifacts,
required File previewBinary, required File previewBinary,
@ -170,6 +170,7 @@ class PreviewDevice extends Device {
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
Map<String, dynamic> platformArgs = const <String, dynamic>{}, Map<String, dynamic> platformArgs = const <String, dynamic>{},
bool prebuiltApplication = false, bool prebuiltApplication = false,
bool ipv6 = false,
String? userIdentifier, String? userIdentifier,
}) async { }) async {
final Directory assetDirectory = _fileSystem.systemTempDirectory final Directory assetDirectory = _fileSystem.systemTempDirectory
@ -213,7 +214,7 @@ class PreviewDevice extends Device {
final ProtocolDiscovery vmServiceDiscovery = ProtocolDiscovery.vmService(_logReader, final ProtocolDiscovery vmServiceDiscovery = ProtocolDiscovery.vmService(_logReader,
devicePort: debuggingOptions.deviceVmServicePort, devicePort: debuggingOptions.deviceVmServicePort,
hostPort: debuggingOptions.hostVmServicePort, hostPort: debuggingOptions.hostVmServicePort,
ipv6: debuggingOptions.ipv6, ipv6: ipv6,
logger: _logger, logger: _logger,
); );
try { try {

View File

@ -19,7 +19,6 @@ import '../device.dart';
import '../device_port_forwarder.dart'; import '../device_port_forwarder.dart';
import '../device_vm_service_discovery_for_attach.dart'; import '../device_vm_service_discovery_for_attach.dart';
import '../project.dart'; import '../project.dart';
import '../resident_runner.dart';
import 'debounce_data_stream.dart'; import 'debounce_data_stream.dart';
import 'file_transfer.dart'; import 'file_transfer.dart';
@ -176,7 +175,7 @@ class ProxiedDevice extends Device {
required this.supportsScreenshot, required this.supportsScreenshot,
required this.supportsFastStart, required this.supportsFastStart,
required bool supportsHardwareRendering, required bool supportsHardwareRendering,
required super.logger, required Logger logger,
FileTransfer fileTransfer = const FileTransfer(), FileTransfer fileTransfer = const FileTransfer(),
}): _deltaFileTransfer = deltaFileTransfer, }): _deltaFileTransfer = deltaFileTransfer,
_enableDdsProxy = enableDdsProxy, _enableDdsProxy = enableDdsProxy,
@ -335,6 +334,7 @@ class ProxiedDevice extends Device {
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
Map<String, Object?> platformArgs = const <String, Object?>{}, Map<String, Object?> platformArgs = const <String, Object?>{},
bool prebuiltApplication = false, bool prebuiltApplication = false,
bool ipv6 = false,
String? userIdentifier, String? userIdentifier,
}) async { }) async {
final Map<String, Object?> result = _cast<Map<String, Object?>>(await connection.sendRequest('device.startApp', <String, Object?>{ final Map<String, Object?> result = _cast<Map<String, Object?>>(await connection.sendRequest('device.startApp', <String, Object?>{
@ -345,7 +345,7 @@ class ProxiedDevice extends Device {
'debuggingOptions': debuggingOptions.toJson(), 'debuggingOptions': debuggingOptions.toJson(),
'platformArgs': platformArgs, 'platformArgs': platformArgs,
'prebuiltApplication': prebuiltApplication, 'prebuiltApplication': prebuiltApplication,
'ipv6': debuggingOptions.ipv6, 'ipv6': ipv6,
'userIdentifier': userIdentifier, 'userIdentifier': userIdentifier,
})); }));
final bool started = _cast<bool>(result['started']); final bool started = _cast<bool>(result['started']);
@ -748,7 +748,7 @@ Future<ServerSocket> _defaultCreateServerSocket(Logger logger, int? hostPort, bo
/// There are a lot of communications between DDS and the VM service on the /// 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 /// device. When using proxied device, starting DDS remotely helps reduces the
/// amount of data transferred with the remote daemon, hence improving latency. /// amount of data transferred with the remote daemon, hence improving latency.
class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMixin implements DartDevelopmentService { class ProxiedDartDevelopmentService implements DartDevelopmentService {
ProxiedDartDevelopmentService( ProxiedDartDevelopmentService(
this.connection, this.connection,
this.deviceId, { this.deviceId, {
@ -756,11 +756,10 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi
required ProxiedPortForwarder proxiedPortForwarder, required ProxiedPortForwarder proxiedPortForwarder,
required ProxiedPortForwarder devicePortForwarder, required ProxiedPortForwarder devicePortForwarder,
@visibleForTesting DartDevelopmentService? localDds, @visibleForTesting DartDevelopmentService? localDds,
}) : }) : _logger = logger,
_logger = logger,
_proxiedPortForwarder = proxiedPortForwarder, _proxiedPortForwarder = proxiedPortForwarder,
_devicePortForwarder = devicePortForwarder, _devicePortForwarder = devicePortForwarder,
_localDds = localDds ?? DartDevelopmentService(logger: logger); _localDds = localDds ?? DartDevelopmentService();
final String deviceId; final String deviceId;
@ -777,9 +776,10 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi
/// It forwards a port on the remotely connected device, to the remote host, then to the local host. /// It forwards a port on the remotely connected device, to the remote host, then to the local host.
final ProxiedPortForwarder _devicePortForwarder; final ProxiedPortForwarder _devicePortForwarder;
Uri? _localUri;
@override @override
Uri? get uri => _ddsStartedLocally ? _localDds.uri : _localUri; Uri? get uri => _ddsStartedLocally ? _localDds.uri : _localUri;
Uri? _localUri;
@override @override
Future<void> get done => _completer.future; Future<void> get done => _completer.future;
@ -792,14 +792,11 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi
@override @override
Future<void> startDartDevelopmentService( Future<void> startDartDevelopmentService(
Uri vmServiceUri, { Uri vmServiceUri, {
FlutterDevice? device, required Logger logger,
int? ddsPort, int? hostPort,
bool? ipv6, bool? ipv6,
bool? disableServiceAuthCodes, bool? disableServiceAuthCodes,
bool enableDevTools = false,
bool cacheStartupProfile = false, bool cacheStartupProfile = false,
String? google3WorkspaceRoot,
Uri? devToolsServerAddress,
}) async { }) async {
// Locate the original VM service port on the remote daemon. // Locate the original VM service port on the remote daemon.
// A proxied device has two PortForwarder. Check both to determine which // A proxied device has two PortForwarder. Check both to determine which
@ -808,26 +805,18 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi
_proxiedPortForwarder.originalRemotePort(vmServiceUri.port) ?? _proxiedPortForwarder.originalRemotePort(vmServiceUri.port) ??
_devicePortForwarder.originalRemotePort(vmServiceUri.port); _devicePortForwarder.originalRemotePort(vmServiceUri.port);
Future<void> startLocalDds() async { if (remoteVMServicePort == null) {
_logger.printTrace('VM service port is not a forwarded port. Start DDS locally.');
_ddsStartedLocally = true; _ddsStartedLocally = true;
await _localDds.startDartDevelopmentService( await _localDds.startDartDevelopmentService(
vmServiceUri, vmServiceUri,
ddsPort: ddsPort, logger: logger,
hostPort: hostPort,
ipv6: ipv6, ipv6: ipv6,
disableServiceAuthCodes: disableServiceAuthCodes, disableServiceAuthCodes: disableServiceAuthCodes,
cacheStartupProfile: cacheStartupProfile, cacheStartupProfile: cacheStartupProfile,
enableDevTools: enableDevTools,
google3WorkspaceRoot: google3WorkspaceRoot,
devToolsServerAddress: devToolsServerAddress,
); );
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// unawaited(_localDds.invokeServiceExtensions(device));
unawaited(_localDds.done.then(_completer.complete)); 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; return;
} }
@ -846,33 +835,11 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi
// Ignore if we did not receive any event from the server. // Ignore if we did not receive any event from the server.
}, },
)); ));
final Object? response = await connection.sendRequest(method, <String, Object?>{ remoteUriStr = _cast<String?>(await connection.sendRequest(method, <String, Object?>{
'deviceId': deviceId, 'deviceId': deviceId,
'vmServiceUri': remoteVMServiceUri.toString(), 'vmServiceUri': remoteVMServiceUri.toString(),
'disableServiceAuthCodes': disableServiceAuthCodes, 'disableServiceAuthCodes': disableServiceAuthCodes,
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS. }));
// 'enableDevTools': enableDevTools,
// if (devToolsServerAddress != null) 'devToolsServerAddress': devToolsServerAddress.toString(),
});
if (response is Map<String, Object?>) {
remoteUriStr = response['ddsUri'] as String?;
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
/*
final String? devToolsUriStr = response['devToolsUri'] as String?;
if (devToolsUriStr != null) {
_remoteDevToolsUri = Uri.parse(devToolsUriStr);
}
final String? dtdUriStr = response['dtdUri'] as String?;
if (dtdUriStr != null) {
_remoteDtdUri = Uri.parse(dtdUriStr);
}
*/
} else {
// For backwards compatibility in google3.
// TODO(bkonyi): remove once a newer version of the flutter_tool is rolled out.
remoteUriStr = _cast<String?>(response);
}
} on String catch (e) { } on String catch (e) {
if (!e.contains(method)) { if (!e.contains(method)) {
rethrow; rethrow;
@ -883,7 +850,16 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi
if (remoteUriStr == null) { if (remoteUriStr == null) {
_logger.printTrace('Remote daemon cannot start DDS. Start a local DDS instead.'); _logger.printTrace('Remote daemon cannot start DDS. Start a local DDS instead.');
await startLocalDds(); _ddsStartedLocally = true;
await _localDds.startDartDevelopmentService(
vmServiceUri,
logger: logger,
hostPort: hostPort,
ipv6: ipv6,
disableServiceAuthCodes: disableServiceAuthCodes,
cacheStartupProfile: cacheStartupProfile,
);
unawaited(_localDds.done.then(_completer.complete));
return; return;
} }
@ -893,7 +869,7 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi
final Uri remoteUri = Uri.parse(remoteUriStr); final Uri remoteUri = Uri.parse(remoteUriStr);
final int localPort = await _proxiedPortForwarder.forward( final int localPort = await _proxiedPortForwarder.forward(
remoteUri.port, remoteUri.port,
hostPort: ddsPort, hostPort: hostPort,
ipv6: ipv6, ipv6: ipv6,
); );
@ -909,7 +885,7 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi
@override @override
Future<void> shutdown() async { Future<void> shutdown() async {
if (_ddsStartedLocally) { if (_ddsStartedLocally) {
_localDds.shutdown(); await _localDds.shutdown();
_ddsStartedLocally = false; _ddsStartedLocally = false;
} else { } else {
await connection.sendRequest('device.shutdownDartDevelopmentService', <String, Object?>{ await connection.sendRequest('device.shutdownDartDevelopmentService', <String, Object?>{
@ -917,6 +893,14 @@ class ProxiedDartDevelopmentService with DartDevelopmentServiceLocalOperationsMi
}); });
} }
} }
@override
void setExternalDevToolsUri(Uri uri) {
connection.sendRequest('device.setExternalDevToolsUriForDartDevelopmentService', <String, Object?>{
'deviceId': deviceId,
'uri': uri.toString(),
});
}
} }
class ProxiedVMServiceDiscoveryForAttach extends VMServiceDiscoveryForAttach { class ProxiedVMServiceDiscoveryForAttach extends VMServiceDiscoveryForAttach {

View File

@ -2,10 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // 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 'dart:async';
import 'package:browser_launcher/browser_launcher.dart'; import 'package:browser_launcher/browser_launcher.dart';
@ -114,6 +110,18 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler {
return; 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<void> callServiceExtensions() async { Future<void> callServiceExtensions() async {
final List<FlutterDevice?> devicesWithExtension = await _devicesWithExtensions(flutterDevices); final List<FlutterDevice?> devicesWithExtension = await _devicesWithExtensions(flutterDevices);
await Future.wait( await Future.wait(
@ -206,12 +214,10 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler {
}, },
); );
} on Exception catch (e) { } on Exception catch (e) {
if (!_shutdown) { _logger.printError(
_logger.printError( 'Failed to set DevTools server address: $e. Deep links to'
'Failed to set DevTools server address: $e. Deep links to' ' DevTools will not show in Flutter errors.',
' DevTools will not show in Flutter errors.', );
);
}
} }
} }
@ -260,13 +266,11 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler {
}, },
); );
} on Exception catch (e) { } on Exception catch (e) {
if (!_shutdown) { _logger.printError(e.toString());
_logger.printError(e.toString()); _logger.printError(
_logger.printError( 'Failed to set vm service URI: $e. Deep links to DevTools'
'Failed to set vm service URI: $e. Deep links to DevTools' ' will not show in Flutter errors.',
' will not show in Flutter errors.', );
);
}
} }
} }
@ -304,10 +308,10 @@ class FlutterResidentDevtoolsHandler implements ResidentDevtoolsHandler {
@override @override
Future<void> shutdown() async { Future<void> shutdown() async {
_shutdown = true; if (_devToolsLauncher == null || _shutdown || !_served) {
if (_devToolsLauncher == null || !_served) {
return; return;
} }
_shutdown = true;
_readyToAnnounce = false; _readyToAnnounce = false;
await _devToolsLauncher.close(); await _devToolsLauncher.close();
} }

View File

@ -4,6 +4,7 @@
import 'dart:async'; import 'dart:async';
import 'package:dds/dds.dart' as dds;
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart'; import 'package:package_config/package_config.dart';
import 'package:vm_service/vm_service.dart' as vm_service; import 'package:vm_service/vm_service.dart' as vm_service;
@ -14,7 +15,6 @@ import 'asset.dart';
import 'base/command_help.dart'; import 'base/command_help.dart';
import 'base/common.dart'; import 'base/common.dart';
import 'base/context.dart'; import 'base/context.dart';
import 'base/dds.dart';
import 'base/file_system.dart'; import 'base/file_system.dart';
import 'base/io.dart' as io; import 'base/io.dart' as io;
import 'base/logger.dart'; import 'base/logger.dart';
@ -252,9 +252,13 @@ class FlutterDevice {
CompileExpression? compileExpression, CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod, GetSkSLMethod? getSkSLMethod,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
required DebuggingOptions debuggingOptions,
int? hostVmServicePort, int? hostVmServicePort,
int? ddsPort,
bool disableServiceAuthCodes = false,
bool cacheStartupProfile = false,
bool enableDds = true,
required bool allowExistingDdsInstance, required bool allowExistingDdsInstance,
bool ipv6 = false,
}) { }) {
final Completer<void> completer = Completer<void>(); final Completer<void> completer = Completer<void>();
late StreamSubscription<void> subscription; late StreamSubscription<void> subscription;
@ -266,11 +270,11 @@ class FlutterDevice {
isWaitingForVm = true; isWaitingForVm = true;
bool existingDds = false; bool existingDds = false;
FlutterVmService? service; FlutterVmService? service;
if (debuggingOptions.enableDds) { if (enableDds) {
void handleError(Exception e, StackTrace st) { void handleError(Exception e, StackTrace st) {
globals.printTrace('Fail to connect to service protocol: $vmServiceUri: $e'); globals.printTrace('Fail to connect to service protocol: $vmServiceUri: $e');
if (!completer.isCompleted) { if (!completer.isCompleted) {
completer.completeError('failed to connect to $vmServiceUri $e', st); completer.completeError('failed to connect to $vmServiceUri', st);
} }
} }
// First check if the VM service is actually listening on vmServiceUri as // First check if the VM service is actually listening on vmServiceUri as
@ -282,7 +286,7 @@ class FlutterDevice {
} on Exception catch (exception) { } on Exception catch (exception) {
globals.printTrace('Fail to connect to service protocol: $vmServiceUri: $exception'); globals.printTrace('Fail to connect to service protocol: $vmServiceUri: $exception');
if (!completer.isCompleted && !_isListeningForVmServiceUri!) { if (!completer.isCompleted && !_isListeningForVmServiceUri!) {
completer.completeError('failed to connect to $vmServiceUri $exception'); completer.completeError('failed to connect to $vmServiceUri');
} }
return; return;
} }
@ -291,13 +295,17 @@ class FlutterDevice {
// (e.g., failure to bind to a port, failure to connect to the VM service, // (e.g., failure to bind to a port, failure to connect to the VM service,
// attaching to a VM service with existing clients, etc.). // attaching to a VM service with existing clients, etc.).
try { try {
await device!.dds.startDartDevelopmentServiceFromDebuggingOptions( await device!.dds.startDartDevelopmentService(
vmServiceUri, vmServiceUri,
debuggingOptions: debuggingOptions, hostPort: ddsPort,
ipv6: ipv6,
disableServiceAuthCodes: disableServiceAuthCodes,
logger: globals.logger,
cacheStartupProfile: cacheStartupProfile,
); );
} on DartDevelopmentServiceException catch (e, st) { } on dds.DartDevelopmentServiceException catch (e, st) {
if (!allowExistingDdsInstance || if (!allowExistingDdsInstance ||
(e.errorCode != DartDevelopmentServiceException.existingDdsInstanceError)) { (e.errorCode != dds.DartDevelopmentServiceException.existingDdsInstanceError)) {
handleError(e, st); handleError(e, st);
return; return;
} else { } else {
@ -318,7 +326,7 @@ class FlutterDevice {
service = await Future.any<dynamic>( service = await Future.any<dynamic>(
<Future<dynamic>>[ <Future<dynamic>>[
connectToVmService( connectToVmService(
debuggingOptions.enableDds ? (device!.dds.uri ?? vmServiceUri!): vmServiceUri!, enableDds ? (device!.dds.uri ?? vmServiceUri!): vmServiceUri!,
reloadSources: reloadSources, reloadSources: reloadSources,
restart: restart, restart: restart,
compileExpression: compileExpression, compileExpression: compileExpression,
@ -335,7 +343,7 @@ class FlutterDevice {
} on Exception catch (exception) { } on Exception catch (exception) {
globals.printTrace('Fail to connect to service protocol: $vmServiceUri: $exception'); globals.printTrace('Fail to connect to service protocol: $vmServiceUri: $exception');
if (!completer.isCompleted && !_isListeningForVmServiceUri!) { if (!completer.isCompleted && !_isListeningForVmServiceUri!) {
completer.completeError('failed to connect to $vmServiceUri $exception'); completer.completeError('failed to connect to $vmServiceUri');
} }
return; return;
} }
@ -345,22 +353,6 @@ class FlutterDevice {
globals.printTrace('Successfully connected to service protocol: $vmServiceUri'); globals.printTrace('Successfully connected to service protocol: $vmServiceUri');
vmService = service; vmService = service;
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
/*
if (debuggingOptions.enableDds && !existingDds) {
// Don't await this as service extensions won't return if the target
// isolate is paused on start.
unawaited(device!.dds.invokeServiceExtensions(this));
}
if (existingDds && debuggingOptions.devToolsServerAddress != null) {
// Don't await this as service extensions won't return if the target
// isolate is paused on start.
unawaited(device!.dds.maybeCallDevToolsUriServiceExtension(
device: this,
uri: debuggingOptions.devToolsServerAddress,
));
}
*/
(await device!.getLogReader(app: package)).connectedVMService = vmService; (await device!.getLogReader(app: package)).connectedVMService = vmService;
completer.complete(); completer.complete();
await subscription.cancel(); await subscription.cancel();
@ -480,6 +472,7 @@ class FlutterDevice {
platformArgs: platformArgs, platformArgs: platformArgs,
route: route, route: route,
prebuiltApplication: prebuiltMode, prebuiltApplication: prebuiltMode,
ipv6: hotRunner.ipv6!,
userIdentifier: userIdentifier, userIdentifier: userIdentifier,
); );
@ -545,6 +538,7 @@ class FlutterDevice {
platformArgs: platformArgs, platformArgs: platformArgs,
route: route, route: route,
prebuiltApplication: prebuiltMode, prebuiltApplication: prebuiltMode,
ipv6: coldRunner.ipv6!,
userIdentifier: userIdentifier, userIdentifier: userIdentifier,
); );
@ -616,13 +610,6 @@ class FlutterDevice {
await generator?.reject(); await generator?.reject();
} }
} }
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
/*
Future<void> handleHotRestart() async {
await device?.dds.handleHotRestart(this);
}
*/
} }
/// A subset of the [ResidentRunner] for delegating to attached flutter devices. /// A subset of the [ResidentRunner] for delegating to attached flutter devices.
@ -661,7 +648,6 @@ abstract class ResidentHandlers {
/// Whether all of the connected devices support hot reload. /// Whether all of the connected devices support hot reload.
bool get canHotReload; bool get canHotReload;
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
ResidentDevtoolsHandler? get residentDevtoolsHandler; ResidentDevtoolsHandler? get residentDevtoolsHandler;
@protected @protected
@ -1110,6 +1096,7 @@ abstract class ResidentRunner extends ResidentHandlers {
required this.target, required this.target,
required this.debuggingOptions, required this.debuggingOptions,
String? projectRootPath, String? projectRootPath,
this.ipv6,
this.stayResident = true, this.stayResident = true,
this.hotMode = true, this.hotMode = true,
String? dillOutputPath, String? dillOutputPath,
@ -1132,7 +1119,6 @@ abstract class ResidentRunner extends ResidentHandlers {
if (!artifactDirectory.existsSync()) { if (!artifactDirectory.existsSync()) {
artifactDirectory.createSync(recursive: true); artifactDirectory.createSync(recursive: true);
} }
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
_residentDevtoolsHandler = devtoolsHandler(DevtoolsLauncher.instance, this, globals.logger); _residentDevtoolsHandler = devtoolsHandler(DevtoolsLauncher.instance, this, globals.logger);
} }
@ -1150,6 +1136,7 @@ abstract class ResidentRunner extends ResidentHandlers {
@override @override
final bool stayResident; final bool stayResident;
final bool? ipv6;
final String? _dillOutputPath; final String? _dillOutputPath;
/// The parent location of the incremental artifacts. /// The parent location of the incremental artifacts.
final Directory artifactDirectory; final Directory artifactDirectory;
@ -1161,7 +1148,6 @@ abstract class ResidentRunner extends ResidentHandlers {
final CommandHelp commandHelp; final CommandHelp commandHelp;
final bool machine; final bool machine;
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
@override @override
ResidentDevtoolsHandler? get residentDevtoolsHandler => _residentDevtoolsHandler; ResidentDevtoolsHandler? get residentDevtoolsHandler => _residentDevtoolsHandler;
ResidentDevtoolsHandler? _residentDevtoolsHandler; ResidentDevtoolsHandler? _residentDevtoolsHandler;
@ -1242,6 +1228,7 @@ abstract class ResidentRunner extends ResidentHandlers {
Future<int?> run({ Future<int?> run({
Completer<DebugConnectionInfo>? connectionInfoCompleter, Completer<DebugConnectionInfo>? connectionInfoCompleter,
Completer<void>? appStartedCompleter, Completer<void>? appStartedCompleter,
bool enableDevTools = false,
String? route, String? route,
}); });
@ -1253,6 +1240,7 @@ abstract class ResidentRunner extends ResidentHandlers {
Completer<DebugConnectionInfo>? connectionInfoCompleter, Completer<DebugConnectionInfo>? connectionInfoCompleter,
Completer<void>? appStartedCompleter, Completer<void>? appStartedCompleter,
bool allowExistingDdsInstance = false, bool allowExistingDdsInstance = false,
bool enableDevTools = false,
bool needsFullRestart = true, bool needsFullRestart = true,
}); });
@ -1318,21 +1306,19 @@ abstract class ResidentRunner extends ResidentHandlers {
@override @override
Future<void> exit() async { Future<void> exit() async {
_exited = true; _exited = true;
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
await residentDevtoolsHandler!.shutdown(); await residentDevtoolsHandler!.shutdown();
await stopEchoingDeviceLog(); await stopEchoingDeviceLog();
await preExit(); await preExit();
await exitApp(); // calls appFinished await exitApp(); // calls appFinished
shutdownDartDevelopmentService(); await shutdownDartDevelopmentService();
} }
@override @override
Future<void> detach() async { Future<void> detach() async {
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
await residentDevtoolsHandler!.shutdown(); await residentDevtoolsHandler!.shutdown();
await stopEchoingDeviceLog(); await stopEchoingDeviceLog();
await preExit(); await preExit();
shutdownDartDevelopmentService(); await shutdownDartDevelopmentService();
appFinished(); appFinished();
} }
@ -1342,10 +1328,12 @@ abstract class ResidentRunner extends ResidentHandlers {
); );
} }
void shutdownDartDevelopmentService() { Future<void> shutdownDartDevelopmentService() async {
for (final FlutterDevice device in flutterDevices) { await Future.wait<void>(
device.device?.dds.shutdown(); flutterDevices.map<Future<void>>(
} (FlutterDevice? device) => device?.device?.dds.shutdown() ?? Future<void>.value()
)
);
} }
@protected @protected
@ -1414,14 +1402,18 @@ abstract class ResidentRunner extends ResidentHandlers {
// Listen for service protocol connection to close. // Listen for service protocol connection to close.
for (final FlutterDevice? device in flutterDevices) { for (final FlutterDevice? device in flutterDevices) {
await device!.connect( await device!.connect(
debuggingOptions: debuggingOptions,
reloadSources: reloadSources, reloadSources: reloadSources,
restart: restart, restart: restart,
compileExpression: compileExpression, compileExpression: compileExpression,
enableDds: debuggingOptions.enableDds,
ddsPort: debuggingOptions.ddsPort,
allowExistingDdsInstance: allowExistingDdsInstance, allowExistingDdsInstance: allowExistingDdsInstance,
hostVmServicePort: debuggingOptions.hostVmServicePort, hostVmServicePort: debuggingOptions.hostVmServicePort,
getSkSLMethod: getSkSLMethod, getSkSLMethod: getSkSLMethod,
printStructuredErrorLogMethod: printStructuredErrorLog, printStructuredErrorLogMethod: printStructuredErrorLog,
ipv6: ipv6 ?? false,
disableServiceAuthCodes: debuggingOptions.disableServiceAuthCodes,
cacheStartupProfile: debuggingOptions.cacheStartupProfile,
); );
await device.vmService!.getFlutterViews(); await device.vmService!.getFlutterViews();
@ -1511,8 +1503,7 @@ abstract class ResidentRunner extends ResidentHandlers {
bool get reportedDebuggers => _reportedDebuggers; bool get reportedDebuggers => _reportedDebuggers;
bool _reportedDebuggers = false; 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; final DevToolsServerAddress? devToolsServerAddress = residentDevtoolsHandler!.activeDevToolsServer;
if (!residentDevtoolsHandler!.readyToAnnounce) { if (!residentDevtoolsHandler!.readyToAnnounce) {
includeDevtools = false; includeDevtools = false;
@ -1825,13 +1816,6 @@ class TerminalHandler {
case 'v': case 'v':
case 'V': case 'V':
return residentRunner.residentDevtoolsHandler!.launchDevToolsInBrowser(flutterDevices: residentRunner.flutterDevices); return residentRunner.residentDevtoolsHandler!.launchDevToolsInBrowser(flutterDevices: residentRunner.flutterDevices);
// TODO(bkonyi): uncomment and replace above line when ready to serve DevTools from DDS.
/*
return residentRunner.flutterDevices.fold<bool>(
true,
(bool s, FlutterDevice? device) => s && device!.device!.dds.launchDevToolsInBrowser(device),
);
*/
case 'w': case 'w':
case 'W': case 'W':
return residentRunner.debugDumpApp(); return residentRunner.debugDumpApp();
@ -1972,7 +1956,6 @@ abstract class DevtoolsLauncher {
@protected @protected
set dtdUri(Uri? value) => _dtdUri = value; set dtdUri(Uri? value) => _dtdUri = value;
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
/// Whether to print the Dart Tooling Daemon URI. /// Whether to print the Dart Tooling Daemon URI.
/// ///
/// This will always return false when there is not a DTD instance being /// This will always return false when there is not a DTD instance being

View File

@ -21,6 +21,7 @@ class ColdRunner extends ResidentRunner {
this.traceStartup = false, this.traceStartup = false,
this.awaitFirstFrameWhenTracing = true, this.awaitFirstFrameWhenTracing = true,
this.applicationBinary, this.applicationBinary,
bool super.ipv6 = false,
super.stayResident, super.stayResident,
super.machine, super.machine,
super.devtoolsHandler, super.devtoolsHandler,
@ -46,6 +47,7 @@ class ColdRunner extends ResidentRunner {
Future<int> run({ Future<int> run({
Completer<DebugConnectionInfo>? connectionInfoCompleter, Completer<DebugConnectionInfo>? connectionInfoCompleter,
Completer<void>? appStartedCompleter, Completer<void>? appStartedCompleter,
bool enableDevTools = false,
String? route, String? route,
}) async { }) async {
try { try {
@ -76,18 +78,18 @@ class ColdRunner extends ResidentRunner {
} }
} }
if (debuggingEnabled && debuggingOptions.serveObservatory) { if (debuggingEnabled) {
await enableObservatory(); if (enableDevTools) {
} // The method below is guaranteed never to return a failing future.
unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools(
// TODO(bkonyi): remove when ready to serve DevTools from DDS. devToolsServerAddress: debuggingOptions.devToolsServerAddress,
if (debuggingEnabled && debuggingOptions.enableDevTools) { flutterDevices: flutterDevices,
// The method below is guaranteed never to return a failing future. isStartPaused: debuggingOptions.startPaused,
unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools( ));
devToolsServerAddress: debuggingOptions.devToolsServerAddress, }
flutterDevices: flutterDevices, if (debuggingOptions.serveObservatory) {
isStartPaused: debuggingOptions.startPaused, await enableObservatory();
)); }
} }
if (flutterDevices.first.vmServiceUris != null) { if (flutterDevices.first.vmServiceUris != null) {
@ -140,6 +142,7 @@ class ColdRunner extends ResidentRunner {
Completer<DebugConnectionInfo>? connectionInfoCompleter, Completer<DebugConnectionInfo>? connectionInfoCompleter,
Completer<void>? appStartedCompleter, Completer<void>? appStartedCompleter,
bool allowExistingDdsInstance = false, bool allowExistingDdsInstance = false,
bool enableDevTools = false,
bool needsFullRestart = true, bool needsFullRestart = true,
}) async { }) async {
_didAttach = true; _didAttach = true;
@ -163,8 +166,18 @@ class ColdRunner extends ResidentRunner {
} }
} }
if (debuggingEnabled && debuggingOptions.serveObservatory) { if (debuggingEnabled) {
await enableObservatory(); if (enableDevTools) {
// The method below is guaranteed never to return a failing future.
unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools(
devToolsServerAddress: debuggingOptions.devToolsServerAddress,
flutterDevices: flutterDevices,
isStartPaused: debuggingOptions.startPaused,
));
}
if (debuggingOptions.serveObservatory) {
await enableObservatory();
}
} }
appStartedCompleter?.complete(); appStartedCompleter?.complete();
@ -190,11 +203,12 @@ class ColdRunner extends ResidentRunner {
await flutterDevice!.device!.dispose(); await flutterDevice!.device!.dispose();
} }
await residentDevtoolsHandler!.shutdown();
await stopEchoingDeviceLog(); await stopEchoingDeviceLog();
} }
@override @override
void printHelp({required bool details}) { void printHelp({ required bool details }) {
globals.printStatus('Flutter run key commands.'); globals.printStatus('Flutter run key commands.');
if (details) { if (details) {
printHelpDetails(); printHelpDetails();

View File

@ -86,6 +86,7 @@ class HotRunner extends ResidentRunner {
super.projectRootPath, super.projectRootPath,
super.dillOutputPath, super.dillOutputPath,
super.stayResident, super.stayResident,
bool super.ipv6 = false,
super.machine, super.machine,
super.devtoolsHandler, super.devtoolsHandler,
StopwatchFactory stopwatchFactory = const StopwatchFactory(), StopwatchFactory stopwatchFactory = const StopwatchFactory(),
@ -227,6 +228,7 @@ class HotRunner extends ResidentRunner {
Completer<DebugConnectionInfo>? connectionInfoCompleter, Completer<DebugConnectionInfo>? connectionInfoCompleter,
Completer<void>? appStartedCompleter, Completer<void>? appStartedCompleter,
bool allowExistingDdsInstance = false, bool allowExistingDdsInstance = false,
bool enableDevTools = false,
bool needsFullRestart = true, bool needsFullRestart = true,
}) async { }) async {
_didAttach = true; _didAttach = true;
@ -251,8 +253,7 @@ class HotRunner extends ResidentRunner {
await enableObservatory(); await enableObservatory();
} }
// TODO(bkonyi): remove when ready to serve DevTools from DDS. if (enableDevTools) {
if (debuggingOptions.enableDevTools) {
// The method below is guaranteed never to return a failing future. // The method below is guaranteed never to return a failing future.
unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools( unawaited(residentDevtoolsHandler!.serveAndAnnounceDevTools(
devToolsServerAddress: debuggingOptions.devToolsServerAddress, devToolsServerAddress: debuggingOptions.devToolsServerAddress,
@ -361,6 +362,7 @@ class HotRunner extends ResidentRunner {
Future<int> run({ Future<int> run({
Completer<DebugConnectionInfo>? connectionInfoCompleter, Completer<DebugConnectionInfo>? connectionInfoCompleter,
Completer<void>? appStartedCompleter, Completer<void>? appStartedCompleter,
bool enableDevTools = false,
String? route, String? route,
}) async { }) async {
await _calculateTargetPlatform(); await _calculateTargetPlatform();
@ -468,6 +470,7 @@ class HotRunner extends ResidentRunner {
return attach( return attach(
connectionInfoCompleter: connectionInfoCompleter, connectionInfoCompleter: connectionInfoCompleter,
appStartedCompleter: appStartedCompleter, appStartedCompleter: appStartedCompleter,
enableDevTools: enableDevTools,
needsFullRestart: false, needsFullRestart: false,
); );
} }
@ -787,11 +790,7 @@ class HotRunner extends ResidentRunner {
if (!silent) { if (!silent) {
globals.printStatus('Restarted application in ${getElapsedAsMilliseconds(timer.elapsed)}.'); globals.printStatus('Restarted application in ${getElapsedAsMilliseconds(timer.elapsed)}.');
} }
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
unawaited(residentDevtoolsHandler!.hotRestart(flutterDevices)); unawaited(residentDevtoolsHandler!.hotRestart(flutterDevices));
// for (final FlutterDevice? device in flutterDevices) {
// unawaited(device?.handleHotRestart());
// }
return result; return result;
} }
final OperationResult result = await _hotReloadHelper( final OperationResult result = await _hotReloadHelper(

View File

@ -489,7 +489,7 @@ abstract class FlutterCommand extends Command<void> {
defaultsTo: true, defaultsTo: true,
help: 'Enable (or disable, with "--no-$kEnableDevTools") the launching of the ' help: 'Enable (or disable, with "--no-$kEnableDevTools") the launching of the '
'Flutter DevTools debugger and profiler. ' 'Flutter DevTools debugger and profiler. '
'If "--no-$kEnableDevTools" is specified, "--$kDevToolsServerAddress" is ignored.' 'If specified, "--$kDevToolsServerAddress" is ignored.'
); );
argParser.addOption( argParser.addOption(
kDevToolsServerAddress, kDevToolsServerAddress,

View File

@ -414,7 +414,6 @@ class FlutterCommandRunner extends CommandRunner<void> {
throwToolExit('The "--machine" flag is only valid with the "--version" flag or the "analyze --suggestions" command.', exitCode: 2); 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; final bool shouldPrintDtdUri = topLevelResults[FlutterGlobalOptions.kPrintDtd] as bool? ?? false;
DevtoolsLauncher.instance!.printDtdUri = shouldPrintDtdUri; DevtoolsLauncher.instance!.printDtdUri = shouldPrintDtdUri;

View File

@ -6,6 +6,7 @@
import 'dart:async'; import 'dart:async';
import 'package:dds/dds.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart'; import 'package:package_config/package_config.dart';
import 'package:stream_channel/stream_channel.dart'; import 'package:stream_channel/stream_channel.dart';
@ -69,6 +70,7 @@ FlutterPlatform installHook({
Device? integrationTestDevice, Device? integrationTestDevice,
String? integrationTestUserIdentifier, String? integrationTestUserIdentifier,
TestTimeRecorder? testTimeRecorder, TestTimeRecorder? testTimeRecorder,
UriConverter? uriConverter,
TestCompilerNativeAssetsBuilder? nativeAssetsBuilder, TestCompilerNativeAssetsBuilder? nativeAssetsBuilder,
BuildInfo? buildInfo, BuildInfo? buildInfo,
}) { }) {
@ -100,6 +102,7 @@ FlutterPlatform installHook({
integrationTestDevice: integrationTestDevice, integrationTestDevice: integrationTestDevice,
integrationTestUserIdentifier: integrationTestUserIdentifier, integrationTestUserIdentifier: integrationTestUserIdentifier,
testTimeRecorder: testTimeRecorder, testTimeRecorder: testTimeRecorder,
uriConverter: uriConverter,
nativeAssetsBuilder: nativeAssetsBuilder, nativeAssetsBuilder: nativeAssetsBuilder,
buildInfo: buildInfo, buildInfo: buildInfo,
); );
@ -306,6 +309,7 @@ class FlutterPlatform extends PlatformPlugin {
this.integrationTestDevice, this.integrationTestDevice,
this.integrationTestUserIdentifier, this.integrationTestUserIdentifier,
this.testTimeRecorder, this.testTimeRecorder,
this.uriConverter,
this.nativeAssetsBuilder, this.nativeAssetsBuilder,
this.buildInfo, this.buildInfo,
}); });
@ -327,6 +331,9 @@ class FlutterPlatform extends PlatformPlugin {
final TestCompilerNativeAssetsBuilder? nativeAssetsBuilder; final TestCompilerNativeAssetsBuilder? nativeAssetsBuilder;
final BuildInfo? buildInfo; 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. /// 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 /// If this is null, the test will run as a regular test with the Flutter
@ -455,6 +462,7 @@ class FlutterPlatform extends PlatformPlugin {
icudtlPath: icudtlPath, icudtlPath: icudtlPath,
compileExpression: _compileExpressionService, compileExpression: _compileExpressionService,
fontConfigManager: _fontConfigManager, fontConfigManager: _fontConfigManager,
uriConverter: uriConverter,
); );
} }

View File

@ -5,12 +5,12 @@
import 'dart:async'; import 'dart:async';
import 'dart:io' as io; // flutter_ignore: dart_io_import; import 'dart:io' as io; // flutter_ignore: dart_io_import;
import 'package:dds/dds.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
import 'package:stream_channel/stream_channel.dart'; import 'package:stream_channel/stream_channel.dart';
import 'package:vm_service/vm_service.dart' as vm_service; import 'package:vm_service/vm_service.dart' as vm_service;
import '../base/dds.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/io.dart'; import '../base/io.dart';
import '../base/logger.dart'; import '../base/logger.dart';
@ -43,6 +43,7 @@ class FlutterTesterTestDevice extends TestDevice {
required this.icudtlPath, required this.icudtlPath,
required this.compileExpression, required this.compileExpression,
required this.fontConfigManager, required this.fontConfigManager,
required this.uriConverter,
}) : assert(!debuggingOptions.startPaused || enableVmService), }) : assert(!debuggingOptions.startPaused || enableVmService),
_gotProcessVmServiceUri = enableVmService _gotProcessVmServiceUri = enableVmService
? Completer<Uri?>() : (Completer<Uri?>()..complete()); ? Completer<Uri?>() : (Completer<Uri?>()..complete());
@ -63,8 +64,8 @@ class FlutterTesterTestDevice extends TestDevice {
final String? icudtlPath; final String? icudtlPath;
final CompileExpression? compileExpression; final CompileExpression? compileExpression;
final FontConfigManager fontConfigManager; final FontConfigManager fontConfigManager;
final UriConverter? uriConverter;
late final DartDevelopmentService _ddsLauncher = DartDevelopmentService(logger: logger);
final Completer<Uri?> _gotProcessVmServiceUri; final Completer<Uri?> _gotProcessVmServiceUri;
final Completer<int> _exitCode = Completer<int>(); final Completer<int> _exitCode = Completer<int>();
@ -169,20 +170,16 @@ class FlutterTesterTestDevice extends TestDevice {
debuggingOptions.hostVmServicePort == detectedUri.port); debuggingOptions.hostVmServicePort == detectedUri.port);
Uri? forwardingUri; Uri? forwardingUri;
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS. DartDevelopmentService? dds;
// Uri? devToolsUri;
if (debuggingOptions.enableDds) { if (debuggingOptions.enableDds) {
logger.printTrace('test $id: Starting Dart Development Service'); logger.printTrace('test $id: Starting Dart Development Service');
dds = await startDds(
await _ddsLauncher.startDartDevelopmentServiceFromDebuggingOptions(
detectedUri, detectedUri,
debuggingOptions: debuggingOptions, uriConverter: uriConverter,
); );
forwardingUri = _ddsLauncher.uri; forwardingUri = dds.uri;
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS. logger.printTrace('test $id: Dart Development Service started at ${dds.uri}, forwarding to VM service at ${dds.remoteVmServiceUri}.');
// devToolsUri = _ddsLauncher.devToolsUri;
logger.printTrace('test $id: Dart Development Service started at $forwardingUri, forwarding to VM service at $detectedUri.');
} else { } else {
forwardingUri = detectedUri; forwardingUri = detectedUri;
} }
@ -204,11 +201,7 @@ class FlutterTesterTestDevice extends TestDevice {
if (debuggingOptions.startPaused && !machine!) { if (debuggingOptions.startPaused && !machine!) {
logger.printStatus('The Dart VM service is listening on $forwardingUri'); logger.printStatus('The Dart VM service is listening on $forwardingUri');
await _startDevTools(forwardingUri, _ddsLauncher); await _startDevTools(forwardingUri, dds);
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// if (devToolsUri != null) {
// logger.printStatus('The Flutter DevTools debugger and profiler is available at: $devToolsUri');
// }
logger.printStatus(''); logger.printStatus('');
logger.printStatus('The test process has been started. Set any relevant breakpoints and then resume the test in the debugger.'); logger.printStatus('The test process has been started. Set any relevant breakpoints and then resume the test in the debugger.');
} }
@ -255,6 +248,28 @@ class FlutterTesterTestDevice extends TestDevice {
throw TestDeviceException(_getExitCodeMessage(exitCode), StackTrace.current); 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<DartDevelopmentService> startDds(Uri uri, {UriConverter? uriConverter}) {
return DartDevelopmentService.startDartDevelopmentService(
uri,
serviceUri: _ddsServiceUri,
enableAuthCodes: !debuggingOptions.disableServiceAuthCodes,
ipv6: host!.type == InternetAddressType.IPv6,
uriConverter: uriConverter,
);
}
@visibleForTesting @visibleForTesting
@protected @protected
@ -270,7 +285,6 @@ class FlutterTesterTestDevice extends TestDevice {
); );
} }
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
Future<void> _startDevTools(Uri forwardingUri, DartDevelopmentService? dds) async { Future<void> _startDevTools(Uri forwardingUri, DartDevelopmentService? dds) async {
_devToolsLauncher = DevtoolsLauncher.instance; _devToolsLauncher = DevtoolsLauncher.instance;
logger.printTrace('test $id: Serving DevTools...'); logger.printTrace('test $id: Serving DevTools...');
@ -283,6 +297,10 @@ class FlutterTesterTestDevice extends TestDevice {
await _devToolsLauncher?.ready; await _devToolsLauncher?.ready;
logger.printTrace('test $id: DevTools is being served at ${devToolsServerAddress.uri}'); 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( final Uri devToolsUri = devToolsServerAddress.uri!.replace(
// Use query instead of queryParameters to avoid unnecessary encoding. // Use query instead of queryParameters to avoid unnecessary encoding.
query: 'uri=$forwardingUri', query: 'uri=$forwardingUri',

View File

@ -40,6 +40,7 @@ abstract class FlutterTestRunner {
String? tags, String? tags,
String? excludeTags, String? excludeTags,
bool enableVmService = false, bool enableVmService = false,
bool ipv6 = false,
bool machine = false, bool machine = false,
String? precompiledDillPath, String? precompiledDillPath,
Map<String, String>? precompiledDillFiles, Map<String, String>? precompiledDillFiles,
@ -107,6 +108,7 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner {
String? tags, String? tags,
String? excludeTags, String? excludeTags,
bool enableVmService = false, bool enableVmService = false,
bool ipv6 = false,
bool machine = false, bool machine = false,
String? precompiledDillPath, String? precompiledDillPath,
Map<String, String>? precompiledDillFiles, Map<String, String>? precompiledDillFiles,
@ -237,7 +239,7 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner {
..addAll(testFiles.map((Uri uri) => uri.toString())); ..addAll(testFiles.map((Uri uri) => uri.toString()));
final InternetAddressType serverType = final InternetAddressType serverType =
debuggingOptions.ipv6 ? InternetAddressType.IPv6 : InternetAddressType.IPv4; ipv6 ? InternetAddressType.IPv6 : InternetAddressType.IPv4;
final loader.FlutterPlatform platform = loader.installHook( final loader.FlutterPlatform platform = loader.installHook(
testWrapper: testWrapper, testWrapper: testWrapper,

View File

@ -46,7 +46,7 @@ class FlutterTesterDevice extends Device {
FlutterTesterDevice(super.id, { FlutterTesterDevice(super.id, {
required ProcessManager processManager, required ProcessManager processManager,
required FlutterVersion flutterVersion, required FlutterVersion flutterVersion,
required super.logger, required Logger logger,
required FileSystem fileSystem, required FileSystem fileSystem,
required Artifacts artifacts, required Artifacts artifacts,
}) : _processManager = processManager, }) : _processManager = processManager,
@ -135,6 +135,7 @@ class FlutterTesterDevice extends Device {
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
Map<String, Object?> platformArgs = const <String, Object>{}, Map<String, Object?> platformArgs = const <String, Object>{},
bool prebuiltApplication = false, bool prebuiltApplication = false,
bool ipv6 = false,
String? userIdentifier, String? userIdentifier,
}) async { }) async {
final BuildInfo buildInfo = debuggingOptions.buildInfo; final BuildInfo buildInfo = debuggingOptions.buildInfo;
@ -192,7 +193,7 @@ class FlutterTesterDevice extends Device {
getLogReader(), getLogReader(),
hostPort: debuggingOptions.hostVmServicePort, hostPort: debuggingOptions.hostVmServicePort,
devicePort: debuggingOptions.deviceVmServicePort, devicePort: debuggingOptions.deviceVmServicePort,
ipv6: debuggingOptions.ipv6, ipv6: ipv6,
logger: _logger, logger: _logger,
); );
_logReader.initializeProcess(_process!); _logReader.initializeProcess(_process!);

View File

@ -38,7 +38,7 @@ abstract class ChromiumDevice extends Device {
required String name, required String name,
required this.chromeLauncher, required this.chromeLauncher,
required FileSystem fileSystem, required FileSystem fileSystem,
required super.logger, required Logger logger,
}) : _fileSystem = fileSystem, }) : _fileSystem = fileSystem,
_logger = logger, _logger = logger,
super( super(
@ -124,6 +124,7 @@ abstract class ChromiumDevice extends Device {
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
Map<String, Object?> platformArgs = const <String, Object?>{}, Map<String, Object?> platformArgs = const <String, Object?>{},
bool prebuiltApplication = false, bool prebuiltApplication = false,
bool ipv6 = false,
String? userIdentifier, String? userIdentifier,
}) async { }) async {
// See [ResidentWebRunner.run] in flutter_tools/lib/src/resident_web_runner.dart // See [ResidentWebRunner.run] in flutter_tools/lib/src/resident_web_runner.dart
@ -381,7 +382,7 @@ String parseVersionForWindows(String input) {
/// A special device type to allow serving for arbitrary browsers. /// A special device type to allow serving for arbitrary browsers.
class WebServerDevice extends Device { class WebServerDevice extends Device {
WebServerDevice({ WebServerDevice({
required super.logger, required Logger logger,
}) : _logger = logger, }) : _logger = logger,
super( super(
'web-server', 'web-server',
@ -459,6 +460,7 @@ class WebServerDevice extends Device {
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
Map<String, Object?> platformArgs = const <String, Object?>{}, Map<String, Object?> platformArgs = const <String, Object?>{},
bool prebuiltApplication = false, bool prebuiltApplication = false,
bool ipv6 = false,
String? userIdentifier, String? userIdentifier,
}) async { }) async {
final String? url = platformArgs['uri'] as String?; final String? url = platformArgs['uri'] as String?;

View File

@ -26,6 +26,7 @@ abstract class WebRunnerFactory {
String? target, String? target,
required bool stayResident, required bool stayResident,
required FlutterProject flutterProject, required FlutterProject flutterProject,
required bool? ipv6,
required DebuggingOptions debuggingOptions, required DebuggingOptions debuggingOptions,
UrlTunneller? urlTunneller, UrlTunneller? urlTunneller,
required Logger logger, required Logger logger,

View File

@ -73,7 +73,7 @@ void main() {
artifacts = Artifacts.test(fileSystem: testFileSystem); artifacts = Artifacts.test(fileSystem: testFileSystem);
stdio = FakeStdio(); stdio = FakeStdio();
terminal = FakeTerminal(); terminal = FakeTerminal();
signals = FakeSignals(); signals = Signals.test();
processInfo = FakeProcessInfo(); processInfo = FakeProcessInfo();
testDeviceManager = TestDeviceManager(logger: logger); testDeviceManager = TestDeviceManager(logger: logger);
}); });
@ -802,13 +802,6 @@ void main() {
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Logger: () => logger, Logger: () => logger,
DeviceManager: () => testDeviceManager, DeviceManager: () => testDeviceManager,
MDnsVmServiceDiscovery: () => MDnsVmServiceDiscovery(
mdnsClient: FakeMDnsClient(<PtrResourceRecord>[], <String, List<SrvResourceRecord>>{}),
preliminaryMDnsClient: FakeMDnsClient(<PtrResourceRecord>[], <String, List<SrvResourceRecord>>{}),
logger: logger,
flutterUsage: TestUsage(),
analytics: const NoOpAnalytics(),
),
}); });
testUsingContext('exits when vm-service-port is specified and debug-port is not', () async { testUsingContext('exits when vm-service-port is specified and debug-port is not', () async {
@ -1401,14 +1394,11 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService
@override @override
Future<void> startDartDevelopmentService( Future<void> startDartDevelopmentService(
Uri vmServiceUri, { Uri vmServiceUri, {
int? ddsPort, required Logger logger,
FlutterDevice? device, int? hostPort,
bool? ipv6, bool? ipv6,
bool? disableServiceAuthCodes, bool? disableServiceAuthCodes,
bool enableDevTools = false,
bool cacheStartupProfile = false, bool cacheStartupProfile = false,
String? google3WorkspaceRoot,
Uri? devToolsServerAddress,
}) async {} }) async {}
@override @override

View File

@ -695,22 +695,17 @@ void main() {
'deviceId': 'device', 'deviceId': 'device',
'disableServiceAuthCodes': false, 'disableServiceAuthCodes': false,
'vmServiceUri': 'http://fake_uri/auth_code', 'vmServiceUri': 'http://fake_uri/auth_code',
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// 'enableDevTools': true,
}, },
})); }));
final Stream<DaemonMessage> broadcastOutput = daemonStreams.outputs.stream.asBroadcastStream(); final Stream<DaemonMessage> broadcastOutput = daemonStreams.outputs.stream.asBroadcastStream();
final DaemonMessage startResponse = await broadcastOutput.firstWhere(_notEvent); final DaemonMessage startResponse = await broadcastOutput.firstWhere(_notEvent);
expect(startResponse.data['id'], 0); expect(startResponse.data['id'], 0);
expect(startResponse.data['error'], isNull); expect(startResponse.data['error'], isNull);
final Map<String, Object?>? result = startResponse.data['result'] as Map<String, Object?>?; final String? ddsUri = startResponse.data['result'] as String?;
final String? ddsUri = result!['ddsUri'] as String?;
expect(ddsUri, fakeDdsUri.toString()); expect(ddsUri, fakeDdsUri.toString());
expect(device.dds.startCalled, true); expect(device.dds.startCalled, true);
expect(device.dds.startDisableServiceAuthCodes, false); expect(device.dds.startDisableServiceAuthCodes, false);
expect(device.dds.startVMServiceUri, Uri.parse('http://fake_uri/auth_code')); expect(device.dds.startVMServiceUri, Uri.parse('http://fake_uri/auth_code'));
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// expect(device.dds.enableDevTools, true);
// dds.done event should be sent to the client. // dds.done event should be sent to the client.
ddsDoneCompleter.complete(); ddsDoneCompleter.complete();
@ -1241,8 +1236,6 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService
bool? startDisableServiceAuthCodes; bool? startDisableServiceAuthCodes;
bool shutdownCalled = false; bool shutdownCalled = false;
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// bool enableDevTools = false;
@override @override
late Future<void> done; late Future<void> done;
@ -1250,32 +1243,18 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService
@override @override
Uri? uri; Uri? uri;
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
/*
@override
Uri? devToolsUri;
@override
Uri? dtdUri;
*/
@override @override
Future<void> startDartDevelopmentService( Future<void> startDartDevelopmentService(
Uri vmServiceUri, { Uri vmServiceUri, {
int? ddsPort, required Logger logger,
FlutterDevice? device, int? hostPort,
bool? ipv6, bool? ipv6,
bool? disableServiceAuthCodes, bool? disableServiceAuthCodes,
bool enableDevTools = false,
bool cacheStartupProfile = false, bool cacheStartupProfile = false,
String? google3WorkspaceRoot,
Uri? devToolsServerAddress,
}) async { }) async {
startCalled = true; startCalled = true;
startVMServiceUri = vmServiceUri; startVMServiceUri = vmServiceUri;
startDisableServiceAuthCodes = disableServiceAuthCodes; startDisableServiceAuthCodes = disableServiceAuthCodes;
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// this.enableDevTools = enableDevTools;
} }
@override @override

View File

@ -640,7 +640,7 @@ class NeverEndingDriverService extends Fake implements DriverService {
final void Function() callback; final void Function() callback;
@override @override
Future<void> reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions) async { } Future<void> reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions, bool ipv6) async { }
@override @override
Future<int> startTest( Future<int> startTest(
@ -670,7 +670,7 @@ class FailingFakeFlutterDriverFactory extends Fake implements FlutterDriverFacto
class FailingFakeDriverService extends Fake implements DriverService { class FailingFakeDriverService extends Fake implements DriverService {
@override @override
Future<void> reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions) async { } Future<void> reuseApplication(Uri vmServiceUri, Device device, DebuggingOptions debuggingOptions, bool ipv6) async { }
@override @override
Future<int> startTest( Future<int> startTest(

View File

@ -1544,13 +1544,16 @@ class CapturingAppDomain extends AppDomain {
String? projectRootPath, String? projectRootPath,
String? packagesFilePath, String? packagesFilePath,
String? dillOutputPath, String? dillOutputPath,
bool ipv6 = false,
String? isolateFilter, String? isolateFilter,
bool machine = true, bool machine = true,
String? userIdentifier, String? userIdentifier,
required HotRunnerNativeAssetsBuilder? nativeAssetsBuilder, bool enableDevTools = true,
String? flavor,
HotRunnerNativeAssetsBuilder? nativeAssetsBuilder,
}) async { }) async {
this.userIdentifier = userIdentifier; this.userIdentifier = userIdentifier;
enableDevTools = options.enableDevTools; this.enableDevTools = enableDevTools;
throwToolExit(''); throwToolExit('');
} }
} }

View File

@ -213,9 +213,13 @@ class TestFlutterDevice extends FlutterDevice {
GetSkSLMethod? getSkSLMethod, GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject, FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
required DebuggingOptions debuggingOptions, bool enableDds = true,
bool cacheStartupProfile = false,
bool disableServiceAuthCodes = false,
int? hostVmServicePort, int? hostVmServicePort,
required bool allowExistingDdsInstance, int? ddsPort,
bool? ipv6 = false,
bool allowExistingDdsInstance = false,
}) async { }) async {
throw exception; throw exception;
} }

View File

@ -932,13 +932,13 @@ void main() {
testWithoutContext('Get launch arguments for physical device with iPv6 network connection', () { testWithoutContext('Get launch arguments for physical device with iPv6 network connection', () {
final DebuggingOptions original = DebuggingOptions.enabled( final DebuggingOptions original = DebuggingOptions.enabled(
BuildInfo.debug, BuildInfo.debug,
ipv6: true,
); );
final List<String> launchArguments = original.getIOSLaunchArguments( final List<String> launchArguments = original.getIOSLaunchArguments(
EnvironmentType.physical, EnvironmentType.physical,
null, null,
<String, Object?>{}, <String, Object?>{},
ipv6: true,
interfaceType: DeviceConnectionInterface.wireless, interfaceType: DeviceConnectionInterface.wireless,
); );

View File

@ -33,8 +33,6 @@ void main() {
'Artifact.engineDartBinary', 'Artifact.engineDartBinary',
'devtools', 'devtools',
'--no-launch-browser', '--no-launch-browser',
// TODO(bkonyi): does this need to be removed?
// '--print-dtd',
], ],
stdout: 'Serving DevTools at http://127.0.0.1:9100.\n', stdout: 'Serving DevTools at http://127.0.0.1:9100.\n',
completer: completer, completer: completer,
@ -51,7 +49,6 @@ void main() {
expect(launcher.printDtdUri, false); 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 { testWithoutContext('DevtoolsLauncher saves the Dart Tooling Daemon uri', () async {
final (BufferLogger logger, Artifacts artifacts) = getTestState(); final (BufferLogger logger, Artifacts artifacts) = getTestState();
final Completer<void> completer = Completer<void>(); final Completer<void> completer = Completer<void>();
@ -98,7 +95,6 @@ Serving DevTools at http://127.0.0.1:9100.
'Artifact.engineDartBinary', 'Artifact.engineDartBinary',
'devtools', 'devtools',
'--no-launch-browser', '--no-launch-browser',
// '--print-dtd',
], ],
stdout: 'Serving DevTools at http://127.0.0.1:9100.\n', stdout: 'Serving DevTools at http://127.0.0.1:9100.\n',
completer: completer, completer: completer,
@ -124,7 +120,6 @@ Serving DevTools at http://127.0.0.1:9100.
'Artifact.engineDartBinary', 'Artifact.engineDartBinary',
'devtools', 'devtools',
'--no-launch-browser', '--no-launch-browser',
// '--print-dtd',
'--vm-uri=localhost:8181/abcdefg', '--vm-uri=localhost:8181/abcdefg',
'--profile-memory=foo', '--profile-memory=foo',
], ],
@ -156,7 +151,6 @@ Serving DevTools at http://127.0.0.1:9100.
'Artifact.engineDartBinary', 'Artifact.engineDartBinary',
'devtools', 'devtools',
'--no-launch-browser', '--no-launch-browser',
// '--print-dtd',
'--vm-uri=http://127.0.0.1:1234/abcdefg', '--vm-uri=http://127.0.0.1:1234/abcdefg',
], ],
exception: ProcessException('pub', <String>[]), exception: ProcessException('pub', <String>[]),
@ -182,7 +176,6 @@ Serving DevTools at http://127.0.0.1:9100.
'Artifact.engineDartBinary', 'Artifact.engineDartBinary',
'devtools', 'devtools',
'--no-launch-browser', '--no-launch-browser',
// '--print-dtd',
], ],
stdout: 'Serving DevTools at http://127.0.0.1:9100.\n', stdout: 'Serving DevTools at http://127.0.0.1:9100.\n',
completer: completer, completer: completer,

View File

@ -93,7 +93,7 @@ void main() {
final Device device = FakeDevice(LaunchResult.failed()); final Device device = FakeDevice(LaunchResult.failed());
expect( expect(
() => driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)), () => driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true),
throwsToolExit(message: 'Application failed to start. Will not run test. Quitting.'), throwsToolExit(message: 'Application failed to start. Will not run test. Quitting.'),
); );
}); });
@ -118,7 +118,7 @@ void main() {
))..failOnce = true; ))..failOnce = true;
await expectLater( await expectLater(
() async => driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)), () async => driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true),
returnsNormally, returnsNormally,
); );
}); });
@ -142,7 +142,7 @@ void main() {
vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'),
)); ));
await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)); await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true);
final int testResult = await driverService.startTest( final int testResult = await driverService.startTest(
'foo.test', 'foo.test',
<String>['--enable-experiment=non-nullable'], <String>['--enable-experiment=non-nullable'],
@ -173,7 +173,7 @@ void main() {
vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'),
)); ));
await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)); await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true);
final int testResult = await driverService.startTest( final int testResult = await driverService.startTest(
'foo.test', 'foo.test',
<String>['--enable-experiment=non-nullable'], <String>['--enable-experiment=non-nullable'],
@ -205,7 +205,7 @@ void main() {
vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'),
)); ));
await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)); await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true);
final int testResult = await driverService.startTest( final int testResult = await driverService.startTest(
'foo.test', 'foo.test',
<String>['--enable-experiment=non-nullable'], <String>['--enable-experiment=non-nullable'],
@ -237,7 +237,7 @@ void main() {
final FakeDartDevelopmentService dds = device.dds as FakeDartDevelopmentService; final FakeDartDevelopmentService dds = device.dds as FakeDartDevelopmentService;
expect(dds.started, false); expect(dds.started, false);
await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, enableDds: false, ipv6: true)); await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, enableDds: false), true);
expect(dds.started, false); expect(dds.started, false);
final int testResult = await driverService.startTest( final int testResult = await driverService.startTest(
@ -261,7 +261,7 @@ void main() {
vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'),
)); ));
await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)); await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true);
await driverService.stop(); await driverService.stop();
expect(device.didStopApp, true); expect(device.didStopApp, true);
@ -293,7 +293,7 @@ void main() {
vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), vmServiceUri: Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'),
)); ));
await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)); await driverService.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true);
await driverService.stop(writeSkslOnExit: fileSystem.file('out.json')); await driverService.stop(writeSkslOnExit: fileSystem.file('out.json'));
expect(device.didStopApp, true); expect(device.didStopApp, true);
@ -327,6 +327,7 @@ void main() {
Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'),
device, device,
DebuggingOptions.enabled(BuildInfo.debug), DebuggingOptions.enabled(BuildInfo.debug),
false,
); );
await driverService.stop(); await driverService.stop();
}); });
@ -350,6 +351,7 @@ void main() {
Uri.parse('ws://127.0.0.1:63426/1UasC_ihpXY=/ws/'), Uri.parse('ws://127.0.0.1:63426/1UasC_ihpXY=/ws/'),
device, device,
DebuggingOptions.enabled(BuildInfo.debug), DebuggingOptions.enabled(BuildInfo.debug),
false,
); );
await driverService.stop(); await driverService.stop();
}); });
@ -373,6 +375,7 @@ void main() {
Uri.parse('ws://127.0.0.1:63426/1UasC_ihpXY=/ws'), Uri.parse('ws://127.0.0.1:63426/1UasC_ihpXY=/ws'),
device, device,
DebuggingOptions.enabled(BuildInfo.debug), DebuggingOptions.enabled(BuildInfo.debug),
false,
); );
await driverService.stop(); await driverService.stop();
}); });
@ -396,6 +399,7 @@ void main() {
Uri.parse('ws://127.0.0.1:63426/wsasC_ihpXY=/ws'), Uri.parse('ws://127.0.0.1:63426/wsasC_ihpXY=/ws'),
device, device,
DebuggingOptions.enabled(BuildInfo.debug), DebuggingOptions.enabled(BuildInfo.debug),
false,
); );
await driverService.stop(); await driverService.stop();
}); });
@ -412,6 +416,7 @@ void main() {
Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'), Uri.parse('http://127.0.0.1:63426/1UasC_ihpXY=/'),
device, device,
DebuggingOptions.enabled(BuildInfo.debug), DebuggingOptions.enabled(BuildInfo.debug),
false,
); );
await driverService.stop(); await driverService.stop();
}); });
@ -535,9 +540,7 @@ class FakeDevice extends Fake implements Device {
} }
} }
class FakeDartDevelopmentService extends Fake class FakeDartDevelopmentService extends Fake implements DartDevelopmentService {
with DartDevelopmentServiceLocalOperationsMixin
implements DartDevelopmentService {
bool started = false; bool started = false;
bool disposed = false; bool disposed = false;
@ -547,14 +550,11 @@ class FakeDartDevelopmentService extends Fake
@override @override
Future<void> startDartDevelopmentService( Future<void> startDartDevelopmentService(
Uri vmServiceUri, { Uri vmServiceUri, {
FlutterDevice? device, required Logger logger,
int? ddsPort, int? hostPort,
bool? ipv6, bool? ipv6,
bool? disableServiceAuthCodes, bool? disableServiceAuthCodes,
bool enableDevTools = false,
bool cacheStartupProfile = false, bool cacheStartupProfile = false,
String? google3WorkspaceRoot,
Uri? devToolsServerAddress,
}) async { }) async {
started = true; started = true;
} }

View File

@ -248,7 +248,7 @@ void main() {
testUsingContext('WebDriverService starts and stops an app', () async { testUsingContext('WebDriverService starts and stops an app', () async {
final WebDriverService service = setUpDriverService(); final WebDriverService service = setUpDriverService();
final FakeDevice device = FakeDevice(); final FakeDevice device = FakeDevice();
await service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)); await service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true);
await service.stop(); await service.stop();
expect(FakeResidentRunner.instance.callLog, <String>[ expect(FakeResidentRunner.instance.callLog, <String>[
'run', 'run',
@ -263,7 +263,7 @@ void main() {
final WebDriverService service = setUpDriverService(); final WebDriverService service = setUpDriverService();
final FakeDevice device = FakeDevice(); final FakeDevice device = FakeDevice();
const String testUrl = 'http://localhost:1234/test'; const String testUrl = 'http://localhost:1234/test';
await service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, webLaunchUrl: testUrl, ipv6: true)); await service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, webLaunchUrl: testUrl), true);
await service.stop(); await service.stop();
expect(service.webUri, Uri.parse(testUrl)); expect(service.webUri, Uri.parse(testUrl));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -275,7 +275,7 @@ void main() {
final FakeDevice device = FakeDevice(); final FakeDevice device = FakeDevice();
const String invalidTestUrl = '::INVALID_URL::'; const String invalidTestUrl = '::INVALID_URL::';
await expectLater( await expectLater(
service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, webLaunchUrl: invalidTestUrl, ipv6: true)), service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, webLaunchUrl: invalidTestUrl), true),
throwsA(isA<FormatException>()), throwsA(isA<FormatException>()),
); );
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -286,7 +286,7 @@ void main() {
final WebDriverService service = setUpDriverService(); final WebDriverService service = setUpDriverService();
final Device device = FakeDevice(); final Device device = FakeDevice();
await expectLater( await expectLater(
service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile, ipv6: true)), service.start(BuildInfo.profile, device, DebuggingOptions.enabled(BuildInfo.profile), true),
throwsA('This is a test error'), throwsA('This is a test error'),
); );
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{

View File

@ -102,6 +102,7 @@ void main() {
platformPluginRegistration: (FlutterPlatform platform) { platformPluginRegistration: (FlutterPlatform platform) {
capturedPlatform = platform; capturedPlatform = platform;
}, },
uriConverter: (String input) => '$input/test',
); );
expect(identical(capturedPlatform, flutterPlatform), equals(true)); expect(identical(capturedPlatform, flutterPlatform), equals(true));
@ -118,6 +119,7 @@ void main() {
expect(flutterPlatform.updateGoldens, equals(true)); expect(flutterPlatform.updateGoldens, equals(true));
expect(flutterPlatform.testAssetDirectory, '/build/test'); expect(flutterPlatform.testAssetDirectory, '/build/test');
expect(flutterPlatform.icudtlPath, equals('ghi')); expect(flutterPlatform.icudtlPath, equals('ghi'));
expect(flutterPlatform.uriConverter?.call('hello'), 'hello/test');
}); });
}); });

View File

@ -4,8 +4,8 @@
import 'dart:async'; import 'dart:async';
import 'package:dds/dds.dart';
import 'package:file/memory.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/file_system.dart';
import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
@ -48,6 +48,7 @@ void main() {
processManager: processManager, processManager: processManager,
enableVmService: enableVmService, enableVmService: enableVmService,
dartEntrypointArgs: dartEntrypointArgs, dartEntrypointArgs: dartEntrypointArgs,
uriConverter: (String input) => '$input/converted',
enableImpeller: enableImpeller, enableImpeller: enableImpeller,
); );
@ -197,7 +198,6 @@ void main() {
}); });
group('DDS', () { group('DDS', () {
late DDSLauncherCallback originalDdsLauncher;
setUp(() { setUp(() {
processManager = FakeProcessManager.list(<FakeCommand>[ processManager = FakeProcessManager.list(<FakeCommand>[
const FakeCommand( const FakeCommand(
@ -221,30 +221,26 @@ void main() {
), ),
]); ]);
device = createDevice(enableVmService: true); device = createDevice(enableVmService: true);
originalDdsLauncher = ddsLauncherCallback;
ddsLauncherCallback = (Uri remoteVmServiceUri, {
required bool enableAuthCodes,
required bool ipv6,
required bool enableDevTools,
required List<String> 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 { testUsingContext('skips setting VM Service port and uses the input port for DDS instead', () async {
await device.start('example.dill'); await device.start('example.dill');
await device.vmServiceUri; await device.vmServiceUri;
final Uri? uri = await (device as TestFlutterTesterDevice).vmServiceUri; final Uri uri = await (device as TestFlutterTesterDevice).ddsServiceUriFuture();
expect(uri!.port, 1234); 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');
}); });
}); });
} }
@ -259,6 +255,7 @@ class TestFlutterTesterDevice extends FlutterTesterTestDevice {
required super.processManager, required super.processManager,
required super.enableVmService, required super.enableVmService,
required List<String> dartEntrypointArgs, required List<String> dartEntrypointArgs,
required UriConverter uriConverter,
required bool enableImpeller, required bool enableImpeller,
}) : super( }) : super(
id: 999, id: 999,
@ -282,7 +279,27 @@ class TestFlutterTesterDevice extends FlutterTesterTestDevice {
icudtlPath: null, icudtlPath: null,
compileExpression: null, compileExpression: null,
fontConfigManager: FontConfigManager(), fontConfigManager: FontConfigManager(),
uriConverter: uriConverter,
); );
late DartDevelopmentService dds;
final Completer<Uri> _ddsServiceUriCompleter = Completer<Uri>();
Future<Uri> ddsServiceUriFuture() => _ddsServiceUriCompleter.future;
@override
Future<DartDevelopmentService> 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 @override
Future<FlutterVmService> connectToVmServiceImpl( Future<FlutterVmService> connectToVmServiceImpl(
@ -302,6 +319,18 @@ class TestFlutterTesterDevice extends FlutterTesterTestDevice {
Future<StreamChannel<String>> get remoteChannel async => StreamChannelController<String>().foreign; Future<StreamChannel<String>> get remoteChannel async => StreamChannelController<String>().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 { class FakeHttpServer extends Fake implements HttpServer {
@override @override
int get port => 0; int get port => 0;

View File

@ -9,7 +9,6 @@ import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart'; import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.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/os.dart';
import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_info.dart';
@ -39,7 +38,6 @@ void main() {
late FakeProcessManager fakeSuccessfulProcessManager; late FakeProcessManager fakeSuccessfulProcessManager;
late FakeProcessManager fakeFailedProcessManagerForHostAddress; late FakeProcessManager fakeFailedProcessManagerForHostAddress;
late File sshConfig; late File sshConfig;
final Logger logger = FakeLogger();
setUp(() { setUp(() {
memoryFileSystem = MemoryFileSystem.test(); memoryFileSystem = MemoryFileSystem.test();
@ -116,7 +114,7 @@ void main() {
required BuildMode mode, required BuildMode mode,
}) async { }) async {
const String appName = 'app_name'; const String appName = 'app_name';
final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123', logger: logger); final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123');
globals.fs.directory('fuchsia').createSync(recursive: true); globals.fs.directory('fuchsia').createSync(recursive: true);
final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync(); final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync();
pubspecFile.writeAsStringSync('name: $appName'); pubspecFile.writeAsStringSync('name: $appName');
@ -188,7 +186,7 @@ void main() {
'start and stop prebuilt in release mode fails without session', 'start and stop prebuilt in release mode fails without session',
() async { () async {
const String appName = 'app_name'; const String appName = 'app_name';
final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123', logger: logger); final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123');
globals.fs.directory('fuchsia').createSync(recursive: true); globals.fs.directory('fuchsia').createSync(recursive: true);
final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync(); final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync();
pubspecFile.writeAsStringSync('name: $appName'); pubspecFile.writeAsStringSync('name: $appName');
@ -218,7 +216,7 @@ void main() {
testUsingContext('start and stop prebuilt in release mode with session', testUsingContext('start and stop prebuilt in release mode with session',
() async { () async {
const String appName = 'app_name'; const String appName = 'app_name';
final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123', logger: logger); final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123');
globals.fs.directory('fuchsia').createSync(recursive: true); globals.fs.directory('fuchsia').createSync(recursive: true);
final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync(); final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync();
pubspecFile.writeAsStringSync('name: $appName'); pubspecFile.writeAsStringSync('name: $appName');
@ -411,7 +409,7 @@ void main() {
}); });
testUsingContext('fail when cant get host address', () async { testUsingContext('fail when cant get host address', () async {
expect(() async => FuchsiaDeviceWithFakeDiscovery('123', logger: logger).hostAddress, expect(() async => FuchsiaDeviceWithFakeDiscovery('123').hostAddress,
throwsToolExit(message: 'Failed to get local address, aborting.')); throwsToolExit(message: 'Failed to get local address, aborting.'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Artifacts: () => artifacts, Artifacts: () => artifacts,
@ -481,7 +479,7 @@ Process _createFakeProcess({
} }
class FuchsiaDeviceWithFakeDiscovery extends FuchsiaDevice { class FuchsiaDeviceWithFakeDiscovery extends FuchsiaDevice {
FuchsiaDeviceWithFakeDiscovery(super.id, {super.name = '', required super.logger}); FuchsiaDeviceWithFakeDiscovery(super.id, {super.name = ''});
@override @override
FuchsiaIsolateDiscoveryProtocol getIsolateDiscoveryProtocol( FuchsiaIsolateDiscoveryProtocol getIsolateDiscoveryProtocol(

View File

@ -26,7 +26,6 @@ import 'package:flutter_tools/src/fuchsia/fuchsia_sdk.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_workflow.dart'; import 'package:flutter_tools/src/fuchsia/fuchsia_workflow.dart';
import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/resident_runner.dart';
import 'package:flutter_tools/src/vmservice.dart'; import 'package:flutter_tools/src/vmservice.dart';
import 'package:test/fake.dart'; import 'package:test/fake.dart';
import 'package:vm_service/vm_service.dart' as vm_service; import 'package:vm_service/vm_service.dart' as vm_service;
@ -59,7 +58,6 @@ void main() {
late MemoryFileSystem memoryFileSystem; late MemoryFileSystem memoryFileSystem;
late File sshConfig; late File sshConfig;
late FakeProcessManager processManager; late FakeProcessManager processManager;
final Logger logger = FakeLogger();
setUp(() { setUp(() {
memoryFileSystem = MemoryFileSystem.test(); memoryFileSystem = MemoryFileSystem.test();
@ -70,7 +68,7 @@ void main() {
testWithoutContext('stores the requested id and name', () { testWithoutContext('stores the requested id and name', () {
const String deviceId = 'e80::0000:a00a:f00f:2002/3'; const String deviceId = 'e80::0000:a00a:f00f:2002/3';
const String name = 'halfbaked'; const String name = 'halfbaked';
final FuchsiaDevice device = FuchsiaDevice(deviceId, name: name, logger: logger); final FuchsiaDevice device = FuchsiaDevice(deviceId, name: name);
expect(device.id, deviceId); expect(device.id, deviceId);
expect(device.name, name); expect(device.name, name);
@ -79,7 +77,7 @@ void main() {
testWithoutContext('supports all runtime modes besides jitRelease', () { testWithoutContext('supports all runtime modes besides jitRelease', () {
const String deviceId = 'e80::0000:a00a:f00f:2002/3'; const String deviceId = 'e80::0000:a00a:f00f:2002/3';
const String name = 'halfbaked'; const String name = 'halfbaked';
final FuchsiaDevice device = FuchsiaDevice(deviceId, name: name, logger: logger); final FuchsiaDevice device = FuchsiaDevice(deviceId, name: name);
expect(device.supportsRuntimeMode(BuildMode.debug), true); expect(device.supportsRuntimeMode(BuildMode.debug), true);
expect(device.supportsRuntimeMode(BuildMode.profile), true); expect(device.supportsRuntimeMode(BuildMode.profile), true);
@ -159,7 +157,7 @@ void main() {
testUsingContext('disposing device disposes the portForwarder', () async { testUsingContext('disposing device disposes the portForwarder', () async {
final FakePortForwarder portForwarder = FakePortForwarder(); final FakePortForwarder portForwarder = FakePortForwarder();
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
device.portForwarder = portForwarder; device.portForwarder = portForwarder;
await device.dispose(); await device.dispose();
@ -167,7 +165,7 @@ void main() {
}); });
testWithoutContext('default capabilities', () async { testWithoutContext('default capabilities', () async {
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
final FlutterProject project = final FlutterProject project =
FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory); FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory);
memoryFileSystem.directory('fuchsia').createSync(recursive: true); memoryFileSystem.directory('fuchsia').createSync(recursive: true);
@ -180,13 +178,13 @@ void main() {
}); });
test('is ephemeral', () { test('is ephemeral', () {
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(device.ephemeral, true); expect(device.ephemeral, true);
}); });
testWithoutContext('supported for project', () async { testWithoutContext('supported for project', () async {
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
final FlutterProject project = final FlutterProject project =
FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory); FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory);
memoryFileSystem.directory('fuchsia').createSync(recursive: true); memoryFileSystem.directory('fuchsia').createSync(recursive: true);
@ -196,7 +194,7 @@ void main() {
}); });
testWithoutContext('not supported for project', () async { testWithoutContext('not supported for project', () async {
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
final FlutterProject project = final FlutterProject project =
FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory); FlutterProject.fromDirectoryTest(memoryFileSystem.currentDirectory);
memoryFileSystem.file('pubspec.yaml').createSync(); memoryFileSystem.file('pubspec.yaml').createSync();
@ -206,7 +204,7 @@ void main() {
testUsingContext('targetPlatform does not throw when sshConfig is missing', testUsingContext('targetPlatform does not throw when sshConfig is missing',
() async { () async {
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.targetPlatform, TargetPlatform.fuchsia_arm64); expect(await device.targetPlatform, TargetPlatform.fuchsia_arm64);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -221,7 +219,7 @@ void main() {
stdout: 'aarch64', stdout: 'aarch64',
)); ));
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.targetPlatform, TargetPlatform.fuchsia_arm64); expect(await device.targetPlatform, TargetPlatform.fuchsia_arm64);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
@ -235,7 +233,7 @@ void main() {
stdout: 'x86_64', stdout: 'x86_64',
)); ));
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.targetPlatform, TargetPlatform.fuchsia_x64); expect(await device.targetPlatform, TargetPlatform.fuchsia_x64);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
@ -256,7 +254,7 @@ void main() {
'fe80::8c6c:2fff:fe3d:c5e1%ethp0003 50666 fe80::5054:ff:fe63:5e7a%ethp0003 22', 'fe80::8c6c:2fff:fe3d:c5e1%ethp0003 50666 fe80::5054:ff:fe63:5e7a%ethp0003 22',
)); ));
final FuchsiaDevice device = FuchsiaDevice('id', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('id', name: 'device');
expect(await device.hostAddress, 'fe80::8c6c:2fff:fe3d:c5e1%25ethp0003'); expect(await device.hostAddress, 'fe80::8c6c:2fff:fe3d:c5e1%25ethp0003');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
@ -277,7 +275,7 @@ void main() {
exitCode: 1, exitCode: 1,
)); ));
final FuchsiaDevice device = FuchsiaDevice('id', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('id', name: 'device');
await expectLater(() => device.hostAddress, throwsToolExit()); await expectLater(() => device.hostAddress, throwsToolExit());
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
@ -297,7 +295,7 @@ void main() {
], ],
)); ));
final FuchsiaDevice device = FuchsiaDevice('id', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('id', name: 'device');
expect(() async => device.hostAddress, throwsToolExit()); expect(() async => device.hostAddress, throwsToolExit());
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig), FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
@ -309,7 +307,6 @@ void main() {
group('displays friendly error when', () { group('displays friendly error when', () {
late File artifactFile; late File artifactFile;
late FakeProcessManager processManager; late FakeProcessManager processManager;
final Logger logger = FakeLogger();
setUp(() { setUp(() {
processManager = FakeProcessManager.empty(); processManager = FakeProcessManager.empty();
@ -326,7 +323,7 @@ void main() {
'find /hub -name vmservice-port' 'find /hub -name vmservice-port'
], ],
)); ));
final FuchsiaDevice device = FuchsiaDevice('id', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('id', name: 'device');
await expectLater( await expectLater(
device.servicePorts, device.servicePorts,
@ -355,7 +352,6 @@ void main() {
late FakeProcessManager processManager; late FakeProcessManager processManager;
late File ffx; late File ffx;
late File sshConfig; late File sshConfig;
final Logger logger = FakeLogger();
setUp(() { setUp(() {
processManager = FakeProcessManager.empty(); processManager = FakeProcessManager.empty();
@ -378,7 +374,7 @@ void main() {
stdout: exampleUtcLogs, stdout: exampleUtcLogs,
completer: lock, completer: lock,
)); ));
final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');
final DeviceLogReader reader = final DeviceLogReader reader =
device.getLogReader(app: FuchsiaModulePackage(name: 'example_app')); device.getLogReader(app: FuchsiaModulePackage(name: 'example_app'));
final List<String> logLines = <String>[]; final List<String> logLines = <String>[];
@ -415,7 +411,7 @@ void main() {
stdout: exampleUtcLogs, stdout: exampleUtcLogs,
completer: lock, completer: lock,
)); ));
final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');
final DeviceLogReader reader = final DeviceLogReader reader =
device.getLogReader(app: FuchsiaModulePackage(name: 'example_app')); device.getLogReader(app: FuchsiaModulePackage(name: 'example_app'));
final List<String> logLines = <String>[]; final List<String> logLines = <String>[];
@ -450,7 +446,7 @@ void main() {
stdout: exampleUtcLogs, stdout: exampleUtcLogs,
completer: lock, completer: lock,
)); ));
final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');
final DeviceLogReader reader = device.getLogReader(); final DeviceLogReader reader = device.getLogReader();
final List<String> logLines = <String>[]; final List<String> logLines = <String>[];
reader.logLines.listen((String line) { reader.logLines.listen((String line) {
@ -479,14 +475,13 @@ void main() {
group('screenshot', () { group('screenshot', () {
late FakeProcessManager processManager; late FakeProcessManager processManager;
final Logger logger = FakeLogger();
setUp(() { setUp(() {
processManager = FakeProcessManager.empty(); processManager = FakeProcessManager.empty();
}); });
testUsingContext('is supported on posix platforms', () { testUsingContext('is supported on posix platforms', () {
final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');
expect(device.supportsScreenshot, true); expect(device.supportsScreenshot, true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => FakePlatform(), Platform: () => FakePlatform(),
@ -494,7 +489,7 @@ void main() {
}); });
testUsingContext('is not supported on Windows', () { testUsingContext('is not supported on Windows', () {
final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');
expect(device.supportsScreenshot, false); expect(device.supportsScreenshot, false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -505,7 +500,7 @@ void main() {
}); });
test("takeScreenshot throws if file isn't .ppm", () async { test("takeScreenshot throws if file isn't .ppm", () async {
final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');
await expectLater( await expectLater(
() => device.takeScreenshot(globals.fs.file('file.invalid')), () => device.takeScreenshot(globals.fs.file('file.invalid')),
throwsA(isA<Exception>().having( throwsA(isA<Exception>().having(
@ -523,7 +518,7 @@ void main() {
'0.0.0.0', '0.0.0.0',
'screencap > /tmp/screenshot.ppm', 'screencap > /tmp/screenshot.ppm',
], exitCode: 1, stderr: '<error-message>')); ], exitCode: 1, stderr: '<error-message>'));
final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester', logger: logger); final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester');
await expectLater( await expectLater(
() => device.takeScreenshot(globals.fs.file('file.ppm')), () => device.takeScreenshot(globals.fs.file('file.ppm')),
@ -545,7 +540,7 @@ void main() {
}); });
testUsingContext('takeScreenshot throws if scp failed', () async { testUsingContext('takeScreenshot throws if scp failed', () async {
final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester', logger: logger); final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester');
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
'ssh', 'ssh',
@ -598,7 +593,7 @@ void main() {
testUsingContext( testUsingContext(
"takeScreenshot prints error if can't delete file from device", "takeScreenshot prints error if can't delete file from device",
() async { () async {
final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester', logger: logger); final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester');
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
'ssh', 'ssh',
@ -647,7 +642,7 @@ void main() {
}, testOn: 'posix'); }, testOn: 'posix');
testUsingContext('takeScreenshot returns', () async { testUsingContext('takeScreenshot returns', () async {
final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester', logger: logger); final FuchsiaDevice device = FuchsiaDevice('0.0.0.0', name: 'tester');
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
'ssh', 'ssh',
@ -693,7 +688,6 @@ void main() {
group('portForwarder', () { group('portForwarder', () {
late FakeProcessManager processManager; late FakeProcessManager processManager;
late File sshConfig; late File sshConfig;
final Logger logger = FakeLogger();
setUp(() { setUp(() {
processManager = FakeProcessManager.empty(); processManager = FakeProcessManager.empty();
@ -703,7 +697,7 @@ void main() {
testUsingContext( testUsingContext(
'`unforward` prints stdout and stderr if ssh command failed', () async { '`unforward` prints stdout and stderr if ssh command failed', () async {
final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester', logger: logger); final FuchsiaDevice device = FuchsiaDevice('id', name: 'tester');
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
'ssh', 'ssh',
@ -867,7 +861,6 @@ void main() {
group('sdkNameAndVersion: ', () { group('sdkNameAndVersion: ', () {
late File sshConfig; late File sshConfig;
late FakeProcessManager processManager; late FakeProcessManager processManager;
final Logger logger = FakeLogger();
setUp(() { setUp(() {
sshConfig = MemoryFileSystem.test().file('ssh_config') sshConfig = MemoryFileSystem.test().file('ssh_config')
@ -876,7 +869,7 @@ void main() {
}); });
testUsingContext('does not throw on non-existent ssh config', () async { testUsingContext('does not throw on non-existent ssh config', () async {
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.sdkNameAndVersion, equals('Fuchsia')); expect(await device.sdkNameAndVersion, equals('Fuchsia'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -894,7 +887,7 @@ void main() {
'123', '123',
'cat /pkgfs/packages/build-info/0/data/version' 'cat /pkgfs/packages/build-info/0/data/version'
], stdout: 'version')); ], stdout: 'version'));
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.sdkNameAndVersion, equals('Fuchsia version')); expect(await device.sdkNameAndVersion, equals('Fuchsia version'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -914,7 +907,7 @@ void main() {
], ],
exitCode: 1, exitCode: 1,
)); ));
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.sdkNameAndVersion, equals('Fuchsia')); expect(await device.sdkNameAndVersion, equals('Fuchsia'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -934,7 +927,7 @@ void main() {
'cat /pkgfs/packages/build-info/0/data/version' 'cat /pkgfs/packages/build-info/0/data/version'
], ],
)); ));
final FuchsiaDevice device = FuchsiaDevice('123', name: 'device', logger: logger); final FuchsiaDevice device = FuchsiaDevice('123', name: 'device');
expect(await device.sdkNameAndVersion, equals('Fuchsia')); expect(await device.sdkNameAndVersion, equals('Fuchsia'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -1048,14 +1041,11 @@ class FakeDartDevelopmentService extends Fake
@override @override
Future<void> startDartDevelopmentService( Future<void> startDartDevelopmentService(
Uri vmServiceUri, { Uri vmServiceUri, {
FlutterDevice? device, required Logger logger,
int? ddsPort, int? hostPort,
bool? ipv6, bool? ipv6,
bool? disableServiceAuthCodes, bool? disableServiceAuthCodes,
bool cacheStartupProfile = false, bool cacheStartupProfile = false,
bool enableDevTools = false,
String? google3WorkspaceRoot,
Uri? devToolsServerAddress,
}) async {} }) async {}
@override @override

View File

@ -128,10 +128,6 @@ class FakeFlutterDevice extends Fake implements FlutterDevice {
required PackageConfig packageConfig, required PackageConfig packageConfig,
}) => updateDevFSReportCallback(); }) => updateDevFSReportCallback();
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// @override
// Future<void> handleHotRestart() async {}
@override @override
TargetPlatform? get targetPlatform => device._targetPlatform; TargetPlatform? get targetPlatform => device._targetPlatform;
} }
@ -154,10 +150,12 @@ class TestFlutterDevice extends FlutterDevice {
GetSkSLMethod? getSkSLMethod, GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject, FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
required DebuggingOptions debuggingOptions, bool disableServiceAuthCodes = false,
int? hostVmServicePort, bool enableDds = true,
bool cacheStartupProfile = false,
bool? ipv6 = false, bool? ipv6 = false,
bool enableDevTools = false, int? hostVmServicePort,
int? ddsPort,
bool allowExistingDdsInstance = false, bool allowExistingDdsInstance = false,
}) async { }) async {
throw exception; throw exception;

View File

@ -137,7 +137,8 @@ void main() {
..writeAsStringSync('\n'); ..writeAsStringSync('\n');
final FakeDevice device = FakeDevice(); final FakeDevice device = FakeDevice();
final List<FlutterDevice> devices = <FlutterDevice>[ final List<FlutterDevice> devices = <FlutterDevice>[
FakeFlutterDevice(device), FlutterDevice(device, generator: residentCompiler, buildInfo: BuildInfo.debug, developmentShaderCompiler: const FakeShaderCompiler())
..devFS = FakeDevFs(),
]; ];
final OperationResult result = await HotRunner( final OperationResult result = await HotRunner(
devices, devices,
@ -145,6 +146,7 @@ void main() {
target: 'main.dart', target: 'main.dart',
devtoolsHandler: createNoOpHandler, devtoolsHandler: createNoOpHandler,
analytics: fakeAnalytics, analytics: fakeAnalytics,
).restart(fullRestart: true); ).restart(fullRestart: true);
expect(result.isOk, false); expect(result.isOk, false);
expect(result.message, 'setupHotRestart failed'); expect(result.message, 'setupHotRestart failed');

View File

@ -37,7 +37,6 @@ void main() {
late FakePlatform osx; late FakePlatform osx;
late FileSystemUtils fsUtils; late FileSystemUtils fsUtils;
late MemoryFileSystem fileSystem; late MemoryFileSystem fileSystem;
final Logger logger = FakeLogger();
setUp(() { setUp(() {
osx = FakePlatform( osx = FakePlatform(
@ -63,7 +62,6 @@ void main() {
name: 'iPhone 11', name: 'iPhone 11',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-14-4', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-14-4',
logger: logger,
); );
final DevicePortForwarder portForwarder = simulator.portForwarder; final DevicePortForwarder portForwarder = simulator.portForwarder;
await portForwarder.forward(123); await portForwarder.forward(123);
@ -89,7 +87,6 @@ void main() {
name: 'iPhone 11', name: 'iPhone 11',
simControl: FakeSimControl(), simControl: FakeSimControl(),
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-14-4', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-14-4',
logger: logger,
); );
expect(simulator.supportsRuntimeMode(BuildMode.debug), true); expect(simulator.supportsRuntimeMode(BuildMode.debug), true);
@ -116,7 +113,6 @@ void main() {
name: 'iPhone 11', name: 'iPhone 11',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-14-4', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-14-4',
logger: logger,
); );
expect(simulator.logFilePath, '/foo/bar/Library/Logs/CoreSimulator/123/system.log'); expect(simulator.logFilePath, '/foo/bar/Library/Logs/CoreSimulator/123/system.log');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -134,7 +130,6 @@ void main() {
name: 'iPhone 11', name: 'iPhone 11',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-14-4', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-14-4',
logger: logger,
); );
expect(simulator.logFilePath, '/baz/qux/456/system.log'); expect(simulator.logFilePath, '/baz/qux/456/system.log');
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -159,7 +154,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
simControl: simControl, simControl: simControl,
logger: logger,
); );
expect(await device.sdkMajorVersion, 11); expect(await device.sdkMajorVersion, 11);
@ -171,7 +165,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.2', simulatorCategory: 'iOS 11.2',
simControl: simControl, simControl: simControl,
logger: logger,
); );
expect(await device.sdkMajorVersion, 11); expect(await device.sdkMajorVersion, 11);
@ -183,7 +176,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.2', simulatorCategory: 'iOS 11.2',
simControl: simControl, simControl: simControl,
logger: logger,
); );
expect(device.category, Category.mobile); expect(device.category, Category.mobile);
@ -203,7 +195,6 @@ void main() {
name: 'Apple TV', name: 'Apple TV',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.tvOS-14-5', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.tvOS-14-5',
logger: logger,
); );
expect(simulator.isSupported(), false); expect(simulator.isSupported(), false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -218,7 +209,6 @@ void main() {
name: 'Apple Watch', name: 'Apple Watch',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.watchOS-8-0', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.watchOS-8-0',
logger: logger,
).isSupported(), false); ).isSupported(), false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
@ -232,7 +222,6 @@ void main() {
name: 'iPad 2', name: 'iPad 2',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
logger: logger,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
@ -246,7 +235,6 @@ void main() {
name: 'iPad Retina', name: 'iPad Retina',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
logger: logger,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
@ -260,7 +248,6 @@ void main() {
name: 'iPhone 5', name: 'iPhone 5',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
logger: logger,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
@ -274,7 +261,6 @@ void main() {
name: 'iPhone 5s', name: 'iPhone 5s',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
logger: logger,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
@ -288,7 +274,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
logger: logger,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
@ -302,7 +287,6 @@ void main() {
name: 'iPhone 7 Plus', name: 'iPhone 7 Plus',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
logger: logger,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
@ -316,7 +300,6 @@ void main() {
name: 'iPhone X', name: 'iPhone X',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
logger: logger,
).isSupported(), true); ).isSupported(), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => osx, Platform: () => osx,
@ -354,7 +337,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
logger: logger,
); );
final File screenshot = MemoryFileSystem.test().file('screenshot.png'); final File screenshot = MemoryFileSystem.test().file('screenshot.png');
@ -378,7 +360,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 9.3', simulatorCategory: 'iOS 9.3',
simControl: simControl, simControl: simControl,
logger: logger,
); );
fakeProcessManager.addCommand(const FakeCommand(command: <String>[ fakeProcessManager.addCommand(const FakeCommand(command: <String>[
'tail', 'tail',
@ -406,7 +387,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.0', simulatorCategory: 'iOS 11.0',
simControl: simControl, simControl: simControl,
logger: logger,
); );
const String expectedPredicate = 'eventType = logEvent AND ' const String expectedPredicate = 'eventType = logEvent AND '
'processImagePath ENDSWITH "My Super Awesome App" AND ' 'processImagePath ENDSWITH "My Super Awesome App" AND '
@ -441,7 +421,6 @@ void main() {
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.0', simulatorCategory: 'iOS 11.0',
simControl: simControl, simControl: simControl,
logger: logger,
); );
const String expectedPredicate = 'eventType = logEvent AND ' const String expectedPredicate = 'eventType = logEvent AND '
'(senderImagePath ENDSWITH "/Flutter" OR senderImagePath ENDSWITH "/libswiftCore.dylib" OR processImageUUID == senderImageUUID) AND ' '(senderImagePath ENDSWITH "/Flutter" OR senderImagePath ENDSWITH "/libswiftCore.dylib" OR processImageUUID == senderImageUUID) AND '
@ -506,7 +485,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'iPhone 11', name: 'iPhone 11',
simulatorCategory: 'iOS 10.0', simulatorCategory: 'iOS 10.0',
simControl: simControl, simControl: simControl,
logger: logger,
); );
final DeviceLogReader logReader = device.getLogReader( final DeviceLogReader logReader = device.getLogReader(
app: await BuildableIOSApp.fromProject(mockIosProject, null), app: await BuildableIOSApp.fromProject(mockIosProject, null),
@ -542,7 +520,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'iPhone 11', name: 'iPhone 11',
simulatorCategory: 'iOS 10.3', simulatorCategory: 'iOS 10.3',
simControl: simControl, simControl: simControl,
logger: logger,
); );
final DeviceLogReader logReader = device.getLogReader( final DeviceLogReader logReader = device.getLogReader(
app: await BuildableIOSApp.fromProject(mockIosProject, null), app: await BuildableIOSApp.fromProject(mockIosProject, null),
@ -591,7 +568,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'iPhone 11', name: 'iPhone 11',
simulatorCategory: 'iOS 10.3', simulatorCategory: 'iOS 10.3',
simControl: simControl, simControl: simControl,
logger: logger,
); );
final DeviceLogReader logReader = device.getLogReader( final DeviceLogReader logReader = device.getLogReader(
app: await BuildableIOSApp.fromProject(mockIosProject, null), app: await BuildableIOSApp.fromProject(mockIosProject, null),
@ -664,7 +640,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'iPhone 11', name: 'iPhone 11',
simulatorCategory: 'iOS 11.0', simulatorCategory: 'iOS 11.0',
simControl: simControl, simControl: simControl,
logger: logger,
); );
final DeviceLogReader logReader = device.getLogReader( final DeviceLogReader logReader = device.getLogReader(
app: await BuildableIOSApp.fromProject(mockIosProject, null), app: await BuildableIOSApp.fromProject(mockIosProject, null),
@ -708,7 +683,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'iPhone 11', name: 'iPhone 11',
simulatorCategory: 'iOS 11.0', simulatorCategory: 'iOS 11.0',
simControl: simControl, simControl: simControl,
logger: logger,
); );
final DeviceLogReader logReader = device.getLogReader( final DeviceLogReader logReader = device.getLogReader(
app: await BuildableIOSApp.fromProject(mockIosProject, null), app: await BuildableIOSApp.fromProject(mockIosProject, null),
@ -850,7 +824,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'Testo', name: 'Testo',
simulatorCategory: 'NaN', simulatorCategory: 'NaN',
simControl: simControl, simControl: simControl,
logger: logger,
); );
expect(await iosSimulatorA.sdkMajorVersion, 11); expect(await iosSimulatorA.sdkMajorVersion, 11);
@ -935,7 +908,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'Testo', name: 'Testo',
simulatorCategory: 'NaN', simulatorCategory: 'NaN',
simControl: simControl, simControl: simControl,
logger: logger,
); );
expect(await iosSimulator.stopApp(null), isFalse); expect(await iosSimulator.stopApp(null), isFalse);
@ -1114,7 +1086,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.2', simulatorCategory: 'iOS 11.2',
simControl: simControl, simControl: simControl,
logger: logger,
); );
testPlistParser.setProperty('CFBundleIdentifier', 'correct'); testPlistParser.setProperty('CFBundleIdentifier', 'correct');
@ -1144,7 +1115,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.2', simulatorCategory: 'iOS 11.2',
simControl: simControl, simControl: simControl,
logger: logger,
); );
final Directory mockDir = globals.fs.currentDirectory; final Directory mockDir = globals.fs.currentDirectory;
@ -1176,7 +1146,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.2', simulatorCategory: 'iOS 11.2',
simControl: simControl, simControl: simControl,
logger: logger,
); );
testPlistParser.setProperty('CFBundleIdentifier', 'correct'); testPlistParser.setProperty('CFBundleIdentifier', 'correct');
@ -1249,7 +1218,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
name: 'iPhone SE', name: 'iPhone SE',
simulatorCategory: 'iOS 11.2', simulatorCategory: 'iOS 11.2',
simControl: simControl, simControl: simControl,
logger: logger,
); );
testPlistParser.setProperty('CFBundleIdentifier', 'correct'); testPlistParser.setProperty('CFBundleIdentifier', 'correct');
@ -1300,7 +1268,6 @@ flutter:
name: 'iPhone 11', name: 'iPhone 11',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
logger: logger,
); );
expect(simulator.isSupportedForProject(flutterProject), true); expect(simulator.isSupportedForProject(flutterProject), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -1321,7 +1288,6 @@ flutter:
name: 'iPhone 11', name: 'iPhone 11',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
logger: logger,
); );
expect(simulator.isSupportedForProject(flutterProject), true); expect(simulator.isSupportedForProject(flutterProject), true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -1340,7 +1306,6 @@ flutter:
name: 'iPhone 11', name: 'iPhone 11',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
logger: logger,
); );
expect(simulator.isSupportedForProject(flutterProject), false); expect(simulator.isSupportedForProject(flutterProject), false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
@ -1355,7 +1320,6 @@ flutter:
name: 'iPhone 11', name: 'iPhone 11',
simControl: simControl, simControl: simControl,
simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3', simulatorCategory: 'com.apple.CoreSimulator.SimRuntime.iOS-11-3',
logger: logger,
); );
expect(simulator.createDevFSWriter(null, ''), isA<LocalDevFSWriter>()); expect(simulator.createDevFSWriter(null, ''), isA<LocalDevFSWriter>());

View File

@ -17,7 +17,6 @@ import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/device_vm_service_discovery_for_attach.dart'; import 'package:flutter_tools/src/device_vm_service_discovery_for_attach.dart';
import 'package:flutter_tools/src/proxied_devices/devices.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/proxied_devices/file_transfer.dart';
import 'package:flutter_tools/src/resident_runner.dart';
import 'package:test/fake.dart'; import 'package:test/fake.dart';
import '../../src/common.dart'; import '../../src/common.dart';
@ -645,8 +644,9 @@ void main() {
final Future<void> startFuture = dds.startDartDevelopmentService( final Future<void> startFuture = dds.startDartDevelopmentService(
Uri.parse('http://127.0.0.1:100/fake'), Uri.parse('http://127.0.0.1:100/fake'),
disableServiceAuthCodes: true, disableServiceAuthCodes: true,
ddsPort: 150, hostPort: 150,
ipv6: false, ipv6: false,
logger: bufferLogger,
); );
final DaemonMessage startMessage = await broadcastOutput.first; final DaemonMessage startMessage = await broadcastOutput.first;
@ -656,13 +656,9 @@ void main() {
'deviceId': 'test_id', 'deviceId': 'test_id',
'vmServiceUri': 'http://127.0.0.1:200/fake', 'vmServiceUri': 'http://127.0.0.1:200/fake',
'disableServiceAuthCodes': true, 'disableServiceAuthCodes': true,
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// 'enableDevTools': false,
}); });
serverDaemonConnection.sendResponse( startMessage.data['id']!, const <String, Object?>{ serverDaemonConnection.sendResponse(startMessage.data['id']!, 'http://127.0.0.1:300/remote');
'ddsUri': 'http://127.0.0.1:300/remote',
});
await startFuture; await startFuture;
expect(portForwarder.receivedLocalForwardedPort, 100); expect(portForwarder.receivedLocalForwardedPort, 100);
@ -705,8 +701,9 @@ void main() {
final Future<void> startFuture = dds.startDartDevelopmentService( final Future<void> startFuture = dds.startDartDevelopmentService(
Uri.parse('http://127.0.0.1:100/fake'), Uri.parse('http://127.0.0.1:100/fake'),
disableServiceAuthCodes: true, disableServiceAuthCodes: true,
ddsPort: 150, hostPort: 150,
ipv6: false, ipv6: false,
logger: bufferLogger,
); );
final DaemonMessage startMessage = await broadcastOutput.first; final DaemonMessage startMessage = await broadcastOutput.first;
@ -716,13 +713,9 @@ void main() {
'deviceId': 'test_id', 'deviceId': 'test_id',
'vmServiceUri': 'http://127.0.0.1:200/fake', 'vmServiceUri': 'http://127.0.0.1:200/fake',
'disableServiceAuthCodes': true, 'disableServiceAuthCodes': true,
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// 'enableDevTools': false,
}); });
serverDaemonConnection.sendResponse(startMessage.data['id']!, <String, Object?>{ serverDaemonConnection.sendResponse(startMessage.data['id']!, 'http://127.0.0.1:300/remote');
'ddsUri': 'http://127.0.0.1:300/remote',
});
await startFuture; await startFuture;
expect(portForwarder.receivedLocalForwardedPort, 100); expect(portForwarder.receivedLocalForwardedPort, 100);
@ -765,8 +758,9 @@ void main() {
await dds.startDartDevelopmentService( await dds.startDartDevelopmentService(
Uri.parse('http://127.0.0.1:100/fake'), Uri.parse('http://127.0.0.1:100/fake'),
disableServiceAuthCodes: true, disableServiceAuthCodes: true,
ddsPort: 150, hostPort: 150,
ipv6: false, ipv6: false,
logger: bufferLogger,
); );
expect(localDds.startCalled, true); expect(localDds.startCalled, true);
@ -803,8 +797,9 @@ void main() {
final Future<void> startFuture = dds.startDartDevelopmentService( final Future<void> startFuture = dds.startDartDevelopmentService(
Uri.parse('http://127.0.0.1:100/fake'), Uri.parse('http://127.0.0.1:100/fake'),
disableServiceAuthCodes: true, disableServiceAuthCodes: true,
ddsPort: 150, hostPort: 150,
ipv6: false, ipv6: false,
logger: bufferLogger,
); );
expect(localDds.startCalled, false); expect(localDds.startCalled, false);
@ -815,8 +810,6 @@ void main() {
'deviceId': 'test_id', 'deviceId': 'test_id',
'vmServiceUri': 'http://127.0.0.1:200/fake', 'vmServiceUri': 'http://127.0.0.1:200/fake',
'disableServiceAuthCodes': true, 'disableServiceAuthCodes': true,
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// 'enableDevTools': false,
}); });
serverDaemonConnection.sendErrorResponse(startMessage.data['id']!, 'command not understood: device.startDartDevelopmentService', StackTrace.current); serverDaemonConnection.sendErrorResponse(startMessage.data['id']!, 'command not understood: device.startDartDevelopmentService', StackTrace.current);
@ -1185,14 +1178,11 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService
@override @override
Future<void> startDartDevelopmentService( Future<void> startDartDevelopmentService(
Uri vmServiceUri, { Uri vmServiceUri, {
FlutterDevice? device, required Logger logger,
int? ddsPort, int? hostPort,
bool? ipv6, bool? ipv6,
bool? disableServiceAuthCodes, bool? disableServiceAuthCodes,
bool enableDevTools = false,
bool cacheStartupProfile = false, bool cacheStartupProfile = false,
String? google3WorkspaceRoot,
Uri? devToolsServerAddress,
}) async { }) async {
startCalled = true; startCalled = true;
startUri = vmServiceUri; startUri = vmServiceUri;
@ -1200,10 +1190,6 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService
@override @override
Future<void> shutdown() async => shutdownCalled = true; Future<void> shutdown() async => shutdownCalled = true;
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// @override
// Future<void> invokeServiceExtensions(FlutterDevice? device) async {}
} }
class FakePrebuiltApplicationPackage extends Fake implements PrebuiltApplicationPackage { class FakePrebuiltApplicationPackage extends Fake implements PrebuiltApplicationPackage {

View File

@ -469,14 +469,12 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService
@override @override
Future<void> startDartDevelopmentService( Future<void> startDartDevelopmentService(
Uri vmServiceUri, { Uri observatoryUri, {
int? ddsPort, required Logger logger,
bool? disableServiceAuthCodes, int? hostPort,
bool? ipv6, bool? ipv6,
bool enableDevTools = true, bool? disableServiceAuthCodes,
bool cacheStartupProfile = false, bool cacheStartupProfile = false,
String? google3WorkspaceRoot,
Uri? devToolsServerAddress,
}) async { }) async {
started = true; started = true;
} }
@ -485,4 +483,7 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService
Future<void> shutdown() async { Future<void> shutdown() async {
disposed = true; disposed = true;
} }
@override
void setExternalDevToolsUri(Uri uri) {}
} }

View File

@ -4,6 +4,7 @@
import 'dart:async'; import 'dart:async';
import 'package:dds/dds.dart' as dds;
import 'package:flutter_tools/src/application_package.dart'; import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/asset.dart'; import 'package:flutter_tools/src/asset.dart';
import 'package:flutter_tools/src/base/dds.dart'; import 'package:flutter_tools/src/base/dds.dart';
@ -150,44 +151,33 @@ const FakeVmServiceRequest evictShader = FakeVmServiceRequest(
} }
); );
const DartDevelopmentServiceInstance fakeDartDevelopmentServiceInstance = (
process: null,
serviceUri: null,
devToolsUri: null,
dtdUri: null,
);
final Uri testUri = Uri.parse('foo://bar'); final Uri testUri = Uri.parse('foo://bar');
class FakeDartDevelopmentService extends Fake with DartDevelopmentServiceLocalOperationsMixin implements DartDevelopmentService { // This implements [dds.DartDevelopmentService], not the [DartDevelopmentService]
// interface from package:flutter_tools.
class FakeDartDevelopmentService extends Fake implements dds.DartDevelopmentService {
@override @override
Future<void> get done => Future<void>.value(); Future<void> get done => Future<void>.value();
@override @override
Uri? get uri => null; Uri? get uri => null;
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS>
/*
@override
Uri? get devToolsUri => null;
@override
Uri? get dtdUri => null;
@override
Future<void> handleHotRestart(FlutterDevice? device) async {}
*/
} }
class FakeDartDevelopmentServiceException implements DartDevelopmentServiceException { class FakeDartDevelopmentServiceException implements dds.DartDevelopmentServiceException {
FakeDartDevelopmentServiceException({this.message = defaultMessage}); FakeDartDevelopmentServiceException({this.message = defaultMessage});
@override @override
final int errorCode = DartDevelopmentServiceException.existingDdsInstanceError; final int errorCode = dds.DartDevelopmentServiceException.existingDdsInstanceError;
@override @override
final String message; final String message;
static const String defaultMessage = 'A DDS instance is already connected at http://localhost:8181'; static const String defaultMessage = 'A DDS instance is already connected at http://localhost:8181';
@override
Map<String, Object?> toJson() => <String, Object?>{
'error_code': errorCode,
'message': message,
};
} }
class TestFlutterDevice extends FlutterDevice { class TestFlutterDevice extends FlutterDevice {
@ -282,10 +272,13 @@ class FakeFlutterDevice extends Fake implements FlutterDevice {
GetSkSLMethod? getSkSLMethod, GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject, FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
required DebuggingOptions debuggingOptions,
int? hostVmServicePort, int? hostVmServicePort,
bool? ipv6 = false, int? ddsPort,
bool allowExistingDdsInstance = false, bool disableServiceAuthCodes = false,
bool enableDds = true,
bool cacheStartupProfile = false,
required bool allowExistingDdsInstance,
bool ipv6 = false,
}) async { } }) async { }
@override @override
@ -310,10 +303,6 @@ class FakeFlutterDevice extends Fake implements FlutterDevice {
@override @override
Future<void> updateReloadStatus(bool wasReloadSuccessful) async { } Future<void> updateReloadStatus(bool wasReloadSuccessful) async { }
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// @override
// Future<void> handleHotRestart() async {}
} }
class FakeDelegateFlutterDevice extends FlutterDevice { class FakeDelegateFlutterDevice extends FlutterDevice {
@ -328,13 +317,16 @@ class FakeDelegateFlutterDevice extends FlutterDevice {
Future<void> connect({ Future<void> connect({
ReloadSources? reloadSources, ReloadSources? reloadSources,
Restart? restart, Restart? restart,
bool enableDds = true,
bool cacheStartupProfile = false,
bool disableServiceAuthCodes = false,
bool ipv6 = false,
CompileExpression? compileExpression, CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod, GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject, FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
required DebuggingOptions debuggingOptions,
int? hostVmServicePort, int? hostVmServicePort,
bool? ipv6 = false, int? ddsPort,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
bool allowExistingDdsInstance = false, bool allowExistingDdsInstance = false,
}) async { } }) async { }
@ -443,7 +435,7 @@ class FakeDevice extends Fake implements Device {
String get name => 'FakeDevice'; String get name => 'FakeDevice';
@override @override
late DartDevelopmentService dds = FakeDartDevelopmentService(); late DartDevelopmentService dds;
@override @override
Future<void> dispose() async { Future<void> dispose() async {

View File

@ -4,10 +4,12 @@
import 'dart:async'; import 'dart:async';
import 'package:dds/dds.dart' as dds;
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart'; import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/artifacts.dart'; import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/command_help.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/dds.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart' as io; import 'package:flutter_tools/src/base/io.dart' as io;
@ -63,8 +65,8 @@ void main() {
stayResident: false, stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart', target: 'main.dart',
analytics: fakeAnalytics,
devtoolsHandler: createNoOpHandler, devtoolsHandler: createNoOpHandler,
analytics: globals.analytics,
); );
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Analytics: () => FakeAnalytics(), Analytics: () => FakeAnalytics(),
@ -88,6 +90,7 @@ void main() {
final Future<int?> result = residentRunner.attach( final Future<int?> result = residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
); );
final Future<DebugConnectionInfo> connectionInfo = futureConnectionInfo.future; final Future<DebugConnectionInfo> connectionInfo = futureConnectionInfo.future;
@ -119,7 +122,7 @@ void main() {
); );
flutterDevice.generator = residentCompiler; flutterDevice.generator = residentCompiler;
expect(await residentRunner.run(), 0); expect(await residentRunner.run(enableDevTools: true), 0);
expect(residentCompiler.didSuppressErrors, true); expect(residentCompiler.didSuppressErrors, true);
expect(fakeVmServiceHost?.hasRemainingExpectations, false); expect(fakeVmServiceHost?.hasRemainingExpectations, false);
})); }));
@ -213,7 +216,7 @@ void main() {
); );
flutterDevice.generator = residentCompiler; flutterDevice.generator = residentCompiler;
expect(await residentRunner.run(), 0); expect(await residentRunner.run(enableDevTools: true), 0);
expect(residentCompiler.didSuppressErrors, false); expect(residentCompiler.didSuppressErrors, false);
expect(fakeVmServiceHost?.hasRemainingExpectations, false); expect(fakeVmServiceHost?.hasRemainingExpectations, false);
})); }));
@ -276,6 +279,7 @@ void main() {
final Future<int?> result = residentRunner.attach( final Future<int?> result = residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
); );
final Future<DebugConnectionInfo> connectionInfo = futureConnectionInfo.future; final Future<DebugConnectionInfo> connectionInfo = futureConnectionInfo.future;
@ -297,6 +301,7 @@ void main() {
unawaited(residentRunner.attach( unawaited(residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
)); ));
await futureAppStart.future; await futureAppStart.future;
flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, ''); flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, '');
@ -338,6 +343,7 @@ void main() {
unawaited(residentRunner.attach( unawaited(residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
)); ));
await futureAppStart.future; await futureAppStart.future;
@ -383,6 +389,7 @@ void main() {
unawaited(residentRunner.attach( unawaited(residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
)); ));
await futureAppStart.future; await futureAppStart.future;
flutterDevice.reportError = vm_service.RPCError('something bad happened', kIsolateReloadBarred, ''); flutterDevice.reportError = vm_service.RPCError('something bad happened', kIsolateReloadBarred, '');
@ -426,15 +433,13 @@ void main() {
], ],
stayResident: false, stayResident: false,
target: 'main.dart', target: 'main.dart',
debuggingOptions: DebuggingOptions.enabled( debuggingOptions: DebuggingOptions.enabled(const BuildInfo(
const BuildInfo( BuildMode.debug, '', treeShakeIcons: false, extraFrontEndOptions: <String>[
BuildMode.debug, '', treeShakeIcons: false, extraFrontEndOptions: <String>[ '--enable-experiment=non-nullable',
'--enable-experiment=non-nullable', ],
], packageConfigPath: '.dart_tool/package_config.json'
packageConfigPath: '.dart_tool/package_config.json', )),
), devtoolsHandler: createNoOpHandler,
enableDevTools: false,
),
analytics: fakeAnalytics, analytics: fakeAnalytics,
); );
final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync(); final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
@ -442,6 +447,7 @@ void main() {
unawaited(residentRunner.attach( unawaited(residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
)); ));
await futureAppStart.future; await futureAppStart.future;
flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, ''); flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, '');
@ -506,6 +512,7 @@ void main() {
unawaited(residentRunner.attach( unawaited(residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
)); ));
await futureAppStart.future; await futureAppStart.future;
flutterDevice.report = UpdateFSReport(success: true); flutterDevice.report = UpdateFSReport(success: true);
@ -563,6 +570,7 @@ void main() {
unawaited(residentRunner.attach( unawaited(residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
)); ));
await futureAppStart.future; await futureAppStart.future;
flutterDevice.report = UpdateFSReport(success: true, invalidatedSourcesCount: 1); flutterDevice.report = UpdateFSReport(success: true, invalidatedSourcesCount: 1);
@ -626,6 +634,7 @@ void main() {
unawaited(residentRunner.attach( unawaited(residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
)); ));
await futureAppStart.future; await futureAppStart.future;
flutterDevice.report = UpdateFSReport(success: true, invalidatedSourcesCount: 1); flutterDevice.report = UpdateFSReport(success: true, invalidatedSourcesCount: 1);
@ -685,6 +694,7 @@ void main() {
unawaited(residentRunner.attach( unawaited(residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
)); ));
await futureAppStart.future; await futureAppStart.future;
@ -775,6 +785,7 @@ void main() {
unawaited(residentRunner.attach( unawaited(residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
)); ));
await futureAppStart.future; await futureAppStart.future;
@ -836,6 +847,7 @@ void main() {
unawaited(residentRunner.attach( unawaited(residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
)); ));
final OperationResult result = await residentRunner.restart(fullRestart: true); final OperationResult result = await residentRunner.restart(fullRestart: true);
@ -925,6 +937,7 @@ void main() {
unawaited(residentRunner.attach( unawaited(residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
)); ));
final OperationResult result = await residentRunner.restart(fullRestart: true); final OperationResult result = await residentRunner.restart(fullRestart: true);
@ -1045,6 +1058,7 @@ void main() {
unawaited(residentRunner.attach( unawaited(residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
)); ));
await residentRunner.restart(fullRestart: true); await residentRunner.restart(fullRestart: true);
@ -1064,6 +1078,7 @@ void main() {
unawaited(residentRunner.attach( unawaited(residentRunner.attach(
appStartedCompleter: futureAppStart, appStartedCompleter: futureAppStart,
connectionInfoCompleter: futureConnectionInfo, connectionInfoCompleter: futureConnectionInfo,
enableDevTools: true,
)); ));
await futureAppStart.future; await futureAppStart.future;
flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, ''); flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, '');
@ -1506,7 +1521,7 @@ flutter:
flutterDevice, flutterDevice,
], ],
stayResident: false, stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo', enableDevTools: false), debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'),
target: 'main.dart', target: 'main.dart',
devtoolsHandler: createNoOpHandler, devtoolsHandler: createNoOpHandler,
); );
@ -1556,7 +1571,7 @@ flutter:
analytics: fakeAnalytics, analytics: fakeAnalytics,
); );
await residentRunner.run(); await residentRunner.run(enableDevTools: true);
expect(fakeVmServiceHost?.hasRemainingExpectations, false); expect(fakeVmServiceHost?.hasRemainingExpectations, false);
expect(await globals.fs.file('foo').readAsString(), testUri.toString()); expect(await globals.fs.file('foo').readAsString(), testUri.toString());
@ -1587,7 +1602,7 @@ flutter:
); );
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
await residentRunner.run(); await residentRunner.run(enableDevTools: true);
expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill')).readAsString(), 'ABC'); expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill')).readAsString(), 'ABC');
})); }));
@ -1618,7 +1633,7 @@ flutter:
); );
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
await residentRunner.run(); await residentRunner.run(enableDevTools: true);
expect(await globals.fs.file(globals.fs.path.join( expect(await globals.fs.file(globals.fs.path.join(
'build', '187ef4436122d1cc2f40dc2b92f0eba0.cache.dill')).readAsString(), 'ABC'); 'build', '187ef4436122d1cc2f40dc2b92f0eba0.cache.dill')).readAsString(), 'ABC');
@ -1650,7 +1665,7 @@ flutter:
); );
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
await residentRunner.run(); await residentRunner.run(enableDevTools: true);
expect(await globals.fs.file(globals.fs.path.join( expect(await globals.fs.file(globals.fs.path.join(
'build', 'cache.dill')).readAsString(), 'ABC'); 'build', 'cache.dill')).readAsString(), 'ABC');
@ -1674,7 +1689,7 @@ flutter:
); );
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
await residentRunner.run(); await residentRunner.run(enableDevTools: true);
expect(await globals.fs.file(globals.fs.path.join( expect(await globals.fs.file(globals.fs.path.join(
'build', 'cache.dill.track.dill')).readAsString(), 'ABC'); 'build', 'cache.dill.track.dill')).readAsString(), 'ABC');
@ -1699,7 +1714,7 @@ flutter:
); );
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
await residentRunner.run(); await residentRunner.run(enableDevTools: true);
expect(globals.fs.file(globals.fs.path.join('build', 'cache.dill')), isNot(exists)); expect(globals.fs.file(globals.fs.path.join('build', 'cache.dill')), isNot(exists));
})); }));
@ -1728,7 +1743,7 @@ flutter:
); );
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC'); residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
await residentRunner.run(); await residentRunner.run(enableDevTools: true);
expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill.track.dill')).readAsString(), 'ABC'); expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill.track.dill')).readAsString(), 'ABC');
})); }));
@ -1771,7 +1786,7 @@ flutter:
analytics: fakeAnalytics, analytics: fakeAnalytics,
); );
await residentRunner.run(); await residentRunner.run(enableDevTools: true);
expect(testLogger.errorText, contains('Failed to write vmservice-out-file at foo')); expect(testLogger.errorText, contains('Failed to write vmservice-out-file at foo'));
expect(fakeVmServiceHost?.hasRemainingExpectations, false); expect(fakeVmServiceHost?.hasRemainingExpectations, false);
@ -1790,11 +1805,11 @@ flutter:
], ],
stayResident: false, stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'), debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'),
devtoolsHandler: createNoOpHandler,
target: 'main.dart', target: 'main.dart',
devtoolsHandler: createNoOpHandler,
); );
await residentRunner.run(); await residentRunner.run(enableDevTools: true);
expect(await globals.fs.file('foo').readAsString(), testUri.toString()); expect(await globals.fs.file('foo').readAsString(), testUri.toString());
expect(fakeVmServiceHost?.hasRemainingExpectations, false); expect(fakeVmServiceHost?.hasRemainingExpectations, false);
@ -1960,19 +1975,61 @@ flutter:
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
}); });
testUsingContext('Handle existing VM service clients DDS error', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
final FakeDevice device = FakeDevice()
..dds = DartDevelopmentService();
ddsLauncherCallback = (Uri uri, {bool enableAuthCodes = true, bool ipv6 = false, Uri? serviceUri, List<String> cachedUserTags = const <String>[], 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<Uri>.value(testUri),
);
bool caught = false;
final Completer<void>done = Completer<void>();
runZonedGuarded(() {
flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete());
}, (Object e, StackTrace st) {
expect(e, isA<ToolExit>());
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: <Type, Generator>{
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: <VmServiceExpectation>[]).vmService,
}));
testUsingContext('Uses existing DDS URI from exception field', () => testbed.run(() async { testUsingContext('Uses existing DDS URI from exception field', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]); fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
final FakeDevice device = FakeDevice() final FakeDevice device = FakeDevice()
..dds = DartDevelopmentService(logger: testLogger); ..dds = DartDevelopmentService();
ddsLauncherCallback = (Uri uri, ddsLauncherCallback = (Uri uri, {bool enableAuthCodes = true, bool ipv6 = false, Uri? serviceUri, List<String> cachedUserTags = const <String>[], dds.UriConverter? uriConverter}) {
{bool enableDevTools = false, throw dds.DartDevelopmentServiceException.existingDdsInstance(
bool enableAuthCodes = true,
bool ipv6 = false, Uri? serviceUri,
List<String> cachedUserTags = const <String>[],
String? google3WorkspaceRoot,
Uri? devToolsServerAddress,
}) {
throw DartDevelopmentServiceException.existingDdsInstance(
'Existing DDS at http://localhost/existingDdsInMessage.', 'Existing DDS at http://localhost/existingDdsInMessage.',
ddsUri: Uri.parse('http://localhost/existingDdsInField'), ddsUri: Uri.parse('http://localhost/existingDdsInField'),
); );
@ -1983,10 +2040,7 @@ flutter:
); );
final Completer<void> done = Completer<void>(); final Completer<void> done = Completer<void>();
unawaited(runZonedGuarded( unawaited(runZonedGuarded(
() => flutterDevice.connect( () => flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete()),
allowExistingDdsInstance: true,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
).then((_) => done.complete()),
(_, __) => done.complete(), (_, __) => done.complete(),
)); ));
await done.future; await done.future;
@ -1998,7 +2052,41 @@ flutter:
CompileExpression? compileExpression, CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod, GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject, FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
required Logger logger,
}) async => FakeVmServiceHost(requests: <VmServiceExpectation>[]).vmService,
}));
testUsingContext('Falls back to existing DDS URI from exception message', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
final FakeDevice device = FakeDevice()
..dds = DartDevelopmentService();
ddsLauncherCallback = (Uri uri, {bool enableAuthCodes = true, bool ipv6 = false, Uri? serviceUri, List<String> cachedUserTags = const <String>[], dds.UriConverter? uriConverter}) {
throw dds.DartDevelopmentServiceException.existingDdsInstance(
'Existing DDS at http://localhost/existingDdsInMessage.',
);
};
final TestFlutterDevice flutterDevice = TestFlutterDevice(
device,
vmServiceUris: Stream<Uri>.value(testUri),
);
final Completer<void>done = Completer<void>();
unawaited(runZonedGuarded(
() => flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete()),
(_, __) => done.complete(),
));
await done.future;
expect(device.dds.uri, Uri.parse('http://localhost/existingDdsInMessage'));
}, overrides: <Type, Generator>{
VMServiceConnector: () => (Uri httpUri, {
ReloadSources? reloadSources,
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression, io.CompressionOptions? compression,
Device? device, Device? device,
required Logger logger, required Logger logger,
@ -2008,34 +2096,23 @@ flutter:
testUsingContext('Host VM service ipv6 defaults', () => testbed.run(() async { testUsingContext('Host VM service ipv6 defaults', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]); fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
final FakeDevice device = FakeDevice() final FakeDevice device = FakeDevice()
..dds = DartDevelopmentService(logger: testLogger); ..dds = DartDevelopmentService();
final Completer<void>done = Completer<void>(); final Completer<void>done = Completer<void>();
ddsLauncherCallback = (Uri uri, ddsLauncherCallback = (Uri uri, {bool enableAuthCodes = true, bool ipv6 = false, Uri? serviceUri, List<String> cachedUserTags = const <String>[], dds.UriConverter? uriConverter}) async {
{bool enableDevTools = false,
bool enableAuthCodes = true,
bool ipv6 = false, Uri? serviceUri,
List<String> cachedUserTags = const <String>[],
String? google3WorkspaceRoot,
Uri? devToolsServerAddress,
}) async {
expect(uri, Uri(scheme: 'foo', host: 'bar')); expect(uri, Uri(scheme: 'foo', host: 'bar'));
expect(enableAuthCodes, isFalse); expect(enableAuthCodes, isFalse);
expect(ipv6, isTrue); expect(ipv6, isTrue);
expect(serviceUri, Uri(scheme: 'http', host: '::1', port: 0)); expect(serviceUri, Uri(scheme: 'http', host: '::1', port: 0));
expect(cachedUserTags, isEmpty); expect(cachedUserTags, isEmpty);
expect(uriConverter, isNull);
done.complete(); done.complete();
return fakeDartDevelopmentServiceInstance; return FakeDartDevelopmentService();
}; };
final TestFlutterDevice flutterDevice = TestFlutterDevice( final TestFlutterDevice flutterDevice = TestFlutterDevice(
device, device,
vmServiceUris: Stream<Uri>.value(testUri), vmServiceUris: Stream<Uri>.value(testUri),
); );
await flutterDevice.connect( await flutterDevice.connect(allowExistingDdsInstance: true, ipv6: true, disableServiceAuthCodes: true);
allowExistingDdsInstance: true,
debuggingOptions: DebuggingOptions.enabled(
BuildInfo.debug, disableServiceAuthCodes: true, ipv6: true,
)
);
await done.future; await done.future;
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
VMServiceConnector: () => (Uri httpUri, { VMServiceConnector: () => (Uri httpUri, {
@ -2051,25 +2128,67 @@ flutter:
}) async => FakeVmServiceHost(requests: <VmServiceExpectation>[]).vmService, }) async => FakeVmServiceHost(requests: <VmServiceExpectation>[]).vmService,
})); }));
testUsingContext('Failed DDS start outputs error message', () => testbed.run(() async { testUsingContext('Context includes URI converter', () => testbed.run(() async {
// See https://github.com/flutter/flutter/issues/72385 for context. fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
final FakeDevice device = FakeDevice() final FakeDevice device = FakeDevice()
..dds = DartDevelopmentService(logger: testLogger); ..dds = DartDevelopmentService();
final Completer<void>done = Completer<void>();
ddsLauncherCallback = ( ddsLauncherCallback = (
Uri uri, { Uri uri, {
bool enableDevTools = false,
bool enableAuthCodes = false, bool enableAuthCodes = false,
bool ipv6 = false, bool ipv6 = false,
Uri? serviceUri, Uri? serviceUri,
List<String> cachedUserTags = const <String>[], List<String> cachedUserTags = const <String>[],
String? google3WorkspaceRoot, dds.UriConverter? uriConverter,
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, isNotNull);
done.complete();
return FakeDartDevelopmentService();
};
final TestFlutterDevice flutterDevice = TestFlutterDevice(
device,
vmServiceUris: Stream<Uri>.value(testUri),
);
await flutterDevice.connect(allowExistingDdsInstance: true, ipv6: true, disableServiceAuthCodes: true);
await done.future;
}, overrides: <Type, Generator>{
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: <VmServiceExpectation>[]).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();
ddsLauncherCallback = (
Uri uri, {
bool enableAuthCodes = false,
bool ipv6 = false,
Uri? serviceUri,
List<String> cachedUserTags = const <String>[],
dds.UriConverter? uriConverter,
}) { }) {
expect(uri, Uri(scheme: 'foo', host: 'bar')); expect(uri, Uri(scheme: 'foo', host: 'bar'));
expect(enableAuthCodes, isTrue); expect(enableAuthCodes, isTrue);
expect(ipv6, isFalse); expect(ipv6, isFalse);
expect(serviceUri, Uri(scheme: 'http', host: '127.0.0.1', port: 0)); expect(serviceUri, Uri(scheme: 'http', host: '127.0.0.1', port: 0));
expect(cachedUserTags, isEmpty); expect(cachedUserTags, isEmpty);
expect(uriConverter, isNull);
throw FakeDartDevelopmentServiceException(message: 'No URI'); throw FakeDartDevelopmentServiceException(message: 'No URI');
}; };
final TestFlutterDevice flutterDevice = TestFlutterDevice( final TestFlutterDevice flutterDevice = TestFlutterDevice(
@ -2079,10 +2198,7 @@ flutter:
bool caught = false; bool caught = false;
final Completer<void>done = Completer<void>(); final Completer<void>done = Completer<void>();
runZonedGuarded(() { runZonedGuarded(() {
flutterDevice.connect( flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete());
allowExistingDdsInstance: true,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, enableDevTools: false),
).then((_) => done.complete());
}, (Object e, StackTrace st) { }, (Object e, StackTrace st) {
expect(e, isA<StateError>()); expect(e, isA<StateError>());
expect((e as StateError).message, contains('No URI')); expect((e as StateError).message, contains('No URI'));
@ -2120,7 +2236,6 @@ flutter:
expect(() => nextPlatform('unknown'), throwsAssertionError); expect(() => nextPlatform('unknown'), throwsAssertionError);
}); });
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
testUsingContext('cleanupAtFinish shuts down resident devtools handler', () => testbed.run(() async { testUsingContext('cleanupAtFinish shuts down resident devtools handler', () => testbed.run(() async {
residentRunner = HotRunner( residentRunner = HotRunner(
<FlutterDevice>[ <FlutterDevice>[

View File

@ -50,6 +50,7 @@ void main() {
mockFlutterDevice, mockFlutterDevice,
flutterProject: project, flutterProject: project,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
ipv6: true,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: BufferLogger.test(), logger: BufferLogger.test(),
systemClock: SystemClock.fixed(DateTime(0, 0, 0)), systemClock: SystemClock.fixed(DateTime(0, 0, 0)),
@ -80,6 +81,7 @@ void main() {
mockFlutterDevice, mockFlutterDevice,
flutterProject: project, flutterProject: project,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
ipv6: true,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: BufferLogger.test(), logger: BufferLogger.test(),
systemClock: SystemClock.fixed(DateTime(0, 0, 0)), systemClock: SystemClock.fixed(DateTime(0, 0, 0)),
@ -105,6 +107,7 @@ void main() {
mockFlutterDevice, mockFlutterDevice,
flutterProject: project, flutterProject: project,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
ipv6: true,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: BufferLogger.test(), logger: BufferLogger.test(),
systemClock: SystemClock.fixed(DateTime(0, 0, 0)), systemClock: SystemClock.fixed(DateTime(0, 0, 0)),
@ -129,6 +132,7 @@ void main() {
mockFlutterDevice, mockFlutterDevice,
flutterProject: project, flutterProject: project,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
ipv6: true,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: BufferLogger.test(), logger: BufferLogger.test(),
systemClock: SystemClock.fixed(DateTime(0, 0, 0)), systemClock: SystemClock.fixed(DateTime(0, 0, 0)),
@ -158,6 +162,7 @@ void main() {
mockFlutterDevice, mockFlutterDevice,
flutterProject: project, flutterProject: project,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release), debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
ipv6: true,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: BufferLogger.test(), logger: BufferLogger.test(),
systemClock: SystemClock.fixed(DateTime(0, 0, 0)), systemClock: SystemClock.fixed(DateTime(0, 0, 0)),
@ -240,8 +245,4 @@ class FakeFlutterDevice extends Fake implements FlutterDevice {
@override @override
FlutterVmService? vmService; FlutterVmService? vmService;
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// @override
// Future<void> handleHotRestart() async {}
} }

View File

@ -162,6 +162,7 @@ void main() {
flutterProject: flutterProject:
FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
ipv6: true,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: BufferLogger.test(), logger: BufferLogger.test(),
usage: globals.flutterUsage, usage: globals.flutterUsage,
@ -194,6 +195,7 @@ void main() {
FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
debuggingOptions: debuggingOptions:
DebuggingOptions.enabled(BuildInfo.debug, startPaused: true), DebuggingOptions.enabled(BuildInfo.debug, startPaused: true),
ipv6: true,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: BufferLogger.test(), logger: BufferLogger.test(),
usage: globals.flutterUsage, usage: globals.flutterUsage,
@ -213,6 +215,7 @@ void main() {
flutterProject: flutterProject:
FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
ipv6: true,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: BufferLogger.test(), logger: BufferLogger.test(),
usage: globals.flutterUsage, usage: globals.flutterUsage,
@ -226,6 +229,7 @@ void main() {
flutterProject: flutterProject:
FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile), debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile),
ipv6: true,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: BufferLogger.test(), logger: BufferLogger.test(),
usage: globals.flutterUsage, usage: globals.flutterUsage,
@ -358,13 +362,13 @@ void main() {
flutterProject: flutterProject:
FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
ipv6: true,
stayResident: false, stayResident: false,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: logger, logger: logger,
usage: globals.flutterUsage, usage: globals.flutterUsage,
analytics: globals.analytics, analytics: globals.analytics,
systemClock: globals.systemClock, systemClock: globals.systemClock,
devtoolsHandler: createNoOpHandler,
); );
expect(await residentWebRunner.run(), 0); expect(await residentWebRunner.run(), 0);
@ -385,13 +389,13 @@ void main() {
flutterProject: flutterProject:
FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
ipv6: true,
stayResident: false, stayResident: false,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: BufferLogger.test(), logger: BufferLogger.test(),
usage: globals.flutterUsage, usage: globals.flutterUsage,
analytics: globals.analytics, analytics: globals.analytics,
systemClock: globals.systemClock, systemClock: globals.systemClock,
devtoolsHandler: createNoOpHandler,
); );
expect(await residentWebRunner.run(), 0); expect(await residentWebRunner.run(), 0);
@ -587,12 +591,12 @@ void main() {
FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
debuggingOptions: debuggingOptions:
DebuggingOptions.enabled(BuildInfo.debug, startPaused: true), DebuggingOptions.enabled(BuildInfo.debug, startPaused: true),
ipv6: true,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: BufferLogger.test(), logger: BufferLogger.test(),
usage: globals.flutterUsage, usage: globals.flutterUsage,
analytics: globals.analytics, analytics: globals.analytics,
systemClock: globals.systemClock, systemClock: globals.systemClock,
devtoolsHandler: createNoOpHandler,
); );
fakeVmServiceHost = fakeVmServiceHost =
FakeVmServiceHost(requests: kAttachExpectations.toList()); FakeVmServiceHost(requests: kAttachExpectations.toList());
@ -1008,7 +1012,7 @@ void main() {
testUsingContext('cleanup of resources is safe to call multiple times', testUsingContext('cleanup of resources is safe to call multiple times',
() async { () async {
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice); final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
mockDevice.dds = DartDevelopmentService(logger: test_fakes.FakeLogger()); mockDevice.dds = DartDevelopmentService();
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[ fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations, ...kAttachExpectations,
]); ]);
@ -1111,12 +1115,12 @@ void main() {
flutterProject: flutterProject:
FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
ipv6: true,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: logger, logger: logger,
usage: globals.flutterUsage, usage: globals.flutterUsage,
analytics: globals.analytics, analytics: globals.analytics,
systemClock: globals.systemClock, systemClock: globals.systemClock,
devtoolsHandler: createNoOpHandler,
); );
final Completer<DebugConnectionInfo> connectionInfoCompleter = final Completer<DebugConnectionInfo> connectionInfoCompleter =
@ -1160,12 +1164,12 @@ void main() {
flutterProject: flutterProject:
FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
ipv6: true,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: logger, logger: logger,
usage: globals.flutterUsage, usage: globals.flutterUsage,
analytics: globals.analytics, analytics: globals.analytics,
systemClock: globals.systemClock, systemClock: globals.systemClock,
devtoolsHandler: createNoOpHandler,
); );
final Completer<DebugConnectionInfo> connectionInfoCompleter = final Completer<DebugConnectionInfo> connectionInfoCompleter =
@ -1202,13 +1206,13 @@ void main() {
flutterProject: flutterProject:
FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
ipv6: true,
stayResident: false, stayResident: false,
fileSystem: fileSystem, fileSystem: fileSystem,
logger: BufferLogger.test(), logger: BufferLogger.test(),
usage: globals.flutterUsage, usage: globals.flutterUsage,
analytics: globals.analytics, analytics: globals.analytics,
systemClock: globals.systemClock, systemClock: globals.systemClock,
devtoolsHandler: createNoOpHandler,
); );
// Create necessary files. // Create necessary files.
@ -1406,6 +1410,7 @@ ResidentRunner setUpResidentRunner(
FlutterProject.fromDirectoryTest(globals.fs.currentDirectory), FlutterProject.fromDirectoryTest(globals.fs.currentDirectory),
debuggingOptions: debuggingOptions:
debuggingOptions ?? DebuggingOptions.enabled(BuildInfo.debug), debuggingOptions ?? DebuggingOptions.enabled(BuildInfo.debug),
ipv6: true,
usage: globals.flutterUsage, usage: globals.flutterUsage,
analytics: globals.analytics, analytics: globals.analytics,
systemClock: systemClock ?? SystemClock.fixed(DateTime.now()), systemClock: systemClock ?? SystemClock.fixed(DateTime.now()),
@ -1714,11 +1719,13 @@ class FakeFlutterDevice extends Fake implements FlutterDevice {
GetSkSLMethod? getSkSLMethod, GetSkSLMethod? getSkSLMethod,
FlutterProject? flutterProject, FlutterProject? flutterProject,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod, PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
required DebuggingOptions debuggingOptions,
int? hostVmServicePort, int? hostVmServicePort,
int? ddsPort,
bool disableServiceAuthCodes = false,
bool enableDds = true,
bool cacheStartupProfile = false,
required bool allowExistingDdsInstance,
bool? ipv6 = false, bool? ipv6 = false,
bool enableDevTools = false,
bool allowExistingDdsInstance = false,
}) async {} }) async {}
@override @override
@ -1744,10 +1751,6 @@ class FakeFlutterDevice extends Fake implements FlutterDevice {
@override @override
Future<void> updateReloadStatus(bool wasReloadSuccessful) async {} Future<void> updateReloadStatus(bool wasReloadSuccessful) async {}
// TODO(bkonyi): uncomment when ready to serve DevTools from DDS.
// @override
// Future<void> handleHotRestart() async {}
} }
class FakeShaderCompiler implements DevelopmentShaderCompiler { class FakeShaderCompiler implements DevelopmentShaderCompiler {

View File

@ -191,7 +191,6 @@ void main() {
Analytics: () => fakeAnalytics, Analytics: () => fakeAnalytics,
}); });
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
group('${FlutterGlobalOptions.kPrintDtd} flag', () { group('${FlutterGlobalOptions.kPrintDtd} flag', () {
testUsingContext('sets DevtoolsLauncher.printDtdUri to false when not present', () async { testUsingContext('sets DevtoolsLauncher.printDtdUri to false when not present', () async {
final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner; final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;

View File

@ -7,7 +7,6 @@ import 'dart:async';
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:file_testing/file_testing.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/io.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/signals.dart'; import 'package:flutter_tools/src/base/signals.dart';
@ -26,7 +25,6 @@ import 'package:vm_service/vm_service.dart' as vm_service;
import '../src/common.dart'; import '../src/common.dart';
import '../src/fake_vm_services.dart'; import '../src/fake_vm_services.dart';
import '../src/fakes.dart';
final vm_service.Isolate fakeUnpausedIsolate = vm_service.Isolate( final vm_service.Isolate fakeUnpausedIsolate = vm_service.Isolate(
id: '1', id: '1',
@ -834,20 +832,8 @@ void main() {
final FakeResidentDevtoolsHandler devtoolsHandler = runner.residentDevtoolsHandler as FakeResidentDevtoolsHandler; final FakeResidentDevtoolsHandler devtoolsHandler = runner.residentDevtoolsHandler as FakeResidentDevtoolsHandler;
expect(devtoolsHandler.calledLaunchDevToolsInBrowser, isFalse); expect(devtoolsHandler.calledLaunchDevToolsInBrowser, isFalse);
// TODO(bkonyi): uncomment these checks and remove existing checks when ready to
// serve DevTools from DDS.
/*
for (final FlutterDevice? device in runner.flutterDevices) {
expect(device!.device!.dds.calledLaunchDevToolsInBrowser, isFalse);
}
*/
await terminalHandler.processTerminalInput('v'); await terminalHandler.processTerminalInput('v');
expect(devtoolsHandler.calledLaunchDevToolsInBrowser, isTrue); expect(devtoolsHandler.calledLaunchDevToolsInBrowser, isTrue);
/*
for (final FlutterDevice? device in runner.flutterDevices) {
expect(device!.device!.dds.calledLaunchDevToolsInBrowser, isTrue);
}
*/
}); });
testWithoutContext('w,W - debugDumpApp without service protocol is skipped', () async { testWithoutContext('w,W - debugDumpApp without service protocol is skipped', () async {
@ -1322,13 +1308,11 @@ class FakeResidentRunner extends ResidentHandlers {
return OperationResult(reloadExitCode, '', fatal: fatalReloadError); return OperationResult(reloadExitCode, '', fatal: fatalReloadError);
} }
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
@override @override
ResidentDevtoolsHandler get residentDevtoolsHandler => _residentDevtoolsHandler; ResidentDevtoolsHandler get residentDevtoolsHandler => _residentDevtoolsHandler;
final ResidentDevtoolsHandler _residentDevtoolsHandler = FakeResidentDevtoolsHandler(); final ResidentDevtoolsHandler _residentDevtoolsHandler = FakeResidentDevtoolsHandler();
} }
// TODO(bkonyi): remove when ready to serve DevTools from DDS.
class FakeResidentDevtoolsHandler extends Fake implements ResidentDevtoolsHandler { class FakeResidentDevtoolsHandler extends Fake implements ResidentDevtoolsHandler {
bool calledLaunchDevToolsInBrowser = false; bool calledLaunchDevToolsInBrowser = false;
@ -1348,9 +1332,6 @@ class FakeDevice extends Fake implements Device {
@override @override
String get name => 'Fake Device'; String get name => 'Fake Device';
@override
DartDevelopmentService dds = DartDevelopmentService(logger: FakeLogger());
@override @override
Future<void> takeScreenshot(File file) async { Future<void> takeScreenshot(File file) async {
if (!supportsScreenshot) { if (!supportsScreenshot) {
@ -1358,6 +1339,7 @@ class FakeDevice extends Fake implements Device {
} }
file.writeAsBytesSync(<int>[1, 2, 3, 4]); file.writeAsBytesSync(<int>[1, 2, 3, 4]);
} }
} }
TerminalHandler setUpTerminalHandler(List<FakeVmServiceRequest> requests, { TerminalHandler setUpTerminalHandler(List<FakeVmServiceRequest> requests, {

View File

@ -9,8 +9,6 @@ import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/project.dart';
import 'fakes.dart';
/// A list of fake devices to test JSON serialization /// A list of fake devices to test JSON serialization
/// (`Device.toJson()` and `--machine` flag for `devices` command) /// (`Device.toJson()` and `--machine` flag for `devices` command)
List<FakeDeviceJsonData> fakeDevices = <FakeDeviceJsonData>[ List<FakeDeviceJsonData> fakeDevices = <FakeDeviceJsonData>[
@ -131,7 +129,6 @@ class FakeDevice extends Device {
platformType: type, platformType: type,
category: Category.mobile, category: Category.mobile,
ephemeral: ephemeral, ephemeral: ephemeral,
logger: FakeLogger(),
); );
final bool _isSupported; final bool _isSupported;

View File

@ -741,12 +741,6 @@ class FakeDevtoolsLauncher extends Fake implements DevtoolsLauncher {
} }
} }
/// A fake [Logger] that throws the [Invocation] for any method call.
class FakeLogger implements Logger {
@override
dynamic noSuchMethod(Invocation invocation) => throw invocation; // ignore: only_throw_errors
}
class ClosedStdinController extends Fake implements StreamSink<List<int>> { class ClosedStdinController extends Fake implements StreamSink<List<int>> {
@override @override
Future<Object?> addStream(Stream<List<int>> stream) async => throw const SocketException('Bad pipe'); Future<Object?> addStream(Stream<List<int>> stream) async => throw const SocketException('Bad pipe');