[flutter_tools] move service extensions off of deprecated vm service (#55012)
diff --git a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart index e856412..26f1dbd 100644 --- a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart +++ b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
@@ -34,6 +34,7 @@ import '../reporting/reporting.dart'; import '../resident_runner.dart'; import '../run_hot.dart'; +import '../vmservice.dart'; import '../web/chrome.dart'; import '../web/compile.dart'; import '../web/web_device.dart'; @@ -195,9 +196,10 @@ @override Future<void> debugDumpApp() async { try { - await _vmService?.callServiceExtension( - 'ext.flutter.debugDumpApp', - ); + await _vmService + ?.flutterDebugDumpApp( + isolateId: null, + ); } on vmservice.RPCError { return; } @@ -206,9 +208,10 @@ @override Future<void> debugDumpRenderTree() async { try { - await _vmService?.callServiceExtension( - 'ext.flutter.debugDumpRenderTree', - ); + await _vmService + ?.flutterDebugDumpRenderTree( + isolateId: null, + ); } on vmservice.RPCError { return; } @@ -217,9 +220,10 @@ @override Future<void> debugDumpLayerTree() async { try { - await _vmService?.callServiceExtension( - 'ext.flutter.debugDumpLayerTree', - ); + await _vmService + ?.flutterDebugDumpLayerTree( + isolateId: null, + ); } on vmservice.RPCError { return; } @@ -228,8 +232,10 @@ @override Future<void> debugDumpSemanticsTreeInTraversalOrder() async { try { - await _vmService?.callServiceExtension( - 'ext.flutter.debugDumpSemanticsTreeInTraversalOrder'); + await _vmService + ?.flutterDebugDumpSemanticsTreeInTraversalOrder( + isolateId: null, + ); } on vmservice.RPCError { return; } @@ -238,14 +244,16 @@ @override Future<void> debugTogglePlatform() async { try { - final vmservice.Response response = await _vmService - ?.callServiceExtension('ext.flutter.platformOverride'); - final String currentPlatform = response.json['value'] as String; + final String currentPlatform = await _vmService + ?.flutterPlatformOverride( + isolateId: null, + ); final String platform = nextPlatform(currentPlatform, featureFlags); - await _vmService?.callServiceExtension('ext.flutter.platformOverride', - args: <String, Object>{ - 'value': platform, - }); + await _vmService + ?.flutterPlatformOverride( + platform: platform, + isolateId: null, + ); globals.printStatus('Switched operating system to $platform'); } on vmservice.RPCError { return; @@ -261,8 +269,10 @@ @override Future<void> debugDumpSemanticsTreeInInverseHitTestOrder() async { try { - await _vmService?.callServiceExtension( - 'ext.flutter.debugDumpSemanticsTreeInInverseHitTestOrder'); + await _vmService + ?.flutterDebugDumpSemanticsTreeInInverseHitTestOrder( + isolateId: null, + ); } on vmservice.RPCError { return; } @@ -271,16 +281,10 @@ @override Future<void> debugToggleDebugPaintSizeEnabled() async { try { - final vmservice.Response response = - await _vmService?.callServiceExtension( - 'ext.flutter.debugPaint', - ); - await _vmService?.callServiceExtension( - 'ext.flutter.debugPaint', - args: <dynamic, dynamic>{ - 'enabled': !(response.json['enabled'] == 'true') - }, - ); + await _vmService + ?.flutterToggleDebugPaintSizeEnabled( + isolateId: null, + ); } on vmservice.RPCError { return; } @@ -289,16 +293,10 @@ @override Future<void> debugToggleDebugCheckElevationsEnabled() async { try { - final vmservice.Response response = - await _vmService?.callServiceExtension( - 'ext.flutter.debugCheckElevationsEnabled', - ); - await _vmService?.callServiceExtension( - 'ext.flutter.debugCheckElevationsEnabled', - args: <dynamic, dynamic>{ - 'enabled': !(response.json['enabled'] == 'true') - }, - ); + await _vmService + ?.flutterToggleDebugCheckElevationsEnabled( + isolateId: null, + ); } on vmservice.RPCError { return; } @@ -307,14 +305,10 @@ @override Future<void> debugTogglePerformanceOverlayOverride() async { try { - final vmservice.Response response = await _vmService - ?.callServiceExtension('ext.flutter.showPerformanceOverlay'); - await _vmService?.callServiceExtension( - 'ext.flutter.showPerformanceOverlay', - args: <dynamic, dynamic>{ - 'enabled': !(response.json['enabled'] == 'true') - }, - ); + await _vmService + ?.flutterTogglePerformanceOverlayOverride( + isolateId: null, + ); } on vmservice.RPCError { return; } @@ -323,14 +317,10 @@ @override Future<void> debugToggleWidgetInspector() async { try { - final vmservice.Response response = await _vmService - ?.callServiceExtension('ext.flutter.debugToggleWidgetInspector'); - await _vmService?.callServiceExtension( - 'ext.flutter.debugToggleWidgetInspector', - args: <dynamic, dynamic>{ - 'enabled': !(response.json['enabled'] == 'true') - }, - ); + await _vmService + ?.flutterToggleWidgetInspector( + isolateId: null, + ); } on vmservice.RPCError { return; } @@ -339,14 +329,10 @@ @override Future<void> debugToggleProfileWidgetBuilds() async { try { - final vmservice.Response response = await _vmService - ?.callServiceExtension('ext.flutter.profileWidgetBuilds'); - await _vmService?.callServiceExtension( - 'ext.flutter.profileWidgetBuilds', - args: <dynamic, dynamic>{ - 'enabled': !(response.json['enabled'] == 'true') - }, - ); + await _vmService + ?.flutterToggleProfileWidgetBuilds( + isolateId: null, + ); } on vmservice.RPCError { return; } @@ -674,6 +660,14 @@ _connectionResult = await webDevFS.connect(useDebugExtension); unawaited(_connectionResult.debugConnection.onDone.whenComplete(_cleanupAndExit)); + _stdOutSub = _vmService.onStdoutEvent.listen((vmservice.Event log) { + final String message = utf8.decode(base64.decode(log.bytes)); + globals.printStatus(message, newline: false); + }); + _stdErrSub = _vmService.onStderrEvent.listen((vmservice.Event log) { + final String message = utf8.decode(base64.decode(log.bytes)); + globals.printStatus(message, newline: false); + }); try { await _vmService.streamListen(vmservice.EventStreams.kStdout); } on vmservice.RPCError { @@ -692,14 +686,6 @@ // It is safe to ignore this error because we expect an error to be // thrown if we're not already subscribed. } - _stdOutSub = _vmService.onStdoutEvent.listen((vmservice.Event log) { - final String message = utf8.decode(base64.decode(log.bytes)); - globals.printStatus(message, newline: false); - }); - _stdErrSub = _vmService.onStderrEvent.listen((vmservice.Event log) { - final String message = utf8.decode(base64.decode(log.bytes)); - globals.printStatus(message, newline: false); - }); unawaited(_vmService.registerService('reloadSources', 'FlutterTools')); _vmService.registerServiceCallback('reloadSources', (Map<String, Object> params) async { final bool pause = params['pause'] as bool ?? false;
diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart index 3286a17..976e941 100644 --- a/packages/flutter_tools/lib/src/device.dart +++ b/packages/flutter_tools/lib/src/device.dart
@@ -6,6 +6,7 @@ import 'dart:math' as math; import 'package:meta/meta.dart'; +import 'package:vm_service/vm_service.dart' as vm_service; import 'android/android_device_discovery.dart'; import 'android/android_workflow.dart'; @@ -25,7 +26,6 @@ import 'macos/macos_device.dart'; import 'project.dart'; import 'tester/flutter_tester.dart'; -import 'vmservice.dart'; import 'web/web_device.dart'; import 'windows/windows_device.dart'; @@ -755,7 +755,7 @@ /// Some logs can be obtained from a VM service stream. /// Set this after the VM services are connected. - VMService connectedVMService; + vm_service.VmService connectedVMService; @override String toString() => name; @@ -785,7 +785,7 @@ int appPid; @override - VMService connectedVMService; + vm_service.VmService connectedVMService; @override Stream<String> get logLines => const Stream<String>.empty();
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart index 4a35480..0bfd341 100644 --- a/packages/flutter_tools/lib/src/ios/devices.dart +++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -24,7 +24,6 @@ import '../mdns_discovery.dart'; import '../project.dart'; import '../protocol_discovery.dart'; -import '../vmservice.dart'; import 'fallback_discovery.dart'; import 'ios_deploy.dart'; import 'ios_workflow.dart'; @@ -561,18 +560,18 @@ Stream<String> get logLines => _linesController.stream; @override - VMService get connectedVMService => _connectedVMService; - VMService _connectedVMService; + vm_service.VmService get connectedVMService => _connectedVMService; + vm_service.VmService _connectedVMService; @override - set connectedVMService(VMService connectedVmService) { + set connectedVMService(vm_service.VmService connectedVmService) { _listenToUnifiedLoggingEvents(connectedVmService); _connectedVMService = connectedVmService; } static const int _minimumUniversalLoggingSdkVersion = 13; - Future<void> _listenToUnifiedLoggingEvents(VMService connectedVmService) async { + Future<void> _listenToUnifiedLoggingEvents(vm_service.VmService connectedVmService) async { if (_majorSdkVersion < _minimumUniversalLoggingSdkVersion) { return; }
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index 816e488..0650e27 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -152,7 +152,7 @@ final ResidentCompiler generator; final BuildInfo buildInfo; Stream<Uri> observatoryUris; - VMService vmService; + vm_service.VmService vmService; DevFS devFS; ApplicationPackage package; List<String> fileSystemRoots; @@ -226,24 +226,28 @@ return completer.future; } + // TODO(jonahwilliams): remove once all callsites are updated. + VMService get flutterDeprecatedVmService => vmService as VMService; + Future<void> refreshViews() async { if (vmService == null) { return; } - await vmService.vm.refreshViews(waitForViews: true); + await flutterDeprecatedVmService.vm.refreshViews(waitForViews: true); } List<FlutterView> get views { - if (vmService == null || vmService.isClosed) { + if (vmService == null || flutterDeprecatedVmService.isClosed) { return <FlutterView>[]; } + return (viewFilter != null - ? vmService.vm.allViewsWithName(viewFilter) - : vmService.vm.views).toList(); + ? flutterDeprecatedVmService.vm.allViewsWithName(viewFilter) + : flutterDeprecatedVmService.vm.views).toList(); } - Future<void> getVMs() => vmService.getVMOld(); + Future<void> getVMs() => flutterDeprecatedVmService.getVMOld(); Future<void> exitApps() async { if (!device.supportsFlutterExit) { @@ -270,7 +274,9 @@ for (final FlutterView view in flutterViews) { if (view != null && view.uiIsolate != null) { assert(!view.uiIsolate.pauseEvent.isPauseEvent); - futures.add(view.uiIsolate.flutterExit()); + futures.add(vmService.flutterExit( + isolateId: view.uiIsolate.id, + )); } } // The flutterExit message only returns if it fails, so just wait a few @@ -286,7 +292,7 @@ }) { // One devFS per device. Shared by all running instances. devFS = DevFS( - vmService, + flutterDeprecatedVmService, fsName, rootDirectory, osUtils: globals.os, @@ -301,7 +307,7 @@ final String deviceEntryUri = devFS.baseUri .resolveUri(globals.fs.path.toUri(entryPath)).toString(); return <Future<vm_service.ReloadReport>>[ - for (final Isolate isolate in vmService.vm.isolates) + for (final Isolate isolate in flutterDeprecatedVmService.vm.isolates) vmService.reloadSources( isolate.id, pause: pause, @@ -325,68 +331,91 @@ Future<void> debugDumpApp() async { for (final FlutterView view in views) { - await view.uiIsolate.flutterDebugDumpApp(); + await vmService.flutterDebugDumpApp( + isolateId: view.uiIsolate.id, + ); } } Future<void> debugDumpRenderTree() async { for (final FlutterView view in views) { - await view.uiIsolate.flutterDebugDumpRenderTree(); + await vmService.flutterDebugDumpRenderTree( + isolateId: view.uiIsolate.id, + ); } } Future<void> debugDumpLayerTree() async { for (final FlutterView view in views) { - await view.uiIsolate.flutterDebugDumpLayerTree(); + await vmService.flutterDebugDumpLayerTree( + isolateId: view.uiIsolate.id, + ); } } Future<void> debugDumpSemanticsTreeInTraversalOrder() async { for (final FlutterView view in views) { - await view.uiIsolate.flutterDebugDumpSemanticsTreeInTraversalOrder(); + await vmService.flutterDebugDumpSemanticsTreeInTraversalOrder( + isolateId: view.uiIsolate.id, + ); } } Future<void> debugDumpSemanticsTreeInInverseHitTestOrder() async { for (final FlutterView view in views) { - await view.uiIsolate.flutterDebugDumpSemanticsTreeInInverseHitTestOrder(); + await vmService.flutterDebugDumpSemanticsTreeInInverseHitTestOrder( + isolateId: view.uiIsolate.id, + ); } } Future<void> toggleDebugPaintSizeEnabled() async { for (final FlutterView view in views) { - await view.uiIsolate.flutterToggleDebugPaintSizeEnabled(); + await vmService.flutterToggleDebugPaintSizeEnabled( + isolateId: view.uiIsolate.id, + ); } } Future<void> toggleDebugCheckElevationsEnabled() async { for (final FlutterView view in views) { - await view.uiIsolate.flutterToggleDebugCheckElevationsEnabled(); + await vmService.flutterToggleDebugCheckElevationsEnabled( + isolateId: view.uiIsolate.id, + ); } } Future<void> debugTogglePerformanceOverlayOverride() async { for (final FlutterView view in views) { - await view.uiIsolate.flutterTogglePerformanceOverlayOverride(); + await vmService.flutterTogglePerformanceOverlayOverride( + isolateId: view.uiIsolate.id, + ); } } Future<void> toggleWidgetInspector() async { for (final FlutterView view in views) { - await view.uiIsolate.flutterToggleWidgetInspector(); + await vmService.flutterToggleWidgetInspector( + isolateId: view.uiIsolate.id, + ); } } Future<void> toggleProfileWidgetBuilds() async { for (final FlutterView view in views) { - await view.uiIsolate.flutterToggleProfileWidgetBuilds(); + await vmService.flutterToggleProfileWidgetBuilds( + isolateId: view.uiIsolate.id, + ); } } Future<String> togglePlatform({ String from }) async { final String to = nextPlatform(from, featureFlags); for (final FlutterView view in views) { - await view.uiIsolate.flutterPlatformOverride(to); + await vmService.flutterPlatformOverride( + platform: to, + isolateId: view.uiIsolate.id, + ); } return to; } @@ -416,7 +445,9 @@ } Future<void> initLogReader() async { - (await device.getLogReader(app: package)).appPid = vmService.vm.pid; + final vm_service.VM vm = await vmService.getVM(); + final DeviceLogReader logReader = await device.getLogReader(app: package); + logReader.appPid = vm.pid; } Future<int> runHot({ @@ -721,8 +752,16 @@ String method, { Map<String, dynamic> params, }) { - return flutterDevices.first.views.first.uiIsolate - .invokeFlutterExtensionRpcRaw(method, params: params); + return flutterDevices + .first + .vmService + .invokeFlutterExtensionRpcRaw( + method, + args: params, + isolateId: flutterDevices + .first.views + .first.uiIsolate.id + ); } /// Whether this runner can hot reload. @@ -812,7 +851,7 @@ void writeVmserviceFile() { if (debuggingOptions.vmserviceOutFile != null) { try { - final String address = flutterDevices.first.vmService.wsAddress.toString(); + final String address = flutterDevices.first.flutterDeprecatedVmService.wsAddress.toString(); final File vmserviceOutFile = globals.fs.file(debuggingOptions.vmserviceOutFile); vmserviceOutFile.createSync(recursive: true); vmserviceOutFile.writeAsStringSync(address); @@ -944,7 +983,10 @@ await device.refreshViews(); try { for (final FlutterView view in device.views) { - await view.uiIsolate.flutterDebugAllowBanner(false); + await device.vmService.flutterDebugAllowBanner( + false, + isolateId: view.uiIsolate.id, + ); } } on Exception catch (error) { status.cancel(); @@ -958,7 +1000,10 @@ if (supportsServiceProtocol && isRunningDebug) { try { for (final FlutterView view in device.views) { - await view.uiIsolate.flutterDebugAllowBanner(true); + await device.vmService.flutterDebugAllowBanner( + true, + isolateId: view.uiIsolate.id, + ); } } on Exception catch (error) { status.cancel(); @@ -980,7 +1025,12 @@ Future<void> debugTogglePlatform() async { await refreshViews(); - final String from = await flutterDevices[0].views[0].uiIsolate.flutterPlatformOverride(); + final String isolateId = flutterDevices + .first.views.first.uiIsolate.id; + final String from = await flutterDevices + .first.vmService.flutterPlatformOverride( + isolateId: isolateId, + ); String to; for (final FlutterDevice device in flutterDevices) { to = await device.togglePlatform(from: from); @@ -1039,7 +1089,7 @@ // This hooks up callbacks for when the connection stops in the future. // We don't want to wait for them. We don't handle errors in those callbacks' // futures either because they just print to logger and is not critical. - unawaited(device.vmService.done.then<void>( + unawaited(device.vmService.onDone.then<void>( _serviceProtocolDone, onError: _serviceProtocolError, ).whenComplete(_serviceDisconnected)); @@ -1056,7 +1106,7 @@ <String, dynamic>{ 'reuseWindows': true, }, - flutterDevices.first.vmService.httpAddress, + flutterDevices.first.flutterDeprecatedVmService.httpAddress, 'http://${_devtoolsServer.address.host}:${_devtoolsServer.port}', false, // headless mode, false, // machine mode
diff --git a/packages/flutter_tools/lib/src/run_cold.dart b/packages/flutter_tools/lib/src/run_cold.dart index 1779426..1b84279 100644 --- a/packages/flutter_tools/lib/src/run_cold.dart +++ b/packages/flutter_tools/lib/src/run_cold.dart
@@ -83,8 +83,8 @@ if (flutterDevices.first.observatoryUris != null) { // For now, only support one debugger connection. connectionInfoCompleter?.complete(DebugConnectionInfo( - httpUri: flutterDevices.first.vmService.httpAddress, - wsUri: flutterDevices.first.vmService.wsAddress, + httpUri: flutterDevices.first.flutterDeprecatedVmService.httpAddress, + wsUri: flutterDevices.first.flutterDeprecatedVmService.wsAddress, )); } @@ -105,7 +105,7 @@ if (device.vmService != null) { globals.printStatus('Tracing startup on ${device.device.name}.'); await downloadStartupTrace( - device.vmService, + device.flutterDeprecatedVmService, awaitFirstFrame: awaitFirstFrameWhenTracing, ); } @@ -197,7 +197,7 @@ // Caution: This log line is parsed by device lab tests. globals.printStatus( 'An Observatory debugger and profiler on $dname is available at: ' - '${device.vmService.httpAddress}', + '${device.flutterDeprecatedVmService.httpAddress}', ); } }
diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index 55094f4..9b11efe 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart
@@ -205,7 +205,10 @@ for (final FlutterDevice device in flutterDevices) { for (final FlutterView view in device.views) { - await view.uiIsolate.flutterFastReassemble(classId); + await device.vmService.flutterFastReassemble( + classId, + isolateId: view.uiIsolate.id, + ); } } @@ -260,8 +263,8 @@ // Only handle one debugger connection. connectionInfoCompleter.complete( DebugConnectionInfo( - httpUri: flutterDevices.first.vmService.httpAddress, - wsUri: flutterDevices.first.vmService.wsAddress, + httpUri: flutterDevices.first.flutterDeprecatedVmService.httpAddress, + wsUri: flutterDevices.first.flutterDeprecatedVmService.wsAddress, baseUri: baseUris.first.toString(), ), ); @@ -570,7 +573,7 @@ // The engine handles killing and recreating isolates that it has spawned // ("uiIsolates"). The isolates that were spawned from these uiIsolates // will not be restared, and so they must be manually killed. - for (final Isolate isolate in device?.vmService?.vm?.isolates ?? <Isolate>[]) { + for (final Isolate isolate in device?.flutterDeprecatedVmService?.vm?.isolates ?? <Isolate>[]) { if (!uiIsolates.contains(isolate)) { operations.add(isolate.invokeRpcRaw('kill', params: <String, dynamic>{ 'isolateId': isolate.id, @@ -938,10 +941,16 @@ } await Future.wait(allDevices); - // Check if any isolates are paused. + globals.printTrace('Evicting dirty assets'); + await _evictDirtyAssets(); + + // Check if any isolates are paused and reassemble those + // that aren't. final List<FlutterView> reassembleViews = <FlutterView>[]; + final List<Future<void>> reassembleFutures = <Future<void>>[]; String serviceEventKind; int pausedIsolatesFound = 0; + bool failedReassemble = false; for (final FlutterDevice device in flutterDevices) { for (final FlutterView view in device.views) { // Check if the isolate is paused, and if so, don't reassemble. Ignore the @@ -956,6 +965,12 @@ } } else { reassembleViews.add(view); + reassembleFutures.add(device.vmService.flutterReassemble( + isolateId: view.uiIsolate.id, + ).catchError((dynamic error) { + failedReassemble = true; + globals.printError('Reassembling ${view.uiIsolate.name} failed: $error'); + }, test: (dynamic error) => error is Exception)); } } } @@ -968,24 +983,10 @@ return OperationResult(OperationResult.ok.code, reloadMessage); } } - globals.printTrace('Evicting dirty assets'); - await _evictDirtyAssets(); assert(reassembleViews.isNotEmpty); + globals.printTrace('Reassembling application'); - bool failedReassemble = false; - final List<Future<void>> futures = <Future<void>>[ - for (final FlutterView view in reassembleViews) - () async { - try { - await view.uiIsolate.flutterReassemble(); - } on Exception catch (error) { - failedReassemble = true; - globals.printError('Reassembling ${view.uiIsolate.name} failed: $error'); - return; - } - }(), - ]; - final Future<void> reassembleFuture = Future.wait<void>(futures); + final Future<void> reassembleFuture = Future.wait<void>(reassembleFutures); await reassembleFuture.timeout( const Duration(seconds: 2), onTimeout: () async { @@ -1128,7 +1129,7 @@ // Caution: This log line is parsed by device lab tests. globals.printStatus( 'An Observatory debugger and profiler on $dname is available at: ' - '${device.vmService.httpAddress}', + '${device.flutterDeprecatedVmService.httpAddress}', ); } } @@ -1144,7 +1145,13 @@ continue; } for (final String assetPath in device.devFS.assetPathsToEvict) { - futures.add(device.views.first.uiIsolate.flutterEvictAsset(assetPath)); + futures.add( + device.views.first.uiIsolate.vmService + .flutterEvictAsset( + assetPath, + isolateId: device.views.first.uiIsolate.id, + ) + ); } device.devFS.assetPathsToEvict.clear(); }
diff --git a/packages/flutter_tools/lib/src/tracing.dart b/packages/flutter_tools/lib/src/tracing.dart index 5ea6cfb..aa41645 100644 --- a/packages/flutter_tools/lib/src/tracing.dart +++ b/packages/flutter_tools/lib/src/tracing.dart
@@ -54,7 +54,10 @@ }); bool done = false; for (final FlutterView view in vmService.vm.views) { - if (await view.uiIsolate.flutterAlreadyPaintedFirstUsefulFrame()) { + if (await view.uiIsolate.vmService + .flutterAlreadyPaintedFirstUsefulFrame( + isolateId: view.uiIsolate.id, + )) { done = true; break; }
diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart index 3de2238..75b6f92 100644 --- a/packages/flutter_tools/lib/src/vmservice.dart +++ b/packages/flutter_tools/lib/src/vmservice.dart
@@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:math' as math; import 'package:meta/meta.dart' show required; import 'package:vm_service/vm_service.dart' as vm_service; @@ -476,6 +475,18 @@ return _delegateService.callMethod(method, isolateId: isolateId, args: args); } + @override + Future<void> get onDone => _delegateService.onDone; + + @override + Future<vm_service.Response> callServiceExtension(String method, + {String isolateId, Map<Object, Object> args}) { + return _delegateService.callServiceExtension(method, isolateId: isolateId, args: args); + } + + @override + Future<vm_service.VM> getVM() => _delegateService.getVM(); + StreamController<ServiceEvent> _getEventController(String eventName) { StreamController<ServiceEvent> controller = _eventControllers[eventName]; if (controller == null) { @@ -890,7 +901,6 @@ _upgradeCollection(map, this); _loaded = true; - _pid = map['pid'] as int; if (map['_heapAllocatedMemoryUsage'] != null) { _heapAllocatedMemoryUsage = map['_heapAllocatedMemoryUsage'] as int; } @@ -910,10 +920,6 @@ /// The set of live views. final Map<String, FlutterView> _viewCache = <String, FlutterView>{}; - /// The pid of the VM's process. - int _pid; - int get pid => _pid; - /// The number of bytes allocated (e.g. by malloc) in the native heap. int _heapAllocatedMemoryUsage; int get heapAllocatedMemoryUsage => _heapAllocatedMemoryUsage ?? 0; @@ -1131,44 +1137,6 @@ } } -class HeapSpace extends ServiceObject { - HeapSpace._empty(ServiceObjectOwner owner) : super._empty(owner); - - int _used = 0; - int _capacity = 0; - int _external = 0; - int _collections = 0; - double _totalCollectionTimeInSeconds = 0.0; - double _averageCollectionPeriodInMillis = 0.0; - - int get used => _used; - int get capacity => _capacity; - int get external => _external; - - Duration get avgCollectionTime { - final double mcs = _totalCollectionTimeInSeconds * - Duration.microsecondsPerSecond / - math.max(_collections, 1); - return Duration(microseconds: mcs.ceil()); - } - - Duration get avgCollectionPeriod { - final double mcs = _averageCollectionPeriodInMillis * - Duration.microsecondsPerMillisecond; - return Duration(microseconds: mcs.ceil()); - } - - @override - void _update(Map<String, dynamic> map, bool mapIsRef) { - _used = map['used'] as int; - _capacity = map['capacity'] as int; - _external = map['external'] as int; - _collections = map['collections'] as int; - _totalCollectionTimeInSeconds = map['time'] as double; - _averageCollectionPeriodInMillis = map['avgCollectionPeriodMillis'] as double; - } -} - /// An isolate running inside the VM. Instances of the Isolate class are always /// canonicalized. class Isolate extends ServiceObjectOwner { @@ -1250,118 +1218,6 @@ pauseEvent = map['pauseEvent'] as ServiceEvent; } - // Flutter extension methods. - - // Invoke a flutter extension method, if the flutter extension is not - // available, returns null. - Future<Map<String, dynamic>> invokeFlutterExtensionRpcRaw( - String method, { - Map<String, dynamic> params, - }) async { - try { - return await invokeRpcRaw(method, params: params); - } on vm_service.RPCError catch (err) { - // If an application is not using the framework - if (err.code == RPCErrorCodes.kMethodNotFound) { - return null; - } - rethrow; - } - } - - Future<Map<String, dynamic>> flutterDebugDumpApp() { - return invokeFlutterExtensionRpcRaw('ext.flutter.debugDumpApp'); - } - - Future<Map<String, dynamic>> flutterDebugDumpRenderTree() { - return invokeFlutterExtensionRpcRaw('ext.flutter.debugDumpRenderTree'); - } - - Future<Map<String, dynamic>> flutterDebugDumpLayerTree() { - return invokeFlutterExtensionRpcRaw('ext.flutter.debugDumpLayerTree'); - } - - Future<Map<String, dynamic>> flutterDebugDumpSemanticsTreeInTraversalOrder() { - return invokeFlutterExtensionRpcRaw('ext.flutter.debugDumpSemanticsTreeInTraversalOrder'); - } - - Future<Map<String, dynamic>> flutterDebugDumpSemanticsTreeInInverseHitTestOrder() { - return invokeFlutterExtensionRpcRaw('ext.flutter.debugDumpSemanticsTreeInInverseHitTestOrder'); - } - - Future<Map<String, dynamic>> _flutterToggle(String name) async { - Map<String, dynamic> state = await invokeFlutterExtensionRpcRaw('ext.flutter.$name'); - if (state != null && state.containsKey('enabled') && state['enabled'] is String) { - state = await invokeFlutterExtensionRpcRaw( - 'ext.flutter.$name', - params: <String, dynamic>{'enabled': state['enabled'] == 'true' ? 'false' : 'true'}, - ); - } - return state; - } - - Future<Map<String, dynamic>> flutterToggleDebugPaintSizeEnabled() => _flutterToggle('debugPaint'); - - Future<Map<String, dynamic>> flutterToggleDebugCheckElevationsEnabled() => _flutterToggle('debugCheckElevationsEnabled'); - - Future<Map<String, dynamic>> flutterTogglePerformanceOverlayOverride() => _flutterToggle('showPerformanceOverlay'); - - Future<Map<String, dynamic>> flutterToggleWidgetInspector() => _flutterToggle('inspector.show'); - - Future<Map<String, dynamic>> flutterToggleProfileWidgetBuilds() => _flutterToggle('profileWidgetBuilds'); - - Future<Map<String, dynamic>> flutterDebugAllowBanner(bool show) { - return invokeFlutterExtensionRpcRaw( - 'ext.flutter.debugAllowBanner', - params: <String, dynamic>{'enabled': show ? 'true' : 'false'}, - ); - } - - Future<Map<String, dynamic>> flutterReassemble() { - return invokeFlutterExtensionRpcRaw('ext.flutter.reassemble'); - } - - Future<Map<String, dynamic>> flutterFastReassemble(String classId) { - return invokeFlutterExtensionRpcRaw('ext.flutter.fastReassemble', params: <String, Object>{ - 'class': classId, - }); - } - - Future<bool> flutterAlreadyPaintedFirstUsefulFrame() async { - final Map<String, dynamic> result = await invokeFlutterExtensionRpcRaw('ext.flutter.didSendFirstFrameRasterizedEvent'); - // result might be null when the service extension is not initialized - return result != null && result['enabled'] == 'true'; - } - - Future<Map<String, dynamic>> uiWindowScheduleFrame() { - return invokeFlutterExtensionRpcRaw('ext.ui.window.scheduleFrame'); - } - - Future<Map<String, dynamic>> flutterEvictAsset(String assetPath) { - return invokeFlutterExtensionRpcRaw( - 'ext.flutter.evict', - params: <String, dynamic>{ - 'value': assetPath, - }, - ); - } - - // Application control extension methods. - Future<Map<String, dynamic>> flutterExit() { - return invokeFlutterExtensionRpcRaw('ext.flutter.exit'); - } - - Future<String> flutterPlatformOverride([ String platform ]) async { - final Map<String, dynamic> result = await invokeFlutterExtensionRpcRaw( - 'ext.flutter.platformOverride', - params: platform != null ? <String, dynamic>{'value': platform} : <String, String>{}, - ); - if (result != null && result['value'] is String) { - return result['value'] as String; - } - return 'unknown'; - } - @override String toString() => 'Isolate $id'; } @@ -1523,4 +1379,213 @@ ); await onRunnable; } + + Future<Map<String, dynamic>> flutterDebugDumpApp({ + @required String isolateId, + }) { + return invokeFlutterExtensionRpcRaw( + 'ext.flutter.debugDumpApp', + isolateId: isolateId, + ); + } + + Future<Map<String, dynamic>> flutterDebugDumpRenderTree({ + @required String isolateId, + }) { + return invokeFlutterExtensionRpcRaw( + 'ext.flutter.debugDumpRenderTree', + isolateId: isolateId, + ); + } + + Future<Map<String, dynamic>> flutterDebugDumpLayerTree({ + @required String isolateId, + }) { + return invokeFlutterExtensionRpcRaw( + 'ext.flutter.debugDumpLayerTree', + isolateId: isolateId, + ); + } + + Future<Map<String, dynamic>> flutterDebugDumpSemanticsTreeInTraversalOrder({ + @required String isolateId, + }) { + return invokeFlutterExtensionRpcRaw( + 'ext.flutter.debugDumpSemanticsTreeInTraversalOrder', + isolateId: isolateId, + ); + } + + Future<Map<String, dynamic>> flutterDebugDumpSemanticsTreeInInverseHitTestOrder({ + @required String isolateId, + }) { + return invokeFlutterExtensionRpcRaw( + 'ext.flutter.debugDumpSemanticsTreeInInverseHitTestOrder', + isolateId: isolateId, + ); + } + + Future<Map<String, dynamic>> _flutterToggle(String name, { + @required String isolateId, + }) async { + Map<String, dynamic> state = await invokeFlutterExtensionRpcRaw( + 'ext.flutter.$name', + isolateId: isolateId, + ); + if (state != null && state.containsKey('enabled') && state['enabled'] is String) { + state = await invokeFlutterExtensionRpcRaw( + 'ext.flutter.$name', + isolateId: isolateId, + args: <String, dynamic>{ + 'enabled': state['enabled'] == 'true' ? 'false' : 'true', + }, + ); + } + + return state; + } + + Future<Map<String, dynamic>> flutterToggleDebugPaintSizeEnabled({ + @required String isolateId, + }) => _flutterToggle('debugPaint', isolateId: isolateId); + + Future<Map<String, dynamic>> flutterToggleDebugCheckElevationsEnabled({ + @required String isolateId, + }) => _flutterToggle('debugCheckElevationsEnabled', isolateId: isolateId); + + Future<Map<String, dynamic>> flutterTogglePerformanceOverlayOverride({ + @required String isolateId, + }) => _flutterToggle('showPerformanceOverlay', isolateId: isolateId); + + Future<Map<String, dynamic>> flutterToggleWidgetInspector({ + @required String isolateId, + }) => _flutterToggle('inspector.show', isolateId: isolateId); + + Future<Map<String, dynamic>> flutterToggleProfileWidgetBuilds({ + @required String isolateId, + }) => _flutterToggle('profileWidgetBuilds', isolateId: isolateId); + + Future<Map<String, dynamic>> flutterDebugAllowBanner(bool show, { + @required String isolateId, + }) { + return invokeFlutterExtensionRpcRaw( + 'ext.flutter.debugAllowBanner', + isolateId: isolateId, + args: <String, dynamic>{'enabled': show ? 'true' : 'false'}, + ); + } + + Future<Map<String, dynamic>> flutterReassemble({ + @required String isolateId, + }) { + return invokeFlutterExtensionRpcRaw( + 'ext.flutter.reassemble', + isolateId: isolateId, + ); + } + + Future<Map<String, dynamic>> flutterFastReassemble(String classId, { + @required String isolateId, + }) { + return invokeFlutterExtensionRpcRaw( + 'ext.flutter.fastReassemble', + isolateId: isolateId, + args: <String, Object>{ + 'class': classId, + }, + ); + } + + Future<bool> flutterAlreadyPaintedFirstUsefulFrame({ + @required String isolateId, + }) async { + final Map<String, dynamic> result = await invokeFlutterExtensionRpcRaw( + 'ext.flutter.didSendFirstFrameRasterizedEvent', + isolateId: isolateId, + ); + // result might be null when the service extension is not initialized + return result != null && result['enabled'] == 'true'; + } + + Future<Map<String, dynamic>> uiWindowScheduleFrame({ + @required String isolateId, + }) { + return invokeFlutterExtensionRpcRaw( + 'ext.ui.window.scheduleFrame', + isolateId: isolateId, + ); + } + + Future<Map<String, dynamic>> flutterEvictAsset(String assetPath, { + @required String isolateId, + }) { + return invokeFlutterExtensionRpcRaw( + 'ext.flutter.evict', + isolateId: isolateId, + args: <String, dynamic>{ + 'value': assetPath, + }, + ); + } + + /// Exit the application by calling [exit] from `dart:io`. + /// + /// This method is only supported by certain embedders. This is + /// described by [Device.supportsFlutterExit]. + Future<Map<String, dynamic>> flutterExit({ + @required String isolateId, + }) { + return invokeFlutterExtensionRpcRaw( + 'ext.flutter.exit', + isolateId: isolateId, + ); + } + + /// Return the current platform override for the flutter view running with + /// the main isolate [isolateId]. + /// + /// If a non-null value is provided for [platform], the platform override + /// is updated with this value. + Future<String> flutterPlatformOverride({ + String platform, + @required String isolateId, + }) async { + final Map<String, dynamic> result = await invokeFlutterExtensionRpcRaw( + 'ext.flutter.platformOverride', + isolateId: isolateId, + args: platform != null + ? <String, dynamic>{'value': platform} + : <String, String>{}, + ); + if (result != null && result['value'] is String) { + return result['value'] as String; + } + return 'unknown'; + } + + /// Invoke a flutter extension method, if the flutter extension is not + /// available, returns null. + Future<Map<String, dynamic>> invokeFlutterExtensionRpcRaw( + String method, { + @required String isolateId, + Map<String, dynamic> args, + }) async { + try { + + final vm_service.Response response = await callServiceExtension( + method, + args: <String, Object>{ + 'isolateId': isolateId, + ...?args, + }, + ); + return response.json; + } on vm_service.RPCError catch (err) { + // If an application is not using the framework + if (err.code == RPCErrorCodes.kMethodNotFound) { + return null; + } + rethrow; + } + } }