Unverified Commit fe7bbf72 authored by Ben Konyi's avatar Ben Konyi Committed by GitHub

Add support for Dart Development Service (DDS) in Flutter Tools (#59114)

parent dc0f1228
...@@ -38,6 +38,10 @@ void main() { ...@@ -38,6 +38,10 @@ void main() {
await binding.endOfFrame; await binding.endOfFrame;
}); });
tearDownAll(() {
vmService.dispose();
});
test('Image painting events - deduplicates across frames', () async { test('Image painting events - deduplicates across frames', () async {
final Completer<Event> completer = Completer<Event>(); final Completer<Event> completer = Completer<Event>();
vmService.onExtensionEvent.first.then(completer.complete); vmService.onExtensionEvent.first.then(completer.complete);
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:dds/dds.dart' as dds;
import 'package:meta/meta.dart';
import 'io.dart' as io;
import 'logger.dart';
/// Helper class to launch a [dds.DartDevelopmentService]. Allows for us to
/// mock out this functionality for testing purposes.
class DartDevelopmentService {
DartDevelopmentService({@required this.logger});
final Logger logger;
dds.DartDevelopmentService _ddsInstance;
Future<void> startDartDevelopmentService(
Uri observatoryUri,
bool ipv6,
) async {
final Uri ddsUri = Uri(
scheme: 'http',
host: (ipv6 ?
io.InternetAddress.loopbackIPv6 :
io.InternetAddress.loopbackIPv4
).host,
port: 0,
);
logger.printTrace(
'Launching a Dart Developer Service (DDS) instance at $ddsUri, '
'connecting to VM service at $observatoryUri.',
);
try {
_ddsInstance = await dds.DartDevelopmentService.startDartDevelopmentService(
observatoryUri,
serviceUri: ddsUri,
);
logger.printTrace('DDS is listening at ${_ddsInstance.uri}.');
} on dds.DartDevelopmentServiceException catch (e) {
logger.printError('Warning: Failed to start DDS: ${e.message}');
}
}
Future<void> shutdown() async => await _ddsInstance?.shutdown();
}
...@@ -100,6 +100,7 @@ class AttachCommand extends FlutterCommand { ...@@ -100,6 +100,7 @@ class AttachCommand extends FlutterCommand {
'and progress in machine friendly format.', 'and progress in machine friendly format.',
); );
usesTrackWidgetCreation(verboseHelp: verboseHelp); usesTrackWidgetCreation(verboseHelp: verboseHelp);
addDdsOptions(verboseHelp: verboseHelp);
hotRunnerFactory ??= HotRunnerFactory(); hotRunnerFactory ??= HotRunnerFactory();
} }
...@@ -372,7 +373,7 @@ class AttachCommand extends FlutterCommand { ...@@ -372,7 +373,7 @@ class AttachCommand extends FlutterCommand {
); );
flutterDevice.observatoryUris = observatoryUris; flutterDevice.observatoryUris = observatoryUris;
final List<FlutterDevice> flutterDevices = <FlutterDevice>[flutterDevice]; final List<FlutterDevice> flutterDevices = <FlutterDevice>[flutterDevice];
final DebuggingOptions debuggingOptions = DebuggingOptions.enabled(getBuildInfo()); final DebuggingOptions debuggingOptions = DebuggingOptions.enabled(getBuildInfo(), disableDds: boolArg('disable-dds'));
return getBuildInfo().isDebug return getBuildInfo().isDebug
? hotRunnerFactory.build( ? hotRunnerFactory.build(
......
...@@ -244,6 +244,10 @@ class DriveCommand extends RunCommandBase { ...@@ -244,6 +244,10 @@ class DriveCommand extends RunCommandBase {
throwToolExit('Application failed to start. Will not run test. Quitting.', exitCode: 1); throwToolExit('Application failed to start. Will not run test. Quitting.', exitCode: 1);
} }
observatoryUri = result.observatoryUri.toString(); observatoryUri = result.observatoryUri.toString();
// TODO(bkonyi): add web support (https://github.com/flutter/flutter/issues/61259)
if (!isWebPlatform) {
await device.dds.startDartDevelopmentService(Uri.parse(observatoryUri), ipv6);
}
} else { } else {
globals.printStatus('Will connect to already running application instance.'); globals.printStatus('Will connect to already running application instance.');
observatoryUri = stringArg('use-existing-app'); observatoryUri = stringArg('use-existing-app');
......
...@@ -218,6 +218,7 @@ class RunCommand extends RunCommandBase { ...@@ -218,6 +218,7 @@ class RunCommand extends RunCommandBase {
'Currently this is only supported on Android devices. This option ' 'Currently this is only supported on Android devices. This option '
'cannot be paired with --use-application-binary.' 'cannot be paired with --use-application-binary.'
); );
addDdsOptions(verboseHelp: verboseHelp);
} }
@override @override
...@@ -383,6 +384,7 @@ class RunCommand extends RunCommandBase { ...@@ -383,6 +384,7 @@ class RunCommand extends RunCommandBase {
buildInfo, buildInfo,
startPaused: boolArg('start-paused'), startPaused: boolArg('start-paused'),
disableServiceAuthCodes: boolArg('disable-service-auth-codes'), disableServiceAuthCodes: boolArg('disable-service-auth-codes'),
disableDds: boolArg('disable-dds'),
dartFlags: stringArg('dart-flags') ?? '', dartFlags: stringArg('dart-flags') ?? '',
useTestFonts: boolArg('use-test-fonts'), useTestFonts: boolArg('use-test-fonts'),
enableSoftwareRendering: boolArg('enable-software-rendering'), enableSoftwareRendering: boolArg('enable-software-rendering'),
......
...@@ -16,6 +16,7 @@ import 'application_package.dart'; ...@@ -16,6 +16,7 @@ import 'application_package.dart';
import 'artifacts.dart'; import 'artifacts.dart';
import 'base/config.dart'; import 'base/config.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'; import 'base/io.dart';
import 'base/logger.dart'; import 'base/logger.dart';
...@@ -547,6 +548,12 @@ abstract class Device { ...@@ -547,6 +548,12 @@ abstract class Device {
/// Get the port forwarder for this device. /// Get the port forwarder for this device.
DevicePortForwarder get portForwarder; DevicePortForwarder get portForwarder;
/// Get the DDS instance for this device.
DartDevelopmentService get dds => _dds ??= DartDevelopmentService(
logger: globals.logger,
);
DartDevelopmentService _dds;
/// Clear the device's logs. /// Clear the device's logs.
void clearLogs(); void clearLogs();
...@@ -720,6 +727,7 @@ class DebuggingOptions { ...@@ -720,6 +727,7 @@ class DebuggingOptions {
this.buildInfo, { this.buildInfo, {
this.startPaused = false, this.startPaused = false,
this.disableServiceAuthCodes = false, this.disableServiceAuthCodes = false,
this.disableDds = false,
this.dartFlags = '', this.dartFlags = '',
this.enableSoftwareRendering = false, this.enableSoftwareRendering = false,
this.skiaDeterministicRendering = false, this.skiaDeterministicRendering = false,
...@@ -760,6 +768,7 @@ class DebuggingOptions { ...@@ -760,6 +768,7 @@ class DebuggingOptions {
startPaused = false, startPaused = false,
dartFlags = '', dartFlags = '',
disableServiceAuthCodes = false, disableServiceAuthCodes = false,
disableDds = false,
enableSoftwareRendering = false, enableSoftwareRendering = false,
skiaDeterministicRendering = false, skiaDeterministicRendering = false,
traceSkia = false, traceSkia = false,
...@@ -779,6 +788,7 @@ class DebuggingOptions { ...@@ -779,6 +788,7 @@ class DebuggingOptions {
final bool startPaused; final bool startPaused;
final String dartFlags; final String dartFlags;
final bool disableServiceAuthCodes; final bool disableServiceAuthCodes;
final bool disableDds;
final bool enableSoftwareRendering; final bool enableSoftwareRendering;
final bool skiaDeterministicRendering; final bool skiaDeterministicRendering;
final bool traceSkia; final bool traceSkia;
......
...@@ -52,6 +52,13 @@ Future<vm_service.VmService> _kDefaultFuchsiaIsolateDiscoveryConnector(Uri uri) ...@@ -52,6 +52,13 @@ Future<vm_service.VmService> _kDefaultFuchsiaIsolateDiscoveryConnector(Uri uri)
return connectToVmService(uri); return connectToVmService(uri);
} }
Future<void> _kDefaultDartDevelopmentServiceStarter(
Device device,
Uri observatoryUri,
) async {
await device.dds.startDartDevelopmentService(observatoryUri, true);
}
/// Read the log for a particular device. /// Read the log for a particular device.
class _FuchsiaLogReader extends DeviceLogReader { class _FuchsiaLogReader extends DeviceLogReader {
_FuchsiaLogReader(this._device, this._systemClock, [this._app]); _FuchsiaLogReader(this._device, this._systemClock, [this._app]);
...@@ -695,6 +702,7 @@ class FuchsiaIsolateDiscoveryProtocol { ...@@ -695,6 +702,7 @@ class FuchsiaIsolateDiscoveryProtocol {
this._device, this._device,
this._isolateName, [ this._isolateName, [
this._vmServiceConnector = _kDefaultFuchsiaIsolateDiscoveryConnector, this._vmServiceConnector = _kDefaultFuchsiaIsolateDiscoveryConnector,
this._ddsStarter = _kDefaultDartDevelopmentServiceStarter,
this._pollOnce = false, this._pollOnce = false,
]); ]);
...@@ -704,6 +712,7 @@ class FuchsiaIsolateDiscoveryProtocol { ...@@ -704,6 +712,7 @@ class FuchsiaIsolateDiscoveryProtocol {
final String _isolateName; final String _isolateName;
final Completer<Uri> _foundUri = Completer<Uri>(); final Completer<Uri> _foundUri = Completer<Uri>();
final Future<vm_service.VmService> Function(Uri) _vmServiceConnector; final Future<vm_service.VmService> Function(Uri) _vmServiceConnector;
final Future<void> Function(Device, Uri) _ddsStarter;
// whether to only poll once. // whether to only poll once.
final bool _pollOnce; final bool _pollOnce;
Timer _pollingTimer; Timer _pollingTimer;
...@@ -746,6 +755,7 @@ class FuchsiaIsolateDiscoveryProtocol { ...@@ -746,6 +755,7 @@ class FuchsiaIsolateDiscoveryProtocol {
final int localPort = await _device.portForwarder.forward(port); final int localPort = await _device.portForwarder.forward(port);
try { try {
final Uri uri = Uri.parse('http://[$_ipv6Loopback]:$localPort'); final Uri uri = Uri.parse('http://[$_ipv6Loopback]:$localPort');
await _ddsStarter(_device, uri);
service = await _vmServiceConnector(uri); service = await _vmServiceConnector(uri);
_ports[port] = service; _ports[port] = service;
} on SocketException catch (err) { } on SocketException catch (err) {
......
...@@ -437,7 +437,7 @@ class IOSDevice extends Device { ...@@ -437,7 +437,7 @@ class IOSDevice extends Device {
); );
final Uri localUri = await fallbackDiscovery.discover( final Uri localUri = await fallbackDiscovery.discover(
assumedDevicePort: assumedObservatoryPort, assumedDevicePort: assumedObservatoryPort,
deivce: this, device: this,
usesIpv6: ipv6, usesIpv6: ipv6,
hostVmservicePort: debuggingOptions.hostVmServicePort, hostVmservicePort: debuggingOptions.hostVmServicePort,
packageId: packageId, packageId: packageId,
......
...@@ -67,7 +67,7 @@ class FallbackDiscovery { ...@@ -67,7 +67,7 @@ class FallbackDiscovery {
Future<Uri> discover({ Future<Uri> discover({
@required int assumedDevicePort, @required int assumedDevicePort,
@required String packageId, @required String packageId,
@required Device deivce, @required Device device,
@required bool usesIpv6, @required bool usesIpv6,
@required int hostVmservicePort, @required int hostVmservicePort,
@required String packageName, @required String packageName,
...@@ -84,7 +84,7 @@ class FallbackDiscovery { ...@@ -84,7 +84,7 @@ class FallbackDiscovery {
try { try {
final Uri result = await _mDnsObservatoryDiscovery.getObservatoryUri( final Uri result = await _mDnsObservatoryDiscovery.getObservatoryUri(
packageId, packageId,
deivce, device,
usesIpv6: usesIpv6, usesIpv6: usesIpv6,
hostVmservicePort: hostVmservicePort, hostVmservicePort: hostVmservicePort,
); );
......
...@@ -211,6 +211,8 @@ class FlutterDevice { ...@@ -211,6 +211,8 @@ class FlutterDevice {
ReloadMethod reloadMethod, ReloadMethod reloadMethod,
GetSkSLMethod getSkSLMethod, GetSkSLMethod getSkSLMethod,
PrintStructuredErrorLogMethod printStructuredErrorLogMethod, PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
bool disableDds = false,
bool ipv6 = false,
}) { }) {
final Completer<void> completer = Completer<void>(); final Completer<void> completer = Completer<void>();
StreamSubscription<void> subscription; StreamSubscription<void> subscription;
...@@ -221,7 +223,12 @@ class FlutterDevice { ...@@ -221,7 +223,12 @@ class FlutterDevice {
globals.printTrace('Connecting to service protocol: $observatoryUri'); globals.printTrace('Connecting to service protocol: $observatoryUri');
isWaitingForVm = true; isWaitingForVm = true;
vm_service.VmService service; vm_service.VmService service;
if (!disableDds) {
await device.dds.startDartDevelopmentService(
observatoryUri,
ipv6,
);
}
try { try {
service = await connectToVmService( service = await connectToVmService(
observatoryUri, observatoryUri,
...@@ -943,6 +950,7 @@ abstract class ResidentRunner { ...@@ -943,6 +950,7 @@ abstract class ResidentRunner {
Future<void> exit() async { Future<void> exit() async {
_exited = true; _exited = true;
await shutdownDevtools(); await shutdownDevtools();
await shutdownDartDevelopmentService();
await stopEchoingDeviceLog(); await stopEchoingDeviceLog();
await preExit(); await preExit();
await exitApp(); await exitApp();
...@@ -950,6 +958,7 @@ abstract class ResidentRunner { ...@@ -950,6 +958,7 @@ abstract class ResidentRunner {
Future<void> detach() async { Future<void> detach() async {
await shutdownDevtools(); await shutdownDevtools();
await shutdownDartDevelopmentService();
await stopEchoingDeviceLog(); await stopEchoingDeviceLog();
await preExit(); await preExit();
appFinished(); appFinished();
...@@ -1112,6 +1121,14 @@ abstract class ResidentRunner { ...@@ -1112,6 +1121,14 @@ abstract class ResidentRunner {
); );
} }
Future<void> shutdownDartDevelopmentService() async {
await Future.wait<void>(
flutterDevices.map<Future<void>>(
(FlutterDevice device) => device.device?.dds?.shutdown()
).where((Future<void> element) => element != null)
);
}
@protected @protected
void cacheInitialDillCompilation() { void cacheInitialDillCompilation() {
if (_dillOutputPath != null) { if (_dillOutputPath != null) {
...@@ -1165,9 +1182,11 @@ abstract class ResidentRunner { ...@@ -1165,9 +1182,11 @@ abstract class ResidentRunner {
reloadSources: reloadSources, reloadSources: reloadSources,
restart: restart, restart: restart,
compileExpression: compileExpression, compileExpression: compileExpression,
disableDds: debuggingOptions.disableDds,
reloadMethod: reloadMethod, reloadMethod: reloadMethod,
getSkSLMethod: getSkSLMethod, getSkSLMethod: getSkSLMethod,
printStructuredErrorLogMethod: printStructuredErrorLog, printStructuredErrorLogMethod: printStructuredErrorLog,
ipv6: ipv6,
); );
// This will wait for at least one flutter view before returning. // This will wait for at least one flutter view before returning.
final Status status = globals.logger.startProgress( final Status status = globals.logger.startProgress(
......
...@@ -289,6 +289,19 @@ abstract class FlutterCommand extends Command<void> { ...@@ -289,6 +289,19 @@ abstract class FlutterCommand extends Command<void> {
_usesPortOption = true; _usesPortOption = true;
} }
void addDdsOptions({@required bool verboseHelp}) {
argParser.addFlag(
'disable-dds',
hide: !verboseHelp,
help: 'Disable the Dart Developer Service (DDS). This flag should only be provided'
' when attaching to an application with an existing DDS instance (e.g.,'
' attaching to an application currently connected to by "flutter run") or'
' when running certain tests.\n'
'Note: passing this flag may degrade IDE functionality if a DDS instance is not'
' already connected to the target application.'
);
}
/// Gets the vmservice port provided to in the 'observatory-port' or /// Gets the vmservice port provided to in the 'observatory-port' or
/// 'host-vmservice-port option. /// 'host-vmservice-port option.
/// ///
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,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';
...@@ -514,7 +515,7 @@ class FlutterPlatform extends PlatformPlugin { ...@@ -514,7 +515,7 @@ class FlutterPlatform extends PlatformPlugin {
Uri processObservatoryUri; Uri processObservatoryUri;
_pipeStandardStreamsToConsole( _pipeStandardStreamsToConsole(
process, process,
reportObservatoryUri: (Uri detectedUri) { reportObservatoryUri: (Uri detectedUri) async {
assert(processObservatoryUri == null); assert(processObservatoryUri == null);
assert(explicitObservatoryPort == null || assert(explicitObservatoryPort == null ||
explicitObservatoryPort == detectedUri.port); explicitObservatoryPort == detectedUri.port);
...@@ -527,13 +528,14 @@ class FlutterPlatform extends PlatformPlugin { ...@@ -527,13 +528,14 @@ class FlutterPlatform extends PlatformPlugin {
globals.printTrace('test $ourTestCount: using observatory uri $detectedUri from pid ${process.pid}'); globals.printTrace('test $ourTestCount: using observatory uri $detectedUri from pid ${process.pid}');
} }
processObservatoryUri = detectedUri; processObservatoryUri = detectedUri;
await DartDevelopmentService.startDartDevelopmentService(processObservatoryUri);
{ {
globals.printTrace('Connecting to service protocol: $processObservatoryUri'); globals.printTrace('Connecting to service protocol: $processObservatoryUri');
final Future<vm_service.VmService> localVmService = connectToVmService(processObservatoryUri, final Future<vm_service.VmService> localVmService = connectToVmService(processObservatoryUri,
compileExpression: _compileExpressionService); compileExpression: _compileExpressionService);
localVmService.then((vm_service.VmService vmservice) { unawaited(localVmService.then((vm_service.VmService vmservice) {
globals.printTrace('Successfully connected to service protocol: $processObservatoryUri'); globals.printTrace('Successfully connected to service protocol: $processObservatoryUri');
}); }));
} }
gotProcessObservatoryUri.complete(); gotProcessObservatoryUri.complete();
watcher?.handleStartedProcess( watcher?.handleStartedProcess(
...@@ -870,8 +872,9 @@ class FlutterPlatform extends PlatformPlugin { ...@@ -870,8 +872,9 @@ class FlutterPlatform extends PlatformPlugin {
void _pipeStandardStreamsToConsole( void _pipeStandardStreamsToConsole(
Process process, { Process process, {
void startTimeoutTimer(), void startTimeoutTimer(),
void reportObservatoryUri(Uri uri), Future<void> reportObservatoryUri(Uri uri),
}) { }) {
const String observatoryString = 'Observatory listening on '; const String observatoryString = 'Observatory listening on ';
for (final Stream<List<int>> stream in <Stream<List<int>>>[ for (final Stream<List<int>> stream in <Stream<List<int>>>[
process.stderr, process.stderr,
...@@ -881,7 +884,7 @@ class FlutterPlatform extends PlatformPlugin { ...@@ -881,7 +884,7 @@ class FlutterPlatform extends PlatformPlugin {
.transform<String>(utf8.decoder) .transform<String>(utf8.decoder)
.transform<String>(const LineSplitter()) .transform<String>(const LineSplitter())
.listen( .listen(
(String line) { (String line) async {
if (line == _kStartTimeoutTimerMessage) { if (line == _kStartTimeoutTimerMessage) {
if (startTimeoutTimer != null) { if (startTimeoutTimer != null) {
startTimeoutTimer(); startTimeoutTimer();
...@@ -894,7 +897,7 @@ class FlutterPlatform extends PlatformPlugin { ...@@ -894,7 +897,7 @@ class FlutterPlatform extends PlatformPlugin {
try { try {
final Uri uri = Uri.parse(line.substring(observatoryString.length)); final Uri uri = Uri.parse(line.substring(observatoryString.length));
if (reportObservatoryUri != null) { if (reportObservatoryUri != null) {
reportObservatoryUri(uri); await reportObservatoryUri(uri);
} }
} on Exception catch (error) { } on Exception catch (error) {
globals.printError('Could not parse shell observatory port message: $error'); globals.printError('Could not parse shell observatory port message: $error');
......
...@@ -22,12 +22,6 @@ class Tracing { ...@@ -22,12 +22,6 @@ class Tracing {
Tracing(this.vmService); Tracing(this.vmService);
static const String firstUsefulFrameEventName = kFirstFrameRasterizedEventName; static const String firstUsefulFrameEventName = kFirstFrameRasterizedEventName;
static Future<Tracing> connect(Uri uri) async {
final vm_service.VmService observatory = await connectToVmService(uri);
return Tracing(observatory);
}
final vm_service.VmService vmService; final vm_service.VmService vmService;
Future<void> startTracing() async { Future<void> startTracing() async {
......
...@@ -11,10 +11,11 @@ dependencies: ...@@ -11,10 +11,11 @@ dependencies:
# To update these, use "flutter update-packages --force-upgrade". # To update these, use "flutter update-packages --force-upgrade".
archive: 2.0.13 archive: 2.0.13
args: 1.6.0 args: 1.6.0
dwds: 5.0.0
completion: 0.2.2 completion: 0.2.2
coverage: 0.14.0 coverage: 0.14.0
crypto: 2.1.5 crypto: 2.1.5
dds: 1.2.1
dwds: 5.0.0
file: 5.2.1 file: 5.2.1
flutter_template_images: 1.0.1 flutter_template_images: 1.0.1
http: 0.12.1 http: 0.12.1
...@@ -63,6 +64,7 @@ dependencies: ...@@ -63,6 +64,7 @@ dependencies:
http_parser: 3.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" http_parser: 3.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 0.3.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" io: 0.3.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
js: 0.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" js: 0.6.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
json_rpc_2: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 0.11.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" logging: 0.11.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" matcher: 0.12.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 0.9.6+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" mime: 0.9.6+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
...@@ -107,4 +109,4 @@ dartdoc: ...@@ -107,4 +109,4 @@ dartdoc:
# Exclude this package from the hosted API docs. # Exclude this package from the hosted API docs.
nodoc: true nodoc: true
# PUBSPEC CHECKSUM: f9c4 # PUBSPEC CHECKSUM: 7f8b
...@@ -7,6 +7,7 @@ import 'dart:io'; ...@@ -7,6 +7,7 @@ import 'dart:io';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/dds.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/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';
...@@ -71,6 +72,7 @@ void main() { ...@@ -71,6 +72,7 @@ void main() {
FakeDeviceLogReader mockLogReader; FakeDeviceLogReader mockLogReader;
MockPortForwarder portForwarder; MockPortForwarder portForwarder;
MockDartDevelopmentService mockDds;
MockAndroidDevice device; MockAndroidDevice device;
MockHttpClient httpClient; MockHttpClient httpClient;
...@@ -78,6 +80,7 @@ void main() { ...@@ -78,6 +80,7 @@ void main() {
mockLogReader = FakeDeviceLogReader(); mockLogReader = FakeDeviceLogReader();
portForwarder = MockPortForwarder(); portForwarder = MockPortForwarder();
device = MockAndroidDevice(); device = MockAndroidDevice();
mockDds = MockDartDevelopmentService();
when(device.portForwarder) when(device.portForwarder)
.thenReturn(portForwarder); .thenReturn(portForwarder);
when(portForwarder.forward(devicePort, hostPort: anyNamed('hostPort'))) when(portForwarder.forward(devicePort, hostPort: anyNamed('hostPort')))
...@@ -86,6 +89,8 @@ void main() { ...@@ -86,6 +89,8 @@ void main() {
.thenReturn(<ForwardedPort>[ForwardedPort(hostPort, devicePort)]); .thenReturn(<ForwardedPort>[ForwardedPort(hostPort, devicePort)]);
when(portForwarder.unforward(any)) when(portForwarder.unforward(any))
.thenAnswer((_) async => null); .thenAnswer((_) async => null);
when(device.dds).thenReturn(mockDds);
when(mockDds.startDartDevelopmentService(any, false)).thenReturn(null);
final HttpClientRequest httpClientRequest = MockHttpClientRequest(); final HttpClientRequest httpClientRequest = MockHttpClientRequest();
httpClient = MockHttpClient(); httpClient = MockHttpClient();
...@@ -286,11 +291,14 @@ void main() { ...@@ -286,11 +291,14 @@ void main() {
const int hostPort = 42; const int hostPort = 42;
final FakeDeviceLogReader mockLogReader = FakeDeviceLogReader(); final FakeDeviceLogReader mockLogReader = FakeDeviceLogReader();
final MockPortForwarder portForwarder = MockPortForwarder(); final MockPortForwarder portForwarder = MockPortForwarder();
final MockDartDevelopmentService mockDds = MockDartDevelopmentService();
final MockAndroidDevice device = MockAndroidDevice(); final MockAndroidDevice device = MockAndroidDevice();
final MockHotRunner mockHotRunner = MockHotRunner(); final MockHotRunner mockHotRunner = MockHotRunner();
final MockHotRunnerFactory mockHotRunnerFactory = MockHotRunnerFactory(); final MockHotRunnerFactory mockHotRunnerFactory = MockHotRunnerFactory();
when(device.portForwarder) when(device.portForwarder)
.thenReturn(portForwarder); .thenReturn(portForwarder);
when(device.dds)
.thenReturn(mockDds);
when(portForwarder.forward(devicePort, hostPort: anyNamed('hostPort'))) when(portForwarder.forward(devicePort, hostPort: anyNamed('hostPort')))
.thenAnswer((_) async => hostPort); .thenAnswer((_) async => hostPort);
when(portForwarder.forwardedPorts) when(portForwarder.forwardedPorts)
...@@ -309,6 +317,7 @@ void main() { ...@@ -309,6 +317,7 @@ void main() {
)).thenReturn(mockHotRunner); )).thenReturn(mockHotRunner);
when(mockHotRunner.exited).thenReturn(false); when(mockHotRunner.exited).thenReturn(false);
when(mockHotRunner.isWaitingForObservatory).thenReturn(false); when(mockHotRunner.isWaitingForObservatory).thenReturn(false);
when(mockDds.startDartDevelopmentService(any, false)).thenReturn(null);
testDeviceManager.addDevice(device); testDeviceManager.addDevice(device);
when(device.getLogReader(includePastLogs: anyNamed('includePastLogs'))) when(device.getLogReader(includePastLogs: anyNamed('includePastLogs')))
...@@ -359,10 +368,14 @@ void main() { ...@@ -359,10 +368,14 @@ void main() {
const int hostPort = 42; const int hostPort = 42;
final FakeDeviceLogReader mockLogReader = FakeDeviceLogReader(); final FakeDeviceLogReader mockLogReader = FakeDeviceLogReader();
final MockPortForwarder portForwarder = MockPortForwarder(); final MockPortForwarder portForwarder = MockPortForwarder();
final MockDartDevelopmentService mockDds = MockDartDevelopmentService();
final MockIOSDevice device = MockIOSDevice(); final MockIOSDevice device = MockIOSDevice();
final MockHotRunner mockHotRunner = MockHotRunner(); final MockHotRunner mockHotRunner = MockHotRunner();
final MockHotRunnerFactory mockHotRunnerFactory = MockHotRunnerFactory(); final MockHotRunnerFactory mockHotRunnerFactory = MockHotRunnerFactory();
when(device.portForwarder).thenReturn(portForwarder); when(device.portForwarder)
.thenReturn(portForwarder);
when(device.dds)
.thenReturn(mockDds);
when(device.getLogReader(includePastLogs: anyNamed('includePastLogs'))) when(device.getLogReader(includePastLogs: anyNamed('includePastLogs')))
.thenAnswer((_) => mockLogReader); .thenAnswer((_) => mockLogReader);
when(portForwarder.forward(devicePort, hostPort: anyNamed('hostPort'))) when(portForwarder.forward(devicePort, hostPort: anyNamed('hostPort')))
...@@ -383,6 +396,7 @@ void main() { ...@@ -383,6 +396,7 @@ void main() {
)).thenReturn(mockHotRunner); )).thenReturn(mockHotRunner);
when(mockHotRunner.exited).thenReturn(false); when(mockHotRunner.exited).thenReturn(false);
when(mockHotRunner.isWaitingForObservatory).thenReturn(false); when(mockHotRunner.isWaitingForObservatory).thenReturn(false);
when(mockDds.startDartDevelopmentService(any, false)).thenReturn(null);
testDeviceManager.addDevice(device); testDeviceManager.addDevice(device);
...@@ -415,6 +429,7 @@ void main() { ...@@ -415,6 +429,7 @@ void main() {
setUp(() { setUp(() {
portForwarder = MockPortForwarder(); portForwarder = MockPortForwarder();
final MockDartDevelopmentService mockDds = MockDartDevelopmentService();
device = MockAndroidDevice(); device = MockAndroidDevice();
when(device.portForwarder) when(device.portForwarder)
...@@ -425,6 +440,10 @@ void main() { ...@@ -425,6 +440,10 @@ void main() {
.thenReturn(<ForwardedPort>[ForwardedPort(hostPort, devicePort)]); .thenReturn(<ForwardedPort>[ForwardedPort(hostPort, devicePort)]);
when(portForwarder.unforward(any)) when(portForwarder.unforward(any))
.thenAnswer((_) async => null); .thenAnswer((_) async => null);
when(device.dds)
.thenReturn(mockDds);
when(mockDds.startDartDevelopmentService(any, any))
.thenReturn(null);
}); });
testUsingContext('succeeds in ipv4 mode', () async { testUsingContext('succeeds in ipv4 mode', () async {
...@@ -795,6 +814,7 @@ class TestHotRunnerFactory extends HotRunnerFactory { ...@@ -795,6 +814,7 @@ class TestHotRunnerFactory extends HotRunnerFactory {
} }
} }
class MockDartDevelopmentService extends Mock implements DartDevelopmentService {}
class MockProcessManager extends Mock implements ProcessManager {} class MockProcessManager extends Mock implements ProcessManager {}
class MockProcess extends Mock implements Process {} class MockProcess extends Mock implements Process {}
class MockHttpClientRequest extends Mock implements HttpClientRequest {} class MockHttpClientRequest extends Mock implements HttpClientRequest {}
......
...@@ -8,6 +8,7 @@ import 'package:file/memory.dart'; ...@@ -8,6 +8,7 @@ import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart'; import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/android/android_device.dart'; import 'package:flutter_tools/src/android/android_device.dart';
import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/dds.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/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/platform.dart'; import 'package:flutter_tools/src/base/platform.dart';
...@@ -67,6 +68,12 @@ void main() { ...@@ -67,6 +68,12 @@ void main() {
tryToDelete(tempDir); tryToDelete(tempDir);
}); });
void applyDdsMocks(Device device) {
final MockDartDevelopmentService mockDds = MockDartDevelopmentService();
when(device.dds).thenReturn(mockDds);
when(mockDds.startDartDevelopmentService(any, any)).thenReturn(null);
}
testUsingContext('returns 1 when test file is not found', () async { testUsingContext('returns 1 when test file is not found', () async {
testDeviceManager.addDevice(MockDevice()); testDeviceManager.addDevice(MockDevice());
...@@ -188,7 +195,9 @@ void main() { ...@@ -188,7 +195,9 @@ void main() {
}); });
testUsingContext('returns 0 when test ends successfully', () async { testUsingContext('returns 0 when test ends successfully', () async {
testDeviceManager.addDevice(MockAndroidDevice()); final MockAndroidDevice mockDevice = MockAndroidDevice();
applyDdsMocks(mockDevice);
testDeviceManager.addDevice(mockDevice);
final String testApp = globals.fs.path.join(tempDir.path, 'test', 'e2e.dart'); final String testApp = globals.fs.path.join(tempDir.path, 'test', 'e2e.dart');
final String testFile = globals.fs.path.join(tempDir.path, 'test_driver', 'e2e_test.dart'); final String testFile = globals.fs.path.join(tempDir.path, 'test_driver', 'e2e_test.dart');
...@@ -227,7 +236,9 @@ void main() { ...@@ -227,7 +236,9 @@ void main() {
}); });
testUsingContext('returns exitCode set by test runner', () async { testUsingContext('returns exitCode set by test runner', () async {
testDeviceManager.addDevice(MockDevice()); final MockDevice mockDevice = MockDevice();
applyDdsMocks(mockDevice);
testDeviceManager.addDevice(mockDevice);
final String testApp = globals.fs.path.join(tempDir.path, 'test', 'e2e.dart'); final String testApp = globals.fs.path.join(tempDir.path, 'test', 'e2e.dart');
final String testFile = globals.fs.path.join(tempDir.path, 'test_driver', 'e2e_test.dart'); final String testFile = globals.fs.path.join(tempDir.path, 'test_driver', 'e2e_test.dart');
...@@ -374,6 +385,7 @@ void main() { ...@@ -374,6 +385,7 @@ void main() {
Future<Device> appStarterSetup() async { Future<Device> appStarterSetup() async {
final Device mockDevice = MockDevice(); final Device mockDevice = MockDevice();
applyDdsMocks(mockDevice);
testDeviceManager.addDevice(mockDevice); testDeviceManager.addDevice(mockDevice);
final FakeDeviceLogReader mockDeviceLogReader = FakeDeviceLogReader(); final FakeDeviceLogReader mockDeviceLogReader = FakeDeviceLogReader();
...@@ -509,6 +521,7 @@ void main() { ...@@ -509,6 +521,7 @@ void main() {
Future<Device> appStarterSetup() async { Future<Device> appStarterSetup() async {
final Device mockDevice = MockDevice(); final Device mockDevice = MockDevice();
applyDdsMocks(mockDevice);
testDeviceManager.addDevice(mockDevice); testDeviceManager.addDevice(mockDevice);
final FakeDeviceLogReader mockDeviceLogReader = FakeDeviceLogReader(); final FakeDeviceLogReader mockDeviceLogReader = FakeDeviceLogReader();
...@@ -792,5 +805,5 @@ class MockDevice extends Mock implements Device { ...@@ -792,5 +805,5 @@ class MockDevice extends Mock implements Device {
} }
class MockAndroidDevice extends Mock implements AndroidDevice { } class MockAndroidDevice extends Mock implements AndroidDevice { }
class MockDartDevelopmentService extends Mock implements DartDevelopmentService { }
class MockLaunchResult extends Mock implements LaunchResult { } class MockLaunchResult extends Mock implements LaunchResult { }
...@@ -139,6 +139,8 @@ class TestFlutterDevice extends FlutterDevice { ...@@ -139,6 +139,8 @@ class TestFlutterDevice extends FlutterDevice {
ReloadMethod reloadMethod, ReloadMethod reloadMethod,
GetSkSLMethod getSkSLMethod, GetSkSLMethod getSkSLMethod,
PrintStructuredErrorLogMethod printStructuredErrorLogMethod, PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
bool disableDds = false,
bool ipv6 = false,
}) async { }) async {
throw exception; throw exception;
} }
......
...@@ -728,6 +728,7 @@ void main() { ...@@ -728,6 +728,7 @@ void main() {
fuchsiaDevice, fuchsiaDevice,
expectedIsolateName, expectedIsolateName,
(Uri uri) async => fakeVmServiceHost.vmService, (Uri uri) async => fakeVmServiceHost.vmService,
(Device device, Uri uri) => null,
true, // only poll once. true, // only poll once.
); );
......
...@@ -578,6 +578,8 @@ class TestFlutterDevice extends FlutterDevice { ...@@ -578,6 +578,8 @@ class TestFlutterDevice extends FlutterDevice {
ReloadMethod reloadMethod, ReloadMethod reloadMethod,
GetSkSLMethod getSkSLMethod, GetSkSLMethod getSkSLMethod,
PrintStructuredErrorLogMethod printStructuredErrorLogMethod, PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
bool disableDds = false,
bool ipv6 = false,
}) async { }) async {
throw exception; throw exception;
} }
......
...@@ -61,7 +61,7 @@ void main() { ...@@ -61,7 +61,7 @@ void main() {
expect(await fallbackDiscovery.discover( expect(await fallbackDiscovery.discover(
assumedDevicePort: 23, assumedDevicePort: 23,
deivce: null, device: null,
hostVmservicePort: 1, hostVmservicePort: 1,
packageId: null, packageId: null,
usesIpv6: false, usesIpv6: false,
...@@ -86,7 +86,7 @@ void main() { ...@@ -86,7 +86,7 @@ void main() {
}); });
expect(await fallbackDiscovery.discover( expect(await fallbackDiscovery.discover(
assumedDevicePort: 23, assumedDevicePort: 23,
deivce: null, device: null,
hostVmservicePort: 1, hostVmservicePort: 1,
packageId: null, packageId: null,
usesIpv6: false, usesIpv6: false,
...@@ -117,7 +117,7 @@ void main() { ...@@ -117,7 +117,7 @@ void main() {
expect(await fallbackDiscovery.discover( expect(await fallbackDiscovery.discover(
assumedDevicePort: 23, assumedDevicePort: 23,
deivce: null, device: null,
hostVmservicePort: 1, hostVmservicePort: 1,
packageId: 'hello', packageId: 'hello',
usesIpv6: false, usesIpv6: false,
...@@ -139,7 +139,7 @@ void main() { ...@@ -139,7 +139,7 @@ void main() {
expect(await fallbackDiscovery.discover( expect(await fallbackDiscovery.discover(
assumedDevicePort: 23, assumedDevicePort: 23,
deivce: null, device: null,
hostVmservicePort: 1, hostVmservicePort: 1,
packageId: 'hello', packageId: 'hello',
usesIpv6: false, usesIpv6: false,
...@@ -161,7 +161,7 @@ void main() { ...@@ -161,7 +161,7 @@ void main() {
expect(await fallbackDiscovery.discover( expect(await fallbackDiscovery.discover(
assumedDevicePort: 23, assumedDevicePort: 23,
deivce: null, device: null,
hostVmservicePort: 1, hostVmservicePort: 1,
packageId: 'hello', packageId: 'hello',
usesIpv6: false, usesIpv6: false,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter_tools/src/base/dds.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:vm_service/vm_service.dart' as vm_service; import 'package:vm_service/vm_service.dart' as vm_service;
import 'package:file/memory.dart'; import 'package:file/memory.dart';
...@@ -1645,8 +1646,11 @@ void main() { ...@@ -1645,8 +1646,11 @@ void main() {
testUsingContext('connect sets up log reader', () => testbed.run(() async { testUsingContext('connect sets up log reader', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]); fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
final MockDevice mockDevice = MockDevice(); final MockDevice mockDevice = MockDevice();
final MockDartDevelopmentService mockDds = MockDartDevelopmentService();
final MockDeviceLogReader mockLogReader = MockDeviceLogReader(); final MockDeviceLogReader mockLogReader = MockDeviceLogReader();
when(mockDevice.getLogReader(app: anyNamed('app'))).thenReturn(mockLogReader); when(mockDevice.getLogReader(app: anyNamed('app'))).thenReturn(mockLogReader);
when(mockDevice.dds).thenReturn(mockDds);
when(mockDds.startDartDevelopmentService(any, any)).thenReturn(null);
final TestFlutterDevice flutterDevice = TestFlutterDevice( final TestFlutterDevice flutterDevice = TestFlutterDevice(
mockDevice, mockDevice,
...@@ -1678,6 +1682,7 @@ void main() { ...@@ -1678,6 +1682,7 @@ void main() {
} }
class MockFlutterDevice extends Mock implements FlutterDevice {} class MockFlutterDevice extends Mock implements FlutterDevice {}
class MockDartDevelopmentService extends Mock implements DartDevelopmentService {}
class MockVMService extends Mock implements vm_service.VmService {} class MockVMService extends Mock implements vm_service.VmService {}
class MockDevFS extends Mock implements DevFS {} class MockDevFS extends Mock implements DevFS {}
class MockDevice extends Mock implements Device {} class MockDevice extends Mock implements Device {}
......
...@@ -21,7 +21,14 @@ void main() { ...@@ -21,7 +21,14 @@ void main() {
tempDir = createResolvedTempDirectorySync('attach_test.'); tempDir = createResolvedTempDirectorySync('attach_test.');
await _project.setUpIn(tempDir); await _project.setUpIn(tempDir);
_flutterRun = FlutterRunTestDriver(tempDir, logPrefix: ' RUN '); _flutterRun = FlutterRunTestDriver(tempDir, logPrefix: ' RUN ');
_flutterAttach = FlutterRunTestDriver(tempDir, logPrefix: 'ATTACH '); _flutterAttach = FlutterRunTestDriver(
tempDir,
logPrefix: 'ATTACH ',
// Only one DDS instance can be connected to the VM service at a time.
// DDS can also only initialize if the VM service doesn't have any existing
// clients, so we'll just let _flutterRun be responsible for spawning DDS.
spawnDdsInstance: false,
);
}); });
tearDown(() async { tearDown(() async {
...@@ -58,7 +65,11 @@ void main() { ...@@ -58,7 +65,11 @@ void main() {
await _flutterRun.run(withDebugger: true); await _flutterRun.run(withDebugger: true);
await _flutterAttach.attach(_flutterRun.vmServicePort); await _flutterAttach.attach(_flutterRun.vmServicePort);
await _flutterAttach.quit(); await _flutterAttach.quit();
_flutterAttach = FlutterRunTestDriver(tempDir, logPrefix: 'ATTACH-2'); _flutterAttach = FlutterRunTestDriver(
tempDir,
logPrefix: 'ATTACH-2',
spawnDdsInstance: false,
);
await _flutterAttach.attach(_flutterRun.vmServicePort); await _flutterAttach.attach(_flutterRun.vmServicePort);
await _flutterAttach.hotReload(); await _flutterAttach.hotReload();
}); });
......
...@@ -25,7 +25,6 @@ void main() { ...@@ -25,7 +25,6 @@ void main() {
}); });
tearDown(() async { tearDown(() async {
await _flutter.stop();
tryToDelete(tempDir); tryToDelete(tempDir);
}); });
...@@ -51,7 +50,6 @@ void main() { ...@@ -51,7 +50,6 @@ void main() {
// Complete anyway in case we don't see the 'Another exception' line. // Complete anyway in case we don't see the 'Another exception' line.
completer.complete(); completer.complete();
}); });
await _flutter.stop(); await _flutter.stop();
expect(stdout.toString(), contains(_exceptionStart)); expect(stdout.toString(), contains(_exceptionStart));
...@@ -62,7 +60,6 @@ void main() { ...@@ -62,7 +60,6 @@ void main() {
await _flutter.run(startPaused: true, withDebugger: true, structuredErrors: true, chrome: true); await _flutter.run(startPaused: true, withDebugger: true, structuredErrors: true, chrome: true);
await _flutter.resume(); await _flutter.resume();
final Completer<void> completer = Completer<void>(); final Completer<void> completer = Completer<void>();
bool lineFound = false; bool lineFound = false;
......
...@@ -428,6 +428,7 @@ class FlutterRunTestDriver extends FlutterTestDriver { ...@@ -428,6 +428,7 @@ class FlutterRunTestDriver extends FlutterTestDriver {
FlutterRunTestDriver( FlutterRunTestDriver(
Directory projectFolder, { Directory projectFolder, {
String logPrefix, String logPrefix,
this.spawnDdsInstance = true,
}) : super(projectFolder, logPrefix: logPrefix); }) : super(projectFolder, logPrefix: logPrefix);
String _currentRunningAppId; String _currentRunningAppId;
...@@ -447,6 +448,8 @@ class FlutterRunTestDriver extends FlutterTestDriver { ...@@ -447,6 +448,8 @@ class FlutterRunTestDriver extends FlutterTestDriver {
'run', 'run',
if (!chrome) if (!chrome)
'--disable-service-auth-codes', '--disable-service-auth-codes',
if (!spawnDdsInstance)
'--disable-dds',
'--machine', '--machine',
'-d', '-d',
if (chrome) if (chrome)
...@@ -479,6 +482,8 @@ class FlutterRunTestDriver extends FlutterTestDriver { ...@@ -479,6 +482,8 @@ class FlutterRunTestDriver extends FlutterTestDriver {
<String>[ <String>[
'attach', 'attach',
'--machine', '--machine',
if (!spawnDdsInstance)
'--disable-dds',
'-d', '-d',
'flutter-tester', 'flutter-tester',
'--debug-port', '--debug-port',
...@@ -680,6 +685,8 @@ class FlutterRunTestDriver extends FlutterTestDriver { ...@@ -680,6 +685,8 @@ class FlutterRunTestDriver extends FlutterTestDriver {
void _throwErrorResponse(String message) { void _throwErrorResponse(String message) {
throw '$message\n\n$_lastResponse\n\n${_errorBuffer.toString()}'.trim(); throw '$message\n\n$_lastResponse\n\n${_errorBuffer.toString()}'.trim();
} }
final bool spawnDdsInstance;
} }
class FlutterTestTestDriver extends FlutterTestDriver { class FlutterTestTestDriver extends FlutterTestDriver {
......
...@@ -39,6 +39,15 @@ void main() { ...@@ -39,6 +39,15 @@ void main() {
tryToDelete(tempDir); tryToDelete(tempDir);
}); });
test('getSupportedProtocols includes DDS', () async {
final ProtocolList protocolList =
await vmService.getSupportedProtocols();
expect(protocolList.protocols, hasLength(2));
for (final Protocol protocol in protocolList.protocols) {
expect(protocol.protocolName, anyOf('VM Service', 'DDS'));
}
});
test('flutterVersion can be called', () async { test('flutterVersion can be called', () async {
final Response response = final Response response =
await vmService.callServiceExtension('s0.flutterVersion'); await vmService.callServiceExtension('s0.flutterVersion');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment