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

Commit aebafa28 authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

Merge "Fix ActivityEmbedding issues with REORDER_TO_FRONT" into tm-qpr-dev

parents f4f0f07c 722ec8b7
Loading
Loading
Loading
Loading
+62 −2
Original line number Diff line number Diff line
@@ -71,20 +71,42 @@ public final class TaskFragmentCreationParams implements Parcelable {
     *
     * This is needed in case we need to launch a placeholder Activity to split below a transparent
     * always-expand Activity.
     *
     * This should not be used with {@link #mPairedActivityToken}.
     */
    @Nullable
    private final IBinder mPairedPrimaryFragmentToken;

    /**
     * The Activity token to place the new TaskFragment on top of.
     * When it is set, the new TaskFragment will be positioned right above the target Activity.
     * Otherwise, the new TaskFragment will be positioned on the top of the Task by default.
     *
     * This is needed in case we need to place an Activity into TaskFragment to launch placeholder
     * below a transparent always-expand Activity, or when there is another Intent being started in
     * a TaskFragment above.
     *
     * This should not be used with {@link #mPairedPrimaryFragmentToken}.
     */
    @Nullable
    private final IBinder mPairedActivityToken;

    private TaskFragmentCreationParams(
            @NonNull TaskFragmentOrganizerToken organizer, @NonNull IBinder fragmentToken,
            @NonNull IBinder ownerToken, @NonNull Rect initialBounds,
            @WindowingMode int windowingMode, @Nullable IBinder pairedPrimaryFragmentToken) {
            @WindowingMode int windowingMode, @Nullable IBinder pairedPrimaryFragmentToken,
            @Nullable IBinder pairedActivityToken) {
        if (pairedPrimaryFragmentToken != null && pairedActivityToken != null) {
            throw new IllegalArgumentException("pairedPrimaryFragmentToken and"
                    + " pairedActivityToken should not be set at the same time.");
        }
        mOrganizer = organizer;
        mFragmentToken = fragmentToken;
        mOwnerToken = ownerToken;
        mInitialBounds.set(initialBounds);
        mWindowingMode = windowingMode;
        mPairedPrimaryFragmentToken = pairedPrimaryFragmentToken;
        mPairedActivityToken = pairedActivityToken;
    }

    @NonNull
@@ -121,6 +143,15 @@ public final class TaskFragmentCreationParams implements Parcelable {
        return mPairedPrimaryFragmentToken;
    }

    /**
     * TODO(b/232476698): remove the hide with adding CTS for this in next release.
     * @hide
     */
    @Nullable
    public IBinder getPairedActivityToken() {
        return mPairedActivityToken;
    }

    private TaskFragmentCreationParams(Parcel in) {
        mOrganizer = TaskFragmentOrganizerToken.CREATOR.createFromParcel(in);
        mFragmentToken = in.readStrongBinder();
@@ -128,6 +159,7 @@ public final class TaskFragmentCreationParams implements Parcelable {
        mInitialBounds.readFromParcel(in);
        mWindowingMode = in.readInt();
        mPairedPrimaryFragmentToken = in.readStrongBinder();
        mPairedActivityToken = in.readStrongBinder();
    }

    /** @hide */
@@ -139,6 +171,7 @@ public final class TaskFragmentCreationParams implements Parcelable {
        mInitialBounds.writeToParcel(dest, flags);
        dest.writeInt(mWindowingMode);
        dest.writeStrongBinder(mPairedPrimaryFragmentToken);
        dest.writeStrongBinder(mPairedActivityToken);
    }

    @NonNull
@@ -164,6 +197,7 @@ public final class TaskFragmentCreationParams implements Parcelable {
                + " initialBounds=" + mInitialBounds
                + " windowingMode=" + mWindowingMode
                + " pairedFragmentToken=" + mPairedPrimaryFragmentToken
                + " pairedActivityToken=" + mPairedActivityToken
                + "}";
    }

@@ -194,6 +228,9 @@ public final class TaskFragmentCreationParams implements Parcelable {
        @Nullable
        private IBinder mPairedPrimaryFragmentToken;

        @Nullable
        private IBinder mPairedActivityToken;

        public Builder(@NonNull TaskFragmentOrganizerToken organizer,
                @NonNull IBinder fragmentToken, @NonNull IBinder ownerToken) {
            mOrganizer = organizer;
@@ -224,6 +261,8 @@ public final class TaskFragmentCreationParams implements Parcelable {
         * This is needed in case we need to launch a placeholder Activity to split below a
         * transparent always-expand Activity.
         *
         * This should not be used with {@link #setPairedActivityToken}.
         *
         * TODO(b/232476698): remove the hide with adding CTS for this in next release.
         * @hide
         */
@@ -233,11 +272,32 @@ public final class TaskFragmentCreationParams implements Parcelable {
            return this;
        }

        /**
         * Sets the Activity token to place the new TaskFragment on top of.
         * When it is set, the new TaskFragment will be positioned right above the target Activity.
         * Otherwise, the new TaskFragment will be positioned on the top of the Task by default.
         *
         * This is needed in case we need to place an Activity into TaskFragment to launch
         * placeholder below a transparent always-expand Activity, or when there is another Intent
         * being started in a TaskFragment above.
         *
         * This should not be used with {@link #setPairedPrimaryFragmentToken}.
         *
         * TODO(b/232476698): remove the hide with adding CTS for this in next release.
         * @hide
         */
        @NonNull
        public Builder setPairedActivityToken(@Nullable IBinder activityToken) {
            mPairedActivityToken = activityToken;
            return this;
        }

        /** Constructs the options to create TaskFragment with. */
        @NonNull
        public TaskFragmentCreationParams build() {
            return new TaskFragmentCreationParams(mOrganizer, mFragmentToken, mOwnerToken,
                    mInitialBounds, mWindowingMode, mPairedPrimaryFragmentToken);
                    mInitialBounds, mWindowingMode, mPairedPrimaryFragmentToken,
                    mPairedActivityToken);
        }
    }
}
+19 −2
Original line number Diff line number Diff line
@@ -191,10 +191,25 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
     */
    void createTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
            @NonNull IBinder ownerToken, @NonNull Rect bounds, @WindowingMode int windowingMode) {
        createTaskFragment(wct, fragmentToken, ownerToken, bounds, windowingMode,
                null /* pairedActivityToken */);
    }

    /**
     * @param ownerToken The token of the activity that creates this task fragment. It does not
     *                   have to be a child of this task fragment, but must belong to the same task.
     * @param pairedActivityToken The token of the activity that will be reparented to this task
     *                            fragment. When it is not {@code null}, the task fragment will be
     *                            positioned right above it.
     */
    void createTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
            @NonNull IBinder ownerToken, @NonNull Rect bounds, @WindowingMode int windowingMode,
            @Nullable IBinder pairedActivityToken) {
        final TaskFragmentCreationParams fragmentOptions = new TaskFragmentCreationParams.Builder(
                getOrganizerToken(), fragmentToken, ownerToken)
                .setInitialBounds(bounds)
                .setWindowingMode(windowingMode)
                .setPairedActivityToken(pairedActivityToken)
                .build();
        createTaskFragment(wct, fragmentOptions);
    }
@@ -216,8 +231,10 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer {
    private void createTaskFragmentAndReparentActivity(@NonNull WindowContainerTransaction wct,
            @NonNull IBinder fragmentToken, @NonNull IBinder ownerToken, @NonNull Rect bounds,
            @WindowingMode int windowingMode, @NonNull Activity activity) {
        createTaskFragment(wct, fragmentToken, ownerToken, bounds, windowingMode);
        wct.reparentActivityToTaskFragment(fragmentToken, activity.getActivityToken());
        final IBinder reparentActivityToken = activity.getActivityToken();
        createTaskFragment(wct, fragmentToken, ownerToken, bounds, windowingMode,
                reparentActivityToken);
        wct.reparentActivityToTaskFragment(fragmentToken, reparentActivityToken);
    }

    void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
+1 −1
Original line number Diff line number Diff line
@@ -1499,7 +1499,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
     * Returns the active split that has the provided containers as primary and secondary or as
     * secondary and primary, if available.
     */
    @VisibleForTesting
    @GuardedBy("mLock")
    @Nullable
    SplitContainer getActiveSplitForContainers(
            @NonNull TaskFragmentContainer firstContainer,
+4 −3
Original line number Diff line number Diff line
@@ -268,10 +268,11 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
            container = mController.newContainer(activity, taskId);
            final int windowingMode = mController.getTaskContainer(taskId)
                    .getWindowingModeForSplitTaskFragment(bounds);
            createTaskFragment(wct, container.getTaskFragmentToken(), activity.getActivityToken(),
                    bounds, windowingMode);
            final IBinder reparentActivityToken = activity.getActivityToken();
            createTaskFragment(wct, container.getTaskFragmentToken(), reparentActivityToken,
                    bounds, windowingMode, reparentActivityToken);
            wct.reparentActivityToTaskFragment(container.getTaskFragmentToken(),
                    activity.getActivityToken());
                    reparentActivityToken);
        } else {
            resizeTaskFragmentIfRegistered(wct, container, bounds);
            final int windowingMode = mController.getTaskContainer(taskId)
+38 −0
Original line number Diff line number Diff line
@@ -141,12 +141,26 @@ class TaskFragmentContainer {
        mToken = new Binder("TaskFragmentContainer");
        mTaskContainer = taskContainer;
        if (pairedPrimaryContainer != null) {
            // The TaskFragment will be positioned right above the paired container.
            if (pairedPrimaryContainer.getTaskContainer() != taskContainer) {
                throw new IllegalArgumentException(
                        "pairedPrimaryContainer must be in the same Task");
            }
            final int primaryIndex = taskContainer.mContainers.indexOf(pairedPrimaryContainer);
            taskContainer.mContainers.add(primaryIndex + 1, this);
        } else if (pendingAppearedActivity != null) {
            // The TaskFragment will be positioned right above the pending appeared Activity. If any
            // existing TaskFragment is empty with pending Intent, it is likely that the Activity of
            // the pending Intent hasn't been created yet, so the new Activity should be below the
            // empty TaskFragment.
            int i = taskContainer.mContainers.size() - 1;
            for (; i >= 0; i--) {
                final TaskFragmentContainer container = taskContainer.mContainers.get(i);
                if (!container.isEmpty() || container.getPendingAppearedIntent() == null) {
                    break;
                }
            }
            taskContainer.mContainers.add(i + 1, this);
        } else {
            taskContainer.mContainers.add(this);
        }
@@ -500,6 +514,8 @@ class TaskFragmentContainer {
        }

        if (!shouldFinishDependent) {
            // Always finish the placeholder when the primary is finished.
            finishPlaceholderIfAny(wct, presenter);
            return;
        }

@@ -526,6 +542,28 @@ class TaskFragmentContainer {
        mActivitiesToFinishOnExit.clear();
    }

    @GuardedBy("mController.mLock")
    private void finishPlaceholderIfAny(@NonNull WindowContainerTransaction wct,
            @NonNull SplitPresenter presenter) {
        final List<TaskFragmentContainer> containersToRemove = new ArrayList<>();
        for (TaskFragmentContainer container : mContainersToFinishOnExit) {
            if (container.mIsFinished) {
                continue;
            }
            final SplitContainer splitContainer = mController.getActiveSplitForContainers(
                    this, container);
            if (splitContainer != null && splitContainer.isPlaceholderContainer()
                    && splitContainer.getSecondaryContainer() == container) {
                // Remove the placeholder secondary TaskFragment.
                containersToRemove.add(container);
            }
        }
        mContainersToFinishOnExit.removeAll(containersToRemove);
        for (TaskFragmentContainer container : containersToRemove) {
            container.finish(false /* shouldFinishDependent */, presenter, wct, mController);
        }
    }

    boolean isFinished() {
        return mIsFinished;
    }
Loading