14package org.dartlang.vm.service;
16import com.google.common.collect.Maps;
17import com.google.gson.JsonElement;
18import com.google.gson.JsonObject;
19import com.google.gson.JsonParser;
20import de.roderick.weberknecht.WebSocket;
21import de.roderick.weberknecht.WebSocketEventHandler;
22import de.roderick.weberknecht.WebSocketException;
23import de.roderick.weberknecht.WebSocketMessage;
24import org.dartlang.vm.service.consumer.*;
25import org.dartlang.vm.service.element.*;
26import org.dartlang.vm.service.internal.RequestSink;
27import org.dartlang.vm.service.internal.VmServiceConst;
28import org.dartlang.vm.service.internal.WebSocketRequestSink;
29import org.dartlang.vm.service.logging.Logging;
31import java.io.IOException;
33import java.net.URISyntaxException;
34import java.util.ArrayList;
37import java.util.concurrent.CountDownLatch;
38import java.util.concurrent.TimeUnit;
39import java.util.concurrent.atomic.AtomicInteger;
44@SuppressWarnings({
"unused",
"WeakerAccess"})
51 public static VmService
connect(
final String url)
throws IOException {
56 }
catch (URISyntaxException
e) {
57 throw new IOException(
"Invalid URL: " + url,
e);
59 String wsScheme = uri.getScheme();
61 throw new IOException(
"Unsupported URL scheme: " + wsScheme);
67 webSocket =
new WebSocket(uri);
68 }
catch (WebSocketException
e) {
69 throw new IOException(
"Failed to create websocket: " + url,
e);
71 final VmService vmService =
new VmService();
74 webSocket.setEventHandler(
new WebSocketEventHandler() {
76 public void onClose() {
79 vmService.connectionClosed();
83 public void onMessage(WebSocketMessage
message) {
86 vmService.processMessage(
message.getText());
87 }
catch (Exception
e) {
93 public void onOpen() {
94 vmService.connectionOpened();
100 public void onPing() {
104 public void onPong() {
112 }
catch (WebSocketException
e) {
113 throw new IOException(
"Failed to connect: " + url,
e);
114 }
catch (ArrayIndexOutOfBoundsException
e) {
117 throw new IOException(
"Failed to connect: " + url,
e);
122 final CountDownLatch latch =
new CountDownLatch(1);
123 final String[] errMsg =
new String[1];
124 vmService.getVersion(
new VersionConsumer() {
127 String msg =
"Failed to determine protocol version: " +
error.getCode() +
"\n message: "
128 +
error.getMessage() +
"\n details: " +
error.getDetails();
135 vmService.runtimeVersion =
version;
142 if (!latch.await(5, TimeUnit.SECONDS)) {
143 throw new IOException(
"Failed to determine protocol version");
145 if (errMsg[0] !=
null) {
146 throw new IOException(errMsg[0]);
148 }
catch (InterruptedException
e) {
149 throw new RuntimeException(
"Interrupted while waiting for response",
e);
164 return connect(
"ws://localhost:" +
port +
"/ws");
171 private final Map<String, Consumer> consumerMap = Maps.newHashMap();
176 private final Object consumerMapLock =
new Object();
181 private final AtomicInteger nextId =
new AtomicInteger();
186 private final List<VmServiceListener> vmListeners =
new ArrayList<>();
191 private final Map<String, RemoteServiceRunner> remoteServiceRunners = Maps.newHashMap();
204 vmListeners.add(listener);
211 vmListeners.remove(listener);
218 remoteServiceRunners.put(
service, runner);
225 remoteServiceRunners.remove(
service);
232 return runtimeVersion;
246 getObject(isolateId, instanceId,
new GetObjectConsumer() {
254 public void received(Obj response) {
255 if (response instanceof Instance) {
256 consumer.
received((Instance) response);
263 public void received(Sentinel response) {
273 getObject(isolateId, libraryId,
new GetObjectConsumer() {
281 public void received(Obj response) {
282 if (response instanceof Library) {
283 consumer.
received((Library) response);
290 public void received(Sentinel response) {
296 public abstract void getObject(String isolateId, String objectId, GetObjectConsumer consumer);
304 JsonObject
params =
new JsonObject();
305 params.addProperty(
"isolateId", isolateId);
306 request(method,
params, consumer);
315 params.addProperty(
"isolateId", isolateId);
316 request(method,
params, consumer);
325 String
id = Integer.toString(nextId.incrementAndGet());
326 JsonObject request =
new JsonObject();
328 request.addProperty(JSONRPC, JSONRPC_VERSION);
329 request.addProperty(ID,
id);
330 request.addProperty(METHOD, method);
331 request.add(PARAMS,
params);
334 synchronized (consumerMapLock) {
335 consumerMap.put(
id, consumer);
339 requestSink.
add(request);
345 listener.connectionOpened();
346 }
catch (Exception
e) {
352 private void forwardEvent(String streamId,
Event event) {
355 listener.received(streamId,
event);
356 }
catch (Exception
e) {
357 Logging.getLogger().logError(
"Exception processing event: " + streamId +
", " +
event.getJson(),
e);
365 listener.connectionClosed();
366 }
catch (Exception
e) {
375 Class<? extends Consumer> consumerClass = consumer.getClass();
376 StringBuilder msg =
new StringBuilder();
377 msg.append(
"Expected response for ").append(consumerClass).append(
"\n");
378 for (Class<?> interf : consumerClass.getInterfaces()) {
379 msg.append(
" implementing ").append(interf).append(
"\n");
381 msg.append(
" but received ").append(json);
390 if (jsonText ==
null || jsonText.isEmpty()) {
397 json = (JsonObject)
new JsonParser().parse(jsonText);
398 }
catch (Exception
e) {
403 if (json.has(
"method")) {
404 if (!json.has(PARAMS)) {
405 final String
message =
"Missing " + PARAMS;
407 final JsonObject response =
new JsonObject();
408 response.addProperty(JSONRPC, JSONRPC_VERSION);
409 final JsonObject
error =
new JsonObject();
410 error.addProperty(CODE, INVALID_REQUEST);
413 requestSink.
add(response);
416 if (json.has(
"id")) {
417 processRequest(json);
419 processNotification(json);
421 }
else if (json.has(
"result") || json.has(
"error")) {
422 processResponse(json);
429 final JsonObject response =
new JsonObject();
430 response.addProperty(JSONRPC, JSONRPC_VERSION);
435 id = json.get(ID).getAsString();
436 }
catch (Exception
e) {
437 final String
message =
"Request malformed " + ID;
439 final JsonObject
error =
new JsonObject();
440 error.addProperty(CODE, INVALID_REQUEST);
443 requestSink.
add(response);
447 response.addProperty(ID,
id);
451 method = json.get(METHOD).getAsString();
452 }
catch (Exception
e) {
453 final String
message =
"Request malformed " + METHOD;
455 final JsonObject
error =
new JsonObject();
456 error.addProperty(CODE, INVALID_REQUEST);
459 requestSink.
add(response);
465 params = json.get(PARAMS).getAsJsonObject();
466 }
catch (Exception
e) {
467 final String
message =
"Request malformed " + METHOD;
469 final JsonObject
error =
new JsonObject();
470 error.addProperty(CODE, INVALID_REQUEST);
473 requestSink.
add(response);
477 if (!remoteServiceRunners.containsKey(method)) {
478 final String
message =
"Unknown service " + method;
480 final JsonObject
error =
new JsonObject();
481 error.addProperty(CODE, METHOD_NOT_FOUND);
484 requestSink.
add(response);
493 requestSink.
add(response);
497 final JsonObject
error =
new JsonObject();
504 requestSink.
add(response);
507 }
catch (Exception
e) {
508 final String
message =
"Internal Server Error";
510 final JsonObject
error =
new JsonObject();
511 error.addProperty(CODE, SERVER_ERROR);
514 requestSink.
add(response);
532 method = json.get(METHOD).getAsString();
533 }
catch (Exception
e) {
539 params = json.get(PARAMS).getAsJsonObject();
540 }
catch (Exception
e) {
544 if (
"streamNotify".
equals(method)) {
547 streamId =
params.get(STREAM_ID).getAsString();
548 }
catch (Exception
e) {
554 event =
new Event(
params.get(EVENT).getAsJsonObject());
555 }
catch (Exception
e) {
559 forwardEvent(streamId,
event);
561 if (!remoteServiceRunners.containsKey(method)) {
569 }
catch (Exception
e) {
576 return str.replaceAll(
"\r\n",
" ").replaceAll(
"\n",
" ");
580 JsonElement idElem = json.get(ID);
581 if (idElem ==
null) {
589 id = idElem.getAsString();
590 }
catch (Exception
e) {
594 Consumer consumer = consumerMap.remove(
id);
595 if (consumer ==
null) {
601 JsonElement resultElem = json.get(
RESULT);
602 if (resultElem !=
null) {
605 result = resultElem.getAsJsonObject();
606 }
catch (Exception
e) {
610 String responseType =
"";
612 responseType =
result.get(
TYPE).getAsString();
619 forwardResponse(consumer, responseType,
result);
624 resultElem = json.get(
ERROR);
625 if (resultElem !=
null) {
628 error = resultElem.getAsJsonObject();
629 }
catch (Exception
e) {
GrAATriangulator::Event Event
bool equals(SkDrawable *a, SkDrawable *b)
void addServiceRunner(String service, RemoteServiceRunner runner)
void processNotification(JsonObject json)
void processResponse(JsonObject json)
String removeNewLines(String str)
void getLibrary(String isolateId, String libraryId, final GetLibraryConsumer consumer)
static VmService connect(final String url)
void logUnknownResponse(Consumer consumer, JsonObject json)
void request(String method, JsonObject params, Consumer consumer)
void removeServiceRunner(String service)
void callServiceExtension(String isolateId, String method, JsonObject params, ServiceExtensionConsumer consumer)
void processRequest(JsonObject json)
void addVmServiceListener(VmServiceListener listener)
void processMessage(String jsonText)
Version getRuntimeVersion()
abstract void getObject(String isolateId, String objectId, GetObjectConsumer consumer)
void getInstance(String isolateId, String instanceId, final GetInstanceConsumer consumer)
static VmService localConnect(int port)
void callServiceExtension(String isolateId, String method, ServiceExtensionConsumer consumer)
abstract void forwardResponse(Consumer consumer, String type, JsonObject json)
void removeVmServiceListener(VmServiceListener listener)
static RPCError unexpected(String expectedType, Response response)
static Logger getLogger()
const EmbeddedViewParams * params
const uint8_t uint32_t uint32_t GError ** error
void run(JsonObject params, RemoteServiceCompleter completer)
void onError(RPCError error)
void received(Instance response)
void received(Library response)
void add(JsonObject request)
void logError(String message)
void logInformation(String message)
const CatchEntryMove de[]
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service port
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm service
std::shared_ptr< const fml::Mapping > data