Merge branch 'readonly-p4-donut' into donut

This commit is contained in:
Mitsuru Oshima
2009-04-28 18:13:25 -07:00
committed by The Android Open Source Project
12 changed files with 324 additions and 50 deletions

View File

@ -161,7 +161,7 @@ public final class ActivityThread {
return metrics; return metrics;
} }
Resources getTopLevelResources(String appDir) { Resources getTopLevelResources(String appDir, float applicationScale) {
synchronized (mPackages) { synchronized (mPackages) {
//Log.w(TAG, "getTopLevelResources: " + appDir); //Log.w(TAG, "getTopLevelResources: " + appDir);
WeakReference<Resources> wr = mActiveResources.get(appDir); WeakReference<Resources> wr = mActiveResources.get(appDir);
@ -181,7 +181,27 @@ public final class ActivityThread {
return null; return null;
} }
DisplayMetrics metrics = getDisplayMetricsLocked(false); DisplayMetrics metrics = getDisplayMetricsLocked(false);
r = new Resources(assets, metrics, getConfiguration()); // density used to load resources
// scaledDensity is calculated in Resources constructor
//
boolean usePreloaded = true;
// TODO: use explicit flag to indicate the compatibility mode.
if (applicationScale != 1.0f) {
usePreloaded = false;
DisplayMetrics newMetrics = new DisplayMetrics();
newMetrics.setTo(metrics);
float invertedScale = 1.0f / applicationScale;
newMetrics.density *= invertedScale;
newMetrics.xdpi *= invertedScale;
newMetrics.ydpi *= invertedScale;
newMetrics.widthPixels *= invertedScale;
newMetrics.heightPixels *= invertedScale;
metrics = newMetrics;
}
//Log.i(TAG, "Resource:" + appDir + ", density " + newMetrics.density + ", orig density:" +
// metrics.density);
r = new Resources(assets, metrics, getConfiguration(), usePreloaded);
//Log.i(TAG, "Created app resources " + r + ": " + r.getConfiguration()); //Log.i(TAG, "Created app resources " + r + ": " + r.getConfiguration());
// XXX need to remove entries when weak references go away // XXX need to remove entries when weak references go away
mActiveResources.put(appDir, new WeakReference<Resources>(r)); mActiveResources.put(appDir, new WeakReference<Resources>(r));
@ -209,6 +229,8 @@ public final class ActivityThread {
private Resources mResources; private Resources mResources;
private ClassLoader mClassLoader; private ClassLoader mClassLoader;
private Application mApplication; private Application mApplication;
private float mApplicationScale;
private final HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers private final HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
= new HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>>(); = new HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>>();
private final HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>> mUnregisteredReceivers private final HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>> mUnregisteredReceivers
@ -241,8 +263,8 @@ public final class ActivityThread {
mSystemContext = mSystemContext =
ApplicationContext.createSystemContext(mainThread); ApplicationContext.createSystemContext(mainThread);
mSystemContext.getResources().updateConfiguration( mSystemContext.getResources().updateConfiguration(
mainThread.getConfiguration(), mainThread.getConfiguration(),
mainThread.getDisplayMetricsLocked(false)); mainThread.getDisplayMetricsLocked(false));
//Log.i(TAG, "Created system resources " //Log.i(TAG, "Created system resources "
// + mSystemContext.getResources() + ": " // + mSystemContext.getResources() + ": "
// + mSystemContext.getResources().getConfiguration()); // + mSystemContext.getResources().getConfiguration());
@ -250,6 +272,8 @@ public final class ActivityThread {
mClassLoader = mSystemContext.getClassLoader(); mClassLoader = mSystemContext.getClassLoader();
mResources = mSystemContext.getResources(); mResources = mSystemContext.getResources();
} }
mApplicationScale = -1.0f;
} }
public PackageInfo(ActivityThread activityThread, String name, public PackageInfo(ActivityThread activityThread, String name,
@ -268,6 +292,7 @@ public final class ActivityThread {
mIncludeCode = true; mIncludeCode = true;
mClassLoader = systemContext.getClassLoader(); mClassLoader = systemContext.getClassLoader();
mResources = systemContext.getResources(); mResources = systemContext.getResources();
mApplicationScale = systemContext.getApplicationScale();
} }
public String getPackageName() { public String getPackageName() {
@ -278,6 +303,47 @@ public final class ActivityThread {
return mSecurityViolation; return mSecurityViolation;
} }
public float getApplicationScale() {
if (mApplicationScale > 0.0f) {
return mApplicationScale;
}
DisplayMetrics metrics = mActivityThread.getDisplayMetricsLocked(false);
// Find out the density scale (relative to 160) of the supported density that
// is closest to the system's density.
try {
ApplicationInfo ai = getPackageManager().getApplicationInfo(
mPackageName, PackageManager.GET_SUPPORTS_DENSITIES);
float appScale = -1.0f;
if (ai.supportsDensities != null) {
// TODO: precompute this in DisplayMetrics
float systemDensityDpi = metrics.density * DisplayMetrics.DEFAULT_DENSITY;
int minDiff = Integer.MAX_VALUE;
for (int density : ai.supportsDensities) {
int tmpDiff = (int) Math.abs(systemDensityDpi - density);
if (tmpDiff == 0) {
appScale = 1.0f;
break;
}
// prefer higher density (appScale>1.0), unless that's only option.
if (tmpDiff < minDiff && appScale < 1.0f) {
appScale = systemDensityDpi / density;
minDiff = tmpDiff;
}
}
}
if (appScale < 0.0f) {
mApplicationScale = metrics.density;
} else {
mApplicationScale = appScale;
}
} catch (RemoteException e) {
throw new AssertionError(e);
}
if (localLOGV) Log.v(TAG, "appScale=" + mApplicationScale + ", pkg=" + mPackageName);
return mApplicationScale;
}
/** /**
* Gets the array of shared libraries that are listed as * Gets the array of shared libraries that are listed as
* used by the given package. * used by the given package.
@ -435,7 +501,7 @@ public final class ActivityThread {
public Resources getResources(ActivityThread mainThread) { public Resources getResources(ActivityThread mainThread) {
if (mResources == null) { if (mResources == null) {
mResources = mainThread.getTopLevelResources(mResDir); mResources = mainThread.getTopLevelResources(mResDir, getApplicationScale());
} }
return mResources; return mResources;
} }

View File

@ -550,6 +550,19 @@ class ApplicationContext extends Context {
} }
} }
/**
* @hide
*/
@Override
public float getApplicationScale() {
if (mPackageInfo != null) {
return mPackageInfo.getApplicationScale();
} else {
// same as system density
return 1.0f;
}
}
@Override @Override
public void setWallpaper(Bitmap bitmap) throws IOException { public void setWallpaper(Bitmap bitmap) throws IOException {
try { try {
@ -2008,9 +2021,11 @@ class ApplicationContext extends Context {
if (app.packageName.equals("system")) { if (app.packageName.equals("system")) {
return mContext.mMainThread.getSystemContext().getResources(); return mContext.mMainThread.getSystemContext().getResources();
} }
ActivityThread.PackageInfo pi = mContext.mMainThread.getPackageInfoNoCheck(app);
Resources r = mContext.mMainThread.getTopLevelResources( Resources r = mContext.mMainThread.getTopLevelResources(
app.uid == Process.myUid() ? app.sourceDir app.uid == Process.myUid() ? app.sourceDir
: app.publicSourceDir); : app.publicSourceDir,
pi.getApplicationScale());
if (r != null) { if (r != null) {
return r; return r;
} }

View File

@ -526,6 +526,16 @@ public abstract class Context {
*/ */
public abstract int getWallpaperDesiredMinimumHeight(); public abstract int getWallpaperDesiredMinimumHeight();
/**
* Returns the scale in which the application will be drawn on the
* screen. This is usually 1.0f if the application supports the device's
* resolution/density. This will be 1.5f, for example, if the application
* that supports only 160 density runs on 240 density screen.
*
* @hide
*/
public abstract float getApplicationScale();
/** /**
* Change the current system wallpaper to a bitmap. The given bitmap is * Change the current system wallpaper to a bitmap. The given bitmap is
* converted to a PNG and stored as the wallpaper. On success, the intent * converted to a PNG and stored as the wallpaper. On success, the intent

View File

@ -419,4 +419,12 @@ public class ContextWrapper extends Context {
throws PackageManager.NameNotFoundException { throws PackageManager.NameNotFoundException {
return mBase.createPackageContext(packageName, flags); return mBase.createPackageContext(packageName, flags);
} }
/**
* @hide
*/
@Override
public float getApplicationScale() {
return mBase.getApplicationScale();
}
} }

View File

@ -24,6 +24,7 @@ import org.xmlpull.v1.XmlPullParserException;
import android.graphics.Movie; import android.graphics.Movie;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.os.SystemProperties; import android.os.SystemProperties;
@ -56,12 +57,14 @@ public class Resources {
// Information about preloaded resources. Note that they are not // Information about preloaded resources. Note that they are not
// protected by a lock, because while preloading in zygote we are all // protected by a lock, because while preloading in zygote we are all
// single-threaded, and after that these are immutable. // single-threaded, and after that these are immutable.
private static final SparseArray<Drawable.ConstantState> mPreloadedDrawables private static final SparseArray<Drawable.ConstantState> sPreloadedDrawables
= new SparseArray<Drawable.ConstantState>(); = new SparseArray<Drawable.ConstantState>();
private static final SparseArray<ColorStateList> mPreloadedColorStateLists private static final SparseArray<ColorStateList> mPreloadedColorStateLists
= new SparseArray<ColorStateList>(); = new SparseArray<ColorStateList>();
private static boolean mPreloaded; private static boolean mPreloaded;
private final SparseArray<Drawable.ConstantState> mPreloadedDrawables;
/*package*/ final TypedValue mTmpValue = new TypedValue(); /*package*/ final TypedValue mTmpValue = new TypedValue();
// These are protected by the mTmpValue lock. // These are protected by the mTmpValue lock.
@ -82,6 +85,22 @@ public class Resources {
/*package*/ final DisplayMetrics mMetrics = new DisplayMetrics(); /*package*/ final DisplayMetrics mMetrics = new DisplayMetrics();
PluralRules mPluralRule; PluralRules mPluralRule;
private static final SparseArray<Object> EMPTY_ARRAY = new SparseArray<Object>() {
@Override
public void put(int k, Object o) {
throw new UnsupportedOperationException();
}
@Override
public void append(int k, Object o) {
throw new UnsupportedOperationException();
}
};
@SuppressWarnings("unchecked")
private static <T> SparseArray<T> emptySparseArray() {
return (SparseArray<T>) EMPTY_ARRAY;
}
/** /**
* This exception is thrown by the resource APIs when a requested resource * This exception is thrown by the resource APIs when a requested resource
* can not be found. * can not be found.
@ -107,11 +126,27 @@ public class Resources {
*/ */
public Resources(AssetManager assets, DisplayMetrics metrics, public Resources(AssetManager assets, DisplayMetrics metrics,
Configuration config) { Configuration config) {
this(assets, metrics, config, true);
}
/**
* Create a resource with an additional flag for preloaded
* drawable cache. Used by {@link ActivityThread}.
*
* @hide
*/
public Resources(AssetManager assets, DisplayMetrics metrics,
Configuration config, boolean usePreloadedCache) {
mAssets = assets; mAssets = assets;
mConfiguration.setToDefaults(); mConfiguration.setToDefaults();
mMetrics.setToDefaults(); mMetrics.setToDefaults();
updateConfiguration(config, metrics); updateConfiguration(config, metrics);
assets.ensureStringBlocks(); assets.ensureStringBlocks();
if (usePreloadedCache) {
mPreloadedDrawables = sPreloadedDrawables;
} else {
mPreloadedDrawables = emptySparseArray();
}
} }
/** /**
@ -1218,6 +1253,7 @@ public class Resources {
mMetrics.setTo(metrics); mMetrics.setTo(metrics);
} }
mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale; mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
String locale = null; String locale = null;
if (mConfiguration.locale != null) { if (mConfiguration.locale != null) {
locale = mConfiguration.locale.getLanguage(); locale = mConfiguration.locale.getLanguage();
@ -1653,7 +1689,7 @@ public class Resources {
cs = dr.getConstantState(); cs = dr.getConstantState();
if (cs != null) { if (cs != null) {
if (mPreloading) { if (mPreloading) {
mPreloadedDrawables.put(key, cs); sPreloadedDrawables.put(key, cs);
} else { } else {
synchronized (mTmpValue) { synchronized (mTmpValue) {
//Log.i(TAG, "Saving cached drawable @ #" + //Log.i(TAG, "Saving cached drawable @ #" +
@ -1883,6 +1919,6 @@ public class Resources {
mMetrics.setToDefaults(); mMetrics.setToDefaults();
updateConfiguration(null, null); updateConfiguration(null, null);
mAssets.ensureStringBlocks(); mAssets.ensureStringBlocks();
mPreloadedDrawables = sPreloadedDrawables;
} }
} }

View File

@ -102,7 +102,7 @@ public final class MotionEvent implements Parcelable {
private float mYPrecision; private float mYPrecision;
private int mDeviceId; private int mDeviceId;
private int mEdgeFlags; private int mEdgeFlags;
private MotionEvent mNext; private MotionEvent mNext;
private RuntimeException mRecycledLocation; private RuntimeException mRecycledLocation;
private boolean mRecycled; private boolean mRecycled;
@ -210,7 +210,29 @@ public final class MotionEvent implements Parcelable {
return ev; return ev;
} }
/**
* Scales down the cood of this event by the given scale.
*
* @hide
*/
public void scale(float scale) {
if (scale != 1.0f) {
mX *= scale;
mY *= scale;
mRawX *= scale;
mRawY *= scale;
mSize *= scale;
mXPrecision *= scale;
mYPrecision *= scale;
float[] history = mHistory;
int length = history.length;
for (int i = 0; i < length; i++) {
history[i] *= scale;
}
}
}
/** /**
* Create a new MotionEvent, copying from an existing one. * Create a new MotionEvent, copying from an existing one.
*/ */
@ -682,4 +704,3 @@ public final class MotionEvent implements Parcelable {
} }
} }

View File

@ -135,20 +135,28 @@ public class SurfaceView extends View {
int mFormat = -1; int mFormat = -1;
int mType = -1; int mType = -1;
final Rect mSurfaceFrame = new Rect(); final Rect mSurfaceFrame = new Rect();
private final float mAppScale;
private final float mAppScaleInverted;
public SurfaceView(Context context) { public SurfaceView(Context context) {
super(context); super(context);
setWillNotDraw(true); setWillNotDraw(true);
mAppScale = context.getApplicationScale();
mAppScaleInverted = 1.0f / mAppScale;
} }
public SurfaceView(Context context, AttributeSet attrs) { public SurfaceView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
setWillNotDraw(true); setWillNotDraw(true);
mAppScale = context.getApplicationScale();
mAppScaleInverted = 1.0f / mAppScale;
} }
public SurfaceView(Context context, AttributeSet attrs, int defStyle) { public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle); super(context, attrs, defStyle);
setWillNotDraw(true); setWillNotDraw(true);
mAppScale = context.getApplicationScale();
mAppScaleInverted = 1.0f / mAppScale;
} }
/** /**
@ -297,8 +305,8 @@ public class SurfaceView extends View {
mLayout.x = mLeft; mLayout.x = mLeft;
mLayout.y = mTop; mLayout.y = mTop;
mLayout.width = getWidth(); mLayout.width = (int) (getWidth() * mAppScale);
mLayout.height = getHeight(); mLayout.height = (int) (getHeight() * mAppScale);
mLayout.format = mRequestedFormat; mLayout.format = mRequestedFormat;
mLayout.flags |=WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS mLayout.flags |=WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_SCALED | WindowManager.LayoutParams.FLAG_SCALED
@ -325,9 +333,14 @@ public class SurfaceView extends View {
mSurfaceLock.lock(); mSurfaceLock.lock();
mDrawingStopped = !visible; mDrawingStopped = !visible;
final int relayoutResult = mSession.relayout( final int relayoutResult = mSession.relayout(
mWindow, mLayout, mWidth, mHeight, mWindow, mLayout, (int) (mWidth * mAppScale), (int) (mHeight * mAppScale),
visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets, visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
mVisibleInsets, mSurface); mVisibleInsets, mSurface);
mContentInsets.scale(mAppScaleInverted);
mVisibleInsets.scale(mAppScaleInverted);
mWinFrame.scale(mAppScaleInverted);
if (localLOGV) Log.i(TAG, "New surface: " + mSurface if (localLOGV) Log.i(TAG, "New surface: " + mSurface
+ ", vis=" + visible + ", frame=" + mWinFrame); + ", vis=" + visible + ", frame=" + mWinFrame);
mSurfaceFrame.left = 0; mSurfaceFrame.left = 0;
@ -395,15 +408,25 @@ public class SurfaceView extends View {
} }
private static class MyWindow extends IWindow.Stub { private static class MyWindow extends IWindow.Stub {
private WeakReference<SurfaceView> mSurfaceView; private final WeakReference<SurfaceView> mSurfaceView;
private final float mAppScale;
private final float mAppScaleInverted;
public MyWindow(SurfaceView surfaceView) { public MyWindow(SurfaceView surfaceView) {
mSurfaceView = new WeakReference<SurfaceView>(surfaceView); mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
mAppScale = surfaceView.getContext().getApplicationScale();
mAppScaleInverted = 1.0f / mAppScale;
} }
public void resized(int w, int h, Rect coveredInsets, public void resized(int w, int h, Rect coveredInsets,
Rect visibleInsets, boolean reportDraw) { Rect visibleInsets, boolean reportDraw) {
SurfaceView surfaceView = mSurfaceView.get(); SurfaceView surfaceView = mSurfaceView.get();
float scale = mAppScaleInverted;
w *= scale;
h *= scale;
coveredInsets.scale(scale);
visibleInsets.scale(scale);
if (surfaceView != null) { if (surfaceView != null) {
if (localLOGV) Log.v( if (localLOGV) Log.v(
"SurfaceView", surfaceView + " got resized: w=" + "SurfaceView", surfaceView + " got resized: w=" +
@ -566,6 +589,7 @@ public class SurfaceView extends View {
Canvas c = null; Canvas c = null;
if (!mDrawingStopped && mWindow != null) { if (!mDrawingStopped && mWindow != null) {
Rect frame = dirty != null ? dirty : mSurfaceFrame; Rect frame = dirty != null ? dirty : mSurfaceFrame;
frame.scale(mAppScale);
try { try {
c = mSurface.lockCanvas(frame); c = mSurface.lockCanvas(frame);
} catch (Exception e) { } catch (Exception e) {
@ -611,4 +635,3 @@ public class SurfaceView extends View {
} }
}; };
} }

View File

@ -128,6 +128,9 @@ public final class ViewRoot extends Handler implements ViewParent,
int mHeight; int mHeight;
Rect mDirty; // will be a graphics.Region soon Rect mDirty; // will be a graphics.Region soon
boolean mIsAnimating; boolean mIsAnimating;
// TODO: change these to scaler class.
float mAppScale;
float mAppScaleInverted; // = 1.0f / mAppScale
final View.AttachInfo mAttachInfo; final View.AttachInfo mAttachInfo;
@ -384,10 +387,12 @@ public final class ViewRoot extends Handler implements ViewParent,
View panelParentView) { View panelParentView) {
synchronized (this) { synchronized (this) {
if (mView == null) { if (mView == null) {
mView = view;
mAppScale = mView.getContext().getApplicationScale();
mAppScaleInverted = 1.0f / mAppScale;
mWindowAttributes.copyFrom(attrs); mWindowAttributes.copyFrom(attrs);
mSoftInputMode = attrs.softInputMode; mSoftInputMode = attrs.softInputMode;
mWindowAttributesChanged = true; mWindowAttributesChanged = true;
mView = view;
mAttachInfo.mRootView = view; mAttachInfo.mRootView = view;
if (panelParentView != null) { if (panelParentView != null) {
mAttachInfo.mPanelParentWindowToken mAttachInfo.mPanelParentWindowToken
@ -400,7 +405,7 @@ public final class ViewRoot extends Handler implements ViewParent,
// manager, to make sure we do the relayout before receiving // manager, to make sure we do the relayout before receiving
// any other events from the system. // any other events from the system.
requestLayout(); requestLayout();
try { try {
res = sWindowSession.add(mWindow, attrs, res = sWindowSession.add(mWindow, attrs,
getHostVisibility(), mAttachInfo.mContentInsets); getHostVisibility(), mAttachInfo.mContentInsets);
@ -411,6 +416,7 @@ public final class ViewRoot extends Handler implements ViewParent,
unscheduleTraversals(); unscheduleTraversals();
throw new RuntimeException("Adding window failed", e); throw new RuntimeException("Adding window failed", e);
} }
mAttachInfo.mContentInsets.scale(mAppScaleInverted);
mPendingContentInsets.set(mAttachInfo.mContentInsets); mPendingContentInsets.set(mAttachInfo.mContentInsets);
mPendingVisibleInsets.set(0, 0, 0, 0); mPendingVisibleInsets.set(0, 0, 0, 0);
if (Config.LOGV) Log.v("ViewRoot", "Added window " + mWindow); if (Config.LOGV) Log.v("ViewRoot", "Added window " + mWindow);
@ -472,6 +478,8 @@ public final class ViewRoot extends Handler implements ViewParent,
synchronized (this) { synchronized (this) {
int oldSoftInputMode = mWindowAttributes.softInputMode; int oldSoftInputMode = mWindowAttributes.softInputMode;
mWindowAttributes.copyFrom(attrs); mWindowAttributes.copyFrom(attrs);
mWindowAttributes.scale(mAppScale);
if (newView) { if (newView) {
mSoftInputMode = attrs.softInputMode; mSoftInputMode = attrs.softInputMode;
requestLayout(); requestLayout();
@ -521,9 +529,14 @@ public final class ViewRoot extends Handler implements ViewParent,
public void invalidateChild(View child, Rect dirty) { public void invalidateChild(View child, Rect dirty) {
checkThread(); checkThread();
if (LOCAL_LOGV) Log.v(TAG, "Invalidate child: " + dirty); if (LOCAL_LOGV) Log.v(TAG, "Invalidate child: " + dirty);
if (mCurScrollY != 0) { if (mCurScrollY != 0 || mAppScale != 1.0f) {
mTempRect.set(dirty); mTempRect.set(dirty);
mTempRect.offset(0, -mCurScrollY); if (mCurScrollY != 0) {
mTempRect.offset(0, -mCurScrollY);
}
if (mAppScale != 1.0f) {
mTempRect.scale(mAppScale);
}
dirty = mTempRect; dirty = mTempRect;
} }
mDirty.union(dirty); mDirty.union(dirty);
@ -613,8 +626,8 @@ public final class ViewRoot extends Handler implements ViewParent,
mLayoutRequested = true; mLayoutRequested = true;
Display d = new Display(0); Display d = new Display(0);
desiredWindowWidth = d.getWidth(); desiredWindowWidth = (int) (d.getWidth() * mAppScaleInverted);
desiredWindowHeight = d.getHeight(); desiredWindowHeight = (int) (d.getHeight() * mAppScaleInverted);
// For the very first time, tell the view hierarchy that it // For the very first time, tell the view hierarchy that it
// is attached to the window. Note that at this point the surface // is attached to the window. Note that at this point the surface
@ -683,8 +696,8 @@ public final class ViewRoot extends Handler implements ViewParent,
windowResizesToFitContent = true; windowResizesToFitContent = true;
Display d = new Display(0); Display d = new Display(0);
desiredWindowWidth = d.getWidth(); desiredWindowWidth = (int) (d.getWidth() * mAppScaleInverted);
desiredWindowHeight = d.getHeight(); desiredWindowHeight = (int) (d.getHeight() * mAppScaleInverted);
} }
} }
@ -792,10 +805,12 @@ public final class ViewRoot extends Handler implements ViewParent,
params.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; params.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
} }
} }
relayoutResult = sWindowSession.relayout( if (DEBUG_LAYOUT) {
mWindow, params, host.mMeasuredWidth, host.mMeasuredHeight, Log.i(TAG, "host=w:" + host.mMeasuredWidth + ", h:" +
viewVisibility, insetsPending, frame, host.mMeasuredHeight + ", params=" + params);
mPendingContentInsets, mPendingVisibleInsets, mSurface); }
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
if (params != null) { if (params != null) {
params.flags = fl; params.flags = fl;
} }
@ -862,7 +877,7 @@ public final class ViewRoot extends Handler implements ViewParent,
mHeight = frame.height(); mHeight = frame.height();
if (initialized) { if (initialized) {
mGlCanvas.setViewport(mWidth, mHeight); mGlCanvas.setViewport((int) (mWidth * mAppScale), (int) (mHeight * mAppScale));
} }
boolean focusChangedDueToTouchMode = ensureTouchModeLocally( boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
@ -944,6 +959,11 @@ public final class ViewRoot extends Handler implements ViewParent,
mTmpLocation[1] + host.mBottom - host.mTop); mTmpLocation[1] + host.mBottom - host.mTop);
host.gatherTransparentRegion(mTransparentRegion); host.gatherTransparentRegion(mTransparentRegion);
// TODO: scale the region, like:
// Region uses native methods. We probabl should have ScalableRegion class.
// Region does not have equals method ?
if (!mTransparentRegion.equals(mPreviousTransparentRegion)) { if (!mTransparentRegion.equals(mPreviousTransparentRegion)) {
mPreviousTransparentRegion.set(mTransparentRegion); mPreviousTransparentRegion.set(mTransparentRegion);
// reconfigure window manager // reconfigure window manager
@ -974,6 +994,9 @@ public final class ViewRoot extends Handler implements ViewParent,
givenContent.left = givenContent.top = givenContent.right givenContent.left = givenContent.top = givenContent.right
= givenContent.bottom = givenVisible.left = givenVisible.top = givenContent.bottom = givenVisible.left = givenVisible.top
= givenVisible.right = givenVisible.bottom = 0; = givenVisible.right = givenVisible.bottom = 0;
insets.contentInsets.scale(mAppScale);
insets.visibleInsets.scale(mAppScale);
attachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets); attachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets);
if (insetsPending || !mLastGivenInsets.equals(insets)) { if (insetsPending || !mLastGivenInsets.equals(insets)) {
mLastGivenInsets.set(insets); mLastGivenInsets.set(insets);
@ -1113,7 +1136,7 @@ public final class ViewRoot extends Handler implements ViewParent,
int yoff; int yoff;
final boolean scrolling = mScroller != null final boolean scrolling = mScroller != null
&& mScroller.computeScrollOffset(); && mScroller.computeScrollOffset();
if (scrolling) { if (scrolling) {
yoff = mScroller.getCurrY(); yoff = mScroller.getCurrY();
} else { } else {
@ -1135,10 +1158,19 @@ public final class ViewRoot extends Handler implements ViewParent,
mGL.glEnable(GL_SCISSOR_TEST); mGL.glEnable(GL_SCISSOR_TEST);
mAttachInfo.mDrawingTime = SystemClock.uptimeMillis(); mAttachInfo.mDrawingTime = SystemClock.uptimeMillis();
canvas.translate(0, -yoff);
mView.mPrivateFlags |= View.DRAWN; mView.mPrivateFlags |= View.DRAWN;
mView.draw(canvas);
canvas.translate(0, yoff); float scale = mAppScale;
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
try {
canvas.translate(0, -yoff);
if (scale != 1.0f) {
canvas.scale(scale, scale);
}
mView.draw(canvas);
} finally {
canvas.restoreToCount(saveCount);
}
mEgl.eglSwapBuffers(mEglDisplay, mEglSurface); mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
checkEglErrors(); checkEglErrors();
@ -1160,7 +1192,7 @@ public final class ViewRoot extends Handler implements ViewParent,
} }
if (fullRedrawNeeded) if (fullRedrawNeeded)
dirty.union(0, 0, mWidth, mHeight); dirty.union(0, 0, (int) (mWidth * mAppScale), (int) (mHeight * mAppScale));
if (DEBUG_ORIENTATION || DEBUG_DRAW) { if (DEBUG_ORIENTATION || DEBUG_DRAW) {
Log.v("ViewRoot", "Draw " + mView + "/" Log.v("ViewRoot", "Draw " + mView + "/"
@ -1212,10 +1244,24 @@ public final class ViewRoot extends Handler implements ViewParent,
dirty.setEmpty(); dirty.setEmpty();
mIsAnimating = false; mIsAnimating = false;
mAttachInfo.mDrawingTime = SystemClock.uptimeMillis(); mAttachInfo.mDrawingTime = SystemClock.uptimeMillis();
canvas.translate(0, -yoff); mView.mPrivateFlags |= View.DRAWN;
mView.mPrivateFlags |= View.DRAWN;
mView.draw(canvas); float scale = mAppScale;
canvas.translate(0, yoff); Context cxt = mView.getContext();
if (DEBUG_DRAW) {
Log.i(TAG, "Drawing: package:" + cxt.getPackageName() + ", appScale=" + mAppScale);
}
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
try {
canvas.translate(0, -yoff);
if (scale != 1.0f) {
// re-scale this
canvas.scale(scale, scale);
}
mView.draw(canvas);
} finally {
canvas.restoreToCount(saveCount);
}
if (SHOW_FPS) { if (SHOW_FPS) {
int now = (int)SystemClock.elapsedRealtime(); int now = (int)SystemClock.elapsedRealtime();
@ -1508,6 +1554,9 @@ public final class ViewRoot extends Handler implements ViewParent,
} else { } else {
didFinish = event.getAction() == MotionEvent.ACTION_OUTSIDE; didFinish = event.getAction() == MotionEvent.ACTION_OUTSIDE;
} }
if (event != null) {
event.scale(mAppScaleInverted);
}
try { try {
boolean handled; boolean handled;
@ -1628,7 +1677,8 @@ public final class ViewRoot extends Handler implements ViewParent,
if (mGlWanted && !mUseGL) { if (mGlWanted && !mUseGL) {
initializeGL(); initializeGL();
if (mGlCanvas != null) { if (mGlCanvas != null) {
mGlCanvas.setViewport(mWidth, mHeight); mGlCanvas.setViewport((int) (mWidth * mAppScale),
(int) (mHeight * mAppScale));
} }
} }
} }
@ -1828,6 +1878,9 @@ public final class ViewRoot extends Handler implements ViewParent,
} else { } else {
didFinish = false; didFinish = false;
} }
if (event != null) {
event.scale(mAppScaleInverted);
}
if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event); if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event);
@ -2254,6 +2307,20 @@ public final class ViewRoot extends Handler implements ViewParent,
return mAudioManager; return mAudioManager;
} }
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
int relayoutResult = sWindowSession.relayout(
mWindow, params,
(int) (mView.mMeasuredWidth * mAppScale),
(int) (mView.mMeasuredHeight * mAppScale),
viewVisibility, insetsPending, mWinFrame,
mPendingContentInsets, mPendingVisibleInsets, mSurface);
mPendingContentInsets.scale(mAppScaleInverted);
mPendingVisibleInsets.scale(mAppScaleInverted);
mWinFrame.scale(mAppScaleInverted);
return relayoutResult;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -2322,12 +2389,8 @@ public final class ViewRoot extends Handler implements ViewParent,
// to the window manager to make sure it has the correct // to the window manager to make sure it has the correct
// animation info. // animation info.
try { try {
if ((sWindowSession.relayout( if ((relayoutWindow(mWindowAttributes, viewVisibility, false)
mWindow, mWindowAttributes, & WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
mView.mMeasuredWidth, mView.mMeasuredHeight,
viewVisibility, false, mWinFrame, mPendingContentInsets,
mPendingVisibleInsets, mSurface)
&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
sWindowSession.finishDrawing(mWindow); sWindowSession.finishDrawing(mWindow);
} }
} catch (RemoteException e) { } catch (RemoteException e) {
@ -2361,8 +2424,11 @@ public final class ViewRoot extends Handler implements ViewParent,
+ " visibleInsets=" + visibleInsets.toShortString() + " visibleInsets=" + visibleInsets.toShortString()
+ " reportDraw=" + reportDraw); + " reportDraw=" + reportDraw);
Message msg = obtainMessage(reportDraw ? RESIZED_REPORT :RESIZED); Message msg = obtainMessage(reportDraw ? RESIZED_REPORT :RESIZED);
msg.arg1 = w;
msg.arg2 = h; coveredInsets.scale(mAppScaleInverted);
visibleInsets.scale(mAppScaleInverted);
msg.arg1 = (int) (w * mAppScaleInverted);
msg.arg2 = (int) (h * mAppScaleInverted);
msg.obj = new Rect[] { new Rect(coveredInsets), new Rect(visibleInsets) }; msg.obj = new Rect[] { new Rect(coveredInsets), new Rect(visibleInsets) };
sendMessage(msg); sendMessage(msg);
} }
@ -2493,7 +2559,7 @@ public final class ViewRoot extends Handler implements ViewParent,
sWindowSession.finishKey(mWindow); sWindowSession.finishKey(mWindow);
} catch (RemoteException e) { } catch (RemoteException e) {
} }
} else if (mIsPointer) { } else if (mIsPointer) {
boolean didFinish; boolean didFinish;
MotionEvent event = mMotionEvent; MotionEvent event = mMotionEvent;
if (event == null) { if (event == null) {

View File

@ -954,7 +954,7 @@ public interface WindowManager extends ViewManager {
return sb.toString(); return sb.toString();
} }
void scaleUp(float scale) { void scale(float scale) {
if (scale != 1.0f) { if (scale != 1.0f) {
x *= scale; x *= scale;
y *= scale; y *= scale;

View File

@ -545,4 +545,17 @@ public final class Rect implements Parcelable {
right = in.readInt(); right = in.readInt();
bottom = in.readInt(); bottom = in.readInt();
} }
/**
* Scales up the rect by the given scale.
* @hide
*/
public void scale(float scale) {
if (scale != 1.0f) {
left *= scale;
top *= scale;
right *= scale;
bottom*= scale;
}
}
} }

View File

@ -386,4 +386,12 @@ public class MockContext extends Context {
throws PackageManager.NameNotFoundException { throws PackageManager.NameNotFoundException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/**
* @hide
*/
@Override
public float getApplicationScale() {
throw new UnsupportedOperationException();
}
} }

View File

@ -1145,4 +1145,12 @@ public final class BridgeContext extends Context {
public Context getApplicationContext() { public Context getApplicationContext() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/**
* @hide
*/
@Override
public float getApplicationScale() {
throw new UnsupportedOperationException();
}
} }