/
service.dart
149 lines (131 loc) · 5.85 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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// 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.
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.
final 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.
@Since('3.2')
static String? getIsolateId(Isolate isolate) {
// TODO: When NNBD is complete, delete the following line.
ArgumentError.checkNotNull(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) {
// TODO: When NNBD is complete, delete the following line.
ArgumentError.checkNotNull(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.
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);