From a53b828635fce8b6b2d3e3377d74d72070056623 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Fri, 17 Jul 2009 11:13:48 -0700 Subject: [PATCH] Add "nodpi" density, and expose a bunch of density-related APIs. Also update the DpiTest app to use nodpi images, and try to have a mode where it turns off compatibility though it's not quite working. --- api/current.xml | 222 ++++++++++++++++++ core/java/android/app/ActivityThread.java | 1 - .../content/res/CompatibilityInfo.java | 6 +- core/java/android/content/res/Resources.java | 11 +- core/java/android/util/DisplayMetrics.java | 36 ++- core/java/android/util/TypedValue.java | 12 +- graphics/java/android/graphics/Bitmap.java | 26 +- .../java/android/graphics/BitmapFactory.java | 18 +- graphics/java/android/graphics/Canvas.java | 4 - include/utils/ResourceTypes.h | 3 +- libs/utils/ResourceTypes.cpp | 13 +- .../unit_tests/content/ConfigTest.java | 2 +- tests/DpiTest/AndroidManifest.xml | 9 +- .../res/drawable-nodpi/logonodpi120.png | Bin 0 -> 5178 bytes .../res/drawable-nodpi/logonodpi160.png | Bin 0 -> 8114 bytes .../res/drawable-nodpi/logonodpi240.png | Bin 0 -> 13388 bytes .../android/test/dpi/DpiTestActivity.java | 37 +++ .../test/dpi/DpiTestNoCompatActivity.java | 23 ++ tools/aapt/AaptAssets.cpp | 8 +- .../com/android/layoutlib/bridge/Bridge.java | 10 +- 20 files changed, 374 insertions(+), 67 deletions(-) create mode 100644 tests/DpiTest/res/drawable-nodpi/logonodpi120.png create mode 100644 tests/DpiTest/res/drawable-nodpi/logonodpi160.png create mode 100644 tests/DpiTest/res/drawable-nodpi/logonodpi240.png create mode 100644 tests/DpiTest/src/com/google/android/test/dpi/DpiTestNoCompatActivity.java diff --git a/api/current.xml b/api/current.xml index a0886648d19e3..bb932e675fbe7 100644 --- a/api/current.xml +++ b/api/current.xml @@ -48942,6 +48942,17 @@ visibility="public" > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -49415,6 +49517,16 @@ visibility="public" > + + + + + + + + + + + + + + + + + + + + + + + + 1.0), unless that's only option. if (tmpDiff < minDiff && packageDensityScale < 1.0f) { - packageDensityScale = DisplayMetrics.DEVICE_DENSITY / (float) density; + packageDensityScale = DisplayMetrics.DENSITY_DEVICE / (float) density; minDiff = tmpDiff; } } @@ -130,7 +130,7 @@ public class CompatibilityInfo { applicationScale = packageDensityScale; } else { applicationScale = - DisplayMetrics.DEVICE_DENSITY / (float) DisplayMetrics.DEFAULT_DENSITY; + DisplayMetrics.DENSITY_DEVICE / (float) DisplayMetrics.DENSITY_DEFAULT; } applicationInvertedScale = 1.0f / applicationScale; diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index a9aa1ee6b835a..2354519d6ad6f 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -87,7 +87,7 @@ public class Resources { /*package*/ final DisplayMetrics mMetrics = new DisplayMetrics(); PluralRules mPluralRule; - private final CompatibilityInfo mCompatibilityInfo; + private CompatibilityInfo mCompatibilityInfo; private Display mDefaultDisplay; private static final LongSparseArray EMPTY_ARRAY = new LongSparseArray() { @@ -1385,6 +1385,15 @@ public class Resources { return mCompatibilityInfo; } + /** + * This is just for testing. + * @hide + */ + public void setCompatibilityInfo(CompatibilityInfo ci) { + mCompatibilityInfo = ci; + updateConfiguration(mConfiguration, mMetrics); + } + /** * Return a resource identifier for the given resource name. A fully * qualified resource name is of the form "package:type/entry". The first diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java index 9071bf029f9e7..bfab49d60fa1e 100644 --- a/core/java/android/util/DisplayMetrics.java +++ b/core/java/android/util/DisplayMetrics.java @@ -27,17 +27,31 @@ import android.os.*; */ public class DisplayMetrics { /** - * The reference density used throughout the system. - * - * @hide Pending API council approval + * Standard quantized DPI for low-density screens. */ - public static final int DEFAULT_DENSITY = 160; + public static final int DENSITY_LOW = 120; + + /** + * Standard quantized DPI for medium-density screens. + */ + public static final int DENSITY_MEDIUM = 160; + + /** + * Standard quantized DPI for high-density screens. + */ + public static final int DENSITY_HIGH = 240; + + /** + * The reference density used throughout the system. + */ + public static final int DENSITY_DEFAULT = DENSITY_MEDIUM; /** * The device's density. - * @hide + * @hide becase eventually this should be able to change while + * running, so shouldn't be a constant. */ - public static final int DEVICE_DENSITY = getDeviceDensity(); + public static final int DENSITY_DEVICE = getDeviceDensity(); /** * The absolute width of the display in pixels. @@ -62,7 +76,7 @@ public class DisplayMetrics { * 320x480 but the screen size remained 1.5"x2" then the density would be * increased (probably to 1.5). * - * @see #DEFAULT_DENSITY + * @see #DENSITY_DEFAULT */ public float density; /** @@ -95,10 +109,10 @@ public class DisplayMetrics { public void setToDefaults() { widthPixels = 0; heightPixels = 0; - density = DEVICE_DENSITY / (float) DEFAULT_DENSITY; + density = DENSITY_DEVICE / (float) DENSITY_DEFAULT; scaledDensity = density; - xdpi = DEVICE_DENSITY; - ydpi = DEVICE_DENSITY; + xdpi = DENSITY_DEVICE; + ydpi = DENSITY_DEVICE; } /** @@ -176,6 +190,6 @@ public class DisplayMetrics { // The reason for this is that ro.sf.lcd_density is write-once and is // set by the init process when it parses build.prop before anything else. return SystemProperties.getInt("qemu.sf.lcd_density", - SystemProperties.getInt("ro.sf.lcd_density", DEFAULT_DENSITY)); + SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT)); } } diff --git a/core/java/android/util/TypedValue.java b/core/java/android/util/TypedValue.java index d4ba9e21ac13f..ed4529851d8f0 100644 --- a/core/java/android/util/TypedValue.java +++ b/core/java/android/util/TypedValue.java @@ -140,12 +140,16 @@ public class TypedValue { /** * If {@link #density} is equal to this value, then the density should be - * treated as the system's default density value: {@link DisplayMetrics#DEFAULT_DENSITY}. - * - * @hide Pending API council approval + * treated as the system's default density value: {@link DisplayMetrics#DENSITY_DEFAULT}. */ public static final int DENSITY_DEFAULT = 0; + /** + * If {@link #density} is equal to this value, then there is no density + * associated with the resource and it should not be scaled. + */ + public static final int DENSITY_NONE = 0xffff; + /* ------------------------------------------------------------ */ /** The type held by this value, as defined by the constants here. @@ -171,8 +175,6 @@ public class TypedValue { /** * If the Value came from a resource, this holds the corresponding pixel density. - * - * @hide Pending API council approval * */ public int density; diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index e2e93eb87e678..141553e9ca74c 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -31,8 +31,6 @@ public final class Bitmap implements Parcelable { * * @see Bitmap#getDensityScale() * @see Bitmap#setDensityScale(float) - * - * @hide pending API council approval */ public static final float DENSITY_SCALE_UNKNOWN = -1.0f; @@ -84,11 +82,9 @@ public final class Bitmap implements Parcelable { * @see #setDensityScale(float) * @see #isAutoScalingEnabled() * @see #setAutoScalingEnabled(boolean) - * @see android.util.DisplayMetrics#DEFAULT_DENSITY + * @see android.util.DisplayMetrics#DENSITY_DEFAULT * @see android.util.DisplayMetrics#density * @see #DENSITY_SCALE_UNKNOWN - * - * @hide pending API council approval */ public float getDensityScale() { return mDensityScale; @@ -106,11 +102,9 @@ public final class Bitmap implements Parcelable { * @see #getDensityScale() * @see #isAutoScalingEnabled() * @see #setAutoScalingEnabled(boolean) - * @see android.util.DisplayMetrics#DEFAULT_DENSITY + * @see android.util.DisplayMetrics#DENSITY_DEFAULT * @see android.util.DisplayMetrics#density * @see #DENSITY_SCALE_UNKNOWN - * - * @hide pending API council approval */ public void setDensityScale(float densityScale) { mDensityScale = densityScale; @@ -132,8 +126,6 @@ public final class Bitmap implements Parcelable { * @see #setAutoScalingEnabled(boolean) * @see #getDensityScale() * @see #setDensityScale(float) - * - * @hide pending API council approval */ public boolean isAutoScalingEnabled() { return mAutoScaling; @@ -150,8 +142,6 @@ public final class Bitmap implements Parcelable { * the bitmap will never be automatically scaled at drawing time.

* * @param autoScalingEnabled True to scale the bitmap at drawing time, false otherwise. - * - * @hide pending API council approval */ public void setAutoScalingEnabled(boolean autoScalingEnabled) { mAutoScaling = autoScalingEnabled; @@ -465,8 +455,8 @@ public final class Bitmap implements Parcelable { // The new bitmap was created from a known bitmap source so assume that // they use the same density scale - bitmap.setDensityScale(source.getDensityScale()); - bitmap.setAutoScalingEnabled(source.isAutoScalingEnabled()); + bitmap.mDensityScale = source.mDensityScale; + bitmap.mAutoScaling = source.mAutoScaling; return bitmap; } @@ -616,11 +606,9 @@ public final class Bitmap implements Parcelable { * by the density scale factor. * * @return The scaled width of this bitmap, according to the density scale factor. - * - * @hide pending API council approval */ public int getScaledWidth() { - final float scale = getDensityScale(); + final float scale = mDensityScale; return scale == DENSITY_SCALE_UNKNOWN ? getWidth() : (int) (getWidth() / scale); } @@ -629,11 +617,9 @@ public final class Bitmap implements Parcelable { * by the density scale factor. * * @return The scaled height of this bitmap, according to the density scale factor. - * - * @hide pending API council approval */ public int getScaledHeight() { - final float scale = getDensityScale(); + final float scale = mDensityScale; return scale == DENSITY_SCALE_UNKNOWN ? getWidth() : (int) (getHeight() / scale); } diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index 082e0c069c0ee..76abaa23b9a09 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -81,10 +81,8 @@ public class BitmapFactory { /** * The desired pixel density of the bitmap. * - * @see android.util.DisplayMetrics#DEFAULT_DENSITY + * @see android.util.DisplayMetrics#DENSITY_DEFAULT * @see android.util.DisplayMetrics#density - * - * @hide pending API council approval */ public int inDensity; @@ -97,8 +95,6 @@ public class BitmapFactory { * a non-scaled version of the bitmap. In this case, * {@link android.graphics.Bitmap#setAutoScalingEnabled(boolean)} can be used * to properly scale the bitmap at drawing time.

- * - * @hide pending API council approval */ public boolean inScaled; @@ -238,8 +234,6 @@ public class BitmapFactory { /** * Decode a new Bitmap from an InputStream. This InputStream was obtained from * resources, which we pass to be able to scale the bitmap accordingly. - * - * @hide */ public static Bitmap decodeStream(Resources res, TypedValue value, InputStream is, Rect pad, Options opts) { @@ -251,15 +245,19 @@ public class BitmapFactory { Bitmap bm = decodeStream(is, pad, opts); if (bm != null && res != null && value != null) { + final int density = value.density; + if (density == TypedValue.DENSITY_NONE) { + return bm; + } + byte[] np = bm.getNinePatchChunk(); final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np); - final int density = value.density; if (opts.inDensity == 0) { opts.inDensity = density == TypedValue.DENSITY_DEFAULT ? - DisplayMetrics.DEFAULT_DENSITY : density; + DisplayMetrics.DENSITY_DEFAULT : density; } - float scale = opts.inDensity / (float) DisplayMetrics.DEFAULT_DENSITY; + float scale = opts.inDensity / (float) DisplayMetrics.DENSITY_DEFAULT; if (opts.inScaled || isNinePatch) { bm.setDensityScale(1.0f); diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 4498e1a2e117e..da7359772ee38 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -184,8 +184,6 @@ public class Canvas { * * @see #setDensityScale(float) * @see Bitmap#getDensityScale() - * - * @hide pending API council approval */ public float getDensityScale() { if (mBitmap != null) { @@ -205,8 +203,6 @@ public class Canvas { * * @see #getDensityScale() * @see Bitmap#setDensityScale(float) - * - * @hide pending API council approval */ public void setDensityScale(float densityScale) { if (mBitmap != null) { diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h index 93bca4aefc08a..381933556d2f3 100644 --- a/include/utils/ResourceTypes.h +++ b/include/utils/ResourceTypes.h @@ -825,7 +825,8 @@ struct ResTable_config }; enum { - DENSITY_ANY = 0 + DENSITY_DEFAULT = 0, + DENSITY_NONE = 0xffff }; union { diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp index 87edb0125e738..98d450b76edca 100644 --- a/libs/utils/ResourceTypes.cpp +++ b/libs/utils/ResourceTypes.cpp @@ -4007,7 +4007,16 @@ void ResTable::print(bool inclValues) const printf(" NON-INTEGER ResTable_type ADDRESS: %p\n", type); continue; } - printf(" config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%d key=%d infl=%d nav=%d w=%d h=%d lyt=%d\n", + char density[16]; + uint16_t dval = dtohs(type->config.density); + if (dval == ResTable_config::DENSITY_DEFAULT) { + strcpy(density, "def"); + } else if (dval == ResTable_config::DENSITY_NONE) { + strcpy(density, "non"); + } else { + sprintf(density, "%d", (int)dval); + } + printf(" config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%s key=%d infl=%d nav=%d w=%d h=%d lyt=%d\n", (int)configIndex, type->config.language[0] ? type->config.language[0] : '-', type->config.language[1] ? type->config.language[1] : '-', @@ -4015,7 +4024,7 @@ void ResTable::print(bool inclValues) const type->config.country[1] ? type->config.country[1] : '-', type->config.orientation, type->config.touchscreen, - dtohs(type->config.density), + density, type->config.keyboard, type->config.inputFlags, type->config.navigation, diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java b/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java index e6639d3720cd6..a065d7016af06 100644 --- a/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java +++ b/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java @@ -133,7 +133,7 @@ public class ConfigTest extends AndroidTestCase { case DENSITY: // this is the ratio from the standard - mMetrics.density = (((float)value)/((float)DisplayMetrics.DEFAULT_DENSITY)); + mMetrics.density = (((float)value)/((float)DisplayMetrics.DENSITY_DEFAULT)); break; default: assert(false); diff --git a/tests/DpiTest/AndroidManifest.xml b/tests/DpiTest/AndroidManifest.xml index 64ad7beeda348..ea355a4c72d18 100644 --- a/tests/DpiTest/AndroidManifest.xml +++ b/tests/DpiTest/AndroidManifest.xml @@ -19,10 +19,15 @@ - + + + + + + + - diff --git a/tests/DpiTest/res/drawable-nodpi/logonodpi120.png b/tests/DpiTest/res/drawable-nodpi/logonodpi120.png new file mode 100644 index 0000000000000000000000000000000000000000..46bbd5bd3d485ba132f14fd5b04a7c6b69004d0c GIT binary patch literal 5178 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 = 0; + if (out) out->density = ResTable_config::DENSITY_DEFAULT; return true; } + + if (strcmp(name, "nodpi") == 0) { + if (out) out->density = ResTable_config::DENSITY_NONE; + return true; + } + char* c = (char*)name; while (*c >= '0' && *c <= '9') { c++; diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java index d0a1c46bf6444..fd77d5143d9e9 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -286,8 +286,8 @@ public final class Bridge implements ILayoutBridge { } return computeLayout(layoutDescription, projectKey, - screenWidth, screenHeight, DisplayMetrics.DEFAULT_DENSITY, - DisplayMetrics.DEFAULT_DENSITY, DisplayMetrics.DEFAULT_DENSITY, + screenWidth, screenHeight, DisplayMetrics.DENSITY_DEFAULT, + DisplayMetrics.DENSITY_DEFAULT, DisplayMetrics.DENSITY_DEFAULT, themeName, isProjectTheme, projectResources, frameworkResources, customViewLoader, logger); } @@ -304,8 +304,8 @@ public final class Bridge implements ILayoutBridge { Map> frameworkResources, IProjectCallback customViewLoader, ILayoutLog logger) { return computeLayout(layoutDescription, projectKey, - screenWidth, screenHeight, DisplayMetrics.DEFAULT_DENSITY, - DisplayMetrics.DEFAULT_DENSITY, DisplayMetrics.DEFAULT_DENSITY, + screenWidth, screenHeight, DisplayMetrics.DENSITY_DEFAULT, + DisplayMetrics.DENSITY_DEFAULT, DisplayMetrics.DENSITY_DEFAULT, themeName, isProjectTheme, projectResources, frameworkResources, customViewLoader, logger); } @@ -340,7 +340,7 @@ public final class Bridge implements ILayoutBridge { try { // setup the display Metrics. DisplayMetrics metrics = new DisplayMetrics(); - metrics.density = density / (float) DisplayMetrics.DEFAULT_DENSITY; + metrics.density = density / (float) DisplayMetrics.DENSITY_DEFAULT; metrics.scaledDensity = metrics.density; metrics.widthPixels = screenWidth; metrics.heightPixels = screenHeight;