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

Commit 005e2692 authored by Hongwei Wang's avatar Hongwei Wang Committed by Android (Google) Code Review
Browse files

Merge "Polish auto-enter-pip from landscape and split-screen" into sc-dev

parents 4e0bc773 338bdd1f
Loading
Loading
Loading
Loading
+30 −14
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import android.content.Intent;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.os.IBinder;
import android.os.SystemClock;
@@ -1233,30 +1234,40 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
        final RecentsOrientedState orientationState = mTaskViewSimulator.getOrientationState();
        final int windowRotation = orientationState.getDisplayRotation();
        final int homeRotation = orientationState.getRecentsActivityRotation();

        final Matrix homeToWindowPositionMap = new Matrix();
        final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap, startProgress);
        // Move the startRect to Launcher space as floatingIconView runs in Launcher
        final Matrix windowToHomePositionMap = new Matrix();
        homeToWindowPositionMap.invert(windowToHomePositionMap);
        windowToHomePositionMap.mapRect(startRect);

        final Rect destinationBounds = SystemUiProxy.INSTANCE.get(mContext)
                .startSwipePipToHome(taskInfo.topActivity,
                        TaskInfoCompat.getTopActivityInfo(taskInfo),
                        runningTaskTarget.taskInfo.pictureInPictureParams,
                        homeRotation,
                        mDp.hotseatBarSizePx);
        final SwipePipToHomeAnimator swipePipToHomeAnimator = new SwipePipToHomeAnimator(
                mContext,
                runningTaskTarget.taskId,
                taskInfo.topActivity,
                runningTaskTarget.leash.getSurfaceControl(),
                TaskInfoCompat.getPipSourceRectHint(
                        runningTaskTarget.taskInfo.pictureInPictureParams),
                TaskInfoCompat.getWindowConfigurationBounds(taskInfo),
                updateProgressForStartRect(new Matrix(), startProgress),
                destinationBounds,
                mRecentsView.getPipCornerRadius(),
                mRecentsView);
        final SwipePipToHomeAnimator.Builder builder = new SwipePipToHomeAnimator.Builder()
                .setContext(mContext)
                .setTaskId(runningTaskTarget.taskId)
                .setComponentName(taskInfo.topActivity)
                .setLeash(runningTaskTarget.leash.getSurfaceControl())
                .setSourceRectHint(TaskInfoCompat.getPipSourceRectHint(
                        runningTaskTarget.taskInfo.pictureInPictureParams))
                .setAppBounds(TaskInfoCompat.getWindowConfigurationBounds(taskInfo))
                .setHomeToWindowPositionMap(homeToWindowPositionMap)
                .setStartBounds(startRect)
                .setDestinationBounds(destinationBounds)
                .setCornerRadius(mRecentsView.getPipCornerRadius())
                .setAttachedView(mRecentsView);
        // We would assume home and app window always in the same rotation While homeRotation
        // is not ROTATION_0 (which implies the rotation is turned on in launcher settings).
        if (homeRotation == ROTATION_0
                && (windowRotation == ROTATION_90 || windowRotation == ROTATION_270)) {
            swipePipToHomeAnimator.setFromRotation(mTaskViewSimulator, windowRotation);
            builder.setFromRotation(mTaskViewSimulator, windowRotation);
        }
        final SwipePipToHomeAnimator swipePipToHomeAnimator = builder.build();
        AnimatorPlaybackController activityAnimationToHome =
                homeAnimFactory.createActivityAnimationToHome();
        swipePipToHomeAnimator.addAnimatorListener(new AnimatorListenerAdapter() {
@@ -1283,6 +1294,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
                mGestureState.setState(STATE_END_TARGET_ANIMATION_FINISHED);
            }
        });
        setupWindowAnimation(swipePipToHomeAnimator);
        return swipePipToHomeAnimator;
    }

@@ -1313,6 +1325,11 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
            HomeAnimationFactory homeAnimationFactory) {
        RectFSpringAnim anim =
                super.createWindowAnimationToHome(startProgress, homeAnimationFactory);
        setupWindowAnimation(anim);
        return anim;
    }

    private void setupWindowAnimation(RectFSpringAnim anim) {
        anim.addOnUpdateListener((v, r, p) -> {
            updateSysUiFlags(Math.max(p, mCurrentShift.value));
        });
@@ -1330,7 +1347,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
        if (mRecentsAnimationTargets != null) {
            mRecentsAnimationTargets.addReleaseCheck(anim);
        }
        return anim;
    }

    public void onConsumerAboutToBeSwitched() {
+120 −33
Original line number Diff line number Diff line
@@ -56,7 +56,9 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
    private final ComponentName mComponentName;
    private final SurfaceControl mLeash;
    private final Rect mAppBounds = new Rect();
    private final Matrix mHomeToWindowPositionMap = new Matrix();
    private final Rect mStartBounds = new Rect();
    private final RectF mCurrentBoundsF = new RectF();
    private final Rect mCurrentBounds = new Rect();
    private final Rect mDestinationBounds = new Rect();
    private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
@@ -66,10 +68,9 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
    private final Rect mSourceHintRectInsets;
    private final Rect mSourceInsets = new Rect();

    /** for rotation via {@link #setFromRotation(TaskViewSimulator, int)} */
    private @RecentsOrientedState.SurfaceRotation int mFromRotation = Surface.ROTATION_0;
    /** for rotation calculations */
    private final @RecentsOrientedState.SurfaceRotation int mFromRotation;
    private final Rect mDestinationBoundsTransformed = new Rect();
    private final Rect mDestinationBoundsAnimation = new Rect();

    /**
     * Flag to avoid the double-end problem since the leash would have been released
@@ -91,31 +92,39 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
     * @param leash {@link SurfaceControl} this animator operates on
     * @param sourceRectHint See the definition in {@link android.app.PictureInPictureParams}
     * @param appBounds Bounds of the application, sourceRectHint is based on this bounds
     * @param homeToWindowPositionMap {@link Matrix} to map a Rect from home to window space
     * @param startBounds Bounds of the application when this animator starts. This can be
     *                    different from the appBounds if user has swiped a certain distance and
     *                    Launcher has performed transform on the leash.
     * @param destinationBounds Bounds of the destination this animator ends to
     * @param fromRotation From rotation if different from final rotation, ROTATION_0 otherwise
     * @param destinationBoundsTransformed Destination bounds in window space
     * @param cornerRadius Corner radius in pixel value for PiP window
     * @param view Attached view for logging purpose
     */
    public SwipePipToHomeAnimator(@NonNull Context context,
    private SwipePipToHomeAnimator(@NonNull Context context,
            int taskId,
            @NonNull ComponentName componentName,
            @NonNull SurfaceControl leash,
            @Nullable Rect sourceRectHint,
            @NonNull Rect appBounds,
            @NonNull Matrix homeToWindowPositionMap,
            @NonNull RectF startBounds,
            @NonNull Rect destinationBounds,
            @RecentsOrientedState.SurfaceRotation int fromRotation,
            @NonNull Rect destinationBoundsTransformed,
            int cornerRadius,
            @NonNull View view) {
        super(startBounds, new RectF(destinationBounds), context);
        super(startBounds, new RectF(destinationBoundsTransformed), context);
        mTaskId = taskId;
        mComponentName = componentName;
        mLeash = leash;
        mAppBounds.set(appBounds);
        mHomeToWindowPositionMap.set(homeToWindowPositionMap);
        startBounds.round(mStartBounds);
        mDestinationBounds.set(destinationBounds);
        mDestinationBoundsTransformed.set(mDestinationBounds);
        mDestinationBoundsAnimation.set(mDestinationBounds);
        mFromRotation = fromRotation;
        mDestinationBoundsTransformed.set(destinationBoundsTransformed);
        mSurfaceTransactionHelper = new PipSurfaceTransactionHelper(cornerRadius);

        if (sourceRectHint != null && (sourceRectHint.width() < destinationBounds.width()
@@ -191,37 +200,13 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
        addOnUpdateListener(this::onAnimationUpdate);
    }

    /** sets the from rotation if it's different from the target rotation. */
    public void setFromRotation(TaskViewSimulator taskViewSimulator,
            @RecentsOrientedState.SurfaceRotation int fromRotation) {
        if (fromRotation != Surface.ROTATION_90 && fromRotation != Surface.ROTATION_270) {
            Log.wtf(TAG, "Not a supported rotation, rotation=" + fromRotation);
            return;
        }
        mFromRotation = fromRotation;
        final Matrix matrix = new Matrix();
        taskViewSimulator.applyWindowToHomeRotation(matrix);

        // map the destination bounds into window space. mDestinationBounds is always calculated
        // in the final home space and the animation runs in original window space.
        final RectF transformed = new RectF(mDestinationBounds);
        matrix.mapRect(transformed, new RectF(mDestinationBounds));
        transformed.round(mDestinationBoundsTransformed);

        // set the animation destination bounds for RectEvaluator calculation.
        // bounds and insets are calculated as if the transition is from mAppBounds to
        // mDestinationBoundsAnimation, separated from rotate / scale / position.
        mDestinationBoundsAnimation.set(mAppBounds.left, mAppBounds.top,
                mAppBounds.left + mDestinationBounds.width(),
                mAppBounds.top + mDestinationBounds.height());
    }

    private void onAnimationUpdate(@Nullable AppCloseConfig values, RectF currentRect,
            float progress) {
        if (mHasAnimationEnded) return;
        final SurfaceControl.Transaction tx =
                PipSurfaceTransactionHelper.newSurfaceControlTransaction();
        onAnimationUpdate(tx, currentRect, progress);
        mHomeToWindowPositionMap.mapRect(mCurrentBoundsF, currentRect);
        onAnimationUpdate(tx, mCurrentBoundsF, progress);
        tx.apply();
    }

@@ -309,6 +294,108 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
        return new RotatedPosition(degree, positionX, positionY);
    }

    /** Builder class for {@link SwipePipToHomeAnimator} */
    public static class Builder {
        private Context mContext;
        private int mTaskId;
        private ComponentName mComponentName;
        private SurfaceControl mLeash;
        private Rect mSourceRectHint;
        private Rect mAppBounds;
        private Matrix mHomeToWindowPositionMap;
        private RectF mStartBounds;
        private Rect mDestinationBounds;
        private int mCornerRadius;
        private View mAttachedView;
        private @RecentsOrientedState.SurfaceRotation int mFromRotation = Surface.ROTATION_0;
        private final Rect mDestinationBoundsTransformed = new Rect();

        public Builder setContext(Context context) {
            mContext = context;
            return this;
        }

        public Builder setTaskId(int taskId) {
            mTaskId = taskId;
            return this;
        }

        public Builder setComponentName(ComponentName componentName) {
            mComponentName = componentName;
            return this;
        }

        public Builder setLeash(SurfaceControl leash) {
            mLeash = leash;
            return this;
        }

        public Builder setSourceRectHint(Rect sourceRectHint) {
            mSourceRectHint = new Rect(sourceRectHint);
            return this;
        }

        public Builder setAppBounds(Rect appBounds) {
            mAppBounds = new Rect(appBounds);
            return this;
        }

        public Builder setHomeToWindowPositionMap(Matrix homeToWindowPositionMap) {
            mHomeToWindowPositionMap = new Matrix(homeToWindowPositionMap);
            return this;
        }

        public Builder setStartBounds(RectF startBounds) {
            mStartBounds = new RectF(startBounds);
            return this;
        }

        public Builder setDestinationBounds(Rect destinationBounds) {
            mDestinationBounds = new Rect(destinationBounds);
            return this;
        }

        public Builder setCornerRadius(int cornerRadius) {
            mCornerRadius = cornerRadius;
            return this;
        }

        public Builder setAttachedView(View attachedView) {
            mAttachedView = attachedView;
            return this;
        }

        public Builder setFromRotation(TaskViewSimulator taskViewSimulator,
                @RecentsOrientedState.SurfaceRotation int fromRotation) {
            if (fromRotation != Surface.ROTATION_90 && fromRotation != Surface.ROTATION_270) {
                Log.wtf(TAG, "Not a supported rotation, rotation=" + fromRotation);
                return this;
            }
            final Matrix matrix = new Matrix();
            taskViewSimulator.applyWindowToHomeRotation(matrix);

            // map the destination bounds into window space. mDestinationBounds is always calculated
            // in the final home space and the animation runs in original window space.
            final RectF transformed = new RectF(mDestinationBounds);
            matrix.mapRect(transformed, new RectF(mDestinationBounds));
            transformed.round(mDestinationBoundsTransformed);

            mFromRotation = fromRotation;
            return this;
        }

        public SwipePipToHomeAnimator build() {
            if (mDestinationBoundsTransformed.isEmpty()) {
                mDestinationBoundsTransformed.set(mDestinationBounds);
            }
            return new SwipePipToHomeAnimator(mContext, mTaskId, mComponentName, mLeash,
                    mSourceRectHint, mAppBounds,
                    mHomeToWindowPositionMap, mStartBounds, mDestinationBounds,
                    mFromRotation, mDestinationBoundsTransformed,
                    mCornerRadius, mAttachedView);
        }
    }

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