From 8880ef79311d283a1357ca0c14be6e56281ba5f0 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Mon, 11 Feb 2019 19:41:48 +0200 Subject: Terminate Qt gracefully When the application is closed via the task manager on Android then we need to ensure that that the application can close down any running event loops. So we wake up all the event loops and then call quit() directly on the application object to start a graceful termination of the application. In order to aid the graceful termination of Qt then a check is added to ensure that it does not try to create a new surface when the application is suspended. This prevents it from locking while trying to create a new surface when this is not possible. Fixes: QTBUG-70772 Change-Id: I6795b3d280e178d7f1207004a1b965a31a0cc9e9 Reviewed-by: Paul Olav Tvete Reviewed-by: Andy Shaw --- src/plugins/platforms/android/androidjnimain.cpp | 16 +++++++++------- .../platforms/android/qandroidplatformopenglwindow.cpp | 3 ++- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 13d41bea99..74edfd8356 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -560,10 +560,15 @@ static void quitQtAndroidPlugin(JNIEnv *env, jclass /*clazz*/) static void terminateQt(JNIEnv *env, jclass /*clazz*/) { // QAndroidEventDispatcherStopper is stopped when the user uses the task manager to kill the application - if (!QAndroidEventDispatcherStopper::instance()->stopped()) { - sem_wait(&m_terminateSemaphore); - sem_destroy(&m_terminateSemaphore); + if (QAndroidEventDispatcherStopper::instance()->stopped()) { + QAndroidEventDispatcherStopper::instance()->startAll(); + QCoreApplication::quit(); + QAndroidEventDispatcherStopper::instance()->goingToStop(false); } + + sem_wait(&m_terminateSemaphore); + sem_destroy(&m_terminateSemaphore); + env->DeleteGlobalRef(m_applicationClass); env->DeleteGlobalRef(m_classLoaderObject); if (m_resourcesObj) @@ -583,10 +588,7 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/) m_androidPlatformIntegration = nullptr; delete m_androidAssetsFileEngineHandler; m_androidAssetsFileEngineHandler = nullptr; - - if (!QAndroidEventDispatcherStopper::instance()->stopped()) { - sem_post(&m_exitSemaphore); - } + sem_post(&m_exitSemaphore); } static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface, jint w, jint h) diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp index 3e1cfe305d..3de5d30623 100644 --- a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp @@ -47,6 +47,7 @@ #include #include +#include #include #include @@ -121,7 +122,7 @@ void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect) EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config) { - if (QAndroidEventDispatcherStopper::stopped()) + if (QAndroidEventDispatcherStopper::stopped() || QGuiApplication::applicationState() == Qt::ApplicationSuspended) return m_eglSurface; QMutexLocker lock(&m_surfaceMutex); -- cgit v1.2.3