diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2022-01-28 13:29:32 +0100 |
---|---|---|
committer | Ivan Solovev <ivan.solovev@qt.io> | 2022-01-31 11:28:14 +0100 |
commit | aa06466863edf27a006bff902ef3e51626b49890 (patch) | |
tree | d37f53c60d77c0bb6c500a5c1f1c1c5b320c0be0 /src/plugins/platforms/android | |
parent | 6c0ed94a1b5b3d3f9d79008b897c69cc90cebfff (diff) |
[Android]: Handle the screen name, modes and refreshRate properly
Fixes: QTBUG-87136
Fixes: QTBUG-93823
Fixes: QTBUG-94959
Change-Id: Id480e22611ec949b5e3ee780fc695fb502a5950c
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit c1a93b20ff1fec370b2483276b74f07eb54486ef)
Diffstat (limited to 'src/plugins/platforms/android')
5 files changed, 74 insertions, 3 deletions
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index ed88fbdba3..c02425855a 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -655,7 +655,7 @@ static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/, jint widthPixels, jint heightPixels, jint desktopWidthPixels, jint desktopHeightPixels, jdouble xdpi, jdouble ydpi, - jdouble scaledDensity, jdouble density) + jdouble scaledDensity, jdouble density, jfloat refreshRate) { // Android does not give us the correct screen size for immersive mode, but // the surface does have the right size @@ -681,6 +681,7 @@ static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/, qRound(double(heightPixels) / ydpi * 25.4)); m_androidPlatformIntegration->setScreenSize(widthPixels, heightPixels); m_androidPlatformIntegration->setDesktopSize(desktopWidthPixels, desktopHeightPixels); + m_androidPlatformIntegration->setRefreshRate(refreshRate); } } @@ -781,6 +782,12 @@ static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint new } } +static void handleRefreshRateChanged(JNIEnv */*env*/, jclass /*cls*/, jfloat refreshRate) +{ + if (m_androidPlatformIntegration) + m_androidPlatformIntegration->setRefreshRate(refreshRate); +} + static void onActivityResult(JNIEnv */*env*/, jclass /*cls*/, jint requestCode, jint resultCode, @@ -806,14 +813,15 @@ static JNINativeMethod methods[] = { {"quitQtCoreApplication", "()V", (void *)quitQtCoreApplication}, {"terminateQt", "()V", (void *)terminateQt}, {"waitForServiceSetup", "()V", (void *)waitForServiceSetup}, - {"setDisplayMetrics", "(IIIIDDDD)V", (void *)setDisplayMetrics}, + {"setDisplayMetrics", "(IIIIDDDDF)V", (void *)setDisplayMetrics}, {"setSurface", "(ILjava/lang/Object;II)V", (void *)setSurface}, {"updateWindow", "()V", (void *)updateWindow}, {"updateApplicationState", "(I)V", (void *)updateApplicationState}, {"handleOrientationChanged", "(II)V", (void *)handleOrientationChanged}, {"onActivityResult", "(IILandroid/content/Intent;)V", (void *)onActivityResult}, {"onNewIntent", "(Landroid/content/Intent;)V", (void *)onNewIntent}, - {"onBind", "(Landroid/content/Intent;)Landroid/os/IBinder;", (void *)onBind} + {"onBind", "(Landroid/content/Intent;)Landroid/os/IBinder;", (void *)onBind}, + {"handleRefreshRateChanged", "(F)V", (void *)handleRefreshRateChanged} }; #define FIND_AND_CHECK_CLASS(CLASS_NAME) \ diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp index f137db28dd..d6b84c2c7f 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp @@ -494,6 +494,12 @@ void QAndroidPlatformIntegration::setScreenSize(int width, int height) QMetaObject::invokeMethod(m_primaryScreen, "setSize", Qt::AutoConnection, Q_ARG(QSize, QSize(width, height))); } +void QAndroidPlatformIntegration::setRefreshRate(qreal refreshRate) +{ + if (m_primaryScreen) + QMetaObject::invokeMethod(m_primaryScreen, "setRefreshRate", Qt::AutoConnection, + Q_ARG(qreal, refreshRate)); +} #if QT_CONFIG(vulkan) QPlatformVulkanInstance *QAndroidPlatformIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h index de97cbce4f..1fb849af56 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/qandroidplatformintegration.h @@ -96,6 +96,7 @@ public: virtual void setDesktopSize(int width, int height); virtual void setDisplayMetrics(int width, int height); void setScreenSize(int width, int height); + void setRefreshRate(qreal refreshRate); bool isVirtualDesktop() { return true; } QPlatformFontDatabase *fontDatabase() const override; diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index 12ce0d514e..0e53c2200b 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -55,6 +55,7 @@ #include <android/native_window_jni.h> #include <qguiapplication.h> +#include <QtCore/private/qjnihelpers_p.h> #include <QtGui/QGuiApplication> #include <QtGui/QWindow> #include <QtGui/private/qwindow_p.h> @@ -104,6 +105,42 @@ QAndroidPlatformScreen::QAndroidPlatformScreen() m_physicalSize.setHeight(QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight); m_physicalSize.setWidth(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth); connect(qGuiApp, &QGuiApplication::applicationStateChanged, this, &QAndroidPlatformScreen::applicationStateChanged); + + QJNIObjectPrivate activity(QtAndroid::activity()); + if (!activity.isValid()) + return; + QJNIObjectPrivate display; + if (QtAndroidPrivate::androidSdkVersion() < 30) { + display = activity.callObjectMethod("getWindowManager", "()Landroid/view/WindowManager;") + .callObjectMethod("getDefaultDisplay", "()Landroid/view/Display;"); + } else { + display = activity.callObjectMethod("getDisplay", "()Landroid/view/Display;"); + } + if (!display.isValid()) + return; + m_name = display.callObjectMethod("getName", "()Ljava/lang/String;").toString(); + m_refreshRate = display.callMethod<jfloat>("getRefreshRate"); + if (QtAndroidPrivate::androidSdkVersion() < 23) { + m_modes << Mode { .size = m_physicalSize.toSize(), .refreshRate = m_refreshRate }; + return; + } + QJNIEnvironmentPrivate env; + const jint currentMode = display.callObjectMethod("getMode", "()Landroid/view/Display$Mode;") + .callMethod<jint>("getModeId"); + const auto modes = display.callObjectMethod("getSupportedModes", + "()[Landroid/view/Display$Mode;"); + const auto modesArray = jobjectArray(modes.object()); + const auto sz = env->GetArrayLength(modesArray); + for (jsize i = 0; i < sz; ++i) { + auto mode = QJNIObjectPrivate::fromLocalRef(env->GetObjectArrayElement(modesArray, i)); + if (currentMode == mode.callMethod<jint>("getModeId")) + m_currentMode = m_modes.size(); + m_modes << Mode { .size = QSize { mode.callMethod<jint>("getPhysicalHeight"), + mode.callMethod<jint>("getPhysicalWidth") }, + .refreshRate = mode.callMethod<jfloat>("getRefreshRate") }; + } + if (m_modes.isEmpty()) + m_modes << Mode { .size = m_physicalSize.toSize(), .refreshRate = m_refreshRate }; } QAndroidPlatformScreen::~QAndroidPlatformScreen() @@ -243,6 +280,14 @@ void QAndroidPlatformScreen::setSize(const QSize &size) QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry()); } +void QAndroidPlatformScreen::setRefreshRate(qreal refreshRate) +{ + if (refreshRate == m_refreshRate) + return; + m_refreshRate = refreshRate; + QWindowSystemInterface::handleScreenRefreshRateChange(QPlatformScreen::screen(), refreshRate); +} + void QAndroidPlatformScreen::setAvailableGeometry(const QRect &rect) { QMutexLocker lock(&m_surfaceMutex); diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h index 4c0cd07293..28d3d21a45 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.h +++ b/src/plugins/platforms/android/qandroidplatformscreen.h @@ -69,6 +69,12 @@ public: QImage::Format format() const override { return m_format; } QSizeF physicalSize() const override { return m_physicalSize; } + QString name() const override { return m_name; } + QVector<Mode> modes() const override { return m_modes; } + int currentMode() const override { return m_currentMode; } + int preferredMode() const override { return m_currentMode; } + qreal refreshRate() const override { return m_refreshRate; } + inline QWindow *topWindow() const; QWindow *topLevelAt(const QPoint & p) const override; @@ -87,6 +93,7 @@ public slots: void setPhysicalSize(const QSize &size); void setAvailableGeometry(const QRect &rect); void setSize(const QSize &size); + void setRefreshRate(qreal refreshRate); protected: bool event(QEvent *event) override; @@ -100,6 +107,10 @@ protected: int m_depth; QImage::Format m_format; QSizeF m_physicalSize; + qreal m_refreshRate; + QString m_name; + QVector<Mode> m_modes; + int m_currentMode = 0; private: QDpi logicalDpi() const override; |