/
service.dart
126 lines (111 loc) · 5.06 KB
/
service.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// 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.
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.
Uri? get serverWebSocketUri {
Uri? uri = serverUri;
if (uri != null) {
final pathSegments = <String>[];
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.
class Service {
/// Get information about the service protocol (version number and
/// Uri to access the service).
static Future<ServiceProtocolInfo> getInfo() async {
// Port to receive response from service isolate.
final RawReceivePort receivePort =
new RawReceivePort(null, 'Service.getInfo');
final Completer<String?> completer = new Completer<String?>();
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<ServiceProtocolInfo> controlWebServer(
{bool enable = false, bool? silenceOutput}) async {
// TODO: When NNBD is complete, delete the following line.
ArgumentError.checkNotNull(enable, 'enable');
// Port to receive response from service isolate.
final RawReceivePort receivePort =
new RawReceivePort(null, 'Service.controlWebServer');
final Completer<String?> completer = new Completer<String?>();
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.
static String? getIsolateID(Isolate isolate) {
// TODO: When NNBD is complete, delete the following line.
ArgumentError.checkNotNull(isolate, 'isolate');
return _getIsolateIDFromSendPort(isolate.controlPort);
}
}
/// [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);