Loading core/java/android/window/TransitionInfo.java +8 −4 Original line number Diff line number Diff line Loading @@ -76,6 +76,9 @@ public final class TransitionInfo implements Parcelable { /** The container is the recipient of a transferred starting-window */ public static final int FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT = 1 << 3; /** The first unused bit. This can be used by remotes to attach custom flags to this change. */ public static final int FLAG_FIRST_CUSTOM = 1 << 4; /** @hide */ @IntDef(prefix = { "FLAG_" }, value = { FLAG_NONE, Loading Loading @@ -252,7 +255,8 @@ public final class TransitionInfo implements Parcelable { * Indication that `change` is independent of parents (ie. it has a different type of * transition vs. "going along for the ride") */ public static boolean isIndependent(TransitionInfo.Change change, TransitionInfo info) { public static boolean isIndependent(@NonNull TransitionInfo.Change change, @NonNull TransitionInfo info) { // If the change has no parent (it is root), then it is independent if (change.getParent() == null) return true; Loading Loading @@ -343,7 +347,7 @@ public final class TransitionInfo implements Parcelable { * Sets the taskinfo of this container if this is a task. WARNING: this takes the * reference, so don't modify it afterwards. */ public void setTaskInfo(ActivityManager.RunningTaskInfo taskInfo) { public void setTaskInfo(@Nullable ActivityManager.RunningTaskInfo taskInfo) { mTaskInfo = taskInfo; } Loading Loading @@ -424,8 +428,8 @@ public final class TransitionInfo implements Parcelable { return mEndRotation; } @Override /** @hide */ @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeTypedObject(mContainer, flags); dest.writeTypedObject(mParent, flags); Loading Loading @@ -454,8 +458,8 @@ public final class TransitionInfo implements Parcelable { } }; @Override /** @hide */ @Override public int describeContents() { return 0; } Loading core/java/android/window/WindowContainerTransaction.java +47 −7 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.app.WindowConfiguration; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -337,6 +338,18 @@ public final class WindowContainerTransaction implements Parcelable { return this; } /** * Starts a task by id. The task is expected to already exist (eg. as a recent task). * @param taskId Id of task to start. * @param options bundle containing ActivityOptions for the task's top activity. * @hide */ @NonNull public WindowContainerTransaction startTask(int taskId, @Nullable Bundle options) { mHierarchyOps.add(HierarchyOp.createForTaskLaunch(taskId, options)); return this; } /** * Merges another WCT into this one. * @param transfer When true, this will transfer everything from other potentially leaving Loading Loading @@ -663,6 +676,11 @@ public final class WindowContainerTransaction implements Parcelable { public static final int HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT = 2; public static final int HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT = 3; public static final int HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS = 4; public static final int HIERARCHY_OP_TYPE_LAUNCH_TASK = 5; // The following key(s) are for use with mLaunchOptions: // When launching a task (eg. from recents), this is the taskId to be launched. public static final String LAUNCH_KEY_TASK_ID = "android:transaction.hop.taskId"; private final int mType; Loading @@ -678,36 +696,47 @@ public final class WindowContainerTransaction implements Parcelable { final private int[] mWindowingModes; final private int[] mActivityTypes; private final Bundle mLaunchOptions; public static HierarchyOp createForReparent( @NonNull IBinder container, @Nullable IBinder reparent, boolean toTop) { return new HierarchyOp(HIERARCHY_OP_TYPE_REPARENT, container, reparent, null, null, toTop); container, reparent, null, null, toTop, null); } public static HierarchyOp createForReorder(@NonNull IBinder container, boolean toTop) { return new HierarchyOp(HIERARCHY_OP_TYPE_REORDER, container, container, null, null, toTop); container, container, null, null, toTop, null); } public static HierarchyOp createForChildrenTasksReparent(IBinder currentParent, IBinder newParent, int[] windowingModes, int[] activityTypes, boolean onTop) { return new HierarchyOp(HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT, currentParent, newParent, windowingModes, activityTypes, onTop); currentParent, newParent, windowingModes, activityTypes, onTop, null); } public static HierarchyOp createForSetLaunchRoot(IBinder container, int[] windowingModes, int[] activityTypes) { return new HierarchyOp(HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT, container, null, windowingModes, activityTypes, false); container, null, windowingModes, activityTypes, false, null); } public static HierarchyOp createForAdjacentRoots(IBinder root1, IBinder root2) { return new HierarchyOp(HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS, root1, root2, null, null, false); root1, root2, null, null, false, null); } /** Create a hierarchy op for launching a task. */ public static HierarchyOp createForTaskLaunch(int taskId, @Nullable Bundle options) { final Bundle fullOptions = options == null ? new Bundle() : options; fullOptions.putInt(LAUNCH_KEY_TASK_ID, taskId); return new HierarchyOp(HIERARCHY_OP_TYPE_LAUNCH_TASK, null, null, null, null, true, fullOptions); } private HierarchyOp(int type, @NonNull IBinder container, @Nullable IBinder reparent, int[] windowingModes, int[] activityTypes, boolean toTop) { private HierarchyOp(int type, @Nullable IBinder container, @Nullable IBinder reparent, int[] windowingModes, int[] activityTypes, boolean toTop, @Nullable Bundle launchOptions) { mType = type; mContainer = container; mReparent = reparent; Loading @@ -716,6 +745,7 @@ public final class WindowContainerTransaction implements Parcelable { mActivityTypes = activityTypes != null ? Arrays.copyOf(activityTypes, activityTypes.length) : null; mToTop = toTop; mLaunchOptions = launchOptions; } public HierarchyOp(@NonNull HierarchyOp copy) { Loading @@ -725,6 +755,7 @@ public final class WindowContainerTransaction implements Parcelable { mToTop = copy.mToTop; mWindowingModes = copy.mWindowingModes; mActivityTypes = copy.mActivityTypes; mLaunchOptions = copy.mLaunchOptions; } protected HierarchyOp(Parcel in) { Loading @@ -734,6 +765,7 @@ public final class WindowContainerTransaction implements Parcelable { mToTop = in.readBoolean(); mWindowingModes = in.createIntArray(); mActivityTypes = in.createIntArray(); mLaunchOptions = in.readBundle(); } public int getType() { Loading Loading @@ -771,6 +803,11 @@ public final class WindowContainerTransaction implements Parcelable { return mActivityTypes; } @Nullable public Bundle getLaunchOptions() { return mLaunchOptions; } @Override public String toString() { switch (mType) { Loading @@ -790,6 +827,8 @@ public final class WindowContainerTransaction implements Parcelable { case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS: return "{SetAdjacentRoot: container=" + mContainer + " adjacentRoot=" + mReparent + "}"; case HIERARCHY_OP_TYPE_LAUNCH_TASK: return "{LaunchTask: " + mLaunchOptions + "}"; default: return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent + " mToTop=" + mToTop + " mWindowingMode=" + mWindowingModes Loading @@ -805,6 +844,7 @@ public final class WindowContainerTransaction implements Parcelable { dest.writeBoolean(mToTop); dest.writeIntArray(mWindowingModes); dest.writeIntArray(mActivityTypes); dest.writeBundle(mLaunchOptions); } @Override Loading services/core/java/com/android/server/wm/WindowOrganizerController.java +20 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.wm; import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_LAUNCH_TASK; 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_SET_ADJACENT_ROOTS; Loading @@ -38,6 +39,7 @@ import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; Loading Loading @@ -191,6 +193,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub if (type < 0) { throw new IllegalArgumentException("Can't create transition with no type"); } if (mTransitionController.getTransitionPlayer() == null) { Slog.w(TAG, "Using shell transitions API for legacy transitions."); if (t == null) { throw new IllegalArgumentException("Can't use legacy transitions in" + " compatibility mode with no WCT."); } applyTransaction(t, -1 /* syncId */, null); return null; } transition = mTransitionController.createTransition(type); } transition.start(); Loading Loading @@ -346,6 +357,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } } effects |= sanitizeAndApplyHierarchyOp(wc, hop); break; case HIERARCHY_OP_TYPE_LAUNCH_TASK: Bundle launchOpts = hop.getLaunchOptions(); int taskId = launchOpts.getInt( WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID); launchOpts.remove( WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID); mService.startActivityFromRecents(taskId, launchOpts); break; } } } Loading services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +23 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.wm; import static android.app.ActivityManager.START_CANCELED; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; Loading Loading @@ -55,6 +56,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; Loading @@ -68,6 +70,7 @@ import android.content.pm.ParceledListSlice; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; Loading Loading @@ -1315,6 +1318,26 @@ public class WindowOrganizerTests extends WindowTestsBase { assertFalse(info.topActivityInSizeCompat); } @Test public void testStartTasksInTransaction() { WindowContainerTransaction wct = new WindowContainerTransaction(); Bundle testOptions = new Bundle(); testOptions.putInt("test", 20); wct.startTask(1, null /* options */); wct.startTask(2, testOptions); spyOn(mWm.mAtmService); doReturn(START_CANCELED).when(mWm.mAtmService).startActivityFromRecents(anyInt(), any()); clearInvocations(mWm.mAtmService); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); verify(mWm.mAtmService, times(1)).startActivityFromRecents(eq(1), bundleCaptor.capture()); assertTrue(bundleCaptor.getValue().isEmpty()); verify(mWm.mAtmService, times(1)).startActivityFromRecents(eq(2), bundleCaptor.capture()); assertEquals(20, bundleCaptor.getValue().getInt("test")); } /** * Verifies that task vanished is called for a specific task. */ Loading Loading
core/java/android/window/TransitionInfo.java +8 −4 Original line number Diff line number Diff line Loading @@ -76,6 +76,9 @@ public final class TransitionInfo implements Parcelable { /** The container is the recipient of a transferred starting-window */ public static final int FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT = 1 << 3; /** The first unused bit. This can be used by remotes to attach custom flags to this change. */ public static final int FLAG_FIRST_CUSTOM = 1 << 4; /** @hide */ @IntDef(prefix = { "FLAG_" }, value = { FLAG_NONE, Loading Loading @@ -252,7 +255,8 @@ public final class TransitionInfo implements Parcelable { * Indication that `change` is independent of parents (ie. it has a different type of * transition vs. "going along for the ride") */ public static boolean isIndependent(TransitionInfo.Change change, TransitionInfo info) { public static boolean isIndependent(@NonNull TransitionInfo.Change change, @NonNull TransitionInfo info) { // If the change has no parent (it is root), then it is independent if (change.getParent() == null) return true; Loading Loading @@ -343,7 +347,7 @@ public final class TransitionInfo implements Parcelable { * Sets the taskinfo of this container if this is a task. WARNING: this takes the * reference, so don't modify it afterwards. */ public void setTaskInfo(ActivityManager.RunningTaskInfo taskInfo) { public void setTaskInfo(@Nullable ActivityManager.RunningTaskInfo taskInfo) { mTaskInfo = taskInfo; } Loading Loading @@ -424,8 +428,8 @@ public final class TransitionInfo implements Parcelable { return mEndRotation; } @Override /** @hide */ @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeTypedObject(mContainer, flags); dest.writeTypedObject(mParent, flags); Loading Loading @@ -454,8 +458,8 @@ public final class TransitionInfo implements Parcelable { } }; @Override /** @hide */ @Override public int describeContents() { return 0; } Loading
core/java/android/window/WindowContainerTransaction.java +47 −7 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.app.WindowConfiguration; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -337,6 +338,18 @@ public final class WindowContainerTransaction implements Parcelable { return this; } /** * Starts a task by id. The task is expected to already exist (eg. as a recent task). * @param taskId Id of task to start. * @param options bundle containing ActivityOptions for the task's top activity. * @hide */ @NonNull public WindowContainerTransaction startTask(int taskId, @Nullable Bundle options) { mHierarchyOps.add(HierarchyOp.createForTaskLaunch(taskId, options)); return this; } /** * Merges another WCT into this one. * @param transfer When true, this will transfer everything from other potentially leaving Loading Loading @@ -663,6 +676,11 @@ public final class WindowContainerTransaction implements Parcelable { public static final int HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT = 2; public static final int HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT = 3; public static final int HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS = 4; public static final int HIERARCHY_OP_TYPE_LAUNCH_TASK = 5; // The following key(s) are for use with mLaunchOptions: // When launching a task (eg. from recents), this is the taskId to be launched. public static final String LAUNCH_KEY_TASK_ID = "android:transaction.hop.taskId"; private final int mType; Loading @@ -678,36 +696,47 @@ public final class WindowContainerTransaction implements Parcelable { final private int[] mWindowingModes; final private int[] mActivityTypes; private final Bundle mLaunchOptions; public static HierarchyOp createForReparent( @NonNull IBinder container, @Nullable IBinder reparent, boolean toTop) { return new HierarchyOp(HIERARCHY_OP_TYPE_REPARENT, container, reparent, null, null, toTop); container, reparent, null, null, toTop, null); } public static HierarchyOp createForReorder(@NonNull IBinder container, boolean toTop) { return new HierarchyOp(HIERARCHY_OP_TYPE_REORDER, container, container, null, null, toTop); container, container, null, null, toTop, null); } public static HierarchyOp createForChildrenTasksReparent(IBinder currentParent, IBinder newParent, int[] windowingModes, int[] activityTypes, boolean onTop) { return new HierarchyOp(HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT, currentParent, newParent, windowingModes, activityTypes, onTop); currentParent, newParent, windowingModes, activityTypes, onTop, null); } public static HierarchyOp createForSetLaunchRoot(IBinder container, int[] windowingModes, int[] activityTypes) { return new HierarchyOp(HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT, container, null, windowingModes, activityTypes, false); container, null, windowingModes, activityTypes, false, null); } public static HierarchyOp createForAdjacentRoots(IBinder root1, IBinder root2) { return new HierarchyOp(HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS, root1, root2, null, null, false); root1, root2, null, null, false, null); } /** Create a hierarchy op for launching a task. */ public static HierarchyOp createForTaskLaunch(int taskId, @Nullable Bundle options) { final Bundle fullOptions = options == null ? new Bundle() : options; fullOptions.putInt(LAUNCH_KEY_TASK_ID, taskId); return new HierarchyOp(HIERARCHY_OP_TYPE_LAUNCH_TASK, null, null, null, null, true, fullOptions); } private HierarchyOp(int type, @NonNull IBinder container, @Nullable IBinder reparent, int[] windowingModes, int[] activityTypes, boolean toTop) { private HierarchyOp(int type, @Nullable IBinder container, @Nullable IBinder reparent, int[] windowingModes, int[] activityTypes, boolean toTop, @Nullable Bundle launchOptions) { mType = type; mContainer = container; mReparent = reparent; Loading @@ -716,6 +745,7 @@ public final class WindowContainerTransaction implements Parcelable { mActivityTypes = activityTypes != null ? Arrays.copyOf(activityTypes, activityTypes.length) : null; mToTop = toTop; mLaunchOptions = launchOptions; } public HierarchyOp(@NonNull HierarchyOp copy) { Loading @@ -725,6 +755,7 @@ public final class WindowContainerTransaction implements Parcelable { mToTop = copy.mToTop; mWindowingModes = copy.mWindowingModes; mActivityTypes = copy.mActivityTypes; mLaunchOptions = copy.mLaunchOptions; } protected HierarchyOp(Parcel in) { Loading @@ -734,6 +765,7 @@ public final class WindowContainerTransaction implements Parcelable { mToTop = in.readBoolean(); mWindowingModes = in.createIntArray(); mActivityTypes = in.createIntArray(); mLaunchOptions = in.readBundle(); } public int getType() { Loading Loading @@ -771,6 +803,11 @@ public final class WindowContainerTransaction implements Parcelable { return mActivityTypes; } @Nullable public Bundle getLaunchOptions() { return mLaunchOptions; } @Override public String toString() { switch (mType) { Loading @@ -790,6 +827,8 @@ public final class WindowContainerTransaction implements Parcelable { case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS: return "{SetAdjacentRoot: container=" + mContainer + " adjacentRoot=" + mReparent + "}"; case HIERARCHY_OP_TYPE_LAUNCH_TASK: return "{LaunchTask: " + mLaunchOptions + "}"; default: return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent + " mToTop=" + mToTop + " mWindowingMode=" + mWindowingModes Loading @@ -805,6 +844,7 @@ public final class WindowContainerTransaction implements Parcelable { dest.writeBoolean(mToTop); dest.writeIntArray(mWindowingModes); dest.writeIntArray(mActivityTypes); dest.writeBundle(mLaunchOptions); } @Override Loading
services/core/java/com/android/server/wm/WindowOrganizerController.java +20 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.wm; import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_LAUNCH_TASK; 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_SET_ADJACENT_ROOTS; Loading @@ -38,6 +39,7 @@ import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; Loading Loading @@ -191,6 +193,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub if (type < 0) { throw new IllegalArgumentException("Can't create transition with no type"); } if (mTransitionController.getTransitionPlayer() == null) { Slog.w(TAG, "Using shell transitions API for legacy transitions."); if (t == null) { throw new IllegalArgumentException("Can't use legacy transitions in" + " compatibility mode with no WCT."); } applyTransaction(t, -1 /* syncId */, null); return null; } transition = mTransitionController.createTransition(type); } transition.start(); Loading Loading @@ -346,6 +357,15 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } } effects |= sanitizeAndApplyHierarchyOp(wc, hop); break; case HIERARCHY_OP_TYPE_LAUNCH_TASK: Bundle launchOpts = hop.getLaunchOptions(); int taskId = launchOpts.getInt( WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID); launchOpts.remove( WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID); mService.startActivityFromRecents(taskId, launchOpts); break; } } } Loading
services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +23 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.wm; import static android.app.ActivityManager.START_CANCELED; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; Loading Loading @@ -55,6 +56,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; Loading @@ -68,6 +70,7 @@ import android.content.pm.ParceledListSlice; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; Loading Loading @@ -1315,6 +1318,26 @@ public class WindowOrganizerTests extends WindowTestsBase { assertFalse(info.topActivityInSizeCompat); } @Test public void testStartTasksInTransaction() { WindowContainerTransaction wct = new WindowContainerTransaction(); Bundle testOptions = new Bundle(); testOptions.putInt("test", 20); wct.startTask(1, null /* options */); wct.startTask(2, testOptions); spyOn(mWm.mAtmService); doReturn(START_CANCELED).when(mWm.mAtmService).startActivityFromRecents(anyInt(), any()); clearInvocations(mWm.mAtmService); mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct); final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); verify(mWm.mAtmService, times(1)).startActivityFromRecents(eq(1), bundleCaptor.capture()); assertTrue(bundleCaptor.getValue().isEmpty()); verify(mWm.mAtmService, times(1)).startActivityFromRecents(eq(2), bundleCaptor.capture()); assertEquals(20, bundleCaptor.getValue().getInt("test")); } /** * Verifies that task vanished is called for a specific task. */ Loading