Reland: "Copy mCompatInsetTypes and mCompatIgnoreVisibility"

Before this CL, when creating a new WindowInsets based on an existing
one by using WindowInsets.Builder, some fields were not copyied
properly.

This CL passes mCompatInsetTypes and mCompatIgnoreVisibility from the
given WindowInsets to the newly created one.

The previous attempt didn't make mCompatInsetTypes align with the types
in assignCompatInsets and didn't reset mCompatIgnoreVisibility, which
caused issues that the insets returned from getSystemWindowInsets were
not the same as ones passed to setSystemWindowInsets. This CL won't
have that issue.

Bug: 409469172
Flag: com.android.window.flags.copy_compat_fields_of_window_insets
Test: atest FrameworksCoreTests:WindowInsetsTest
Change-Id: I0d8c08817543e5a2b6d4299be76c0b0505639009
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index b8d021d..532a927 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -1411,6 +1411,8 @@
         private final Rect[][] mTypeBoundingRectsMap;
         @NonNull
         private final Rect[][] mTypeMaxBoundingRectsMap;
+        private @InsetsType int mCompatInsetTypes = systemBars();
+        private boolean mCompatIgnoreVisibility;
         private boolean mSystemInsetsConsumed = true;
         private boolean mStableInsetsConsumed = true;
 
@@ -1453,6 +1455,10 @@
             mTypeInsetsMap = insets.mTypeInsetsMap.clone();
             mTypeMaxInsetsMap = insets.mTypeMaxInsetsMap.clone();
             mTypeVisibilityMap = insets.mTypeVisibilityMap.clone();
+            if (com.android.window.flags.Flags.copyCompatFieldsOfWindowInsets()) {
+                mCompatInsetTypes = insets.mCompatInsetsTypes;
+                mCompatIgnoreVisibility = insets.mCompatIgnoreVisibility;
+            }
             mSystemInsetsConsumed = insets.mSystemWindowInsetsConsumed;
             mStableInsetsConsumed = insets.mStableInsetsConsumed;
             mDisplayCutout = displayCutoutCopyConstructorArgument(insets);
@@ -1486,6 +1492,11 @@
         public Builder setSystemWindowInsets(@NonNull Insets systemWindowInsets) {
             Objects.requireNonNull(systemWindowInsets);
             assignCompatInsets(mTypeInsetsMap, systemWindowInsets.toRect());
+            if (com.android.window.flags.Flags.copyCompatFieldsOfWindowInsets()) {
+                // This should match the types used in assignCompatInsets.
+                mCompatInsetTypes = STATUS_BARS | NAVIGATION_BARS;
+                mCompatIgnoreVisibility = false;
+            }
             mSystemInsetsConsumed = false;
             return this;
         }
@@ -1828,7 +1839,7 @@
                     mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mTypeVisibilityMap,
                     mIsRound, mForceConsumingTypes, mForceConsumingOpaqueCaptionBar,
                     mSuppressScrimTypes, mDisplayCutout, mRoundedCorners, mPrivacyIndicatorBounds,
-                    mDisplayShape, systemBars(), false /* compatIgnoreVisibility */,
+                    mDisplayShape, mCompatInsetTypes, mCompatIgnoreVisibility,
                     mSystemInsetsConsumed ? null : mTypeBoundingRectsMap,
                     mStableInsetsConsumed ? null : mTypeMaxBoundingRectsMap,
                     mFrameWidth, mFrameHeight);
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 1ef482e..fa52f7a 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -57,6 +57,17 @@
 }
 
 flag {
+  name: "copy_compat_fields_of_window_insets"
+  namespace: "windowing_frontend"
+  description: "Copy mCompatInsetTypes and mCompatIgnoreVisibility from WindowInsets"
+  bug: "409469172"
+  is_fixed_read_only: true
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
   name: "close_to_square_config_includes_status_bar"
   namespace: "windowing_frontend"
   description: "On close to square display, when necessary, configuration includes status bar"
diff --git a/core/tests/coretests/src/android/view/WindowInsetsTest.java b/core/tests/coretests/src/android/view/WindowInsetsTest.java
index 860358c..791d892 100644
--- a/core/tests/coretests/src/android/view/WindowInsetsTest.java
+++ b/core/tests/coretests/src/android/view/WindowInsetsTest.java
@@ -21,6 +21,7 @@
 import static android.view.WindowInsets.Type.captionBar;
 import static android.view.WindowInsets.Type.displayCutout;
 import static android.view.WindowInsets.Type.ime;
+import static android.view.WindowInsets.Type.indexOf;
 import static android.view.WindowInsets.Type.navigationBars;
 import static android.view.WindowInsets.Type.statusBars;
 import static android.view.WindowInsets.Type.systemBars;
@@ -29,6 +30,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 
 import android.graphics.Insets;
 import android.graphics.Rect;
@@ -170,6 +172,64 @@
     }
 
     @Test
+    public void builder_copy_compatInsetTypes() {
+        assumeTrue(com.android.window.flags.Flags.copyCompatFieldsOfWindowInsets());
+        final Insets[] insets = new Insets[TYPES.length];
+        final Insets[] maxInsets = new Insets[TYPES.length];
+        final boolean[] visible = new boolean[TYPES.length];
+        final int compatInsetTypes = systemBars() | displayCutout() | ime();
+        final WindowInsets windowInsets = new WindowInsets(insets, maxInsets, visible, false, 0,
+                false, 0, null, null, null, DisplayShape.NONE, compatInsetTypes,
+                false /* compatIgnoreVisibility */, null, null, 0, 0);
+        final WindowInsets modified = new WindowInsets.Builder(windowInsets)
+                .setInsets(statusBars(), Insets.of(0, 10, 0, 0))
+                .setInsets(navigationBars(), Insets.of(0, 0, 20, 0))
+                .setInsets(displayCutout(), Insets.of(30, 0, 0, 0))
+                .setInsets(ime(), Insets.of(0, 0, 0, 40))
+                .build();
+        assertEquals(Insets.of(30, 10, 20, 40), modified.getSystemWindowInsets());
+    }
+
+    @Test
+    public void builder_copy_compatIgnoreVisibility() {
+        assumeTrue(com.android.window.flags.Flags.copyCompatFieldsOfWindowInsets());
+        final Insets[] insets = new Insets[TYPES.length];
+        final Insets[] maxInsets = new Insets[TYPES.length];
+        final boolean[] visible = new boolean[TYPES.length];
+        final int compatInsetTypes = systemBars() | displayCutout();
+        final WindowInsets windowInsets = new WindowInsets(insets, maxInsets, visible, false, 0,
+                false, 0, null, null, null, DisplayShape.NONE, compatInsetTypes,
+                true /* compatIgnoreVisibility */, null, null, 0, 0);
+        final WindowInsets modified = new WindowInsets.Builder(windowInsets)
+                .setInsetsIgnoringVisibility(statusBars(), Insets.of(0, 10, 0, 0))
+                .setInsetsIgnoringVisibility(navigationBars(), Insets.of(0, 0, 20, 0))
+                .setInsetsIgnoringVisibility(displayCutout(), Insets.of(30, 0, 0, 0))
+                .build();
+        assertEquals(Insets.of(30, 10, 20, 0), modified.getSystemWindowInsets());
+    }
+
+    @Test
+    public void builder_setSystemWindowInsets() {
+        assumeTrue(com.android.window.flags.Flags.copyCompatFieldsOfWindowInsets());
+        final Insets[] insets = new Insets[TYPES.length];
+        final Insets[] maxInsets = new Insets[TYPES.length];
+        final boolean[] visible = new boolean[TYPES.length];
+        final int compatInsetTypes = systemBars() | displayCutout() | ime();
+        maxInsets[indexOf(captionBar())] = Insets.of(0, 10, 0, 0);
+        maxInsets[indexOf(navigationBars())] = Insets.of(0, 0, 20, 0);
+        maxInsets[indexOf(displayCutout())] = Insets.of(30, 0, 0, 0);
+        insets[indexOf(ime())] = Insets.of(0, 0, 0, 40);
+        final WindowInsets windowInsets = new WindowInsets(insets, maxInsets, visible, false, 0,
+                false, 0, null, null, null, DisplayShape.NONE, compatInsetTypes,
+                true /* compatIgnoreVisibility */, null, null, 0, 0);
+        assertEquals(Insets.of(30, 10, 20, 40), windowInsets.getSystemWindowInsets());
+        final WindowInsets modified = new WindowInsets.Builder(windowInsets)
+                .setSystemWindowInsets(Insets.of(1, 2, 3, 4))
+                .build();
+        assertEquals(Insets.of(1, 2, 3, 4), modified.getSystemWindowInsets());
+    }
+
+    @Test
     public void testSetBoundingRectsInBuilder_noInsets_preservedInWindowInsets() {
         final List<Rect> rects = List.of(new Rect(0, 0, 50, 100));
         final WindowInsets insets =