diff options
9 files changed, 301 insertions, 317 deletions
diff --git a/core/java/android/view/InsetsFrameProvider.java b/core/java/android/view/InsetsFrameProvider.java index a2e0326c84b1..2d7dc316cb51 100644 --- a/core/java/android/view/InsetsFrameProvider.java +++ b/core/java/android/view/InsetsFrameProvider.java @@ -16,8 +16,6 @@ package android.view; -import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT; - import android.annotation.IntRange; import android.annotation.NonNull; import android.graphics.Insets; @@ -44,44 +42,41 @@ import java.util.Objects; public class InsetsFrameProvider implements Parcelable { /** - * If specified in source field, the insets calculation will be based on the display frame. + * Uses the display frame as the source. */ public static final int SOURCE_DISPLAY = 0; /** - * If specified in source field, the insets calculation will be based on the window bounds. The - * container bounds can sometimes be different from the window frame. For example, when a task - * bar needs the entire screen to be prepared to showing the apps, the window container can take - * the entire display, or display area, but the window frame, as a result of the layout, will - * stay small until it actually taking the entire display to draw their view. + * Uses the window bounds as the source. */ public static final int SOURCE_CONTAINER_BOUNDS = 1; /** - * If specified in source field, the insets calculation will be based on the window frame. This - * is also the default value of the source. + * Uses the window frame as the source. */ public static final int SOURCE_FRAME = 2; - private static final int HAS_INSETS_SIZE = 1; - private static final int HAS_INSETS_SIZE_OVERRIDE = 2; - - private static final Rect sTmpRect = new Rect(); - private static final Rect sTmpRect2 = new Rect(); + /** + * Uses {@link #mArbitraryRectangle} as the source. + */ + public static final int SOURCE_ARBITRARY_RECTANGLE = 3; private final IBinder mOwner; private final int mIndex; private final @InsetsType int mType; /** - * The source of frame. By default, all adjustment will be based on the window frame, it - * can be set to window bounds or display bounds instead. + * The selection of the starting rectangle to be converted into source frame. */ private int mSource = SOURCE_FRAME; /** - * The provided insets size based on the source frame. The result will be used as the insets - * size to windows other than IME. Only one side should be set. + * This is used as the source frame only if SOURCE_ARBITRARY_RECTANGLE is applied. + */ + private Rect mArbitraryRectangle; + + /** + * Modifies the starting rectangle selected by {@link #mSource}. * * For example, when the given source frame is (0, 0) - (100, 200), and the insetsSize is null, * the source frame will be directly used as the final insets frame. If the insetsSize is set to @@ -163,6 +158,15 @@ public class InsetsFrameProvider implements Parcelable { return mInsetsSize; } + public InsetsFrameProvider setArbitraryRectangle(Rect rect) { + mArbitraryRectangle = new Rect(rect); + return this; + } + + public Rect getArbitraryRectangle() { + return mArbitraryRectangle; + } + public InsetsFrameProvider setInsetsSizeOverrides(InsetsSizeOverride[] insetsSizeOverrides) { mInsetsSizeOverrides = insetsSizeOverrides; return this; @@ -200,6 +204,9 @@ public class InsetsFrameProvider implements Parcelable { if (mInsetsSizeOverrides != null) { sb.append(", insetsSizeOverrides=").append(Arrays.toString(mInsetsSizeOverrides)); } + if (mArbitraryRectangle != null) { + sb.append(", mArbitraryRectangle=").append(mArbitraryRectangle.toShortString()); + } sb.append("}"); return sb.toString(); } @@ -212,6 +219,8 @@ public class InsetsFrameProvider implements Parcelable { return "CONTAINER_BOUNDS"; case SOURCE_FRAME: return "FRAME"; + case SOURCE_ARBITRARY_RECTANGLE: + return "ARBITRARY_RECTANGLE"; } return "UNDEFINED"; } @@ -220,14 +229,10 @@ public class InsetsFrameProvider implements Parcelable { mOwner = in.readStrongBinder(); mIndex = in.readInt(); mType = in.readInt(); - int insetsSizeModified = in.readInt(); mSource = in.readInt(); - if ((insetsSizeModified & HAS_INSETS_SIZE) != 0) { - mInsetsSize = Insets.CREATOR.createFromParcel(in); - } - if ((insetsSizeModified & HAS_INSETS_SIZE_OVERRIDE) != 0) { - mInsetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR); - } + mInsetsSize = in.readTypedObject(Insets.CREATOR); + mInsetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR); + mArbitraryRectangle = in.readTypedObject(Rect.CREATOR); } @Override @@ -235,21 +240,10 @@ public class InsetsFrameProvider implements Parcelable { out.writeStrongBinder(mOwner); out.writeInt(mIndex); out.writeInt(mType); - int insetsSizeModified = 0; - if (mInsetsSize != null) { - insetsSizeModified |= HAS_INSETS_SIZE; - } - if (mInsetsSizeOverrides != null) { - insetsSizeModified |= HAS_INSETS_SIZE_OVERRIDE; - } - out.writeInt(insetsSizeModified); out.writeInt(mSource); - if (mInsetsSize != null) { - mInsetsSize.writeToParcel(out, flags); - } - if (mInsetsSizeOverrides != null) { - out.writeTypedArray(mInsetsSizeOverrides, flags); - } + out.writeTypedObject(mInsetsSize, flags); + out.writeTypedArray(mInsetsSizeOverrides, flags); + out.writeTypedObject(mArbitraryRectangle, flags); } public boolean idEquals(InsetsFrameProvider o) { @@ -268,13 +262,14 @@ public class InsetsFrameProvider implements Parcelable { return Objects.equals(mOwner, other.mOwner) && mIndex == other.mIndex && mType == other.mType && mSource == other.mSource && Objects.equals(mInsetsSize, other.mInsetsSize) - && Arrays.equals(mInsetsSizeOverrides, other.mInsetsSizeOverrides); + && Arrays.equals(mInsetsSizeOverrides, other.mInsetsSizeOverrides) + && Objects.equals(mArbitraryRectangle, other.mArbitraryRectangle); } @Override public int hashCode() { return Objects.hash(mOwner, mIndex, mType, mSource, mInsetsSize, - Arrays.hashCode(mInsetsSizeOverrides)); + Arrays.hashCode(mInsetsSizeOverrides), mArbitraryRectangle); } public static final @NonNull Parcelable.Creator<InsetsFrameProvider> CREATOR = @@ -290,67 +285,6 @@ public class InsetsFrameProvider implements Parcelable { } }; - public static void calculateInsetsFrame(Rect displayFrame, Rect containerBounds, - Rect displayCutoutSafe, Rect inOutFrame, int source, Insets insetsSize, - @WindowManager.LayoutParams.PrivateFlags int privateFlags, - Insets displayCutoutSafeInsetsSize, Rect givenContentInsets) { - boolean extendByCutout = false; - if (source == InsetsFrameProvider.SOURCE_DISPLAY) { - inOutFrame.set(displayFrame); - } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) { - inOutFrame.set(containerBounds); - } else { - extendByCutout = (privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0; - if (givenContentInsets != null) { - inOutFrame.inset(givenContentInsets); - } - } - if (displayCutoutSafeInsetsSize != null) { - sTmpRect2.set(inOutFrame); - } - if (insetsSize != null) { - calculateInsetsFrame(inOutFrame, insetsSize); - } - - if (extendByCutout && insetsSize != null) { - // Only extend if the insets size is not null. Otherwise, the frame has already been - // extended by the display cutout during layout process. - WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, inOutFrame, sTmpRect); - } - - if (displayCutoutSafeInsetsSize != null) { - // The insets is at least with the given size within the display cutout safe area. - // Calculate the smallest size. - calculateInsetsFrame(sTmpRect2, displayCutoutSafeInsetsSize); - WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, sTmpRect2, sTmpRect); - // If it's larger than previous calculation, use it. - if (sTmpRect2.contains(inOutFrame)) { - inOutFrame.set(sTmpRect2); - } - } - } - - /** - * Calculate the insets frame given the insets size and the source frame. - * @param inOutFrame the source frame. - * @param insetsSize the insets size. Only the first non-zero value will be taken. - */ - private static void calculateInsetsFrame(Rect inOutFrame, Insets insetsSize) { - // Only one side of the provider shall be applied. Check in the order of left - top - - // right - bottom, only the first non-zero value will be applied. - if (insetsSize.left != 0) { - inOutFrame.right = inOutFrame.left + insetsSize.left; - } else if (insetsSize.top != 0) { - inOutFrame.bottom = inOutFrame.top + insetsSize.top; - } else if (insetsSize.right != 0) { - inOutFrame.left = inOutFrame.right - insetsSize.right; - } else if (insetsSize.bottom != 0) { - inOutFrame.top = inOutFrame.bottom - insetsSize.bottom; - } else { - inOutFrame.setEmpty(); - } - } - /** * Class to describe the insets size to be provided to window with specific window type. If not * used, same insets size will be sent as instructed in the insetsSize and source. diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java index fabb08923089..ad20432bd57d 100644 --- a/core/java/android/window/WindowContainerTransaction.java +++ b/core/java/android/window/WindowContainerTransaction.java @@ -40,8 +40,9 @@ import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import android.util.ArrayMap; -import android.view.InsetsState; +import android.view.InsetsFrameProvider; import android.view.SurfaceControl; +import android.view.WindowInsets.Type.InsetsType; import java.util.ArrayList; import java.util.Arrays; @@ -666,50 +667,51 @@ public final class WindowContainerTransaction implements Parcelable { } /** - * Adds a given {@code Rect} as a rect insets provider on the {@code receiverWindowContainer}. - * This will trigger a change of insets for all the children in the subtree of - * {@code receiverWindowContainer}. + * Adds a given {@code Rect} as an insets source frame on the {@code receiver}. * - * @param receiverWindowContainer the window container which the insets provider need to be - * added to - * @param insetsProviderFrame the frame that will be added as Insets provider - * @param insetsTypes types of insets the rect provides + * @param receiver The window container that the insets source is added to. + * @param owner The owner of the insets source. An insets source can only be modified by its + * owner. + * @param index An owner might add multiple insets sources with the same type. + * This identifies them. + * @param type The {@link InsetsType} of the insets source. + * @param frame The rectangle area of the insets source. * @hide */ @NonNull - public WindowContainerTransaction addRectInsetsProvider( - @NonNull WindowContainerToken receiverWindowContainer, - @NonNull Rect insetsProviderFrame, - @InsetsState.InternalInsetsType int[] insetsTypes) { + public WindowContainerTransaction addInsetsSource( + @NonNull WindowContainerToken receiver, + IBinder owner, int index, @InsetsType int type, Rect frame) { final HierarchyOp hierarchyOp = - new HierarchyOp.Builder( - HierarchyOp.HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER) - .setContainer(receiverWindowContainer.asBinder()) - .setInsetsProviderFrame(insetsProviderFrame) - .setInsetsTypes(insetsTypes) + new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_ADD_INSETS_FRAME_PROVIDER) + .setContainer(receiver.asBinder()) + .setInsetsFrameProvider(new InsetsFrameProvider(owner, index, type) + .setSource(InsetsFrameProvider.SOURCE_ARBITRARY_RECTANGLE) + .setArbitraryRectangle(frame)) .build(); mHierarchyOps.add(hierarchyOp); return this; } /** - * Removes the insets provider for the given types from the - * {@code receiverWindowContainer}. This will trigger a change of insets for all the children - * in the subtree of {@code receiverWindowContainer}. + * Removes the insets source from the {@code receiver}. * - * @param receiverWindowContainer the window container which the insets-override-provider has - * to be removed from - * @param insetsTypes types of insets that have to be removed + * @param receiver The window container that the insets source was added to. + * @param owner The owner of the insets source. An insets source can only be modified by its + * owner. + * @param index An owner might add multiple insets sources with the same type. + * This identifies them. + * @param type The {@link InsetsType} of the insets source. * @hide */ @NonNull - public WindowContainerTransaction removeInsetsProvider( - @NonNull WindowContainerToken receiverWindowContainer, - @InsetsState.InternalInsetsType int[] insetsTypes) { + public WindowContainerTransaction removeInsetsSource( + @NonNull WindowContainerToken receiver, + IBinder owner, int index, @InsetsType int type) { final HierarchyOp hierarchyOp = - new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER) - .setContainer(receiverWindowContainer.asBinder()) - .setInsetsTypes(insetsTypes) + new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_INSETS_FRAME_PROVIDER) + .setContainer(receiver.asBinder()) + .setInsetsFrameProvider(new InsetsFrameProvider(owner, index, type)) .build(); mHierarchyOps.add(hierarchyOp); return this; @@ -1315,8 +1317,8 @@ public final class WindowContainerTransaction implements Parcelable { public static final int HIERARCHY_OP_TYPE_PENDING_INTENT = 7; public static final int HIERARCHY_OP_TYPE_START_SHORTCUT = 8; public static final int HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER = 9; - public static final int HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER = 10; - public static final int HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER = 11; + public static final int HIERARCHY_OP_TYPE_ADD_INSETS_FRAME_PROVIDER = 10; + public static final int HIERARCHY_OP_TYPE_REMOVE_INSETS_FRAME_PROVIDER = 11; public static final int HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP = 12; public static final int HIERARCHY_OP_TYPE_REMOVE_TASK = 13; public static final int HIERARCHY_OP_TYPE_FINISH_ACTIVITY = 14; @@ -1342,9 +1344,7 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private IBinder mReparent; - private @InsetsState.InternalInsetsType int[] mInsetsTypes; - - private Rect mInsetsProviderFrame; + private InsetsFrameProvider mInsetsFrameProvider; // Moves/reparents to top of parent when {@code true}, otherwise moves/reparents to bottom. private boolean mToTop; @@ -1477,8 +1477,7 @@ public final class WindowContainerTransaction implements Parcelable { mType = copy.mType; mContainer = copy.mContainer; mReparent = copy.mReparent; - mInsetsTypes = copy.mInsetsTypes; - mInsetsProviderFrame = copy.mInsetsProviderFrame; + mInsetsFrameProvider = copy.mInsetsFrameProvider; mToTop = copy.mToTop; mReparentTopOnly = copy.mReparentTopOnly; mWindowingModes = copy.mWindowingModes; @@ -1496,12 +1495,7 @@ public final class WindowContainerTransaction implements Parcelable { mType = in.readInt(); mContainer = in.readStrongBinder(); mReparent = in.readStrongBinder(); - mInsetsTypes = in.createIntArray(); - if (in.readInt() != 0) { - mInsetsProviderFrame = Rect.CREATOR.createFromParcel(in); - } else { - mInsetsProviderFrame = null; - } + mInsetsFrameProvider = in.readTypedObject(InsetsFrameProvider.CREATOR); mToTop = in.readBoolean(); mReparentTopOnly = in.readBoolean(); mWindowingModes = in.createIntArray(); @@ -1529,12 +1523,8 @@ public final class WindowContainerTransaction implements Parcelable { } @Nullable - public @InsetsState.InternalInsetsType int[] getInsetsTypes() { - return mInsetsTypes; - } - - public Rect getInsetsProviderFrame() { - return mInsetsProviderFrame; + public InsetsFrameProvider getInsetsFrameProvider() { + return mInsetsFrameProvider; } @NonNull @@ -1624,13 +1614,12 @@ public final class WindowContainerTransaction implements Parcelable { case HIERARCHY_OP_TYPE_START_SHORTCUT: return "{StartShortcut: options=" + mLaunchOptions + " info=" + mShortcutInfo + "}"; - case HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER: + case HIERARCHY_OP_TYPE_ADD_INSETS_FRAME_PROVIDER: return "{addRectInsetsProvider: container=" + mContainer - + " insetsProvidingFrame=" + mInsetsProviderFrame - + " insetsType=" + Arrays.toString(mInsetsTypes) + "}"; - case HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER: + + " provider=" + mInsetsFrameProvider + "}"; + case HIERARCHY_OP_TYPE_REMOVE_INSETS_FRAME_PROVIDER: return "{removeLocalInsetsProvider: container=" + mContainer - + " insetsType=" + Arrays.toString(mInsetsTypes) + "}"; + + " provider=" + mInsetsFrameProvider + "}"; case HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP: return "{setAlwaysOnTop: container=" + mContainer + " alwaysOnTop=" + mAlwaysOnTop + "}"; @@ -1659,13 +1648,7 @@ public final class WindowContainerTransaction implements Parcelable { dest.writeInt(mType); dest.writeStrongBinder(mContainer); dest.writeStrongBinder(mReparent); - dest.writeIntArray(mInsetsTypes); - if (mInsetsProviderFrame != null) { - dest.writeInt(1); - mInsetsProviderFrame.writeToParcel(dest, 0); - } else { - dest.writeInt(0); - } + dest.writeTypedObject(mInsetsFrameProvider, flags); dest.writeBoolean(mToTop); dest.writeBoolean(mReparentTopOnly); dest.writeIntArray(mWindowingModes); @@ -1706,9 +1689,7 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private IBinder mReparent; - private int[] mInsetsTypes; - - private Rect mInsetsProviderFrame; + private InsetsFrameProvider mInsetsFrameProvider; private boolean mToTop; @@ -1753,13 +1734,8 @@ public final class WindowContainerTransaction implements Parcelable { return this; } - Builder setInsetsTypes(int[] insetsTypes) { - mInsetsTypes = insetsTypes; - return this; - } - - Builder setInsetsProviderFrame(Rect insetsProviderFrame) { - mInsetsProviderFrame = insetsProviderFrame; + Builder setInsetsFrameProvider(InsetsFrameProvider providers) { + mInsetsFrameProvider = providers; return this; } @@ -1829,8 +1805,7 @@ public final class WindowContainerTransaction implements Parcelable { hierarchyOp.mActivityTypes = mActivityTypes != null ? Arrays.copyOf(mActivityTypes, mActivityTypes.length) : null; - hierarchyOp.mInsetsTypes = mInsetsTypes; - hierarchyOp.mInsetsProviderFrame = mInsetsProviderFrame; + hierarchyOp.mInsetsFrameProvider = mInsetsFrameProvider; hierarchyOp.mToTop = mToTop; hierarchyOp.mReparentTopOnly = mReparentTopOnly; hierarchyOp.mLaunchOptions = mLaunchOptions; 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 31e93ac6068f..4ebd09fdecee 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 @@ -24,13 +24,14 @@ import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; +import android.os.Binder; import android.view.Display; -import android.view.InsetsState; import android.view.LayoutInflater; import android.view.SurfaceControl; import android.view.SurfaceControlViewHost; import android.view.View; import android.view.ViewRootImpl; +import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowlessWindowManager; import android.window.TaskConstants; @@ -58,7 +59,6 @@ import java.util.function.Supplier; */ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> implements AutoCloseable { - private static final int[] CAPTION_INSETS_TYPES = { InsetsState.ITYPE_CAPTION_BAR }; /** * System-wide context. Only used to create context with overridden configurations. @@ -96,6 +96,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> private WindowlessWindowManager mCaptionWindowManager; private SurfaceControlViewHost mViewHost; + private final Binder mOwner = new Binder(); private final Rect mCaptionInsetsRect = new Rect(); private final Rect mTaskSurfaceCrop = new Rect(); private final float[] mTmpColor = new float[3]; @@ -304,10 +305,9 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> // Caption insets mCaptionInsetsRect.set(taskBounds); - mCaptionInsetsRect.bottom = - mCaptionInsetsRect.top + captionHeight + params.mCaptionY; - wct.addRectInsetsProvider(mTaskInfo.token, mCaptionInsetsRect, - CAPTION_INSETS_TYPES); + mCaptionInsetsRect.bottom = mCaptionInsetsRect.top + captionHeight + params.mCaptionY; + wct.addInsetsSource(mTaskInfo.token, + mOwner, 0 /* index */, WindowInsets.Type.captionBar(), mCaptionInsetsRect); } else { startT.hide(mCaptionContainerSurface); } @@ -372,7 +372,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> } final WindowContainerTransaction wct = mWindowContainerTransactionSupplier.get(); - wct.removeInsetsProvider(mTaskInfo.token, CAPTION_INSETS_TYPES); + wct.removeInsetsSource(mTaskInfo.token, + mOwner, 0 /* index */, WindowInsets.Type.captionBar()); mTaskOrganizer.applyTransaction(wct); } 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 7e39b5b8f2ce..c92d2f36d3a7 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 @@ -23,6 +23,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.any; import static org.mockito.Mockito.argThat; import static org.mockito.Mockito.doReturn; @@ -42,11 +43,11 @@ import android.graphics.Rect; import android.testing.AndroidTestingRunner; import android.util.DisplayMetrics; import android.view.Display; -import android.view.InsetsState; import android.view.SurfaceControl; import android.view.SurfaceControlViewHost; import android.view.View; import android.view.ViewRootImpl; +import android.view.WindowInsets; import android.view.WindowManager.LayoutParams; import android.window.TaskConstants; import android.window.WindowContainerTransaction; @@ -256,10 +257,12 @@ public class WindowDecorationTests extends ShellTestCase { && (lp.flags & LayoutParams.FLAG_NOT_FOCUSABLE) != 0)); if (ViewRootImpl.CAPTION_ON_SHELL) { verify(mMockView).setTaskFocusState(true); - verify(mMockWindowContainerTransaction) - .addRectInsetsProvider(taskInfo.token, - new Rect(100, 300, 400, 364), - new int[] { InsetsState.ITYPE_CAPTION_BAR }); + verify(mMockWindowContainerTransaction).addInsetsSource( + eq(taskInfo.token), + any(), + eq(0 /* index */), + eq(WindowInsets.Type.captionBar()), + eq(new Rect(100, 300, 400, 364))); } verify(mMockSurfaceControlFinishT) @@ -323,7 +326,7 @@ public class WindowDecorationTests extends ShellTestCase { verify(mMockSurfaceControlViewHost, never()).release(); verify(t, never()).apply(); verify(mMockWindowContainerTransaction, never()) - .removeInsetsProvider(eq(taskInfo.token), any()); + .removeInsetsSource(eq(taskInfo.token), any(), anyInt(), anyInt()); taskInfo.isVisible = false; windowDecor.relayout(taskInfo); @@ -334,7 +337,8 @@ public class WindowDecorationTests extends ShellTestCase { releaseOrder.verify(t).remove(decorContainerSurface); releaseOrder.verify(t).remove(taskBackgroundSurface); releaseOrder.verify(t).apply(); - verify(mMockWindowContainerTransaction).removeInsetsProvider(eq(taskInfo.token), any()); + verify(mMockWindowContainerTransaction) + .removeInsetsSource(eq(taskInfo.token), any(), anyInt(), anyInt()); } @Test diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index c719a1d30a16..22dd0e5128e9 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -19,6 +19,10 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.view.Display.TYPE_INTERNAL; +import static android.view.InsetsFrameProvider.SOURCE_ARBITRARY_RECTANGLE; +import static android.view.InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS; +import static android.view.InsetsFrameProvider.SOURCE_DISPLAY; +import static android.view.InsetsFrameProvider.SOURCE_FRAME; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS; @@ -35,6 +39,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; @@ -167,6 +172,8 @@ public class DisplayPolicy { private static final int SHOW_TYPES_FOR_SWIPE = Type.statusBars() | Type.navigationBars(); private static final int SHOW_TYPES_FOR_PANIC = Type.navigationBars(); + private static final int INSETS_OVERRIDE_INDEX_INVALID = -1; + private final WindowManagerService mService; private final Context mContext; private final Context mUiContext; @@ -1075,7 +1082,7 @@ public class DisplayPolicy { // runtime as ensured in WMS. Make use of the index in the provider directly // to access the latest provided size at runtime. final TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider = - getFrameProvider(win, i); + getFrameProvider(win, i, INSETS_OVERRIDE_INDEX_INVALID); final InsetsFrameProvider.InsetsSizeOverride[] overrides = provider.getInsetsSizeOverrides(); final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> @@ -1083,10 +1090,8 @@ public class DisplayPolicy { if (overrides != null) { overrideProviders = new SparseArray<>(); for (int j = overrides.length - 1; j >= 0; j--) { - final TriConsumer<DisplayFrames, WindowContainer, Rect> - overrideFrameProvider = - getOverrideFrameProvider(win, i, j); - overrideProviders.put(overrides[j].getWindowType(), overrideFrameProvider); + overrideProviders.put( + overrides[j].getWindowType(), getFrameProvider(win, i, j)); } } else { overrideProviders = null; @@ -1101,30 +1106,78 @@ public class DisplayPolicy { } } - private TriConsumer<DisplayFrames, WindowContainer, Rect> getFrameProvider(WindowState win, - int index) { + private static TriConsumer<DisplayFrames, WindowContainer, Rect> getFrameProvider( + WindowState win, int index, int overrideIndex) { return (displayFrames, windowContainer, inOutFrame) -> { final LayoutParams lp = win.mAttrs.forRotation(displayFrames.mRotation); final InsetsFrameProvider ifp = lp.providedInsets[index]; - InsetsFrameProvider.calculateInsetsFrame(displayFrames.mUnrestricted, - windowContainer.getBounds(), displayFrames.mDisplayCutoutSafe, inOutFrame, - ifp.getSource(), ifp.getInsetsSize(), lp.privateFlags, - ifp.getMinimalInsetsSizeInDisplayCutoutSafe(), win.mGivenContentInsets); + final Rect displayFrame = displayFrames.mUnrestricted; + final Rect safe = displayFrames.mDisplayCutoutSafe; + boolean extendByCutout = false; + switch (ifp.getSource()) { + case SOURCE_DISPLAY: + inOutFrame.set(displayFrame); + break; + case SOURCE_CONTAINER_BOUNDS: + inOutFrame.set(windowContainer.getBounds()); + break; + case SOURCE_FRAME: + inOutFrame.inset(win.mGivenContentInsets); + extendByCutout = + (lp.privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0; + break; + case SOURCE_ARBITRARY_RECTANGLE: + inOutFrame.set(ifp.getArbitraryRectangle()); + break; + } + final Insets insetsSize = overrideIndex == INSETS_OVERRIDE_INDEX_INVALID + ? ifp.getInsetsSize() + : ifp.getInsetsSizeOverrides()[overrideIndex].getInsetsSize(); + + if (ifp.getMinimalInsetsSizeInDisplayCutoutSafe() != null) { + sTmpRect2.set(inOutFrame); + } + calculateInsetsFrame(inOutFrame, insetsSize); + + if (extendByCutout && insetsSize != null) { + WindowLayout.extendFrameByCutout(safe, displayFrame, inOutFrame, sTmpRect); + } + + if (ifp.getMinimalInsetsSizeInDisplayCutoutSafe() != null) { + // The insets is at least with the given size within the display cutout safe area. + // Calculate the smallest size. + calculateInsetsFrame(sTmpRect2, ifp.getMinimalInsetsSizeInDisplayCutoutSafe()); + WindowLayout.extendFrameByCutout(safe, displayFrame, sTmpRect2, sTmpRect); + // If it's larger than previous calculation, use it. + if (sTmpRect2.contains(inOutFrame)) { + inOutFrame.set(sTmpRect2); + } + } }; } - @NonNull - private TriConsumer<DisplayFrames, WindowContainer, Rect> getOverrideFrameProvider( - WindowState win, int index, int overrideIndex) { - return (displayFrames, windowContainer, inOutFrame) -> { - final LayoutParams lp = win.mAttrs.forRotation(displayFrames.mRotation); - final InsetsFrameProvider ifp = lp.providedInsets[index]; - InsetsFrameProvider.calculateInsetsFrame(displayFrames.mUnrestricted, - windowContainer.getBounds(), displayFrames.mDisplayCutoutSafe, inOutFrame, - ifp.getSource(), ifp.getInsetsSizeOverrides()[overrideIndex].getInsetsSize(), - lp.privateFlags, null /* displayCutoutSafeInsetsSize */, - null /* givenContentInsets */); - }; + /** + * Calculate the insets frame given the insets size and the source frame. + * @param inOutFrame the source frame. + * @param insetsSize the insets size. Only the first non-zero value will be taken. + */ + private static void calculateInsetsFrame(Rect inOutFrame, Insets insetsSize) { + if (insetsSize == null) { + return; + } + // Only one side of the provider shall be applied. Check in the order of left - top - + // right - bottom, only the first non-zero value will be applied. + if (insetsSize.left != 0) { + inOutFrame.right = inOutFrame.left + insetsSize.left; + } else if (insetsSize.top != 0) { + inOutFrame.bottom = inOutFrame.top + insetsSize.top; + } else if (insetsSize.right != 0) { + inOutFrame.left = inOutFrame.right - insetsSize.right; + } else if (insetsSize.bottom != 0) { + inOutFrame.top = inOutFrame.bottom - insetsSize.bottom; + } else { + inOutFrame.setEmpty(); + } } TriConsumer<DisplayFrames, WindowContainer, Rect> getImeSourceFrameProvider() { diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 520d06d53c0c..bd0344faa078 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -90,6 +90,7 @@ import android.util.Slog; import android.util.SparseArray; import android.util.proto.ProtoOutputStream; import android.view.DisplayInfo; +import android.view.InsetsFrameProvider; import android.view.InsetsSource; import android.view.InsetsState; import android.view.MagnificationSpec; @@ -419,18 +420,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } /** - * Sets the given {@code providerFrame} as one of the insets provider for this window - * container. These insets are only passed to the subtree of the current WindowContainer. - * For a given WindowContainer-to-Leaf path, one insetsType can't be overridden more than once. - * If that happens, only the latest one will be chosen. + * Adds an {@link InsetsFrameProvider} which describes what insets should be provided to + * this {@link WindowContainer} and its children. * - * @param providerFrame the frame that will act as one of the insets providers for this window - * container - * @param insetsTypes the insets type which the providerFrame provides + * @param provider describes the insets types and the frames. */ - void addLocalRectInsetsSourceProvider(Rect providerFrame, - @InsetsState.InternalInsetsType int[] insetsTypes) { - if (insetsTypes == null || insetsTypes.length == 0) { + void addLocalInsetsFrameProvider(InsetsFrameProvider provider) { + if (provider == null) { throw new IllegalArgumentException("Insets type not specified."); } if (mDisplayContent == null) { @@ -443,45 +439,41 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< if (mLocalInsetsSourceProviders == null) { mLocalInsetsSourceProviders = new SparseArray<>(); } - for (int i = 0; i < insetsTypes.length; i++) { - final @InsetsState.InternalInsetsType int type = insetsTypes[i]; - InsetsSourceProvider insetsSourceProvider = - mLocalInsetsSourceProviders.get(type); - if (insetsSourceProvider != null) { - if (DEBUG) { - Slog.d(TAG, "The local insets provider for this type " + type - + " already exists. Overwriting"); - } + final int id = InsetsSource.createId( + provider.getOwner(), provider.getIndex(), provider.getType()); + if (mLocalInsetsSourceProviders.get(id) != null) { + if (DEBUG) { + Slog.d(TAG, "The local insets provider for this " + provider + + " already exists. Overwriting"); } - insetsSourceProvider = new RectInsetsSourceProvider( - new InsetsSource(type, InsetsState.toPublicType(type)), - mDisplayContent.getInsetsStateController(), mDisplayContent); - mLocalInsetsSourceProviders.put(insetsTypes[i], insetsSourceProvider); - ((RectInsetsSourceProvider) insetsSourceProvider).setRect(providerFrame); } + final RectInsetsSourceProvider insetsSourceProvider = new RectInsetsSourceProvider( + new InsetsSource(id, provider.getType()), + mDisplayContent.getInsetsStateController(), mDisplayContent); + mLocalInsetsSourceProviders.put(id, insetsSourceProvider); + insetsSourceProvider.setRect(provider.getArbitraryRectangle()); mDisplayContent.getInsetsStateController().updateAboveInsetsState(true); } - void removeLocalInsetsSourceProvider(@InsetsState.InternalInsetsType int[] insetsTypes) { - if (insetsTypes == null || insetsTypes.length == 0) { + void removeLocalInsetsFrameProvider(InsetsFrameProvider provider) { + if (provider == null) { throw new IllegalArgumentException("Insets type not specified."); } if (mLocalInsetsSourceProviders == null) { return; } - for (int i = 0; i < insetsTypes.length; i++) { - InsetsSourceProvider insetsSourceProvider = - mLocalInsetsSourceProviders.get(insetsTypes[i]); - if (insetsSourceProvider == null) { - if (DEBUG) { - Slog.d(TAG, "Given insets type " + insetsTypes[i] + " doesn't have a " - + "local insetsSourceProvider."); - } - continue; + final int id = InsetsSource.createId( + provider.getOwner(), provider.getIndex(), provider.getType()); + if (mLocalInsetsSourceProviders.get(id) == null) { + if (DEBUG) { + Slog.d(TAG, "Given " + provider + + " doesn't have a local insetsSourceProvider."); } - mLocalInsetsSourceProviders.remove(insetsTypes[i]); + return; } + mLocalInsetsSourceProviders.remove(id); + // Update insets if this window is attached. if (mDisplayContent != null) { mDisplayContent.getInsetsStateController().updateAboveInsetsState(true); diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index c74af8291142..806a32af4958 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -33,14 +33,14 @@ import static android.window.TaskFragmentOperation.OP_TYPE_SET_RELATIVE_BOUNDS; import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT; import static android.window.TaskFragmentOperation.OP_TYPE_UNKNOWN; import static android.window.WindowContainerTransaction.Change.CHANGE_RELATIVE_BOUNDS; -import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER; +import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_INSETS_FRAME_PROVIDER; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_FINISH_ACTIVITY; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_LAUNCH_TASK; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_PENDING_INTENT; -import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER; +import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_INSETS_FRAME_PROVIDER; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_TASK; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT; @@ -1055,28 +1055,24 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub taskDisplayArea.moveRootTaskBehindRootTask(thisTask.getRootTask(), restoreAt); break; } - case HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER: { - final Rect insetsProviderWindowContainer = hop.getInsetsProviderFrame(); - final WindowContainer container = - WindowContainer.fromBinder(hop.getContainer()); + case HIERARCHY_OP_TYPE_ADD_INSETS_FRAME_PROVIDER: { + final WindowContainer container = WindowContainer.fromBinder(hop.getContainer()); if (container == null) { Slog.e(TAG, "Attempt to add local insets source provider on unknown: " - + container); + + container); break; } - container.addLocalRectInsetsSourceProvider( - insetsProviderWindowContainer, hop.getInsetsTypes()); + container.addLocalInsetsFrameProvider(hop.getInsetsFrameProvider()); break; } - case HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER: { - final WindowContainer container = - WindowContainer.fromBinder(hop.getContainer()); + case HIERARCHY_OP_TYPE_REMOVE_INSETS_FRAME_PROVIDER: { + final WindowContainer container = WindowContainer.fromBinder(hop.getContainer()); if (container == null) { Slog.e(TAG, "Attempt to remove local insets source provider from unknown: " + container); break; } - container.removeLocalInsetsSourceProvider(hop.getInsetsTypes()); + container.removeLocalInsetsFrameProvider(hop.getInsetsFrameProvider()); break; } case HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP: { diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java index 5006bf72430c..6261e56a87c5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java @@ -22,8 +22,6 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; -import static android.view.InsetsState.ITYPE_BOTTOM_GENERIC_OVERLAY; -import static android.view.InsetsState.ITYPE_TOP_GENERIC_OVERLAY; import static android.view.WindowInsets.Type.systemOverlays; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; @@ -73,11 +71,13 @@ import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.view.IRemoteAnimationFinishedCallback; import android.view.IRemoteAnimationRunner; +import android.view.InsetsFrameProvider; import android.view.InsetsSource; import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceSession; +import android.view.WindowInsets; import android.view.WindowManager; import androidx.test.filters.SmallTest; @@ -1437,40 +1437,46 @@ public class WindowContainerTests extends WindowTestsBase { activity2.addWindow(createWindowState(attrs2, activity2)); Rect genericOverlayInsetsRect1 = new Rect(0, 200, 1080, 700); Rect genericOverlayInsetsRect2 = new Rect(0, 0, 1080, 200); - - rootTask.addLocalRectInsetsSourceProvider(genericOverlayInsetsRect1, - new int[]{ITYPE_TOP_GENERIC_OVERLAY}); - container.addLocalRectInsetsSourceProvider(genericOverlayInsetsRect2, - new int[]{ITYPE_BOTTOM_GENERIC_OVERLAY}); + final InsetsFrameProvider provider1 = + new InsetsFrameProvider(null, 1, WindowInsets.Type.systemOverlays()) + .setArbitraryRectangle(genericOverlayInsetsRect1); + final InsetsFrameProvider provider2 = + new InsetsFrameProvider(null, 2, WindowInsets.Type.systemOverlays()) + .setArbitraryRectangle(genericOverlayInsetsRect2); + final int sourceId1 = InsetsSource.createId( + provider1.getOwner(), provider1.getIndex(), provider1.getType()); + final int sourceId2 = InsetsSource.createId( + provider2.getOwner(), provider2.getIndex(), provider2.getType()); + + rootTask.addLocalInsetsFrameProvider(provider1); + container.addLocalInsetsFrameProvider(provider2); InsetsSource genericOverlayInsetsProvider1Source = new InsetsSource( - ITYPE_TOP_GENERIC_OVERLAY, systemOverlays()); + sourceId1, systemOverlays()); genericOverlayInsetsProvider1Source.setFrame(genericOverlayInsetsRect1); genericOverlayInsetsProvider1Source.setVisible(true); InsetsSource genericOverlayInsetsProvider2Source = new InsetsSource( - ITYPE_BOTTOM_GENERIC_OVERLAY, systemOverlays()); + sourceId2, systemOverlays()); genericOverlayInsetsProvider2Source.setFrame(genericOverlayInsetsRect2); genericOverlayInsetsProvider2Source.setVisible(true); activity0.forAllWindows(window -> { assertEquals(genericOverlayInsetsRect1, - window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY).getFrame()); + window.getInsetsState().peekSource(sourceId1).getFrame()); assertEquals(null, - window.getInsetsState().peekSource(ITYPE_BOTTOM_GENERIC_OVERLAY)); + window.getInsetsState().peekSource(sourceId2)); }, true); activity1.forAllWindows(window -> { assertEquals(genericOverlayInsetsRect1, - window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY).getFrame()); + window.getInsetsState().peekSource(sourceId1).getFrame()); assertEquals(genericOverlayInsetsRect2, - window.getInsetsState().peekSource(ITYPE_BOTTOM_GENERIC_OVERLAY) - .getFrame()); + window.getInsetsState().peekSource(sourceId2).getFrame()); }, true); activity2.forAllWindows(window -> { assertEquals(genericOverlayInsetsRect1, - window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY).getFrame()); + window.getInsetsState().peekSource(sourceId1).getFrame()); assertEquals(genericOverlayInsetsRect2, - window.getInsetsState().peekSource(ITYPE_BOTTOM_GENERIC_OVERLAY) - .getFrame()); + window.getInsetsState().peekSource(sourceId2).getFrame()); }, true); } @@ -1490,22 +1496,30 @@ public class WindowContainerTests extends WindowTestsBase { attrs.setTitle("AppWindow0"); activity0.addWindow(createWindowState(attrs, activity0)); - Rect genericOverlayInsetsRect1 = new Rect(0, 200, 1080, 700); - Rect genericOverlayInsetsRect2 = new Rect(0, 0, 1080, 200); - - rootTask.addLocalRectInsetsSourceProvider(genericOverlayInsetsRect1, - new int[]{ITYPE_TOP_GENERIC_OVERLAY}); + final Rect genericOverlayInsetsRect1 = new Rect(0, 200, 1080, 700); + final Rect genericOverlayInsetsRect2 = new Rect(0, 0, 1080, 200); + final InsetsFrameProvider provider1 = + new InsetsFrameProvider(null, 1, WindowInsets.Type.systemOverlays()) + .setArbitraryRectangle(genericOverlayInsetsRect1); + final InsetsFrameProvider provider2 = + new InsetsFrameProvider(null, 1, WindowInsets.Type.systemOverlays()) + .setArbitraryRectangle(genericOverlayInsetsRect2); + final int sourceId1 = InsetsSource.createId( + provider1.getOwner(), provider1.getIndex(), provider1.getType()); + final int sourceId2 = InsetsSource.createId( + provider2.getOwner(), provider2.getIndex(), provider2.getType()); + + rootTask.addLocalInsetsFrameProvider(provider1); activity0.forAllWindows(window -> { assertEquals(genericOverlayInsetsRect1, - window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY).getFrame()); + window.getInsetsState().peekSource(sourceId1).getFrame()); }, true); - rootTask.addLocalRectInsetsSourceProvider(genericOverlayInsetsRect2, - new int[]{ITYPE_TOP_GENERIC_OVERLAY}); + rootTask.addLocalInsetsFrameProvider(provider2); activity0.forAllWindows(window -> { assertEquals(genericOverlayInsetsRect2, - window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY).getFrame()); + window.getInsetsState().peekSource(sourceId2).getFrame()); }, true); } @@ -1543,35 +1557,44 @@ public class WindowContainerTests extends WindowTestsBase { activity2.addWindow(createWindowState(attrs2, activity2)); activity2.addWindow(createWindowState(attrs2, activity2)); - Rect navigationBarInsetsRect1 = new Rect(0, 200, 1080, 700); - Rect navigationBarInsetsRect2 = new Rect(0, 0, 1080, 200); - rootTask.addLocalRectInsetsSourceProvider(navigationBarInsetsRect1, - new int[]{ITYPE_TOP_GENERIC_OVERLAY}); - container.addLocalRectInsetsSourceProvider(navigationBarInsetsRect2, - new int[]{ITYPE_BOTTOM_GENERIC_OVERLAY}); + final Rect navigationBarInsetsRect1 = new Rect(0, 200, 1080, 700); + final Rect navigationBarInsetsRect2 = new Rect(0, 0, 1080, 200); + final InsetsFrameProvider provider1 = + new InsetsFrameProvider(null, 1, WindowInsets.Type.systemOverlays()) + .setArbitraryRectangle(navigationBarInsetsRect1); + final InsetsFrameProvider provider2 = + new InsetsFrameProvider(null, 2, WindowInsets.Type.systemOverlays()) + .setArbitraryRectangle(navigationBarInsetsRect2); + final int sourceId1 = InsetsSource.createId( + provider1.getOwner(), provider1.getIndex(), provider1.getType()); + final int sourceId2 = InsetsSource.createId( + provider2.getOwner(), provider2.getIndex(), provider2.getType()); + + rootTask.addLocalInsetsFrameProvider(provider1); + container.addLocalInsetsFrameProvider(provider2); mDisplayContent.getInsetsStateController().onPostLayout(); - rootTask.removeLocalInsetsSourceProvider(new int[]{ITYPE_TOP_GENERIC_OVERLAY}); + rootTask.removeLocalInsetsFrameProvider(provider1); mDisplayContent.getInsetsStateController().onPostLayout(); activity0.forAllWindows(window -> { assertEquals(null, - window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY)); + window.getInsetsState().peekSource(sourceId1)); assertEquals(null, - window.getInsetsState().peekSource(ITYPE_BOTTOM_GENERIC_OVERLAY)); + window.getInsetsState().peekSource(sourceId2)); }, true); activity1.forAllWindows(window -> { assertEquals(null, - window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY)); + window.getInsetsState().peekSource(sourceId1)); assertEquals(navigationBarInsetsRect2, - window.getInsetsState().peekSource(ITYPE_BOTTOM_GENERIC_OVERLAY) + window.getInsetsState().peekSource(sourceId2) .getFrame()); }, true); activity2.forAllWindows(window -> { assertEquals(null, - window.getInsetsState().peekSource(ITYPE_TOP_GENERIC_OVERLAY)); + window.getInsetsState().peekSource(sourceId1)); assertEquals(navigationBarInsetsRect2, - window.getInsetsState().peekSource(ITYPE_BOTTOM_GENERIC_OVERLAY) + window.getInsetsState().peekSource(sourceId2) .getFrame()); }, true); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index 17ad4e3a6d68..373f994f83a4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -30,7 +30,6 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED; import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED; -import static android.view.InsetsState.ITYPE_TOP_GENERIC_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; @@ -77,6 +76,7 @@ import android.util.ArrayMap; import android.util.Rational; import android.view.Display; import android.view.SurfaceControl; +import android.view.WindowInsets; import android.window.ITaskOrganizer; import android.window.IWindowContainerTransactionCallback; import android.window.StartingWindowInfo; @@ -785,44 +785,50 @@ public class WindowOrganizerTests extends WindowTestsBase { } @Test - public void testAddRectInsetsProvider() { + public void testAddInsetsSource() { final Task rootTask = createTask(mDisplayContent); final Task navigationBarInsetsReceiverTask = createTaskInRootTask(rootTask, 0); navigationBarInsetsReceiverTask.getConfiguration().windowConfiguration.setBounds(new Rect( 0, 200, 1080, 700)); - final Rect navigationBarInsetsProviderRect = new Rect(0, 0, 1080, 200); - final WindowContainerTransaction wct = new WindowContainerTransaction(); - wct.addRectInsetsProvider(navigationBarInsetsReceiverTask.mRemoteToken - .toWindowContainerToken(), navigationBarInsetsProviderRect, - new int[]{ITYPE_TOP_GENERIC_OVERLAY}); + wct.addInsetsSource( + navigationBarInsetsReceiverTask.mRemoteToken.toWindowContainerToken(), + new Binder(), + 0 /* index */, + WindowInsets.Type.systemOverlays(), + new Rect(0, 0, 1080, 200)); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); assertThat(navigationBarInsetsReceiverTask.mLocalInsetsSourceProviders - .valueAt(0).getSource().getId()).isEqualTo(ITYPE_TOP_GENERIC_OVERLAY); + .valueAt(0).getSource().getType()).isEqualTo( + WindowInsets.Type.systemOverlays()); } @Test - public void testRemoveInsetsProvider() { + public void testRemoveInsetsSource() { final Task rootTask = createTask(mDisplayContent); final Task navigationBarInsetsReceiverTask = createTaskInRootTask(rootTask, 0); navigationBarInsetsReceiverTask.getConfiguration().windowConfiguration.setBounds(new Rect( 0, 200, 1080, 700)); - - final Rect navigationBarInsetsProviderRect = new Rect(0, 0, 1080, 200); - + final Binder owner = new Binder(); final WindowContainerTransaction wct = new WindowContainerTransaction(); - wct.addRectInsetsProvider(navigationBarInsetsReceiverTask.mRemoteToken - .toWindowContainerToken(), navigationBarInsetsProviderRect, - new int[]{ITYPE_TOP_GENERIC_OVERLAY}); + wct.addInsetsSource( + navigationBarInsetsReceiverTask.mRemoteToken.toWindowContainerToken(), + owner, + 0 /* index */, + WindowInsets.Type.systemOverlays(), + new Rect(0, 0, 1080, 200)); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); final WindowContainerTransaction wct2 = new WindowContainerTransaction(); - wct2.removeInsetsProvider(navigationBarInsetsReceiverTask.mRemoteToken - .toWindowContainerToken(), new int[]{ITYPE_TOP_GENERIC_OVERLAY}); + wct2.removeInsetsSource( + navigationBarInsetsReceiverTask.mRemoteToken.toWindowContainerToken(), + owner, + 0 /* index */, + WindowInsets.Type.systemOverlays()); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct2); assertThat(navigationBarInsetsReceiverTask.mLocalInsetsSourceProviders.size()).isEqualTo(0); |