diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/jar/src/org/qtproject/qt5/android/view/QtAndroidWebViewController.java | 18 | ||||
-rw-r--r-- | src/plugins/android/qandroidwebview.cpp | 18 |
2 files changed, 31 insertions, 5 deletions
diff --git a/src/jar/src/org/qtproject/qt5/android/view/QtAndroidWebViewController.java b/src/jar/src/org/qtproject/qt5/android/view/QtAndroidWebViewController.java index ebfe8da..366be27 100644 --- a/src/jar/src/org/qtproject/qt5/android/view/QtAndroidWebViewController.java +++ b/src/jar/src/org/qtproject/qt5/android/view/QtAndroidWebViewController.java @@ -90,6 +90,7 @@ public class QtAndroidWebViewController private native void c_onReceivedTitle(long id, String title); private native void c_onRunJavaScriptResult(long id, long callbackId, String result); private native void c_onReceivedError(long id, int errorCode, String description, String url); + private native void c_processEventsFromQueue(); // We need to block the UI thread in some cases, if it takes to long we should timeout before // ANR kicks in... Usually the hard limit is set to 10s and if exceed that then we're in trouble. @@ -257,10 +258,19 @@ public class QtAndroidWebViewController } }); - try { - sem.acquire(); - } catch (Exception e) { - e.printStackTrace(); + boolean semAcquired = false; + while (!semAcquired) { + try { + semAcquired = sem.tryAcquire(BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS); + } catch (Exception e) { + e.printStackTrace(); + } + if (!semAcquired) { + // If the waiting time elapsed before a permit was acquired probably we have a + // deadlock here. To unlock the thread that block us, we need to process events + // from the queue and try again. + c_processEventsFromQueue(); + } } } diff --git a/src/plugins/android/qandroidwebview.cpp b/src/plugins/android/qandroidwebview.cpp index 91122bd..29e3cf2 100644 --- a/src/plugins/android/qandroidwebview.cpp +++ b/src/plugins/android/qandroidwebview.cpp @@ -48,6 +48,9 @@ #include <QtCore/qurl.h> #include <QtCore/qdebug.h> +#include <QAbstractEventDispatcher> +#include <QThread> + QT_BEGIN_NAMESPACE static const char qtAndroidWebViewControllerClass[] = "org/qtproject/qt5/android/view/QtAndroidWebViewController"; @@ -407,6 +410,18 @@ static void c_onReceivedError(JNIEnv *env, Q_EMIT wc->loadingChanged(loadRequest); } +static void c_processEventsFromQueue(JNIEnv *env, jobject thiz) +{ + Q_UNUSED(env) + Q_UNUSED(thiz) + if (QThread::currentThread() == qGuiApp->thread()) { + auto eventDispatcher = QThread::currentThread()->eventDispatcher(); + if (eventDispatcher) + eventDispatcher->processEvents( + QEventLoop::ExcludeUserInputEvents|QEventLoop::ExcludeSocketNotifiers); + } +} + JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/) { static bool initialized = false; @@ -438,7 +453,8 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/) {"c_onReceivedIcon", "(JLandroid/graphics/Bitmap;)V", reinterpret_cast<void *>(c_onReceivedIcon)}, {"c_onReceivedTitle", "(JLjava/lang/String;)V", reinterpret_cast<void *>(c_onReceivedTitle)}, {"c_onRunJavaScriptResult", "(JJLjava/lang/String;)V", reinterpret_cast<void *>(c_onRunJavaScriptResult)}, - {"c_onReceivedError", "(JILjava/lang/String;Ljava/lang/String;)V", reinterpret_cast<void *>(c_onReceivedError)} + {"c_onReceivedError", "(JILjava/lang/String;Ljava/lang/String;)V", reinterpret_cast<void *>(c_onReceivedError)}, + {"c_processEventsFromQueue", "()V", reinterpret_cast<void *>(c_processEventsFromQueue)} }; const int nMethods = sizeof(methods) / sizeof(methods[0]); |