Chromium Code Reviews| Index: sdk/lib/vmservice/vmservice.dart | 
| diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart | 
| index a56c2932d4e40df002f369d2ffabe7cb1f04517b..75de45930797208111b7689cf5252bc4f2448a27 100644 | 
| --- a/sdk/lib/vmservice/vmservice.dart | 
| +++ b/sdk/lib/vmservice/vmservice.dart | 
| @@ -7,7 +7,9 @@ library dart._vmservice; | 
| import 'dart:async'; | 
| import 'dart:collection'; | 
| import 'dart:convert'; | 
| +import 'dart:developer' show ServiceProtocolInfo; | 
| import 'dart:isolate'; | 
| +import 'dart:math'; | 
| import 'dart:typed_data'; | 
| part 'asset.dart'; | 
| @@ -19,13 +21,26 @@ part 'running_isolates.dart'; | 
| part 'message.dart'; | 
| part 'message_router.dart'; | 
| -final RawReceivePort isolateLifecyclePort = new RawReceivePort(); | 
| +final RawReceivePort isolateControlPort = new RawReceivePort(); | 
| final RawReceivePort scriptLoadPort = new RawReceivePort(); | 
| abstract class IsolateEmbedderData { | 
| void cleanup(); | 
| } | 
| +String _makeAuthToken() { | 
| + final kTokenByteSize = 8; | 
| + Uint8List bytes = new Uint8List(kTokenByteSize); | 
| + Random random = new Random.secure(); | 
| + for (int i = 0; i < kTokenByteSize; i++) { | 
| + bytes[i] = random.nextInt(256); | 
| + } | 
| + return BASE64URL.encode(bytes); | 
| +} | 
| + | 
| +// The randomly generated auth token used to access the VM service. | 
| +final String serviceAuthToken = _makeAuthToken(); | 
| + | 
| // This is for use by the embedder. It is a map from the isolateId to | 
| // anything implementing IsolateEmbedderData. When an isolate goes away, | 
| // the cleanup method will be invoked after being removed from the map. | 
| @@ -125,6 +140,12 @@ typedef Future<List<int>> ReadFileCallback(Uri path); | 
| /// Called to list all files under some path. | 
| typedef Future<List<Map<String,String>>> ListFilesCallback(Uri path); | 
| +/// Called when we need information about the server. | 
| +typedef Future<Uri> ServerInformationCallback(); | 
| + | 
| +/// Called when we want to [enable] or disable the web server. | 
| +typedef Future<Uri> WebServerControlCallback(bool enable); | 
| + | 
| /// Hooks that are setup by the embedder. | 
| class VMServiceEmbedderHooks { | 
| static ServerStartCallback serverStart; | 
| @@ -136,6 +157,8 @@ class VMServiceEmbedderHooks { | 
| static WriteStreamFileCallback writeStreamFile; | 
| static ReadFileCallback readFile; | 
| static ListFilesCallback listFiles; | 
| + static ServerInformationCallback serverInformation; | 
| + static WebServerControlCallback webServerControl; | 
| } | 
| class VMService extends MessageRouter { | 
| @@ -194,6 +217,27 @@ class VMService extends MessageRouter { | 
| } | 
| } | 
| + Future<Null> _serverMessageHandler(int code, SendPort sp, bool enable) async { | 
| 
 
rmacnak
2016/10/20 17:12:31
Future
 
Cutch
2016/10/20 23:31:51
Strong mode requires Future<Null> :(
 
 | 
| + switch (code) { | 
| + case Constants.WEB_SERVER_CONTROL_MESSAGE_ID: | 
| + if (VMServiceEmbedderHooks.webServerControl == null) { | 
| + sp.send(null); | 
| + return; | 
| + } | 
| + Uri uri = await VMServiceEmbedderHooks.webServerControl(enable); | 
| + sp.send(uri); | 
| + break; | 
| + case Constants.SERVER_INFO_MESSAGE_ID: | 
| + if (VMServiceEmbedderHooks.serverInformation == null) { | 
| + sp.send(null); | 
| + return; | 
| + } | 
| + Uri uri = await VMServiceEmbedderHooks.serverInformation(); | 
| + sp.send(uri); | 
| + break; | 
| + } | 
| + } | 
| + | 
| Future _exit() async { | 
| // Stop the server. | 
| if (VMServiceEmbedderHooks.serverStop != null) { | 
| @@ -201,7 +245,7 @@ class VMService extends MessageRouter { | 
| } | 
| // Close receive ports. | 
| - isolateLifecyclePort.close(); | 
| + isolateControlPort.close(); | 
| scriptLoadPort.close(); | 
| // Create a copy of the set as a list because client.disconnect() will | 
| @@ -233,6 +277,13 @@ class VMService extends MessageRouter { | 
| _exit(); | 
| return; | 
| } | 
| + if (message.length == 3) { | 
| + // This is a message interacting with the web server. | 
| + assert((message[0] == Constants.WEB_SERVER_CONTROL_MESSAGE_ID) || | 
| + (message[0] == Constants.SERVER_INFO_MESSAGE_ID)); | 
| + _serverMessageHandler(message[0], message[1], message[2]); | 
| + return; | 
| + } | 
| if (message.length == 4) { | 
| // This is a message informing us of the birth or death of an | 
| // isolate. | 
| @@ -244,7 +295,7 @@ class VMService extends MessageRouter { | 
| } | 
| VMService._internal() | 
| - : eventPort = isolateLifecyclePort { | 
| + : eventPort = isolateControlPort { | 
| eventPort.handler = messageHandler; | 
| } | 
| @@ -425,8 +476,8 @@ class VMService extends MessageRouter { | 
| } | 
| RawReceivePort boot() { | 
| - // Return the port we expect isolate startup and shutdown messages on. | 
| - return isolateLifecyclePort; | 
| + // Return the port we expect isolate control messages on. | 
| + return isolateControlPort; | 
| } | 
| void _registerIsolate(int port_id, SendPort sp, String name) { |