Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64670e3f authored by Charles Chen's avatar Charles Chen Committed by Android (Google) Code Review
Browse files

Merge "Add operation to pin TaskFragment" into main

parents 0856c9f7 dbeba776
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -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;

@@ -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,
@@ -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 {}
+8 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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(
+3 −6
Original line number Diff line number Diff line
@@ -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();
@@ -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;
        }

@@ -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)) {
+45 −10
Original line number Diff line number Diff line
@@ -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;
        }
@@ -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.
@@ -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,
@@ -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);
@@ -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);
    }

+33 −0
Original line number Diff line number Diff line
@@ -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.
     */
@@ -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