am c404e9b2: Merge "More compatibility mode improvements." into honeycomb-mr2

* commit 'c404e9b20165f634904d1489216d17d8e09fe696':
  More compatibility mode improvements.
This commit is contained in:
Dianne Hackborn
2011-05-24 19:10:53 -07:00
committed by Android Git Automerger
11 changed files with 172 additions and 108 deletions

View File

@ -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);
}});
}

View File

@ -1045,7 +1045,7 @@ public class Instrumentation {
}
}
activity.onCreate(icicle);
activity.performCreate(icicle);
if (mActivityMonitors != null) {
synchronized (mSync) {

View File

@ -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()) {

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
/**

View File

@ -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();
}