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
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user