summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/content/Intent.java3
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java14
-rw-r--r--core/java/android/content/pm/PackageParser.java9
-rw-r--r--core/java/android/content/res/CompatibilityInfo.java62
-rw-r--r--core/java/android/content/res/Configuration.java51
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java3
-rw-r--r--core/java/android/util/DisplayMetrics.java98
-rw-r--r--core/java/android/view/Surface.java23
-rw-r--r--core/java/android/view/SurfaceView.java10
-rw-r--r--core/java/android/view/ViewRoot.java23
-rw-r--r--core/java/android/view/WindowManager.java8
-rw-r--r--core/java/android/widget/TextView.java15
12 files changed, 232 insertions, 87 deletions
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index b0dbfcb..a5f298c 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -4513,6 +4513,9 @@ public class Intent implements Parcelable {
* and {@link #FILL_IN_COMPONENT} to override the restriction where the
* corresponding field will not be replaced if it is already set.
*
+ * <p>Note: The component field will only be copied if {@link #FILL_IN_COMPONENT} is explicitly
+ * specified.
+ *
* <p>For example, consider Intent A with {data="foo", categories="bar"}
* and Intent B with {action="gotit", data-type="some/thing",
* categories="one","two"}.
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 28a77a5..4a3137f 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -161,12 +161,20 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public static final int FLAG_SUPPORTS_LARGE_SCREENS = 1<<11;
/**
+ * Value for {@link #flags}: true when the application knows how to adjust
+ * its UI for different screen sizes. Corresponds to
+ * {@link android.R.styleable#AndroidManifestSupportsScreens_resizeable
+ * android:resizeable}.
+ */
+ public static final int FLAG_RESIZEABLE_FOR_SCREENS = 1<<12;
+
+ /**
* Value for {@link #flags}: this is false if the application has set
* its android:allowBackup to false, true otherwise.
*
* {@hide}
*/
- public static final int FLAG_ALLOW_BACKUP = 1<<12;
+ public static final int FLAG_ALLOW_BACKUP = 1<<13;
/**
* Indicates that the application supports any densities;
@@ -183,7 +191,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* {@link #FLAG_ALLOW_CLEAR_USER_DATA}, {@link #FLAG_UPDATED_SYSTEM_APP},
* {@link #FLAG_TEST_ONLY}, {@link #FLAG_SUPPORTS_SMALL_SCREENS},
* {@link #FLAG_SUPPORTS_NORMAL_SCREENS},
- * {@link #FLAG_SUPPORTS_LARGE_SCREENS}.
+ * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_RESIZEABLE_FOR_SCREENS}.
*/
public int flags = 0;
@@ -400,7 +408,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
*/
public void disableCompatibilityMode() {
flags |= (FLAG_SUPPORTS_LARGE_SCREENS | FLAG_SUPPORTS_NORMAL_SCREENS |
- FLAG_SUPPORTS_SMALL_SCREENS);
+ FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS);
supportsDensities = ANY_DENSITIES_ARRAY;
}
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 39c27aa..93ba959 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -674,6 +674,7 @@ public class PackageParser {
int supportsSmallScreens = 1;
int supportsNormalScreens = 1;
int supportsLargeScreens = 1;
+ int resizeable = 1;
int outerDepth = parser.getDepth();
while ((type=parser.next()) != parser.END_DOCUMENT
@@ -883,6 +884,9 @@ public class PackageParser {
supportsLargeScreens = sa.getInteger(
com.android.internal.R.styleable.AndroidManifestSupportsScreens_largeScreens,
supportsLargeScreens);
+ resizeable = sa.getInteger(
+ com.android.internal.R.styleable.AndroidManifestSupportsScreens_resizeable,
+ supportsLargeScreens);
sa.recycle();
@@ -969,6 +973,11 @@ public class PackageParser {
>= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
}
+ if (resizeable < 0 || (resizeable > 0
+ && pkg.applicationInfo.targetSdkVersion
+ >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
+ pkg.applicationInfo.flags |= ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS;
+ }
int densities[] = null;
int size = pkg.supportsDensityList.size();
if (size > 0) {
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 6e34cc8..517551e 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -69,8 +69,8 @@ public class CompatibilityInfo {
/**
* A flag mask to indicates that the application can expand over the original size.
* The flag is set to true if
- * 1) Application declares its expandable in manifest file using <expandable /> or
- * 2) The screen size is same as (320 x 480) * density.
+ * 1) Application declares its expandable in manifest file using <supports-screens> or
+ * 2) Configuration.SCREENLAYOUT_COMPAT_NEEDED is not set
* {@see compatibilityFlag}
*/
private static final int EXPANDABLE = 2;
@@ -78,11 +78,28 @@ public class CompatibilityInfo {
/**
* A flag mask to tell if the application is configured to be expandable. This differs
* from EXPANDABLE in that the application that is not expandable will be
- * marked as expandable if it runs in (320x 480) * density screen size.
+ * marked as expandable if Configuration.SCREENLAYOUT_COMPAT_NEEDED is not set.
*/
private static final int CONFIGURED_EXPANDABLE = 4;
- private static final int SCALING_EXPANDABLE_MASK = SCALING_REQUIRED | EXPANDABLE;
+ /**
+ * A flag mask to indicates that the application supports large screens.
+ * The flag is set to true if
+ * 1) Application declares it supports large screens in manifest file using <supports-screens> or
+ * 2) The screen size is not large
+ * {@see compatibilityFlag}
+ */
+ private static final int LARGE_SCREENS = 8;
+
+ /**
+ * A flag mask to tell if the application supports large screens. This differs
+ * from LARGE_SCREENS in that the application that does not support large
+ * screens will be marked as supporting them if the current screen is not
+ * large.
+ */
+ private static final int CONFIGURED_LARGE_SCREENS = 16;
+
+ private static final int SCALING_EXPANDABLE_MASK = SCALING_REQUIRED | EXPANDABLE | LARGE_SCREENS;
/**
* The effective screen density we have selected for this application.
@@ -108,7 +125,10 @@ public class CompatibilityInfo {
appFlags = appInfo.flags;
if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
- mCompatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
+ mCompatibilityFlags |= LARGE_SCREENS | CONFIGURED_LARGE_SCREENS;
+ }
+ if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
+ mCompatibilityFlags |= EXPANDABLE | CONFIGURED_EXPANDABLE;
}
float packageDensityScale = -1.0f;
@@ -162,7 +182,8 @@ public class CompatibilityInfo {
private CompatibilityInfo() {
this(ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS
| ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
- | ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS,
+ | ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS
+ | ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS,
EXPANDABLE | CONFIGURED_EXPANDABLE,
DisplayMetrics.DENSITY_DEVICE,
1.0f,
@@ -190,6 +211,17 @@ public class CompatibilityInfo {
}
/**
+ * Sets large screen bit in the compatibility flag.
+ */
+ public void setLargeScreens(boolean expandable) {
+ if (expandable) {
+ mCompatibilityFlags |= CompatibilityInfo.LARGE_SCREENS;
+ } else {
+ mCompatibilityFlags &= ~CompatibilityInfo.LARGE_SCREENS;
+ }
+ }
+
+ /**
* @return true if the application is configured to be expandable.
*/
public boolean isConfiguredExpandable() {
@@ -197,6 +229,13 @@ public class CompatibilityInfo {
}
/**
+ * @return true if the application is configured to be expandable.
+ */
+ public boolean isConfiguredLargeScreens() {
+ return (mCompatibilityFlags & CompatibilityInfo.CONFIGURED_LARGE_SCREENS) != 0;
+ }
+
+ /**
* @return true if the scaling is required
*/
public boolean isScalingRequired() {
@@ -204,7 +243,8 @@ public class CompatibilityInfo {
}
public boolean supportsScreen() {
- return (mCompatibilityFlags & CompatibilityInfo.EXPANDABLE) != 0;
+ return (mCompatibilityFlags & (EXPANDABLE|LARGE_SCREENS))
+ == (EXPANDABLE|LARGE_SCREENS);
}
@Override
@@ -219,8 +259,8 @@ public class CompatibilityInfo {
* @param params the window's parameter
*/
public Translator getTranslator(WindowManager.LayoutParams params) {
- if ( (mCompatibilityFlags & CompatibilityInfo.SCALING_EXPANDABLE_MASK)
- == CompatibilityInfo.EXPANDABLE) {
+ if ( (mCompatibilityFlags & SCALING_EXPANDABLE_MASK)
+ == (EXPANDABLE|LARGE_SCREENS)) {
if (DBG) Log.d(TAG, "no translation required");
return null;
}
@@ -342,8 +382,8 @@ public class CompatibilityInfo {
public static void updateCompatibleScreenFrame(DisplayMetrics dm, int orientation,
Rect outRect) {
int width = dm.widthPixels;
- int portraitHeight = (int) (DEFAULT_PORTRAIT_HEIGHT * dm.density);
- int portraitWidth = (int) (DEFAULT_PORTRAIT_WIDTH * dm.density);
+ int portraitHeight = (int) (DEFAULT_PORTRAIT_HEIGHT * dm.density + 0.5f);
+ int portraitWidth = (int) (DEFAULT_PORTRAIT_WIDTH * dm.density + 0.5f);
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
int xOffset = (width - portraitHeight) / 2 ;
outRect.set(xOffset, 0, xOffset + portraitHeight, portraitWidth);
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 577aa60..5f44cc9 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -41,6 +41,39 @@ public final class Configuration implements Parcelable, Comparable<Configuration
*/
public boolean userSetLocale;
+ public static final int SCREENLAYOUT_SIZE_MASK = 0x0f;
+ public static final int SCREENLAYOUT_SIZE_UNDEFINED = 0x00;
+ public static final int SCREENLAYOUT_SIZE_SMALL = 0x01;
+ public static final int SCREENLAYOUT_SIZE_NORMAL = 0x02;
+ public static final int SCREENLAYOUT_SIZE_LARGE = 0x03;
+
+ public static final int SCREENLAYOUT_LONG_MASK = 0x30;
+ public static final int SCREENLAYOUT_LONG_UNDEFINED = 0x00;
+ public static final int SCREENLAYOUT_LONG_NO = 0x10;
+ public static final int SCREENLAYOUT_LONG_YES = 0x20;
+
+ /**
+ * Special flag we generate to indicate that the screen layout requires
+ * us to use a compatibility mode for apps that are not modern layout
+ * aware.
+ * @hide
+ */
+ public static final int SCREENLAYOUT_COMPAT_NEEDED = 0x10000000;
+
+ /**
+ * Bit mask of overall layout of the screen. Currently there are two
+ * fields:
+ * <p>The {@link #SCREENLAYOUT_SIZE_MASK} bits define the overall size
+ * of the screen. They may be one of
+ * {@link #SCREENLAYOUT_SIZE_SMALL}, {@link #SCREENLAYOUT_SIZE_NORMAL},
+ * or {@link #SCREENLAYOUT_SIZE_LARGE}.
+ *
+ * <p>The {@link #SCREENLAYOUT_LONG_MASK} defines whether the screen
+ * is wider/taller than normal. They may be one of
+ * {@link #SCREENLAYOUT_LONG_NO} or {@link #SCREENLAYOUT_LONG_YES}.
+ */
+ public int screenLayout;
+
public static final int TOUCHSCREEN_UNDEFINED = 0;
public static final int TOUCHSCREEN_NOTOUCH = 1;
public static final int TOUCHSCREEN_STYLUS = 2;
@@ -116,18 +149,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration
*/
public int orientation;
- public static final int SCREENLAYOUT_UNDEFINED = 0;
- public static final int SCREENLAYOUT_SMALL = 1;
- public static final int SCREENLAYOUT_NORMAL = 2;
- public static final int SCREENLAYOUT_LARGE = 3;
-
- /**
- * Overall layout of the screen. May be one of
- * {@link #SCREENLAYOUT_SMALL}, {@link #SCREENLAYOUT_NORMAL},
- * or {@link #SCREENLAYOUT_LARGE}.
- */
- public int screenLayout;
-
/**
* Construct an invalid Configuration. You must call {@link #setToDefaults}
* for this object to be valid. {@more}
@@ -198,7 +219,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
hardKeyboardHidden = HARDKEYBOARDHIDDEN_UNDEFINED;
navigation = NAVIGATION_UNDEFINED;
orientation = ORIENTATION_UNDEFINED;
- screenLayout = SCREENLAYOUT_UNDEFINED;
+ screenLayout = SCREENLAYOUT_SIZE_UNDEFINED;
}
/** {@hide} */
@@ -269,7 +290,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
changed |= ActivityInfo.CONFIG_ORIENTATION;
orientation = delta.orientation;
}
- if (delta.screenLayout != SCREENLAYOUT_UNDEFINED
+ if (delta.screenLayout != SCREENLAYOUT_SIZE_UNDEFINED
&& screenLayout != delta.screenLayout) {
changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
screenLayout = delta.screenLayout;
@@ -342,7 +363,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
&& orientation != delta.orientation) {
changed |= ActivityInfo.CONFIG_ORIENTATION;
}
- if (delta.screenLayout != SCREENLAYOUT_UNDEFINED
+ if (delta.screenLayout != SCREENLAYOUT_SIZE_UNDEFINED
&& screenLayout != delta.screenLayout) {
changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
}
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 7d331dc..184d6dc 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -1412,8 +1412,9 @@ public class SQLiteDatabase extends SQLiteClosable {
StringBuilder sql = new StringBuilder(120);
sql.append("UPDATE ");
if (algorithm != null) {
- sql.append(" OR ");
+ sql.append("OR ");
sql.append(algorithm.value());
+ sql.append(" ");
}
sql.append(table);
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index bfab49d..061f98a 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -123,47 +123,67 @@ public class DisplayMetrics {
*/
public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation,
int screenLayout) {
- if (!compatibilityInfo.isConfiguredExpandable()) {
- // Note: this assume that configuration is updated before calling
- // updateMetrics method.
- if (screenLayout == Configuration.SCREENLAYOUT_LARGE) {
- // This is a large screen device and the app is not
- // compatible with large screens, to diddle it.
-
+ boolean expandable = compatibilityInfo.isConfiguredExpandable();
+ boolean largeScreens = compatibilityInfo.isConfiguredLargeScreens();
+
+ // Note: this assume that configuration is updated before calling
+ // updateMetrics method.
+ if (!expandable) {
+ if ((screenLayout&Configuration.SCREENLAYOUT_COMPAT_NEEDED) == 0) {
+ expandable = true;
+ // the current screen size is compatible with non-resizing apps.
+ compatibilityInfo.setExpandable(true);
+ } else {
compatibilityInfo.setExpandable(false);
- // Figure out the compatibility width and height of the screen.
- int defaultWidth;
- int defaultHeight;
- switch (orientation) {
- case Configuration.ORIENTATION_LANDSCAPE: {
- defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
- defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
- break;
- }
- case Configuration.ORIENTATION_PORTRAIT:
- case Configuration.ORIENTATION_SQUARE:
- default: {
- defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
- defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
- break;
- }
- case Configuration.ORIENTATION_UNDEFINED: {
- // don't change
- return;
- }
+ }
+ }
+ if (!largeScreens) {
+ if ((screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK)
+ != Configuration.SCREENLAYOUT_SIZE_LARGE) {
+ largeScreens = true;
+ // the current screen size is not large.
+ compatibilityInfo.setLargeScreens(true);
+ } else {
+ compatibilityInfo.setLargeScreens(false);
+ }
+ }
+
+ if (!expandable || !largeScreens) {
+ // This is a larger screen device and the app is not
+ // compatible with large screens, so diddle it.
+
+ // Figure out the compatibility width and height of the screen.
+ int defaultWidth;
+ int defaultHeight;
+ switch (orientation) {
+ case Configuration.ORIENTATION_LANDSCAPE: {
+ defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density +
+ 0.5f);
+ defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density +
+ 0.5f);
+ break;
}
-
- if (defaultWidth < widthPixels) {
- // content/window's x offset in original pixels
- widthPixels = defaultWidth;
+ case Configuration.ORIENTATION_PORTRAIT:
+ case Configuration.ORIENTATION_SQUARE:
+ default: {
+ defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density +
+ 0.5f);
+ defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density +
+ 0.5f);
+ break;
}
- if (defaultHeight < heightPixels) {
- heightPixels = defaultHeight;
+ case Configuration.ORIENTATION_UNDEFINED: {
+ // don't change
+ return;
}
-
- } else {
- // the screen size is same as expected size. make it expandable
- compatibilityInfo.setExpandable(true);
+ }
+
+ if (defaultWidth < widthPixels) {
+ // content/window's x offset in original pixels
+ widthPixels = defaultWidth;
+ }
+ if (defaultHeight < heightPixels) {
+ heightPixels = defaultHeight;
}
}
if (compatibilityInfo.isScalingRequired()) {
@@ -172,8 +192,8 @@ public class DisplayMetrics {
scaledDensity *= invertedRatio;
xdpi *= invertedRatio;
ydpi *= invertedRatio;
- widthPixels *= invertedRatio;
- heightPixels *= invertedRatio;
+ widthPixels = (int) (widthPixels * invertedRatio + 0.5f);
+ heightPixels = (int) (heightPixels * invertedRatio + 0.5f);
}
}
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 0178d63..83c30e1 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -19,6 +19,7 @@ package android.view;
import android.graphics.*;
import android.os.Parcelable;
import android.os.Parcel;
+import android.util.DisplayMetrics;
import android.util.Log;
/**
@@ -131,6 +132,10 @@ public class Surface implements Parcelable {
@SuppressWarnings("unused")
private Canvas mCanvas;
+ // The display metrics used to provide the pseudo canvas size for applications
+ // running in compatibility mode. This is set to null for regular mode.
+ private DisplayMetrics mDisplayMetrics;
+
/**
* Exception thrown when a surface couldn't be created or resized
*/
@@ -167,7 +172,23 @@ public class Surface implements Parcelable {
* {@hide}
*/
public Surface() {
- mCanvas = new Canvas();
+ mCanvas = new Canvas() {
+ @Override
+ public int getWidth() {
+ return mDisplayMetrics == null ? super.getWidth() : mDisplayMetrics.widthPixels;
+ }
+ @Override
+ public int getHeight() {
+ return mDisplayMetrics == null ? super.getHeight() : mDisplayMetrics.heightPixels;
+ }
+ };
+ }
+
+ /**
+ * Sets the display metrics used to provide canva's width/height in comaptibility mode.
+ */
+ void setCompatibleDisplayMetrics(DisplayMetrics metrics) {
+ mDisplayMetrics = metrics;
}
/**
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index aa701af..95bba97 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -17,6 +17,7 @@
package android.view;
import android.content.Context;
+import android.content.res.Resources;
import android.content.res.CompatibilityInfo.Translator;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
@@ -301,6 +302,11 @@ public class SurfaceView extends View {
float appScale = mTranslator == null ? 1.0f : mTranslator.applicationScale;
+ Resources res = getContext().getResources();
+ if (mTranslator != null || !res.getCompatibilityInfo().supportsScreen()) {
+ mSurface.setCompatibleDisplayMetrics(res.getDisplayMetrics());
+ }
+
int myWidth = mRequestedWidth;
if (myWidth <= 0) myWidth = getWidth();
int myHeight = mRequestedHeight;
@@ -309,8 +315,8 @@ public class SurfaceView extends View {
// Use original size if the app specified the size of the view,
// and let the flinger to scale up.
if (mRequestedWidth <= 0 && mTranslator != null) {
- myWidth *= appScale;
- myHeight *= appScale;
+ myWidth = (int) (myWidth * appScale + 0.5f);
+ myHeight = (int) (myHeight * appScale + 0.5f);
mScaled = true;
} else {
mScaled = false;
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 301d604..2f92b32 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -42,6 +42,7 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.Scroller;
import android.content.pm.PackageManager;
import android.content.res.CompatibilityInfo;
+import android.content.res.Resources;
import android.content.Context;
import android.app.ActivityManagerNative;
import android.Manifest;
@@ -386,10 +387,14 @@ public final class ViewRoot extends Handler implements ViewParent,
mView = view;
mWindowAttributes.copyFrom(attrs);
attrs = mWindowAttributes;
-
- CompatibilityInfo compatibilityInfo =
- mView.getContext().getResources().getCompatibilityInfo();
+ Resources resources = mView.getContext().getResources();
+ CompatibilityInfo compatibilityInfo = resources.getCompatibilityInfo();
mTranslator = compatibilityInfo.getTranslator(attrs);
+
+ if (mTranslator != null || !compatibilityInfo.supportsScreen()) {
+ mSurface.setCompatibleDisplayMetrics(resources.getDisplayMetrics());
+ }
+
boolean restore = false;
if (attrs != null && mTranslator != null) {
restore = true;
@@ -907,7 +912,8 @@ public final class ViewRoot extends Handler implements ViewParent,
mHeight = frame.height();
if (initialized) {
- mGlCanvas.setViewport((int) (mWidth * appScale), (int) (mHeight * appScale));
+ mGlCanvas.setViewport((int) (mWidth * appScale + 0.5f),
+ (int) (mHeight * appScale + 0.5f));
}
boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
@@ -1237,7 +1243,7 @@ public final class ViewRoot extends Handler implements ViewParent,
if (fullRedrawNeeded) {
mAttachInfo.mIgnoreDirtyState = true;
- dirty.union(0, 0, (int) (mWidth * appScale), (int) (mHeight * appScale));
+ dirty.union(0, 0, (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f));
}
if (DEBUG_ORIENTATION || DEBUG_DRAW) {
@@ -1749,7 +1755,8 @@ public final class ViewRoot extends Handler implements ViewParent,
if (mGlCanvas != null) {
float appScale = mAttachInfo.mApplicationScale;
mGlCanvas.setViewport(
- (int) (mWidth * appScale), (int) (mHeight * appScale));
+ (int) (mWidth * appScale + 0.5f),
+ (int) (mHeight * appScale + 0.5f));
}
}
}
@@ -2394,8 +2401,8 @@ public final class ViewRoot extends Handler implements ViewParent,
}
int relayoutResult = sWindowSession.relayout(
mWindow, params,
- (int) (mView.mMeasuredWidth * appScale),
- (int) (mView.mMeasuredHeight * appScale),
+ (int) (mView.mMeasuredWidth * appScale + 0.5f),
+ (int) (mView.mMeasuredHeight * appScale + 0.5f),
viewVisibility, insetsPending, mWinFrame,
mPendingContentInsets, mPendingVisibleInsets, mSurface);
if (restore) {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 6a26a31..c0be9e8 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -991,13 +991,13 @@ public interface WindowManager extends ViewManager {
* @hide
*/
public void scale(float scale) {
- x *= scale;
- y *= scale;
+ x = (int) (x * scale + 0.5f);
+ y = (int) (y * scale + 0.5f);
if (width > 0) {
- width *= scale;
+ width = (int) (width * scale + 0.5f);
}
if (height > 0) {
- height *= scale;
+ height = (int) (height * scale + 0.5f);
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d8ed4f0..3fab692 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -2443,7 +2443,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (ss.error != null) {
- setError(ss.error);
+ final CharSequence error = ss.error;
+ // Display the error later, after the first layout pass
+ post(new Runnable() {
+ public void run() {
+ setError(error);
+ }
+ });
}
}
@@ -3263,7 +3269,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final TextView err = (TextView) inflater.inflate(com.android.internal.R.layout.textview_hint,
null);
- mPopup = new ErrorPopup(err, 200, 50);
+ final float scale = getResources().getDisplayMetrics().density;
+ mPopup = new ErrorPopup(err, (int) (200 * scale + 0.5f),
+ (int) (50 * scale + 0.5f));
mPopup.setFocusable(false);
// The user is entering text, so the input method is needed. We
// don't want the popup to be displayed on top of it.
@@ -3317,11 +3325,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* The "25" is the distance between the point and the right edge
* of the background
*/
+ final float scale = getResources().getDisplayMetrics().density;
final Drawables dr = mDrawables;
return getWidth() - mPopup.getWidth()
- getPaddingRight()
- - (dr != null ? dr.mDrawableSizeRight : 0) / 2 + 25;
+ - (dr != null ? dr.mDrawableSizeRight : 0) / 2 + (int) (25 * scale + 0.5f);
}
/**