Set stack size and position and update children surface position.

Update the stack's size and position to represent the bounds. Then
update all children's positions so they are in the correct place within
the stack's bounds.

Test: Split screen, pip
Change-Id: I0372a8d20407ec35d1e8c0fc8165253f68d2f18f
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a4ef750..8d7f432 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -69,7 +69,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
@@ -91,8 +90,6 @@
 import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
 import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
 import static com.android.server.wm.WindowManagerService.SEAMLESS_ROTATION_TIMEOUT_DURATION;
-import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
-import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_ACTIVE;
 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
@@ -123,7 +120,6 @@
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
-import android.graphics.GraphicBuffer;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -715,9 +711,13 @@
             winAnimator.setSurfaceBoundariesLocked(mTmpRecoveringMemory /* recoveringMemory */);
 
             // Since setSurfaceBoundariesLocked applies the clipping, we need to apply the position
-            // to the surface of the window container as well. Use mTmpTransaction instead of
-            // mPendingTransaction to avoid committing any existing changes in there.
+            // to the surface of the window container and also the position of the stack window
+            // container as well. Use mTmpTransaction instead of mPendingTransaction to avoid
+            // committing any existing changes in there.
             w.updateSurfacePosition(mTmpTransaction);
+            if (stack != null) {
+                stack.updateSurfaceBounds(mTmpTransaction);
+            }
             SurfaceControl.mergeToGlobalTransaction(mTmpTransaction);
         }
 
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 374c06c..3c96ca1 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -649,6 +649,9 @@
         mDimmer.resetDimStates();
         super.prepareSurfaces();
         getDimBounds(mTmpDimBoundsRect);
+
+        // Bounds need to be relative, as the dim layer is a child.
+        mTmpDimBoundsRect.offsetTo(0, 0);
         if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
             scheduleAnimation();
         }
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index a07a8d4..7aae129 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -31,9 +31,8 @@
 import static android.view.WindowManager.DOCKED_LEFT;
 import static android.view.WindowManager.DOCKED_RIGHT;
 import static android.view.WindowManager.DOCKED_TOP;
-import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+
 import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.proto.StackProto.ANIMATION_BACKGROUND_SURFACE_IS_DIMMING;
@@ -220,6 +219,8 @@
         }
         alignTasksToAdjustedBounds(adjusted ? mAdjustedBounds : getRawBounds(), insetBounds);
         mDisplayContent.setLayoutNeeded();
+
+        updateSurfaceBounds();
     }
 
     private void alignTasksToAdjustedBounds(Rect adjustedBounds, Rect tempInsetBounds) {
@@ -241,10 +242,11 @@
             return;
         }
         getRawBounds(mTmpRect);
-        // TODO: Should be in relative coordinates.
-        getPendingTransaction().setSize(mAnimationBackgroundSurface, mTmpRect.width(),
-                mTmpRect.height()).setPosition(mAnimationBackgroundSurface, mTmpRect.left,
-                mTmpRect.top);
+        final Rect stackBounds = getBounds();
+        getPendingTransaction()
+                .setSize(mAnimationBackgroundSurface, mTmpRect.width(), mTmpRect.height())
+                .setPosition(mAnimationBackgroundSurface, mTmpRect.left - stackBounds.left,
+                        mTmpRect.top - stackBounds.top);
         scheduleAnimation();
     }
 
@@ -297,6 +299,7 @@
 
         updateAdjustedBounds();
 
+        updateSurfaceBounds();
         return result;
     }
 
@@ -711,8 +714,12 @@
     @Override
     public void onConfigurationChanged(Configuration newParentConfig) {
         final int prevWindowingMode = getWindowingMode();
+        // Only need to update surface size here since the super method will handle updating
+        // surface position.
+        updateSurfaceSize(getPendingTransaction());
         super.onConfigurationChanged(newParentConfig);
         final int windowingMode = getWindowingMode();
+
         if (mDisplayContent == null || prevWindowingMode == windowingMode) {
             return;
         }
@@ -720,6 +727,25 @@
         updateBoundsForWindowModeChange();
     }
 
+    private void updateSurfaceBounds() {
+        updateSurfaceBounds(getPendingTransaction());
+        scheduleAnimation();
+    }
+
+    void updateSurfaceBounds(SurfaceControl.Transaction transaction) {
+        updateSurfaceSize(transaction);
+        updateSurfacePosition(transaction);
+    }
+
+    private void updateSurfaceSize(SurfaceControl.Transaction transaction) {
+        if (mSurfaceControl == null) {
+            return;
+        }
+
+        final Rect stackBounds = getBounds();
+        transaction.setSize(mSurfaceControl, stackBounds.width(), stackBounds.height());
+    }
+
     @Override
     void onDisplayChanged(DisplayContent dc) {
         if (mDisplayContent != null) {
@@ -1677,6 +1703,9 @@
         mDimmer.resetDimStates();
         super.prepareSurfaces();
         getDimBounds(mTmpDimBoundsRect);
+
+        // Bounds need to be relative, as the dim layer is a child.
+        mTmpDimBoundsRect.offsetTo(0, 0);
         if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
             scheduleAnimation();
         }
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index af06900..f297cc8 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -29,7 +29,8 @@
 
 import android.annotation.CallSuper;
 import android.content.res.Configuration;
-import android.graphics.PixelFormat.Opacity;
+import android.graphics.Point;
+import android.graphics.Rect;
 import android.util.Slog;
 import android.view.MagnificationSpec;
 import android.view.SurfaceControl;
@@ -93,6 +94,8 @@
     protected final SurfaceAnimator mSurfaceAnimator;
     protected final WindowManagerService mService;
 
+    private final Point mTmpPos = new Point();
+
     WindowContainer(WindowManagerService service) {
         mService = service;
         mPendingTransaction = service.mTransactionFactory.make();
@@ -114,6 +117,13 @@
         return mChildren.get(index);
     }
 
+    @Override
+    public void onConfigurationChanged(Configuration newParentConfig) {
+        super.onConfigurationChanged(newParentConfig);
+        updateSurfacePosition(getPendingTransaction());
+        scheduleAnimation();
+    }
+
     final protected void setParent(WindowContainer<WindowContainer> parent) {
         mParent = parent;
         // Removing parent usually means that we've detached this entity to destroy it or to attach
@@ -1076,4 +1086,27 @@
             mSurfaceAnimator.dump(pw, prefix + "  ");
         }
     }
+
+    void updateSurfacePosition(SurfaceControl.Transaction transaction) {
+        if (mSurfaceControl == null) {
+            return;
+        }
+
+        getRelativePosition(mTmpPos);
+        transaction.setPosition(mSurfaceControl, mTmpPos.x, mTmpPos.y);
+
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            mChildren.get(i).updateSurfacePosition(transaction);
+        }
+    }
+
+    void getRelativePosition(Point outPos) {
+        final Rect bounds = getBounds();
+        outPos.set(bounds.left, bounds.top);
+        final WindowContainer parent = getParent();
+        if (parent != null) {
+            final Rect parentBounds = parent.getBounds();
+            outPos.offset(-parentBounds.left, -parentBounds.top);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ca13984..0a2ffbc 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5477,7 +5477,9 @@
 
     /** Note that Locked in this case is on mLayoutToAnim */
     void scheduleAnimationLocked() {
-        mAnimator.scheduleAnimation();
+        if (mAnimator != null) {
+            mAnimator.scheduleAnimation();
+        }
     }
 
     // TODO: Move to DisplayContent
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index f39a9ec..a5c46e0 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -4425,6 +4425,7 @@
         updateSurfacePosition(t);
     }
 
+    @Override
     void updateSurfacePosition(Transaction t) {
         if (mSurfaceControl == null) {
             return;
@@ -4438,11 +4439,15 @@
 
     private void transformFrameToSurfacePosition(int left, int top, Point outPoint) {
         outPoint.set(left, top);
+        final WindowContainer parentWindowContainer = getParent();
         if (isChildWindow()) {
             // TODO: This probably falls apart at some point and we should
             // actually compute relative coordinates.
             final WindowState parent = getParentWindow();
             outPoint.offset(-parent.mFrame.left, -parent.mFrame.top);
+        } else if (parentWindowContainer != null) {
+            final Rect parentBounds = parentWindowContainer.getBounds();
+            outPoint.offset(-parentBounds.left, -parentBounds.top);
         }
 
         // Expand for surface insets. See WindowState.expandForSurfaceInsets.