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:
parent
6eb29cab2a
commit
1215f61a1f
@ -96,6 +96,7 @@ void QAndroidPlatformWindow::initialize()
|
|||||||
|
|
||||||
QAndroidPlatformWindow::~QAndroidPlatformWindow()
|
QAndroidPlatformWindow::~QAndroidPlatformWindow()
|
||||||
{
|
{
|
||||||
|
const auto guard = destructionGuard();
|
||||||
if (window()->isTopLevel())
|
if (window()->isTopLevel())
|
||||||
platformScreen()->removeWindow(this);
|
platformScreen()->removeWindow(this);
|
||||||
}
|
}
|
||||||
@ -353,6 +354,9 @@ void QAndroidPlatformWindow::setSurface(JNIEnv *env, jobject object, jint window
|
|||||||
continue;
|
continue;
|
||||||
QAndroidPlatformWindow *platformWindow =
|
QAndroidPlatformWindow *platformWindow =
|
||||||
static_cast<QAndroidPlatformWindow *>(window->handle());
|
static_cast<QAndroidPlatformWindow *>(window->handle());
|
||||||
|
const auto guard = platformWindow->destructionGuard();
|
||||||
|
if (!platformWindow->m_surfaceCreated)
|
||||||
|
continue;
|
||||||
if (platformWindow->nativeViewId() == windowId)
|
if (platformWindow->nativeViewId() == windowId)
|
||||||
platformWindow->onSurfaceChanged(surface);
|
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)
|
bool QAndroidPlatformWindow::registerNatives(QJniEnvironment &env)
|
||||||
{
|
{
|
||||||
if (!env.registerNativeMethods(QtJniTypes::Traits<QtJniTypes::QtWindow>::className(),
|
if (!env.registerNativeMethods(QtJniTypes::Traits<QtJniTypes::QtWindow>::className(),
|
||||||
|
@ -96,12 +96,15 @@ protected:
|
|||||||
QWaitCondition m_surfaceWaitCondition;
|
QWaitCondition m_surfaceWaitCondition;
|
||||||
bool m_surfaceCreated = false;
|
bool m_surfaceCreated = false;
|
||||||
QMutex m_surfaceMutex;
|
QMutex m_surfaceMutex;
|
||||||
|
QMutex m_destructionMutex;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void setSurface(JNIEnv *env, jobject obj, jint windowId, QtJniTypes::Surface surface);
|
static void setSurface(JNIEnv *env, jobject obj, jint windowId, QtJniTypes::Surface surface);
|
||||||
Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(setSurface)
|
Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(setSurface)
|
||||||
static void windowFocusChanged(JNIEnv *env, jobject object, jboolean focus, jint windowId);
|
static void windowFocusChanged(JNIEnv *env, jobject object, jboolean focus, jint windowId);
|
||||||
Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(windowFocusChanged)
|
Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(windowFocusChanged)
|
||||||
|
|
||||||
|
[[nodiscard]] QMutexLocker<QMutex> destructionGuard();
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user