Disable certain transaction when swiping pip to home
When swiping pip to home is happening, following transactions become conflicts - onFixedRotationStarted / onFixedRotationFinished - onMovementBoundsChanged skip these transactions entirely if that's the case - Added also scaleAndRotate support in PipSurfaceTransactionHelper - Need to address the final glitch Video: http://rcll/aaaaaabFQoRHlzixHdtY/cOco1yoMXwFzSifFqQET9U Video: http://rcll/aaaaaabFQoRHlzixHdtY/f3IWG09DRO9aUNnzqSdPLU Bug: 171802909 Test: see video Change-Id: Ied0e9d485e3d9ecff4d7a9e4ea3687103b7b47c3
This commit is contained in:
@@ -64,9 +64,9 @@ import com.android.internal.os.SomeArgs;
|
||||
import com.android.wm.shell.R;
|
||||
import com.android.wm.shell.ShellTaskOrganizer;
|
||||
import com.android.wm.shell.common.DisplayController;
|
||||
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
|
||||
import com.android.wm.shell.pip.phone.PipMotionHelper;
|
||||
import com.android.wm.shell.pip.phone.PipUpdateThread;
|
||||
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
@@ -251,7 +251,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
* If set to {@code true}, the entering animation will be skipped and we will wait for
|
||||
* {@link #onFixedRotationFinished(int)} callback to actually enter PiP.
|
||||
*/
|
||||
private boolean mShouldDeferEnteringPip;
|
||||
private boolean mWaitForFixedRotation;
|
||||
|
||||
/**
|
||||
* If set to {@code true}, no entering PiP transition would be kicked off and most likely
|
||||
@@ -259,7 +259,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
* auto PiP-able Activity to home.
|
||||
* See also {@link #startSwipePipToHome(ComponentName, ActivityInfo, PictureInPictureParams)}.
|
||||
*/
|
||||
private boolean mShouldIgnoreEnteringPipTransition;
|
||||
private boolean mInSwipePipToHomeTransition;
|
||||
|
||||
public PipTaskOrganizer(Context context, @NonNull PipBoundsState pipBoundsState,
|
||||
@NonNull PipBoundsAlgorithm boundsHandler,
|
||||
@@ -304,7 +304,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
}
|
||||
|
||||
public boolean isDeferringEnterPipAnimation() {
|
||||
return mState.isInPip() && mShouldDeferEnteringPip;
|
||||
return mState.isInPip() && mWaitForFixedRotation;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -336,9 +336,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
*/
|
||||
public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo,
|
||||
PictureInPictureParams pictureInPictureParams) {
|
||||
mShouldIgnoreEnteringPipTransition = true;
|
||||
mInSwipePipToHomeTransition = true;
|
||||
sendOnPipTransitionStarted(componentName, TRANSITION_DIRECTION_TO_PIP);
|
||||
setBoundsStateForEntry(componentName, pictureInPictureParams, activityInfo);
|
||||
// disable the conflicting transaction from fixed rotation, see also
|
||||
// onFixedRotationStarted and onFixedRotationFinished
|
||||
mWaitForFixedRotation = false;
|
||||
return mPipBoundsAlgorithm.getEntryDestinationBounds();
|
||||
}
|
||||
|
||||
@@ -348,7 +351,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
*/
|
||||
public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) {
|
||||
// do nothing if there is no startSwipePipToHome being called before
|
||||
if (mShouldIgnoreEnteringPipTransition) {
|
||||
if (mInSwipePipToHomeTransition) {
|
||||
mPipBoundsState.setBounds(destinationBounds);
|
||||
}
|
||||
}
|
||||
@@ -502,7 +505,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
|
||||
mPipMenuController.attach(leash);
|
||||
|
||||
if (mShouldIgnoreEnteringPipTransition) {
|
||||
if (mInSwipePipToHomeTransition) {
|
||||
final Rect destinationBounds = mPipBoundsState.getBounds();
|
||||
// animation is finished in the Launcher and here we directly apply the final touch.
|
||||
applyEnterPipSyncTransaction(destinationBounds, () -> {
|
||||
@@ -510,11 +513,11 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
finishResizeForMenu(destinationBounds);
|
||||
sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
|
||||
});
|
||||
mShouldIgnoreEnteringPipTransition = false;
|
||||
mInSwipePipToHomeTransition = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mShouldDeferEnteringPip) {
|
||||
if (mWaitForFixedRotation) {
|
||||
if (DEBUG) Log.d(TAG, "Defer entering PiP animation, fixed rotation is ongoing");
|
||||
// if deferred, hide the surface till fixed rotation is completed
|
||||
final SurfaceControl.Transaction tx =
|
||||
@@ -666,8 +669,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
Log.wtf(TAG, "Unrecognized token: " + token);
|
||||
return;
|
||||
}
|
||||
mShouldDeferEnteringPip = false;
|
||||
mShouldIgnoreEnteringPipTransition = false;
|
||||
mWaitForFixedRotation = false;
|
||||
mInSwipePipToHomeTransition = false;
|
||||
mPictureInPictureParams = null;
|
||||
mState = State.UNDEFINED;
|
||||
mPipUiEventLoggerLogger.setTaskInfo(null);
|
||||
@@ -694,17 +697,17 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
|
||||
@Override
|
||||
public void onFixedRotationStarted(int displayId, int newRotation) {
|
||||
mShouldDeferEnteringPip = true;
|
||||
mWaitForFixedRotation = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFixedRotationFinished(int displayId) {
|
||||
if (mShouldDeferEnteringPip && mState.isInPip()) {
|
||||
if (mWaitForFixedRotation && mState.isInPip()) {
|
||||
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
|
||||
// schedule a regular animation to ensure all the callbacks are still being sent
|
||||
enterPipWithAlphaAnimation(destinationBounds, 0 /* durationMs */);
|
||||
}
|
||||
mShouldDeferEnteringPip = false;
|
||||
mWaitForFixedRotation = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -723,6 +726,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
public void onMovementBoundsChanged(Rect destinationBoundsOut, boolean fromRotation,
|
||||
boolean fromImeAdjustment, boolean fromShelfAdjustment,
|
||||
WindowContainerTransaction wct) {
|
||||
// note that this can be called when swiping pip to home is happening. For instance,
|
||||
// swiping an app in landscape to portrait home. skip this entirely if that's the case.
|
||||
if (mInSwipePipToHomeTransition && fromRotation) {
|
||||
if (DEBUG) Log.d(TAG, "skip onMovementBoundsChanged due to swipe-pip-to-home");
|
||||
return;
|
||||
}
|
||||
final PipAnimationController.PipTransitionAnimator animator =
|
||||
mPipAnimationController.getCurrentAnimator();
|
||||
if (animator == null || !animator.isRunning()
|
||||
@@ -806,7 +815,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
*/
|
||||
public void scheduleAnimateResizePip(Rect toBounds, int duration,
|
||||
Consumer<Rect> updateBoundsCallback) {
|
||||
if (mShouldDeferEnteringPip) {
|
||||
if (mWaitForFixedRotation) {
|
||||
Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred");
|
||||
return;
|
||||
}
|
||||
@@ -820,7 +829,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
*/
|
||||
public void scheduleAnimateResizePip(Rect fromBounds, Rect toBounds, int duration,
|
||||
Consumer<Rect> updateBoundsCallback) {
|
||||
if (mShouldDeferEnteringPip) {
|
||||
if (mWaitForFixedRotation) {
|
||||
Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred");
|
||||
return;
|
||||
}
|
||||
@@ -922,7 +931,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
if (mState.shouldBlockResizeRequest()) {
|
||||
return;
|
||||
}
|
||||
if (mShouldDeferEnteringPip) {
|
||||
if (mWaitForFixedRotation) {
|
||||
Log.d(TAG, "skip scheduleOffsetPip, entering pip deferred");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.android.systemui.shared.pip;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.view.Choreographer;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
/**
|
||||
@@ -50,8 +52,32 @@ public class PipSurfaceTransactionHelper {
|
||||
.setPosition(leash, left, top);
|
||||
}
|
||||
|
||||
public void reset(SurfaceControl.Transaction tx, SurfaceControl leash, Rect destinationBounds) {
|
||||
public void scaleAndRotate(SurfaceControl.Transaction tx, SurfaceControl leash,
|
||||
Rect sourceBounds, Rect destinationBounds, Rect insets,
|
||||
float degree, float positionX, float positionY) {
|
||||
mTmpSourceRectF.set(sourceBounds);
|
||||
mTmpDestinationRect.set(sourceBounds);
|
||||
mTmpDestinationRect.inset(insets);
|
||||
// Scale by the shortest edge and offset such that the top/left of the scaled inset
|
||||
// source rect aligns with the top/left of the destination bounds
|
||||
final float scale = sourceBounds.width() <= sourceBounds.height()
|
||||
? (float) destinationBounds.width() / sourceBounds.width()
|
||||
: (float) destinationBounds.height() / sourceBounds.height();
|
||||
mTmpTransform.setRotate(degree, 0, 0);
|
||||
mTmpTransform.postScale(scale, scale);
|
||||
tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
|
||||
.setWindowCrop(leash, mTmpDestinationRect)
|
||||
.setPosition(leash, positionX, positionY);
|
||||
}
|
||||
|
||||
public void reset(SurfaceControl.Transaction tx, SurfaceControl leash, Rect destinationBounds,
|
||||
@Surface.Rotation int rotation) {
|
||||
resetScale(tx, leash, destinationBounds);
|
||||
if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
|
||||
final int degree = (rotation == Surface.ROTATION_90) ? -90 : 90;
|
||||
mTmpTransform.setRotate(degree, 0, 0);
|
||||
tx.setMatrix(leash, mTmpTransform, mTmpFloat9);
|
||||
}
|
||||
resetCornerRadius(tx, leash);
|
||||
crop(tx, leash, destinationBounds);
|
||||
}
|
||||
@@ -71,4 +97,11 @@ public class PipSurfaceTransactionHelper {
|
||||
tx.setWindowCrop(leash, destinationBounds.width(), destinationBounds.height())
|
||||
.setPosition(leash, destinationBounds.left, destinationBounds.top);
|
||||
}
|
||||
|
||||
/** @return {@link SurfaceControl.Transaction} instance with vsync-id */
|
||||
public static SurfaceControl.Transaction newSurfaceControlTransaction() {
|
||||
final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
|
||||
tx.setFrameTimelineVsync(Choreographer.getSfInstance().getVsyncId());
|
||||
return tx;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user