From 83e0bc18e03868295f8358d875f2b67cb78f16a8 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Thu, 23 Jun 2011 11:58:50 -0700 Subject: DO NOT MERGE. Fix density compat mode. Fix issue #4770360: older app compatibility mode is really tiny on ICS phones We were applying the density compat mode scaling multiple times to display metrics, causing bad values. Change-Id: Iafafd9a5e94b9d774cd2715bf968e91602a1bd82 --- .../android/content/res/CompatibilityInfo.java | 20 ++++++----- core/java/android/content/res/Resources.java | 23 ++++++------- core/java/android/util/DisplayMetrics.java | 40 ++++++++++++++++++---- core/java/android/view/Display.java | 17 ++++----- .../android/server/wm/WindowManagerService.java | 10 +++--- 5 files changed, 69 insertions(+), 41 deletions(-) diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index acf2f2f..1c9285e 100644 --- a/core/java/android/content/res/CompatibilityInfo.java +++ b/core/java/android/content/res/CompatibilityInfo.java @@ -432,17 +432,17 @@ public class CompatibilityInfo implements Parcelable { // compatible with large screens, so diddle it. CompatibilityInfo.computeCompatibleScaling(inoutDm, inoutDm); } else { - inoutDm.widthPixels = inoutDm.unscaledWidthPixels; - inoutDm.heightPixels = inoutDm.unscaledHeightPixels; + inoutDm.widthPixels = inoutDm.noncompatWidthPixels; + inoutDm.heightPixels = inoutDm.noncompatHeightPixels; } if (isScalingRequired()) { float invertedRatio = applicationInvertedScale; - inoutDm.density *= invertedRatio; + inoutDm.density = inoutDm.noncompatDensity * invertedRatio; inoutDm.densityDpi = (int)((inoutDm.density*DisplayMetrics.DENSITY_DEFAULT)+.5f); - inoutDm.scaledDensity *= invertedRatio; - inoutDm.xdpi *= invertedRatio; - inoutDm.ydpi *= invertedRatio; + inoutDm.scaledDensity = inoutDm.noncompatScaledDensity * invertedRatio; + inoutDm.xdpi = inoutDm.noncompatXdpi * invertedRatio; + inoutDm.ydpi = inoutDm.noncompatYdpi * invertedRatio; inoutDm.widthPixels = (int) (inoutDm.widthPixels * invertedRatio + 0.5f); inoutDm.heightPixels = (int) (inoutDm.heightPixels * invertedRatio + 0.5f); } @@ -471,8 +471,8 @@ public class CompatibilityInfo implements Parcelable { * @return Returns the scaling factor for the window. */ public static float computeCompatibleScaling(DisplayMetrics dm, DisplayMetrics outDm) { - final int width = dm.unscaledWidthPixels; - final int height = dm.unscaledHeightPixels; + final int width = dm.noncompatWidthPixels; + final int height = dm.noncompatHeightPixels; int shortSize, longSize; if (width < height) { shortSize = width; @@ -532,7 +532,9 @@ public class CompatibilityInfo implements Parcelable { sb.append(applicationDensity); sb.append("dpi"); if (isScalingRequired()) { - sb.append(" scaling"); + sb.append(" "); + sb.append(applicationScale); + sb.append("x"); } if (!supportsScreen()) { sb.append(" resizing"); diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index bd8b1a4..324c9fd 100755 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -1416,23 +1416,19 @@ public class Resources { } if (metrics != null) { mMetrics.setTo(metrics); - // NOTE: We should re-arrange this code to create a Display - // with the CompatibilityInfo that is used everywhere we deal - // with the display in relation to this app, rather than - // doing the conversion here. This impl should be okay because - // we make sure to return a compatible display in the places - // where there are public APIs to retrieve the display... but - // it would be cleaner and more maintainble to just be - // consistently dealing with a compatible display everywhere in - // the framework. - if (mCompatibilityInfo != null) { - mCompatibilityInfo.applyToDisplayMetrics(mMetrics); - } } + // NOTE: We should re-arrange this code to create a Display + // with the CompatibilityInfo that is used everywhere we deal + // with the display in relation to this app, rather than + // doing the conversion here. This impl should be okay because + // we make sure to return a compatible display in the places + // where there are public APIs to retrieve the display... but + // it would be cleaner and more maintainble to just be + // consistently dealing with a compatible display everywhere in + // the framework. if (mCompatibilityInfo != null) { mCompatibilityInfo.applyToDisplayMetrics(mMetrics); } - mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale; int configChanges = 0xfffffff; if (config != null) { mTmpConfig.setTo(config); @@ -1448,6 +1444,7 @@ public class Resources { if (mConfiguration.locale == null) { mConfiguration.locale = Locale.getDefault(); } + mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale; String locale = null; if (mConfiguration.locale != null) { diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java index d594567..519b980 100644 --- a/core/java/android/util/DisplayMetrics.java +++ b/core/java/android/util/DisplayMetrics.java @@ -119,13 +119,37 @@ public class DisplayMetrics { * being applied. * @hide */ - public int unscaledWidthPixels; + public int noncompatWidthPixels; /** * The reported display height prior to any compatibility mode scaling * being applied. * @hide */ - public int unscaledHeightPixels; + public int noncompatHeightPixels; + /** + * The reported display density prior to any compatibility mode scaling + * being applied. + * @hide + */ + public float noncompatDensity; + /** + * The reported scaled density prior to any compatibility mode scaling + * being applied. + * @hide + */ + public float noncompatScaledDensity; + /** + * The reported display xdpi prior to any compatibility mode scaling + * being applied. + * @hide + */ + public float noncompatXdpi; + /** + * The reported display ydpi prior to any compatibility mode scaling + * being applied. + * @hide + */ + public float noncompatYdpi; public DisplayMetrics() { } @@ -138,8 +162,12 @@ public class DisplayMetrics { scaledDensity = o.scaledDensity; xdpi = o.xdpi; ydpi = o.ydpi; - unscaledWidthPixels = o.unscaledWidthPixels; - unscaledHeightPixels = o.unscaledHeightPixels; + noncompatWidthPixels = o.noncompatWidthPixels; + noncompatHeightPixels = o.noncompatHeightPixels; + noncompatDensity = o.noncompatDensity; + noncompatScaledDensity = o.noncompatScaledDensity; + noncompatXdpi = o.noncompatXdpi; + noncompatYdpi = o.noncompatYdpi; } public void setToDefaults() { @@ -150,8 +178,8 @@ public class DisplayMetrics { scaledDensity = density; xdpi = DENSITY_DEVICE; ydpi = DENSITY_DEVICE; - unscaledWidthPixels = 0; - unscaledHeightPixels = 0; + noncompatWidthPixels = 0; + noncompatHeightPixels = 0; } @Override diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 3fa8dfd..2be5a49 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -107,8 +107,8 @@ public class Display { CompatibilityInfo ci; if (doCompat && (ci=mCompatibilityInfo.getIfNeeded()) != null) { synchronized (mTmpMetrics) { - mTmpMetrics.unscaledWidthPixels = outSize.x; - mTmpMetrics.unscaledHeightPixels = outSize.y; + mTmpMetrics.noncompatWidthPixels = outSize.x; + mTmpMetrics.noncompatHeightPixels = outSize.y; mTmpMetrics.density = mDensity; ci.applyToDisplayMetrics(mTmpMetrics); outSize.x = mTmpMetrics.widthPixels; @@ -268,14 +268,15 @@ public class Display { } private void getNonSizeMetrics(DisplayMetrics outMetrics) { - outMetrics.density = mDensity; outMetrics.densityDpi = (int)((mDensity*DisplayMetrics.DENSITY_DEFAULT)+.5f); - outMetrics.scaledDensity= outMetrics.density; - outMetrics.xdpi = mDpiX; - outMetrics.ydpi = mDpiY; - outMetrics.unscaledWidthPixels = outMetrics.widthPixels; - outMetrics.unscaledHeightPixels = outMetrics.heightPixels; + outMetrics.noncompatWidthPixels = outMetrics.widthPixels; + outMetrics.noncompatHeightPixels = outMetrics.heightPixels; + + outMetrics.density = outMetrics.noncompatDensity = mDensity; + outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density; + outMetrics.xdpi = outMetrics.noncompatXdpi = mDpiX; + outMetrics.ydpi = outMetrics.noncompatYdpi = mDpiY; } static IWindowManager getWindowManager() { diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index c40c7fc..f7fd8f4 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -5552,10 +5552,10 @@ public class WindowManagerService extends IWindowManager.Stub private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm, int dw, int dh) { - dm.unscaledWidthPixels = mPolicy.getNonDecorDisplayWidth(rotation, dw); - dm.unscaledHeightPixels = mPolicy.getNonDecorDisplayHeight(rotation, dh); + dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(rotation, dw); + dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(rotation, dh); float scale = CompatibilityInfo.computeCompatibleScaling(dm, null); - int size = (int)(((dm.unscaledWidthPixels / scale) / dm.density) + .5f); + int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f); if (curSize == 0 || size < curSize) { curSize = size; } @@ -5630,9 +5630,9 @@ public class WindowManagerService extends IWindowManager.Stub // Override display width and height with what we are computing, // to be sure they remain consistent. - dm.widthPixels = dm.unscaledWidthPixels = mAppDisplayWidth + dm.widthPixels = dm.noncompatWidthPixels = mAppDisplayWidth = mPolicy.getNonDecorDisplayWidth(mRotation, dw); - dm.heightPixels = dm.unscaledHeightPixels = mAppDisplayHeight + dm.heightPixels = dm.noncompatHeightPixels = mAppDisplayHeight = mPolicy.getNonDecorDisplayHeight(mRotation, dh); mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm, -- cgit v1.1