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

Commit f2701eb9 authored by Ikram Gabiyev's avatar Ikram Gabiyev Committed by Android (Google) Code Review
Browse files

Merge "Implement no anim auto-enter pip 2/3" into main

parents d89fdc62 1469d98a
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