diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-05-24 19:07:55 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-05-24 19:07:55 -0700 |
commit | c404e9b20165f634904d1489216d17d8e09fe696 (patch) | |
tree | 80e855064d573e1b198fe6b7a320758eb94fffb0 /core | |
parent | 36ac304c6e62dbb1caaf729c70d7aa956aff63be (diff) | |
parent | 5be8de3420ba4c9d816b98e29bdec11715f6b626 (diff) | |
download | frameworks_base-c404e9b20165f634904d1489216d17d8e09fe696.zip frameworks_base-c404e9b20165f634904d1489216d17d8e09fe696.tar.gz frameworks_base-c404e9b20165f634904d1489216d17d8e09fe696.tar.bz2 |
Merge "More compatibility mode improvements." into honeycomb-mr2
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/app/ContextImpl.java | 8 | ||||
-rw-r--r-- | core/java/android/app/Instrumentation.java | 2 | ||||
-rw-r--r-- | core/java/android/content/res/CompatibilityInfo.java | 19 | ||||
-rw-r--r-- | core/java/android/content/res/Configuration.java | 5 | ||||
-rwxr-xr-x | core/java/android/content/res/Resources.java | 28 | ||||
-rw-r--r-- | core/java/android/view/Display.java | 50 | ||||
-rw-r--r-- | core/java/android/view/Surface.java | 26 | ||||
-rw-r--r-- | core/java/android/view/SurfaceView.java | 6 | ||||
-rw-r--r-- | core/java/android/view/ViewRoot.java | 5 | ||||
-rw-r--r-- | core/java/android/view/Window.java | 31 | ||||
-rw-r--r-- | core/java/android/view/WindowManagerImpl.java | 100 |
11 files changed, 172 insertions, 108 deletions
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 36b9d72..51f1e3d 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -35,6 +35,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.res.AssetManager; +import android.content.res.CompatibilityInfo; import android.content.res.Resources; import android.database.DatabaseErrorHandler; import android.database.sqlite.SQLiteDatabase; @@ -78,6 +79,7 @@ import android.content.ClipboardManager; import android.util.AndroidRuntimeException; import android.util.Log; import android.view.ContextThemeWrapper; +import android.view.Display; import android.view.WindowManagerImpl; import android.view.accessibility.AccessibilityManager; import android.view.inputmethod.InputMethodManager; @@ -423,7 +425,11 @@ class ContextImpl extends Context { registerService(WINDOW_SERVICE, new ServiceFetcher() { public Object getService(ContextImpl ctx) { - return WindowManagerImpl.getDefault(); + RuntimeException e = new RuntimeException("foo"); + e.fillInStackTrace(); + Log.i(TAG, "Getting window manager", e); + CompatibilityInfo ci = ctx.mResources.getCompatibilityInfo(); + return WindowManagerImpl.getDefault(ci); }}); } diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index cd278be..3d4c966 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -1045,7 +1045,7 @@ public class Instrumentation { } } - activity.onCreate(icicle); + activity.performCreate(icicle); if (mActivityMonitors != null) { synchronized (mSync) { diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index 8bcb005..854d410 100644 --- a/core/java/android/content/res/CompatibilityInfo.java +++ b/core/java/android/content/res/CompatibilityInfo.java @@ -125,14 +125,16 @@ public class CompatibilityInfo implements Parcelable { if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) { compatFlags |= XLARGE_SCREENS | EXPANDABLE; } - if (!forceCompat) { + if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) { + compatFlags |= EXPANDABLE; + } + + if (forceCompat) { // If we are forcing compatibility mode, then ignore an app that // just says it is resizable for screens. We'll only have it fill // the screen if it explicitly says it supports the screen size we // are running in. - if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) { - compatFlags |= EXPANDABLE; - } + compatFlags &= ~EXPANDABLE; } boolean supportsScreen = false; @@ -155,12 +157,10 @@ public class CompatibilityInfo implements Parcelable { break; } - if ((screenLayout&Configuration.SCREENLAYOUT_COMPAT_NEEDED) == 0) { + if ((screenLayout&Configuration.SCREENLAYOUT_COMPAT_NEEDED) != 0) { if ((compatFlags&EXPANDABLE) != 0) { supportsScreen = true; - } - if ((compatFlags&EXPANDABLE) == 0 && - (appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) == 0) { + } else if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) == 0) { compatFlags |= ALWAYS_COMPAT; } } @@ -382,6 +382,9 @@ public class CompatibilityInfo implements Parcelable { // This is a larger screen device and the app is not // compatible with large screens, so diddle it. CompatibilityInfo.updateCompatibleScreenFrame(inoutDm, null, inoutDm); + } else { + inoutDm.widthPixels = inoutDm.realWidthPixels; + inoutDm.heightPixels = inoutDm.realHeightPixels; } if (isScalingRequired()) { diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index 51a7115..d476997 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -316,10 +316,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration StringBuilder sb = new StringBuilder(128); sb.append("{"); sb.append(fontScale); - sb.append("x imsi="); + sb.append(" "); sb.append(mcc); - sb.append("/"); + sb.append("mcc"); sb.append(mnc); + sb.append("mnc"); if (locale != null) { sb.append(" "); sb.append(locale); diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index a072e94..e63e7eb 100755 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -115,7 +115,6 @@ public class Resources { private NativePluralRules mPluralRule; private CompatibilityInfo mCompatibilityInfo; - private Display mDefaultDisplay; private static final LongSparseArray<Object> EMPTY_ARRAY = new LongSparseArray<Object>(0) { @Override @@ -1426,6 +1425,15 @@ public class Resources { } if (metrics != null) { mMetrics.setTo(metrics); + // NOTE: We should re-arrange this code to create a Display + // with the CompatibilityInfo that is used everywhere we deal + // with the display in relation to this app, rather than + // doing the conversion here. This impl should be okay because + // we make sure to return a compatible display in the places + // where there are public APIs to retrieve the display... but + // it would be cleaner and more maintainble to just be + // consistently dealing with a compatible display everywhere in + // the framework. mCompatibilityInfo.applyToDisplayMetrics(mMetrics); } mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale; @@ -2121,24 +2129,6 @@ public class Resources { + Integer.toHexString(id)); } - /** - * Returns the display adjusted for the Resources' metrics. - * @hide - */ - public Display getDefaultDisplay(Display defaultDisplay) { - if (mDefaultDisplay == null) { - if (!mCompatibilityInfo.isScalingRequired() && mCompatibilityInfo.supportsScreen()) { - // the app supports the display. just use the default one. - mDefaultDisplay = defaultDisplay; - } else { - // display needs adjustment. - mDefaultDisplay = Display.createMetricsBasedDisplay( - defaultDisplay.getDisplayId(), mMetrics); - } - } - return mDefaultDisplay; - } - private TypedArray getCachedStyledAttributes(int len) { synchronized (mTmpValue) { TypedArray attrs = mCachedStyledAttributes; diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 1d60066..b5d36d9 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -16,6 +16,7 @@ package android.view; +import android.content.res.CompatibilityInfo; import android.graphics.Point; import android.graphics.Rect; import android.os.RemoteException; @@ -37,7 +38,7 @@ public class Display { * Display gives you access to some information about a particular display * connected to the device. */ - Display(int display) { + Display(int display, CompatibilityInfo compatInfo) { // initalize the statics when this class is first instansiated. This is // done here instead of in the static block because Zygote synchronized (sStaticInit) { @@ -46,6 +47,12 @@ public class Display { sInitialized = true; } } + if (compatInfo != null && (compatInfo.isScalingRequired() + || !compatInfo.supportsScreen())) { + mCompatibilityInfo = compatInfo; + } else { + mCompatibilityInfo = null; + } mDisplay = display; init(display); } @@ -82,6 +89,16 @@ public class Display { // system process before the window manager is up. outSize.y = getRealHeight(); } + if (mCompatibilityInfo != null) { + synchronized (mTmpMetrics) { + mTmpMetrics.realWidthPixels = outSize.x; + mTmpMetrics.realHeightPixels = outSize.y; + mTmpMetrics.density = mDensity; + mCompatibilityInfo.applyToDisplayMetrics(mTmpMetrics); + outSize.x = mTmpMetrics.widthPixels; + outSize.y = mTmpMetrics.heightPixels; + } + } } catch (RemoteException e) { Slog.w("Display", "Unable to get display size", e); } @@ -206,6 +223,10 @@ public class Display { outMetrics.heightPixels = mTmpPoint.y; } getNonSizeMetrics(outMetrics); + + if (mCompatibilityInfo != null) { + mCompatibilityInfo.applyToDisplayMetrics(outMetrics); + } } /** @@ -249,7 +270,8 @@ public class Display { private native void init(int display); - private int mDisplay; + private final CompatibilityInfo mCompatibilityInfo; + private final int mDisplay; // Following fields are initialized from native code private int mPixelFormat; private float mRefreshRate; @@ -258,6 +280,7 @@ public class Display { private float mDpiY; private final Point mTmpPoint = new Point(); + private final DisplayMetrics mTmpMetrics = new DisplayMetrics(); private float mLastGetTime; private static final Object sStaticInit = new Object(); @@ -268,27 +291,8 @@ public class Display { * Returns a display object which uses the metric's width/height instead. * @hide */ - public static Display createMetricsBasedDisplay(int displayId, DisplayMetrics metrics) { - return new CompatibleDisplay(displayId, metrics); - } - - private static class CompatibleDisplay extends Display { - private final DisplayMetrics mMetrics; - - private CompatibleDisplay(int displayId, DisplayMetrics metrics) { - super(displayId); - mMetrics = metrics; - } - - @Override - public int getWidth() { - return mMetrics.widthPixels; - } - - @Override - public int getHeight() { - return mMetrics.heightPixels; - } + public static Display createCompatibleDisplay(int displayId, CompatibilityInfo compat) { + return new Display(displayId, compat); } } diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 83f9119..c913bb3 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -20,7 +20,6 @@ import android.content.res.CompatibilityInfo.Translator; import android.graphics.*; import android.os.Parcelable; import android.os.Parcel; -import android.util.DisplayMetrics; import android.util.Log; /** @@ -174,9 +173,9 @@ public class Surface implements Parcelable { private int mSurfaceGenerationId; private String mName; - // The display metrics used to provide the pseudo canvas size for applications - // running in compatibility mode. This is set to null for non compatibility mode. - private DisplayMetrics mCompatibleDisplayMetrics; + // The Translator for density compatibility mode. This is used for scaling + // the canvas to perform the appropriate density transformation. + private Translator mCompatibilityTranslator; // A matrix to scale the matrix set by application. This is set to null for // non compatibility mode. @@ -263,14 +262,20 @@ public class Surface implements Parcelable { @Override public int getWidth() { - return mCompatibleDisplayMetrics == null ? - super.getWidth() : mCompatibleDisplayMetrics.widthPixels; + int w = super.getWidth(); + if (mCompatibilityTranslator != null) { + w = (int)(w * mCompatibilityTranslator.applicationInvertedScale + .5f); + } + return w; } @Override public int getHeight() { - return mCompatibleDisplayMetrics == null ? - super.getHeight() : mCompatibleDisplayMetrics.heightPixels; + int h = super.getHeight(); + if (mCompatibilityTranslator != null) { + h = (int)(h * mCompatibilityTranslator.applicationInvertedScale + .5f); + } + return h; } @Override @@ -297,10 +302,9 @@ public class Surface implements Parcelable { } /** - * Sets the display metrics used to provide canvas's width/height in compatibility mode. + * Sets the translator used to scale canvas's width/height in compatibility mode. */ - void setCompatibleDisplayMetrics(DisplayMetrics metrics, Translator translator) { - mCompatibleDisplayMetrics = metrics; + void setCompatibilityTranslator(Translator translator) { if (translator != null) { float appScale = translator.applicationScale; mCompatibleMatrix = new Matrix(); diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 87b3d79..3efc799 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -21,7 +21,6 @@ import com.android.internal.view.BaseIWindow; import android.content.Context; import android.content.res.Configuration; -import android.content.res.Resources; import android.content.res.CompatibilityInfo.Translator; import android.graphics.Canvas; import android.graphics.PixelFormat; @@ -433,9 +432,8 @@ public class SurfaceView extends View { mTranslator = viewRoot.mTranslator; } - Resources res = getContext().getResources(); - if (mTranslator != null || !res.getCompatibilityInfo().supportsScreen()) { - mSurface.setCompatibleDisplayMetrics(res.getDisplayMetrics(), mTranslator); + if (mTranslator != null) { + mSurface.setCompatibilityTranslator(mTranslator); } int myWidth = mRequestedWidth; diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index a4aeed8..5ad0b6b 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -373,9 +373,8 @@ public final class ViewRoot extends Handler implements ViewParent, CompatibilityInfo compatibilityInfo = resources.getCompatibilityInfo(); mTranslator = compatibilityInfo.getTranslator(); - if (mTranslator != null || !compatibilityInfo.supportsScreen()) { - mSurface.setCompatibleDisplayMetrics(resources.getDisplayMetrics(), - mTranslator); + if (mTranslator != null) { + mSurface.setCompatibilityTranslator(mTranslator); } boolean restore = false; diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 2095a93..5236a9e 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -17,6 +17,7 @@ package android.view; import android.content.Context; +import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.content.res.TypedArray; import android.graphics.PixelFormat; @@ -462,13 +463,11 @@ public abstract class Window { mWindowManager = new LocalWindowManager(wm, hardwareAccelerated); } - private class LocalWindowManager implements WindowManager { - private boolean mHardwareAccelerated; + private class LocalWindowManager extends WindowManagerImpl.CompatModeWrapper { + private final boolean mHardwareAccelerated; LocalWindowManager(WindowManager wm, boolean hardwareAccelerated) { - mWindowManager = wm; - mDefaultDisplay = mContext.getResources().getDefaultDisplay( - mWindowManager.getDefaultDisplay()); + super(wm, mContext.getResources().getCompatibilityInfo()); mHardwareAccelerated = hardwareAccelerated; } @@ -523,28 +522,8 @@ public abstract class Window { if (mHardwareAccelerated) { wp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; } - mWindowManager.addView(view, params); + super.addView(view, params); } - - public void updateViewLayout(View view, ViewGroup.LayoutParams params) { - mWindowManager.updateViewLayout(view, params); - } - - public final void removeView(View view) { - mWindowManager.removeView(view); - } - - public final void removeViewImmediate(View view) { - mWindowManager.removeViewImmediate(view); - } - - public Display getDefaultDisplay() { - return mDefaultDisplay; - } - - private final WindowManager mWindowManager; - - private final Display mDefaultDisplay; } /** diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index a4c4544..9cae75c 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -16,6 +16,9 @@ package android.view; +import java.util.HashMap; + +import android.content.res.CompatibilityInfo; import android.graphics.PixelFormat; import android.os.IBinder; import android.util.AndroidRuntimeException; @@ -75,9 +78,92 @@ public class WindowManagerImpl implements WindowManager { public static final int ADD_MULTIPLE_SINGLETON = -7; public static final int ADD_PERMISSION_DENIED = -8; - public static WindowManagerImpl getDefault() - { - return mWindowManager; + private View[] mViews; + private ViewRoot[] mRoots; + private WindowManager.LayoutParams[] mParams; + + private final static Object sLock = new Object(); + private final static WindowManagerImpl sWindowManager = new WindowManagerImpl(); + private final static HashMap<CompatibilityInfo, WindowManager> sCompatWindowManagers + = new HashMap<CompatibilityInfo, WindowManager>(); + + static class CompatModeWrapper implements WindowManager { + private final WindowManager mWindowManager; + private final Display mDefaultDisplay; + + CompatModeWrapper(WindowManager wm, CompatibilityInfo ci) { + mWindowManager = wm; + + // Use the original display if there is no compatibility mode + // to apply, or the underlying window manager is already a + // compatibility mode wrapper. (We assume that if it is a + // wrapper, it is applying the same compatibility mode.) + if (ci == null || wm instanceof CompatModeWrapper + || (!ci.isScalingRequired() && ci.supportsScreen())) { + mDefaultDisplay = mWindowManager.getDefaultDisplay(); + } else { + //mDefaultDisplay = mWindowManager.getDefaultDisplay(); + mDefaultDisplay = Display.createCompatibleDisplay( + mWindowManager.getDefaultDisplay().getDisplayId(), ci); + } + } + + @Override + public void addView(View view, android.view.ViewGroup.LayoutParams params) { + mWindowManager.addView(view, params); + } + + @Override + public void updateViewLayout(View view, android.view.ViewGroup.LayoutParams params) { + mWindowManager.updateViewLayout(view, params); + + } + + @Override + public void removeView(View view) { + mWindowManager.removeView(view); + } + + @Override + public Display getDefaultDisplay() { + return mDefaultDisplay; + } + + @Override + public void removeViewImmediate(View view) { + mWindowManager.removeViewImmediate(view); + } + + @Override + public boolean isHardwareAccelerated() { + return mWindowManager.isHardwareAccelerated(); + } + + } + + public static WindowManagerImpl getDefault() { + return sWindowManager; + } + + public static WindowManager getDefault(CompatibilityInfo compatInfo) { + if (compatInfo == null || (!compatInfo.isScalingRequired() + && compatInfo.supportsScreen())) { + return sWindowManager; + } + + synchronized (sLock) { + // NOTE: It would be cleaner to move the implementation of + // WindowManagerImpl into a static inner class, and have this + // public impl just call into that. Then we can make multiple + // instances of WindowManagerImpl for compat mode rather than + // having to make wrappers. + WindowManager wm = sCompatWindowManagers.get(compatInfo); + if (wm == null) { + wm = new CompatModeWrapper(sWindowManager, compatInfo); + sCompatWindowManagers.put(compatInfo, wm); + } + return wm; + } } public boolean isHardwareAccelerated() { @@ -341,13 +427,9 @@ public class WindowManagerImpl implements WindowManager { } public Display getDefaultDisplay() { - return new Display(Display.DEFAULT_DISPLAY); + return new Display(Display.DEFAULT_DISPLAY, null); } - private View[] mViews; - private ViewRoot[] mRoots; - private WindowManager.LayoutParams[] mParams; - private static void removeItem(Object[] dst, Object[] src, int index) { if (dst.length > 0) { @@ -376,6 +458,4 @@ public class WindowManagerImpl implements WindowManager { return -1; } } - - private static WindowManagerImpl mWindowManager = new WindowManagerImpl(); } |