Loading core/java/android/view/InsetsController.java +3 −4 Original line number Diff line number Diff line Loading @@ -22,8 +22,7 @@ import static android.internal.perfetto.protos.Insetscontroller.InsetsController import static android.view.InsetsSource.ID_IME; import static android.view.InsetsSource.ID_IME_CAPTION_BAR; import static android.view.ViewProtoLogGroups.IME_INSETS_CONTROLLER; import static android.view.WindowInsets.Type.FIRST; import static android.view.WindowInsets.Type.LAST; import static android.view.WindowInsets.Type.TYPES; import static android.view.WindowInsets.Type.all; import static android.view.WindowInsets.Type.captionBar; import static android.view.WindowInsets.Type.ime; Loading Loading @@ -1204,7 +1203,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation int typesReady = 0; final boolean imeVisible = mState.isSourceOrDefaultVisible( mImeSourceConsumer.getId(), ime()); for (@InsetsType int type = FIRST; type <= LAST; type = type << 1) { for (@InsetsType int type : TYPES) { if ((types & type) == 0) { continue; } Loading Loading @@ -1287,7 +1286,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @InsetsType int typesReady = 0; for (@InsetsType int type = FIRST; type <= LAST; type = type << 1) { for (@InsetsType int type : TYPES) { if ((types & type) == 0) { continue; } Loading core/java/android/view/InsetsState.java +6 −6 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import static android.internal.perfetto.protos.Insetsstate.InsetsStateProto.DISP import static android.internal.perfetto.protos.Insetsstate.InsetsStateProto.DISPLAY_FRAME; import static android.internal.perfetto.protos.Insetsstate.InsetsStateProto.SOURCES; import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE; import static android.view.WindowInsets.Type.SIZE; import static android.view.WindowInsets.Type.TYPES; import static android.view.WindowInsets.Type.captionBar; import static android.view.WindowInsets.Type.defaultCompatible; import static android.view.WindowInsets.Type.displayCutout; Loading Loading @@ -142,9 +142,9 @@ public class InsetsState implements Parcelable { int legacySoftInputMode, int legacyWindowFlags, int legacySystemUiFlags, @WindowType int windowType, @ActivityType int activityType, @Nullable @InternalInsetsSide SparseIntArray idSideMap) { final Insets[] typeInsetsMap = new Insets[SIZE]; final Insets[] typeMaxInsetsMap = new Insets[SIZE]; final boolean[] typeVisibilityMap = new boolean[SIZE]; final Insets[] typeInsetsMap = new Insets[TYPES.length]; final Insets[] typeMaxInsetsMap = new Insets[TYPES.length]; final boolean[] typeVisibilityMap = new boolean[TYPES.length]; final Rect relativeFrame = new Rect(frame); final Rect relativeFrameMax = new Rect(frame); @InsetsType Loading @@ -152,8 +152,8 @@ public class InsetsState implements Parcelable { boolean forceConsumingOpaqueCaptionBar = false; @InsetsType int suppressScrimTypes = 0; final Rect[][] typeBoundingRectsMap = new Rect[SIZE][]; final Rect[][] typeMaxBoundingRectsMap = new Rect[SIZE][]; final Rect[][] typeBoundingRectsMap = new Rect[TYPES.length][]; final Rect[][] typeMaxBoundingRectsMap = new Rect[TYPES.length][]; for (int i = mSources.size() - 1; i >= 0; i--) { final InsetsSource source = mSources.valueAt(i); @InsetsType Loading core/java/android/view/WindowInsets.java +87 −63 Original line number Diff line number Diff line Loading @@ -19,15 +19,13 @@ package android.view; import static android.view.Surface.ROTATION_0; import static android.view.WindowInsets.Type.DISPLAY_CUTOUT; import static android.view.WindowInsets.Type.FIRST; import static android.view.WindowInsets.Type.IME; import static android.view.WindowInsets.Type.LAST; import static android.view.WindowInsets.Type.MANDATORY_SYSTEM_GESTURES; import static android.view.WindowInsets.Type.NAVIGATION_BARS; import static android.view.WindowInsets.Type.SIZE; import static android.view.WindowInsets.Type.STATUS_BARS; import static android.view.WindowInsets.Type.SYSTEM_GESTURES; import static android.view.WindowInsets.Type.TAPPABLE_ELEMENT; import static android.view.WindowInsets.Type.TYPES; import static android.view.WindowInsets.Type.all; import static android.view.WindowInsets.Type.defaultCompatible; import static android.view.WindowInsets.Type.displayCutout; Loading Loading @@ -173,12 +171,12 @@ public final class WindowInsets { int frameWidth, int frameHeight) { mSystemWindowInsetsConsumed = typeInsetsMap == null; mTypeInsetsMap = mSystemWindowInsetsConsumed ? new Insets[SIZE] ? new Insets[TYPES.length] : typeInsetsMap.clone(); mStableInsetsConsumed = typeMaxInsetsMap == null; mTypeMaxInsetsMap = mStableInsetsConsumed ? new Insets[SIZE] ? new Insets[TYPES.length] : typeMaxInsetsMap.clone(); mTypeVisibilityMap = typeVisibilityMap; Loading @@ -197,10 +195,10 @@ public final class WindowInsets { mPrivacyIndicatorBounds = privacyIndicatorBounds; mDisplayShape = displayShape; mTypeBoundingRectsMap = (mSystemWindowInsetsConsumed || typeBoundingRectsMap == null) ? new Rect[SIZE][] ? new Rect[TYPES.length][] : typeBoundingRectsMap.clone(); mTypeMaxBoundingRectsMap = (mStableInsetsConsumed || typeMaxBoundingRectsMap == null) ? new Rect[SIZE][] ? new Rect[TYPES.length][] : typeMaxBoundingRectsMap.clone(); mFrameWidth = frameWidth; mFrameHeight = frameHeight; Loading Loading @@ -248,11 +246,11 @@ public final class WindowInsets { @NonNull static Insets getInsets(@NonNull Insets[] typeInsetsMap, @InsetsType int typeMask) { Insets result = null; for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } Insets insets = typeInsetsMap[indexOf(i)]; Insets insets = typeInsetsMap[indexOf(type)]; if (insets == null) { continue; } Loading @@ -270,20 +268,20 @@ public final class WindowInsets { */ private static void setInsets(@NonNull Insets[] typeInsetsMap, @InsetsType int typeMask, @NonNull Insets insets) { for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } typeInsetsMap[indexOf(i)] = insets; typeInsetsMap[indexOf(type)] = insets; } } /** @hide */ @UnsupportedAppUsage public WindowInsets(@Nullable Rect systemWindowInsets) { this(createCompatTypeMap(systemWindowInsets), null, new boolean[SIZE], false, 0, false, 0, null, null, null, null, defaultCompatible(), false /* compatIgnoreVisibility */, new Rect[SIZE][], null, 0, 0); this(createCompatTypeMap(systemWindowInsets), null, new boolean[TYPES.length], false, 0, false, 0, null, null, null, null, defaultCompatible(), false /* compatIgnoreVisibility */, new Rect[TYPES.length][], null, 0, 0); } /** Loading @@ -299,7 +297,7 @@ public final class WindowInsets { if (insets == null) { return null; } Insets[] typeInsetsMap = new Insets[SIZE]; Insets[] typeInsetsMap = new Insets[TYPES.length]; assignCompatInsets(typeInsetsMap, insets); return typeInsetsMap; } Loading @@ -320,12 +318,12 @@ public final class WindowInsets { @VisibleForTesting @NonNull private static boolean[] createCompatVisibilityMap(@Nullable Insets[] typeInsetsMap) { boolean[] typeVisibilityMap = new boolean[SIZE]; final boolean[] typeVisibilityMap = new boolean[TYPES.length]; if (typeInsetsMap == null) { return typeVisibilityMap; } for (int i = FIRST; i <= LAST; i = i << 1) { int index = indexOf(i); for (@InsetsType int type : TYPES) { final int index = indexOf(type); if (!Insets.NONE.equals(typeInsetsMap[index])) { typeVisibilityMap[index] = true; } Loading Loading @@ -424,11 +422,11 @@ public final class WindowInsets { * visible on screen. */ public boolean isVisible(@InsetsType int typeMask) { for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } if (!mTypeVisibilityMap[indexOf(i)]) { if (!mTypeVisibilityMap[indexOf(type)]) { return false; } } Loading Loading @@ -601,11 +599,11 @@ public final class WindowInsets { private List<Rect> getBoundingRects(@NonNull Rect[][] typeBoundingRectsMap, @InsetsType int typeMask) { Rect[] allRects = null; for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } final Rect[] rects = typeBoundingRectsMap[indexOf(i)]; final Rect[] rects = typeBoundingRectsMap[indexOf(type)]; if (rects == null) { continue; } Loading Loading @@ -1069,19 +1067,20 @@ public final class WindowInsets { @Override public String toString() { StringBuilder result = new StringBuilder("WindowInsets{\n "); for (int i = 0; i < SIZE; i++) { Insets insets = mTypeInsetsMap[i]; Insets maxInsets = mTypeMaxInsetsMap[i]; boolean visible = mTypeVisibilityMap[i]; final var result = new StringBuilder("WindowInsets{\n "); for (@InsetsType int type : TYPES) { final int index = indexOf(type); final Insets insets = mTypeInsetsMap[index]; final Insets maxInsets = mTypeMaxInsetsMap[index]; final boolean visible = mTypeVisibilityMap[index]; if (!Insets.NONE.equals(insets) || !Insets.NONE.equals(maxInsets) || visible) { result.append(Type.toString(1 << i)).append("=").append(insets) result.append(Type.toString(type)).append("=").append(insets) .append(" max=").append(maxInsets) .append(" vis=").append(visible) .append(" boundingRects=") .append(Arrays.toString(mTypeBoundingRectsMap[i])) .append(Arrays.toString(mTypeBoundingRectsMap[index])) .append(" maxBoundingRects=") .append(Arrays.toString(mTypeMaxBoundingRectsMap[i])) .append(Arrays.toString(mTypeMaxBoundingRectsMap[index])) .append("\n "); } } Loading Loading @@ -1295,8 +1294,9 @@ public final class WindowInsets { private static Insets[] insetInsets( @NonNull Insets[] typeInsetsMap, int left, int top, int right, int bottom) { boolean cloned = false; for (int i = 0; i < SIZE; i++) { Insets insets = typeInsetsMap[i]; for (@InsetsType int type : TYPES) { final int index = indexOf(type); final Insets insets = typeInsetsMap[index]; if (insets == null) { continue; } Loading @@ -1306,7 +1306,7 @@ public final class WindowInsets { typeInsetsMap = typeInsetsMap.clone(); cloned = true; } typeInsetsMap[i] = insetInsets; typeInsetsMap[index] = insetInsets; } } return typeInsetsMap; Loading @@ -1333,8 +1333,9 @@ public final class WindowInsets { return typeBoundingRectsMap; } boolean cloned = false; for (int i = 0; i < SIZE; i++) { final Rect[] boundingRects = typeBoundingRectsMap[i]; for (@InsetsType int type : TYPES) { final int index = indexOf(type); final Rect[] boundingRects = typeBoundingRectsMap[index]; if (boundingRects == null) { continue; } Loading @@ -1345,7 +1346,7 @@ public final class WindowInsets { typeBoundingRectsMap = typeBoundingRectsMap.clone(); cloned = true; } typeBoundingRectsMap[i] = insetBoundingRects; typeBoundingRectsMap[index] = insetBoundingRects; } } return typeBoundingRectsMap; Loading Loading @@ -1440,11 +1441,11 @@ public final class WindowInsets { * Creates a builder where all insets are initially consumed. */ public Builder() { mTypeInsetsMap = new Insets[SIZE]; mTypeMaxInsetsMap = new Insets[SIZE]; mTypeVisibilityMap = new boolean[SIZE]; mTypeBoundingRectsMap = new Rect[SIZE][]; mTypeMaxBoundingRectsMap = new Rect[SIZE][]; mTypeInsetsMap = new Insets[TYPES.length]; mTypeMaxInsetsMap = new Insets[TYPES.length]; mTypeVisibilityMap = new boolean[TYPES.length]; mTypeBoundingRectsMap = new Rect[TYPES.length][]; mTypeMaxBoundingRectsMap = new Rect[TYPES.length][]; mCompatInsetTypes = defaultCompatible(); mCompatIgnoreVisibility = false; } Loading Loading @@ -1624,11 +1625,11 @@ public final class WindowInsets { */ @NonNull public Builder setVisible(@InsetsType int typeMask, boolean visible) { for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } mTypeVisibilityMap[indexOf(i)] = visible; mTypeVisibilityMap[indexOf(type)] = visible; } return this; } Loading Loading @@ -1770,11 +1771,11 @@ public final class WindowInsets { @FlaggedApi(Flags.FLAG_CUSTOMIZABLE_WINDOW_HEADERS) @NonNull public Builder setBoundingRects(@InsetsType int typeMask, @NonNull List<Rect> rects) { for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } mTypeBoundingRectsMap[indexOf(i)] = rects.toArray(new Rect[0]); mTypeBoundingRectsMap[indexOf(type)] = rects.toArray(new Rect[0]); } mSystemInsetsConsumed = false; return this; Loading @@ -1799,11 +1800,11 @@ public final class WindowInsets { if (typeMask == IME) { throw new IllegalArgumentException("Maximum bounding rects not available for IME"); } for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } mTypeMaxBoundingRectsMap[indexOf(i)] = rects.toArray(new Rect[0]); mTypeMaxBoundingRectsMap[indexOf(type)] = rects.toArray(new Rect[0]); } mStableInsetsConsumed = false; return this; Loading Loading @@ -1856,18 +1857,42 @@ public final class WindowInsets { static final int TAPPABLE_ELEMENT = 1 << 6; static final int DISPLAY_CUTOUT = 1 << 7; static final int SYSTEM_OVERLAYS = 1 << 8; @InsetsType static final int FIRST = STATUS_BARS; @InsetsType static final int LAST = SYSTEM_OVERLAYS; static final int SIZE = 9; /** * The array of all insets types. * * @hide */ @NonNull public static final int[] TYPES = { STATUS_BARS, NAVIGATION_BARS, CAPTION_BAR, IME, SYSTEM_GESTURES, MANDATORY_SYSTEM_GESTURES, TAPPABLE_ELEMENT, DISPLAY_CUTOUT, SYSTEM_OVERLAYS, }; /** The bitmask of all insets types combined. */ @InsetsType static final int ALL = ((1 << SIZE) - 1); static final int ALL = STATUS_BARS | NAVIGATION_BARS | CAPTION_BAR | IME | SYSTEM_GESTURES | MANDATORY_SYSTEM_GESTURES | TAPPABLE_ELEMENT | DISPLAY_CUTOUT | SYSTEM_OVERLAYS; /** The bitmask of default visible insets types. */ @InsetsType static final int DEFAULT_VISIBLE = ALL & ~IME; static int indexOf(@InsetsType int type) { /** * Gets the index of the bit corresponding to the given type. * * @param type the type to get the bit index of. * * @hide */ public static int indexOf(@InsetsType int type) { switch (type) { case STATUS_BARS: return 0; Loading @@ -1888,8 +1913,7 @@ public final class WindowInsets { case SYSTEM_OVERLAYS: return 8; default: throw new IllegalArgumentException("type needs to be >= FIRST and <= LAST," + " type=" + type); throw new IllegalArgumentException("Unknown insets type: " + type); } } Loading core/tests/coretests/src/android/view/InsetsSourceTest.java +6 −7 Original line number Diff line number Diff line Loading @@ -17,9 +17,7 @@ package android.view; import static android.view.InsetsSource.ID_IME_CAPTION_BAR; import static android.view.WindowInsets.Type.FIRST; import static android.view.WindowInsets.Type.LAST; import static android.view.WindowInsets.Type.SIZE; import static android.view.WindowInsets.Type.TYPES; import static android.view.WindowInsets.Type.captionBar; import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.navigationBars; Loading @@ -31,6 +29,7 @@ import android.graphics.Insets; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.util.SparseArray; import android.view.WindowInsets.Type.InsetsType; import androidx.test.ext.junit.runners.AndroidJUnit4; Loading Loading @@ -367,11 +366,11 @@ public class InsetsSourceTest { @Test public void testCreateId() { final int numSourcePerType = 2048; final int numTotalSources = SIZE * numSourcePerType; final int numTotalSources = TYPES.length * numSourcePerType; final SparseArray<InsetsSource> sources = new SparseArray<>(numTotalSources); final Object owner = new Object(); for (int index = 0; index < numSourcePerType; index++) { for (int type = FIRST; type <= LAST; type = type << 1) { for (@InsetsType int type : TYPES) { final int id = InsetsSource.createId(owner, index, type); assertNull("Must not create the same ID.", sources.get(id)); sources.append(id, new InsetsSource(id, type)); Loading @@ -385,7 +384,7 @@ public class InsetsSourceTest { // Here doesn't iterate all the owners, or the test cannot be done before timeout. for (int owner = 0; owner < 100; owner++) { for (int index = 0; index < 2048; index++) { for (int type = FIRST; type <= LAST; type = type << 1) { for (@InsetsType int type : TYPES) { final int id = InsetsSource.createId(owner, index, type); final int indexFromId = InsetsSource.getIndex(id); assertEquals("index and indexFromId must be the same. id=" + id Loading @@ -403,7 +402,7 @@ public class InsetsSourceTest { // Here doesn't iterate all the owners, or the test cannot be done before timeout. for (int owner = 0; owner < 100; owner++) { for (int index = 0; index < 2048; index++) { for (int type = FIRST; type <= LAST; type = type << 1) { for (@InsetsType int type : TYPES) { final int id = InsetsSource.createId(owner, index, type); final int typeFromId = InsetsSource.getType(id); assertEquals("type and typeFromId must be the same. id=" + id Loading core/tests/coretests/src/android/view/WindowInsetsTest.java +103 −10 Original line number Diff line number Diff line Loading @@ -16,7 +16,8 @@ package android.view; import static android.view.WindowInsets.Type.SIZE; import static android.view.WindowInsets.Type.ALL; import static android.view.WindowInsets.Type.TYPES; import static android.view.WindowInsets.Type.captionBar; import static android.view.WindowInsets.Type.displayCutout; import static android.view.WindowInsets.Type.ime; Loading @@ -25,11 +26,14 @@ import static android.view.WindowInsets.Type.statusBars; import static android.view.WindowInsets.Type.systemBars; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import android.graphics.Insets; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.view.WindowInsets.Type.InsetsType; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; Loading @@ -44,6 +48,95 @@ import java.util.List; @Presubmit public class WindowInsetsTest { /** * Verifies that all the values in {@link WindowInsets.Type#TYPES} are included in * {@link WindowInsets.Type#ALL}. */ @Test public void testTypesInAll() { int combinedTypes = 0; for (@InsetsType int type : TYPES) { assertTrue("type in TYPES should be included in ALL", (type & ALL) != 0); combinedTypes |= type; } assertEquals("ALL should match bitmask of combined types", ALL, combinedTypes); } /** * Verifies that all the values in {@link WindowInsets.Type#ALL} are included in * {@link WindowInsets.Type#TYPES}. */ @Test public void testAllInTypes() { for (int index = 0; index < Integer.SIZE; index++) { final int type = 1 << index; if ((type & WindowInsets.Type.ALL) != 0) { assertTrue("index of bit in ALL should be less than number of TYPES", index < TYPES.length); assertEquals("type in ALL should be included in TYPES", type, TYPES[index]); } } } /** * Verifies that all the values in {@link WindowInsets.Type#TYPES} are included in * {@link WindowInsets.Type#indexOf}. */ @Test public void testTypesInIndexOf() { for (@InsetsType int type : TYPES) { assertEquals("type should match", type, TYPES[WindowInsets.Type.indexOf(type)]); } assertThrows(IllegalArgumentException.class, () -> WindowInsets.Type.indexOf(-1)); } /** * Verifies that all the values returned by {@link WindowInsets.Type#indexOf} are included in * {@link WindowInsets.Type#TYPES}. */ @Test public void testIndexOfInTypes() { for (int i = 0; i < Integer.SIZE; i++) { final int type = 1 << i; try { final int index = WindowInsets.Type.indexOf(type); assertTrue("index should be non-negative", index >= 0); assertTrue("index should be less than number of TYPES", index < TYPES.length); assertEquals(type, TYPES[index]); } catch (IllegalArgumentException e) { // ignore undefined indexOf case, handled through testTypesInIndexOf above. } } } /** * Verifies that all the values in {@link WindowInsets.Type#TYPES} are included in * {@link WindowInsets.Type#toString}. */ @Test public void testTypesInToString() { for (@InsetsType int type : TYPES) { assertFalse("type toString should not be empty", WindowInsets.Type.toString(type).isEmpty()); } assertTrue("invalid type toString should be empty", WindowInsets.Type.toString(0).isEmpty()); } /** * Verifies that all the values accepted by {@link WindowInsets.Type#toString} are included in * {@link WindowInsets.Type#TYPES}. */ @Test public void testToStringInTypes() { for (int i = 0; i < Integer.SIZE; i++) { final int type = 1 << i; if (!WindowInsets.Type.toString(type).isEmpty()) { assertEquals("type should match", type, TYPES[i]); } } } @Test public void systemWindowInsets_afterConsuming_isConsumed() { assertTrue(new WindowInsets(WindowInsets.createCompatTypeMap(new Rect(1, 2, 3, 4)), null, Loading @@ -65,9 +158,9 @@ public class WindowInsetsTest { @Test public void compatInsets_layoutStable() { Insets[] insets = new Insets[SIZE]; Insets[] maxInsets = new Insets[SIZE]; boolean[] visible = new boolean[SIZE]; Insets[] insets = new Insets[TYPES.length]; Insets[] maxInsets = new Insets[TYPES.length]; boolean[] visible = new boolean[TYPES.length]; WindowInsets.assignCompatInsets(maxInsets, new Rect(0, 10, 0, 0)); WindowInsets.assignCompatInsets(insets, new Rect(0, 0, 0, 0)); WindowInsets windowInsets = new WindowInsets(insets, maxInsets, visible, false, 0, Loading @@ -78,9 +171,9 @@ public class WindowInsetsTest { @Test public void builder_copy_compatInsetTypes() { final Insets[] insets = new Insets[SIZE]; final Insets[] maxInsets = new Insets[SIZE]; final boolean[] visible = new boolean[SIZE]; 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, Loading @@ -96,9 +189,9 @@ public class WindowInsetsTest { @Test public void builder_copy_compatIgnoreVisibility() { final Insets[] insets = new Insets[SIZE]; final Insets[] maxInsets = new Insets[SIZE]; final boolean[] visible = new boolean[SIZE]; 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, Loading Loading
core/java/android/view/InsetsController.java +3 −4 Original line number Diff line number Diff line Loading @@ -22,8 +22,7 @@ import static android.internal.perfetto.protos.Insetscontroller.InsetsController import static android.view.InsetsSource.ID_IME; import static android.view.InsetsSource.ID_IME_CAPTION_BAR; import static android.view.ViewProtoLogGroups.IME_INSETS_CONTROLLER; import static android.view.WindowInsets.Type.FIRST; import static android.view.WindowInsets.Type.LAST; import static android.view.WindowInsets.Type.TYPES; import static android.view.WindowInsets.Type.all; import static android.view.WindowInsets.Type.captionBar; import static android.view.WindowInsets.Type.ime; Loading Loading @@ -1204,7 +1203,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation int typesReady = 0; final boolean imeVisible = mState.isSourceOrDefaultVisible( mImeSourceConsumer.getId(), ime()); for (@InsetsType int type = FIRST; type <= LAST; type = type << 1) { for (@InsetsType int type : TYPES) { if ((types & type) == 0) { continue; } Loading Loading @@ -1287,7 +1286,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @InsetsType int typesReady = 0; for (@InsetsType int type = FIRST; type <= LAST; type = type << 1) { for (@InsetsType int type : TYPES) { if ((types & type) == 0) { continue; } Loading
core/java/android/view/InsetsState.java +6 −6 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import static android.internal.perfetto.protos.Insetsstate.InsetsStateProto.DISP import static android.internal.perfetto.protos.Insetsstate.InsetsStateProto.DISPLAY_FRAME; import static android.internal.perfetto.protos.Insetsstate.InsetsStateProto.SOURCES; import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE; import static android.view.WindowInsets.Type.SIZE; import static android.view.WindowInsets.Type.TYPES; import static android.view.WindowInsets.Type.captionBar; import static android.view.WindowInsets.Type.defaultCompatible; import static android.view.WindowInsets.Type.displayCutout; Loading Loading @@ -142,9 +142,9 @@ public class InsetsState implements Parcelable { int legacySoftInputMode, int legacyWindowFlags, int legacySystemUiFlags, @WindowType int windowType, @ActivityType int activityType, @Nullable @InternalInsetsSide SparseIntArray idSideMap) { final Insets[] typeInsetsMap = new Insets[SIZE]; final Insets[] typeMaxInsetsMap = new Insets[SIZE]; final boolean[] typeVisibilityMap = new boolean[SIZE]; final Insets[] typeInsetsMap = new Insets[TYPES.length]; final Insets[] typeMaxInsetsMap = new Insets[TYPES.length]; final boolean[] typeVisibilityMap = new boolean[TYPES.length]; final Rect relativeFrame = new Rect(frame); final Rect relativeFrameMax = new Rect(frame); @InsetsType Loading @@ -152,8 +152,8 @@ public class InsetsState implements Parcelable { boolean forceConsumingOpaqueCaptionBar = false; @InsetsType int suppressScrimTypes = 0; final Rect[][] typeBoundingRectsMap = new Rect[SIZE][]; final Rect[][] typeMaxBoundingRectsMap = new Rect[SIZE][]; final Rect[][] typeBoundingRectsMap = new Rect[TYPES.length][]; final Rect[][] typeMaxBoundingRectsMap = new Rect[TYPES.length][]; for (int i = mSources.size() - 1; i >= 0; i--) { final InsetsSource source = mSources.valueAt(i); @InsetsType Loading
core/java/android/view/WindowInsets.java +87 −63 Original line number Diff line number Diff line Loading @@ -19,15 +19,13 @@ package android.view; import static android.view.Surface.ROTATION_0; import static android.view.WindowInsets.Type.DISPLAY_CUTOUT; import static android.view.WindowInsets.Type.FIRST; import static android.view.WindowInsets.Type.IME; import static android.view.WindowInsets.Type.LAST; import static android.view.WindowInsets.Type.MANDATORY_SYSTEM_GESTURES; import static android.view.WindowInsets.Type.NAVIGATION_BARS; import static android.view.WindowInsets.Type.SIZE; import static android.view.WindowInsets.Type.STATUS_BARS; import static android.view.WindowInsets.Type.SYSTEM_GESTURES; import static android.view.WindowInsets.Type.TAPPABLE_ELEMENT; import static android.view.WindowInsets.Type.TYPES; import static android.view.WindowInsets.Type.all; import static android.view.WindowInsets.Type.defaultCompatible; import static android.view.WindowInsets.Type.displayCutout; Loading Loading @@ -173,12 +171,12 @@ public final class WindowInsets { int frameWidth, int frameHeight) { mSystemWindowInsetsConsumed = typeInsetsMap == null; mTypeInsetsMap = mSystemWindowInsetsConsumed ? new Insets[SIZE] ? new Insets[TYPES.length] : typeInsetsMap.clone(); mStableInsetsConsumed = typeMaxInsetsMap == null; mTypeMaxInsetsMap = mStableInsetsConsumed ? new Insets[SIZE] ? new Insets[TYPES.length] : typeMaxInsetsMap.clone(); mTypeVisibilityMap = typeVisibilityMap; Loading @@ -197,10 +195,10 @@ public final class WindowInsets { mPrivacyIndicatorBounds = privacyIndicatorBounds; mDisplayShape = displayShape; mTypeBoundingRectsMap = (mSystemWindowInsetsConsumed || typeBoundingRectsMap == null) ? new Rect[SIZE][] ? new Rect[TYPES.length][] : typeBoundingRectsMap.clone(); mTypeMaxBoundingRectsMap = (mStableInsetsConsumed || typeMaxBoundingRectsMap == null) ? new Rect[SIZE][] ? new Rect[TYPES.length][] : typeMaxBoundingRectsMap.clone(); mFrameWidth = frameWidth; mFrameHeight = frameHeight; Loading Loading @@ -248,11 +246,11 @@ public final class WindowInsets { @NonNull static Insets getInsets(@NonNull Insets[] typeInsetsMap, @InsetsType int typeMask) { Insets result = null; for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } Insets insets = typeInsetsMap[indexOf(i)]; Insets insets = typeInsetsMap[indexOf(type)]; if (insets == null) { continue; } Loading @@ -270,20 +268,20 @@ public final class WindowInsets { */ private static void setInsets(@NonNull Insets[] typeInsetsMap, @InsetsType int typeMask, @NonNull Insets insets) { for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } typeInsetsMap[indexOf(i)] = insets; typeInsetsMap[indexOf(type)] = insets; } } /** @hide */ @UnsupportedAppUsage public WindowInsets(@Nullable Rect systemWindowInsets) { this(createCompatTypeMap(systemWindowInsets), null, new boolean[SIZE], false, 0, false, 0, null, null, null, null, defaultCompatible(), false /* compatIgnoreVisibility */, new Rect[SIZE][], null, 0, 0); this(createCompatTypeMap(systemWindowInsets), null, new boolean[TYPES.length], false, 0, false, 0, null, null, null, null, defaultCompatible(), false /* compatIgnoreVisibility */, new Rect[TYPES.length][], null, 0, 0); } /** Loading @@ -299,7 +297,7 @@ public final class WindowInsets { if (insets == null) { return null; } Insets[] typeInsetsMap = new Insets[SIZE]; Insets[] typeInsetsMap = new Insets[TYPES.length]; assignCompatInsets(typeInsetsMap, insets); return typeInsetsMap; } Loading @@ -320,12 +318,12 @@ public final class WindowInsets { @VisibleForTesting @NonNull private static boolean[] createCompatVisibilityMap(@Nullable Insets[] typeInsetsMap) { boolean[] typeVisibilityMap = new boolean[SIZE]; final boolean[] typeVisibilityMap = new boolean[TYPES.length]; if (typeInsetsMap == null) { return typeVisibilityMap; } for (int i = FIRST; i <= LAST; i = i << 1) { int index = indexOf(i); for (@InsetsType int type : TYPES) { final int index = indexOf(type); if (!Insets.NONE.equals(typeInsetsMap[index])) { typeVisibilityMap[index] = true; } Loading Loading @@ -424,11 +422,11 @@ public final class WindowInsets { * visible on screen. */ public boolean isVisible(@InsetsType int typeMask) { for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } if (!mTypeVisibilityMap[indexOf(i)]) { if (!mTypeVisibilityMap[indexOf(type)]) { return false; } } Loading Loading @@ -601,11 +599,11 @@ public final class WindowInsets { private List<Rect> getBoundingRects(@NonNull Rect[][] typeBoundingRectsMap, @InsetsType int typeMask) { Rect[] allRects = null; for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } final Rect[] rects = typeBoundingRectsMap[indexOf(i)]; final Rect[] rects = typeBoundingRectsMap[indexOf(type)]; if (rects == null) { continue; } Loading Loading @@ -1069,19 +1067,20 @@ public final class WindowInsets { @Override public String toString() { StringBuilder result = new StringBuilder("WindowInsets{\n "); for (int i = 0; i < SIZE; i++) { Insets insets = mTypeInsetsMap[i]; Insets maxInsets = mTypeMaxInsetsMap[i]; boolean visible = mTypeVisibilityMap[i]; final var result = new StringBuilder("WindowInsets{\n "); for (@InsetsType int type : TYPES) { final int index = indexOf(type); final Insets insets = mTypeInsetsMap[index]; final Insets maxInsets = mTypeMaxInsetsMap[index]; final boolean visible = mTypeVisibilityMap[index]; if (!Insets.NONE.equals(insets) || !Insets.NONE.equals(maxInsets) || visible) { result.append(Type.toString(1 << i)).append("=").append(insets) result.append(Type.toString(type)).append("=").append(insets) .append(" max=").append(maxInsets) .append(" vis=").append(visible) .append(" boundingRects=") .append(Arrays.toString(mTypeBoundingRectsMap[i])) .append(Arrays.toString(mTypeBoundingRectsMap[index])) .append(" maxBoundingRects=") .append(Arrays.toString(mTypeMaxBoundingRectsMap[i])) .append(Arrays.toString(mTypeMaxBoundingRectsMap[index])) .append("\n "); } } Loading Loading @@ -1295,8 +1294,9 @@ public final class WindowInsets { private static Insets[] insetInsets( @NonNull Insets[] typeInsetsMap, int left, int top, int right, int bottom) { boolean cloned = false; for (int i = 0; i < SIZE; i++) { Insets insets = typeInsetsMap[i]; for (@InsetsType int type : TYPES) { final int index = indexOf(type); final Insets insets = typeInsetsMap[index]; if (insets == null) { continue; } Loading @@ -1306,7 +1306,7 @@ public final class WindowInsets { typeInsetsMap = typeInsetsMap.clone(); cloned = true; } typeInsetsMap[i] = insetInsets; typeInsetsMap[index] = insetInsets; } } return typeInsetsMap; Loading @@ -1333,8 +1333,9 @@ public final class WindowInsets { return typeBoundingRectsMap; } boolean cloned = false; for (int i = 0; i < SIZE; i++) { final Rect[] boundingRects = typeBoundingRectsMap[i]; for (@InsetsType int type : TYPES) { final int index = indexOf(type); final Rect[] boundingRects = typeBoundingRectsMap[index]; if (boundingRects == null) { continue; } Loading @@ -1345,7 +1346,7 @@ public final class WindowInsets { typeBoundingRectsMap = typeBoundingRectsMap.clone(); cloned = true; } typeBoundingRectsMap[i] = insetBoundingRects; typeBoundingRectsMap[index] = insetBoundingRects; } } return typeBoundingRectsMap; Loading Loading @@ -1440,11 +1441,11 @@ public final class WindowInsets { * Creates a builder where all insets are initially consumed. */ public Builder() { mTypeInsetsMap = new Insets[SIZE]; mTypeMaxInsetsMap = new Insets[SIZE]; mTypeVisibilityMap = new boolean[SIZE]; mTypeBoundingRectsMap = new Rect[SIZE][]; mTypeMaxBoundingRectsMap = new Rect[SIZE][]; mTypeInsetsMap = new Insets[TYPES.length]; mTypeMaxInsetsMap = new Insets[TYPES.length]; mTypeVisibilityMap = new boolean[TYPES.length]; mTypeBoundingRectsMap = new Rect[TYPES.length][]; mTypeMaxBoundingRectsMap = new Rect[TYPES.length][]; mCompatInsetTypes = defaultCompatible(); mCompatIgnoreVisibility = false; } Loading Loading @@ -1624,11 +1625,11 @@ public final class WindowInsets { */ @NonNull public Builder setVisible(@InsetsType int typeMask, boolean visible) { for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } mTypeVisibilityMap[indexOf(i)] = visible; mTypeVisibilityMap[indexOf(type)] = visible; } return this; } Loading Loading @@ -1770,11 +1771,11 @@ public final class WindowInsets { @FlaggedApi(Flags.FLAG_CUSTOMIZABLE_WINDOW_HEADERS) @NonNull public Builder setBoundingRects(@InsetsType int typeMask, @NonNull List<Rect> rects) { for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } mTypeBoundingRectsMap[indexOf(i)] = rects.toArray(new Rect[0]); mTypeBoundingRectsMap[indexOf(type)] = rects.toArray(new Rect[0]); } mSystemInsetsConsumed = false; return this; Loading @@ -1799,11 +1800,11 @@ public final class WindowInsets { if (typeMask == IME) { throw new IllegalArgumentException("Maximum bounding rects not available for IME"); } for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { for (@InsetsType int type : TYPES) { if ((typeMask & type) == 0) { continue; } mTypeMaxBoundingRectsMap[indexOf(i)] = rects.toArray(new Rect[0]); mTypeMaxBoundingRectsMap[indexOf(type)] = rects.toArray(new Rect[0]); } mStableInsetsConsumed = false; return this; Loading Loading @@ -1856,18 +1857,42 @@ public final class WindowInsets { static final int TAPPABLE_ELEMENT = 1 << 6; static final int DISPLAY_CUTOUT = 1 << 7; static final int SYSTEM_OVERLAYS = 1 << 8; @InsetsType static final int FIRST = STATUS_BARS; @InsetsType static final int LAST = SYSTEM_OVERLAYS; static final int SIZE = 9; /** * The array of all insets types. * * @hide */ @NonNull public static final int[] TYPES = { STATUS_BARS, NAVIGATION_BARS, CAPTION_BAR, IME, SYSTEM_GESTURES, MANDATORY_SYSTEM_GESTURES, TAPPABLE_ELEMENT, DISPLAY_CUTOUT, SYSTEM_OVERLAYS, }; /** The bitmask of all insets types combined. */ @InsetsType static final int ALL = ((1 << SIZE) - 1); static final int ALL = STATUS_BARS | NAVIGATION_BARS | CAPTION_BAR | IME | SYSTEM_GESTURES | MANDATORY_SYSTEM_GESTURES | TAPPABLE_ELEMENT | DISPLAY_CUTOUT | SYSTEM_OVERLAYS; /** The bitmask of default visible insets types. */ @InsetsType static final int DEFAULT_VISIBLE = ALL & ~IME; static int indexOf(@InsetsType int type) { /** * Gets the index of the bit corresponding to the given type. * * @param type the type to get the bit index of. * * @hide */ public static int indexOf(@InsetsType int type) { switch (type) { case STATUS_BARS: return 0; Loading @@ -1888,8 +1913,7 @@ public final class WindowInsets { case SYSTEM_OVERLAYS: return 8; default: throw new IllegalArgumentException("type needs to be >= FIRST and <= LAST," + " type=" + type); throw new IllegalArgumentException("Unknown insets type: " + type); } } Loading
core/tests/coretests/src/android/view/InsetsSourceTest.java +6 −7 Original line number Diff line number Diff line Loading @@ -17,9 +17,7 @@ package android.view; import static android.view.InsetsSource.ID_IME_CAPTION_BAR; import static android.view.WindowInsets.Type.FIRST; import static android.view.WindowInsets.Type.LAST; import static android.view.WindowInsets.Type.SIZE; import static android.view.WindowInsets.Type.TYPES; import static android.view.WindowInsets.Type.captionBar; import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.navigationBars; Loading @@ -31,6 +29,7 @@ import android.graphics.Insets; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.util.SparseArray; import android.view.WindowInsets.Type.InsetsType; import androidx.test.ext.junit.runners.AndroidJUnit4; Loading Loading @@ -367,11 +366,11 @@ public class InsetsSourceTest { @Test public void testCreateId() { final int numSourcePerType = 2048; final int numTotalSources = SIZE * numSourcePerType; final int numTotalSources = TYPES.length * numSourcePerType; final SparseArray<InsetsSource> sources = new SparseArray<>(numTotalSources); final Object owner = new Object(); for (int index = 0; index < numSourcePerType; index++) { for (int type = FIRST; type <= LAST; type = type << 1) { for (@InsetsType int type : TYPES) { final int id = InsetsSource.createId(owner, index, type); assertNull("Must not create the same ID.", sources.get(id)); sources.append(id, new InsetsSource(id, type)); Loading @@ -385,7 +384,7 @@ public class InsetsSourceTest { // Here doesn't iterate all the owners, or the test cannot be done before timeout. for (int owner = 0; owner < 100; owner++) { for (int index = 0; index < 2048; index++) { for (int type = FIRST; type <= LAST; type = type << 1) { for (@InsetsType int type : TYPES) { final int id = InsetsSource.createId(owner, index, type); final int indexFromId = InsetsSource.getIndex(id); assertEquals("index and indexFromId must be the same. id=" + id Loading @@ -403,7 +402,7 @@ public class InsetsSourceTest { // Here doesn't iterate all the owners, or the test cannot be done before timeout. for (int owner = 0; owner < 100; owner++) { for (int index = 0; index < 2048; index++) { for (int type = FIRST; type <= LAST; type = type << 1) { for (@InsetsType int type : TYPES) { final int id = InsetsSource.createId(owner, index, type); final int typeFromId = InsetsSource.getType(id); assertEquals("type and typeFromId must be the same. id=" + id Loading
core/tests/coretests/src/android/view/WindowInsetsTest.java +103 −10 Original line number Diff line number Diff line Loading @@ -16,7 +16,8 @@ package android.view; import static android.view.WindowInsets.Type.SIZE; import static android.view.WindowInsets.Type.ALL; import static android.view.WindowInsets.Type.TYPES; import static android.view.WindowInsets.Type.captionBar; import static android.view.WindowInsets.Type.displayCutout; import static android.view.WindowInsets.Type.ime; Loading @@ -25,11 +26,14 @@ import static android.view.WindowInsets.Type.statusBars; import static android.view.WindowInsets.Type.systemBars; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import android.graphics.Insets; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.view.WindowInsets.Type.InsetsType; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; Loading @@ -44,6 +48,95 @@ import java.util.List; @Presubmit public class WindowInsetsTest { /** * Verifies that all the values in {@link WindowInsets.Type#TYPES} are included in * {@link WindowInsets.Type#ALL}. */ @Test public void testTypesInAll() { int combinedTypes = 0; for (@InsetsType int type : TYPES) { assertTrue("type in TYPES should be included in ALL", (type & ALL) != 0); combinedTypes |= type; } assertEquals("ALL should match bitmask of combined types", ALL, combinedTypes); } /** * Verifies that all the values in {@link WindowInsets.Type#ALL} are included in * {@link WindowInsets.Type#TYPES}. */ @Test public void testAllInTypes() { for (int index = 0; index < Integer.SIZE; index++) { final int type = 1 << index; if ((type & WindowInsets.Type.ALL) != 0) { assertTrue("index of bit in ALL should be less than number of TYPES", index < TYPES.length); assertEquals("type in ALL should be included in TYPES", type, TYPES[index]); } } } /** * Verifies that all the values in {@link WindowInsets.Type#TYPES} are included in * {@link WindowInsets.Type#indexOf}. */ @Test public void testTypesInIndexOf() { for (@InsetsType int type : TYPES) { assertEquals("type should match", type, TYPES[WindowInsets.Type.indexOf(type)]); } assertThrows(IllegalArgumentException.class, () -> WindowInsets.Type.indexOf(-1)); } /** * Verifies that all the values returned by {@link WindowInsets.Type#indexOf} are included in * {@link WindowInsets.Type#TYPES}. */ @Test public void testIndexOfInTypes() { for (int i = 0; i < Integer.SIZE; i++) { final int type = 1 << i; try { final int index = WindowInsets.Type.indexOf(type); assertTrue("index should be non-negative", index >= 0); assertTrue("index should be less than number of TYPES", index < TYPES.length); assertEquals(type, TYPES[index]); } catch (IllegalArgumentException e) { // ignore undefined indexOf case, handled through testTypesInIndexOf above. } } } /** * Verifies that all the values in {@link WindowInsets.Type#TYPES} are included in * {@link WindowInsets.Type#toString}. */ @Test public void testTypesInToString() { for (@InsetsType int type : TYPES) { assertFalse("type toString should not be empty", WindowInsets.Type.toString(type).isEmpty()); } assertTrue("invalid type toString should be empty", WindowInsets.Type.toString(0).isEmpty()); } /** * Verifies that all the values accepted by {@link WindowInsets.Type#toString} are included in * {@link WindowInsets.Type#TYPES}. */ @Test public void testToStringInTypes() { for (int i = 0; i < Integer.SIZE; i++) { final int type = 1 << i; if (!WindowInsets.Type.toString(type).isEmpty()) { assertEquals("type should match", type, TYPES[i]); } } } @Test public void systemWindowInsets_afterConsuming_isConsumed() { assertTrue(new WindowInsets(WindowInsets.createCompatTypeMap(new Rect(1, 2, 3, 4)), null, Loading @@ -65,9 +158,9 @@ public class WindowInsetsTest { @Test public void compatInsets_layoutStable() { Insets[] insets = new Insets[SIZE]; Insets[] maxInsets = new Insets[SIZE]; boolean[] visible = new boolean[SIZE]; Insets[] insets = new Insets[TYPES.length]; Insets[] maxInsets = new Insets[TYPES.length]; boolean[] visible = new boolean[TYPES.length]; WindowInsets.assignCompatInsets(maxInsets, new Rect(0, 10, 0, 0)); WindowInsets.assignCompatInsets(insets, new Rect(0, 0, 0, 0)); WindowInsets windowInsets = new WindowInsets(insets, maxInsets, visible, false, 0, Loading @@ -78,9 +171,9 @@ public class WindowInsetsTest { @Test public void builder_copy_compatInsetTypes() { final Insets[] insets = new Insets[SIZE]; final Insets[] maxInsets = new Insets[SIZE]; final boolean[] visible = new boolean[SIZE]; 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, Loading @@ -96,9 +189,9 @@ public class WindowInsetsTest { @Test public void builder_copy_compatIgnoreVisibility() { final Insets[] insets = new Insets[SIZE]; final Insets[] maxInsets = new Insets[SIZE]; final boolean[] visible = new boolean[SIZE]; 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, Loading