diff options
-rw-r--r-- | api/current.txt | 4 | ||||
-rw-r--r-- | cmds/am/src/com/android/commands/am/Am.java | 43 | ||||
-rw-r--r-- | core/java/android/app/ActivityThread.java | 40 | ||||
-rwxr-xr-x | core/java/android/content/res/Resources.java | 53 | ||||
-rw-r--r-- | core/java/android/provider/Settings.java | 7 | ||||
-rw-r--r-- | core/java/android/util/DisplayMetrics.java | 2 | ||||
-rw-r--r-- | core/java/android/view/Display.java | 1 | ||||
-rw-r--r-- | core/java/android/view/IWindowManager.aidl | 2 | ||||
-rw-r--r-- | core/java/android/view/TextureView.java | 3 | ||||
-rw-r--r-- | core/java/android/view/View.java | 6 | ||||
-rw-r--r-- | core/java/android/view/ViewDebug.java | 5 | ||||
-rw-r--r-- | core/java/android/view/WindowManagerPolicy.java | 2 | ||||
-rw-r--r-- | core/java/android/widget/StackView.java | 4 | ||||
-rw-r--r-- | core/java/com/android/internal/os/ZygoteInit.java | 15 | ||||
-rw-r--r-- | graphics/java/android/graphics/Bitmap.java | 98 | ||||
-rwxr-xr-x | policy/src/com/android/internal/policy/impl/PhoneWindowManager.java | 15 | ||||
-rw-r--r-- | services/java/com/android/server/wm/DisplayContent.java | 14 | ||||
-rwxr-xr-x | services/java/com/android/server/wm/WindowManagerService.java | 117 |
18 files changed, 341 insertions, 90 deletions
diff --git a/api/current.txt b/api/current.txt index cc67e89..ebc1fc6 100644 --- a/api/current.txt +++ b/api/current.txt @@ -8114,8 +8114,11 @@ package android.graphics { method public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap, int, int, int, int); method public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap, int, int, int, int, android.graphics.Matrix, boolean); method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config); + method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config); method public static android.graphics.Bitmap createBitmap(int[], int, int, int, int, android.graphics.Bitmap.Config); + method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, int, int, android.graphics.Bitmap.Config); method public static android.graphics.Bitmap createBitmap(int[], int, int, android.graphics.Bitmap.Config); + method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, android.graphics.Bitmap.Config); method public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap, int, int, boolean); method public int describeContents(); method public void eraseColor(int); @@ -19958,7 +19961,6 @@ package android.service.dreams { method public boolean onPreparePanel(int, android.view.View, android.view.Menu); method public boolean onSearchRequested(); method public void onStart(); - method public final int onStartCommand(android.content.Intent, int, int); method public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams); method public void onWindowFocusChanged(boolean); method public android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback); diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index f42fd2a..a79eb14 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -133,6 +133,8 @@ public class Am { runScreenCompat(); } else if (op.equals("display-size")) { runDisplaySize(); + } else if (op.equals("display-density")) { + runDisplayDensity(); } else if (op.equals("to-uri")) { runToUri(false); } else if (op.equals("to-intent-uri")) { @@ -1127,6 +1129,44 @@ public class Am { } } + private void runDisplayDensity() throws Exception { + String densityStr = nextArgRequired(); + int density; + if ("reset".equals(densityStr)) { + density = -1; + } else { + try { + density = Integer.parseInt(densityStr); + } catch (NumberFormatException e) { + System.err.println("Error: bad number " + e); + showUsage(); + return; + } + if (density < 72) { + System.err.println("Error: density must be >= 72"); + showUsage(); + return; + } + } + + IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.checkService( + Context.WINDOW_SERVICE)); + if (wm == null) { + System.err.println(NO_SYSTEM_ERROR_CODE); + throw new AndroidException("Can't connect to window manager; is the system running?"); + } + + try { + if (density > 0) { + // TODO(multidisplay): For now Configuration only applies to main screen. + wm.setForcedDisplayDensity(Display.DEFAULT_DISPLAY, density); + } else { + wm.clearForcedDisplayDensity(Display.DEFAULT_DISPLAY); + } + } catch (RemoteException e) { + } + } + private void runToUri(boolean intentScheme) throws Exception { Intent intent = makeIntent(); System.out.println(intent.toUri(intentScheme ? Intent.URI_INTENT_SCHEME : 0)); @@ -1301,6 +1341,7 @@ public class Am { " am monitor [--gdb <port>]\n" + " am screen-compat [on|off] <PACKAGE>\n" + " am display-size [reset|MxN]\n" + + " am display-density [reset|DENSITY]\n" + " am to-uri [INTENT]\n" + " am to-intent-uri [INTENT]\n" + "\n" + @@ -1355,6 +1396,8 @@ public class Am { "\n" + "am display-size: override display size.\n" + "\n" + + "am display-density: override display density.\n" + + "\n" + "am to-uri: print the given Intent specification as a URI.\n" + "\n" + "am to-intent-uri: print the given Intent specification as an intent: URI.\n" + diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index f8d01de..bb35ddd 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -167,6 +167,7 @@ public final class ActivityThread { AppBindData mBoundApplication; Profiler mProfiler; int mCurDefaultDisplayDpi; + boolean mDensityCompatMode; Configuration mConfiguration; Configuration mCompatConfiguration; Configuration mResConfiguration; @@ -2733,7 +2734,8 @@ public final class ActivityThread { // On platforms where we don't want thumbnails, set dims to (0,0) if ((w > 0) && (h > 0)) { - thumbnail = Bitmap.createBitmap(w, h, THUMBNAIL_FORMAT); + thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(), + w, h, THUMBNAIL_FORMAT); thumbnail.eraseColor(0); } } @@ -3468,6 +3470,7 @@ public final class ActivityThread { // If there was a pending configuration change, execute it first. if (changedConfig != null) { mCurDefaultDisplayDpi = changedConfig.densityDpi; + updateDefaultDensity(); handleConfigurationChanged(changedConfig, null); } @@ -3718,6 +3721,7 @@ public final class ActivityThread { if (!mPendingConfiguration.isOtherSeqNewer(config)) { config = mPendingConfiguration; mCurDefaultDisplayDpi = config.densityDpi; + updateDefaultDensity(); } mPendingConfiguration = null; } @@ -3918,8 +3922,20 @@ public final class ActivityThread { } catch (RemoteException e) { // Ignore } - } - + } + + private void updateDefaultDensity() { + if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED + && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE + && !mDensityCompatMode) { + Slog.i(TAG, "Switching default density from " + + DisplayMetrics.DENSITY_DEVICE + " to " + + mCurDefaultDisplayDpi); + DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi; + Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); + } + } + private void handleBindApplication(AppBindData data) { mBoundApplication = data; mConfiguration = new Configuration(data.config); @@ -3980,6 +3996,16 @@ public final class ActivityThread { data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); + /** + * Switch this process to density compatibility mode if needed. + */ + if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) + == 0) { + mDensityCompatMode = true; + Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); + } + updateDefaultDensity(); + final ContextImpl appContext = new ContextImpl(); appContext.init(data.info, null, this); final File cacheDir = appContext.getCacheDir(); @@ -4010,14 +4036,6 @@ public final class ActivityThread { StrictMode.enableDeathOnNetwork(); } - /** - * Switch this process to density compatibility mode if needed. - */ - if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) - == 0) { - Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); - } - if (data.debugMode != IApplicationThread.DEBUG_OFF) { // XXX should have option to change the port. Debug.changeDebugPort(8100); diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index c7e55ce..d2af3e9 100755 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -89,7 +89,8 @@ public class Resources { = new LongSparseArray<ColorStateList>(); private static final LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables = new LongSparseArray<Drawable.ConstantState>(); - private static boolean mPreloaded; + private static boolean sPreloaded; + private static int sPreloadedDensity; /*package*/ final TypedValue mTmpValue = new TypedValue(); /*package*/ final Configuration mTmpConfig = new Configuration(); @@ -1837,11 +1838,14 @@ public class Resources { */ public final void startPreloading() { synchronized (mSync) { - if (mPreloaded) { + if (sPreloaded) { throw new IllegalStateException("Resources already preloaded"); } - mPreloaded = true; + sPreloaded = true; mPreloading = true; + sPreloadedDensity = DisplayMetrics.DENSITY_DEVICE; + mConfiguration.densityDpi = sPreloadedDensity; + updateConfiguration(null, null); } } @@ -1855,7 +1859,24 @@ public class Resources { flushLayoutCache(); } } - + + private boolean verifyPreloadConfig(TypedValue value, String name) { + if ((value.changingConfigurations&~(ActivityInfo.CONFIG_FONT_SCALE + | ActivityInfo.CONFIG_DENSITY)) != 0) { + String resName; + try { + resName = getResourceName(value.resourceId); + } catch (NotFoundException e) { + resName = "?"; + } + Log.w(TAG, "Preloaded " + name + " resource #0x" + + Integer.toHexString(value.resourceId) + + " (" + resName + ") that varies with configuration!!"); + return false; + } + return true; + } + /*package*/ Drawable loadDrawable(TypedValue value, int id) throws NotFoundException { @@ -1879,8 +1900,10 @@ public class Resources { return dr; } - Drawable.ConstantState cs = isColorDrawable ? - sPreloadedColorDrawables.get(key) : sPreloadedDrawables.get(key); + Drawable.ConstantState cs = isColorDrawable + ? sPreloadedColorDrawables.get(key) + : (sPreloadedDensity == mConfiguration.densityDpi + ? sPreloadedDrawables.get(key) : null); if (cs != null) { dr = cs.newDrawable(this); } else { @@ -1948,10 +1971,12 @@ public class Resources { cs = dr.getConstantState(); if (cs != null) { if (mPreloading) { - if (isColorDrawable) { - sPreloadedColorDrawables.put(key, cs); - } else { - sPreloadedDrawables.put(key, cs); + if (verifyPreloadConfig(value, "drawable")) { + if (isColorDrawable) { + sPreloadedColorDrawables.put(key, cs); + } else { + sPreloadedDrawables.put(key, cs); + } } } else { synchronized (mTmpValue) { @@ -2016,7 +2041,9 @@ public class Resources { csl = ColorStateList.valueOf(value.data); if (mPreloading) { - sPreloadedColorStateLists.put(key, csl); + if (verifyPreloadConfig(value, "color")) { + sPreloadedColorStateLists.put(key, csl); + } } return csl; @@ -2060,7 +2087,9 @@ public class Resources { if (csl != null) { if (mPreloading) { - sPreloadedColorStateLists.put(key, csl); + if (verifyPreloadConfig(value, "color")) { + sPreloadedColorStateLists.put(key, csl); + } } else { synchronized (mTmpValue) { //Log.i(TAG, "Saving cached color state list @ #" + diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 840f27d..c8bb886 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2794,6 +2794,13 @@ public final class Settings { public static final String DISPLAY_SIZE_FORCED = "display_size_forced"; /** + * The saved value for WindowManagerService.setForcedDisplayDensity(). + * One integer in dpi. If unset, then use the real display density. + * @hide + */ + public static final String DISPLAY_DENSITY_FORCED = "display_density_forced"; + + /** * Whether assisted GPS should be enabled or not. * @hide */ diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java index d58eec4..506594b 100644 --- a/core/java/android/util/DisplayMetrics.java +++ b/core/java/android/util/DisplayMetrics.java @@ -92,7 +92,7 @@ public class DisplayMetrics { * density for a display in {@link #densityDpi}. */ @Deprecated - public static final int DENSITY_DEVICE = getDeviceDensity(); + public static int DENSITY_DEVICE = getDeviceDensity(); /** * The absolute width of the display in pixels. diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index c59f1bf..2b0c14d 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -16,7 +16,6 @@ package android.view; -import android.content.res.CompatibilityInfo; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index f58cd83..5bccdd4 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -59,6 +59,8 @@ interface IWindowManager void setForcedDisplaySize(int displayId, int longDimen, int shortDimen); void clearForcedDisplaySize(int displayId); + void setForcedDisplayDensity(int displayId, int density); + void clearForcedDisplayDensity(int displayId); // Is the device configured to have a full system bar for larger screens? boolean hasSystemNavBar(); diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index a719a01..fe14c88 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -534,7 +534,8 @@ public class TextureView extends View { */ public Bitmap getBitmap(int width, int height) { if (isAvailable() && width > 0 && height > 0) { - return getBitmap(Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)); + return getBitmap(Bitmap.createBitmap(getResources().getDisplayMetrics(), + width, height, Bitmap.Config.ARGB_8888)); } return null; } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 50c3407..cd35002 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -12402,7 +12402,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (bitmap != null) bitmap.recycle(); try { - bitmap = Bitmap.createBitmap(width, height, quality); + bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(), + width, height, quality); bitmap.setDensity(getResources().getDisplayMetrics().densityDpi); if (autoScale) { mDrawingCache = bitmap; @@ -12494,7 +12495,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, width = (int) ((width * scale) + 0.5f); height = (int) ((height * scale) + 0.5f); - Bitmap bitmap = Bitmap.createBitmap(width > 0 ? width : 1, height > 0 ? height : 1, quality); + Bitmap bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(), + width > 0 ? width : 1, height > 0 ? height : 1, quality); if (bitmap == null) { throw new OutOfMemoryError(); } diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java index 00d4fc7..dae9265 100644 --- a/core/java/android/view/ViewDebug.java +++ b/core/java/android/view/ViewDebug.java @@ -546,7 +546,7 @@ public class ViewDebug { (view != null && view.getResources() != null) ? view.getResources().getDisplayMetrics() : null; final Bitmap bitmap = metrics != null ? - Bitmap.createBitmap(metrics.widthPixels, + Bitmap.createBitmap(metrics, metrics.widthPixels, metrics.heightPixels, Bitmap.Config.RGB_565) : null; final Canvas canvas = bitmap != null ? new Canvas(bitmap) : null; return new Object[] { @@ -706,7 +706,8 @@ public class ViewDebug { Log.w("View", "Failed to create capture bitmap!"); // Send an empty one so that it doesn't get stuck waiting for // something. - b = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); + b = Bitmap.createBitmap(root.getResources().getDisplayMetrics(), + 1, 1, Bitmap.Config.ARGB_8888); } BufferedOutputStream out = null; diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 9522a1b..407bae5 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -483,7 +483,7 @@ public interface WindowManagerPolicy { * Called by window manager once it has the initial, default native * display dimensions. */ - public void setInitialDisplaySize(Display display, int width, int height); + public void setInitialDisplaySize(Display display, int width, int height, int density); /** * Check permissions when adding a window. diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java index 293eda1..6853660 100644 --- a/core/java/android/widget/StackView.java +++ b/core/java/android/widget/StackView.java @@ -1412,8 +1412,8 @@ public class StackView extends AdapterViewAnimator { return null; } - Bitmap bitmap = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), - Bitmap.Config.ARGB_8888); + Bitmap bitmap = Bitmap.createBitmap(v.getResources().getDisplayMetrics(), + v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888); mCanvas.setBitmap(bitmap); float rotationX = v.getRotationX(); diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 998c037..6ad67c3 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -384,7 +384,12 @@ public class ZygoteInit { Log.v(TAG, "Preloading resource #" + Integer.toHexString(id)); } if (id != 0) { - mResources.getColorStateList(id); + if (mResources.getColorStateList(id) == null) { + throw new IllegalArgumentException( + "Unable to find preloaded color resource #0x" + + Integer.toHexString(id) + + " (" + ar.getString(i) + ")"); + } } } return N; @@ -407,11 +412,11 @@ public class ZygoteInit { Log.v(TAG, "Preloading resource #" + Integer.toHexString(id)); } if (id != 0) { - Drawable dr = mResources.getDrawable(id); - if ((dr.getChangingConfigurations()&~ActivityInfo.CONFIG_FONT_SCALE) != 0) { - Log.w(TAG, "Preloaded drawable resource #0x" + if (mResources.getDrawable(id) == null) { + throw new IllegalArgumentException( + "Unable to find preloaded drawable resource #0x" + Integer.toHexString(id) - + " (" + ar.getString(i) + ") that varies with configuration!!"); + + " (" + ar.getString(i) + ")"); } } } diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index c91c2f1..128adcb 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -63,7 +63,7 @@ public final class Bitmap implements Parcelable { private boolean mRecycled; // Package-scoped for fast access. - int mDensity = sDefaultDensity = getDefaultDensity(); + int mDensity = getDefaultDensity(); private static volatile Matrix sScaleMatrix; @@ -85,7 +85,7 @@ public final class Bitmap implements Parcelable { sDefaultDensity = DisplayMetrics.DENSITY_DEVICE; return sDefaultDensity; } - + /** * @noinspection UnusedDeclaration */ @@ -625,6 +625,22 @@ public final class Bitmap implements Parcelable { /** * Returns a mutable bitmap with the specified width and height. Its + * initial density is determined from the given {@link DisplayMetrics}. + * + * @param display Display metrics for the display this bitmap will be + * drawn on. + * @param width The width of the bitmap + * @param height The height of the bitmap + * @param config The bitmap config to create. + * @throws IllegalArgumentException if the width or height are <= 0 + */ + public static Bitmap createBitmap(DisplayMetrics display, int width, + int height, Config config) { + return createBitmap(display, width, height, config, true); + } + + /** + * Returns a mutable bitmap with the specified width and height. Its * initial density is as per {@link #getDensity}. * * @param width The width of the bitmap @@ -637,10 +653,33 @@ public final class Bitmap implements Parcelable { * @throws IllegalArgumentException if the width or height are <= 0 */ private static Bitmap createBitmap(int width, int height, Config config, boolean hasAlpha) { + return createBitmap(null, width, height, config, hasAlpha); + } + + /** + * Returns a mutable bitmap with the specified width and height. Its + * initial density is determined from the given {@link DisplayMetrics}. + * + * @param display Display metrics for the display this bitmap will be + * drawn on. + * @param width The width of the bitmap + * @param height The height of the bitmap + * @param config The bitmap config to create. + * @param hasAlpha If the bitmap is ARGB_8888 this flag can be used to mark the + * bitmap as opaque. Doing so will clear the bitmap in black + * instead of transparent. + * + * @throws IllegalArgumentException if the width or height are <= 0 + */ + private static Bitmap createBitmap(DisplayMetrics display, int width, int height, + Config config, boolean hasAlpha) { if (width <= 0 || height <= 0) { throw new IllegalArgumentException("width and height must be > 0"); } Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true); + if (display != null) { + bm.mDensity = display.densityDpi; + } if (config == Config.ARGB_8888 && !hasAlpha) { nativeErase(bm.mNativeBitmap, 0xff000000); nativeSetHasAlpha(bm.mNativeBitmap, hasAlpha); @@ -673,6 +712,31 @@ public final class Bitmap implements Parcelable { */ public static Bitmap createBitmap(int colors[], int offset, int stride, int width, int height, Config config) { + return createBitmap(null, colors, offset, stride, width, height, config); + } + + /** + * Returns a immutable bitmap with the specified width and height, with each + * pixel value set to the corresponding value in the colors array. Its + * initial density is determined from the given {@link DisplayMetrics}. + * + * @param display Display metrics for the display this bitmap will be + * drawn on. + * @param colors Array of {@link Color} used to initialize the pixels. + * @param offset Number of values to skip before the first color in the + * array of colors. + * @param stride Number of colors in the array between rows (must be >= + * width or <= -width). + * @param width The width of the bitmap + * @param height The height of the bitmap + * @param config The bitmap config to create. If the config does not + * support per-pixel alpha (e.g. RGB_565), then the alpha + * bytes in the colors[] will be ignored (assumed to be FF) + * @throws IllegalArgumentException if the width or height are <= 0, or if + * the color array's length is less than the number of pixels. + */ + public static Bitmap createBitmap(DisplayMetrics display, int colors[], + int offset, int stride, int width, int height, Config config) { checkWidthHeight(width, height); if (Math.abs(stride) < width) { @@ -687,8 +751,12 @@ public final class Bitmap implements Parcelable { if (width <= 0 || height <= 0) { throw new IllegalArgumentException("width and height must be > 0"); } - return nativeCreate(colors, offset, stride, width, height, + Bitmap bm = nativeCreate(colors, offset, stride, width, height, config.nativeInt, false); + if (display != null) { + bm.mDensity = display.densityDpi; + } + return bm; } /** @@ -707,7 +775,29 @@ public final class Bitmap implements Parcelable { * the color array's length is less than the number of pixels. */ public static Bitmap createBitmap(int colors[], int width, int height, Config config) { - return createBitmap(colors, 0, width, width, height, config); + return createBitmap(null, colors, 0, width, width, height, config); + } + + /** + * Returns a immutable bitmap with the specified width and height, with each + * pixel value set to the corresponding value in the colors array. Its + * initial density is determined from the given {@link DisplayMetrics}. + * + * @param display Display metrics for the display this bitmap will be + * drawn on. + * @param colors Array of {@link Color} used to initialize the pixels. + * This array must be at least as large as width * height. + * @param width The width of the bitmap + * @param height The height of the bitmap + * @param config The bitmap config to create. If the config does not + * support per-pixel alpha (e.g. RGB_565), then the alpha + * bytes in the colors[] will be ignored (assumed to be FF) + * @throws IllegalArgumentException if the width or height are <= 0, or if + * the color array's length is less than the number of pixels. + */ + public static Bitmap createBitmap(DisplayMetrics display, int colors[], + int width, int height, Config config) { + return createBitmap(display, colors, 0, width, width, height, config); } /** diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 215f597..fe459c7 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -964,7 +964,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } - public void setInitialDisplaySize(Display display, int width, int height) { + public void setInitialDisplaySize(Display display, int width, int height, int density) { mDisplay = display; int shortSize, longSize; @@ -1018,11 +1018,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { com.android.internal.R.dimen.navigation_bar_width); // SystemUI (status bar) layout policy - DisplayMetrics metrics = new DisplayMetrics(); - mDisplay.getMetrics(metrics); - int shortSizeDp = shortSize - * DisplayMetrics.DENSITY_DEFAULT - / metrics.densityDpi; + int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density; if (shortSizeDp < 600) { // 0-599dp: "phone" UI with a separate status & navigation bar @@ -1052,12 +1048,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { // The system bar is always at the bottom. If you are watching // a video in landscape, we don't need to hide it if we can still // show a 16:9 aspect ratio with it. - int longSizeDp = longSize - * DisplayMetrics.DENSITY_DEFAULT - / DisplayMetrics.DENSITY_DEVICE; + int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density; int barHeightDp = mNavigationBarHeightForRotation[mLandscapeRotation] - * DisplayMetrics.DENSITY_DEFAULT - / DisplayMetrics.DENSITY_DEVICE; + * DisplayMetrics.DENSITY_DEFAULT / density; int aspect = ((shortSizeDp-barHeightDp) * 16) / longSizeDp; // We have computed the aspect ratio with the bar height taken // out to be 16:aspect. If this is less than 9, then hiding diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java index 2305c88..a8854cf 100644 --- a/services/java/com/android/server/wm/DisplayContent.java +++ b/services/java/com/android/server/wm/DisplayContent.java @@ -56,8 +56,10 @@ class DisplayContent { final Object mDisplaySizeLock = new Object(); int mInitialDisplayWidth = 0; int mInitialDisplayHeight = 0; + int mInitialDisplayDensity = 0; int mBaseDisplayWidth = 0; int mBaseDisplayHeight = 0; + int mBaseDisplayDensity = 0; final DisplayManagerService mDisplayManager; final DisplayInfo mDisplayInfo = new DisplayInfo(); @@ -82,16 +84,14 @@ class DisplayContent { public void dump(PrintWriter pw) { pw.print(" Display: mDisplayId="); pw.println(mDisplayId); pw.print(" init="); pw.print(mInitialDisplayWidth); pw.print("x"); - pw.print(mInitialDisplayHeight); + pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity); + pw.print("dpi"); if (mInitialDisplayWidth != mBaseDisplayWidth - || mInitialDisplayHeight != mBaseDisplayHeight) { + || mInitialDisplayHeight != mBaseDisplayHeight + || mInitialDisplayDensity != mBaseDisplayDensity) { pw.print(" base="); pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight); - } - if (mInitialDisplayWidth != mDisplayInfo.logicalWidth - || mInitialDisplayHeight != mDisplayInfo.logicalHeight) { - pw.print(" init="); pw.print(mInitialDisplayWidth); - pw.print("x"); pw.print(mInitialDisplayHeight); + pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi"); } pw.print(" cur="); pw.print(mDisplayInfo.logicalWidth); diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index e763a56..5b04810 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -6568,6 +6568,7 @@ public class WindowManagerService extends IWindowManager.Stub displayInfo.rotation = mRotation; displayInfo.logicalWidth = dw; displayInfo.logicalHeight = dh; + displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity; displayInfo.appWidth = appWidth; displayInfo.appHeight = appHeight; displayInfo.getLogicalMetrics(mRealDisplayMetrics, null); @@ -6594,7 +6595,7 @@ public class WindowManagerService extends IWindowManager.Stub config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale); config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale); config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh); - config.densityDpi = mDisplayMetrics.densityDpi; + config.densityDpi = displayContent.mBaseDisplayDensity; // Update the configuration based on available input devices, lid switch, // and platform configuration. @@ -6902,8 +6903,8 @@ public class WindowManagerService extends IWindowManager.Stub info.width, info.height); mInputManager.setDisplayOrientation(Display.DEFAULT_DISPLAY, mDisplay.getRotation(), Surface.ROTATION_0); - mPolicy.setInitialDisplaySize(mDisplay, - displayContent.mInitialDisplayWidth, displayContent.mInitialDisplayHeight); + mPolicy.setInitialDisplaySize(mDisplay, displayContent.mInitialDisplayWidth, + displayContent.mInitialDisplayHeight, displayContent.mInitialDisplayDensity); } } @@ -6917,8 +6918,10 @@ public class WindowManagerService extends IWindowManager.Stub mDisplayManager.getDisplayInfo(displayId, displayInfo); displayContent.mInitialDisplayWidth = displayInfo.logicalWidth; displayContent.mInitialDisplayHeight = displayInfo.logicalHeight; + displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi; displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth; displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight; + displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity; } } @@ -6928,7 +6931,7 @@ public class WindowManagerService extends IWindowManager.Stub } synchronized (mWindowMap) { - readForcedDisplaySizeLocked(getDisplayContent(displayId)); + readForcedDisplaySizeAndDensityLocked(getDisplayContent(displayId)); } } @@ -7590,24 +7593,49 @@ public class WindowManagerService extends IWindowManager.Stub } } - private void readForcedDisplaySizeLocked(final DisplayContent displayContent) { - final String str = Settings.Secure.getString(mContext.getContentResolver(), + private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) { + boolean changed = false; + final String sizeStr = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.DISPLAY_SIZE_FORCED); - if (str == null || str.length() == 0) { - return; + if (sizeStr != null && sizeStr.length() > 0) { + final int pos = sizeStr.indexOf(','); + if (pos > 0 && sizeStr.lastIndexOf(',') == pos) { + int width, height; + try { + width = Integer.parseInt(sizeStr.substring(0, pos)); + height = Integer.parseInt(sizeStr.substring(pos+1)); + synchronized(displayContent.mDisplaySizeLock) { + if (displayContent.mBaseDisplayWidth != width + || displayContent.mBaseDisplayHeight != height) { + changed = true; + Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height); + displayContent.mBaseDisplayWidth = width; + displayContent.mBaseDisplayHeight = height; + } + } + } catch (NumberFormatException ex) { + } + } } - final int pos = str.indexOf(','); - if (pos <= 0 || str.lastIndexOf(',') != pos) { - return; + final String densityStr = Settings.Secure.getString(mContext.getContentResolver(), + Settings.Secure.DISPLAY_DENSITY_FORCED); + if (densityStr != null && densityStr.length() > 0) { + int density; + try { + density = Integer.parseInt(densityStr); + synchronized(displayContent.mDisplaySizeLock) { + if (displayContent.mBaseDisplayDensity != density) { + changed = true; + Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density); + displayContent.mBaseDisplayDensity = density; + } + } + } catch (NumberFormatException ex) { + } } - int width, height; - try { - width = Integer.parseInt(str.substring(0, pos)); - height = Integer.parseInt(str.substring(pos+1)); - } catch (NumberFormatException ex) { - return; + if (changed) { + reconfigureDisplayLocked(displayContent); } - setForcedDisplaySizeLocked(displayContent, width, height); } private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) { @@ -7617,8 +7645,49 @@ public class WindowManagerService extends IWindowManager.Stub displayContent.mBaseDisplayWidth = width; displayContent.mBaseDisplayHeight = height; } + reconfigureDisplayLocked(displayContent); + } + + public void clearForcedDisplaySize(int displayId) { + synchronized(mWindowMap) { + final DisplayContent displayContent = getDisplayContent(displayId); + setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth, + displayContent.mInitialDisplayHeight); + Settings.Secure.putString(mContext.getContentResolver(), + Settings.Secure.DISPLAY_SIZE_FORCED, ""); + } + } + + public void setForcedDisplayDensity(int displayId, int density) { + synchronized(mWindowMap) { + final DisplayContent displayContent = getDisplayContent(displayId); + setForcedDisplayDensityLocked(displayContent, density); + Settings.Secure.putString(mContext.getContentResolver(), + Settings.Secure.DISPLAY_SIZE_FORCED, Integer.toString(density)); + } + } + + private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) { + Slog.i(TAG, "Using new display density: " + density); + + synchronized(displayContent.mDisplaySizeLock) { + displayContent.mBaseDisplayDensity = density; + } + reconfigureDisplayLocked(displayContent); + } + + public void clearForcedDisplayDensity(int displayId) { + synchronized(mWindowMap) { + final DisplayContent displayContent = getDisplayContent(displayId); + setForcedDisplayDensityLocked(displayContent, displayContent.mInitialDisplayDensity); + Settings.Secure.putString(mContext.getContentResolver(), + Settings.Secure.DISPLAY_DENSITY_FORCED, ""); + } + } + + private void reconfigureDisplayLocked(DisplayContent displayContent) { mPolicy.setInitialDisplaySize(mDisplay, displayContent.mBaseDisplayWidth, - displayContent.mBaseDisplayHeight); + displayContent.mBaseDisplayHeight, displayContent.mBaseDisplayDensity); mLayoutNeeded = true; @@ -7642,16 +7711,6 @@ public class WindowManagerService extends IWindowManager.Stub performLayoutAndPlaceSurfacesLocked(); } - public void clearForcedDisplaySize(int displayId) { - synchronized(mWindowMap) { - final DisplayContent displayContent = getDisplayContent(displayId); - setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth, - displayContent.mInitialDisplayHeight); - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.DISPLAY_SIZE_FORCED, ""); - } - } - public boolean hasSystemNavBar() { return mPolicy.hasSystemNavBar(); } |