summaryrefslogtreecommitdiff
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorJulian Greilich <j.greilich@gmx.de>2023-01-04 16:32:28 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-01-06 05:46:34 +0000
commit126fe788e3f4acafcbf1f0e2afa9b94fe74e7b47 (patch)
tree6b265dc5edf6da0e5eaa6accc5fc9d4e00fdc43f /src/plugins/platforms
parent1440ee1e3d2edeadd3ccae9d39c31e8132cd4ae7 (diff)
downloadqtbase-126fe788e3f4acafcbf1f0e2afa9b94fe74e7b47.tar.gz
Android A11Y: Only access the main thread when it is not blocked
When the qtMainLoopThread calls QSGThreadedRenderLoop::polishAndSync(), it waits for the QSGRenderThread. In the QSGRenderThread, QAndroidPlatformOpenGLWindow::eglSurface() calls QtAndroid::createSurface() and waits for the "android main thread" to return a valid surface. When the "android main thread" now calls "runInObjectContext" (e.g. by calling QtAndroidAccessibility::childIdListForAccessibleObject()) it waits for the qtMainLoopThread and the program is stuck in a deadlock. To prevent this, we protect all BlockedQueuedConnection from the "android main thread" to the qtMainLoopThread by acquiring the AndroidDeadlockProtector. When QAndroidPlatformOpenGLWindow::eglSurface() already acquired the AndroidDeadlockProtector we abort the current A11y call with an emtpy or default value. Note: b8a95275440b8a143ee648466fd8b5401ee1e839 already tried to fix this by checking "getSurfaceCount() != 0", but there are situations, where a new surface is being created while an old surface is still present. Task-number: QTBUG-105958 Change-Id: Ie40e8654c99aace9e69b0b8412952fa22c89f071 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io> (cherry picked from commit b832a5ac72c6015b6509d60b75b2ce5d5e570800) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index 731937dd8f..54579447d3 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -37,6 +37,7 @@
**
****************************************************************************/
+#include "androiddeadlockprotector.h"
#include "androidjniaccessibility.h"
#include "androidjnimain.h"
#include "qandroidplatformintegration.h"
@@ -94,6 +95,14 @@ namespace QtAndroidAccessibility
template <typename Func, typename Ret>
void runInObjectContext(QObject *context, Func &&func, Ret *retVal)
{
+ AndroidDeadlockProtector protector;
+ if (!protector.acquire()) {
+ __android_log_print(ANDROID_LOG_WARN, m_qtTag,
+ "Could not run accessibility call in object context, accessing "
+ "main thread could lead to deadlock");
+ return;
+ }
+
if (!QtAndroid::blockEventLoopsWhenSuspended()
|| QGuiApplication::applicationState() != Qt::ApplicationSuspended) {
QMetaObject::invokeMethod(context, func, Qt::BlockingQueuedConnection, retVal);