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

Commit 1469d98a authored by Ikram Gabiyev's avatar Ikram Gabiyev
Browse files

Implement no anim auto-enter pip 2/3

Implement no animation auto enter pip with button
navigation mode. Resolve the TransitionRequestInfo in
...pip2.PipTransition#handleRequest() and add
movePipActivityToPinnedRootTask() hierarchy op for it
to directly set the final entry pip bounds in Core.

Note that for now the bounds default to top left corner since display
layout is not being properly updated/set now - that requires
pip2.PipController to be introduced in CL 3/3. The pip is also in the
wrong state at this point since none of the other CUJs are being
handled.

Bug: 301157553
Test: mp droid

Change-Id: Ifdc9825ebf7077bbdd5807df04ebe077aa20d9e9
parent 2f33338a
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -896,6 +896,23 @@ public final class WindowContainerTransaction implements Parcelable {
        return this;
    }

    /**
     * Moves the PiP activity of a parent task to a pinned root task.
     * @param parentToken the parent task of the PiP activity
     * @param bounds the entry bounds
     * @hide
     */
    @NonNull
    public WindowContainerTransaction movePipActivityToPinnedRootTask(
            @NonNull WindowContainerToken parentToken, @NonNull Rect bounds) {
        mHierarchyOps.add(new HierarchyOp
                .Builder(HierarchyOp.HIERARCHY_OP_TYPE_MOVE_PIP_ACTIVITY_TO_PINNED_TASK)
                .setContainer(parentToken.asBinder())
                .setBounds(bounds)
                .build());
        return this;
    }

    /**
     * Merges another WCT into this one.
     * @param transfer When true, this will transfer everything from other potentially leaving
@@ -1327,6 +1344,7 @@ public final class WindowContainerTransaction implements Parcelable {
        public static final int HIERARCHY_OP_TYPE_CLEAR_ADJACENT_ROOTS = 15;
        public static final int HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH = 16;
        public static final int HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION = 17;
        public static final int HIERARCHY_OP_TYPE_MOVE_PIP_ACTIVITY_TO_PINNED_TASK = 18;

        // The following key(s) are for use with mLaunchOptions:
        // When launching a task (eg. from recents), this is the taskId to be launched.
@@ -1379,6 +1397,9 @@ public final class WindowContainerTransaction implements Parcelable {
        @Nullable
        private ShortcutInfo mShortcutInfo;

        @Nullable
        private Rect mBounds;

        private boolean mAlwaysOnTop;

        private boolean mReparentLeafTaskIfRelaunch;
@@ -1482,6 +1503,7 @@ public final class WindowContainerTransaction implements Parcelable {
        public HierarchyOp(@NonNull HierarchyOp copy) {
            mType = copy.mType;
            mContainer = copy.mContainer;
            mBounds = copy.mBounds;
            mReparent = copy.mReparent;
            mInsetsFrameProvider = copy.mInsetsFrameProvider;
            mInsetsFrameOwner = copy.mInsetsFrameOwner;
@@ -1501,6 +1523,7 @@ public final class WindowContainerTransaction implements Parcelable {
        protected HierarchyOp(Parcel in) {
            mType = in.readInt();
            mContainer = in.readStrongBinder();
            mBounds = in.readTypedObject(Rect.CREATOR);
            mReparent = in.readStrongBinder();
            mInsetsFrameProvider = in.readTypedObject(InsetsFrameProvider.CREATOR);
            mInsetsFrameOwner = in.readStrongBinder();
@@ -1599,6 +1622,11 @@ public final class WindowContainerTransaction implements Parcelable {
            return mShortcutInfo;
        }

        @NonNull
        public Rect getBounds() {
            return mBounds;
        }

        /** Gets a string representation of a hierarchy-op type. */
        public static String hopToString(int type) {
            switch (type) {
@@ -1709,6 +1737,7 @@ public final class WindowContainerTransaction implements Parcelable {
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(mType);
            dest.writeStrongBinder(mContainer);
            dest.writeTypedObject(mBounds, flags);
            dest.writeStrongBinder(mReparent);
            dest.writeTypedObject(mInsetsFrameProvider, flags);
            dest.writeStrongBinder(mInsetsFrameOwner);
@@ -1783,6 +1812,9 @@ public final class WindowContainerTransaction implements Parcelable {
            @Nullable
            private ShortcutInfo mShortcutInfo;

            @Nullable
            private Rect mBounds;

            private boolean mAlwaysOnTop;

            private boolean mReparentLeafTaskIfRelaunch;
@@ -1867,6 +1899,11 @@ public final class WindowContainerTransaction implements Parcelable {
                return this;
            }

            Builder setBounds(@NonNull Rect bounds) {
                mBounds = bounds;
                return this;
            }

            HierarchyOp build() {
                final HierarchyOp hierarchyOp = new HierarchyOp(mType);
                hierarchyOp.mContainer = mContainer;
@@ -1887,6 +1924,7 @@ public final class WindowContainerTransaction implements Parcelable {
                hierarchyOp.mAlwaysOnTop = mAlwaysOnTop;
                hierarchyOp.mTaskFragmentOperation = mTaskFragmentOperation;
                hierarchyOp.mShortcutInfo = mShortcutInfo;
                hierarchyOp.mBounds = mBounds;
                hierarchyOp.mReparentLeafTaskIfRelaunch = mReparentLeafTaskIfRelaunch;

                return hierarchyOp;
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
import com.android.wm.shell.common.pip.PipBoundsState;
import com.android.wm.shell.dagger.WMShellBaseModule;
import com.android.wm.shell.dagger.WMSingleton;
import com.android.wm.shell.pip2.PipTransition;
import com.android.wm.shell.pip2.phone.PipTransition;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;

+2 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.wm.shell.dagger.pip;
import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.dagger.WMSingleton;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip2.phone.PipTransition;

import dagger.Module;
import dagger.Provides;
@@ -36,7 +37,7 @@ public abstract class PipModule {
    @Provides
    static PipTransitionController providePipTransitionController(
            com.android.wm.shell.pip.PipTransition legacyPipTransition,
            com.android.wm.shell.pip2.PipTransition newPipTransition) {
            PipTransition newPipTransition) {
        if (PipUtils.isPip2ExperimentEnabled()) {
            return newPipTransition;
        } else {
+60 −2
Original line number Diff line number Diff line
@@ -14,9 +14,14 @@
 * limitations under the License.
 */

package com.android.wm.shell.pip2;
package com.android.wm.shell.pip2.phone;

import static android.view.WindowManager.TRANSIT_OPEN;

import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.PictureInPictureParams;
import android.graphics.Rect;
import android.os.IBinder;
import android.view.SurfaceControl;
import android.window.TransitionInfo;
@@ -34,8 +39,13 @@ import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;

/** Placeholder, for demonstrate purpose only. */
/**
 * Implementation of transitions for PiP on phone.
 */
public class PipTransition extends PipTransitionController {
    @Nullable
    private IBinder mAutoEnterButtonNavTransition;

    public PipTransition(
            @NonNull ShellInit shellInit,
            @NonNull ShellTaskOrganizer shellTaskOrganizer,
@@ -58,15 +68,63 @@ public class PipTransition extends PipTransitionController {
    @Override
    public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
            @NonNull TransitionRequestInfo request) {
        if (isAutoEnterInButtonNavigation(request)) {
            mAutoEnterButtonNavTransition = transition;
            return getEnterPipTransaction(transition, request);
        }
        return null;
    }

    @Override
    public void augmentRequest(@NonNull IBinder transition, @NonNull TransitionRequestInfo request,
            @NonNull WindowContainerTransaction outWct) {
        if (isAutoEnterInButtonNavigation(request)) {
            outWct.merge(getEnterPipTransaction(transition, request), true /* transfer */);
            mAutoEnterButtonNavTransition = transition;
        }
    }

    private WindowContainerTransaction getEnterPipTransaction(@NonNull IBinder transition,
            @NonNull TransitionRequestInfo request) {
        final ActivityManager.RunningTaskInfo pipTask = request.getPipTask();
        PictureInPictureParams pipParams = pipTask.pictureInPictureParams;
        mPipBoundsState.setBoundsStateForEntry(pipTask.topActivity, pipTask.topActivityInfo,
                pipParams, mPipBoundsAlgorithm);

        // calculate the entry bounds and notify core to move task to pinned with final bounds
        final Rect entryBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
        WindowContainerTransaction wct = new WindowContainerTransaction();
        wct.movePipActivityToPinnedRootTask(pipTask.token, entryBounds);
        return wct;
    }

    private boolean isAutoEnterInButtonNavigation(@NonNull TransitionRequestInfo requestInfo) {
        final ActivityManager.RunningTaskInfo pipTask = requestInfo.getPipTask();
        if (pipTask == null) {
            return false;
        }
        if (pipTask.pictureInPictureParams == null) {
            return false;
        }

        // Assuming auto-enter is enabled and pipTask is non-null, the TRANSIT_OPEN request type
        // implies that we are entering PiP in button navigation mode. This is guaranteed by
        // TaskFragment#startPausing()` in Core which wouldn't get called in gesture nav.
        return requestInfo.getType() == TRANSIT_OPEN
                && pipTask.pictureInPictureParams.isAutoEnterEnabled();
    }

    @Override
    public boolean startAnimation(@NonNull IBinder transition,
            @NonNull TransitionInfo info,
            @NonNull SurfaceControl.Transaction startTransaction,
            @NonNull SurfaceControl.Transaction finishTransaction,
            @NonNull Transitions.TransitionFinishCallback finishCallback) {
        if (transition == mAutoEnterButtonNavTransition) {
            startTransaction.apply();
            finishCallback.onTransitionFinished(null);
            return true;
        }
        return false;
    }

+28 −7
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATE
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
import static com.android.server.wm.ActivityTaskManagerService.TAG_SWITCH;
import static com.android.server.wm.ActivityTaskManagerService.isPip2ExperimentEnabled;
import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
@@ -2017,6 +2018,13 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
    void moveActivityToPinnedRootTask(@NonNull ActivityRecord r,
            @Nullable ActivityRecord launchIntoPipHostActivity, String reason,
            @Nullable Transition transition) {
        moveActivityToPinnedRootTask(r, launchIntoPipHostActivity, reason, transition,
                null /* bounds */);
    }

    void moveActivityToPinnedRootTask(@NonNull ActivityRecord r,
            @Nullable ActivityRecord launchIntoPipHostActivity, String reason,
            @Nullable Transition transition, @Nullable Rect bounds) {
        final TaskDisplayArea taskDisplayArea = r.getDisplayArea();
        final Task task = r.getTask();
        final Task rootTask;
@@ -2053,7 +2061,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
            // Defer the windowing mode change until after the transition to prevent the activity
            // from doing work and changing the activity visuals while animating
            // TODO(task-org): Figure-out more structured way to do this long term.
            if (!isPip2ExperimentEnabled()) {
                r.setWindowingMode(r.getWindowingMode());
            }

            final TaskFragment organizedTf = r.getOrganizedTaskFragment();
            final boolean singleActivity = task.getNonFinishingActivityCount() == 1;
@@ -2169,6 +2179,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
            // TODO(remove-legacy-transit): Move this to the `singleActivity` case when removing
            //                              legacy transit.
            rootTask.setWindowingMode(WINDOWING_MODE_PINNED);
            if (isPip2ExperimentEnabled() && bounds != null) {
                // set the final pip bounds in advance if pip2 is enabled
                rootTask.setBounds(bounds);
            }

            // Set the launch bounds for launch-into-pip Activity on the root task.
            if (r.getOptions() != null && r.getOptions().isLaunchIntoPip()) {
                // Record the snapshot now, it will be later fetched for content-pip animation.
@@ -2180,10 +2195,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
            }
            rootTask.setDeferTaskAppear(false);

            if (!isPip2ExperimentEnabled()) {
                // After setting this, it is not expected to change activity configuration until the
                // transition animation is finished. So the activity can keep consistent appearance
                // when animating.
                r.mWaitForEnteringPinnedMode = true;
            }
            // Reset the state that indicates it can enter PiP while pausing after we've moved it
            // to the root pinned task
            r.supportsEnterPipOnTaskSwitch = false;
@@ -2198,7 +2215,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
        } finally {
            mService.continueWindowLayout();
            try {
                if (!isPip2ExperimentEnabled()) {
                    ensureActivitiesVisible(null, 0, false /* preserveWindows */);
                }
            } finally {
                transitionController.continueTransitionReady();
            }
@@ -2214,7 +2233,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
            newTransition.setReady(rootTask, true /* ready */);
        }

        if (!isPip2ExperimentEnabled()) {
            resumeFocusedTasksTopActivities();
        }

        notifyActivityPipModeChanged(r.getTask(), r);
    }
Loading