diff --git a/runtime/src/main/java/com/tns/AndroidJsV8Inspector.java b/runtime/src/main/java/com/tns/AndroidJsV8Inspector.java index 1c4a79338..ca94820a2 100644 --- a/runtime/src/main/java/com/tns/AndroidJsV8Inspector.java +++ b/runtime/src/main/java/com/tns/AndroidJsV8Inspector.java @@ -4,6 +4,10 @@ import android.os.Handler; import android.util.Log; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + import java.io.IOException; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -27,19 +31,17 @@ public class AndroidJsV8Inspector protected static native final void disconnect(); protected native final void dispatchMessage(String message); + protected Handler mainHandler; private LinkedBlockingQueue inspectorMessages = new LinkedBlockingQueue(); - public AndroidJsV8Inspector(Context context, Logger logger) - { + public AndroidJsV8Inspector(Context context, Logger logger) { this.context = context; this.logger = logger; } - public void start() throws IOException - { - if (this.server == null) - { + public void start() throws IOException { + if (this.server == null) { Runtime currentRuntime = Runtime.getCurrentRuntime(); mainHandler = currentRuntime.getHandler(); @@ -56,20 +58,45 @@ public void start() throws IOException } } - private static void send(Object connection, String payload) throws IOException - { + @RuntimeCallable + private static void sendToDevToolsConsole(Object connection, String message, String level) { + try { + JSONObject consoleMessage = new JSONObject(); + + JSONObject params = new JSONObject(); + params.put("type", level); + params.put("executionContextId", 0); + params.put("timestamp", 0.000000000000000); + + JSONArray args = new JSONArray(); + args.put(message); + params.put("args", args); + + consoleMessage.put("method", "Runtime.consoleAPICalled"); + consoleMessage.put("params", params); + + String sendingText = consoleMessage.toString(); + AndroidJsV8Inspector.send(connection, sendingText); + + } catch (JSONException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @RuntimeCallable + private static void send(Object connection, String payload) throws IOException { ((JsV8InspectorWebSocket) connection).send(payload); } - private static String getInspectorMessage(Object connection) - { + @RuntimeCallable + private static String getInspectorMessage(Object connection) { return ((JsV8InspectorWebSocket) connection).getInspectorMessage(); } - class JsV8InspectorServer extends NanoWSD - { - public JsV8InspectorServer(String name) - { + class JsV8InspectorServer extends NanoWSD { + public JsV8InspectorServer(String name) { super(name); } @@ -84,17 +111,14 @@ protected Response serveHttp(IHTTPSession session) } @Override - protected WebSocket openWebSocket(IHTTPSession handshake) - { + protected WebSocket openWebSocket(IHTTPSession handshake) { return new JsV8InspectorWebSocket(handshake); } } - class JsV8InspectorWebSocket extends NanoWSD.WebSocket - { + class JsV8InspectorWebSocket extends NanoWSD.WebSocket { - public JsV8InspectorWebSocket(NanoHTTPD.IHTTPSession handshakeRequest) - { + public JsV8InspectorWebSocket(NanoHTTPD.IHTTPSession handshakeRequest) { super(handshakeRequest); } @@ -106,8 +130,7 @@ protected void onOpen() Log.d("V8Inspector", "onOpen: ThreadID: " + Thread.currentThread().getId()); } - mainHandler.post(new Runnable() - { + mainHandler.post(new Runnable() { @Override public void run() { @@ -153,14 +176,11 @@ protected void onMessage(final NanoWSD.WebSocketFrame message) inspectorMessages.offer(message.getTextPayload()); - mainHandler.post(new Runnable() - { + mainHandler.post(new Runnable() { @Override - public void run() - { + public void run() { String nextMessage = inspectorMessages.poll(); - while (nextMessage != null) - { + while (nextMessage != null) { dispatchMessage(nextMessage); nextMessage = inspectorMessages.poll(); } @@ -179,15 +199,11 @@ public void send(String payload) throws IOException super.send(payload); } - public String getInspectorMessage() - { - try - { + public String getInspectorMessage() { + try { String message = inspectorMessages.take(); return message; - } - catch (InterruptedException e) - { + } catch (InterruptedException e) { e.printStackTrace(); } @@ -200,10 +216,9 @@ protected void onPong(NanoWSD.WebSocketFrame pong) } @Override - protected void onException(IOException exception) - { + protected void onException(IOException exception) { exception.printStackTrace(); disconnect(); } } -} \ No newline at end of file +} diff --git a/runtime/src/main/jni/JsV8InspectorClient.cpp b/runtime/src/main/jni/JsV8InspectorClient.cpp index ad283f85e..a62434de6 100644 --- a/runtime/src/main/jni/JsV8InspectorClient.cpp +++ b/runtime/src/main/jni/JsV8InspectorClient.cpp @@ -8,7 +8,7 @@ #include #include #include "Runtime.h" -#include "src/inspector/string-16.h" +#include "NativeScriptException.h" #include "ArgConverter.h" @@ -33,6 +33,9 @@ JsV8InspectorClient::JsV8InspectorClient(v8::Isolate *isolate) sendMethod = env.GetStaticMethodID(inspectorClass, "send", "(Ljava/lang/Object;Ljava/lang/String;)V"); assert(sendMethod != nullptr); + sendToDevToolsConsoleMethod = env.GetStaticMethodID(inspectorClass, "sendToDevToolsConsole", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V"); + assert(sendToDevToolsConsoleMethod != nullptr); + getInspectorMessageMethod = env.GetStaticMethodID(inspectorClass, "getInspectorMessage", "(Ljava/lang/Object;)Ljava/lang/String;"); assert(getInspectorMessageMethod != nullptr); } @@ -152,8 +155,8 @@ void JsV8InspectorClient::sendProtocolNotification(const v8_inspector::StringVie JEnv env; const char *msss = msg.utf8().c_str(); - JniLocalRef string(env.NewStringUTF(msg.utf8().c_str())); - env.CallStaticVoidMethod(inspectorClass, sendMethod, this->connection, (jstring) string); + JniLocalRef str(env.NewStringUTF(msg.utf8().c_str())); + env.CallStaticVoidMethod(inspectorClass, sendMethod, this->connection, (jstring) str); } void JsV8InspectorClient::flushProtocolNotifications() @@ -197,7 +200,6 @@ void JsV8InspectorClient::init() v8::Local context = Context::New(isolate_); v8::Context::Scope context_scope(context); - inspector_ = V8Inspector::create(isolate_, this); inspector_->contextCreated(v8_inspector::V8ContextInfo(context, 0, v8_inspector::StringView())); @@ -218,6 +220,47 @@ JsV8InspectorClient *JsV8InspectorClient::GetInstance() return instance; } + +void JsV8InspectorClient::sendToFrontEndCallback(const v8::FunctionCallbackInfo& args) { + + if(instance->connection == nullptr) { + return; + } + + try + { + if ((args.Length() > 0) && args[0]->IsString()) + { + std::string message = ArgConverter::ConvertToString(args[0]->ToString()); + + std:string level = "log"; + if (args.Length() > 1 && args[1]->IsString()) + { + level = ArgConverter::ConvertToString(args[1]->ToString()); + } + + JEnv env; + JniLocalRef str(env.NewStringUTF(message.c_str())); + JniLocalRef lev(env.NewStringUTF(level.c_str())); + env.CallStaticVoidMethod(inspectorClass, sendToDevToolsConsoleMethod, instance->connection, (jstring) str, (jstring)lev); + } + } + catch (NativeScriptException& e) + { + e.ReThrowToV8(); + } + catch (std::exception e) { + stringstream ss; + ss << "Error: c++ exception: " << e.what() << endl; + NativeScriptException nsEx(ss.str()); + nsEx.ReThrowToV8(); + } + catch (...) { + NativeScriptException nsEx(std::string("Error: c++ exception!")); + nsEx.ReThrowToV8(); + } +} + void MessageHandler(v8::Local message, v8::Local exception) { // v8::Isolate *isolate = v8::Isolate::GetCurrent(); @@ -257,6 +300,7 @@ void MessageHandler(v8::Local message, v8::Local excepti JsV8InspectorClient *JsV8InspectorClient::instance = nullptr; jclass JsV8InspectorClient::inspectorClass = nullptr; jmethodID JsV8InspectorClient::sendMethod = nullptr; +jmethodID JsV8InspectorClient::sendToDevToolsConsoleMethod = nullptr; jmethodID JsV8InspectorClient::getInspectorMessageMethod = nullptr; diff --git a/runtime/src/main/jni/JsV8InspectorClient.h b/runtime/src/main/jni/JsV8InspectorClient.h index 4b0e8237e..dd5927a8c 100644 --- a/runtime/src/main/jni/JsV8InspectorClient.h +++ b/runtime/src/main/jni/JsV8InspectorClient.h @@ -35,6 +35,8 @@ namespace tns void sendProtocolNotification(const v8_inspector::StringView &message) override; void flushProtocolNotifications() override; + static void sendToFrontEndCallback(const v8::FunctionCallbackInfo& args); + void runMessageLoopOnPause(int context_group_id) override; void quitMessageLoopOnPause() override; v8::Local ensureDefaultContextInGroup(int contextGroupId) override; @@ -46,6 +48,7 @@ namespace tns static jclass inspectorClass; static jmethodID sendMethod; static jmethodID getInspectorMessageMethod; + static jmethodID sendToDevToolsConsoleMethod; v8::Isolate* isolate_; v8::Persistent context_; diff --git a/runtime/src/main/jni/Runtime.cpp b/runtime/src/main/jni/Runtime.cpp index 95c02c37d..8f57256ab 100644 --- a/runtime/src/main/jni/Runtime.cpp +++ b/runtime/src/main/jni/Runtime.cpp @@ -24,6 +24,7 @@ #include #include #include "sys/system_properties.h" +#include "JsV8InspectorClient.h" using namespace v8; using namespace std; @@ -563,7 +564,7 @@ Isolate* Runtime::PrepareV8Runtime(const string& filesPath, jstring nativeLibDir globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__log"), FunctionTemplate::New(isolate, CallbackHandlers::LogMethodCallback)); globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__dumpReferenceTables"), FunctionTemplate::New(isolate, CallbackHandlers::DumpReferenceTablesMethodCallback)); globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__debugbreak"), FunctionTemplate::New(isolate, JsDebugger::DebugBreakCallback)); - globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__consoleMessage"), FunctionTemplate::New(isolate, JsDebugger::ConsoleMessageCallback)); + globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__consoleMessage"), FunctionTemplate::New(isolate, JsV8InspectorClient::sendToFrontEndCallback)); globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__enableVerboseLogging"), FunctionTemplate::New(isolate, CallbackHandlers::EnableVerboseLoggingMethodCallback)); globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__disableVerboseLogging"), FunctionTemplate::New(isolate, CallbackHandlers::DisableVerboseLoggingMethodCallback)); globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__exit"), FunctionTemplate::New(isolate, CallbackHandlers::ExitMethodCallback)); diff --git a/test-app/app/src/main/assets/app/shared b/test-app/app/src/main/assets/app/shared index bcc8d1575..7899ecbf8 160000 --- a/test-app/app/src/main/assets/app/shared +++ b/test-app/app/src/main/assets/app/shared @@ -1 +1 @@ -Subproject commit bcc8d15752a460154ba401cc2b84632c29324003 +Subproject commit 7899ecbf8c876582fcba1cb1f7ad7d482d7d90aa