Loading core/java/android/view/InsetsFrameProvider.java +37 −103 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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(); } Loading @@ -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"; } Loading @@ -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) { mInsetsSize = in.readTypedObject(Insets.CREATOR); mInsetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR); } mArbitraryRectangle = in.readTypedObject(Rect.CREATOR); } @Override Loading @@ -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.writeTypedObject(mInsetsSize, flags); out.writeTypedArray(mInsetsSizeOverrides, flags); } out.writeTypedObject(mArbitraryRectangle, flags); } public boolean idEquals(InsetsFrameProvider o) { Loading @@ -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 = Loading @@ -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. Loading core/java/android/window/WindowContainerTransaction.java +47 −72 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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 Loading Loading @@ -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 + "}"; Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +8 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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]; Loading Loading @@ -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); } Loading Loading @@ -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); } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java +11 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) Loading Loading @@ -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); Loading @@ -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 Loading services/core/java/com/android/server/wm/DisplayPolicy.java +76 −23 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/view/InsetsFrameProvider.java +37 −103 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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(); } Loading @@ -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"; } Loading @@ -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) { mInsetsSize = in.readTypedObject(Insets.CREATOR); mInsetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR); } mArbitraryRectangle = in.readTypedObject(Rect.CREATOR); } @Override Loading @@ -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.writeTypedObject(mInsetsSize, flags); out.writeTypedArray(mInsetsSizeOverrides, flags); } out.writeTypedObject(mArbitraryRectangle, flags); } public boolean idEquals(InsetsFrameProvider o) { Loading @@ -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 = Loading @@ -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. Loading
core/java/android/window/WindowContainerTransaction.java +47 −72 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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 Loading Loading @@ -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 + "}"; Loading Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +8 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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]; Loading Loading @@ -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); } Loading Loading @@ -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); } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java +11 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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) Loading Loading @@ -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); Loading @@ -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 Loading
services/core/java/com/android/server/wm/DisplayPolicy.java +76 −23 File changed.Preview size limit exceeded, changes collapsed. Show changes