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

Commit c241580d authored by Hongwei Wang's avatar Hongwei Wang
Browse files

Fixes autoEnterPip transition from landscape

Fixes included in this change
- PiP bounces back to fullscreen. The animation direction is not cleaned
  up after animation finishes and when display rotation callback
  happens and calls into PipTaskOrganizer#onMovementBoundsChanged, it
  accidentally invokes the onTaskVanished. Therefore, this does not
  happen on the first try but following attempts.
- PiP window offsets to the bottom caused by duplicated display changed
  callbacks, bail early if we know for sure the DisplayLayout objects
  are identical. Also, when display rotation callback happens, the
  PipBoundsState#getNormalBounds is still in landscape though the
  internal rotation has been set in PipController#startSwipePipToHome.

Known issue
- PiP window flickers at the end of the transition, will track in
  different bug.

Video: http://rcll/aaaaaabFQoRHlzixHdtY/hAdwMhKMaYTylRcnW24Utg
Bug: 179721427
Bug: 179718773
Test: repeatedly enter PiP from landscape with autoEnterPip, see video
Change-Id: I77c6f441563bc54720b9ef2952526691c495a777
parent c952ffe7
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import com.android.internal.R;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

/**
 * Contains information about the layout-properties of a display. This refers to internal layout
@@ -81,6 +82,31 @@ public class DisplayLayout {
    private boolean mHasStatusBar = false;
    private int mNavBarFrameHeight = 0;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof DisplayLayout)) return false;
        final DisplayLayout other = (DisplayLayout) o;
        return mUiMode == other.mUiMode
                && mWidth == other.mWidth
                && mHeight == other.mHeight
                && Objects.equals(mCutout, other.mCutout)
                && mRotation == other.mRotation
                && mDensityDpi == other.mDensityDpi
                && Objects.equals(mNonDecorInsets, other.mNonDecorInsets)
                && Objects.equals(mStableInsets, other.mStableInsets)
                && mHasNavigationBar == other.mHasNavigationBar
                && mHasStatusBar == other.mHasStatusBar
                && mNavBarFrameHeight == other.mNavBarFrameHeight;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mUiMode, mWidth, mHeight, mCutout, mRotation, mDensityDpi,
                mNonDecorInsets, mStableInsets, mHasNavigationBar, mHasStatusBar,
                mNavBarFrameHeight);
    }

    /**
     * Create empty layout.
     */
+5 −3
Original line number Diff line number Diff line
@@ -90,15 +90,15 @@ public class PipAnimationController {

    private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;

    private PipTransitionAnimator mCurrentAnimator;

    private ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal =
    private final ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal =
            ThreadLocal.withInitial(() -> {
                AnimationHandler handler = new AnimationHandler();
                handler.setProvider(new SfVsyncFrameCallbackProvider());
                return handler;
            });

    private PipTransitionAnimator mCurrentAnimator;

    public PipAnimationController(PipSurfaceTransactionHelper helper) {
        mSurfaceTransactionHelper = helper;
    }
@@ -268,6 +268,7 @@ public class PipAnimationController {
            if (mPipAnimationCallback != null) {
                mPipAnimationCallback.onPipAnimationEnd(mTaskInfo, tx, this);
            }
            mTransitionDirection = TRANSITION_DIRECTION_NONE;
        }

        @Override
@@ -275,6 +276,7 @@ public class PipAnimationController {
            if (mPipAnimationCallback != null) {
                mPipAnimationCallback.onPipAnimationCancel(mTaskInfo, this);
            }
            mTransitionDirection = TRANSITION_DIRECTION_NONE;
        }

        @Override public void onAnimationRepeat(Animator animation) {}
+14 −4
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip.PipUtils;

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

/**
@@ -101,9 +102,12 @@ public class PipController implements PipTransitionController.PipTransitionCallb
     */
    private final DisplayChangeController.OnDisplayChangingListener mRotationController = (
            int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) -> {
        if (!mPipTaskOrganizer.isInPip() || mPipTaskOrganizer.isDeferringEnterPipAnimation()) {
            // Skip if 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 (!mPipTaskOrganizer.isInPip()
                || mPipBoundsState.getDisplayLayout().rotation() == toRotation
                || mPipTaskOrganizer.isDeferringEnterPipAnimation()) {
            // 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.
            onDisplayRotationChangedNotInPip(mContext, toRotation);
            // do not forget to update the movement bounds as well.
            updateMovementBounds(mPipBoundsState.getNormalBounds(), true /* fromRotation */,
@@ -378,6 +382,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb
    }

    private void onDisplayChanged(DisplayLayout layout, boolean saveRestoreSnapFraction) {
        if (Objects.equals(layout, mPipBoundsState.getDisplayLayout())) {
            return;
        }
        Runnable updateDisplayLayout = () -> {
            mPipBoundsState.setDisplayLayout(layout);
            updateMovementBounds(null /* toBounds */,
@@ -476,8 +483,11 @@ public class PipController implements PipTransitionController.PipTransitionCallb
            int launcherRotation, int shelfHeight) {
        setShelfHeightLocked(shelfHeight > 0 /* visible */, shelfHeight);
        onDisplayRotationChangedNotInPip(mContext, launcherRotation);
        return mPipTaskOrganizer.startSwipePipToHome(componentName, activityInfo,
        final Rect entryBounds = mPipTaskOrganizer.startSwipePipToHome(componentName, activityInfo,
                pictureInPictureParams);
        // sync mPipBoundsState with the newly calculated bounds.
        mPipBoundsState.setNormalBounds(entryBounds);
        return entryBounds;
    }

    private void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) {