diff options
author | Mitsuru Oshima <> | 2009-04-29 13:35:38 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-04-29 13:35:38 -0700 |
commit | c2839e087041b16a1ee7292b85459a396c25c771 (patch) | |
tree | 667f11899be570bcc3e825ee6d3c63c033f5a02b | |
parent | c36349034a399e41e5a78861d03dfe2a40e294fe (diff) | |
parent | 13735a255dedd2c2e3b0cff66f0be2e17671f553 (diff) | |
download | frameworks_base-c2839e087041b16a1ee7292b85459a396c25c771.zip frameworks_base-c2839e087041b16a1ee7292b85459a396c25c771.tar.gz frameworks_base-c2839e087041b16a1ee7292b85459a396c25c771.tar.bz2 |
am 13735a2: Merge branch \'readonly-p4-donut\' into donut
Merge commit '13735a255dedd2c2e3b0cff66f0be2e17671f553'
* commit '13735a255dedd2c2e3b0cff66f0be2e17671f553':
AI 147976: Compatibility mode support. Part 2.
-rw-r--r-- | core/java/android/app/ActivityThread.java | 76 | ||||
-rw-r--r-- | core/java/android/app/ApplicationContext.java | 17 | ||||
-rw-r--r-- | core/java/android/content/Context.java | 10 | ||||
-rw-r--r-- | core/java/android/content/ContextWrapper.java | 8 | ||||
-rw-r--r-- | core/java/android/content/res/Resources.java | 42 | ||||
-rw-r--r-- | core/java/android/view/MotionEvent.java | 27 | ||||
-rw-r--r-- | core/java/android/view/SurfaceView.java | 33 | ||||
-rw-r--r-- | core/java/android/view/ViewRoot.java | 130 | ||||
-rw-r--r-- | core/java/android/view/WindowManager.java | 2 | ||||
-rw-r--r-- | graphics/java/android/graphics/Rect.java | 13 | ||||
-rw-r--r-- | test-runner/android/test/mock/MockContext.java | 8 | ||||
-rw-r--r-- | tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java | 8 |
12 files changed, 324 insertions, 50 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 3bd76a6..dfa3fa8 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -161,7 +161,7 @@ public final class ActivityThread { return metrics; } - Resources getTopLevelResources(String appDir) { + Resources getTopLevelResources(String appDir, float applicationScale) { synchronized (mPackages) { //Log.w(TAG, "getTopLevelResources: " + appDir); WeakReference<Resources> wr = mActiveResources.get(appDir); @@ -181,7 +181,27 @@ public final class ActivityThread { return null; } 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()); // XXX need to remove entries when weak references go away mActiveResources.put(appDir, new WeakReference<Resources>(r)); @@ -209,6 +229,8 @@ public final class ActivityThread { private Resources mResources; private ClassLoader mClassLoader; private Application mApplication; + private float mApplicationScale; + private final HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers = new HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>>(); private final HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>> mUnregisteredReceivers @@ -241,8 +263,8 @@ public final class ActivityThread { mSystemContext = ApplicationContext.createSystemContext(mainThread); mSystemContext.getResources().updateConfiguration( - mainThread.getConfiguration(), - mainThread.getDisplayMetricsLocked(false)); + mainThread.getConfiguration(), + mainThread.getDisplayMetricsLocked(false)); //Log.i(TAG, "Created system resources " // + mSystemContext.getResources() + ": " // + mSystemContext.getResources().getConfiguration()); @@ -250,6 +272,8 @@ public final class ActivityThread { mClassLoader = mSystemContext.getClassLoader(); mResources = mSystemContext.getResources(); } + + mApplicationScale = -1.0f; } public PackageInfo(ActivityThread activityThread, String name, @@ -268,6 +292,7 @@ public final class ActivityThread { mIncludeCode = true; mClassLoader = systemContext.getClassLoader(); mResources = systemContext.getResources(); + mApplicationScale = systemContext.getApplicationScale(); } public String getPackageName() { @@ -278,6 +303,47 @@ public final class ActivityThread { 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 * used by the given package. @@ -435,7 +501,7 @@ public final class ActivityThread { public Resources getResources(ActivityThread mainThread) { if (mResources == null) { - mResources = mainThread.getTopLevelResources(mResDir); + mResources = mainThread.getTopLevelResources(mResDir, getApplicationScale()); } return mResources; } diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java index 94f3373..72d9e3d 100644 --- a/core/java/android/app/ApplicationContext.java +++ b/core/java/android/app/ApplicationContext.java @@ -553,6 +553,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 public void setWallpaper(Bitmap bitmap) throws IOException { try { @@ -2024,9 +2037,11 @@ class ApplicationContext extends Context { if (app.packageName.equals("system")) { return mContext.mMainThread.getSystemContext().getResources(); } + ActivityThread.PackageInfo pi = mContext.mMainThread.getPackageInfoNoCheck(app); Resources r = mContext.mMainThread.getTopLevelResources( app.uid == Process.myUid() ? app.sourceDir - : app.publicSourceDir); + : app.publicSourceDir, + pi.getApplicationScale()); if (r != null) { return r; } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 3d5ed3a..e8daa6e 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -527,6 +527,16 @@ public abstract class Context { 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 * converted to a PNG and stored as the wallpaper. On success, the intent * {@link Intent#ACTION_WALLPAPER_CHANGED} is broadcast. diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 36e1c34..25b2cae 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -419,4 +419,12 @@ public class ContextWrapper extends Context { throws PackageManager.NameNotFoundException { return mBase.createPackageContext(packageName, flags); } + + /** + * @hide + */ + @Override + public float getApplicationScale() { + return mBase.getApplicationScale(); + } } diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index e020462..665e40c 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -24,6 +24,7 @@ import org.xmlpull.v1.XmlPullParserException; import android.graphics.Movie; import android.graphics.drawable.Drawable; +import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.os.SystemProperties; @@ -56,12 +57,14 @@ public class Resources { // Information about preloaded resources. Note that they are not // protected by a lock, because while preloading in zygote we are all // 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>(); private static final SparseArray<ColorStateList> mPreloadedColorStateLists = new SparseArray<ColorStateList>(); private static boolean mPreloaded; + private final SparseArray<Drawable.ConstantState> mPreloadedDrawables; + /*package*/ final TypedValue mTmpValue = new TypedValue(); // These are protected by the mTmpValue lock. @@ -82,6 +85,22 @@ public class Resources { /*package*/ final DisplayMetrics mMetrics = new DisplayMetrics(); 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 * can not be found. @@ -107,11 +126,27 @@ public class Resources { */ public Resources(AssetManager assets, DisplayMetrics metrics, 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; mConfiguration.setToDefaults(); mMetrics.setToDefaults(); updateConfiguration(config, metrics); assets.ensureStringBlocks(); + if (usePreloadedCache) { + mPreloadedDrawables = sPreloadedDrawables; + } else { + mPreloadedDrawables = emptySparseArray(); + } } /** @@ -1218,6 +1253,7 @@ public class Resources { mMetrics.setTo(metrics); } mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale; + String locale = null; if (mConfiguration.locale != null) { locale = mConfiguration.locale.getLanguage(); @@ -1653,7 +1689,7 @@ public class Resources { cs = dr.getConstantState(); if (cs != null) { if (mPreloading) { - mPreloadedDrawables.put(key, cs); + sPreloadedDrawables.put(key, cs); } else { synchronized (mTmpValue) { //Log.i(TAG, "Saving cached drawable @ #" + @@ -1883,6 +1919,6 @@ public class Resources { mMetrics.setToDefaults(); updateConfiguration(null, null); mAssets.ensureStringBlocks(); + mPreloadedDrawables = sPreloadedDrawables; } } - diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index 882a079..2402660 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -102,7 +102,7 @@ public final class MotionEvent implements Parcelable { private float mYPrecision; private int mDeviceId; private int mEdgeFlags; - + private MotionEvent mNext; private RuntimeException mRecycledLocation; private boolean mRecycled; @@ -210,7 +210,29 @@ public final class MotionEvent implements Parcelable { 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. */ @@ -682,4 +704,3 @@ public final class MotionEvent implements Parcelable { } } - diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 03ae6dc..71da9cf 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -136,20 +136,28 @@ public class SurfaceView extends View { int mFormat = -1; int mType = -1; final Rect mSurfaceFrame = new Rect(); + private final float mAppScale; + private final float mAppScaleInverted; public SurfaceView(Context context) { super(context); setWillNotDraw(true); + mAppScale = context.getApplicationScale(); + mAppScaleInverted = 1.0f / mAppScale; } public SurfaceView(Context context, AttributeSet attrs) { super(context, attrs); setWillNotDraw(true); + mAppScale = context.getApplicationScale(); + mAppScaleInverted = 1.0f / mAppScale; } public SurfaceView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setWillNotDraw(true); + mAppScale = context.getApplicationScale(); + mAppScaleInverted = 1.0f / mAppScale; } /** @@ -298,8 +306,8 @@ public class SurfaceView extends View { mLayout.x = mLeft; mLayout.y = mTop; - mLayout.width = getWidth(); - mLayout.height = getHeight(); + mLayout.width = (int) (getWidth() * mAppScale); + mLayout.height = (int) (getHeight() * mAppScale); mLayout.format = mRequestedFormat; mLayout.flags |=WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_SCALED @@ -326,9 +334,14 @@ public class SurfaceView extends View { mSurfaceLock.lock(); mDrawingStopped = !visible; final int relayoutResult = mSession.relayout( - mWindow, mLayout, mWidth, mHeight, + mWindow, mLayout, (int) (mWidth * mAppScale), (int) (mHeight * mAppScale), visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets, mVisibleInsets, mSurface); + + mContentInsets.scale(mAppScaleInverted); + mVisibleInsets.scale(mAppScaleInverted); + mWinFrame.scale(mAppScaleInverted); + if (localLOGV) Log.i(TAG, "New surface: " + mSurface + ", vis=" + visible + ", frame=" + mWinFrame); mSurfaceFrame.left = 0; @@ -396,15 +409,25 @@ public class SurfaceView extends View { } 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) { mSurfaceView = new WeakReference<SurfaceView>(surfaceView); + mAppScale = surfaceView.getContext().getApplicationScale(); + mAppScaleInverted = 1.0f / mAppScale; } public void resized(int w, int h, Rect coveredInsets, Rect visibleInsets, boolean reportDraw) { SurfaceView surfaceView = mSurfaceView.get(); + float scale = mAppScaleInverted; + w *= scale; + h *= scale; + coveredInsets.scale(scale); + visibleInsets.scale(scale); + if (surfaceView != null) { if (localLOGV) Log.v( "SurfaceView", surfaceView + " got resized: w=" + @@ -567,6 +590,7 @@ public class SurfaceView extends View { Canvas c = null; if (!mDrawingStopped && mWindow != null) { Rect frame = dirty != null ? dirty : mSurfaceFrame; + frame.scale(mAppScale); try { c = mSurface.lockCanvas(frame); } catch (Exception e) { @@ -612,4 +636,3 @@ public class SurfaceView extends View { } }; } - diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index 18ee9ae..0b03626 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -128,6 +128,9 @@ public final class ViewRoot extends Handler implements ViewParent, int mHeight; Rect mDirty; // will be a graphics.Region soon boolean mIsAnimating; + // TODO: change these to scaler class. + float mAppScale; + float mAppScaleInverted; // = 1.0f / mAppScale final View.AttachInfo mAttachInfo; @@ -384,10 +387,12 @@ public final class ViewRoot extends Handler implements ViewParent, View panelParentView) { synchronized (this) { if (mView == null) { + mView = view; + mAppScale = mView.getContext().getApplicationScale(); + mAppScaleInverted = 1.0f / mAppScale; mWindowAttributes.copyFrom(attrs); mSoftInputMode = attrs.softInputMode; mWindowAttributesChanged = true; - mView = view; mAttachInfo.mRootView = view; if (panelParentView != null) { mAttachInfo.mPanelParentWindowToken @@ -400,7 +405,7 @@ public final class ViewRoot extends Handler implements ViewParent, // manager, to make sure we do the relayout before receiving // any other events from the system. requestLayout(); - + try { res = sWindowSession.add(mWindow, attrs, getHostVisibility(), mAttachInfo.mContentInsets); @@ -411,6 +416,7 @@ public final class ViewRoot extends Handler implements ViewParent, unscheduleTraversals(); throw new RuntimeException("Adding window failed", e); } + mAttachInfo.mContentInsets.scale(mAppScaleInverted); mPendingContentInsets.set(mAttachInfo.mContentInsets); mPendingVisibleInsets.set(0, 0, 0, 0); if (Config.LOGV) Log.v("ViewRoot", "Added window " + mWindow); @@ -472,6 +478,8 @@ public final class ViewRoot extends Handler implements ViewParent, synchronized (this) { int oldSoftInputMode = mWindowAttributes.softInputMode; mWindowAttributes.copyFrom(attrs); + mWindowAttributes.scale(mAppScale); + if (newView) { mSoftInputMode = attrs.softInputMode; requestLayout(); @@ -521,9 +529,14 @@ public final class ViewRoot extends Handler implements ViewParent, public void invalidateChild(View child, Rect dirty) { checkThread(); if (LOCAL_LOGV) Log.v(TAG, "Invalidate child: " + dirty); - if (mCurScrollY != 0) { + if (mCurScrollY != 0 || mAppScale != 1.0f) { mTempRect.set(dirty); - mTempRect.offset(0, -mCurScrollY); + if (mCurScrollY != 0) { + mTempRect.offset(0, -mCurScrollY); + } + if (mAppScale != 1.0f) { + mTempRect.scale(mAppScale); + } dirty = mTempRect; } mDirty.union(dirty); @@ -613,8 +626,8 @@ public final class ViewRoot extends Handler implements ViewParent, mLayoutRequested = true; Display d = new Display(0); - desiredWindowWidth = d.getWidth(); - desiredWindowHeight = d.getHeight(); + desiredWindowWidth = (int) (d.getWidth() * mAppScaleInverted); + desiredWindowHeight = (int) (d.getHeight() * mAppScaleInverted); // For the very first time, tell the view hierarchy that it // 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; Display d = new Display(0); - desiredWindowWidth = d.getWidth(); - desiredWindowHeight = d.getHeight(); + desiredWindowWidth = (int) (d.getWidth() * mAppScaleInverted); + 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; } } - relayoutResult = sWindowSession.relayout( - mWindow, params, host.mMeasuredWidth, host.mMeasuredHeight, - viewVisibility, insetsPending, frame, - mPendingContentInsets, mPendingVisibleInsets, mSurface); + if (DEBUG_LAYOUT) { + Log.i(TAG, "host=w:" + host.mMeasuredWidth + ", h:" + + host.mMeasuredHeight + ", params=" + params); + } + relayoutResult = relayoutWindow(params, viewVisibility, insetsPending); + if (params != null) { params.flags = fl; } @@ -862,7 +877,7 @@ public final class ViewRoot extends Handler implements ViewParent, mHeight = frame.height(); if (initialized) { - mGlCanvas.setViewport(mWidth, mHeight); + mGlCanvas.setViewport((int) (mWidth * mAppScale), (int) (mHeight * mAppScale)); } boolean focusChangedDueToTouchMode = ensureTouchModeLocally( @@ -944,6 +959,11 @@ public final class ViewRoot extends Handler implements ViewParent, mTmpLocation[1] + host.mBottom - host.mTop); 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)) { mPreviousTransparentRegion.set(mTransparentRegion); // reconfigure window manager @@ -974,6 +994,9 @@ public final class ViewRoot extends Handler implements ViewParent, givenContent.left = givenContent.top = givenContent.right = givenContent.bottom = givenVisible.left = givenVisible.top = givenVisible.right = givenVisible.bottom = 0; + insets.contentInsets.scale(mAppScale); + insets.visibleInsets.scale(mAppScale); + attachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets); if (insetsPending || !mLastGivenInsets.equals(insets)) { mLastGivenInsets.set(insets); @@ -1113,7 +1136,7 @@ public final class ViewRoot extends Handler implements ViewParent, int yoff; final boolean scrolling = mScroller != null - && mScroller.computeScrollOffset(); + && mScroller.computeScrollOffset(); if (scrolling) { yoff = mScroller.getCurrY(); } else { @@ -1135,10 +1158,19 @@ public final class ViewRoot extends Handler implements ViewParent, mGL.glEnable(GL_SCISSOR_TEST); mAttachInfo.mDrawingTime = SystemClock.uptimeMillis(); - canvas.translate(0, -yoff); 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); checkEglErrors(); @@ -1160,7 +1192,7 @@ public final class ViewRoot extends Handler implements ViewParent, } if (fullRedrawNeeded) - dirty.union(0, 0, mWidth, mHeight); + dirty.union(0, 0, (int) (mWidth * mAppScale), (int) (mHeight * mAppScale)); if (DEBUG_ORIENTATION || DEBUG_DRAW) { Log.v("ViewRoot", "Draw " + mView + "/" @@ -1212,10 +1244,24 @@ public final class ViewRoot extends Handler implements ViewParent, dirty.setEmpty(); mIsAnimating = false; mAttachInfo.mDrawingTime = SystemClock.uptimeMillis(); - canvas.translate(0, -yoff); - mView.mPrivateFlags |= View.DRAWN; - mView.draw(canvas); - canvas.translate(0, yoff); + mView.mPrivateFlags |= View.DRAWN; + + float scale = mAppScale; + 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) { int now = (int)SystemClock.elapsedRealtime(); @@ -1508,6 +1554,9 @@ public final class ViewRoot extends Handler implements ViewParent, } else { didFinish = event.getAction() == MotionEvent.ACTION_OUTSIDE; } + if (event != null) { + event.scale(mAppScaleInverted); + } try { boolean handled; @@ -1628,7 +1677,8 @@ public final class ViewRoot extends Handler implements ViewParent, if (mGlWanted && !mUseGL) { initializeGL(); 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 { didFinish = false; } + if (event != null) { + event.scale(mAppScaleInverted); + } if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event); @@ -2254,6 +2307,20 @@ public final class ViewRoot extends Handler implements ViewParent, 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} */ @@ -2322,12 +2389,8 @@ public final class ViewRoot extends Handler implements ViewParent, // to the window manager to make sure it has the correct // animation info. try { - if ((sWindowSession.relayout( - mWindow, mWindowAttributes, - mView.mMeasuredWidth, mView.mMeasuredHeight, - viewVisibility, false, mWinFrame, mPendingContentInsets, - mPendingVisibleInsets, mSurface) - &WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) { + if ((relayoutWindow(mWindowAttributes, viewVisibility, false) + & WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) { sWindowSession.finishDrawing(mWindow); } } catch (RemoteException e) { @@ -2361,8 +2424,11 @@ public final class ViewRoot extends Handler implements ViewParent, + " visibleInsets=" + visibleInsets.toShortString() + " reportDraw=" + reportDraw); 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) }; sendMessage(msg); } @@ -2493,7 +2559,7 @@ public final class ViewRoot extends Handler implements ViewParent, sWindowSession.finishKey(mWindow); } catch (RemoteException e) { } - } else if (mIsPointer) { + } else if (mIsPointer) { boolean didFinish; MotionEvent event = mMotionEvent; if (event == null) { diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 34e65ad..f6a171d 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -954,7 +954,7 @@ public interface WindowManager extends ViewManager { return sb.toString(); } - void scaleUp(float scale) { + void scale(float scale) { if (scale != 1.0f) { x *= scale; y *= scale; diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java index 7022acf..50ab566 100644 --- a/graphics/java/android/graphics/Rect.java +++ b/graphics/java/android/graphics/Rect.java @@ -545,4 +545,17 @@ public final class Rect implements Parcelable { right = 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; + } + } } diff --git a/test-runner/android/test/mock/MockContext.java b/test-runner/android/test/mock/MockContext.java index e733dd1..bd39a14 100644 --- a/test-runner/android/test/mock/MockContext.java +++ b/test-runner/android/test/mock/MockContext.java @@ -386,4 +386,12 @@ public class MockContext extends Context { throws PackageManager.NameNotFoundException { throw new UnsupportedOperationException(); } + + /** + * @hide + */ + @Override + public float getApplicationScale() { + throw new UnsupportedOperationException(); + } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java index baa3d53..f434e14 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java @@ -1145,4 +1145,12 @@ public final class BridgeContext extends Context { public Context getApplicationContext() { throw new UnsupportedOperationException(); } + + /** + * @hide + */ + @Override + public float getApplicationScale() { + throw new UnsupportedOperationException(); + } } |