From 9a8f29832c047ee83cac26ab40569e35a537981b Mon Sep 17 00:00:00 2001 From: Bartlomiej Moskal Date: Fri, 24 Feb 2023 08:34:37 +0100 Subject: Android: Fix for possible thread deadlock QtAndroidWebViewController constructor blocks a qGuiThread until the WebView is created and configured in UI thread. Such an implementation can easily lead to the deadlock (For example in the case of handling InputConnection - it is exactly the opposite. UI thread is blocked and waits for handling event by qGuiThread). That's why we need to lock AndroidDeadlockProtector before blocking qGuiThread. This implementation resolves potential deadlock using AndroidDeadlockProtector. If protector cannot by locked, qGuiThread will handle events to make it possible. Fixes: QTBUG-82810 Change-Id: I71aaea9ceb7c41b818ed533ce41c70b5c0e8d7de Reviewed-by: Michal Klocek (cherry picked from commit 26c2569b73d884e3130705c77b8f2920f5645029) Reviewed-by: Qt Cherry-pick Bot --- src/plugins/android/qandroidwebview.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/plugins/android/qandroidwebview.cpp b/src/plugins/android/qandroidwebview.cpp index f2c33aa..a2044b2 100644 --- a/src/plugins/android/qandroidwebview.cpp +++ b/src/plugins/android/qandroidwebview.cpp @@ -15,6 +15,9 @@ #include #include +#include +#include + QT_BEGIN_NAMESPACE static const char qtAndroidWebViewControllerClass[] = "org/qtproject/qt/android/view/QtAndroidWebViewController"; @@ -45,10 +48,22 @@ QAndroidWebViewPrivate::QAndroidWebViewPrivate(QObject *p) , m_callbackId(0) , m_window(0) { + // QtAndroidWebViewController constructor blocks a qGuiThread until + // the WebView is created and configured in UI thread. + // That is why we cannot proceed until AndroidDeadlockProtector is locked + while (!QtAndroidPrivate::acquireAndroidDeadlockProtector()) { + auto eventDispatcher = QThread::currentThread()->eventDispatcher(); + if (eventDispatcher) + eventDispatcher->processEvents( + QEventLoop::ExcludeUserInputEvents|QEventLoop::ExcludeSocketNotifiers); + } m_viewController = QJniObject(qtAndroidWebViewControllerClass, "(Landroid/app/Activity;J)V", QtAndroidPrivate::activity(), m_id); + + QtAndroidPrivate::releaseAndroidDeadlockProtector(); + m_webView = m_viewController.callObjectMethod("getWebView", "()Landroid/webkit/WebView;"); -- cgit v1.2.3