Skip to content

Commit

Permalink
Android: Add destruction guard in QAndroidPlatformWindow
Browse files Browse the repository at this point in the history
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 0f20fee)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
  • Loading branch information
Petrivirkkunen authored and Qt Cherry-pick Bot committed Oct 2, 2024
1 parent 6eb29ca commit 1215f61
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/plugins/platforms/android/qandroidplatformwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ void QAndroidPlatformWindow::initialize()

QAndroidPlatformWindow::~QAndroidPlatformWindow()
{
const auto guard = destructionGuard();
if (window()->isTopLevel())
platformScreen()->removeWindow(this);
}
Expand Down Expand Up @@ -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);
}
Expand All @@ -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(),
Expand Down
3 changes: 3 additions & 0 deletions src/plugins/platforms/android/qandroidplatformwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,15 @@ class QAndroidPlatformWindow: public QPlatformWindow
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
Expand Down

0 comments on commit 1215f61

Please sign in to comment.