summaryrefslogtreecommitdiffstats
path: root/core/java/android/view
diff options
context:
space:
mode:
authorMitsuru Oshima <>2009-04-28 18:12:09 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-04-28 18:12:09 -0700
commit8169daed2f7a8731d478b884b1f455c747b88478 (patch)
tree3ab1f44b128cef2f18f470af7483a8405329da23 /core/java/android/view
parent8d112675879a2b83197d3b4ae4fb623abd1a1ec3 (diff)
downloadframeworks_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.java27
-rw-r--r--core/java/android/view/SurfaceView.java33
-rw-r--r--core/java/android/view/ViewRoot.java130
-rw-r--r--core/java/android/view/WindowManager.java2
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;