summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/IWindowSession.aidl12
-rw-r--r--core/java/android/view/SurfaceView.java59
-rw-r--r--core/java/android/view/View.java26
-rw-r--r--core/java/android/view/WindowManager.java10
-rw-r--r--services/core/java/com/android/server/wm/Session.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java18
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java4
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;
}