Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +16 −72 Original line number Diff line number Diff line Loading @@ -1322,7 +1322,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen mPresenter.expandTaskFragment(wct, container); } else { // Put activity into a new expanded container. final TaskFragmentContainer newContainer = newContainer(activity, getTaskId(activity)); final TaskFragmentContainer newContainer = new TaskFragmentContainer.Builder(this, getTaskId(activity), activity) .setPendingAppearedActivity(activity).build(); mPresenter.expandActivity(wct, newContainer.getTaskFragmentToken(), activity); } } Loading Loading @@ -1738,9 +1740,13 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Can't find any activity in the Task that we can use as the owner activity. return null; } final TaskFragmentContainer container = newContainer(null /* pendingAppearedActivity */, intent, activityInTask, taskId, null /* pairedPrimaryContainer*/, overlayTag, launchOptions, associateLaunchingActivity); final TaskFragmentContainer container = new TaskFragmentContainer.Builder(this, taskId, activityInTask) .setPendingAppearedIntent(intent) .setOverlayTag(overlayTag) .setLaunchOptions(launchOptions) .setAssociatedActivity(associateLaunchingActivity ? activityInTask : null) .build(); final IBinder taskFragmentToken = container.getTaskFragmentToken(); // Note that taskContainer will not exist before calling #newContainer if the container // is the first embedded TF in the task. Loading Loading @@ -1818,74 +1824,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return null; } @GuardedBy("mLock") TaskFragmentContainer newContainer(@NonNull Activity pendingAppearedActivity, int taskId) { return newContainer(pendingAppearedActivity, pendingAppearedActivity, taskId); } @GuardedBy("mLock") TaskFragmentContainer newContainer(@NonNull Activity pendingAppearedActivity, @NonNull Activity activityInTask, int taskId) { return newContainer(pendingAppearedActivity, null /* pendingAppearedIntent */, activityInTask, taskId, null /* pairedPrimaryContainer */, null /* tag */, null /* launchOptions */, false /* associateLaunchingActivity */); } @GuardedBy("mLock") TaskFragmentContainer newContainer(@NonNull Intent pendingAppearedIntent, @NonNull Activity activityInTask, int taskId) { return newContainer(null /* pendingAppearedActivity */, pendingAppearedIntent, activityInTask, taskId, null /* pairedPrimaryContainer */, null /* tag */, null /* launchOptions */, false /* associateLaunchingActivity */); } @GuardedBy("mLock") TaskFragmentContainer newContainer(@NonNull Intent pendingAppearedIntent, @NonNull Activity activityInTask, int taskId, @NonNull TaskFragmentContainer pairedPrimaryContainer) { return newContainer(null /* pendingAppearedActivity */, pendingAppearedIntent, activityInTask, taskId, pairedPrimaryContainer, null /* tag */, null /* launchOptions */, false /* associateLaunchingActivity */); } /** * Creates and registers a new organized container with an optional activity that will be * re-parented to it in a WCT. * * @param pendingAppearedActivity the activity that will be reparented to the TaskFragment. * @param pendingAppearedIntent the Intent that will be started in the TaskFragment. * @param activityInTask activity in the same Task so that we can get the Task bounds * if needed. * @param taskId parent Task of the new TaskFragment. * @param pairedContainer the paired primary {@link TaskFragmentContainer}. When it is * set, the new container will be added right above it. * @param overlayTag The tag for the new created overlay container. It must be * needed if {@code isOverlay} is {@code true}. Otherwise, * it should be {@code null}. * @param launchOptions The launch options bundle to create a container. Must be * specified for overlay container. * @param associateLaunchingActivity {@code true} to indicate this overlay container * should associate with launching activity. */ @GuardedBy("mLock") TaskFragmentContainer newContainer(@Nullable Activity pendingAppearedActivity, @Nullable Intent pendingAppearedIntent, @NonNull Activity activityInTask, int taskId, @Nullable TaskFragmentContainer pairedContainer, @Nullable String overlayTag, @Nullable Bundle launchOptions, boolean associateLaunchingActivity) { if (activityInTask == null) { throw new IllegalArgumentException("activityInTask must not be null,"); } if (!mTaskContainers.contains(taskId)) { mTaskContainers.put(taskId, new TaskContainer(taskId, activityInTask)); mDividerPresenters.put(taskId, new DividerPresenter(taskId, this, mExecutor)); } final TaskContainer taskContainer = mTaskContainers.get(taskId); final TaskFragmentContainer container = new TaskFragmentContainer(pendingAppearedActivity, pendingAppearedIntent, taskContainer, this, pairedContainer, overlayTag, launchOptions, associateLaunchingActivity ? activityInTask : null); return container; } /** * Creates and registers a new split with the provided containers and configuration. Finishes * existing secondary containers if found for the given primary container. Loading Loading @@ -2581,6 +2519,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return mTaskContainers.get(taskId); } @GuardedBy("mLock") void addTaskContainer(int taskId, TaskContainer taskContainer) { mTaskContainers.put(taskId, taskContainer); mDividerPresenters.put(taskId, new DividerPresenter(taskId, this, mExecutor)); } Handler getHandler() { return mHandler; } Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +15 −9 Original line number Diff line number Diff line Loading @@ -186,8 +186,9 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { // Create new empty task fragment final int taskId = primaryContainer.getTaskId(); final TaskFragmentContainer secondaryContainer = mController.newContainer( secondaryIntent, primaryActivity, taskId); final TaskFragmentContainer secondaryContainer = new TaskFragmentContainer.Builder(mController, taskId, primaryActivity) .setPendingAppearedIntent(secondaryIntent).build(); final Rect secondaryRelBounds = getRelBoundsForPosition(POSITION_END, taskProperties, splitAttributes); final int windowingMode = mController.getTaskContainer(taskId) Loading Loading @@ -261,7 +262,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { TaskFragmentContainer container = mController.getContainerWithActivity(activity); final int taskId = container != null ? container.getTaskId() : activity.getTaskId(); if (container == null || container == containerToAvoid) { container = mController.newContainer(activity, taskId); container = new TaskFragmentContainer.Builder(mController, taskId, activity) .setPendingAppearedActivity(activity).build(); final int windowingMode = mController.getTaskContainer(taskId) .getWindowingModeForTaskFragment(relBounds); final IBinder reparentActivityToken = activity.getActivityToken(); Loading Loading @@ -304,15 +306,19 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { TaskFragmentContainer primaryContainer = mController.getContainerWithActivity( launchingActivity); if (primaryContainer == null) { primaryContainer = mController.newContainer(launchingActivity, launchingActivity.getTaskId()); primaryContainer = new TaskFragmentContainer.Builder(mController, launchingActivity.getTaskId(), launchingActivity) .setPendingAppearedActivity(launchingActivity).build(); } final int taskId = primaryContainer.getTaskId(); final TaskFragmentContainer secondaryContainer = mController.newContainer(activityIntent, launchingActivity, taskId, // Pass in the primary container to make sure it is added right above the primary. primaryContainer); final TaskFragmentContainer secondaryContainer = new TaskFragmentContainer.Builder(mController, taskId, launchingActivity) .setPendingAppearedIntent(activityIntent) // Pass in the primary container to make sure it is added right above the // primary. .setPairedPrimaryContainer(primaryContainer) .build(); final TaskContainer taskContainer = mController.getTaskContainer(taskId); final int windowingMode = taskContainer.getWindowingModeForTaskFragment( primaryRelBounds); Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java +112 −21 Original line number Diff line number Diff line Loading @@ -194,20 +194,6 @@ class TaskFragmentContainer { */ private boolean mLastDimOnTask; /** * @see #TaskFragmentContainer(Activity, Intent, TaskContainer, SplitController, * TaskFragmentContainer, String, Bundle, Activity) */ TaskFragmentContainer(@Nullable Activity pendingAppearedActivity, @Nullable Intent pendingAppearedIntent, @NonNull TaskContainer taskContainer, @NonNull SplitController controller, @Nullable TaskFragmentContainer pairedPrimaryContainer) { this(pendingAppearedActivity, pendingAppearedIntent, taskContainer, controller, pairedPrimaryContainer, null /* overlayTag */, null /* launchOptions */, null /* associatedActivity */); } /** * Creates a container with an existing activity that will be re-parented to it in a window * container transaction. Loading @@ -218,7 +204,7 @@ class TaskFragmentContainer { * @param associatedActivity the associated activity of the overlay container. Must be * {@code null} for a non-overlay container. */ TaskFragmentContainer(@Nullable Activity pendingAppearedActivity, private TaskFragmentContainer(@Nullable Activity pendingAppearedActivity, @Nullable Intent pendingAppearedIntent, @NonNull TaskContainer taskContainer, @NonNull SplitController controller, @Nullable TaskFragmentContainer pairedPrimaryContainer, @Nullable String overlayTag, Loading @@ -232,12 +218,6 @@ class TaskFragmentContainer { mToken = new Binder("TaskFragmentContainer"); mTaskContainer = taskContainer; mOverlayTag = overlayTag; if (overlayTag != null) { Objects.requireNonNull(launchOptions); } else if (associatedActivity != null) { throw new IllegalArgumentException("Associated activity must be null for " + "non-overlay activity."); } mAssociatedActivityToken = associatedActivity != null ? associatedActivity.getActivityToken() : null; Loading Loading @@ -1116,6 +1096,117 @@ class TaskFragmentContainer { return sb.append("]").toString(); } static final class Builder { @NonNull private final SplitController mSplitController; // The parent Task id of the new TaskFragment. private final int mTaskId; // The activity in the same Task so that we can get the Task bounds if needed. @NonNull private final Activity mActivityInTask; // The activity that will be reparented to the TaskFragment. @Nullable private Activity mPendingAppearedActivity; // The Intent that will be started in the TaskFragment. @Nullable private Intent mPendingAppearedIntent; // The paired primary {@link TaskFragmentContainer}. When it is set, the new container // will be added right above it. @Nullable private TaskFragmentContainer mPairedPrimaryContainer; // The launch options bundle to create a container. Must be specified for overlay container. @Nullable private Bundle mLaunchOptions; // The tag for the new created overlay container. This is required when creating an // overlay container. @Nullable private String mOverlayTag; // The associated activity of the overlay container. Must be {@code null} for a // non-overlay container. @Nullable private Activity mAssociatedActivity; Builder(@NonNull SplitController splitController, int taskId, @Nullable Activity activityInTask) { if (taskId <= 0) { throw new IllegalArgumentException("taskId is invalid, " + taskId); } mSplitController = splitController; mTaskId = taskId; mActivityInTask = activityInTask; } @NonNull Builder setPendingAppearedActivity(@Nullable Activity pendingAppearedActivity) { mPendingAppearedActivity = pendingAppearedActivity; return this; } @NonNull Builder setPendingAppearedIntent(@Nullable Intent pendingAppearedIntent) { mPendingAppearedIntent = pendingAppearedIntent; return this; } @NonNull Builder setPairedPrimaryContainer(@Nullable TaskFragmentContainer pairedPrimaryContainer) { mPairedPrimaryContainer = pairedPrimaryContainer; return this; } @NonNull Builder setLaunchOptions(@Nullable Bundle launchOptions) { mLaunchOptions = launchOptions; return this; } @NonNull Builder setOverlayTag(@Nullable String overlayTag) { mOverlayTag = overlayTag; return this; } @NonNull Builder setAssociatedActivity(@Nullable Activity associatedActivity) { mAssociatedActivity = associatedActivity; return this; } @NonNull TaskFragmentContainer build() { if (mOverlayTag != null) { Objects.requireNonNull(mLaunchOptions); } else if (mAssociatedActivity != null) { throw new IllegalArgumentException("Associated activity must be null for " + "non-overlay activity."); } TaskContainer taskContainer = mSplitController.getTaskContainer(mTaskId); if (taskContainer == null && mActivityInTask == null) { throw new IllegalArgumentException("mActivityInTask must be set."); } if (taskContainer == null) { // Adding a TaskContainer if no existed one. taskContainer = new TaskContainer(mTaskId, mActivityInTask); mSplitController.addTaskContainer(mTaskId, taskContainer); } return new TaskFragmentContainer(mPendingAppearedActivity, mPendingAppearedIntent, taskContainer, mSplitController, mPairedPrimaryContainer, mOverlayTag, mLaunchOptions, mAssociatedActivity); } } static class OverlayContainerRestoreParams { /** The token of the overlay container */ @NonNull Loading libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java +13 −0 Original line number Diff line number Diff line Loading @@ -248,4 +248,17 @@ public class EmbeddingTestUtils { return new SplitPlaceholderRule.Builder(placeholderIntent, activityPredicate, intentPredicate, windowMetricsPredicate); } @NonNull static TaskFragmentContainer createTfContainer( @NonNull SplitController splitController, @NonNull Activity activity) { return createTfContainer(splitController, TASK_ID, activity); } @NonNull static TaskFragmentContainer createTfContainer( @NonNull SplitController splitController, int taskId, @NonNull Activity activity) { return new TaskFragmentContainer.Builder(splitController, taskId, activity) .setPendingAppearedActivity(activity).build(); } } libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java +6 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; Loading Loading @@ -105,8 +106,11 @@ public class JetpackTaskFragmentOrganizerTest { @Test public void testExpandTaskFragment() { final TaskContainer taskContainer = createTestTaskContainer(); final TaskFragmentContainer container = new TaskFragmentContainer(null /* activity */, new Intent(), taskContainer, mSplitController, null /* pairedPrimaryContainer */); doReturn(taskContainer).when(mSplitController).getTaskContainer(anyInt()); final TaskFragmentContainer container = new TaskFragmentContainer.Builder(mSplitController, taskContainer.getTaskId(), null /* activityInTask */) .setPendingAppearedIntent(new Intent()) .build(); final TaskFragmentInfo info = createMockInfo(container); mOrganizer.mFragmentInfos.put(container.getTaskFragmentToken(), info); container.setInfo(mTransaction, info); Loading Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +16 −72 Original line number Diff line number Diff line Loading @@ -1322,7 +1322,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen mPresenter.expandTaskFragment(wct, container); } else { // Put activity into a new expanded container. final TaskFragmentContainer newContainer = newContainer(activity, getTaskId(activity)); final TaskFragmentContainer newContainer = new TaskFragmentContainer.Builder(this, getTaskId(activity), activity) .setPendingAppearedActivity(activity).build(); mPresenter.expandActivity(wct, newContainer.getTaskFragmentToken(), activity); } } Loading Loading @@ -1738,9 +1740,13 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Can't find any activity in the Task that we can use as the owner activity. return null; } final TaskFragmentContainer container = newContainer(null /* pendingAppearedActivity */, intent, activityInTask, taskId, null /* pairedPrimaryContainer*/, overlayTag, launchOptions, associateLaunchingActivity); final TaskFragmentContainer container = new TaskFragmentContainer.Builder(this, taskId, activityInTask) .setPendingAppearedIntent(intent) .setOverlayTag(overlayTag) .setLaunchOptions(launchOptions) .setAssociatedActivity(associateLaunchingActivity ? activityInTask : null) .build(); final IBinder taskFragmentToken = container.getTaskFragmentToken(); // Note that taskContainer will not exist before calling #newContainer if the container // is the first embedded TF in the task. Loading Loading @@ -1818,74 +1824,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return null; } @GuardedBy("mLock") TaskFragmentContainer newContainer(@NonNull Activity pendingAppearedActivity, int taskId) { return newContainer(pendingAppearedActivity, pendingAppearedActivity, taskId); } @GuardedBy("mLock") TaskFragmentContainer newContainer(@NonNull Activity pendingAppearedActivity, @NonNull Activity activityInTask, int taskId) { return newContainer(pendingAppearedActivity, null /* pendingAppearedIntent */, activityInTask, taskId, null /* pairedPrimaryContainer */, null /* tag */, null /* launchOptions */, false /* associateLaunchingActivity */); } @GuardedBy("mLock") TaskFragmentContainer newContainer(@NonNull Intent pendingAppearedIntent, @NonNull Activity activityInTask, int taskId) { return newContainer(null /* pendingAppearedActivity */, pendingAppearedIntent, activityInTask, taskId, null /* pairedPrimaryContainer */, null /* tag */, null /* launchOptions */, false /* associateLaunchingActivity */); } @GuardedBy("mLock") TaskFragmentContainer newContainer(@NonNull Intent pendingAppearedIntent, @NonNull Activity activityInTask, int taskId, @NonNull TaskFragmentContainer pairedPrimaryContainer) { return newContainer(null /* pendingAppearedActivity */, pendingAppearedIntent, activityInTask, taskId, pairedPrimaryContainer, null /* tag */, null /* launchOptions */, false /* associateLaunchingActivity */); } /** * Creates and registers a new organized container with an optional activity that will be * re-parented to it in a WCT. * * @param pendingAppearedActivity the activity that will be reparented to the TaskFragment. * @param pendingAppearedIntent the Intent that will be started in the TaskFragment. * @param activityInTask activity in the same Task so that we can get the Task bounds * if needed. * @param taskId parent Task of the new TaskFragment. * @param pairedContainer the paired primary {@link TaskFragmentContainer}. When it is * set, the new container will be added right above it. * @param overlayTag The tag for the new created overlay container. It must be * needed if {@code isOverlay} is {@code true}. Otherwise, * it should be {@code null}. * @param launchOptions The launch options bundle to create a container. Must be * specified for overlay container. * @param associateLaunchingActivity {@code true} to indicate this overlay container * should associate with launching activity. */ @GuardedBy("mLock") TaskFragmentContainer newContainer(@Nullable Activity pendingAppearedActivity, @Nullable Intent pendingAppearedIntent, @NonNull Activity activityInTask, int taskId, @Nullable TaskFragmentContainer pairedContainer, @Nullable String overlayTag, @Nullable Bundle launchOptions, boolean associateLaunchingActivity) { if (activityInTask == null) { throw new IllegalArgumentException("activityInTask must not be null,"); } if (!mTaskContainers.contains(taskId)) { mTaskContainers.put(taskId, new TaskContainer(taskId, activityInTask)); mDividerPresenters.put(taskId, new DividerPresenter(taskId, this, mExecutor)); } final TaskContainer taskContainer = mTaskContainers.get(taskId); final TaskFragmentContainer container = new TaskFragmentContainer(pendingAppearedActivity, pendingAppearedIntent, taskContainer, this, pairedContainer, overlayTag, launchOptions, associateLaunchingActivity ? activityInTask : null); return container; } /** * Creates and registers a new split with the provided containers and configuration. Finishes * existing secondary containers if found for the given primary container. Loading Loading @@ -2581,6 +2519,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return mTaskContainers.get(taskId); } @GuardedBy("mLock") void addTaskContainer(int taskId, TaskContainer taskContainer) { mTaskContainers.put(taskId, taskContainer); mDividerPresenters.put(taskId, new DividerPresenter(taskId, this, mExecutor)); } Handler getHandler() { return mHandler; } Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +15 −9 Original line number Diff line number Diff line Loading @@ -186,8 +186,9 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { // Create new empty task fragment final int taskId = primaryContainer.getTaskId(); final TaskFragmentContainer secondaryContainer = mController.newContainer( secondaryIntent, primaryActivity, taskId); final TaskFragmentContainer secondaryContainer = new TaskFragmentContainer.Builder(mController, taskId, primaryActivity) .setPendingAppearedIntent(secondaryIntent).build(); final Rect secondaryRelBounds = getRelBoundsForPosition(POSITION_END, taskProperties, splitAttributes); final int windowingMode = mController.getTaskContainer(taskId) Loading Loading @@ -261,7 +262,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { TaskFragmentContainer container = mController.getContainerWithActivity(activity); final int taskId = container != null ? container.getTaskId() : activity.getTaskId(); if (container == null || container == containerToAvoid) { container = mController.newContainer(activity, taskId); container = new TaskFragmentContainer.Builder(mController, taskId, activity) .setPendingAppearedActivity(activity).build(); final int windowingMode = mController.getTaskContainer(taskId) .getWindowingModeForTaskFragment(relBounds); final IBinder reparentActivityToken = activity.getActivityToken(); Loading Loading @@ -304,15 +306,19 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { TaskFragmentContainer primaryContainer = mController.getContainerWithActivity( launchingActivity); if (primaryContainer == null) { primaryContainer = mController.newContainer(launchingActivity, launchingActivity.getTaskId()); primaryContainer = new TaskFragmentContainer.Builder(mController, launchingActivity.getTaskId(), launchingActivity) .setPendingAppearedActivity(launchingActivity).build(); } final int taskId = primaryContainer.getTaskId(); final TaskFragmentContainer secondaryContainer = mController.newContainer(activityIntent, launchingActivity, taskId, // Pass in the primary container to make sure it is added right above the primary. primaryContainer); final TaskFragmentContainer secondaryContainer = new TaskFragmentContainer.Builder(mController, taskId, launchingActivity) .setPendingAppearedIntent(activityIntent) // Pass in the primary container to make sure it is added right above the // primary. .setPairedPrimaryContainer(primaryContainer) .build(); final TaskContainer taskContainer = mController.getTaskContainer(taskId); final int windowingMode = taskContainer.getWindowingModeForTaskFragment( primaryRelBounds); Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java +112 −21 Original line number Diff line number Diff line Loading @@ -194,20 +194,6 @@ class TaskFragmentContainer { */ private boolean mLastDimOnTask; /** * @see #TaskFragmentContainer(Activity, Intent, TaskContainer, SplitController, * TaskFragmentContainer, String, Bundle, Activity) */ TaskFragmentContainer(@Nullable Activity pendingAppearedActivity, @Nullable Intent pendingAppearedIntent, @NonNull TaskContainer taskContainer, @NonNull SplitController controller, @Nullable TaskFragmentContainer pairedPrimaryContainer) { this(pendingAppearedActivity, pendingAppearedIntent, taskContainer, controller, pairedPrimaryContainer, null /* overlayTag */, null /* launchOptions */, null /* associatedActivity */); } /** * Creates a container with an existing activity that will be re-parented to it in a window * container transaction. Loading @@ -218,7 +204,7 @@ class TaskFragmentContainer { * @param associatedActivity the associated activity of the overlay container. Must be * {@code null} for a non-overlay container. */ TaskFragmentContainer(@Nullable Activity pendingAppearedActivity, private TaskFragmentContainer(@Nullable Activity pendingAppearedActivity, @Nullable Intent pendingAppearedIntent, @NonNull TaskContainer taskContainer, @NonNull SplitController controller, @Nullable TaskFragmentContainer pairedPrimaryContainer, @Nullable String overlayTag, Loading @@ -232,12 +218,6 @@ class TaskFragmentContainer { mToken = new Binder("TaskFragmentContainer"); mTaskContainer = taskContainer; mOverlayTag = overlayTag; if (overlayTag != null) { Objects.requireNonNull(launchOptions); } else if (associatedActivity != null) { throw new IllegalArgumentException("Associated activity must be null for " + "non-overlay activity."); } mAssociatedActivityToken = associatedActivity != null ? associatedActivity.getActivityToken() : null; Loading Loading @@ -1116,6 +1096,117 @@ class TaskFragmentContainer { return sb.append("]").toString(); } static final class Builder { @NonNull private final SplitController mSplitController; // The parent Task id of the new TaskFragment. private final int mTaskId; // The activity in the same Task so that we can get the Task bounds if needed. @NonNull private final Activity mActivityInTask; // The activity that will be reparented to the TaskFragment. @Nullable private Activity mPendingAppearedActivity; // The Intent that will be started in the TaskFragment. @Nullable private Intent mPendingAppearedIntent; // The paired primary {@link TaskFragmentContainer}. When it is set, the new container // will be added right above it. @Nullable private TaskFragmentContainer mPairedPrimaryContainer; // The launch options bundle to create a container. Must be specified for overlay container. @Nullable private Bundle mLaunchOptions; // The tag for the new created overlay container. This is required when creating an // overlay container. @Nullable private String mOverlayTag; // The associated activity of the overlay container. Must be {@code null} for a // non-overlay container. @Nullable private Activity mAssociatedActivity; Builder(@NonNull SplitController splitController, int taskId, @Nullable Activity activityInTask) { if (taskId <= 0) { throw new IllegalArgumentException("taskId is invalid, " + taskId); } mSplitController = splitController; mTaskId = taskId; mActivityInTask = activityInTask; } @NonNull Builder setPendingAppearedActivity(@Nullable Activity pendingAppearedActivity) { mPendingAppearedActivity = pendingAppearedActivity; return this; } @NonNull Builder setPendingAppearedIntent(@Nullable Intent pendingAppearedIntent) { mPendingAppearedIntent = pendingAppearedIntent; return this; } @NonNull Builder setPairedPrimaryContainer(@Nullable TaskFragmentContainer pairedPrimaryContainer) { mPairedPrimaryContainer = pairedPrimaryContainer; return this; } @NonNull Builder setLaunchOptions(@Nullable Bundle launchOptions) { mLaunchOptions = launchOptions; return this; } @NonNull Builder setOverlayTag(@Nullable String overlayTag) { mOverlayTag = overlayTag; return this; } @NonNull Builder setAssociatedActivity(@Nullable Activity associatedActivity) { mAssociatedActivity = associatedActivity; return this; } @NonNull TaskFragmentContainer build() { if (mOverlayTag != null) { Objects.requireNonNull(mLaunchOptions); } else if (mAssociatedActivity != null) { throw new IllegalArgumentException("Associated activity must be null for " + "non-overlay activity."); } TaskContainer taskContainer = mSplitController.getTaskContainer(mTaskId); if (taskContainer == null && mActivityInTask == null) { throw new IllegalArgumentException("mActivityInTask must be set."); } if (taskContainer == null) { // Adding a TaskContainer if no existed one. taskContainer = new TaskContainer(mTaskId, mActivityInTask); mSplitController.addTaskContainer(mTaskId, taskContainer); } return new TaskFragmentContainer(mPendingAppearedActivity, mPendingAppearedIntent, taskContainer, mSplitController, mPairedPrimaryContainer, mOverlayTag, mLaunchOptions, mAssociatedActivity); } } static class OverlayContainerRestoreParams { /** The token of the overlay container */ @NonNull Loading
libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java +13 −0 Original line number Diff line number Diff line Loading @@ -248,4 +248,17 @@ public class EmbeddingTestUtils { return new SplitPlaceholderRule.Builder(placeholderIntent, activityPredicate, intentPredicate, windowMetricsPredicate); } @NonNull static TaskFragmentContainer createTfContainer( @NonNull SplitController splitController, @NonNull Activity activity) { return createTfContainer(splitController, TASK_ID, activity); } @NonNull static TaskFragmentContainer createTfContainer( @NonNull SplitController splitController, int taskId, @NonNull Activity activity) { return new TaskFragmentContainer.Builder(splitController, taskId, activity) .setPendingAppearedActivity(activity).build(); } }
libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java +6 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; Loading Loading @@ -105,8 +106,11 @@ public class JetpackTaskFragmentOrganizerTest { @Test public void testExpandTaskFragment() { final TaskContainer taskContainer = createTestTaskContainer(); final TaskFragmentContainer container = new TaskFragmentContainer(null /* activity */, new Intent(), taskContainer, mSplitController, null /* pairedPrimaryContainer */); doReturn(taskContainer).when(mSplitController).getTaskContainer(anyInt()); final TaskFragmentContainer container = new TaskFragmentContainer.Builder(mSplitController, taskContainer.getTaskId(), null /* activityInTask */) .setPendingAppearedIntent(new Intent()) .build(); final TaskFragmentInfo info = createMockInfo(container); mOrganizer.mFragmentInfos.put(container.getTaskFragmentToken(), info); container.setInfo(mTransaction, info); Loading