summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAssam Boudjelthia <assam.boudjelthia@qt.io>2023-06-08 23:01:51 +0300
committerAssam Boudjelthia <assam.boudjelthia@qt.io>2023-06-10 11:12:39 +0300
commitc0e0b56055e2ed0155d4e2402319dd8f8f134e10 (patch)
tree4899a640bf67f0a9f26d8eb31b8065e0efc5e529
parent01872d06d9a09c83f28b3ecebcb06f0ed81c5622 (diff)
Android: improve screen size and physical size calculation
Use new api calls for calculating pixel size and physical size of multi-display setups after some existing apis have been deprecated in Android API 30 and 31. Also, do the physical size calculation outside of the supported modes loop. As for the physical size, this patch still uses xdpi/ydpi for the calculation instead of densityDpi as suggested in [1] because from testing few scenarios, the results returned from xdpi/ydpi are more consistent with physical device specs. [1] https://issuetracker.google.com/issues/194120500 Pick-to: 6.6 6.5 Task-number: QTBUG-112742 Change-Id: I0c8ef5185c8b6463830b528374954c324a32d657 Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtNative.java23
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp48
2 files changed, 49 insertions, 22 deletions
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtNative.java b/src/android/jar/src/org/qtproject/qt/android/QtNative.java
index 93bc6d8043..f9afa8ae38 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtNative.java
@@ -51,6 +51,12 @@ import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
+import android.util.Size;
+import android.util.DisplayMetrics;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
+import android.graphics.Rect;
+
public class QtNative
{
private static Activity m_activity = null;
@@ -412,6 +418,23 @@ public class QtNative
return new ArrayList<Display>();
}
+ public static Size getDisplaySize(Context displayContext, Display display)
+ {
+ if (Build.VERSION.SDK_INT < 31) {
+ DisplayMetrics realMetrics = new DisplayMetrics();
+ display.getRealMetrics(realMetrics);
+ return new Size(realMetrics.widthPixels, realMetrics.heightPixels);
+ }
+
+ Context windowsContext = displayContext.createWindowContext(
+ WindowManager.LayoutParams.TYPE_APPLICATION, null);
+ WindowManager displayMgr =
+ (WindowManager) windowsContext.getSystemService(Context.WINDOW_SERVICE);
+ WindowMetrics windowsMetrics = displayMgr.getCurrentWindowMetrics();
+ Rect bounds = windowsMetrics.getBounds();
+ return new Size(bounds.width(), bounds.height());
+ }
+
public static boolean startApplication(String params, String mainLib) throws Exception
{
if (params == null)
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index 4d046685ff..54c7a34efe 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -54,6 +54,9 @@ private:
Q_DECLARE_JNI_CLASS(Display, "android/view/Display")
Q_DECLARE_JNI_CLASS(DisplayMetrics, "android/util/DisplayMetrics")
+Q_DECLARE_JNI_CLASS(Resources, "android/content/res/Resources")
+Q_DECLARE_JNI_CLASS(Size, "android/util/Size")
+Q_DECLARE_JNI_CLASS(QtNative, "org/qtproject/qt/android/QtNative")
Q_DECLARE_JNI_TYPE(DisplayMode, "Landroid/view/Display$Mode;")
@@ -84,19 +87,31 @@ QAndroidPlatformScreen::QAndroidPlatformScreen(const QJniObject &displayObject)
m_refreshRate = displayObject.callMethod<jfloat>("getRefreshRate");
m_displayId = displayObject.callMethod<jint>("getDisplayId");
- QJniObject displayMetricsObj(QtJniTypes::className<QtJniTypes::DisplayMetrics>());
- displayObject.callMethod<void>("getRealMetrics", displayMetricsObj.object<QtJniTypes::DisplayMetrics>());
+ const QJniObject context = QNativeInterface::QAndroidApplication::context();
+ const auto displayContext = context.callMethod<QtJniTypes::Context>("createDisplayContext",
+ displayObject.object<QtJniTypes::Display>());
- const int widthPixels = displayMetricsObj.getField<int>("widthPixels");
- const int heightPixels = displayMetricsObj.getField<int>("heightPixels");
- m_size = QSize(widthPixels, heightPixels);
+ const auto sizeObj = QJniObject::callStaticMethod<QtJniTypes::Size>(
+ QtJniTypes::className<QtJniTypes::QtNative>(),
+ "getDisplaySize",
+ displayContext.object<QtJniTypes::Context>(),
+ displayObject.object<QtJniTypes::Display>());
+ m_size = QSize(sizeObj.callMethod<int>("getWidth"), sizeObj.callMethod<int>("getHeight"));
- if (QNativeInterface::QAndroidApplication::sdkVersion() >= 23) {
- const qreal xdpi = displayMetricsObj.getField<float>("xdpi");
- const qreal ydpi = displayMetricsObj.getField<float>("ydpi");
+ const auto resources = displayContext.callMethod<QtJniTypes::Resources>("getResources");
+ const auto metrics = resources.callMethod<QtJniTypes::DisplayMetrics>("getDisplayMetrics");
+ const float xdpi = metrics.getField<float>("xdpi");
+ const float ydpi = metrics.getField<float>("ydpi");
+
+ // Potentially densityDpi could be used instead of xpdi/ydpi to do the calculation,
+ // but the results are not consistent with devices specs.
+ // (https://issuetracker.google.com/issues/194120500)
+ m_physicalSize.setWidth(qRound(m_size.width() / xdpi * 25.4));
+ m_physicalSize.setHeight(qRound(m_size.height() / ydpi * 25.4));
+ if (QNativeInterface::QAndroidApplication::sdkVersion() >= 23) {
const QJniObject currentMode = displayObject.callObjectMethod<QtJniTypes::DisplayMode>("getMode");
- const jint currentModeId = currentMode.callMethod<jint>("getModeId");
+ m_currentMode = currentMode.callMethod<jint>("getModeId");
const QJniObject supportedModes = displayObject.callObjectMethod<QtJniTypes::DisplayMode[]>(
"getSupportedModes");
@@ -106,20 +121,9 @@ QAndroidPlatformScreen::QAndroidPlatformScreen(const QJniObject &displayObject)
const auto size = env->GetArrayLength(modeArray);
for (jsize i = 0; i < size; ++i) {
const auto mode = QJniObject::fromLocalRef(env->GetObjectArrayElement(modeArray, i));
- // Physical sizes in millimeters
- const int physicalWidth = qRound(mode.callMethod<jint>("getPhysicalWidth") / xdpi * 25.4);
- const int physicalHeight = qRound(mode.callMethod<jint>("getPhysicalHeight") / ydpi * 25.4);
-
- if (currentModeId == mode.callMethod<jint>("getModeId")) {
- m_currentMode = i;
- m_physicalSize = QSize {
- physicalWidth,
- physicalHeight
- };
- }
-
m_modes << QPlatformScreen::Mode {
- .size = QSize { physicalWidth, physicalHeight },
+ .size = QSize { mode.callMethod<jint>("getPhysicalWidth"),
+ mode.callMethod<jint>("getPhysicalHeight") },
.refreshRate = mode.callMethod<jfloat>("getRefreshRate")
};
}