android/lib/src/main/cpp/androidapp.cpp | 57 ++++++--- android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java | 58 ++++++++-- android/lib/src/main/res/values/strings.xml | 4 3 files changed, 89 insertions(+), 30 deletions(-)
New commits: commit 2f7fac7547d1895fc317003d04017c468f4af179 Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Fri Jul 19 17:38:31 2019 +0200 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Fri Jul 19 17:59:06 2019 +0200 android: Fix the LOActivity lifecycle in several ways. First of all, we shouldn't destroy the document in onStop(), instead do that in onDestroy(). onStop() should only (auto-)save the document, but otherwise keep it open, so that when we return from the file picker Activity, the caret is at the same position as it was before. In addition to that, we should close any open document before we try to open the new one (in createLOOLWSD). And finally, when closing the document, we should wait until after the LOOLWSD is completely torn down, so that we avoid the risk that the user tries to load another document too quickly, and the messages from the JS go into the old, still running LOOLWSD. Change-Id: Ib775021bccc5d5bc69aae392a88dc62a7c05a8fa diff --git a/android/lib/src/main/cpp/androidapp.cpp b/android/lib/src/main/cpp/androidapp.cpp index 32610fbf5..f15ebc6a6 100644 --- a/android/lib/src/main/cpp/androidapp.cpp +++ b/android/lib/src/main/cpp/androidapp.cpp @@ -31,9 +31,10 @@ int loolwsd_server_socket_fd = -1; static std::string fileURL; static int fakeClientFd; -static int closeNotificationPipeForForwardingThread[2]; +static int closeNotificationPipeForForwardingThread[2] = {-1, -1}; static JavaVM* javaVM = nullptr; static bool lokInitialized = false; +static std::mutex loolwsdRunningMutex; extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { @@ -142,6 +143,18 @@ static void send2JS(jclass loActivityClz, jobject loActivityObj, const std::vect javaVM->DetachCurrentThread(); } +/// Close the document. +void closeDocument() +{ + // Close one end of the socket pair, that will wake up the forwarding thread that was contstructed in HULLO + if (fakeSocketClose(closeNotificationPipeForForwardingThread[0]) == 0) + { + LOG_DBG("Waiting for LOOLWSD to finish..."); + std::unique_lock<std::mutex> lock(loolwsdRunningMutex); + LOG_DBG("LOOLWSD has finished."); + } +} + /// Handle a message from JavaScript. extern "C" JNIEXPORT void JNICALL Java_org_libreoffice_androidlib_LOActivity_postMobileMessageNative(JNIEnv *env, jobject instance, jstring message) @@ -239,8 +252,7 @@ Java_org_libreoffice_androidlib_LOActivity_postMobileMessageNative(JNIEnv *env, { LOG_DBG("Document window terminating on JavaScript side. Closing our end of the socket."); - // Close one end of the socket pair, that will wake up the forwarding thread above - fakeSocketClose(closeNotificationPipeForForwardingThread[0]); + closeDocument(); } else { @@ -270,7 +282,11 @@ Java_org_libreoffice_androidlib_LOActivity_createLOOLWSD(JNIEnv *env, jobject, j // already initialized? if (lokInitialized) + { + // close the previous document so that we can wait for the new HULLO + closeDocument(); return; + } lokInitialized = true; libreofficekit_initialize(env, dataDir, cacheDir, apkFile, assetManager); @@ -292,6 +308,7 @@ Java_org_libreoffice_androidlib_LOActivity_createLOOLWSD(JNIEnv *env, jobject, j { LOG_DBG("Creating LOOLWSD"); { + std::unique_lock<std::mutex> lock(loolwsdRunningMutex); fakeClientFd = fakeSocketSocket(); LOG_DBG("createLOOLWSD created fakeClientFd: " << fakeClientFd); std::unique_ptr<LOOLWSD> loolwsd(new LOOLWSD()); diff --git a/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java b/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java index c6cebd5e3..7bd40af27 100644 --- a/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java +++ b/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java @@ -396,7 +396,16 @@ public class LOActivity extends AppCompatActivity { @Override protected void onPause() { super.onPause(); - Log.d(TAG, "onPause() - unload the document"); + Log.d(TAG, "onPause() - hinting to save, we might need to return to the doc"); + + // A Save similar to an autosave + postMobileMessageNative("save dontTerminateEdit=true dontSaveIfUnmodified=true"); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + Log.i(TAG, "onDestroy() - we know we are leaving the document"); postMobileMessageNative("BYE"); } commit 155718796ea0020a0cff2429813644a6e1c96794 Author: Jan Holesovsky <ke...@collabora.com> AuthorDate: Fri Jul 19 16:43:44 2019 +0200 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Fri Jul 19 17:58:58 2019 +0200 android: Fix a threading / ordering issue. Sometimes when closing & reloading a document, the JS ended up with: cmd=/storage/0/...document_name... type=unknown error. The problem was that the HULLO response came later than the next message in the queue which was loolclient 0.1 So LOOLWSd tried to load the document called "loolclient 0.1", which failed, and then it did not know what to do with the "/storage/0/..." which it understood as a command. Seems we don't need to send the stuff from a thread on Android, so let's avoid that, instead of setting up another sender queue here. Change-Id: I96b4ad13153f1cad6aeb7fc71efcb402edbdc6d2 diff --git a/android/lib/src/main/cpp/androidapp.cpp b/android/lib/src/main/cpp/androidapp.cpp index 54541e7c4..32610fbf5 100644 --- a/android/lib/src/main/cpp/androidapp.cpp +++ b/android/lib/src/main/cpp/androidapp.cpp @@ -228,15 +228,12 @@ Java_org_libreoffice_androidlib_LOActivity_postMobileMessageNative(JNIEnv *env, // WebSocket. LOG_DBG("Actually sending to Online:" << fileURL); - // Must do this in a thread, too, so that we can return to the GTK+ main loop - std::thread([=] - { - struct pollfd pollfd; - pollfd.fd = currentFakeClientFd; - pollfd.events = POLLOUT; - fakeSocketPoll(&pollfd, 1, -1); - fakeSocketWrite(currentFakeClientFd, fileURL.c_str(), fileURL.size()); - }).detach(); + // Send the document URL to LOOLWSD to setup the docBroker URL + struct pollfd pollfd; + pollfd.fd = currentFakeClientFd; + pollfd.events = POLLOUT; + fakeSocketPoll(&pollfd, 1, -1); + fakeSocketWrite(currentFakeClientFd, fileURL.c_str(), fileURL.size()); } else if (strcmp(string_value, "BYE") == 0) { @@ -247,17 +244,16 @@ Java_org_libreoffice_androidlib_LOActivity_postMobileMessageNative(JNIEnv *env, } else { - // As above + // Send the message to LOOLWSD char *string_copy = strdup(string_value); - std::thread([=] - { - struct pollfd pollfd; - pollfd.fd = currentFakeClientFd; - pollfd.events = POLLOUT; - fakeSocketPoll(&pollfd, 1, -1); - fakeSocketWrite(currentFakeClientFd, string_copy, strlen(string_copy)); - free(string_copy); - }).detach(); + + struct pollfd pollfd; + pollfd.fd = currentFakeClientFd; + pollfd.events = POLLOUT; + fakeSocketPoll(&pollfd, 1, -1); + fakeSocketWrite(currentFakeClientFd, string_copy, strlen(string_copy)); + + free(string_copy); } } else commit 89a8ce60097ce734fd1246a7cd1a876ae47a7958 Author: kaishu-sahu <kaishusahu...@gmail.com> AuthorDate: Fri May 10 02:27:16 2019 +0530 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Fri Jul 19 17:58:49 2019 +0200 android: add insert image feature to document viewer Change-Id: I19cb8ef93606cf1bba7341f0d258487b604ad10e diff --git a/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java b/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java index 98ac6f1ce..c6cebd5e3 100644 --- a/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java +++ b/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java @@ -10,6 +10,7 @@ package org.libreoffice.androidlib; import android.Manifest; +import android.content.ActivityNotFoundException; import android.content.ContentResolver; import android.content.Intent; import android.content.SharedPreferences; @@ -28,9 +29,10 @@ import android.print.PrintDocumentAdapter; import android.print.PrintManager; import android.util.Log; import android.webkit.JavascriptInterface; +import android.webkit.ValueCallback; +import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; -import android.webkit.WebViewClient; import android.widget.Toast; import java.io.File; @@ -81,6 +83,9 @@ public class LOActivity extends AppCompatActivity { private boolean isDocEditable = false; private boolean isDocDebuggable = BuildConfig.DEBUG; + private ValueCallback<Uri[]> valueCallback; + public static final int REQUEST_SELECT_FILE = 555; + private static boolean copyFromAssets(AssetManager assetManager, String fromAssetPath, String targetDir) { try { @@ -262,7 +267,6 @@ public class LOActivity extends AppCompatActivity { createLOOLWSD(dataDir, cacheDir, apkFile, assetManager, urlToLoad); mWebView = findViewById(R.id.browser); - mWebView.setWebViewClient(new WebViewClient()); WebSettings webSettings = mWebView.getSettings(); webSettings.setJavaScriptEnabled(true); @@ -275,13 +279,32 @@ public class LOActivity extends AppCompatActivity { WebView.setWebContentsDebuggingEnabled(true); } } + mainHandler = new Handler(getMainLooper()); - } + mWebView.setWebChromeClient(new WebChromeClient() { + @Override + public boolean onShowFileChooser(WebView mWebView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) { + if (valueCallback != null) { + valueCallback.onReceiveValue(null); + valueCallback = null; + } + + valueCallback = filePathCallback; + Intent intent = fileChooserParams.createIntent(); + + try { + intent.setType("image/*"); + startActivityForResult(intent, REQUEST_SELECT_FILE); + } catch (ActivityNotFoundException e) { + valueCallback = null; + Toast.makeText(LOActivity.this, getString(R.string.cannot_open_file_chooser), Toast.LENGTH_LONG).show(); + return false; + } + return true; + } + }); - @Override - protected void onStart() { - super.onStart(); if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { Log.i(TAG, "asking for read storage permission"); ActivityCompat.requestPermissions(this, @@ -377,6 +400,18 @@ public class LOActivity extends AppCompatActivity { postMobileMessageNative("BYE"); } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + if (requestCode == REQUEST_SELECT_FILE) { + if (valueCallback == null) + return; + valueCallback.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, intent)); + valueCallback = null; + } else { + Toast.makeText(this, getString(R.string.failed_to_insert_image), Toast.LENGTH_LONG).show(); + } + } + private void loadDocument() { String finalUrlToLoad = "file:///android_asset/dist/loleaflet.html?file_path=" + urlToLoad + "&closebutton=1"; diff --git a/android/lib/src/main/res/values/strings.xml b/android/lib/src/main/res/values/strings.xml index 5651df183..a283939e6 100644 --- a/android/lib/src/main/res/values/strings.xml +++ b/android/lib/src/main/res/values/strings.xml @@ -2,7 +2,9 @@ <string name="temp_file_saving_disabled">This file is read-only, saving is disabled.</string> <string name="storage_permission_required">Storage permission is required</string> <string name="failed_to_load_file">Failed to determine the file to load</string> + <string name="failed_to_insert_image">Failed to insert image</string> + <string name="cannot_open_file_chooser">Cannot open file chooser</string> <!-- Loading SlideShow Dialog Strings --> <string name="loading">Loading...</string> -</resources> \ No newline at end of file +</resources> _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits