diff options
7 files changed, 96 insertions, 40 deletions
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 1be2f95cf55a..3fc70cc3b4d9 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -101,16 +101,24 @@ interface IWindowSession { * for the parent window appears. This allows for synchronizing movement of a child * to repainting the contents of the parent. * + * "width" and "height" correspond to the width and height members of + * WindowManager.LayoutParams in the {@link #relayout relayout()} case. + * This may differ from the surface buffer size in the + * case of {@link LayoutParams#FLAG_SCALED} and {@link #relayout relayout()} + * must be used with requestedWidth/height if this must be changed. + * * @param window The window being modified. Must be attached to a parent window * or this call will fail. * @param x The new x position * @param y The new y position + * @param width The new width + * @param height The new height * @param deferTransactionUntilFrame Frame number from our parent (attached) to * defer this action until. * @param outFrame Rect in which is placed the new position/size on screen. */ - void repositionChild(IWindow childWindow, int x, int y, long deferTransactionUntilFrame, - out Rect outFrame); + void repositionChild(IWindow childWindow, int left, int top, int right, int bottom, + long deferTransactionUntilFrame, out Rect outFrame); /** * If a call to relayout() asked to have the surface destroy deferred, diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 514f88bc7f24..589c0dc85b68 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -157,10 +157,10 @@ public class SurfaceView extends View { long mLastLockTime = 0; boolean mVisible = false; - int mLeft = -1; - int mTop = -1; - int mWidth = -1; - int mHeight = -1; + int mWindowSpaceLeft = -1; + int mWindowSpaceTop = -1; + int mWindowSpaceWidth = -1; + int mWindowSpaceHeight = -1; int mFormat = -1; final Rect mSurfaceFrame = new Rect(); int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1; @@ -445,32 +445,33 @@ public class SurfaceView extends View { getLocationInWindow(mLocation); final boolean creating = mWindow == null; final boolean formatChanged = mFormat != mRequestedFormat; - final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight; + final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight; final boolean visibleChanged = mVisible != mRequestedVisible; - final boolean layoutSizeChanged = getWidth() != mLayout.width || getHeight() != mLayout.height; - final boolean positionChanged = mLeft != mLocation[0] || mTop != mLocation[1]; + final boolean layoutSizeChanged = getWidth() != mLayout.width + || getHeight() != mLayout.height; + final boolean positionChanged = mWindowSpaceLeft != mLocation[0] || mWindowSpaceTop != mLocation[1]; if (force || creating || formatChanged || sizeChanged || visibleChanged - || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded || layoutSizeChanged) { + || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) { if (DEBUG) Log.i(TAG, "Changes: creating=" + creating + " format=" + formatChanged + " size=" + sizeChanged + " visible=" + visibleChanged - + " left=" + (mLeft != mLocation[0]) - + " top=" + (mTop != mLocation[1])); + + " left=" + (mWindowSpaceLeft != mLocation[0]) + + " top=" + (mWindowSpaceTop != mLocation[1])); try { final boolean visible = mVisible = mRequestedVisible; - mLeft = mLocation[0]; - mTop = mLocation[1]; - mWidth = myWidth; - mHeight = myHeight; + mWindowSpaceLeft = mLocation[0]; + mWindowSpaceTop = mLocation[1]; + mWindowSpaceWidth = myWidth; + mWindowSpaceHeight = myHeight; mFormat = mRequestedFormat; // Scaling/Translate window's layout here because mLayout is not used elsewhere. // Places the window relative - mLayout.x = mLeft; - mLayout.y = mTop; + mLayout.x = mWindowSpaceLeft; + mLayout.y = mWindowSpaceTop; mLayout.width = getWidth(); mLayout.height = getHeight(); if (mTranslator != null) { @@ -485,6 +486,14 @@ public class SurfaceView extends View { | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE ; + if (!creating && !force && !mUpdateWindowNeeded) { + mLayout.privateFlags |= + WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY; + } else { + mLayout.privateFlags &= + ~WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY; + } + if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) { mLayout.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; @@ -516,7 +525,7 @@ public class SurfaceView extends View { if (DEBUG) Log.i(TAG, "Cur surface: " + mSurface); relayoutResult = mSession.relayout( - mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, + mWindow, mWindow.mSeq, mLayout, mWindowSpaceWidth, mWindowSpaceHeight, visible ? VISIBLE : GONE, WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY, mWinFrame, mOverscanInsets, mContentInsets, @@ -621,11 +630,19 @@ public class SurfaceView extends View { TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y + " w=" + mLayout.width + " h=" + mLayout.height + ", frame=" + mSurfaceFrame); - } else if (positionChanged) { // Only the position has changed - mLeft = mLocation[0]; - mTop = mLocation[1]; + } else if (positionChanged || layoutSizeChanged) { // Only the position has changed + mWindowSpaceLeft = mLocation[0]; + mWindowSpaceTop = mLocation[1]; + // For our size changed check, we keep mLayout.width and mLayout.height + // in view local space. + mLocation[0] = mLayout.width = getWidth(); + mLocation[1] = mLayout.height = getHeight(); + + transformFromViewToWindowSpace(mLocation); + try { - mSession.repositionChild(mWindow, mLeft, mTop, + mSession.repositionChild(mWindow, mWindowSpaceLeft, mWindowSpaceTop, + mLocation[0], mLocation[1], viewRoot != null ? viewRoot.getNextFrameNumber() : -1, mWinFrame); } catch (RemoteException ex) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index c2af9f7bb24a..66b05a20492f 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -18498,21 +18498,29 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * must be an array of two integers. After the method returns, the array * contains the x and y location in that order.</p> * - * @param location an array of two integers in which to hold the coordinates + * @param outWindowSpace an array of two integers in which to hold the coordinates */ - public void getLocationInWindow(@Size(2) int[] location) { - if (location == null || location.length < 2) { - throw new IllegalArgumentException("location must be an array of two integers"); + public void getLocationInWindow(@Size(2) int[] outWindowSpace) { + outWindowSpace[0] = 0; + outWindowSpace[1] = 0; + + transformFromViewToWindowSpace(outWindowSpace); + } + + void transformFromViewToWindowSpace(@Size(2) int[] inOutLocation) { + if (inOutLocation == null || inOutLocation.length < 2) { + throw new IllegalArgumentException("inOutLocation must be an array of two integers"); } if (mAttachInfo == null) { // When the view is not attached to a window, this method does not make sense - location[0] = location[1] = 0; + inOutLocation[0] = inOutLocation[1] = 0; return; } - float[] position = mAttachInfo.mTmpTransformLocation; - position[0] = position[1] = 0.0f; + float position[] = mAttachInfo.mTmpTransformLocation; + position[0] = inOutLocation[0]; + position[1] = inOutLocation[1]; if (!hasIdentityMatrix()) { getMatrix().mapPoints(position); @@ -18544,8 +18552,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, position[1] -= vr.mCurScrollY; } - location[0] = (int) (position[0] + 0.5f); - location[1] = (int) (position[1] + 0.5f); + inOutLocation[0] = (int) (position[0] + 0.5f); + inOutLocation[1] = (int) (position[1] + 0.5f); } /** diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 2d0435f4c7e3..edf4297afdea 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -1148,6 +1148,16 @@ public interface WindowManager extends ViewManager { public static final int PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT = 0x00001000; /** + * Flag indicating that the x, y, width, and height members should be + * ignored (and thus their previous value preserved). For example + * because they are being managed externally through repositionChild. + * + * {@hide} + */ + public static final int PRIVATE_FLAG_PRESERVE_GEOMETRY = 0x00002000; + + + /** * Control flags that are private to the platform. * @hide */ diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index c47c377f4cb8..1caeca09238d 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -188,9 +188,10 @@ final class Session extends IWindowSession.Stub } @Override - public void repositionChild(IWindow window, int x, int y, long deferTransactionUntilFrame, - Rect outFrame) { - mService.repositionChild(this, window, x, y, deferTransactionUntilFrame, outFrame); + public void repositionChild(IWindow window, int left, int top, int right, int bottom, + long deferTransactionUntilFrame, Rect outFrame) { + mService.repositionChild(this, window, left, top, right, bottom, + deferTransactionUntilFrame, outFrame); } public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 05e88caf7bd4..c747d4769f0a 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2504,7 +2504,8 @@ public class WindowManagerService extends IWindowManager.Stub } void repositionChild(Session session, IWindow client, - int x, int y, long deferTransactionUntilFrame, Rect outFrame) { + int top, int left, int right, int bottom, + long deferTransactionUntilFrame, Rect outFrame) { Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "repositionChild"); long origId = Binder.clearCallingIdentity(); @@ -2520,8 +2521,10 @@ public class WindowManagerService extends IWindowManager.Stub + "attached to a parent win=" + win); } - win.mFrame.left = x; - win.mFrame.top = y; + win.mFrame.left = left; + win.mFrame.top = top; + win.mFrame.right = right; + win.mFrame.bottom = bottom; win.mWinAnimator.computeShownFrameLocked(); @@ -2594,6 +2597,15 @@ public class WindowManagerService extends IWindowManager.Stub throw new IllegalArgumentException( "Window type can not be changed after the window is added."); } + + // Odd choice but less odd than embedding in copyFrom() + if ((attrs.flags & WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY) != 0) { + attrs.x = win.mAttrs.x; + attrs.y = win.mAttrs.y; + attrs.width = win.mAttrs.width; + attrs.height = win.mAttrs.height; + } + flagChanges = win.mAttrs.flags ^= attrs.flags; attrChanges = win.mAttrs.copyFrom(attrs); if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java index 11bd15d780fc..1ec054720547 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java @@ -95,8 +95,8 @@ public final class BridgeWindowSession implements IWindowSession { } @Override - public void repositionChild(IWindow childWindow, int x, int y, long deferTransactionUntilFrame, - Rect outFrame) { + public void repositionChild(IWindow childWindow, int x, int y, int width, int height, + long deferTransactionUntilFrame, Rect outFrame) { // pass for now. return; } |