Update the size of SurfaceControl after display changed

Bug: 112963441
Test: atest ActivityManagerMultiDisplayTests
      atest DisplayContentTests
      atest WindowContainerTests

Change-Id: I1b8f3fd48e8b9d642992b4f3a345672eb34e506b
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 6aca464..eaaf804 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -76,6 +76,7 @@
 import static com.android.server.wm.DisplayContentProto.ROTATION;
 import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
 import static com.android.server.wm.DisplayContentProto.STACKS;
+import static com.android.server.wm.DisplayContentProto.SURFACE_SIZE;
 import static com.android.server.wm.DisplayContentProto.WINDOW_CONTAINER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
@@ -2409,6 +2410,7 @@
             screenRotationAnimation.writeToProto(proto, SCREEN_ROTATION_ANIMATION);
         }
         mDisplayFrames.writeToProto(proto, DISPLAY_FRAMES);
+        proto.write(SURFACE_SIZE, mSurfaceSize);
         proto.end(token);
     }
 
@@ -3151,6 +3153,10 @@
         }
     }
 
+    int getSurfaceSize() {
+        return mSurfaceSize;
+    }
+
     void performLayout(boolean initial, boolean updateInputWindows) {
         if (!isLayoutNeeded()) {
             return;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index eb419c9..cc23ab6 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -29,6 +29,8 @@
 import static com.android.server.wm.TaskProto.DEFER_REMOVAL;
 import static com.android.server.wm.TaskProto.FILLS_PARENT;
 import static com.android.server.wm.TaskProto.ID;
+import static com.android.server.wm.TaskProto.SURFACE_HEIGHT;
+import static com.android.server.wm.TaskProto.SURFACE_WIDTH;
 import static com.android.server.wm.TaskProto.TEMP_INSET_BOUNDS;
 import static com.android.server.wm.TaskProto.WINDOW_CONTAINER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
@@ -297,6 +299,12 @@
         return boundsChange;
     }
 
+    @Override
+    void onDisplayChanged(DisplayContent dc) {
+        updateSurfaceSize(dc);
+        super.onDisplayChanged(dc);
+    }
+
     /**
      * Sets the bounds used to calculate the insets. See
      * {@link android.app.IActivityTaskManager#resizeDockedStack} why this is needed.
@@ -703,6 +711,8 @@
         getBounds().writeToProto(proto, BOUNDS);
         mTempInsetBounds.writeToProto(proto, TEMP_INSET_BOUNDS);
         proto.write(DEFER_REMOVAL, mDeferRemoval);
+        proto.write(SURFACE_WIDTH, mSurfaceControl.getWidth());
+        proto.write(SURFACE_HEIGHT, mSurfaceControl.getHeight());
         proto.end(token);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 8e704a8..e860939 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -20,13 +20,14 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.view.SurfaceControl.Transaction;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import static com.android.server.wm.WindowContainerProto.CONFIGURATION_CONTAINER;
 import static com.android.server.wm.WindowContainerProto.ORIENTATION;
 import static com.android.server.wm.WindowContainerProto.SURFACE_ANIMATOR;
 import static com.android.server.wm.WindowContainerProto.VISIBLE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.annotation.CallSuper;
 import android.annotation.IntDef;
@@ -503,6 +504,24 @@
         }
     }
 
+    /**
+     * Update the surface size when display changed in order to avoid children being bound by the
+     * old display size.
+     *
+     * Note that we don't want to apply this to all layers, but only limiting this to layers that
+     * don't set their own size ({@link Task}, {@link WindowState} and {@link WindowToken}).
+     */
+    void updateSurfaceSize(DisplayContent dc) {
+        if (mSurfaceControl == null) {
+            return;
+        }
+
+        final int newSurfaceSize = dc.getSurfaceSize();
+        if (mSurfaceControl.getWidth() != newSurfaceSize) {
+            getPendingTransaction().setSize(mSurfaceControl, newSurfaceSize, newSurfaceSize);
+        }
+    }
+
     void setWaitingForDrawnIfResizingChanged() {
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowContainer wc = mChildren.get(i);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index f1ddda7..db558a8 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1259,6 +1259,7 @@
 
     @Override
     void onDisplayChanged(DisplayContent dc) {
+        updateSurfaceSize(dc);
         super.onDisplayChanged(dc);
         // Window was not laid out for this display yet, so make sure mLayoutSeq does not match.
         if (dc != null) {
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index e411c0a..8972c38 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -18,6 +18,7 @@
 
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
@@ -275,6 +276,7 @@
         // to another display before the window behind
         // it is ready.
 
+        updateSurfaceSize(dc);
         super.onDisplayChanged(dc);
     }