// Copyright (c) 2016, 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. part of "dart:developer"; /// Service protocol is the protocol that a client like the Observatory /// could use to access the services provided by the Dart VM for /// debugging and inspecting Dart programs. This class encapsulates the /// version number and Uri for accessing this service. final class ServiceProtocolInfo { /// The major version of the protocol. If the running Dart environment does /// not support the service protocol, this is 0. final int majorVersion = _getServiceMajorVersion(); /// The minor version of the protocol. If the running Dart environment does /// not support the service protocol, this is 0. final int minorVersion = _getServiceMinorVersion(); /// The Uri to connect to the debugger client hosted by the service. If the /// web server is not running, this will be null. final Uri? serverUri; /// The Uri to connect to the service via web socket. If the web server is /// not running, this will be null. @Since('2.14') Uri? get serverWebSocketUri { Uri? uri = serverUri; if (uri != null) { final pathSegments = []; if (uri.pathSegments.isNotEmpty) { pathSegments.addAll( uri.pathSegments.where( // Strip out the empty string that appears at the end of path segments. // Empty string elements will result in an extra '/' being added to the // URI. (s) => s.isNotEmpty, ), ); } pathSegments.add('ws'); uri = uri.replace(scheme: 'ws', pathSegments: pathSegments); } return uri; } ServiceProtocolInfo(this.serverUri); String toString() { if (serverUri != null) { return 'Dart VM Service Protocol v$majorVersion.$minorVersion ' 'listening on $serverUri'; } else { return 'Dart VM Service Protocol v$majorVersion.$minorVersion'; } } } /// Access information about the service protocol and control the web server /// that provides access to the services provided by the Dart VM for /// debugging and inspecting Dart programs. final class Service { /// Get information about the service protocol (version number and /// Uri to access the service). static Future getInfo() async { // Port to receive response from service isolate. final RawReceivePort receivePort = new RawReceivePort( null, 'Service.getInfo', ); final Completer completer = new Completer(); receivePort.handler = (String? uriString) => completer.complete(uriString); // Request the information from the service isolate. _getServerInfo(receivePort.sendPort); // Await the response from the service isolate. String? uriString = await completer.future; Uri? uri = uriString == null ? null : Uri.parse(uriString); // Close the port. receivePort.close(); return new ServiceProtocolInfo(uri); } /// Control the web server that the service protocol is accessed through. /// [enable] is used as a toggle to enable or disable the web server /// servicing requests. If [silenceOutput] is provided and is true, /// the server will not output information to the console. static Future controlWebServer({ bool enable = false, bool? silenceOutput, }) async { // Port to receive response from service isolate. final RawReceivePort receivePort = new RawReceivePort( null, 'Service.controlWebServer', ); final Completer completer = new Completer(); receivePort.handler = (String? uriString) => completer.complete(uriString); // Request the information from the service isolate. _webServerControl(receivePort.sendPort, enable, silenceOutput); // Await the response from the service isolate. String? uriString = await completer.future; Uri? uri = uriString == null ? null : Uri.parse(uriString); // Close the port. receivePort.close(); return new ServiceProtocolInfo(uri); } /// Returns a [String] token representing the ID of [isolate]. /// /// Returns null if the running Dart environment does not support the service /// protocol. /// /// To get the isolate id of the current isolate, pass [Isolate.current] as /// the [isolate] parameter. @Since('3.2') static String? getIsolateId(Isolate isolate) { return _getIsolateIdFromSendPort(isolate.controlPort); } /// Returns a [String] token representing the ID of [isolate]. /// /// Returns null if the running Dart environment does not support the service /// protocol. @Deprecated("Use getIsolateId instead") static String? getIsolateID(Isolate isolate) { return _getIsolateIdFromSendPort(isolate.controlPort); } /// Returns a [String] token representing the ID of [object]. /// /// Returns null if the running Dart environment does not support the service /// protocol. @Since('3.2') static String? getObjectId(Object object) { return _getObjectId(object); } } /// [sendPort] will receive a Uri or null. external void _getServerInfo(SendPort sendPort); /// [sendPort] will receive a Uri or null. external void _webServerControl( SendPort sendPort, bool enable, bool? silenceOutput, ); /// Returns the major version of the service protocol. external int _getServiceMajorVersion(); /// Returns the minor version of the service protocol. external int _getServiceMinorVersion(); /// Returns the service id for the isolate that owns [sendPort]. external String? _getIsolateIdFromSendPort(SendPort sendPort); /// Returns the service id of [object]. external String? _getObjectId(Object object);