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

Commit 4d69fab5 authored by Hongwei Wang's avatar Hongwei Wang
Browse files

Support autoEnterPip without source rect hint

When no source rect hint is specified, autoEnterPip simply scale the
window down to the PiP.

Video: http://rcll/aaaaaabFQoRHlzixHdtY/cdY8k6V9uhJEXyMAKAUA34
Video: http://rcll/aaaaaabFQoRHlzixHdtY/bvodLNGyrIXH8DSvGHehrp
Bug: 179286893
Test: manual in ApiDemos app, see video
Change-Id: Ife4f1a56ddfd61c13383da9a1066e3d8b4a2181c
parent fd03d04a
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -1071,9 +1071,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
                    && runningTaskTarget != null
                    && runningTaskTarget.pictureInPictureParams != null
                    && TaskInfoCompat.isAutoEnterPipEnabled(
                            runningTaskTarget.pictureInPictureParams)
                    && TaskInfoCompat.getPipSourceRectHint(
                            runningTaskTarget.pictureInPictureParams) != null;
                            runningTaskTarget.pictureInPictureParams);
            if (mIsSwipingPipToHome) {
                mSwipePipToHomeAnimator = getSwipePipToHomeAnimator(
                        homeAnimFactory, runningTaskTarget, start);
@@ -1176,8 +1174,10 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
            swipePipToHomeAnimator.setFromRotation(mTaskViewSimulator, windowRotation);
        }
        swipePipToHomeAnimator.addListener(new AnimatorListenerAdapter() {
            private boolean mHasAnimationEnded;
            @Override
            public void onAnimationStart(Animator animation) {
                if (mHasAnimationEnded) return;
                // Ensure Launcher ends in NORMAL state, we intentionally skip other callbacks
                // since they are not relevant in this swipe-pip-to-home case.
                homeAnimFactory.createActivityAnimationToHome().dispatchOnStart();
@@ -1185,6 +1185,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends

            @Override
            public void onAnimationEnd(Animator animation) {
                if (mHasAnimationEnded) return;
                mHasAnimationEnded = true;
                if (mRecentsAnimationController == null) {
                    // If the recents animation is interrupted, we still end the running
                    // animation (not canceled) so this is still called. In that case, we can
+70 −25
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.view.SurfaceControl;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.systemui.shared.pip.PipSurfaceTransactionHelper;
@@ -60,7 +61,7 @@ public class SwipePipToHomeAnimator extends ValueAnimator implements
    /** for calculating the transform in {@link #onAnimationUpdate(ValueAnimator)} */
    private final RectEvaluator mRectEvaluator = new RectEvaluator(new Rect());
    private final RectEvaluator mInsetsEvaluator = new RectEvaluator(new Rect());
    private final Rect mSourceHintRectInsets = new Rect();
    private final Rect mSourceHintRectInsets;
    private final Rect mSourceInsets = new Rect();

    /** for rotation via {@link #setFromRotation(TaskViewSimulator, int)} */
@@ -89,7 +90,7 @@ public class SwipePipToHomeAnimator extends ValueAnimator implements
    public SwipePipToHomeAnimator(int taskId,
            @NonNull ComponentName componentName,
            @NonNull SurfaceControl leash,
            @NonNull Rect sourceRectHint,
            @Nullable Rect sourceRectHint,
            @NonNull Rect appBounds,
            @NonNull Rect startBounds,
            @NonNull Rect destinationBounds,
@@ -104,10 +105,14 @@ public class SwipePipToHomeAnimator extends ValueAnimator implements
        mDestinationBoundsAnimation.set(mDestinationBounds);
        mSurfaceTransactionHelper = new PipSurfaceTransactionHelper();

        mSourceHintRectInsets.set(sourceRectHint.left - appBounds.left,
        if (sourceRectHint == null) {
            mSourceHintRectInsets = null;
        } else {
            mSourceHintRectInsets = new Rect(sourceRectHint.left - appBounds.left,
                    sourceRectHint.top - appBounds.top,
                    appBounds.right - sourceRectHint.right,
                    appBounds.bottom - sourceRectHint.bottom);
        }

        addListener(new AnimationSuccessListener() {
            @Override
@@ -168,32 +173,42 @@ public class SwipePipToHomeAnimator extends ValueAnimator implements
        final float fraction = animator.getAnimatedFraction();
        final Rect bounds = mRectEvaluator.evaluate(fraction, mStartBounds,
                mDestinationBoundsAnimation);
        final Rect insets = mInsetsEvaluator.evaluate(fraction, mSourceInsets,
                mSourceHintRectInsets);
        final SurfaceControl.Transaction tx =
                PipSurfaceTransactionHelper.newSurfaceControlTransaction();
        if (mSourceHintRectInsets == null) {
            // no source rect hint been set, directly scale the window down
            onAnimationScale(fraction, tx, bounds);
        } else {
            // scale and crop according to the source rect hint
            onAnimationScaleAndCrop(fraction, tx, bounds);
        }
        mSurfaceTransactionHelper.resetCornerRadius(tx, mLeash);
        tx.apply();
    }

    /** scale the window directly with no source rect hint being set */
    private void onAnimationScale(float fraction, SurfaceControl.Transaction tx, Rect bounds) {
        if (mFromRotation == Surface.ROTATION_90 || mFromRotation == Surface.ROTATION_270) {
            final float degree, positionX, positionY;
            if (mFromRotation == Surface.ROTATION_90) {
                degree = -90 * fraction;
                positionX = fraction * (mDestinationBoundsTransformed.left - mAppBounds.left)
                        + mAppBounds.left;
                positionY = fraction * (mDestinationBoundsTransformed.bottom - mAppBounds.top)
                        + mAppBounds.top;
            final RotatedPosition rotatedPosition = getRotatedPosition(fraction);
            mSurfaceTransactionHelper.scale(tx, mLeash, mAppBounds, bounds,
                    rotatedPosition.degree, rotatedPosition.positionX, rotatedPosition.positionY);
        } else {
                degree = 90 * fraction;
                positionX = fraction * (mDestinationBoundsTransformed.right - mAppBounds.left)
                        + mAppBounds.left;
                positionY = fraction * (mDestinationBoundsTransformed.top - mAppBounds.top)
                        + mAppBounds.top;
            mSurfaceTransactionHelper.scale(tx, mLeash, mAppBounds, bounds);
        }
    }

    /** scale and crop the window with source rect hint */
    private void onAnimationScaleAndCrop(float fraction, SurfaceControl.Transaction tx,
            Rect bounds) {
        final Rect insets = mInsetsEvaluator.evaluate(fraction, mSourceInsets,
                mSourceHintRectInsets);
        if (mFromRotation == Surface.ROTATION_90 || mFromRotation == Surface.ROTATION_270) {
            final RotatedPosition rotatedPosition = getRotatedPosition(fraction);
            mSurfaceTransactionHelper.scaleAndRotate(tx, mLeash, mAppBounds, bounds, insets,
                    degree, positionX, positionY);
                    rotatedPosition.degree, rotatedPosition.positionX, rotatedPosition.positionY);
        } else {
            mSurfaceTransactionHelper.scaleAndCrop(tx, mLeash, mAppBounds, bounds, insets);
        }
        mSurfaceTransactionHelper.resetCornerRadius(tx, mLeash);
        tx.apply();
    }

    public int getTaskId() {
@@ -217,4 +232,34 @@ public class SwipePipToHomeAnimator extends ValueAnimator implements
        tx.apply();
        mHasAnimationEnded = true;
    }

    private RotatedPosition getRotatedPosition(float fraction) {
        final float degree, positionX, positionY;
        if (mFromRotation == Surface.ROTATION_90) {
            degree = -90 * fraction;
            positionX = fraction * (mDestinationBoundsTransformed.left - mAppBounds.left)
                    + mAppBounds.left;
            positionY = fraction * (mDestinationBoundsTransformed.bottom - mAppBounds.top)
                    + mAppBounds.top;
        } else {
            degree = 90 * fraction;
            positionX = fraction * (mDestinationBoundsTransformed.right - mAppBounds.left)
                    + mAppBounds.left;
            positionY = fraction * (mDestinationBoundsTransformed.top - mAppBounds.top)
                    + mAppBounds.top;
        }
        return new RotatedPosition(degree, positionX, positionY);
    }

    private static class RotatedPosition {
        private final float degree;
        private final float positionX;
        private final float positionY;

        private RotatedPosition(float degree, float positionX, float positionY) {
            this.degree = degree;
            this.positionX = positionX;
            this.positionY = positionY;
        }
    }
}