diff --git a/[refs] b/[refs] index ccddd6556940..11a7e07a34f5 100644 --- a/[refs] +++ b/[refs] @@ -1994,4 +1994,4 @@ refs/tags/2.14.0-96.0.dev: 1eee24e50fc3028754d9a8e98852b949c04da4e4 refs/tags/2.14.0-97.0.dev: ba9c1636e87fbdcc02b8bc4a584455c32f8378b4 refs/tags/2.14.0-98.0.dev: f2d370c93582bbf4da42b5dd4c906d6145b01ea9 refs/tags/2.14.0-99.0.dev: e722f62b48fb382534efc1f20735def68848006f -refs/heads/main: 22e5856ae561424f55fa5579e5ca14b9916d9ed1 +refs/heads/main: 54fb6ce3c07719d72eec0a14c00f905b724873c2 diff --git a/trunk/pkg/dds/CHANGELOG.md b/trunk/pkg/dds/CHANGELOG.md index 1f3d60f4b416..d795355f1642 100644 --- a/trunk/pkg/dds/CHANGELOG.md +++ b/trunk/pkg/dds/CHANGELOG.md @@ -1,3 +1,9 @@ -# 0.1.0-dev +# 1.1.0 + +- Added `getDartDevelopmentServiceVersion` RPC. +- Added DDS protocol to VM service `getSupportedProtocols` response. +- Added example/example.dart. + +# 1.0.0 - Initial release. diff --git a/trunk/pkg/dds/README.md b/trunk/pkg/dds/README.md index ab9067c81107..64b0c72c99a6 100644 --- a/trunk/pkg/dds/README.md +++ b/trunk/pkg/dds/README.md @@ -1,5 +1,3 @@ -_This package is a work in-progress and the API may not be stable. Stay tuned for updates._ - A package used to spawn the Dart Developer Service (DDS), which is used to communicate with a Dart VM Service instance and provide extended functionality to the core VM Service Protocol. # Functionality diff --git a/trunk/pkg/dds/dds_protocol.md b/trunk/pkg/dds/dds_protocol.md index b3bca7bf807d..8ac77eefe24d 100644 --- a/trunk/pkg/dds/dds_protocol.md +++ b/trunk/pkg/dds/dds_protocol.md @@ -17,12 +17,14 @@ The Service Protocol uses [JSON-RPC 2.0][]. - [Revision History](#revision-history) - [Public RPCs](#public-rpcs) - [getClientName](#getclientname) + - [getDartDevelopmentServiceVersion](#getdartdevelopmentserviceversion) - [getLogHistorySize](#getloghistorysize) - [requirePermissionToResume](#requirepermissiontoresume) - [setClientName](#setclientname) - [setLogHistorySize](#setloghistorysize) - [Public Types](#public-types) - [ClientName](#clientname) + - [DartDevelopmentServiceVersion](#dartdevelopmentserviceversion) - [Size](#size) ## RPCs, Requests, and Responses @@ -61,6 +63,18 @@ connected VM service client. If no name was previously set through the See [ClientName](#clientname) +### getDartDevelopmentServiceVersion + +``` +Version getDartDevelopmentServiceVersion() +``` + +The _getDartDevelopmentServiceVersion_ RPC is used to determine what version of +the Dart Development Service Protocol is served by a DDS instance. + +See [Version](#version). + + ### getLogHistorySize ``` @@ -164,9 +178,11 @@ A simple object representing a size response. version | comments ------- | -------- 1.0 | Initial revision +1.1 | Added `getDartDevelopmentServiceVersion` RPC. [resume]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#resume [success]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#success +[version]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#version [service-protocol]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md [service-protocol-rpcs-requests-and-responses]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#rpcs-requests-and-responses diff --git a/trunk/pkg/dds/example/example.dart b/trunk/pkg/dds/example/example.dart new file mode 100644 index 000000000000..883c678e7db5 --- /dev/null +++ b/trunk/pkg/dds/example/example.dart @@ -0,0 +1,24 @@ +// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:dds/dds.dart'; +import 'package:vm_service/vm_service_io.dart'; + +import '../test/common/test_helper.dart'; + +Future main() async { + final process = await spawnDartProcess('../test/smoke.dart'); + final dds = await DartDevelopmentService.startDartDevelopmentService( + remoteVmServiceUri, + ); + + // Connect to the DDS instance and make a request using package:vm_service. + final service = await vmServiceConnectUri(dds.wsUri.toString()); + final version = await service.getVersion(); + + print('Service Version: $version'); + + await dds.shutdown(); + process.kill(); +} diff --git a/trunk/pkg/dds/lib/dds.dart b/trunk/pkg/dds/lib/dds.dart index b8d24f9d77a7..79d5768e4f45 100644 --- a/trunk/pkg/dds/lib/dds.dart +++ b/trunk/pkg/dds/lib/dds.dart @@ -118,6 +118,10 @@ abstract class DartDevelopmentService { /// Set to `true` if this instance of [DartDevelopmentService] is accepting /// requests. bool get isRunning; + + /// The version of the DDS protocol supported by this [DartDevelopmentService] + /// instance. + static const String protocolVersion = '1.1'; } class DartDevelopmentServiceException implements Exception { diff --git a/trunk/pkg/dds/lib/src/binary_compatible_peer.dart b/trunk/pkg/dds/lib/src/binary_compatible_peer.dart index 7c5b83b69fb4..645c1cac8c37 100644 --- a/trunk/pkg/dds/lib/src/binary_compatible_peer.dart +++ b/trunk/pkg/dds/lib/src/binary_compatible_peer.dart @@ -49,10 +49,8 @@ class _BinaryCompatiblePeer extends json_rpc.Peer { const metadataOffset = 4; final dataOffset = bytesView.getUint32(0, Endian.little); final metadataLength = dataOffset - metadataOffset; - final metadata = Utf8Decoder().convert(new Uint8List.view( - bytesView.buffer, - bytesView.offsetInBytes + metadataOffset, - metadataLength)); + final metadata = Utf8Decoder().convert(Uint8List.view(bytesView.buffer, + bytesView.offsetInBytes + metadataOffset, metadataLength)); final decodedMetadata = json.decode(metadata); streamManager.streamNotify(decodedMetadata['params']['streamId'], data); } diff --git a/trunk/pkg/dds/lib/src/client.dart b/trunk/pkg/dds/lib/src/client.dart index 811aec2cce8e..f1b4a2550d9c 100644 --- a/trunk/pkg/dds/lib/src/client.dart +++ b/trunk/pkg/dds/lib/src/client.dart @@ -117,6 +117,31 @@ class _DartDevelopmentServiceClient { return _RPCResponses.success; }); + _clientPeer.registerMethod('getDartDevelopmentServiceVersion', + (parameters) async { + final ddsVersion = DartDevelopmentService.protocolVersion.split('.'); + return { + 'type': 'Version', + 'major': int.parse(ddsVersion[0]), + 'minor': int.parse(ddsVersion[1]), + }; + }); + + _clientPeer.registerMethod('getSupportedProtocols', (parameters) async { + final Map supportedProtocols = + await _vmServicePeer.sendRequest('getSupportedProtocols'); + final ddsVersion = DartDevelopmentService.protocolVersion.split('.'); + final ddsProtocol = { + 'protocolName': 'DDS', + 'major': int.parse(ddsVersion[0]), + 'minor': int.parse(ddsVersion[1]), + }; + supportedProtocols['protocols'] + .cast>() + .add(ddsProtocol); + return supportedProtocols; + }); + // When invoked within a fallback, the next fallback will start executing. // The final fallback forwards the request to the VM service directly. @alwaysThrows diff --git a/trunk/pkg/dds/pubspec.yaml b/trunk/pkg/dds/pubspec.yaml index 3df2581ec676..3282c477efc6 100644 --- a/trunk/pkg/dds/pubspec.yaml +++ b/trunk/pkg/dds/pubspec.yaml @@ -3,7 +3,7 @@ description: >- A library used to spawn the Dart Developer Service, used to communicate with a Dart VM Service instance. -version: 1.0.0 +version: 1.1.0 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dds @@ -13,6 +13,7 @@ environment: dependencies: async: ^2.4.1 json_rpc_2: ^2.1.0 + meta: ^1.1.8 pedantic: ^1.7.0 shelf: ^0.7.5 shelf_proxy: ^0.1.0+7 diff --git a/trunk/pkg/vm_service/example/vm_service_assert.dart b/trunk/pkg/vm_service/example/vm_service_assert.dart index 1430c952fe59..33a518d1254b 100644 --- a/trunk/pkg/vm_service/example/vm_service_assert.dart +++ b/trunk/pkg/vm_service/example/vm_service_assert.dart @@ -918,6 +918,28 @@ List assertListOfProfileFunction( return list; } +vms.ProtocolList assertProtocolList(vms.ProtocolList obj) { + assertNotNull(obj); + assertString(obj.type); + assertListOfProtocol(obj.protocols); + return obj; +} + +vms.Protocol assertProtocol(vms.Protocol obj) { + assertNotNull(obj); + assertString(obj.protocolName); + assertInt(obj.major); + assertInt(obj.minor); + return obj; +} + +List assertListOfProtocol(List list) { + for (vms.Protocol elem in list) { + assertProtocol(elem); + } + return list; +} + vms.ReloadReport assertReloadReport(vms.ReloadReport obj) { assertNotNull(obj); assertString(obj.type); diff --git a/trunk/pkg/vm_service/java/.gitignore b/trunk/pkg/vm_service/java/.gitignore index ebfb5c784fa7..3e3793d6a780 100644 --- a/trunk/pkg/vm_service/java/.gitignore +++ b/trunk/pkg/vm_service/java/.gitignore @@ -26,6 +26,7 @@ src/org/dartlang/vm/service/consumer/GetStackConsumer.java src/org/dartlang/vm/service/consumer/InvokeConsumer.java src/org/dartlang/vm/service/consumer/KillConsumer.java src/org/dartlang/vm/service/consumer/PauseConsumer.java +src/org/dartlang/vm/service/consumer/ProtocolListConsumer.java src/org/dartlang/vm/service/consumer/ReloadSourcesConsumer.java src/org/dartlang/vm/service/consumer/RemoveBreakpointConsumer.java src/org/dartlang/vm/service/consumer/RequestHeapSnapshotConsumer.java @@ -95,6 +96,8 @@ src/org/dartlang/vm/service/element/NullRef.java src/org/dartlang/vm/service/element/Obj.java src/org/dartlang/vm/service/element/ObjRef.java src/org/dartlang/vm/service/element/ProfileFunction.java +src/org/dartlang/vm/service/element/Protocol.java +src/org/dartlang/vm/service/element/ProtocolList.java src/org/dartlang/vm/service/element/ReloadReport.java src/org/dartlang/vm/service/element/Response.java src/org/dartlang/vm/service/element/RetainingObject.java diff --git a/trunk/pkg/vm_service/java/version.properties b/trunk/pkg/vm_service/java/version.properties index 47ae09427569..469b122c015d 100644 --- a/trunk/pkg/vm_service/java/version.properties +++ b/trunk/pkg/vm_service/java/version.properties @@ -1 +1 @@ -version=3.33 +version=3.35 diff --git a/trunk/pkg/vm_service/lib/src/vm_service.dart b/trunk/pkg/vm_service/lib/src/vm_service.dart index 175b4aa12c5d..745a6e29df6b 100644 --- a/trunk/pkg/vm_service/lib/src/vm_service.dart +++ b/trunk/pkg/vm_service/lib/src/vm_service.dart @@ -28,7 +28,7 @@ export 'snapshot_graph.dart' HeapSnapshotObjectNoData, HeapSnapshotObjectNullData; -const String vmServiceVersion = '3.33.0'; +const String vmServiceVersion = '3.35.0'; /// @optional const String optional = 'optional'; @@ -158,6 +158,8 @@ Map _typeFactories = { '@Object': ObjRef.parse, 'Object': Obj.parse, 'ProfileFunction': ProfileFunction.parse, + 'ProtocolList': ProtocolList.parse, + 'Protocol': Protocol.parse, 'ReloadReport': ReloadReport.parse, 'RetainingObject': RetainingObject.parse, 'RetainingPath': RetainingPath.parse, @@ -208,6 +210,7 @@ Map> _methodReturnTypes = { 'getObject': const ['Obj'], 'getRetainingPath': const ['RetainingPath'], 'getStack': const ['Stack'], + 'getSupportedProtocols': const ['ProtocolList'], 'getSourceReport': const ['SourceReport'], 'getVersion': const ['Version'], 'getVM': const ['VM'], @@ -731,6 +734,16 @@ abstract class VmServiceInterface { /// returned. Future getStack(String isolateId); + /// The `getSupportedProtocols` RPC is used to determine which protocols are + /// supported by the current server. + /// + /// The result of this call should be intercepted by any middleware that + /// extends the core VM service protocol and should add its own protocol to + /// the list of protocols before forwarding the response to the client. + /// + /// See [ProtocolList]. + Future getSupportedProtocols(); + /// The `getSourceReport` RPC is used to generate a set of reports tied to /// source locations in an isolate. /// @@ -1351,6 +1364,9 @@ class VmServerConnection { params['isolateId'], ); break; + case 'getSupportedProtocols': + response = await _serviceImplementation.getSupportedProtocols(); + break; case 'getSourceReport': response = await _serviceImplementation.getSourceReport( params['isolateId'], @@ -1810,6 +1826,10 @@ class VmService implements VmServiceInterface { Future getStack(String isolateId) => _call('getStack', {'isolateId': isolateId}); + @override + Future getSupportedProtocols() => + _call('getSupportedProtocols'); + @override Future getSourceReport( String isolateId, @@ -5776,6 +5796,79 @@ class ProfileFunction { 'resolvedUrl: ${resolvedUrl}, function: ${function}]'; } +/// A `ProtocolList` contains a list of all protocols supported by the service +/// instance. +/// +/// See [Protocol] and [getSupportedProtocols]. +class ProtocolList extends Response { + static ProtocolList parse(Map json) => + json == null ? null : ProtocolList._fromJson(json); + + /// A list of supported protocols provided by this service. + List protocols; + + ProtocolList({ + @required this.protocols, + }); + + ProtocolList._fromJson(Map json) : super._fromJson(json) { + protocols = List.from( + createServiceObject(json['protocols'], const ['Protocol']) ?? []); + } + + @override + Map toJson() { + var json = {}; + json['type'] = 'ProtocolList'; + json.addAll({ + 'protocols': protocols.map((f) => f.toJson()).toList(), + }); + return json; + } + + String toString() => '[ProtocolList type: ${type}, protocols: ${protocols}]'; +} + +/// See [getSupportedProtocols]. +class Protocol { + static Protocol parse(Map json) => + json == null ? null : Protocol._fromJson(json); + + /// The name of the supported protocol. + String protocolName; + + /// The major revision of the protocol. + int major; + + /// The minor revision of the protocol. + int minor; + + Protocol({ + @required this.protocolName, + @required this.major, + @required this.minor, + }); + + Protocol._fromJson(Map json) { + protocolName = json['protocolName']; + major = json['major']; + minor = json['minor']; + } + + Map toJson() { + var json = {}; + json.addAll({ + 'protocolName': protocolName, + 'major': major, + 'minor': minor, + }); + return json; + } + + String toString() => '[Protocol ' // + 'protocolName: ${protocolName}, major: ${major}, minor: ${minor}]'; +} + class ReloadReport extends Response { static ReloadReport parse(Map json) => json == null ? null : ReloadReport._fromJson(json); diff --git a/trunk/pkg/vm_service/tool/dart/generate_dart.dart b/trunk/pkg/vm_service/tool/dart/generate_dart.dart index c5f8703e7d44..a45d705678e0 100644 --- a/trunk/pkg/vm_service/tool/dart/generate_dart.dart +++ b/trunk/pkg/vm_service/tool/dart/generate_dart.dart @@ -1016,6 +1016,7 @@ vms.Event assertIsolateEvent(vms.Event event) { 'LibraryDependency', 'Message', 'ProfileFunction', + 'Protocol', 'RetainingObject', 'SourceReportRange', 'TimelineEvent', diff --git a/trunk/runtime/observatory/tests/service/get_supported_protocols_test.dart b/trunk/runtime/observatory/tests/service/get_supported_protocols_test.dart new file mode 100644 index 000000000000..e72aeef125dc --- /dev/null +++ b/trunk/runtime/observatory/tests/service/get_supported_protocols_test.dart @@ -0,0 +1,32 @@ +// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:observatory/service_io.dart'; +import 'package:test/test.dart'; + +import 'test_helper.dart'; + +final tests = [ + (VM vm) async { + final result = await vm.invokeRpcNoUpgrade('getSupportedProtocols', {}); + expect(result['type'], equals('ProtocolList')); + final List protocols = + result['protocols'].cast>(); + expect(protocols.length, useDds ? 2 : 1); + + final expectedProtocols = { + 'VM Service', + if (useDds) 'DDS', + }; + + for (final protocol in protocols) { + final protocolName = protocol['protocolName']; + expect(expectedProtocols.contains(protocolName), isTrue); + expect(protocol['major'] > 0, isTrue); + expect(protocol['minor'] >= 0, isTrue); + } + }, +]; + +main(args) async => runVMTests(args, tests); diff --git a/trunk/runtime/observatory/tests/service/get_version_rpc_test.dart b/trunk/runtime/observatory/tests/service/get_version_rpc_test.dart index 3dc33db651ca..f6c94733583f 100644 --- a/trunk/runtime/observatory/tests/service/get_version_rpc_test.dart +++ b/trunk/runtime/observatory/tests/service/get_version_rpc_test.dart @@ -12,7 +12,7 @@ var tests = [ var result = await vm.invokeRpcNoUpgrade('getVersion', {}); expect(result['type'], equals('Version')); expect(result['major'], equals(3)); - expect(result['minor'], equals(33)); + expect(result['minor'], equals(35)); expect(result['_privateMajor'], equals(0)); expect(result['_privateMinor'], equals(0)); }, diff --git a/trunk/runtime/vm/service.h b/trunk/runtime/vm/service.h index ffdc290641b6..aee5f5c55013 100644 --- a/trunk/runtime/vm/service.h +++ b/trunk/runtime/vm/service.h @@ -15,7 +15,7 @@ namespace dart { #define SERVICE_PROTOCOL_MAJOR_VERSION 3 -#define SERVICE_PROTOCOL_MINOR_VERSION 33 +#define SERVICE_PROTOCOL_MINOR_VERSION 35 class Array; class EmbedderServiceHandler; diff --git a/trunk/runtime/vm/service/service.md b/trunk/runtime/vm/service/service.md index 7209a93c9f39..1eed739cffd8 100644 --- a/trunk/runtime/vm/service/service.md +++ b/trunk/runtime/vm/service/service.md @@ -1,8 +1,8 @@ -# Dart VM Service Protocol 3.33 +# Dart VM Service Protocol 3.35 > Please post feedback to the [observatory-discuss group][discuss-list] -This document describes of _version 3.33_ of the Dart VM Service Protocol. This +This document describes of _version 3.35_ of the Dart VM Service Protocol. This protocol is used to communicate with a running Dart Virtual Machine. To use the Service Protocol, start the VM with the *--observe* flag. @@ -27,7 +27,9 @@ The Service Protocol uses [JSON-RPC 2.0][]. - [IDs and Names](#ids-and-names) - [Versioning](#versioning) - [Private RPCs, Types, and Properties](#private-rpcs-types-and-properties) -- [Single Client Mode](#single-client-mode) +- [Middleware Support](#middleware-support) + - [Single Client Mode](#single-client-mode) + - [Protocol Extensions](#protocol-extensions) - [Public RPCs](#public-rpcs) - [addBreakpoint](#addbreakpoint) - [addBreakpointWithScriptUri](#addbreakpointwithscripturi) @@ -50,6 +52,7 @@ The Service Protocol uses [JSON-RPC 2.0][]. - [getScripts](#getscripts) - [getSourceReport](#getsourcereport) - [getStack](#getstack) + - [getSupportedProtocols](#getsupportedprotocols) - [getVersion](#getversion) - [getVM](#getvm) - [getVMTimeline](#getvmtimeline) @@ -406,7 +409,9 @@ become stable. Some private types and properties expose VM specific implementation state and will never be appropriate to add to the public api. -## Single Client Mode +## Middleware Support + +### Single Client Mode The VM service allows for an extended feature set via the Dart Development Service (DDS) that forward all core VM service RPCs described in this @@ -417,6 +422,15 @@ mode and will no longer accept incoming web socket connections. If DDS disconnects from the VM service, the VM service will once again start accepting incoming web socket connections. +### Protocol Extensions + +Middleware like the Dart Development Service have the option of providing +functionality which builds on or extends the VM service protocol. Middleware +which offer protocol extensions should intercept calls to +[getSupportedProtocols](#getsupportedprotocols) and modify the resulting +[ProtocolList](#protocolist) to include their own [Protocol](#protocol) +information before responding to the requesting client. + ## Public RPCs The following is a list of all public RPCs supported by the Service Protocol. @@ -979,6 +993,21 @@ _Collected_ [Sentinel](#sentinel) is returned. See [Stack](#stack). +### getSupportedProtocols + +``` +ProtocolList getSupportedProtocols() +``` + +The _getSupportedProtocols_ RPC is used to determine which protocols are +supported by the current server. + +The result of this call should be intercepted by any middleware that extends +the core VM service protocol and should add its own protocol to the list of +protocols before forwarding the response to the client. + +See [ProtocolList](#protocollist). + ### getSourceReport ``` @@ -3215,6 +3244,37 @@ function. See [CpuSamples](#cpusamples). +### ProtocolList + +``` +class ProtocolList extends Response { + // A list of supported protocols provided by this service. + Protocol[] protocols; +} +``` + +A _ProtocolList_ contains a list of all protocols supported by the service +instance. + +See [Protocol](#protocol) and [getSupportedProtocols](#getsupportedprotocols). + +### Protocol + +``` +class Protocol { + // The name of the supported protocol. + string protocolName; + + // The major revision of the protocol. + int major; + + // The minor revision of the protocol. + int minor; +} +``` + +See [getSupportedProtocols](#getsupportedprotocols). + ### ReloadReport ``` @@ -3787,5 +3847,6 @@ the VM service. 3.32 | Added `getClassList` RPC and `ClassList` object. 3.33 | Added deprecation notice for `getClientName`, `setClientName`, `requireResumeApproval`, and `ClientName`. These RPCs are moving to the DDS protocol and will be removed in v4.0 of the VM service protocol. 3.34 | Added `TimelineStreamSubscriptionsUpdate` event which is sent when `setVMTimelineFlags` is invoked. +3.35 | Added `getSupportedProtocols` RPC and `ProtocolList`, `Protocol` objects. [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss diff --git a/trunk/sdk/lib/vmservice/vmservice.dart b/trunk/sdk/lib/vmservice/vmservice.dart index bfbdaf8c96ce..0cd0eeb6ec7d 100644 --- a/trunk/sdk/lib/vmservice/vmservice.dart +++ b/trunk/sdk/lib/vmservice/vmservice.dart @@ -714,6 +714,25 @@ class VMService extends MessageRouter { details: "Unknown service: ${message.method}"); } + Future _getSupportedProtocols(Message message) async { + final version = json.decode( + utf8.decode( + (await Message.forMethod('getVersion').sendToVM()).payload, + ), + )['result']; + final protocols = { + 'type': 'ProtocolList', + 'protocols': [ + { + 'protocolName': 'VM Service', + 'major': version['major'], + 'minor': version['minor'], + }, + ], + }; + return encodeResult(message, protocols); + } + Future routeRequest(VMService _, Message message) async { final response = await _routeRequestImpl(message); if (response == null) { @@ -750,6 +769,9 @@ class VMService extends MessageRouter { if (message.method == 'requirePermissionToResume') { return _requirePermissionToResume(message); } + if (message.method == 'getSupportedProtocols') { + return await _getSupportedProtocols(message); + } if (devfs.shouldHandleMessage(message)) { return await devfs.handleMessage(message); } diff --git a/trunk/sdk_nnbd/lib/vmservice/vmservice.dart b/trunk/sdk_nnbd/lib/vmservice/vmservice.dart index 01847bbc18e2..4f3c12dfacdf 100644 --- a/trunk/sdk_nnbd/lib/vmservice/vmservice.dart +++ b/trunk/sdk_nnbd/lib/vmservice/vmservice.dart @@ -706,6 +706,25 @@ class VMService extends MessageRouter { details: 'Unknown service: ${message.method}'); } + Future _getSupportedProtocols(Message message) async { + final version = json.decode( + utf8.decode( + (await Message.forMethod('getVersion').sendToVM()).payload, + ), + )['result']; + final protocols = { + 'type': 'ProtocolList', + 'protocols': [ + { + 'protocolName': 'VM Service', + 'major': version['major'], + 'minor': version['minor'], + }, + ], + }; + return encodeResult(message, protocols); + } + Future routeRequest(VMService _, Message message) async { final response = await _routeRequestImpl(message); if (response == null) { @@ -742,6 +761,9 @@ class VMService extends MessageRouter { if (message.method == 'requirePermissionToResume') { return _requirePermissionToResume(message); } + if (message.method == 'getSupportedProtocols') { + return await _getSupportedProtocols(message); + } if (devfs.shouldHandleMessage(message)) { return await devfs.handleMessage(message); }