Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +314 −114 File changed.Preview size limit exceeded, changes collapsed. Show changes libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +23 −10 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package androidx.window.extensions.embedding; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.content.pm.PackageManager.MATCH_ALL; import android.app.Activity; Loading Loading @@ -187,7 +189,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { final Rect secondaryRelBounds = getRelBoundsForPosition(POSITION_END, taskProperties, splitAttributes); final int windowingMode = mController.getTaskContainer(taskId) .getWindowingModeForSplitTaskFragment(secondaryRelBounds); .getWindowingModeForTaskFragment(secondaryRelBounds); createTaskFragment(wct, secondaryContainer.getTaskFragmentToken(), primaryActivity.getActivityToken(), secondaryRelBounds, windowingMode); updateAnimationParams(wct, secondaryContainer.getTaskFragmentToken(), splitAttributes); Loading Loading @@ -259,7 +261,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { if (container == null || container == containerToAvoid) { container = mController.newContainer(activity, taskId); final int windowingMode = mController.getTaskContainer(taskId) .getWindowingModeForSplitTaskFragment(relBounds); .getWindowingModeForTaskFragment(relBounds); final IBinder reparentActivityToken = activity.getActivityToken(); createTaskFragment(wct, container.getTaskFragmentToken(), reparentActivityToken, relBounds, windowingMode, reparentActivityToken); Loading @@ -268,7 +270,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { } else { resizeTaskFragmentIfRegistered(wct, container, relBounds); final int windowingMode = mController.getTaskContainer(taskId) .getWindowingModeForSplitTaskFragment(relBounds); .getWindowingModeForTaskFragment(relBounds); updateTaskFragmentWindowingModeIfRegistered(wct, container, windowingMode); } updateAnimationParams(wct, container.getTaskFragmentToken(), splitAttributes); Loading Loading @@ -310,7 +312,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { // Pass in the primary container to make sure it is added right above the primary. primaryContainer); final TaskContainer taskContainer = mController.getTaskContainer(taskId); final int windowingMode = taskContainer.getWindowingModeForSplitTaskFragment( final int windowingMode = taskContainer.getWindowingModeForTaskFragment( primaryRelBounds); mController.registerSplit(wct, primaryContainer, launchingActivity, secondaryContainer, rule, splitAttributes); Loading Loading @@ -347,6 +349,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { && secondaryContainer.areLastRequestedBoundsEqual(null /* bounds */) && !secondaryRelBounds.isEmpty(); // TODO(b/243518738): remove usages of XXXIfRegistered. // If the task fragments are not registered yet, the positions will be updated after they // are created again. resizeTaskFragmentIfRegistered(wct, primaryContainer, primaryRelBounds); Loading @@ -357,7 +360,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { // When placeholder is shown in split, we should keep the focus on the primary. wct.requestFocusOnTaskFragment(primaryContainer.getTaskFragmentToken()); } final int windowingMode = taskContainer.getWindowingModeForSplitTaskFragment( final int windowingMode = taskContainer.getWindowingModeForTaskFragment( primaryRelBounds); updateTaskFragmentWindowingModeIfRegistered(wct, primaryContainer, windowingMode); updateTaskFragmentWindowingModeIfRegistered(wct, secondaryContainer, windowingMode); Loading Loading @@ -398,13 +401,13 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { * Sets whether to enable isolated navigation for this {@link TaskFragmentContainer} */ void setTaskFragmentIsolatedNavigation(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer taskFragmentContainer, @NonNull TaskFragmentContainer container, boolean isolatedNavigationEnabled) { if (taskFragmentContainer.isIsolatedNavigationEnabled() == isolatedNavigationEnabled) { if (container.isIsolatedNavigationEnabled() == isolatedNavigationEnabled) { return; } taskFragmentContainer.setIsolatedNavigationEnabled(isolatedNavigationEnabled); setTaskFragmentIsolatedNavigation(wct, taskFragmentContainer.getTaskFragmentToken(), container.setIsolatedNavigationEnabled(isolatedNavigationEnabled); setTaskFragmentIsolatedNavigation(wct, container.getTaskFragmentToken(), isolatedNavigationEnabled); } Loading Loading @@ -566,6 +569,15 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { super.setCompanionTaskFragment(wct, primary, secondary); } void applyActivityStackAttributes(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer container, @NonNull ActivityStackAttributes attributes) { final Rect bounds = attributes.getRelativeBounds(); resizeTaskFragment(wct, container.getTaskFragmentToken(), bounds); updateWindowingMode(wct, container.getTaskFragmentToken(), bounds.isEmpty() ? WINDOWING_MODE_FULLSCREEN : WINDOWING_MODE_MULTI_WINDOW); } /** * Expands the split container if the current split bounds are smaller than the Activity or * Intent that is added to the container. Loading Loading @@ -1086,7 +1098,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { } @NonNull ParentContainerInfo toParentContainerInfo(@NonNull TaskProperties taskProperties) { ParentContainerInfo createParentContainerInfoFromTaskProperties( @NonNull TaskProperties taskProperties) { final Configuration configuration = taskProperties.getConfiguration(); final WindowLayoutInfo windowLayoutInfo = mWindowLayoutComponent .getCurrentWindowLayoutInfo(taskProperties.getDisplayId(), Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java +21 −1 Original line number Diff line number Diff line Loading @@ -145,7 +145,7 @@ class TaskContainer { * the pair of TaskFragments are stacked due to the limited space. */ @WindowingMode int getWindowingModeForSplitTaskFragment(@Nullable Rect taskFragmentBounds) { int getWindowingModeForTaskFragment(@Nullable Rect taskFragmentBounds) { // Only set to multi-windowing mode if the pair are showing side-by-side. Otherwise, it // will be set to UNDEFINED which will then inherit the Task windowing mode. if (taskFragmentBounds == null || taskFragmentBounds.isEmpty() || isInPictureInPicture()) { Loading Loading @@ -443,6 +443,26 @@ class TaskContainer { return splitStates; } // TODO(b/317358445): Makes ActivityStack and SplitInfo callback more stable. /** * Returns a list of currently active {@link ActivityStack activityStacks}. * * @return a list of {@link ActivityStack activityStacks} if all the containers are in * a stable state, or {@code null} otherwise. */ @Nullable List<ActivityStack> getActivityStacksIfStable() { final List<ActivityStack> activityStacks = new ArrayList<>(); for (TaskFragmentContainer container : mContainers) { final ActivityStack activityStack = container.toActivityStackIfStable(); if (activityStack == null) { return null; } activityStacks.add(activityStack); } return activityStacks; } /** A wrapper class which contains the information of {@link TaskContainer} */ static final class TaskProperties { private final int mDisplayId; Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java +18 −5 Original line number Diff line number Diff line Loading @@ -107,11 +107,11 @@ class TaskFragmentContainer { private final String mOverlayTag; /** * The launch options that was used to create this container. Must not be {@code null} for * {@link #isOverlay()} container. * The launch options that was used to create this container. Must not {@link Bundle#isEmpty()} * for {@link #isOverlay()} container. */ @Nullable private final Bundle mLaunchOptions; @NonNull private final Bundle mLaunchOptions = new Bundle(); /** Indicates whether the container was cleaned up after the last activity was removed. */ private boolean mIsFinished; Loading Loading @@ -210,7 +210,9 @@ class TaskFragmentContainer { if (overlayTag != null) { Objects.requireNonNull(launchOptions); } mLaunchOptions = launchOptions; if (launchOptions != null) { mLaunchOptions.putAll(launchOptions); } if (pairedPrimaryContainer != null) { // The TaskFragment will be positioned right above the paired container. Loading Loading @@ -925,6 +927,17 @@ class TaskFragmentContainer { return mOverlayTag; } /** * Returns the options that was used to launch this {@link TaskFragmentContainer}. * {@link Bundle#isEmpty()} means there's no launch option for this container. * <p> * Note that WM Jetpack owns the logic. The WM Extension library must not modify this object. */ @NonNull Bundle getLaunchOptions() { return mLaunchOptions; } @Override public String toString() { return toString(true /* includeContainersToFinishOnExit */); Loading libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java +52 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package androidx.window.extensions.embedding; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.Display.DEFAULT_DISPLAY; import static androidx.window.extensions.embedding.ActivityEmbeddingOptionsProperties.KEY_OVERLAY_TAG; Loading Loading @@ -287,10 +288,10 @@ public class OverlayPresentationTest { createOrUpdateOverlayTaskFragmentIfNeeded("test"); verify(mSplitPresenter).resizeTaskFragment(mTransaction, overlayToken, new Rect()); verify(mSplitPresenter).setTaskFragmentIsolatedNavigation(mTransaction, overlayToken, verify(mSplitPresenter).updateWindowingMode(mTransaction, overlayToken, WINDOWING_MODE_UNDEFINED); verify(mSplitPresenter).setTaskFragmentIsolatedNavigation(mTransaction, overlayContainer, false); assertThat(mSplitController.getAllOverlayTaskFragmentContainers()) .containsExactly(overlayContainer); } @Test Loading @@ -315,8 +316,10 @@ public class OverlayPresentationTest { createOrUpdateOverlayTaskFragmentIfNeeded("test"); verify(mSplitPresenter).resizeTaskFragment(mTransaction, overlayToken, new Rect()); verify(mSplitPresenter).setTaskFragmentIsolatedNavigation(mTransaction, overlayToken, false); verify(mSplitPresenter).updateWindowingMode(mTransaction, overlayToken, WINDOWING_MODE_UNDEFINED); verify(mSplitPresenter).setTaskFragmentIsolatedNavigation(mTransaction, overlayContainer, false); assertThat(mSplitController.getAllOverlayTaskFragmentContainers()) .containsExactly(overlayContainer); } Loading Loading @@ -425,6 +428,50 @@ public class OverlayPresentationTest { .that(taskContainer.getTaskFragmentContainers()).isEmpty(); } @Test public void testUpdateActivityStackAttributes_nullParams_throwException() { assertThrows(NullPointerException.class, () -> mSplitController.updateActivityStackAttributes(null, new ActivityStackAttributes.Builder().build())); assertThrows(NullPointerException.class, () -> mSplitController.updateActivityStackAttributes(new Binder(), null)); verify(mSplitPresenter, never()).applyActivityStackAttributes(any(), any(), any()); } @Test public void testUpdateActivityStackAttributes_nullContainer_earlyReturn() { final TaskFragmentContainer container = mSplitController.newContainer(mActivity, mActivity.getTaskId()); mSplitController.updateActivityStackAttributes(container.getTaskFragmentToken(), new ActivityStackAttributes.Builder().build()); verify(mSplitPresenter, never()).applyActivityStackAttributes(any(), any(), any()); } @Test public void testUpdateActivityStackAttributes_notOverlay_earlyReturn() { final TaskFragmentContainer container = createMockTaskFragmentContainer(mActivity); mSplitController.updateActivityStackAttributes(container.getTaskFragmentToken(), new ActivityStackAttributes.Builder().build()); verify(mSplitPresenter, never()).applyActivityStackAttributes(any(), any(), any()); } @Test public void testUpdateActivityStackAttributes() { final TaskFragmentContainer container = createTestOverlayContainer(TASK_ID, "test"); doNothing().when(mSplitPresenter).applyActivityStackAttributes(any(), any(), any()); final ActivityStackAttributes attrs = new ActivityStackAttributes.Builder().build(); final IBinder token = container.getTaskFragmentToken(); mSplitController.updateActivityStackAttributes(token, attrs); verify(mSplitPresenter).applyActivityStackAttributes(any(), eq(container), eq(attrs)); } /** * A simplified version of {@link SplitController.ActivityStartMonitor * #createOrUpdateOverlayTaskFragmentIfNeeded} Loading Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +314 −114 File changed.Preview size limit exceeded, changes collapsed. Show changes
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +23 −10 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package androidx.window.extensions.embedding; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.content.pm.PackageManager.MATCH_ALL; import android.app.Activity; Loading Loading @@ -187,7 +189,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { final Rect secondaryRelBounds = getRelBoundsForPosition(POSITION_END, taskProperties, splitAttributes); final int windowingMode = mController.getTaskContainer(taskId) .getWindowingModeForSplitTaskFragment(secondaryRelBounds); .getWindowingModeForTaskFragment(secondaryRelBounds); createTaskFragment(wct, secondaryContainer.getTaskFragmentToken(), primaryActivity.getActivityToken(), secondaryRelBounds, windowingMode); updateAnimationParams(wct, secondaryContainer.getTaskFragmentToken(), splitAttributes); Loading Loading @@ -259,7 +261,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { if (container == null || container == containerToAvoid) { container = mController.newContainer(activity, taskId); final int windowingMode = mController.getTaskContainer(taskId) .getWindowingModeForSplitTaskFragment(relBounds); .getWindowingModeForTaskFragment(relBounds); final IBinder reparentActivityToken = activity.getActivityToken(); createTaskFragment(wct, container.getTaskFragmentToken(), reparentActivityToken, relBounds, windowingMode, reparentActivityToken); Loading @@ -268,7 +270,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { } else { resizeTaskFragmentIfRegistered(wct, container, relBounds); final int windowingMode = mController.getTaskContainer(taskId) .getWindowingModeForSplitTaskFragment(relBounds); .getWindowingModeForTaskFragment(relBounds); updateTaskFragmentWindowingModeIfRegistered(wct, container, windowingMode); } updateAnimationParams(wct, container.getTaskFragmentToken(), splitAttributes); Loading Loading @@ -310,7 +312,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { // Pass in the primary container to make sure it is added right above the primary. primaryContainer); final TaskContainer taskContainer = mController.getTaskContainer(taskId); final int windowingMode = taskContainer.getWindowingModeForSplitTaskFragment( final int windowingMode = taskContainer.getWindowingModeForTaskFragment( primaryRelBounds); mController.registerSplit(wct, primaryContainer, launchingActivity, secondaryContainer, rule, splitAttributes); Loading Loading @@ -347,6 +349,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { && secondaryContainer.areLastRequestedBoundsEqual(null /* bounds */) && !secondaryRelBounds.isEmpty(); // TODO(b/243518738): remove usages of XXXIfRegistered. // If the task fragments are not registered yet, the positions will be updated after they // are created again. resizeTaskFragmentIfRegistered(wct, primaryContainer, primaryRelBounds); Loading @@ -357,7 +360,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { // When placeholder is shown in split, we should keep the focus on the primary. wct.requestFocusOnTaskFragment(primaryContainer.getTaskFragmentToken()); } final int windowingMode = taskContainer.getWindowingModeForSplitTaskFragment( final int windowingMode = taskContainer.getWindowingModeForTaskFragment( primaryRelBounds); updateTaskFragmentWindowingModeIfRegistered(wct, primaryContainer, windowingMode); updateTaskFragmentWindowingModeIfRegistered(wct, secondaryContainer, windowingMode); Loading Loading @@ -398,13 +401,13 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { * Sets whether to enable isolated navigation for this {@link TaskFragmentContainer} */ void setTaskFragmentIsolatedNavigation(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer taskFragmentContainer, @NonNull TaskFragmentContainer container, boolean isolatedNavigationEnabled) { if (taskFragmentContainer.isIsolatedNavigationEnabled() == isolatedNavigationEnabled) { if (container.isIsolatedNavigationEnabled() == isolatedNavigationEnabled) { return; } taskFragmentContainer.setIsolatedNavigationEnabled(isolatedNavigationEnabled); setTaskFragmentIsolatedNavigation(wct, taskFragmentContainer.getTaskFragmentToken(), container.setIsolatedNavigationEnabled(isolatedNavigationEnabled); setTaskFragmentIsolatedNavigation(wct, container.getTaskFragmentToken(), isolatedNavigationEnabled); } Loading Loading @@ -566,6 +569,15 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { super.setCompanionTaskFragment(wct, primary, secondary); } void applyActivityStackAttributes(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer container, @NonNull ActivityStackAttributes attributes) { final Rect bounds = attributes.getRelativeBounds(); resizeTaskFragment(wct, container.getTaskFragmentToken(), bounds); updateWindowingMode(wct, container.getTaskFragmentToken(), bounds.isEmpty() ? WINDOWING_MODE_FULLSCREEN : WINDOWING_MODE_MULTI_WINDOW); } /** * Expands the split container if the current split bounds are smaller than the Activity or * Intent that is added to the container. Loading Loading @@ -1086,7 +1098,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { } @NonNull ParentContainerInfo toParentContainerInfo(@NonNull TaskProperties taskProperties) { ParentContainerInfo createParentContainerInfoFromTaskProperties( @NonNull TaskProperties taskProperties) { final Configuration configuration = taskProperties.getConfiguration(); final WindowLayoutInfo windowLayoutInfo = mWindowLayoutComponent .getCurrentWindowLayoutInfo(taskProperties.getDisplayId(), Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java +21 −1 Original line number Diff line number Diff line Loading @@ -145,7 +145,7 @@ class TaskContainer { * the pair of TaskFragments are stacked due to the limited space. */ @WindowingMode int getWindowingModeForSplitTaskFragment(@Nullable Rect taskFragmentBounds) { int getWindowingModeForTaskFragment(@Nullable Rect taskFragmentBounds) { // Only set to multi-windowing mode if the pair are showing side-by-side. Otherwise, it // will be set to UNDEFINED which will then inherit the Task windowing mode. if (taskFragmentBounds == null || taskFragmentBounds.isEmpty() || isInPictureInPicture()) { Loading Loading @@ -443,6 +443,26 @@ class TaskContainer { return splitStates; } // TODO(b/317358445): Makes ActivityStack and SplitInfo callback more stable. /** * Returns a list of currently active {@link ActivityStack activityStacks}. * * @return a list of {@link ActivityStack activityStacks} if all the containers are in * a stable state, or {@code null} otherwise. */ @Nullable List<ActivityStack> getActivityStacksIfStable() { final List<ActivityStack> activityStacks = new ArrayList<>(); for (TaskFragmentContainer container : mContainers) { final ActivityStack activityStack = container.toActivityStackIfStable(); if (activityStack == null) { return null; } activityStacks.add(activityStack); } return activityStacks; } /** A wrapper class which contains the information of {@link TaskContainer} */ static final class TaskProperties { private final int mDisplayId; Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java +18 −5 Original line number Diff line number Diff line Loading @@ -107,11 +107,11 @@ class TaskFragmentContainer { private final String mOverlayTag; /** * The launch options that was used to create this container. Must not be {@code null} for * {@link #isOverlay()} container. * The launch options that was used to create this container. Must not {@link Bundle#isEmpty()} * for {@link #isOverlay()} container. */ @Nullable private final Bundle mLaunchOptions; @NonNull private final Bundle mLaunchOptions = new Bundle(); /** Indicates whether the container was cleaned up after the last activity was removed. */ private boolean mIsFinished; Loading Loading @@ -210,7 +210,9 @@ class TaskFragmentContainer { if (overlayTag != null) { Objects.requireNonNull(launchOptions); } mLaunchOptions = launchOptions; if (launchOptions != null) { mLaunchOptions.putAll(launchOptions); } if (pairedPrimaryContainer != null) { // The TaskFragment will be positioned right above the paired container. Loading Loading @@ -925,6 +927,17 @@ class TaskFragmentContainer { return mOverlayTag; } /** * Returns the options that was used to launch this {@link TaskFragmentContainer}. * {@link Bundle#isEmpty()} means there's no launch option for this container. * <p> * Note that WM Jetpack owns the logic. The WM Extension library must not modify this object. */ @NonNull Bundle getLaunchOptions() { return mLaunchOptions; } @Override public String toString() { return toString(true /* includeContainersToFinishOnExit */); Loading
libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java +52 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package androidx.window.extensions.embedding; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.Display.DEFAULT_DISPLAY; import static androidx.window.extensions.embedding.ActivityEmbeddingOptionsProperties.KEY_OVERLAY_TAG; Loading Loading @@ -287,10 +288,10 @@ public class OverlayPresentationTest { createOrUpdateOverlayTaskFragmentIfNeeded("test"); verify(mSplitPresenter).resizeTaskFragment(mTransaction, overlayToken, new Rect()); verify(mSplitPresenter).setTaskFragmentIsolatedNavigation(mTransaction, overlayToken, verify(mSplitPresenter).updateWindowingMode(mTransaction, overlayToken, WINDOWING_MODE_UNDEFINED); verify(mSplitPresenter).setTaskFragmentIsolatedNavigation(mTransaction, overlayContainer, false); assertThat(mSplitController.getAllOverlayTaskFragmentContainers()) .containsExactly(overlayContainer); } @Test Loading @@ -315,8 +316,10 @@ public class OverlayPresentationTest { createOrUpdateOverlayTaskFragmentIfNeeded("test"); verify(mSplitPresenter).resizeTaskFragment(mTransaction, overlayToken, new Rect()); verify(mSplitPresenter).setTaskFragmentIsolatedNavigation(mTransaction, overlayToken, false); verify(mSplitPresenter).updateWindowingMode(mTransaction, overlayToken, WINDOWING_MODE_UNDEFINED); verify(mSplitPresenter).setTaskFragmentIsolatedNavigation(mTransaction, overlayContainer, false); assertThat(mSplitController.getAllOverlayTaskFragmentContainers()) .containsExactly(overlayContainer); } Loading Loading @@ -425,6 +428,50 @@ public class OverlayPresentationTest { .that(taskContainer.getTaskFragmentContainers()).isEmpty(); } @Test public void testUpdateActivityStackAttributes_nullParams_throwException() { assertThrows(NullPointerException.class, () -> mSplitController.updateActivityStackAttributes(null, new ActivityStackAttributes.Builder().build())); assertThrows(NullPointerException.class, () -> mSplitController.updateActivityStackAttributes(new Binder(), null)); verify(mSplitPresenter, never()).applyActivityStackAttributes(any(), any(), any()); } @Test public void testUpdateActivityStackAttributes_nullContainer_earlyReturn() { final TaskFragmentContainer container = mSplitController.newContainer(mActivity, mActivity.getTaskId()); mSplitController.updateActivityStackAttributes(container.getTaskFragmentToken(), new ActivityStackAttributes.Builder().build()); verify(mSplitPresenter, never()).applyActivityStackAttributes(any(), any(), any()); } @Test public void testUpdateActivityStackAttributes_notOverlay_earlyReturn() { final TaskFragmentContainer container = createMockTaskFragmentContainer(mActivity); mSplitController.updateActivityStackAttributes(container.getTaskFragmentToken(), new ActivityStackAttributes.Builder().build()); verify(mSplitPresenter, never()).applyActivityStackAttributes(any(), any(), any()); } @Test public void testUpdateActivityStackAttributes() { final TaskFragmentContainer container = createTestOverlayContainer(TASK_ID, "test"); doNothing().when(mSplitPresenter).applyActivityStackAttributes(any(), any(), any()); final ActivityStackAttributes attrs = new ActivityStackAttributes.Builder().build(); final IBinder token = container.getTaskFragmentToken(); mSplitController.updateActivityStackAttributes(token, attrs); verify(mSplitPresenter).applyActivityStackAttributes(any(), eq(container), eq(attrs)); } /** * A simplified version of {@link SplitController.ActivityStartMonitor * #createOrUpdateOverlayTaskFragmentIfNeeded} Loading