Index: sdk/lib/vmservice/vmservice.dart |
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart |
index f1253524dc8c38c1b6c3e09b9cef969fce810854..4101023f6c7dc585ad86a3591acaf7bda4cc1b24 100644 |
--- a/sdk/lib/vmservice/vmservice.dart |
+++ b/sdk/lib/vmservice/vmservice.dart |
@@ -12,6 +12,7 @@ import 'dart:typed_data'; |
part 'asset.dart'; |
part 'client.dart'; |
+part 'devfs.dart'; |
part 'constants.dart'; |
part 'running_isolate.dart'; |
part 'running_isolates.dart'; |
@@ -32,16 +33,24 @@ final Map<int, IsolateEmbedderData> isolateEmbedderData = |
new Map<int, IsolateEmbedderData>(); |
// These must be kept in sync with the declarations in vm/json_stream.h. |
-const kInvalidParams = -32602; |
-const kInternalError = -32603; |
-const kStreamAlreadySubscribed = 103; |
-const kStreamNotSubscribed = 104; |
+const kInvalidParams = -32602; |
+const kInternalError = -32603; |
+const kFeatureDisabled = 100; |
+const kStreamAlreadySubscribed = 103; |
+const kStreamNotSubscribed = 104; |
+const kFileSystemAlreadyExists = 1001; |
+const kFileSystemDoesNotExist = 1002; |
+const kFileDoesNotExist = 1003; |
var _errorMessages = { |
kInvalidParams: 'Invalid params', |
kInternalError: 'Internal error', |
+ kFeatureDisabled: 'Feature is disabled', |
kStreamAlreadySubscribed: 'Stream already subscribed', |
kStreamNotSubscribed: 'Stream not subscribed', |
+ kFileSystemAlreadyExists: 'File system already exists', |
+ kFileSystemDoesNotExist: 'File system does not exist', |
+ kFileDoesNotExist: 'File does not exist', |
}; |
String encodeRpcError(Message message, int code, {String details}) { |
@@ -61,6 +70,19 @@ String encodeRpcError(Message message, int code, {String details}) { |
return JSON.encode(response); |
} |
+String encodeMissingParamError(Message message, String param) { |
+ return encodeRpcError( |
+ message, kInvalidParams, |
+ details: "${message.method} expects the '${param}' parameter"); |
+} |
+ |
+String encodeInvalidParamError(Message message, String param) { |
+ var value = message.params[param]; |
+ return encodeRpcError( |
+ message, kInvalidParams, |
+ details: "${message.method}: invalid '${param}' parameter: ${value}"); |
+} |
+ |
String encodeResult(Message message, Map result) { |
var response = { |
'jsonrpc': '2.0', |
@@ -70,6 +92,10 @@ String encodeResult(Message message, Map result) { |
return JSON.encode(response); |
} |
+String encodeSuccess(Message message) { |
+ return encodeResult(message, { 'type': 'Success' }); |
+} |
+ |
const shortDelay = const Duration(milliseconds: 10); |
/// Called when the server should be started. |
@@ -81,11 +107,31 @@ typedef Future ServerStopCallback(); |
/// Called when the service is exiting. |
typedef Future CleanupCallback(); |
+/// Called to create a temporary directory |
+typedef Future<Uri> CreateTempDirCallback(String base); |
+ |
+/// Called to delete a directory |
+typedef Future DeleteDirCallback(Uri path); |
+ |
+/// Called to write a file. |
+typedef Future WriteFileCallback(Uri path, List<int> bytes); |
+ |
+/// Called to read a file. |
+typedef Future<List<int>> ReadFileCallback(Uri path); |
+ |
+/// Called to list all files under some path. |
+typedef Future<List<Map<String,String>>> ListFilesCallback(Uri path); |
+ |
/// Hooks that are setup by the embedder. |
class VMServiceEmbedderHooks { |
static ServerStartCallback serverStart; |
static ServerStopCallback serverStop; |
static CleanupCallback cleanup; |
+ static CreateTempDirCallback createTempDir; |
+ static DeleteDirCallback deleteDir; |
+ static WriteFileCallback writeFile; |
+ static ReadFileCallback readFile; |
+ static ListFilesCallback listFiles; |
} |
class VMService extends MessageRouter { |
@@ -100,6 +146,8 @@ class VMService extends MessageRouter { |
/// A port used to receive events from the VM. |
final RawReceivePort eventPort; |
+ final _devfs = new DevFS(); |
+ |
void _addClient(Client client) { |
assert(client.streams.isEmpty); |
clients.add(client); |
@@ -158,6 +206,7 @@ class VMService extends MessageRouter { |
for (var client in clientsList) { |
client.disconnect(); |
} |
+ _devfs.cleanup(); |
if (VMServiceEmbedderHooks.cleanup != null) { |
await VMServiceEmbedderHooks.cleanup(); |
} |
@@ -228,8 +277,7 @@ class VMService extends MessageRouter { |
} |
client.streams.add(streamId); |
- var result = { 'type' : 'Success' }; |
- return encodeResult(message, result); |
+ return encodeSuccess(message); |
} |
Future<String> _streamCancel(Message message) async { |
@@ -244,8 +292,7 @@ class VMService extends MessageRouter { |
_vmCancelStream(streamId); |
} |
- var result = { 'type' : 'Success' }; |
- return encodeResult(message, result); |
+ return encodeSuccess(message); |
} |
// TODO(johnmccutchan): Turn this into a command line tool that uses the |
@@ -320,6 +367,9 @@ class VMService extends MessageRouter { |
if (message.method == 'streamCancel') { |
return _streamCancel(message); |
} |
+ if (_devfs.shouldHandleMessage(message)) { |
+ return _devfs.handleMessage(message); |
+ } |
if (message.params['isolateId'] != null) { |
return runningIsolates.route(message); |
} |