Android: Add destruction guard in QAndroidPlatformWindow

To avoid calling functions in QAndroidPlatformWindow during/after
destruction of the object, create a mutex and use lock_guard to
synchronize the destruction of the object and native function calls
originating from Android events.

Task-number: QTBUG-118231
Change-Id: I29818386456c6969ca507d74574b722bf8a19019
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit 0f20feea2112c2391e274dc4e81aa38a738b7023)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Petri Virkkunen 2024-09-18 10:51:08 +03:00 committed by Qt Cherry-pick Bot
parent 6eb29cab2a
commit 1215f61a1f
2 changed files with 19 additions and 0 deletions

View File

@ -96,6 +96,7 @@ void QAndroidPlatformWindow::initialize()
QAndroidPlatformWindow::~QAndroidPlatformWindow()
{
const auto guard = destructionGuard();
if (window()->isTopLevel())
platformScreen()->removeWindow(this);
}
@ -353,6 +354,9 @@ void QAndroidPlatformWindow::setSurface(JNIEnv *env, jobject object, jint window
continue;
QAndroidPlatformWindow *platformWindow =
static_cast<QAndroidPlatformWindow *>(window->handle());
const auto guard = platformWindow->destructionGuard();
if (!platformWindow->m_surfaceCreated)
continue;
if (platformWindow->nativeViewId() == windowId)
platformWindow->onSurfaceChanged(surface);
}
@ -373,6 +377,18 @@ void QAndroidPlatformWindow::windowFocusChanged(JNIEnv *env, jobject object,
}
}
/*
Due to calls originating from Android, it is possible for native methods to
try to manipulate any given instance of QAndroidPlatformWindow when it is
already being destroyed. So we use this to guard against that. It is called
in the destructor, and should also be called in any function registered to
be called from java that may touch an instance of QAndroidPlatformWindow.
*/
QMutexLocker<QMutex> QAndroidPlatformWindow::destructionGuard()
{
return QMutexLocker(&m_destructionMutex);
}
bool QAndroidPlatformWindow::registerNatives(QJniEnvironment &env)
{
if (!env.registerNativeMethods(QtJniTypes::Traits<QtJniTypes::QtWindow>::className(),

View File

@ -96,12 +96,15 @@ protected:
QWaitCondition m_surfaceWaitCondition;
bool m_surfaceCreated = false;
QMutex m_surfaceMutex;
QMutex m_destructionMutex;
private:
static void setSurface(JNIEnv *env, jobject obj, jint windowId, QtJniTypes::Surface surface);
Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(setSurface)
static void windowFocusChanged(JNIEnv *env, jobject object, jboolean focus, jint windowId);
Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(windowFocusChanged)
[[nodiscard]] QMutexLocker<QMutex> destructionGuard();
};
QT_END_NAMESPACE