am c404e9b2
: Merge "More compatibility mode improvements." into honeycomb-mr2
* commit 'c404e9b20165f634904d1489216d17d8e09fe696': More compatibility mode improvements.
This commit is contained in:
@ -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);
|
||||
}});
|
||||
}
|
||||
|
||||
|
@ -1045,7 +1045,7 @@ public class Instrumentation {
|
||||
}
|
||||
}
|
||||
|
||||
activity.onCreate(icicle);
|
||||
activity.performCreate(icicle);
|
||||
|
||||
if (mActivityMonitors != null) {
|
||||
synchronized (mSync) {
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
}
|
||||
|
Reference in New Issue
Block a user