diff options
Diffstat (limited to 'src/plugins/platforms/android')
7 files changed, 57 insertions, 47 deletions
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 17c197ea38..e47dd91a3e 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -82,8 +82,8 @@ static jobject m_serviceObject = nullptr; static jmethodID m_setSurfaceGeometryMethodID = nullptr; static jmethodID m_destroySurfaceMethodID = nullptr; -static bool m_activityActive = true; // defaults to true because when the platform plugin is - // initialized, QtActivity::onResume() has already been called +static int m_pendingApplicationState = -1; +static QBasicMutex m_pendingAppStateMtx; static jclass m_bitmapClass = nullptr; static jmethodID m_createBitmapMethodID = nullptr; @@ -130,13 +130,22 @@ static const char m_qtTag[] = "Qt"; static const char m_classErrorMsg[] = "Can't find class \"%s\""; static const char m_methodErrorMsg[] = "Can't find method \"%s%s\""; +static void flushPendingApplicationState(); + namespace QtAndroid { void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration) { - m_surfacesMutex.lock(); + QMutexLocker lock(&m_surfacesMutex); m_androidPlatformIntegration = androidPlatformIntegration; - m_surfacesMutex.unlock(); + + // flush the pending state if necessary. + if (m_androidPlatformIntegration) { + flushPendingApplicationState(); + } else { + QMutexLocker locker(&m_pendingAppStateMtx); + m_pendingApplicationState = -1; + } } QAndroidPlatformIntegration *androidPlatformIntegration() @@ -215,12 +224,6 @@ namespace QtAndroid m_statusBarShowing = false; } - void setApplicationActive() - { - if (m_activityActive) - QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); - } - jobject createBitmap(QImage img, JNIEnv *env) { if (!m_bitmapClass) @@ -402,11 +405,16 @@ namespace QtAndroid if (surfaceId == -1) return; - QJNIEnvironmentPrivate env; - if (!env) - return; + { + QMutexLocker lock(&m_surfacesMutex); + const auto &it = m_surfaces.find(surfaceId); + if (it != m_surfaces.end()) + m_surfaces.erase(it); + } - env->CallStaticVoidMethod(m_applicationClass, + QJNIEnvironmentPrivate env; + if (env) + env->CallStaticVoidMethod(m_applicationClass, m_destroySurfaceMethodID, surfaceId); } @@ -441,6 +449,16 @@ namespace QtAndroid } // namespace QtAndroid +// Force an update of the pending application state (state set before the platform plugin was created) +static void flushPendingApplicationState() +{ + QMutexLocker locker(&m_pendingAppStateMtx); + if (m_pendingApplicationState == -1) + return; + + QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(m_pendingApplicationState)); + m_pendingApplicationState = -1; +} static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobject applicationAssetManager*/) { @@ -584,18 +602,12 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface, { QMutexLocker lock(&m_surfacesMutex); const auto &it = m_surfaces.find(id); - if (it == m_surfaces.end()) { - qWarning()<<"Can't find surface" << id; + if (it == m_surfaces.end()) return; - } - auto surfaceClient = it.value(); - if (!surfaceClient) // This should never happen... - return; - - surfaceClient->surfaceChanged(env, jSurface, w, h); - if (!jSurface) - m_surfaces.erase(it); + auto surfaceClient = it.value(); + if (surfaceClient) + surfaceClient->surfaceChanged(env, jSurface, w, h); } static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/, @@ -656,13 +668,14 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/) static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state) { - m_activityActive = (state == Qt::ApplicationActive); - - if (!m_main || !m_androidPlatformIntegration || !QGuiApplicationPrivate::platformIntegration()) { - QAndroidPlatformIntegration::setDefaultApplicationState(Qt::ApplicationState(state)); + if (!m_main || !QtAndroid::androidPlatformIntegration()) { + QMutexLocker locker(&m_pendingAppStateMtx); + m_pendingApplicationState = Qt::ApplicationState(state); return; } + flushPendingApplicationState(); + if (state == Qt::ApplicationActive) QtAndroidPrivate::handleResume(); else if (state == Qt::ApplicationInactive) diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h index 218e52ccc1..170596082d 100644 --- a/src/plugins/platforms/android/androidjnimain.h +++ b/src/plugins/platforms/android/androidjnimain.h @@ -85,8 +85,6 @@ namespace QtAndroid jobject activity(); jobject service(); - void setApplicationActive(); - void showStatusBar(); void hideStatusBar(); diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp index 73aa9d0e8a..d8bba4f8e9 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp @@ -81,8 +81,6 @@ int QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight = 71; Qt::ScreenOrientation QAndroidPlatformIntegration::m_orientation = Qt::PrimaryOrientation; Qt::ScreenOrientation QAndroidPlatformIntegration::m_nativeOrientation = Qt::PrimaryOrientation; -Qt::ApplicationState QAndroidPlatformIntegration::m_defaultApplicationState = Qt::ApplicationActive; - bool QAndroidPlatformIntegration::m_showPasswordEnabled = false; void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource) @@ -121,6 +119,12 @@ void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteA return 0; } +void QAndroidPlatformNativeInterface::customEvent(QEvent *event) +{ + if (event->type() == QEvent::User) + QtAndroid::setAndroidPlatformIntegration(static_cast<QAndroidPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration())); +} + QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶mList) : m_touchDevice(nullptr) #ifndef QT_NO_ACCESSIBILITY @@ -148,7 +152,6 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶ m_primaryScreen->setAvailableGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight)); m_mainThread = QThread::currentThread(); - QtAndroid::setAndroidPlatformIntegration(this); m_androidFDB = new QAndroidPlatformFontDatabase(); m_androidPlatformServices = new QAndroidPlatformServices(); @@ -211,7 +214,9 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶ } } - QGuiApplicationPrivate::instance()->setApplicationState(m_defaultApplicationState); + // We can't safely notify the jni bridge that we're up and running just yet, so let's postpone + // it for now. + QCoreApplication::postEvent(m_androidPlatformNativeInterface, new QEvent(QEvent::User)); } static bool needsBasicRenderloopWorkaround() diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h index be10c3d161..923670b9e6 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/qandroidplatformintegration.h @@ -65,6 +65,9 @@ class QAndroidPlatformNativeInterface: public QPlatformNativeInterface public: void *nativeResourceForIntegration(const QByteArray &resource) override; std::shared_ptr<AndroidStyle> m_androidStyle; + +protected: + void customEvent(QEvent *event) override; }; class QAndroidPlatformIntegration : public QPlatformIntegration @@ -122,7 +125,6 @@ public: QTouchDevice *touchDevice() const { return m_touchDevice; } void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; } - static void setDefaultApplicationState(Qt::ApplicationState applicationState) { m_defaultApplicationState = applicationState; } private: EGLDisplay m_eglDisplay; @@ -141,9 +143,6 @@ private: static Qt::ScreenOrientation m_orientation; static Qt::ScreenOrientation m_nativeOrientation; - - static Qt::ApplicationState m_defaultApplicationState; - static bool m_showPasswordEnabled; QPlatformFontDatabase *m_androidFDB; diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp index 89ac0cbd93..8d98882e9e 100644 --- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp +++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp @@ -69,10 +69,7 @@ void QAndroidPlatformOpenGLContext::swapBuffers(QPlatformSurface *surface) bool QAndroidPlatformOpenGLContext::makeCurrent(QPlatformSurface *surface) { - bool ret = QEGLPlatformContext::makeCurrent(surface); - QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context()); - - return ret; + return QEGLPlatformContext::makeCurrent(surface); } EGLSurface QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index 155d6bfb8d..3b59b293a5 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -311,10 +311,13 @@ void QAndroidPlatformScreen::doRedraw() } } if (!hasVisibleRasterWindows) { + lockSurface(); if (m_id != -1) { QtAndroid::destroySurface(m_id); + releaseSurface(); m_id = -1; } + unlockSurface(); return; } QMutexLocker lock(&m_surfaceMutex); diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index 97a1f30a35..424cfefc6c 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -96,11 +96,6 @@ void QAndroidPlatformWindow::setVisible(bool visible) QRect availableGeometry = screen()->availableGeometry(); if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0) QPlatformWindow::setVisible(visible); - - // The Android Activity is activated before Qt is initialized, causing the application state to - // never be set to 'active'. We explicitly set this state when the first window becomes visible. - if (visible) - QtAndroid::setApplicationActive(); } void QAndroidPlatformWindow::setWindowState(Qt::WindowState state) |