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

Commit 849be897 authored by Ikram Gabiyev's avatar Ikram Gabiyev
Browse files

Implement fixed rotation swipe-up PiP2

Implement swipe-pip-to-home with fixed rotation
in PiP2 with seamless flip v2 at config-at-end.

As of now this produces a flicker at the end due
an early draw being applied out of sync with
activity level transform in Core; that is a Display CHANGE
transition issue to be addressed separately (seamless rotation
doesn't end using METHOD_BLAST or screenshots for PiP2).

Bug: 371249390
Flag: com.android.wm.shell.enable_pip2
Test: swipe-up to enter PiP from landscape to portrait

Change-Id: Ie6ce1c42c73a9e905e2700b2bbd2e9cdbdd88640
parent f7faa164
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -77,10 +77,12 @@ public abstract class Pip2Module {
            PipTaskListener pipTaskListener,
            @NonNull PipScheduler pipScheduler,
            @NonNull PipTransitionState pipStackListenerController,
            @NonNull PipDisplayLayoutState pipDisplayLayoutState,
            @NonNull PipUiStateChangeController pipUiStateChangeController) {
        return new PipTransition(context, shellInit, shellTaskOrganizer, transitions,
                pipBoundsState, null, pipBoundsAlgorithm, pipTaskListener,
                pipScheduler, pipStackListenerController, pipUiStateChangeController);
                pipScheduler, pipStackListenerController, pipDisplayLayoutState,
                pipUiStateChangeController);
    }

    @WMSingleton
+8 −2
Original line number Diff line number Diff line
@@ -324,10 +324,16 @@ public class PipController implements ConfigurationChangeListener,
            int launcherRotation, Rect hotseatKeepClearArea) {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "getSwipePipToHomeBounds: %s", componentName);
        // preemptively add the keep clear area for Hotseat, so that it is taken into account
        // when calculating the entry destination bounds of PiP window
        // Preemptively add the keep clear area for Hotseat, so that it is taken into account
        // when calculating the entry destination bounds of PiP window.
        mPipBoundsState.setNamedUnrestrictedKeepClearArea(
                PipBoundsState.NAMED_KCA_LAUNCHER_SHELF, hotseatKeepClearArea);

        // Set the display layout rotation early to calculate final orientation bounds that
        // the animator expects, this will also be used to detect the fixed rotation when
        // Shell resolves the type of the animation we are undergoing.
        mPipDisplayLayoutState.rotateTo(launcherRotation);

        mPipBoundsState.setBoundsStateForEntry(componentName, activityInfo, pictureInPictureParams,
                mPipBoundsAlgorithm);
        return mPipBoundsAlgorithm.getEntryDestinationBounds();
+31 −6
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.wm.shell.pip2.phone;

import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.view.Surface.ROTATION_270;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_PIP;
@@ -33,6 +34,7 @@ import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.PictureInPictureParams;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.IBinder;
@@ -49,6 +51,7 @@ import com.android.internal.util.Preconditions;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
import com.android.wm.shell.common.pip.PipBoundsState;
import com.android.wm.shell.common.pip.PipDisplayLayoutState;
import com.android.wm.shell.common.pip.PipMenuController;
import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.pip.PipTransitionController;
@@ -82,7 +85,7 @@ public class PipTransition extends PipTransitionController implements
     * The fixed start delay in ms when fading out the content overlay from bounds animation.
     * The fadeout animation is guaranteed to start after the client has drawn under the new config.
     */
    private static final int CONTENT_OVERLAY_FADE_OUT_DELAY_MS = 400;
    private static final int CONTENT_OVERLAY_FADE_OUT_DELAY_MS = 500;

    //
    // Dependencies
@@ -92,6 +95,7 @@ public class PipTransition extends PipTransitionController implements
    private final PipTaskListener mPipTaskListener;
    private final PipScheduler mPipScheduler;
    private final PipTransitionState mPipTransitionState;
    private final PipDisplayLayoutState mPipDisplayLayoutState;

    //
    // Transition caches
@@ -124,6 +128,7 @@ public class PipTransition extends PipTransitionController implements
            PipTaskListener pipTaskListener,
            PipScheduler pipScheduler,
            PipTransitionState pipTransitionState,
            PipDisplayLayoutState pipDisplayLayoutState,
            PipUiStateChangeController pipUiStateChangeController) {
        super(shellInit, shellTaskOrganizer, transitions, pipBoundsState, pipMenuController,
                pipBoundsAlgorithm);
@@ -134,6 +139,7 @@ public class PipTransition extends PipTransitionController implements
        mPipScheduler.setPipTransitionController(this);
        mPipTransitionState = pipTransitionState;
        mPipTransitionState.addPipTransitionStateChangedListener(this);
        mPipDisplayLayoutState = pipDisplayLayoutState;
    }

    @Override
@@ -321,11 +327,30 @@ public class PipTransition extends PipTransitionController implements
                            (destinationBounds.width() - overlaySize) / 2f,
                            (destinationBounds.height() - overlaySize) / 2f);
        }

        startTransaction.merge(finishTransaction);

        final int startRotation = pipChange.getStartRotation();
        final int endRotation = mPipDisplayLayoutState.getRotation();
        if (endRotation != startRotation) {
            boolean isClockwise = (endRotation - startRotation) == -ROTATION_270;

            // Display bounds were already updated to represent the final orientation,
            // so we just need to readjust the origin, and perform rotation about (0, 0).
            Rect displayBounds = mPipDisplayLayoutState.getDisplayBounds();
            int originTranslateX = isClockwise ? 0 : -displayBounds.width();
            int originTranslateY = isClockwise ? -displayBounds.height() : 0;

            Matrix transformTensor = new Matrix();
            final float[] matrixTmp = new float[9];
            transformTensor.setTranslate(originTranslateX + destinationBounds.left,
                    originTranslateY + destinationBounds.top);
            final float degrees = (endRotation - startRotation) * 90f;
            transformTensor.postRotate(degrees);
            startTransaction.setMatrix(pipLeash, transformTensor, matrixTmp);
        }
        startTransaction.apply();
        finishCallback.onTransitionFinished(null /* finishWct */);
        onClientDrawAtTransitionEnd();
        finishInner();
        return true;
    }

@@ -397,7 +422,7 @@ public class PipTransition extends PipTransitionController implements
                sourceRectHint, PipEnterExitAnimator.BOUNDS_ENTER, Surface.ROTATION_0);

        tx.addTransactionCommittedListener(mPipScheduler.getMainExecutor(),
                this::onClientDrawAtTransitionEnd);
                this::finishInner);
        finishWct.setBoundsChangeTransaction(pipTaskToken, tx);

        animator.setAnimationEndCallback(() ->
@@ -430,7 +455,7 @@ public class PipTransition extends PipTransitionController implements
        animator.setAnimationEndCallback(() -> {
            finishCallback.onTransitionFinished(null);
            // This should update the pip transition state accordingly after we stop playing.
            onClientDrawAtTransitionEnd();
            finishInner();
        });

        animator.start();
@@ -605,7 +630,7 @@ public class PipTransition extends PipTransitionController implements
    // Miscellaneous callbacks and listeners
    //

    private void onClientDrawAtTransitionEnd() {
    private void finishInner() {
        if (mPipTransitionState.getSwipePipToHomeOverlay() != null) {
            startOverlayFadeoutAnimation();
        } else if (mPipTransitionState.getState() == PipTransitionState.ENTERING_PIP) {