android/app/src/main/cpp/androidapp.cpp | 84 +++------- android/app/src/main/java/org/libreoffice/androidapp/MainActivity.java | 26 +-- 2 files changed, 42 insertions(+), 68 deletions(-)
New commits: commit 40ffc4306a26e59c5bf38576420baabd61921ca8 Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Fri Feb 15 18:45:18 2019 +0100 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Fri Feb 15 18:45:18 2019 +0100 android: Passing messages from the native code to JS (incomplete). Later we can come up with a way how to call it directly, but for the moment, the indirection through Java is the easiest to implement. Incomplete, needs a bit of more work to work from the thread. Change-Id: I85ec997e32b5bd7d809142307e6fbaf42fc6ec2d diff --git a/android/app/src/main/cpp/androidapp.cpp b/android/app/src/main/cpp/androidapp.cpp index 763cf672f..ab6f1586e 100644 --- a/android/app/src/main/cpp/androidapp.cpp +++ b/android/app/src/main/cpp/androidapp.cpp @@ -20,6 +20,8 @@ #include <Protocol.hpp> #include <Util.hpp> +#include "Poco/Base64Encoder.h" + const int SHOW_JS_MAXLEN = 70; int loolwsd_server_socket_fd = -1; @@ -29,15 +31,7 @@ static LOOLWSD *loolwsd = nullptr; static int fakeClientFd; static int closeNotificationPipeForForwardingThread[2]; -#if 0 -static void send2JS_ready_callback(GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - free(user_data); -} - -static void send2JS(const std::vector<char>& buffer) +static void send2JS(JNIEnv *env, jobject obj, const std::vector<char>& buffer) { LOG_TRC_NOFILE("Send to JS: " << LOOLProtocol::getAbbreviatedMessage(buffer.data(), buffer.size())); @@ -53,11 +47,16 @@ static void send2JS(const std::vector<char>& buffer) if (newline != nullptr) { // The data needs to be an ArrayBuffer - js = "window.TheFakeWebSocket.onmessage({'data': Base64ToArrayBuffer('"; - gchar *base64 = g_base64_encode((const guchar*)buffer.data(), buffer.size()); - js = js + std::string(base64); - g_free(base64); - js = js + "')});"; + std::stringstream ss; + ss << "Base64ToArrayBuffer('"; + + Poco::Base64Encoder encoder(ss); + encoder << std::string(buffer.data(), buffer.size()); + encoder.close(); + + ss << "')"; + + js = ss.str(); } else { @@ -79,59 +78,26 @@ static void send2JS(const std::vector<char>& buffer) } data.push_back(0); - js = "window.TheFakeWebSocket.onmessage({'data': '"; - js = js + std::string(buffer.data(), buffer.size()); - js = js + "'});"; + js = std::string(data.data(), data.size()); } std::string subjs = js.substr(0, std::min(std::string::size_type(SHOW_JS_MAXLEN), js.length())); if (js.length() > SHOW_JS_MAXLEN) subjs += "..."; - LOG_TRC_NOFILE( "Evaluating JavaScript: " << subjs); - - char *jscopy = strdup(js.c_str()); - g_idle_add([](gpointer data) - { - char *jscopy = (char*) data; - webkit_web_view_run_javascript(webView, jscopy, nullptr, send2JS_ready_callback, jscopy); - return FALSE; - }, jscopy); -} + LOG_TRC_NOFILE( "Sending to JavaScript: " << subjs); -static char *js_result_as_gstring(WebKitJavascriptResult *js_result) -{ -#if WEBKIT_CHECK_VERSION(2,22,0) // unclear when this API changed ... - JSCValue *value = webkit_javascript_result_get_js_value(js_result); - if (jsc_value_is_string(value)) - return jsc_value_to_string(value); - else - return nullptr; -#else // older Webkits - JSValueRef value = webkit_javascript_result_get_value(js_result); - JSContextRef ctx = webkit_javascript_result_get_global_context(js_result); - if (JSValueIsString(ctx, value)) - { - const JSStringRef js_str = JSValueToStringCopy(ctx, value, nullptr); - size_t gstring_max = JSStringGetMaximumUTF8CStringSize(js_str); - char *gstring = (char *)g_malloc(gstring_max); - if (gstring) - JSStringGetUTF8CString(js_str, gstring, gstring_max); - else - LOG_TRC_NOFILE("No string"); - JSStringRelease(js_str); - return gstring; - } - else - LOG_TRC_NOFILE("Unexpected object type " << JSValueGetType(ctx, value)); - return nullptr; -#endif + /* TODO commented out, see the other TODO wrt. the NewGlobalRef + jstring jstr = env->NewStringUTF(js.c_str()); + jclass clazz = env->FindClass("org/libreoffice/androidapp/MainActivity"); + jmethodID callFakeWebsocket = env->GetMethodID(clazz, "callFakeWebsocketOnMessage", "(V)Ljava/lang/String;"); + env->CallObjectMethod(obj, callFakeWebsocket, jstr); + */ } -#endif /// Handle a message from JavaScript. extern "C" JNIEXPORT void JNICALL -Java_org_libreoffice_androidapp_MainActivity_postMobileMessage(JNIEnv *env, jobject, jstring message) +Java_org_libreoffice_androidapp_MainActivity_postMobileMessage(JNIEnv *env, jobject obj, jstring message) { const char *string_value = env->GetStringUTFChars(message, nullptr); @@ -153,7 +119,9 @@ Java_org_libreoffice_androidapp_MainActivity_postMobileMessage(JNIEnv *env, jobj fakeSocketPipe2(closeNotificationPipeForForwardingThread); // Start another thread to read responses and forward them to the JavaScript - std::thread([] + // TODO here we actually need to do NewGlobalRef and pass that to + // the thread; not the env and obj itself + std::thread([&env, &obj] { Util::setThreadName("app2js"); while (true) @@ -188,7 +156,7 @@ Java_org_libreoffice_androidapp_MainActivity_postMobileMessage(JNIEnv *env, jobj return; std::vector<char> buf(n); n = fakeSocketRead(fakeClientFd, buf.data(), n); - // TODO send2JS(buf); + send2JS(env, obj, buf); } } else diff --git a/android/app/src/main/java/org/libreoffice/androidapp/MainActivity.java b/android/app/src/main/java/org/libreoffice/androidapp/MainActivity.java index 87047f17d..173513e5c 100644 --- a/android/app/src/main/java/org/libreoffice/androidapp/MainActivity.java +++ b/android/app/src/main/java/org/libreoffice/androidapp/MainActivity.java @@ -38,6 +38,8 @@ public class MainActivity extends AppCompatActivity { private static final String ASSETS_EXTRACTED_PREFS_KEY = "ASSETS_EXTRACTED"; + WebView mWebView; + private static boolean copyFromAssets(AssetManager assetManager, String fromAssetPath, String targetDir) { try { @@ -126,14 +128,14 @@ public class MainActivity extends AppCompatActivity { createLOOLWSD(dataDir, cacheDir, apkFile, assetManager, urlToLoad); - final WebView browser = findViewById(R.id.browser); - browser.setWebViewClient(new WebViewClient()); + mWebView = findViewById(R.id.browser); + mWebView.setWebViewClient(new WebViewClient()); - WebSettings browserSettings = browser.getSettings(); - browserSettings.setJavaScriptEnabled(true); - browser.addJavascriptInterface(this, "LOOLMessageHandler"); + WebSettings webSettings = mWebView.getSettings(); + webSettings.setJavaScriptEnabled(true); + mWebView.addJavascriptInterface(this, "LOOLMessageHandler"); - browser.loadUrl("file:///android_asset/dist/loleaflet.html?file_path=" + + mWebView.loadUrl("file:///android_asset/dist/loleaflet.html?file_path=" + urlToLoad + "&closebutton=1&permission=edit" + "&debug=true"); // TODO remove later? @@ -161,19 +163,23 @@ public class MainActivity extends AppCompatActivity { /** Passing messages from JS (instead of the websocket communication). */ @JavascriptInterface - public void postMobileError(String message) - { + public void postMobileError(String message) { // TODO handle this Log.d(TAG, "postMobileError: " + message); } /** Passing messages from JS (instead of the websocket communication). */ @JavascriptInterface - public void postMobileDebug(String message) - { + public void postMobileDebug(String message) { // TODO handle this Log.d(TAG, "postMobileDebug: " + message); } + + /** Passing message the other way around - from Java to the FakeWebSocket in JS. */ + void callFakeWebsocketOnMessage(String message) { + Log.i(TAG,"Got JavaScript, forwarding to the WebView: " + message); + mWebView.loadUrl("javascript:window.TheFakeWebSocket.onmessage({'data': '" + message + "'});"); + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits