[Libreoffice-commits] online.git: android/app

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Feb 15 17:48:21 UTC 2019


 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 <kendy at collabora.com>
AuthorDate: Fri Feb 15 18:45:18 2019 +0100
Commit:     Jan Holesovsky <kendy at 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: */


More information about the Libreoffice-commits mailing list