summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt4
-rw-r--r--cmds/am/src/com/android/commands/am/Am.java43
-rw-r--r--core/java/android/app/ActivityThread.java40
-rwxr-xr-xcore/java/android/content/res/Resources.java53
-rw-r--r--core/java/android/provider/Settings.java7
-rw-r--r--core/java/android/util/DisplayMetrics.java2
-rw-r--r--core/java/android/view/Display.java1
-rw-r--r--core/java/android/view/IWindowManager.aidl2
-rw-r--r--core/java/android/view/TextureView.java3
-rw-r--r--core/java/android/view/View.java6
-rw-r--r--core/java/android/view/ViewDebug.java5
-rw-r--r--core/java/android/view/WindowManagerPolicy.java2
-rw-r--r--core/java/android/widget/StackView.java4
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java15
-rw-r--r--graphics/java/android/graphics/Bitmap.java98
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java15
-rw-r--r--services/java/com/android/server/wm/DisplayContent.java14
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java117
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();
}