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

Commit dc4c8ea3 authored by Riddle Hsu's avatar Riddle Hsu Committed by Android (Google) Code Review
Browse files

Merge "Support PiP with fixed rotation" into sc-dev

parents c4cf0d49 25457d42
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -109,8 +109,8 @@ public final class WindowContainerTransaction implements Parcelable {
    }

    /**
     * Notify activities within the hierarchy of a container that they have entered picture-in-picture
     * mode with the given bounds.
     * Notify {@link com.android.server.wm.PinnedTaskController} that the picture-in-picture task
     * has finished the enter animation with the given bounds.
     */
    @NonNull
    public WindowContainerTransaction scheduleFinishEnterPip(
+48 −29
Original line number Diff line number Diff line
@@ -427,36 +427,44 @@ public class PipAnimationController {
                Rect baseValue, Rect startValue, Rect endValue, Rect sourceHintRect,
                @PipAnimationController.TransitionDirection int direction, float startingAngle,
                @Surface.Rotation int rotationDelta) {
            final boolean isOutPipDirection = isOutPipDirection(direction);

            // Just for simplicity we'll interpolate between the source rect hint insets and empty
            // insets to calculate the window crop
            final Rect initialSourceValue;
            if (isOutPipDirection(direction)) {
            if (isOutPipDirection) {
                initialSourceValue = new Rect(endValue);
            } else {
                initialSourceValue = new Rect(baseValue);
            }

            final Rect sourceHintRectInsets;
            if (sourceHintRect == null) {
                sourceHintRectInsets = null;
            } else {
                sourceHintRectInsets = new Rect(sourceHintRect.left - initialSourceValue.left,
                        sourceHintRect.top - initialSourceValue.top,
                        initialSourceValue.right - sourceHintRect.right,
                        initialSourceValue.bottom - sourceHintRect.bottom);
            }
            final Rect sourceInsets = new Rect(0, 0, 0, 0);

            final Rect rotatedEndRect;
            final Rect lastEndRect;
            final Rect initialContainerRect;
            if (rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270) {
                lastEndRect = new Rect(endValue);
                rotatedEndRect = new Rect(endValue);
                // Rotate the end bounds according to the rotation delta because the display will
                // be rotated to the same orientation.
                rotatedEndRect = new Rect(endValue);
                rotateBounds(rotatedEndRect, endValue, rotationDelta);
                rotateBounds(rotatedEndRect, initialSourceValue, rotationDelta);
                // Use the rect that has the same orientation as the hint rect.
                initialContainerRect = isOutPipDirection ? rotatedEndRect : initialSourceValue;
            } else {
                rotatedEndRect = null;
                rotatedEndRect = lastEndRect = null;
                initialContainerRect = initialSourceValue;
            }

            final Rect sourceHintRectInsets;
            if (sourceHintRect == null) {
                sourceHintRectInsets = null;
            } else {
                sourceHintRectInsets = new Rect(sourceHintRect.left - initialContainerRect.left,
                        sourceHintRect.top - initialContainerRect.top,
                        initialContainerRect.right - sourceHintRect.right,
                        initialContainerRect.bottom - sourceHintRect.bottom);
            }
            final Rect zeroInsets = new Rect(0, 0, 0, 0);

            // construct new Rect instances in case they are recycled
            return new PipTransitionAnimator<Rect>(taskInfo, leash, ANIM_TYPE_BOUNDS,
                    endValue, new Rect(baseValue), new Rect(startValue), new Rect(endValue),
@@ -472,8 +480,8 @@ public class PipAnimationController {
                    final Rect end = getEndValue();
                    if (rotatedEndRect != null) {
                        // Animate the bounds in a different orientation. It only happens when
                        // leaving PiP to fullscreen.
                        applyRotation(tx, leash, fraction, start, end, rotatedEndRect);
                        // switching between PiP and fullscreen.
                        applyRotation(tx, leash, fraction, start, end);
                        return;
                    }
                    Rect bounds = mRectEvaluator.evaluate(fraction, start, end);
@@ -481,20 +489,13 @@ public class PipAnimationController {
                    setCurrentValue(bounds);
                    if (inScaleTransition() || sourceHintRect == null) {

                        if (isOutPipDirection(direction)) {
                        if (isOutPipDirection) {
                            getSurfaceTransactionHelper().scale(tx, leash, end, bounds);
                        } else {
                            getSurfaceTransactionHelper().scale(tx, leash, base, bounds, angle);
                        }
                    } else {
                        final Rect insets;
                        if (isOutPipDirection(direction)) {
                            insets = mInsetsEvaluator.evaluate(fraction, sourceHintRectInsets,
                                    sourceInsets);
                        } else {
                            insets = mInsetsEvaluator.evaluate(fraction, sourceInsets,
                                    sourceHintRectInsets);
                        }
                        final Rect insets = computeInsets(fraction);
                        getSurfaceTransactionHelper().scaleAndCrop(tx, leash,
                                initialSourceValue, bounds, insets);
                    }
@@ -502,9 +503,17 @@ public class PipAnimationController {
                }

                private void applyRotation(SurfaceControl.Transaction tx, SurfaceControl leash,
                        float fraction, Rect start, Rect end, Rect rotatedEndRect) {
                        float fraction, Rect start, Rect end) {
                    if (!end.equals(lastEndRect)) {
                        // If the end bounds are changed during animating (e.g. shelf height), the
                        // rotated end bounds also need to be updated.
                        rotatedEndRect.set(endValue);
                        rotateBounds(rotatedEndRect, initialSourceValue, rotationDelta);
                        lastEndRect.set(end);
                    }
                    final Rect bounds = mRectEvaluator.evaluate(fraction, start, rotatedEndRect);
                    setCurrentValue(bounds);
                    final Rect insets = computeInsets(fraction);
                    final float degree, x, y;
                    if (rotationDelta == ROTATION_90) {
                        degree = 90 * fraction;
@@ -515,11 +524,21 @@ public class PipAnimationController {
                        x = fraction * (end.left - start.left) + start.left;
                        y = fraction * (end.bottom - start.top) + start.top;
                    }
                    getSurfaceTransactionHelper().rotateAndScaleWithCrop(tx, leash, bounds,
                            rotatedEndRect, degree, x, y);
                    getSurfaceTransactionHelper().rotateAndScaleWithCrop(tx, leash,
                            initialContainerRect, bounds, insets, degree, x, y, isOutPipDirection,
                            rotationDelta == ROTATION_270 /* clockwise */);
                    tx.apply();
                }

                private Rect computeInsets(float fraction) {
                    if (sourceHintRectInsets == null) {
                        return zeroInsets;
                    }
                    final Rect startRect = isOutPipDirection ? sourceHintRectInsets : zeroInsets;
                    final Rect endRect = isOutPipDirection ? zeroInsets : sourceHintRectInsets;
                    return mInsetsEvaluator.evaluate(fraction, startRect, endRect);
                }

                @Override
                void onStartTransaction(SurfaceControl leash, SurfaceControl.Transaction tx) {
                    getSurfaceTransactionHelper()
+30 −12
Original line number Diff line number Diff line
@@ -137,23 +137,41 @@ public class PipSurfaceTransactionHelper {
     * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
     */
    public PipSurfaceTransactionHelper rotateAndScaleWithCrop(SurfaceControl.Transaction tx,
            SurfaceControl leash, Rect sourceBounds, Rect destinationBounds, float degrees,
            float positionX, float positionY) {
            SurfaceControl leash, Rect sourceBounds, Rect destinationBounds, Rect insets,
            float degrees, float positionX, float positionY, boolean isExpanding,
            boolean clockwise) {
        mTmpDestinationRect.set(sourceBounds);
        final int dw = destinationBounds.width();
        final int dh = destinationBounds.height();
        mTmpDestinationRect.inset(insets);
        final int srcW = mTmpDestinationRect.width();
        final int srcH = mTmpDestinationRect.height();
        final int destW = destinationBounds.width();
        final int destH = destinationBounds.height();
        // Scale by the short side so there won't be empty area if the aspect ratio of source and
        // destination are different.
        final float scale = dw <= dh
                ? (float) sourceBounds.width() / dw
                : (float) sourceBounds.height() / dh;
        final float scale = srcW <= srcH ? (float) destW / srcW : (float) destH / srcH;
        final Rect crop = mTmpDestinationRect;
        crop.set(0, 0, destW, destH);
        // Inverse scale for crop to fit in screen coordinates.
        mTmpDestinationRect.scale(1 / scale);
        mTmpTransform.setRotate(degrees);
        mTmpTransform.postScale(scale, scale);
        crop.scale(1 / scale);
        crop.offset(insets.left, insets.top);
        if (isExpanding) {
            // Expand bounds (shrink insets) in source orientation.
            positionX -= insets.left * scale;
            positionY -= insets.top * scale;
        } else {
            // Shrink bounds (expand insets) in destination orientation.
            if (clockwise) {
                positionX -= insets.top * scale;
                positionY -= insets.left * scale;
            } else {
                positionX += insets.top * scale;
                positionY += insets.left * scale;
            }
        }
        mTmpTransform.setScale(scale, scale);
        mTmpTransform.postRotate(degrees);
        mTmpTransform.postTranslate(positionX, positionY);
        tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
                .setWindowCrop(leash, mTmpDestinationRect.width(), mTmpDestinationRect.height());
        tx.setMatrix(leash, mTmpTransform, mTmpFloat9).setWindowCrop(leash, crop);
        return this;
    }

+190 −43

File changed.

Preview size limit exceeded, changes collapsed.

+11 −7
Original line number Diff line number Diff line
@@ -114,13 +114,17 @@ public class PipController implements PipTransitionController.PipTransitionCallb
     */
    private final DisplayChangeController.OnDisplayChangingListener mRotationController = (
            int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) -> {
        if (!mPipTaskOrganizer.isInPip()
                || mPipBoundsState.getDisplayLayout().rotation() == toRotation
                || mPipTaskOrganizer.isDeferringEnterPipAnimation()
                || mPipTaskOrganizer.isEntryScheduled()) {
            // Skip if the same rotation has been set or we aren't in PIP or haven't actually
            // entered PIP yet. We still need to update the display layout in the bounds handler
            // in this case.
        if (mPipBoundsState.getDisplayLayout().rotation() == toRotation) {
            // The same rotation may have been set by auto PiP-able or fixed rotation. So notify
            // the change with fromRotation=false to apply the rotated destination bounds from
            // PipTaskOrganizer#onMovementBoundsChanged.
            updateMovementBounds(null, false /* fromRotation */,
                    false /* fromImeAdjustment */, false /* fromShelfAdjustment */, t);
            return;
        }
        if (!mPipTaskOrganizer.isInPip() || mPipTaskOrganizer.isEntryScheduled()) {
            // Update display layout and bounds handler if we aren't in PIP or haven't actually
            // entered PIP yet.
            onDisplayRotationChangedNotInPip(mContext, toRotation);
            // do not forget to update the movement bounds as well.
            updateMovementBounds(mPipBoundsState.getNormalBounds(), true /* fromRotation */,
Loading