Fix some issues that make caption insets remain

This CL does the following:
* Remove caption insets when releasing the window decor
* Update caption insets in InsetsController when the caption is in WM
  shell
* Dump LocalInsetsSourceProviders to help debug related issues

Bug: 241029178
Test: The caption type of insets provider is removed when window decor
      is released.
Test: atest WindowDecorationTests
Change-Id: Ia20e1958588de3a7d965b3ac3d3e4333c67dff36
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index cce3e8c..a2cb1d5 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -733,7 +733,7 @@
         }
         for (@InternalInsetsType int type = 0; type < InsetsState.SIZE; type++) {
             // Only update the server side insets here.
-            if (type == ITYPE_CAPTION_BAR) continue;
+            if (!CAPTION_ON_SHELL && type == ITYPE_CAPTION_BAR) continue;
             InsetsSource source = mState.peekSource(type);
             if (source == null) continue;
             if (newState.peekSource(type) == null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 4380bdc..087304b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -66,6 +66,7 @@
     final DisplayController mDisplayController;
     final ShellTaskOrganizer mTaskOrganizer;
     final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier;
+    final Supplier<WindowContainerTransaction> mWindowContainerTransactionSupplier;
     final SurfaceControlViewHostFactory mSurfaceControlViewHostFactory;
     private final DisplayController.OnDisplaysChangedListener mOnDisplaysChangedListener =
             new DisplayController.OnDisplaysChangedListener() {
@@ -102,7 +103,8 @@
             RunningTaskInfo taskInfo,
             SurfaceControl taskSurface) {
         this(context, displayController, taskOrganizer, taskInfo, taskSurface,
-                SurfaceControl.Builder::new, new SurfaceControlViewHostFactory() {});
+                SurfaceControl.Builder::new, WindowContainerTransaction::new,
+                new SurfaceControlViewHostFactory() {});
     }
 
     WindowDecoration(
@@ -112,6 +114,7 @@
             RunningTaskInfo taskInfo,
             SurfaceControl taskSurface,
             Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
+            Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
             SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
         mContext = context;
         mDisplayController = displayController;
@@ -119,6 +122,7 @@
         mTaskInfo = taskInfo;
         mTaskSurface = taskSurface;
         mSurfaceControlBuilderSupplier = surfaceControlBuilderSupplier;
+        mWindowContainerTransactionSupplier = windowContainerTransactionSupplier;
         mSurfaceControlViewHostFactory = surfaceControlViewHostFactory;
 
         mDisplay = mDisplayController.getDisplay(mTaskInfo.displayId);
@@ -301,6 +305,10 @@
             mTaskBackgroundSurface.release();
             mTaskBackgroundSurface = null;
         }
+
+        final WindowContainerTransaction wct = mWindowContainerTransactionSupplier.get();
+        wct.removeInsetsProvider(mTaskInfo.token, CAPTION_INSETS_TYPES);
+        mTaskOrganizer.applyTransaction(wct);
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index b318bb2..1e7d5fe 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -233,6 +233,57 @@
     }
 
     @Test
+    public void testLayoutResultCalculation_visibleFocusedTaskToInvisible() {
+        final Display defaultDisplay = mock(Display.class);
+        doReturn(defaultDisplay).when(mMockDisplayController)
+                .getDisplay(Display.DEFAULT_DISPLAY);
+
+        final SurfaceControl decorContainerSurface = mock(SurfaceControl.class);
+        final SurfaceControl.Builder decorContainerSurfaceBuilder =
+                createMockSurfaceControlBuilder(decorContainerSurface);
+        mMockSurfaceControlBuilders.add(decorContainerSurfaceBuilder);
+        final SurfaceControl taskBackgroundSurface = mock(SurfaceControl.class);
+        final SurfaceControl.Builder taskBackgroundSurfaceBuilder =
+                createMockSurfaceControlBuilder(taskBackgroundSurface);
+        mMockSurfaceControlBuilders.add(taskBackgroundSurfaceBuilder);
+
+        final ActivityManager.TaskDescription.Builder taskDescriptionBuilder =
+                new ActivityManager.TaskDescription.Builder()
+                        .setBackgroundColor(Color.YELLOW);
+        final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+                .setDisplayId(Display.DEFAULT_DISPLAY)
+                .setTaskDescriptionBuilder(taskDescriptionBuilder)
+                .setBounds(TASK_BOUNDS)
+                .setPositionInParent(TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y)
+                .setVisible(true)
+                .build();
+        taskInfo.isFocused = true;
+        // Density is 2. Outsets are (20, 40, 60, 80) px. Shadow radius is 10px. Caption height is
+        // 64px.
+        taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2;
+        mOutsetsDp.set(10, 20, 30, 40);
+
+        final SurfaceControl taskSurface = mock(SurfaceControl.class);
+        final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface);
+
+        windowDecor.relayout(taskInfo);
+
+        verify(mMockSurfaceControlViewHost, never()).release();
+        verify(decorContainerSurface, never()).release();
+        verify(taskBackgroundSurface, never()).release();
+        verify(mMockWindowContainerTransaction, never())
+                .removeInsetsProvider(eq(taskInfo.token), any());
+
+        taskInfo.isVisible = false;
+        windowDecor.relayout(taskInfo);
+
+        verify(mMockSurfaceControlViewHost).release();
+        verify(decorContainerSurface).release();
+        verify(taskBackgroundSurface).release();
+        verify(mMockWindowContainerTransaction).removeInsetsProvider(eq(taskInfo.token), any());
+    }
+
+    @Test
     public void testNotCrashWhenDisplayAppearsAfterTask() {
         doReturn(mock(Display.class)).when(mMockDisplayController)
                 .getDisplay(Display.DEFAULT_DISPLAY);
@@ -282,7 +333,7 @@
             ActivityManager.RunningTaskInfo taskInfo, SurfaceControl testSurface) {
         return new TestWindowDecoration(mContext, mMockDisplayController, mMockShellTaskOrganizer,
                 taskInfo, testSurface, new MockSurfaceControlBuilderSupplier(),
-                mMockSurfaceControlViewHostFactory);
+                () -> mMockWindowContainerTransaction, mMockSurfaceControlViewHostFactory);
     }
 
     private class MockSurfaceControlBuilderSupplier implements Supplier<SurfaceControl.Builder> {
@@ -313,9 +364,11 @@
                 ShellTaskOrganizer taskOrganizer, ActivityManager.RunningTaskInfo taskInfo,
                 SurfaceControl taskSurface,
                 Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
+                Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
                 SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
             super(context, displayController, taskOrganizer, taskInfo, taskSurface,
-                    surfaceControlBuilderSupplier, surfaceControlViewHostFactory);
+                    surfaceControlBuilderSupplier, windowContainerTransactionSupplier,
+                    surfaceControlViewHostFactory);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index d9b25ad..15fbdb9 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -3393,6 +3393,13 @@
             pw.println(prefix + "mLastOrientationSource=" + mLastOrientationSource);
             pw.println(prefix + "deepestLastOrientationSource=" + getLastOrientationSource());
         }
+        if (mLocalInsetsSourceProviders != null && mLocalInsetsSourceProviders.size() != 0) {
+            pw.println(prefix + mLocalInsetsSourceProviders.size() + " LocalInsetsSourceProviders");
+            final String childPrefix = prefix + "  ";
+            for (int i = 0; i < mLocalInsetsSourceProviders.size(); ++i) {
+                mLocalInsetsSourceProviders.valueAt(i).dump(pw, childPrefix);
+            }
+        }
     }
 
     final void updateSurfacePositionNonOrganized() {