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

Commit cccf15a3 authored by Ikram Gabiyev's avatar Ikram Gabiyev
Browse files

Handle aspect ratio changes in PiP2

Make sure to resize and update PiP bounds
if PiP2 flag is on upon an onTaskInfoChanged()
signal from the client if the requested aspect ratio
is different.

Note that we are not using config-at-end for aspect ratio change.

Also moved the movement bounds and pip bounds updates
for resize transitions into PipScheduler, to avoid
redundancy.

Bug: 361333135
Flag: com.android.wm.shell.enable_pip2_implementation
Test: atest PinnedStackTests#testChangeAspectRationWhenInPipMode
Change-Id: Ic03c01f1b6a5e204e1cc52912cb352a5684f8495
parent 3bc44be9
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import com.android.wm.shell.pip2.phone.PhonePipMenuController;
import com.android.wm.shell.pip2.phone.PipController;
import com.android.wm.shell.pip2.phone.PipMotionHelper;
import com.android.wm.shell.pip2.phone.PipScheduler;
import com.android.wm.shell.pip2.phone.PipTaskListener;
import com.android.wm.shell.pip2.phone.PipTouchHandler;
import com.android.wm.shell.pip2.phone.PipTransition;
import com.android.wm.shell.pip2.phone.PipTransitionState;
@@ -73,12 +74,13 @@ public abstract class Pip2Module {
            PipBoundsAlgorithm pipBoundsAlgorithm,
            Optional<PipController> pipController,
            PipTouchHandler pipTouchHandler,
            PipTaskListener pipTaskListener,
            @NonNull PipScheduler pipScheduler,
            @NonNull PipTransitionState pipStackListenerController,
            @NonNull PipUiStateChangeController pipUiStateChangeController) {
        return new PipTransition(context, shellInit, shellTaskOrganizer, transitions,
                pipBoundsState, null, pipBoundsAlgorithm, pipScheduler,
                pipStackListenerController, pipUiStateChangeController);
                pipBoundsState, null, pipBoundsAlgorithm, pipTaskListener,
                pipScheduler, pipStackListenerController, pipUiStateChangeController);
    }

    @WMSingleton
@@ -123,9 +125,11 @@ public abstract class Pip2Module {
    @Provides
    static PipScheduler providePipScheduler(Context context,
            PipBoundsState pipBoundsState,
            PhonePipMenuController pipMenuController,
            @ShellMainThread ShellExecutor mainExecutor,
            PipTransitionState pipTransitionState) {
        return new PipScheduler(context, pipBoundsState, mainExecutor, pipTransitionState);
        return new PipScheduler(context, pipBoundsState, pipMenuController,
                mainExecutor, pipTransitionState);
    }

    @WMSingleton
@@ -190,4 +194,17 @@ public abstract class Pip2Module {
            PipTransitionState pipTransitionState) {
        return new PipUiStateChangeController(pipTransitionState);
    }

    @WMSingleton
    @Provides
    static PipTaskListener providePipTaskListener(Context context,
            ShellTaskOrganizer shellTaskOrganizer,
            PipTransitionState pipTransitionState,
            PipScheduler pipScheduler,
            PipBoundsState pipBoundsState,
            PipBoundsAlgorithm pipBoundsAlgorithm,
            @ShellMainThread ShellExecutor mainExecutor) {
        return new PipTaskListener(context, shellTaskOrganizer, pipTransitionState,
                pipScheduler, pipBoundsState, pipBoundsAlgorithm, mainExecutor);
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -134,9 +134,10 @@ public class PipResizeAnimator extends ValueAnimator
            Rect baseBounds, Rect targetBounds, float degrees) {
        Matrix transformTensor = new Matrix();
        final float[] mMatrixTmp = new float[9];
        final float scale = (float) targetBounds.width() / baseBounds.width();
        final float scaleX = (float) targetBounds.width() / baseBounds.width();
        final float scaleY = (float) targetBounds.height() / baseBounds.height();

        transformTensor.setScale(scale, scale);
        transformTensor.setScale(scaleX, scaleY);
        transformTensor.postTranslate(targetBounds.left, targetBounds.top);
        transformTensor.postRotate(degrees, targetBounds.centerX(), targetBounds.centerY());

+3 −29
Original line number Diff line number Diff line
@@ -56,7 +56,6 @@ import kotlin.Unit;
import kotlin.jvm.functions.Function0;

import java.util.Optional;
import java.util.function.Consumer;

/**
 * A helper to animate and manipulate the PiP.
@@ -134,18 +133,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
    private final PhysicsAnimator.SpringConfig mConflictResolutionSpringConfig =
            new PhysicsAnimator.SpringConfig(STIFFNESS_LOW, DAMPING_RATIO_NO_BOUNCY);

    @Nullable private Runnable mUpdateMovementBoundsRunnable;

    private final Consumer<Rect> mUpdateBoundsCallback = (Rect newBounds) -> {
        if (mPipBoundsState.getBounds().equals(newBounds)) {
            return;
        }

        mMenuController.updateMenuLayout(newBounds);
        mPipBoundsState.setBounds(newBounds);
        maybeUpdateMovementBounds();
    };

    /**
     * Whether we're springing to the touch event location (vs. moving it to that position
     * instantly). We spring-to-touch after PIP is dragged out of the magnetic target, since it was
@@ -683,16 +670,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
        cleanUpHighPerfSessionMaybe();
    }

    void setUpdateMovementBoundsRunnable(Runnable updateMovementBoundsRunnable) {
        mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable;
    }

    private void maybeUpdateMovementBounds() {
        if (mUpdateMovementBoundsRunnable != null)  {
            mUpdateMovementBoundsRunnable.run();
        }
    }

    /**
     * Notifies the floating coordinator that we're moving, and sets the animating to bounds so
     * we return these bounds from
@@ -720,7 +697,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
    /**
     * Directly resizes the PiP to the given {@param bounds}.
     */
    private void resizeAndAnimatePipUnchecked(Rect toBounds, int duration) {
    void resizeAndAnimatePipUnchecked(Rect toBounds, int duration) {
        if (mPipBoundsState.getMotionBoundsState().isInMotion()) {
            // Do not carry out any resizing if we are dragging or physics animator is running.
            return;
@@ -813,7 +790,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
        cleanUpHighPerfSessionMaybe();

        // Signal that the transition is done - should update transition state by default.
        mPipScheduler.scheduleFinishResizePip(false /* configAtEnd */);
        mPipScheduler.scheduleFinishResizePip(destinationBounds, false /* configAtEnd */);
    }

    private void startResizeAnimation(SurfaceControl.Transaction startTx,
@@ -829,8 +806,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
                startTx, finishTx, mPipBoundsState.getBounds(), mPipBoundsState.getBounds(),
                destinationBounds, duration, 0f /* angle */);
        animator.setAnimationEndCallback(() -> {
            mUpdateBoundsCallback.accept(destinationBounds);

            // In case an ongoing drag/fling was present before a deterministic resize transition
            // kicked in, we need to update the update bounds properly before cleaning in-motion
            // state.
@@ -839,7 +814,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,

            cleanUpHighPerfSessionMaybe();
            // Signal that we are done with resize transition
            mPipScheduler.scheduleFinishResizePip(true /* configAtEnd */);
            mPipScheduler.scheduleFinishResizePip(destinationBounds, true /* configAtEnd */);
        });
        animator.start();
    }
@@ -849,7 +824,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
            // The physics animation ended, though we may not necessarily be done animating, such as
            // when we're still dragging after moving out of the magnetic target. Only set the final
            // bounds state and clear motion bounds completely if the whole animation is over.
            mPipBoundsState.setBounds(mPipBoundsState.getMotionBoundsState().getBoundsInMotion());
            mPipBoundsState.getMotionBoundsState().onAllAnimationsEnded();
        }
        mPipBoundsState.getMotionBoundsState().onPhysicsAnimationEnded();
+4 −15
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.pip2.animation.PipResizeAnimator;

import java.io.PrintWriter;
import java.util.function.Consumer;

/**
 * Helper on top of PipTouchHandler that handles inputs OUTSIDE of the PIP window, which is used to
@@ -86,8 +85,6 @@ public class PipResizeGestureHandler implements
    private final Rect mUserResizeBounds = new Rect();
    private final Rect mDownBounds = new Rect();
    private final Rect mStartBoundsAfterRelease = new Rect();
    private final Runnable mUpdateMovementBoundsRunnable;
    private final Consumer<Rect> mUpdateResizeBoundsCallback;

    private float mTouchSlop;

@@ -121,7 +118,6 @@ public class PipResizeGestureHandler implements
            PipTouchState pipTouchState,
            PipScheduler pipScheduler,
            PipTransitionState pipTransitionState,
            Runnable updateMovementBoundsRunnable,
            PipUiEventLogger pipUiEventLogger,
            PhonePipMenuController menuActivityController,
            ShellExecutor mainExecutor,
@@ -138,18 +134,9 @@ public class PipResizeGestureHandler implements
        mPipTransitionState = pipTransitionState;
        mPipTransitionState.addPipTransitionStateChangedListener(this);

        mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable;
        mPhonePipMenuController = menuActivityController;
        mPipUiEventLogger = pipUiEventLogger;
        mPinchResizingAlgorithm = new PipPinchResizingAlgorithm();

        mUpdateResizeBoundsCallback = (rect) -> {
            mUserResizeBounds.set(rect);
            // mMotionHelper.synchronizePinnedStackBounds();
            mPipBoundsState.setBounds(rect);
            mUpdateMovementBoundsRunnable.run();
            resetState();
        };
    }

    void init() {
@@ -563,11 +550,13 @@ public class PipResizeGestureHandler implements
                        mLastResizeBounds, duration, mAngle);
                animator.setAnimationEndCallback(() -> {
                    // All motion operations have actually finished, so make bounds cache updates.
                    mUpdateResizeBoundsCallback.accept(mLastResizeBounds);
                    mUserResizeBounds.set(mLastResizeBounds);
                    resetState();
                    cleanUpHighPerfSessionMaybe();

                    // Signal that we are done with resize transition
                    mPipScheduler.scheduleFinishResizePip(true /* configAtEnd */);
                    mPipScheduler.scheduleFinishResizePip(
                            mLastResizeBounds, true /* configAtEnd */);
                });
                animator.start();
                break;
+29 −1
Original line number Diff line number Diff line
@@ -52,11 +52,14 @@ public class PipScheduler {

    private final Context mContext;
    private final PipBoundsState mPipBoundsState;
    private final PhonePipMenuController mPipMenuController;
    private final ShellExecutor mMainExecutor;
    private final PipTransitionState mPipTransitionState;
    private PipSchedulerReceiver mSchedulerReceiver;
    private PipTransitionController mPipTransitionController;

    @Nullable private Runnable mUpdateMovementBoundsRunnable;

    /**
     * Temporary PiP CUJ codes to schedule PiP related transitions directly from Shell.
     * This is used for a broadcast receiver to resolve intents. This should be removed once
@@ -94,10 +97,12 @@ public class PipScheduler {

    public PipScheduler(Context context,
            PipBoundsState pipBoundsState,
            PhonePipMenuController pipMenuController,
            ShellExecutor mainExecutor,
            PipTransitionState pipTransitionState) {
        mContext = context;
        mPipBoundsState = pipBoundsState;
        mPipMenuController = pipMenuController;
        mMainExecutor = mainExecutor;
        mPipTransitionState = pipTransitionState;

@@ -189,9 +194,13 @@ public class PipScheduler {
     * Signals to Core to finish the PiP resize transition.
     * Note that we do not allow any actual WM Core changes at this point.
     *
     * @param toBounds destination bounds used only for internal state updates - not sent to Core.
     * @param configAtEnd true if we are waiting for config updates at the end of the transition.
     */
    public void scheduleFinishResizePip(boolean configAtEnd) {
    public void scheduleFinishResizePip(Rect toBounds, boolean configAtEnd) {
        // Make updates to the internal state to reflect new bounds
        onFinishingPipResize(toBounds);

        SurfaceControl.Transaction tx = null;
        if (configAtEnd) {
            tx = new SurfaceControl.Transaction();
@@ -238,4 +247,23 @@ public class PipScheduler {
        tx.setMatrix(leash, transformTensor, mMatrixTmp);
        tx.apply();
    }

    void setUpdateMovementBoundsRunnable(Runnable updateMovementBoundsRunnable) {
        mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable;
    }

    private void maybeUpdateMovementBounds() {
        if (mUpdateMovementBoundsRunnable != null)  {
            mUpdateMovementBoundsRunnable.run();
        }
    }

    private void onFinishingPipResize(Rect newBounds) {
        if (mPipBoundsState.getBounds().equals(newBounds)) {
            return;
        }
        mPipBoundsState.setBounds(newBounds);
        mPipMenuController.updateMenuLayout(newBounds);
        maybeUpdateMovementBounds();
    }
}
Loading