Merge "Add client API to add/remove insets-provider." into tm-dev am: 4b9e5c8811

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16945210

Change-Id: I449a6ae870b7e1fd886ad97506f8e0f5a6e97407
This commit is contained in:
Gaurav Bhola
2022-03-01 17:34:12 +00:00
committed by Automerger Merge Worker
3 changed files with 162 additions and 0 deletions

View File

@@ -31,6 +31,7 @@ import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
import android.view.InsetsState;
import android.view.SurfaceControl;
import java.util.ArrayList;
@@ -588,6 +589,56 @@ public final class WindowContainerTransaction implements Parcelable {
return this;
}
/**
* 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}.
*
* @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
* @hide
*/
@NonNull
public WindowContainerTransaction addRectInsetsProvider(
@NonNull WindowContainerToken receiverWindowContainer,
@NonNull Rect insetsProviderFrame,
@InsetsState.InternalInsetsType int[] insetsTypes) {
final HierarchyOp hierarchyOp =
new HierarchyOp.Builder(
HierarchyOp.HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER)
.setContainer(receiverWindowContainer.asBinder())
.setInsetsProviderFrame(insetsProviderFrame)
.setInsetsTypes(insetsTypes)
.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}.
*
* @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
* @hide
*/
@NonNull
public WindowContainerTransaction removeInsetsProvider(
@NonNull WindowContainerToken receiverWindowContainer,
@InsetsState.InternalInsetsType int[] insetsTypes) {
final HierarchyOp hierarchyOp =
new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER)
.setContainer(receiverWindowContainer.asBinder())
.setInsetsTypes(insetsTypes)
.build();
mHierarchyOps.add(hierarchyOp);
return this;
}
/**
* When this {@link WindowContainerTransaction} failed to finish on the server side, it will
* trigger callback with this {@param errorCallbackToken}.
@@ -993,6 +1044,8 @@ public final class WindowContainerTransaction implements Parcelable {
public static final int HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS = 13;
public static final int HIERARCHY_OP_TYPE_START_SHORTCUT = 14;
public static final int HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER = 15;
public static final int HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER = 16;
public static final int HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER = 17;
// The following key(s) are for use with mLaunchOptions:
// When launching a task (eg. from recents), this is the taskId to be launched.
@@ -1012,6 +1065,10 @@ public final class WindowContainerTransaction implements Parcelable {
@Nullable
private IBinder mReparent;
private @InsetsState.InternalInsetsType int[] mInsetsTypes;
private Rect mInsetsProviderFrame;
// Moves/reparents to top of parent when {@code true}, otherwise moves/reparents to bottom.
private boolean mToTop;
@@ -1130,6 +1187,8 @@ public final class WindowContainerTransaction implements Parcelable {
mType = copy.mType;
mContainer = copy.mContainer;
mReparent = copy.mReparent;
mInsetsTypes = copy.mInsetsTypes;
mInsetsProviderFrame = copy.mInsetsProviderFrame;
mToTop = copy.mToTop;
mReparentTopOnly = copy.mReparentTopOnly;
mMoveAdjacentTogether = copy.mMoveAdjacentTogether;
@@ -1146,6 +1205,12 @@ 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;
}
mToTop = in.readBoolean();
mReparentTopOnly = in.readBoolean();
mMoveAdjacentTogether = in.readBoolean();
@@ -1171,6 +1236,15 @@ public final class WindowContainerTransaction implements Parcelable {
return mReparent;
}
@Nullable
public @InsetsState.InternalInsetsType int[] getInsetsTypes() {
return mInsetsTypes;
}
public Rect getInsetsProviderFrame() {
return mInsetsProviderFrame;
}
@NonNull
public IBinder getContainer() {
return mContainer;
@@ -1276,6 +1350,13 @@ 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:
return "{addRectInsetsProvider: container=" + mContainer
+ " insetsProvidingFrame=" + mInsetsProviderFrame
+ " insetsType=" + Arrays.toString(mInsetsTypes) + "}";
case HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER:
return "{removeLocalInsetsProvider: container=" + mContainer
+ " insetsType=" + Arrays.toString(mInsetsTypes) + "}";
default:
return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent
+ " mToTop=" + mToTop
@@ -1289,6 +1370,13 @@ 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.writeBoolean(mToTop);
dest.writeBoolean(mReparentTopOnly);
dest.writeBoolean(mMoveAdjacentTogether);
@@ -1328,6 +1416,10 @@ public final class WindowContainerTransaction implements Parcelable {
@Nullable
private IBinder mReparent;
private int[] mInsetsTypes;
private Rect mInsetsProviderFrame;
private boolean mToTop;
private boolean mReparentTopOnly;
@@ -1369,6 +1461,16 @@ public final class WindowContainerTransaction implements Parcelable {
return this;
}
Builder setInsetsTypes(int[] insetsTypes) {
mInsetsTypes = insetsTypes;
return this;
}
Builder setInsetsProviderFrame(Rect insetsProviderFrame) {
mInsetsProviderFrame = insetsProviderFrame;
return this;
}
Builder setToTop(boolean toTop) {
mToTop = toTop;
return this;
@@ -1430,6 +1532,8 @@ public final class WindowContainerTransaction implements Parcelable {
hierarchyOp.mActivityTypes = mActivityTypes != null
? Arrays.copyOf(mActivityTypes, mActivityTypes.length)
: null;
hierarchyOp.mInsetsTypes = mInsetsTypes;
hierarchyOp.mInsetsProviderFrame = mInsetsProviderFrame;
hierarchyOp.mToTop = mToTop;
hierarchyOp.mReparentTopOnly = mReparentTopOnly;
hierarchyOp.mMoveAdjacentTogether = mMoveAdjacentTogether;

View File

@@ -21,11 +21,13 @@ import static android.app.ActivityManager.isStartResultSuccessful;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.window.WindowContainerTransaction.Change.CHANGE_BOUNDS_TRANSACTION;
import static android.window.WindowContainerTransaction.Change.CHANGE_BOUNDS_TRANSACTION_RECT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT;
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_REORDER;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
@@ -895,6 +897,17 @@ 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 receiverWindowContainer =
WindowContainer.fromBinder(hop.getContainer());
receiverWindowContainer.addLocalRectInsetsSourceProvider(
insetsProviderWindowContainer, hop.getInsetsTypes());
break;
case HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER:
WindowContainer.fromBinder(hop.getContainer())
.removeLocalInsetsSourceProvider(hop.getInsetsTypes());
break;
}
return effects;
}

View File

@@ -30,6 +30,7 @@ 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_LOCAL_NAVIGATION_BAR_1;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
@@ -610,6 +611,50 @@ public class WindowOrganizerTests extends WindowTestsBase {
assertEquals(ACTIVITY_TYPE_UNDEFINED, info1.topActivityType);
}
@Test
public void testAddRectInsetsProvider() {
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_LOCAL_NAVIGATION_BAR_1});
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
assertThat(navigationBarInsetsReceiverTask.mLocalInsetsSourceProviders
.valueAt(0).getSource().getType()).isEqualTo(ITYPE_LOCAL_NAVIGATION_BAR_1);
}
@Test
public void testRemoveInsetsProvider() {
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_LOCAL_NAVIGATION_BAR_1});
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
final WindowContainerTransaction wct2 = new WindowContainerTransaction();
wct2.removeInsetsProvider(navigationBarInsetsReceiverTask.mRemoteToken
.toWindowContainerToken(), new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct2);
assertThat(navigationBarInsetsReceiverTask.mLocalInsetsSourceProviders.size()).isEqualTo(0);
}
@UseTestDisplay
@Test
public void testTaskInfoCallback() {