Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart._vmservice; | 5 library dart._vmservice; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 import 'dart:convert'; | 9 import 'dart:convert'; |
| 10 import 'dart:developer' show ServiceProtocolInfo; | 10 import 'dart:developer' show ServiceProtocolInfo; |
| 11 import 'dart:isolate'; | 11 import 'dart:isolate'; |
| 12 import 'dart:math'; | 12 import 'dart:math'; |
| 13 import 'dart:typed_data'; | 13 import 'dart:typed_data'; |
| 14 | 14 |
| 15 part 'asset.dart'; | 15 part 'asset.dart'; |
| 16 part 'client.dart'; | 16 part 'client.dart'; |
| 17 part 'devfs.dart'; | 17 part 'devfs.dart'; |
| 18 part 'constants.dart'; | 18 part 'constants.dart'; |
| 19 part 'running_isolate.dart'; | 19 part 'running_isolate.dart'; |
| 20 part 'running_isolates.dart'; | 20 part 'running_isolates.dart'; |
| 21 part 'message.dart'; | 21 part 'message.dart'; |
| 22 part 'message_router.dart'; | 22 part 'message_router.dart'; |
| 23 part 'named_lookup.dart'; | |
| 23 | 24 |
| 24 final RawReceivePort isolateControlPort = new RawReceivePort(); | 25 final RawReceivePort isolateControlPort = new RawReceivePort(); |
| 25 final RawReceivePort scriptLoadPort = new RawReceivePort(); | 26 final RawReceivePort scriptLoadPort = new RawReceivePort(); |
| 26 | 27 |
| 27 abstract class IsolateEmbedderData { | 28 abstract class IsolateEmbedderData { |
| 28 void cleanup(); | 29 void cleanup(); |
| 29 } | 30 } |
| 30 | 31 |
| 31 String _makeAuthToken() { | 32 String _makeAuthToken() { |
| 32 final kTokenByteSize = 8; | 33 final kTokenByteSize = 8; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 44 // TODO(johnmccutchan): Enable the auth token and drop the origin check. | 45 // TODO(johnmccutchan): Enable the auth token and drop the origin check. |
| 45 final bool useAuthToken = const bool.fromEnvironment('DART_SERVICE_USE_AUTH'); | 46 final bool useAuthToken = const bool.fromEnvironment('DART_SERVICE_USE_AUTH'); |
| 46 | 47 |
| 47 // This is for use by the embedder. It is a map from the isolateId to | 48 // This is for use by the embedder. It is a map from the isolateId to |
| 48 // anything implementing IsolateEmbedderData. When an isolate goes away, | 49 // anything implementing IsolateEmbedderData. When an isolate goes away, |
| 49 // the cleanup method will be invoked after being removed from the map. | 50 // the cleanup method will be invoked after being removed from the map. |
| 50 final Map<int, IsolateEmbedderData> isolateEmbedderData = | 51 final Map<int, IsolateEmbedderData> isolateEmbedderData = |
| 51 new Map<int, IsolateEmbedderData>(); | 52 new Map<int, IsolateEmbedderData>(); |
| 52 | 53 |
| 53 // These must be kept in sync with the declarations in vm/json_stream.h. | 54 // These must be kept in sync with the declarations in vm/json_stream.h. |
| 55 const kParseError = -32700; | |
| 56 const kInvalidRequest = -32600; | |
| 57 const kMethodNotFound = -32601; | |
| 54 const kInvalidParams = -32602; | 58 const kInvalidParams = -32602; |
| 55 const kInternalError = -32603; | 59 const kInternalError = -32603; |
| 60 | |
| 61 const kExtensionError = -32000; | |
| 62 | |
| 56 const kFeatureDisabled = 100; | 63 const kFeatureDisabled = 100; |
| 64 const kCannotAddBreakpoint = 102; | |
| 57 const kStreamAlreadySubscribed = 103; | 65 const kStreamAlreadySubscribed = 103; |
| 58 const kStreamNotSubscribed = 104; | 66 const kStreamNotSubscribed = 104; |
| 67 const kIsolateMustBeRunnable = 105; | |
| 68 const kIsolateMustBePaused = 106; | |
| 69 const kCannotResume = 107; | |
| 70 const kIsolateIsReloading = 108; | |
| 71 const kIsolateReloadBarred = 109; | |
| 72 const kServiceAlreadyRegistered = 110; | |
| 73 | |
| 74 // Experimental (used in private rpcs). | |
| 59 const kFileSystemAlreadyExists = 1001; | 75 const kFileSystemAlreadyExists = 1001; |
| 60 const kFileSystemDoesNotExist = 1002; | 76 const kFileSystemDoesNotExist = 1002; |
| 61 const kFileDoesNotExist = 1003; | 77 const kFileDoesNotExist = 1003; |
| 62 | 78 |
| 63 var _errorMessages = { | 79 var _errorMessages = { |
| 64 kInvalidParams: 'Invalid params', | 80 kInvalidParams: 'Invalid params', |
| 65 kInternalError: 'Internal error', | 81 kInternalError: 'Internal error', |
| 66 kFeatureDisabled: 'Feature is disabled', | 82 kFeatureDisabled: 'Feature is disabled', |
| 67 kStreamAlreadySubscribed: 'Stream already subscribed', | 83 kStreamAlreadySubscribed: 'Stream already subscribed', |
| 68 kStreamNotSubscribed: 'Stream not subscribed', | 84 kStreamNotSubscribed: 'Stream not subscribed', |
| 69 kFileSystemAlreadyExists: 'File system already exists', | 85 kFileSystemAlreadyExists: 'File system already exists', |
| 70 kFileSystemDoesNotExist: 'File system does not exist', | 86 kFileSystemDoesNotExist: 'File system does not exist', |
| 71 kFileDoesNotExist: 'File does not exist', | 87 kFileDoesNotExist: 'File does not exist', |
| 88 kServiceAlreadyRegistered: 'Service already registered', | |
| 72 }; | 89 }; |
| 73 | 90 |
| 74 String encodeRpcError(Message message, int code, {String details}) { | 91 String encodeRpcError(Message message, int code, {String details}) { |
| 75 var response = { | 92 var response = { |
| 76 'jsonrpc': '2.0', | 93 'jsonrpc': '2.0', |
| 77 'id': message.serial, | 94 'id': message.serial, |
| 78 'error': { | 95 'error': { |
| 79 'code': code, | 96 'code': code, |
| 80 'message': _errorMessages[code], | 97 'message': _errorMessages[code], |
| 81 }, | 98 }, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 135 /// Called to write a stream into a file. | 152 /// Called to write a stream into a file. |
| 136 typedef Future WriteStreamFileCallback(Uri path, Stream<List<int>> bytes); | 153 typedef Future WriteStreamFileCallback(Uri path, Stream<List<int>> bytes); |
| 137 | 154 |
| 138 /// Called to read a file. | 155 /// Called to read a file. |
| 139 typedef Future<List<int>> ReadFileCallback(Uri path); | 156 typedef Future<List<int>> ReadFileCallback(Uri path); |
| 140 | 157 |
| 141 /// Called to list all files under some path. | 158 /// Called to list all files under some path. |
| 142 typedef Future<List<Map<String, String>>> ListFilesCallback(Uri path); | 159 typedef Future<List<Map<String, String>>> ListFilesCallback(Uri path); |
| 143 | 160 |
| 144 /// Called when we need information about the server. | 161 /// Called when we need information about the server. |
| 162 typedef Future<Uri> ServerInformamessage_routertionCallback(); | |
| 163 | |
| 164 /// Called when we need information about the server. | |
| 145 typedef Future<Uri> ServerInformationCallback(); | 165 typedef Future<Uri> ServerInformationCallback(); |
| 146 | 166 |
| 147 /// Called when we want to [enable] or disable the web server. | 167 /// Called when we want to [enable] or disable the web server. |
| 148 typedef Future<Uri> WebServerControlCallback(bool enable); | 168 typedef Future<Uri> WebServerControlCallback(bool enable); |
| 149 | 169 |
| 150 /// Hooks that are setup by the embedder. | 170 /// Hooks that are setup by the embedder. |
| 151 class VMServiceEmbedderHooks { | 171 class VMServiceEmbedderHooks { |
| 152 static ServerStartCallback serverStart; | 172 static ServerStartCallback serverStart; |
| 153 static ServerStopCallback serverStop; | 173 static ServerStopCallback serverStop; |
| 154 static CleanupCallback cleanup; | 174 static CleanupCallback cleanup; |
| 155 static CreateTempDirCallback createTempDir; | 175 static CreateTempDirCallback createTempDir; |
| 156 static DeleteDirCallback deleteDir; | 176 static DeleteDirCallback deleteDir; |
| 157 static WriteFileCallback writeFile; | 177 static WriteFileCallback writeFile; |
| 158 static WriteStreamFileCallback writeStreamFile; | 178 static WriteStreamFileCallback writeStreamFile; |
| 159 static ReadFileCallback readFile; | 179 static ReadFileCallback readFile; |
| 160 static ListFilesCallback listFiles; | 180 static ListFilesCallback listFiles; |
| 161 static ServerInformationCallback serverInformation; | 181 static ServerInformationCallback serverInformation; |
| 162 static WebServerControlCallback webServerControl; | 182 static WebServerControlCallback webServerControl; |
| 163 } | 183 } |
| 164 | 184 |
| 165 class VMService extends MessageRouter { | 185 class VMService extends MessageRouter { |
| 166 static VMService _instance; | 186 static VMService _instance; |
| 167 | 187 |
| 188 static const serviceNamespace = 's'; | |
| 189 | |
| 168 /// Collection of currently connected clients. | 190 /// Collection of currently connected clients. |
| 169 final Set<Client> clients = new Set<Client>(); | 191 final NamedLookup<Client> clients = |
| 192 new NamedLookup<Client>(prologue: serviceNamespace); | |
| 193 final IdGenerator _serviceRequests = new IdGenerator(prologue: 'sr'); | |
| 170 | 194 |
| 171 /// Collection of currently running isolates. | 195 /// Collection of currently running isolates. |
| 172 RunningIsolates runningIsolates = new RunningIsolates(); | 196 RunningIsolates runningIsolates = new RunningIsolates(); |
| 173 | 197 |
| 174 /// A port used to receive events from the VM. | 198 /// A port used to receive events from the VM. |
| 175 final RawReceivePort eventPort; | 199 final RawReceivePort eventPort; |
| 176 | 200 |
| 177 final devfs = new DevFS(); | 201 final devfs = new DevFS(); |
| 178 | 202 |
| 179 void _addClient(Client client) { | 203 void _addClient(Client client) { |
| 180 assert(client.streams.isEmpty); | 204 assert(client.streams.isEmpty); |
| 205 assert(client.services.isEmpty); | |
| 181 clients.add(client); | 206 clients.add(client); |
| 182 } | 207 } |
| 183 | 208 |
| 184 void _removeClient(Client client) { | 209 void _removeClient(Client client) { |
| 210 final namespace = clients.keyOf(client); | |
| 185 clients.remove(client); | 211 clients.remove(client); |
| 186 for (var streamId in client.streams) { | 212 for (var streamId in client.streams) { |
| 187 if (!_isAnyClientSubscribed(streamId)) { | 213 if (!_isAnyClientSubscribed(streamId)) { |
| 188 _vmCancelStream(streamId); | 214 _vmCancelStream(streamId); |
| 189 } | 215 } |
| 190 } | 216 } |
| 217 for (var service in client.services.keys) { | |
| 218 _eventMessageHandler([ | |
| 219 '_Service', | |
| 220 JSON.encode({ | |
| 221 'jsonrpc': '2.0', | |
| 222 'method': 'streamNotify', | |
| 223 'params': { | |
| 224 'streamId': '_Service', | |
| 225 'event': { | |
| 226 "type": "Event", | |
| 227 "kind": "ServiceUnregistered", | |
| 228 'timestamp': new DateTime.now().millisecondsSinceEpoch, | |
| 229 'service': service, | |
| 230 'method': namespace + '.' + service, | |
| 231 } | |
| 232 } | |
| 233 }) | |
| 234 ]); | |
| 235 } | |
| 236 for (var handle in client.serviceHandles.values) { | |
| 237 handle(null); | |
| 238 } | |
| 191 } | 239 } |
| 192 | 240 |
| 193 void _eventMessageHandler(List eventMessage) { | 241 void _eventMessageHandler(List eventMessage) { |
| 194 var streamId = eventMessage[0]; | 242 var streamId = eventMessage[0]; |
| 195 var event = eventMessage[1]; | 243 var event = eventMessage[1]; |
| 196 for (var client in clients) { | 244 for (var client in clients) { |
| 197 if (client.sendEvents && client.streams.contains(streamId)) { | 245 if (client.sendEvents && client.streams.contains(streamId)) { |
| 198 client.post(event); | 246 client.post(event); |
| 199 } | 247 } |
| 200 } | 248 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 306 | 354 |
| 307 bool _isAnyClientSubscribed(String streamId) { | 355 bool _isAnyClientSubscribed(String streamId) { |
| 308 for (var client in clients) { | 356 for (var client in clients) { |
| 309 if (client.streams.contains(streamId)) { | 357 if (client.streams.contains(streamId)) { |
| 310 return true; | 358 return true; |
| 311 } | 359 } |
| 312 } | 360 } |
| 313 return false; | 361 return false; |
| 314 } | 362 } |
| 315 | 363 |
| 364 static const kServiceStream = '_Service'; | |
| 365 static const serviceStreams = const [kServiceStream]; | |
| 366 | |
| 316 Future<String> _streamListen(Message message) async { | 367 Future<String> _streamListen(Message message) async { |
| 317 var client = message.client; | 368 var client = message.client; |
| 318 var streamId = message.params['streamId']; | 369 var streamId = message.params['streamId']; |
| 319 | 370 |
| 320 if (client.streams.contains(streamId)) { | 371 if (client.streams.contains(streamId)) { |
| 321 return encodeRpcError(message, kStreamAlreadySubscribed); | 372 return encodeRpcError(message, kStreamAlreadySubscribed); |
| 322 } | 373 } |
| 323 if (!_isAnyClientSubscribed(streamId)) { | 374 if (!_isAnyClientSubscribed(streamId)) { |
| 324 if (!_vmListenStream(streamId)) { | 375 if (!serviceStreams.contains(streamId) && !_vmListenStream(streamId)) { |
| 325 return encodeRpcError(message, kInvalidParams, | 376 return encodeRpcError(message, kInvalidParams, |
| 326 details: "streamListen: invalid 'streamId' parameter: ${streamId}"); | 377 details: "streamListen: invalid 'streamId' parameter: ${streamId}"); |
| 327 } | 378 } |
| 328 } | 379 } |
| 380 | |
| 381 switch (streamId) { | |
| 382 case kServiceStream: | |
| 383 for (Client c in clients) { | |
| 384 if (c == client) continue; | |
| 385 for (String service in c.services.keys) { | |
| 386 _sendServiceRegisteredEvent(c, service, target: client); | |
| 387 } | |
| 388 } | |
| 389 ; | |
| 390 break; | |
| 391 } | |
| 392 | |
| 329 client.streams.add(streamId); | 393 client.streams.add(streamId); |
| 330 | |
| 331 return encodeSuccess(message); | 394 return encodeSuccess(message); |
| 332 } | 395 } |
| 333 | 396 |
| 334 Future<String> _streamCancel(Message message) async { | 397 Future<String> _streamCancel(Message message) async { |
| 335 var client = message.client; | 398 var client = message.client; |
| 336 var streamId = message.params['streamId']; | 399 var streamId = message.params['streamId']; |
| 337 | 400 |
| 338 if (!client.streams.contains(streamId)) { | 401 if (!client.streams.contains(streamId)) { |
| 339 return encodeRpcError(message, kStreamNotSubscribed); | 402 return encodeRpcError(message, kStreamNotSubscribed); |
| 340 } | 403 } |
| 341 client.streams.remove(streamId); | 404 client.streams.remove(streamId); |
| 342 if (!_isAnyClientSubscribed(streamId)) { | 405 if (!serviceStreams.contains(streamId) && |
| 406 !_isAnyClientSubscribed(streamId)) { | |
| 343 _vmCancelStream(streamId); | 407 _vmCancelStream(streamId); |
| 344 } | 408 } |
| 345 | 409 |
| 346 return encodeSuccess(message); | 410 return encodeSuccess(message); |
| 347 } | 411 } |
| 348 | 412 |
| 413 static bool _hasNamespace(String method) => | |
| 414 method.contains('.') && | |
| 415 _getNamespace(method).startsWith(serviceNamespace); | |
| 416 static String _getNamespace(String method) => method.split('.').first; | |
| 417 static String _getMethod(String method) => method.split('.').last; | |
| 418 | |
| 419 Future<String> _registerService(Message message) async { | |
| 420 final client = message.client; | |
| 421 final service = message.params['service']; | |
| 422 final alias = message.params['alias']; | |
| 423 | |
| 424 if (service is! String || service == '') { | |
| 425 return encodeRpcError(message, kInvalidParams, | |
| 426 details: "registerService: invalid 'service' parameter: ${service}"); | |
| 427 } | |
| 428 if (alias is! String || alias == '') { | |
| 429 return encodeRpcError(message, kInvalidParams, | |
| 430 details: "registerService: invalid 'alias' parameter: ${alias}"); | |
| 431 } | |
| 432 if (client.services.containsKey(service)) { | |
| 433 return encodeRpcError(message, kServiceAlreadyRegistered); | |
|
siva
2017/07/13 01:07:40
Maybe add a test to ensure that this error is repo
cbernaschina
2017/07/13 04:10:15
Done.
| |
| 434 } | |
| 435 client.services[service] = alias; | |
| 436 | |
| 437 bool removed; | |
| 438 try { | |
| 439 removed = client.streams.remove(kServiceStream); | |
| 440 await _sendServiceRegisteredEvent(client, service); | |
| 441 } finally { | |
| 442 if (removed) client.streams.add(kServiceStream); | |
| 443 } | |
| 444 | |
| 445 return encodeSuccess(message); | |
| 446 } | |
| 447 | |
| 448 _sendServiceRegisteredEvent(Client client, String service, | |
| 449 {Client target}) async { | |
| 450 final namespace = clients.keyOf(client); | |
| 451 final alias = client.services[service]; | |
| 452 final event = JSON.encode({ | |
| 453 'jsonrpc': '2.0', | |
| 454 'method': 'streamNotify', | |
| 455 'params': { | |
| 456 'streamId': kServiceStream, | |
| 457 'event': { | |
| 458 "type": "Event", | |
| 459 "kind": "ServiceRegistered", | |
| 460 'timestamp': new DateTime.now().millisecondsSinceEpoch, | |
| 461 'service': service, | |
| 462 'method': namespace + '.' + service, | |
| 463 'alias': alias | |
| 464 } | |
| 465 } | |
| 466 }); | |
| 467 if (target == null) { | |
| 468 _eventMessageHandler([kServiceStream, event]); | |
| 469 } else { | |
| 470 target.post(event); | |
| 471 } | |
| 472 } | |
| 473 | |
| 474 Future<String> _handleService(Message message) async { | |
| 475 final namespace = _getNamespace(message.method); | |
| 476 final method = _getMethod(message.method); | |
| 477 final client = clients[namespace]; | |
| 478 if (client != null) { | |
| 479 if (client.services.containsKey(method)) { | |
| 480 final id = _serviceRequests.newId(); | |
| 481 final oldId = message.serial; | |
| 482 final completer = new Completer<String>(); | |
| 483 client.serviceHandles[id] = (Message m) { | |
| 484 if (m != null) { | |
| 485 completer.complete(JSON.encode(m.forwardToJson({'id': oldId}))); | |
| 486 } else { | |
| 487 completer.complete(encodeRpcError(message, kMethodNotFound, | |
| 488 details: "Service disappeared: ${message.method}")); | |
| 489 } | |
| 490 }; | |
| 491 client.post( | |
| 492 JSON.encode(message.forwardToJson({'id': id, 'method': method}))); | |
| 493 return completer.future; | |
| 494 } | |
| 495 } | |
| 496 return encodeRpcError(message, kMethodNotFound, | |
| 497 details: "Unknown service: ${message.method}"); | |
| 498 } | |
| 499 | |
| 349 Future<String> _spawnUri(Message message) async { | 500 Future<String> _spawnUri(Message message) async { |
| 350 var token = message.params['token']; | 501 var token = message.params['token']; |
| 351 if (token == null) { | 502 if (token == null) { |
| 352 return encodeMissingParamError(message, 'token'); | 503 return encodeMissingParamError(message, 'token'); |
| 353 } | 504 } |
| 354 if (token is! String) { | 505 if (token is! String) { |
| 355 return encodeInvalidParamError(message, 'token'); | 506 return encodeInvalidParamError(message, 'token'); |
| 356 } | 507 } |
| 357 var uri = message.params['uri']; | 508 var uri = message.params['uri']; |
| 358 if (uri == null) { | 509 if (uri == null) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 416 var getFlagListResponse = responseAsJson( | 567 var getFlagListResponse = responseAsJson( |
| 417 await new Message.fromUri(client, getFlagList).sendToVM()); | 568 await new Message.fromUri(client, getFlagList).sendToVM()); |
| 418 responses[getFlagList.toString()] = getFlagListResponse['result']; | 569 responses[getFlagList.toString()] = getFlagListResponse['result']; |
| 419 | 570 |
| 420 // Make requests to each isolate. | 571 // Make requests to each isolate. |
| 421 for (var isolate in isolates) { | 572 for (var isolate in isolates) { |
| 422 for (var request in perIsolateRequests) { | 573 for (var request in perIsolateRequests) { |
| 423 var message = new Message.forIsolate(client, request, isolate); | 574 var message = new Message.forIsolate(client, request, isolate); |
| 424 // Decode the JSON and and insert it into the map. The map key | 575 // Decode the JSON and and insert it into the map. The map key |
| 425 // is the request Uri. | 576 // is the request Uri. |
| 426 var response = responseAsJson(await isolate.route(message)); | 577 var response = responseAsJson(await isolate.routeRequest(message)); |
| 427 responses[message.toUri().toString()] = response['result']; | 578 responses[message.toUri().toString()] = response['result']; |
| 428 } | 579 } |
| 429 // Dump the object id ring requests. | 580 // Dump the object id ring requests. |
| 430 var message = | 581 var message = |
| 431 new Message.forIsolate(client, Uri.parse('_dumpIdZone'), isolate); | 582 new Message.forIsolate(client, Uri.parse('_dumpIdZone'), isolate); |
| 432 var response = responseAsJson(await isolate.route(message)); | 583 var response = responseAsJson(await isolate.routeRequest(message)); |
| 433 // Insert getObject requests into responses map. | 584 // Insert getObject requests into responses map. |
| 434 for (var object in response['result']['objects']) { | 585 for (var object in response['result']['objects']) { |
| 435 final requestUri = | 586 final requestUri = |
| 436 'getObject&isolateId=${isolate.serviceId}?objectId=${object["id"]}'; | 587 'getObject&isolateId=${isolate.serviceId}?objectId=${object["id"]}'; |
| 437 responses[requestUri] = object; | 588 responses[requestUri] = object; |
| 438 } | 589 } |
| 439 } | 590 } |
| 440 | 591 |
| 441 // Encode the entire crash dump. | 592 // Encode the entire crash dump. |
| 442 return encodeResult(message, responses); | 593 return encodeResult(message, responses); |
| 443 } | 594 } |
| 444 | 595 |
| 445 Future<String> route(Message message) { | 596 Future routeRequest(Message message) async { |
| 446 if (message.completed) { | 597 try { |
| 598 if (message.completed) { | |
| 599 return await message.response; | |
| 600 } | |
| 601 // TODO(turnidge): Update to json rpc. BEFORE SUBMIT. | |
| 602 if (message.method == '_getCrashDump') { | |
| 603 return await _getCrashDump(message); | |
| 604 } | |
| 605 if (message.method == 'streamListen') { | |
| 606 return await _streamListen(message); | |
| 607 } | |
| 608 if (message.method == 'streamCancel') { | |
| 609 return await _streamCancel(message); | |
| 610 } | |
| 611 if (message.method == '_registerService') { | |
| 612 return await _registerService(message); | |
| 613 } | |
| 614 if (message.method == '_spawnUri') { | |
| 615 return await _spawnUri(message); | |
| 616 } | |
| 617 if (devfs.shouldHandleMessage(message)) { | |
| 618 return await devfs.handleMessage(message); | |
| 619 } | |
| 620 if (_hasNamespace(message.method)) { | |
| 621 return await _handleService(message); | |
| 622 } | |
| 623 if (message.params['isolateId'] != null) { | |
| 624 return await runningIsolates.routeRequest(message); | |
| 625 } | |
| 626 return await message.sendToVM(); | |
| 627 } catch (e, st) { | |
| 628 message.setErrorResponse(kInternalError, 'Unexpected exception:$e\n$st'); | |
| 447 return message.response; | 629 return message.response; |
| 448 } | 630 } |
| 449 // TODO(turnidge): Update to json rpc. BEFORE SUBMIT. | 631 } |
| 450 if (message.method == '_getCrashDump') { | 632 |
| 451 return _getCrashDump(message); | 633 void routeResponse(message) { |
| 634 final client = message.client; | |
| 635 if (client.serviceHandles.containsKey(message.serial)) { | |
| 636 client.serviceHandles.remove(message.serial)(message); | |
| 637 _serviceRequests.release(message.serial); | |
| 452 } | 638 } |
| 453 if (message.method == 'streamListen') { | |
| 454 return _streamListen(message); | |
| 455 } | |
| 456 if (message.method == 'streamCancel') { | |
| 457 return _streamCancel(message); | |
| 458 } | |
| 459 if (message.method == '_spawnUri') { | |
| 460 return _spawnUri(message); | |
| 461 } | |
| 462 if (devfs.shouldHandleMessage(message)) { | |
| 463 return devfs.handleMessage(message); | |
| 464 } | |
| 465 if (message.params['isolateId'] != null) { | |
| 466 return runningIsolates.route(message); | |
| 467 } | |
| 468 return message.sendToVM(); | |
| 469 } | 639 } |
| 470 } | 640 } |
| 471 | 641 |
| 472 RawReceivePort boot() { | 642 RawReceivePort boot() { |
| 473 // Return the port we expect isolate control messages on. | 643 // Return the port we expect isolate control messages on. |
| 474 return isolateControlPort; | 644 return isolateControlPort; |
| 475 } | 645 } |
| 476 | 646 |
| 477 void _registerIsolate(int port_id, SendPort sp, String name) { | 647 void _registerIsolate(int port_id, SendPort sp, String name) { |
| 478 var service = new VMService(); | 648 var service = new VMService(); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 493 bool _vmListenStream(String streamId) native "VMService_ListenStream"; | 663 bool _vmListenStream(String streamId) native "VMService_ListenStream"; |
| 494 | 664 |
| 495 /// Cancel a subscription to a service stream. | 665 /// Cancel a subscription to a service stream. |
| 496 void _vmCancelStream(String streamId) native "VMService_CancelStream"; | 666 void _vmCancelStream(String streamId) native "VMService_CancelStream"; |
| 497 | 667 |
| 498 /// Get the bytes to the tar archive. | 668 /// Get the bytes to the tar archive. |
| 499 Uint8List _requestAssets() native "VMService_RequestAssets"; | 669 Uint8List _requestAssets() native "VMService_RequestAssets"; |
| 500 | 670 |
| 501 /// Notify the vm service that an isolate has been spawned via rpc. | 671 /// Notify the vm service that an isolate has been spawned via rpc. |
| 502 void _spawnUriNotify(obj, String token) native "VMService_spawnUriNotify"; | 672 void _spawnUriNotify(obj, String token) native "VMService_spawnUriNotify"; |
| OLD | NEW |