Loading core/java/android/window/TaskFragmentOperation.java +15 −2 Original line number Diff line number Diff line Loading @@ -84,8 +84,8 @@ public final class TaskFragmentOperation implements Parcelable { /** * Sets the activity navigation to be isolated, where the activity navigation on the * TaskFragment is separated from the rest activities in the Task. Activities cannot be * started on an isolated TaskFragment unless the activities are launched from the same * TaskFragment or explicitly requested to. * started on an isolated TaskFragment unless explicitly requested to. That said, new launched * activities should be positioned as a sibling to the TaskFragment with higher z-ordering. */ public static final int OP_TYPE_SET_ISOLATED_NAVIGATION = 11; Loading Loading @@ -149,6 +149,18 @@ public final class TaskFragmentOperation implements Parcelable { */ public static final int OP_TYPE_SET_DECOR_SURFACE_BOOSTED = 18; /** * Sets the TaskFragment to be pinned. * <p> * If a TaskFragment is pinned, the TaskFragment should be the top-most TaskFragment among other * sibling TaskFragments. Any newly launched and embeddable activity should not be placed in the * pinned TaskFragment, unless the activity is launched from the pinned TaskFragment or * explicitly requested to. Non-embeddable activities are not restricted to. * <p> * See {@link #OP_TYPE_REORDER_TO_FRONT} on how to reorder a pinned TaskFragment to the top. */ public static final int OP_TYPE_SET_PINNED = 19; @IntDef(prefix = { "OP_TYPE_" }, value = { OP_TYPE_UNKNOWN, OP_TYPE_CREATE_TASK_FRAGMENT, Loading @@ -170,6 +182,7 @@ public final class TaskFragmentOperation implements Parcelable { OP_TYPE_SET_DIM_ON_TASK, OP_TYPE_SET_MOVE_TO_BOTTOM_IF_CLEAR_WHEN_LAUNCH, OP_TYPE_SET_DECOR_SURFACE_BOOSTED, OP_TYPE_SET_PINNED, }) @Retention(RetentionPolicy.SOURCE) public @interface OperationType {} Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java +8 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT; import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS; import static android.window.TaskFragmentOperation.OP_TYPE_SET_DIM_ON_TASK; import static android.window.TaskFragmentOperation.OP_TYPE_SET_ISOLATED_NAVIGATION; import static android.window.TaskFragmentOperation.OP_TYPE_SET_PINNED; import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior; import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior; Loading Loading @@ -358,6 +359,13 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer { wct.addTaskFragmentOperation(fragmentToken, operation); } void setTaskFragmentPinned(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken, boolean pinned) { final TaskFragmentOperation operation = new TaskFragmentOperation.Builder( OP_TYPE_SET_PINNED).setBooleanValue(pinned).build(); wct.addTaskFragmentOperation(fragmentToken, operation); } void setTaskFragmentDimOnTask(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken, boolean dimOnTask) { final TaskFragmentOperation operation = new TaskFragmentOperation.Builder( Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +3 −6 Original line number Diff line number Diff line Loading @@ -350,8 +350,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Resets the isolated navigation and updates the container. final TransactionRecord transactionRecord = mTransactionManager.startNewTransaction(); final WindowContainerTransaction wct = transactionRecord.getTransaction(); mPresenter.setTaskFragmentIsolatedNavigation(wct, containerToUnpin, false /* isolated */); mPresenter.setTaskFragmentPinned(wct, containerToUnpin, false /* pinned */); updateContainer(wct, containerToUnpin); transactionRecord.apply(false /* shouldApplyIndependently */); updateCallbackIfNecessary(); Loading Loading @@ -1078,8 +1077,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return true; } // Skip resolving if the activity is on an isolated navigated TaskFragmentContainer. if (container != null && container.isIsolatedNavigationEnabled()) { if (container != null && container.shouldSkipActivityResolving()) { return true; } Loading Loading @@ -1535,8 +1533,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen final TaskFragmentContainer taskFragmentContainer = getContainerWithActivity( launchingActivity); if (taskFragmentContainer != null && taskFragmentContainer.isIsolatedNavigationEnabled()) { // Skip resolving if started from an isolated navigated TaskFragmentContainer. && taskFragmentContainer.shouldSkipActivityResolving()) { return null; } if (isAssociatedWithOverlay(launchingActivity)) { Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +45 −10 Original line number Diff line number Diff line Loading @@ -401,18 +401,26 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { return; } setTaskFragmentIsolatedNavigation(wct, secondaryContainer, !isStacked /* isolatedNav */); setTaskFragmentPinned(wct, secondaryContainer, !isStacked /* pinned */); if (isStacked && !splitPinRule.isSticky()) { secondaryContainer.getTaskContainer().removeSplitPinContainer(); } } /** * Sets whether to enable isolated navigation for this {@link TaskFragmentContainer} * Sets whether to enable isolated navigation for this {@link TaskFragmentContainer}. * <p> * If a container enables isolated navigation, activities can't be launched to this container * unless explicitly requested to be launched to. * * @see TaskFragmentContainer#isOverlayWithActivityAssociation() */ void setTaskFragmentIsolatedNavigation(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer container, boolean isolatedNavigationEnabled) { if (!Flags.activityEmbeddingOverlayPresentationFlag() && container.isOverlay()) { return; } if (container.isIsolatedNavigationEnabled() == isolatedNavigationEnabled) { return; } Loading @@ -421,6 +429,28 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { isolatedNavigationEnabled); } /** * Sets whether to pin this {@link TaskFragmentContainer}. * <p> * If a container is pinned, it won't be chosen as the launch target unless it's the launching * container. * * @see TaskFragmentContainer#isAlwaysOnTopOverlay() * @see TaskContainer#getSplitPinContainer() */ void setTaskFragmentPinned(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer container, boolean pinned) { if (!Flags.activityEmbeddingOverlayPresentationFlag() && container.isOverlay()) { return; } if (container.isPinned() == pinned) { return; } container.setPinned(pinned); setTaskFragmentPinned(wct, container.getTaskFragmentToken(), pinned); } /** * Resizes the task fragment if it was already registered. Skips the operation if the container * creation has not been reported from the server yet. Loading Loading @@ -586,6 +616,11 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { super.setCompanionTaskFragment(wct, primary, secondary); } /** * Applies the {@code attributes} to a standalone {@code container}. * * @param minDimensions the minimum dimension of the container. */ void applyActivityStackAttributes( @NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer container, Loading @@ -594,16 +629,17 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { final Rect relativeBounds = sanitizeBounds(attributes.getRelativeBounds(), minDimensions, container); final boolean isFillParent = relativeBounds.isEmpty(); // Note that we only set isolated navigation for overlay container without activity // association. Activity will be launched to an expanded container on top of the overlay // if the overlay is associated with an activity. Thus, an overlay with activity association // will never be isolated navigated. final boolean isIsolatedNavigated = container.isAlwaysOnTopOverlay() && !isFillParent; final boolean dimOnTask = !isFillParent && attributes.getWindowAttributes().getDimAreaBehavior() == DIM_AREA_ON_TASK && Flags.fullscreenDimFlag(); && Flags.fullscreenDimFlag() && attributes.getWindowAttributes().getDimAreaBehavior() == DIM_AREA_ON_TASK; final IBinder fragmentToken = container.getTaskFragmentToken(); if (container.isAlwaysOnTopOverlay()) { setTaskFragmentPinned(wct, container, !isFillParent); } else if (container.isOverlayWithActivityAssociation()) { setTaskFragmentIsolatedNavigation(wct, container, !isFillParent); } // TODO(b/243518738): Update to resizeTaskFragment after we migrate WCT#setRelativeBounds // and WCT#setWindowingMode to take fragmentToken. resizeTaskFragmentIfRegistered(wct, container, relativeBounds); Loading @@ -612,7 +648,6 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { updateTaskFragmentWindowingModeIfRegistered(wct, container, windowingMode); // Always use default animation for standalone ActivityStack. updateAnimationParams(wct, fragmentToken, TaskFragmentAnimationParams.DEFAULT); setTaskFragmentIsolatedNavigation(wct, container, isIsolatedNavigated); setTaskFragmentDimOnTask(wct, fragmentToken, dimOnTask); } Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java +33 −0 Original line number Diff line number Diff line Loading @@ -183,6 +183,11 @@ class TaskFragmentContainer { /** Whether this TaskFragment enable isolated navigation. */ private boolean mIsIsolatedNavigationEnabled; /** * Whether this TaskFragment is pinned. */ private boolean mIsPinned; /** * Whether to apply dimming on the parent Task that was requested last. */ Loading Loading @@ -893,6 +898,34 @@ class TaskFragmentContainer { mIsIsolatedNavigationEnabled = isolatedNavigationEnabled; } /** * Returns whether this container is pinned. * * @see android.window.TaskFragmentOperation#OP_TYPE_SET_PINNED */ boolean isPinned() { return mIsPinned; } /** * Sets whether to pin this container or not. * * @see #isPinned() */ void setPinned(boolean pinned) { mIsPinned = pinned; } /** * Indicates to skip activity resolving if the activity is from this container. * * @see #isIsolatedNavigationEnabled() * @see #isPinned() */ boolean shouldSkipActivityResolving() { return isIsolatedNavigationEnabled() || isPinned(); } /** Sets whether to apply dim on the parent Task. */ void setLastDimOnTask(boolean lastDimOnTask) { mLastDimOnTask = lastDimOnTask; Loading Loading
core/java/android/window/TaskFragmentOperation.java +15 −2 Original line number Diff line number Diff line Loading @@ -84,8 +84,8 @@ public final class TaskFragmentOperation implements Parcelable { /** * Sets the activity navigation to be isolated, where the activity navigation on the * TaskFragment is separated from the rest activities in the Task. Activities cannot be * started on an isolated TaskFragment unless the activities are launched from the same * TaskFragment or explicitly requested to. * started on an isolated TaskFragment unless explicitly requested to. That said, new launched * activities should be positioned as a sibling to the TaskFragment with higher z-ordering. */ public static final int OP_TYPE_SET_ISOLATED_NAVIGATION = 11; Loading Loading @@ -149,6 +149,18 @@ public final class TaskFragmentOperation implements Parcelable { */ public static final int OP_TYPE_SET_DECOR_SURFACE_BOOSTED = 18; /** * Sets the TaskFragment to be pinned. * <p> * If a TaskFragment is pinned, the TaskFragment should be the top-most TaskFragment among other * sibling TaskFragments. Any newly launched and embeddable activity should not be placed in the * pinned TaskFragment, unless the activity is launched from the pinned TaskFragment or * explicitly requested to. Non-embeddable activities are not restricted to. * <p> * See {@link #OP_TYPE_REORDER_TO_FRONT} on how to reorder a pinned TaskFragment to the top. */ public static final int OP_TYPE_SET_PINNED = 19; @IntDef(prefix = { "OP_TYPE_" }, value = { OP_TYPE_UNKNOWN, OP_TYPE_CREATE_TASK_FRAGMENT, Loading @@ -170,6 +182,7 @@ public final class TaskFragmentOperation implements Parcelable { OP_TYPE_SET_DIM_ON_TASK, OP_TYPE_SET_MOVE_TO_BOTTOM_IF_CLEAR_WHEN_LAUNCH, OP_TYPE_SET_DECOR_SURFACE_BOOSTED, OP_TYPE_SET_PINNED, }) @Retention(RetentionPolicy.SOURCE) public @interface OperationType {} Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java +8 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT; import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS; import static android.window.TaskFragmentOperation.OP_TYPE_SET_DIM_ON_TASK; import static android.window.TaskFragmentOperation.OP_TYPE_SET_ISOLATED_NAVIGATION; import static android.window.TaskFragmentOperation.OP_TYPE_SET_PINNED; import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior; import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior; Loading Loading @@ -358,6 +359,13 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer { wct.addTaskFragmentOperation(fragmentToken, operation); } void setTaskFragmentPinned(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken, boolean pinned) { final TaskFragmentOperation operation = new TaskFragmentOperation.Builder( OP_TYPE_SET_PINNED).setBooleanValue(pinned).build(); wct.addTaskFragmentOperation(fragmentToken, operation); } void setTaskFragmentDimOnTask(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken, boolean dimOnTask) { final TaskFragmentOperation operation = new TaskFragmentOperation.Builder( Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +3 −6 Original line number Diff line number Diff line Loading @@ -350,8 +350,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Resets the isolated navigation and updates the container. final TransactionRecord transactionRecord = mTransactionManager.startNewTransaction(); final WindowContainerTransaction wct = transactionRecord.getTransaction(); mPresenter.setTaskFragmentIsolatedNavigation(wct, containerToUnpin, false /* isolated */); mPresenter.setTaskFragmentPinned(wct, containerToUnpin, false /* pinned */); updateContainer(wct, containerToUnpin); transactionRecord.apply(false /* shouldApplyIndependently */); updateCallbackIfNecessary(); Loading Loading @@ -1078,8 +1077,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen return true; } // Skip resolving if the activity is on an isolated navigated TaskFragmentContainer. if (container != null && container.isIsolatedNavigationEnabled()) { if (container != null && container.shouldSkipActivityResolving()) { return true; } Loading Loading @@ -1535,8 +1533,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen final TaskFragmentContainer taskFragmentContainer = getContainerWithActivity( launchingActivity); if (taskFragmentContainer != null && taskFragmentContainer.isIsolatedNavigationEnabled()) { // Skip resolving if started from an isolated navigated TaskFragmentContainer. && taskFragmentContainer.shouldSkipActivityResolving()) { return null; } if (isAssociatedWithOverlay(launchingActivity)) { Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +45 −10 Original line number Diff line number Diff line Loading @@ -401,18 +401,26 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { return; } setTaskFragmentIsolatedNavigation(wct, secondaryContainer, !isStacked /* isolatedNav */); setTaskFragmentPinned(wct, secondaryContainer, !isStacked /* pinned */); if (isStacked && !splitPinRule.isSticky()) { secondaryContainer.getTaskContainer().removeSplitPinContainer(); } } /** * Sets whether to enable isolated navigation for this {@link TaskFragmentContainer} * Sets whether to enable isolated navigation for this {@link TaskFragmentContainer}. * <p> * If a container enables isolated navigation, activities can't be launched to this container * unless explicitly requested to be launched to. * * @see TaskFragmentContainer#isOverlayWithActivityAssociation() */ void setTaskFragmentIsolatedNavigation(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer container, boolean isolatedNavigationEnabled) { if (!Flags.activityEmbeddingOverlayPresentationFlag() && container.isOverlay()) { return; } if (container.isIsolatedNavigationEnabled() == isolatedNavigationEnabled) { return; } Loading @@ -421,6 +429,28 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { isolatedNavigationEnabled); } /** * Sets whether to pin this {@link TaskFragmentContainer}. * <p> * If a container is pinned, it won't be chosen as the launch target unless it's the launching * container. * * @see TaskFragmentContainer#isAlwaysOnTopOverlay() * @see TaskContainer#getSplitPinContainer() */ void setTaskFragmentPinned(@NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer container, boolean pinned) { if (!Flags.activityEmbeddingOverlayPresentationFlag() && container.isOverlay()) { return; } if (container.isPinned() == pinned) { return; } container.setPinned(pinned); setTaskFragmentPinned(wct, container.getTaskFragmentToken(), pinned); } /** * Resizes the task fragment if it was already registered. Skips the operation if the container * creation has not been reported from the server yet. Loading Loading @@ -586,6 +616,11 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { super.setCompanionTaskFragment(wct, primary, secondary); } /** * Applies the {@code attributes} to a standalone {@code container}. * * @param minDimensions the minimum dimension of the container. */ void applyActivityStackAttributes( @NonNull WindowContainerTransaction wct, @NonNull TaskFragmentContainer container, Loading @@ -594,16 +629,17 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { final Rect relativeBounds = sanitizeBounds(attributes.getRelativeBounds(), minDimensions, container); final boolean isFillParent = relativeBounds.isEmpty(); // Note that we only set isolated navigation for overlay container without activity // association. Activity will be launched to an expanded container on top of the overlay // if the overlay is associated with an activity. Thus, an overlay with activity association // will never be isolated navigated. final boolean isIsolatedNavigated = container.isAlwaysOnTopOverlay() && !isFillParent; final boolean dimOnTask = !isFillParent && attributes.getWindowAttributes().getDimAreaBehavior() == DIM_AREA_ON_TASK && Flags.fullscreenDimFlag(); && Flags.fullscreenDimFlag() && attributes.getWindowAttributes().getDimAreaBehavior() == DIM_AREA_ON_TASK; final IBinder fragmentToken = container.getTaskFragmentToken(); if (container.isAlwaysOnTopOverlay()) { setTaskFragmentPinned(wct, container, !isFillParent); } else if (container.isOverlayWithActivityAssociation()) { setTaskFragmentIsolatedNavigation(wct, container, !isFillParent); } // TODO(b/243518738): Update to resizeTaskFragment after we migrate WCT#setRelativeBounds // and WCT#setWindowingMode to take fragmentToken. resizeTaskFragmentIfRegistered(wct, container, relativeBounds); Loading @@ -612,7 +648,6 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { updateTaskFragmentWindowingModeIfRegistered(wct, container, windowingMode); // Always use default animation for standalone ActivityStack. updateAnimationParams(wct, fragmentToken, TaskFragmentAnimationParams.DEFAULT); setTaskFragmentIsolatedNavigation(wct, container, isIsolatedNavigated); setTaskFragmentDimOnTask(wct, fragmentToken, dimOnTask); } Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java +33 −0 Original line number Diff line number Diff line Loading @@ -183,6 +183,11 @@ class TaskFragmentContainer { /** Whether this TaskFragment enable isolated navigation. */ private boolean mIsIsolatedNavigationEnabled; /** * Whether this TaskFragment is pinned. */ private boolean mIsPinned; /** * Whether to apply dimming on the parent Task that was requested last. */ Loading Loading @@ -893,6 +898,34 @@ class TaskFragmentContainer { mIsIsolatedNavigationEnabled = isolatedNavigationEnabled; } /** * Returns whether this container is pinned. * * @see android.window.TaskFragmentOperation#OP_TYPE_SET_PINNED */ boolean isPinned() { return mIsPinned; } /** * Sets whether to pin this container or not. * * @see #isPinned() */ void setPinned(boolean pinned) { mIsPinned = pinned; } /** * Indicates to skip activity resolving if the activity is from this container. * * @see #isIsolatedNavigationEnabled() * @see #isPinned() */ boolean shouldSkipActivityResolving() { return isIsolatedNavigationEnabled() || isPinned(); } /** Sets whether to apply dim on the parent Task. */ void setLastDimOnTask(boolean lastDimOnTask) { mLastDimOnTask = lastDimOnTask; Loading