diff options
| author | Mitsuru Oshima <> | 2009-04-28 18:12:09 -0700 | 
|---|---|---|
| committer | The Android Open Source Project <initial-contribution@android.com> | 2009-04-28 18:12:09 -0700 | 
| commit | 8169daed2f7a8731d478b884b1f455c747b88478 (patch) | |
| tree | 3ab1f44b128cef2f18f470af7483a8405329da23 /core/java/android/view | |
| parent | 8d112675879a2b83197d3b4ae4fb623abd1a1ec3 (diff) | |
| download | frameworks_base-8169daed2f7a8731d478b884b1f455c747b88478.zip frameworks_base-8169daed2f7a8731d478b884b1f455c747b88478.tar.gz frameworks_base-8169daed2f7a8731d478b884b1f455c747b88478.tar.bz2 | |
AI 147976: Compatibility mode support. Part 2.
  * Introduced ApplicationScale (may not be good name. CompatibilityScale? CanvasScale? Pls let me know if you have better idea)
  * Changes to RootView / SurfaceView
  - Makes the app believe it's running in the supported density/resolution.
  - Makes the window manager believe it's running at the right density/resolution.
  * Added methods to Rect/Event for scaling up/down.
  Known issues:
  * certain kind of images (such as nine patch for buttons) seesm to be loaded not by app, thus does not take the scale into account,
  which, in turn, is causing layout issue.
  * ZoomButton in MapView is rendered in wrong place
  * Transparent region on Surface is not correct
  * Specifying different densities in one process is not working.
  BUG=1770627
Automated import of CL 147976
Diffstat (limited to 'core/java/android/view')
| -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 | 
4 files changed, 151 insertions, 41 deletions
| 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 e928998..61dca4c 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -135,20 +135,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;      }      /** @@ -297,8 +305,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 @@ -325,9 +333,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; @@ -395,15 +408,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=" + @@ -566,6 +589,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) { @@ -611,4 +635,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; | 
