Settle auto PiP transaction in WindowContainerTransaction
At the end of autoEnterPip transition, followings happen in sequence - Transition finishes in Launcher side, which operates on the animation leash - RecentsAnimationController.TaskAnimationAdapter#onCleanup has the final chance to set the Task leash - PipTaskOrganizer gets onTaskAppeared callback and commits Task into pinned mode What's been changed here - Transition in Launcher no longer in charge of settle the final transaction - RecentsAnimationController.TaskAnimationAdapter#onCleanup sets the Task leash to be in sync with the final state in Launcher side - PipTaskOrganizer commits the final leash transaction together with WindowContainerTransaction that enters PiP Known issue: transition from landscape is not polished Video: http://rcll/aaaaaabFQoRHlzixHdtY/hT5SXvaCy28P4UtfuoKiDw Bug: 181342797 Test: see video Change-Id: Ieabd6991ea5174099714ec22970198bebde1e336
This commit is contained in:
@@ -43,8 +43,11 @@ interface IRecentsAnimationController {
|
||||
* accordingly. This should be called before `finish`
|
||||
* @param taskId for which the leash should be updated
|
||||
* @param destinationBounds bounds of the final PiP window
|
||||
* @param windowCrop bounds to crop as part of final transform.
|
||||
* @param float9 An array of 9 floats to be used as matrix transform.
|
||||
*/
|
||||
void setFinishTaskBounds(int taskId, in Rect destinationBounds);
|
||||
void setFinishTaskBounds(int taskId, in Rect destinationBounds, in Rect windowCrop,
|
||||
in float[] float9);
|
||||
|
||||
/**
|
||||
* Notifies to the system that the animation into Recents should end, and all leashes associated
|
||||
|
||||
@@ -41,6 +41,7 @@ import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.app.PictureInPictureParams;
|
||||
@@ -423,12 +424,16 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
|
||||
if (mInSwipePipToHomeTransition) {
|
||||
final Rect destinationBounds = mPipBoundsState.getBounds();
|
||||
final SurfaceControl.Transaction tx =
|
||||
mSurfaceControlTransactionFactory.getTransaction();
|
||||
mSurfaceTransactionHelper.resetScale(tx, mLeash, destinationBounds);
|
||||
mSurfaceTransactionHelper.crop(tx, mLeash, destinationBounds);
|
||||
// animation is finished in the Launcher and here we directly apply the final touch.
|
||||
applyEnterPipSyncTransaction(destinationBounds, () -> {
|
||||
// ensure menu's settled in its final bounds first
|
||||
finishResizeForMenu(destinationBounds);
|
||||
sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
|
||||
});
|
||||
}, tx);
|
||||
mInSwipePipToHomeTransition = false;
|
||||
return;
|
||||
}
|
||||
@@ -490,16 +495,20 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
|
||||
// mState is set right after the animation is kicked off to block any resize
|
||||
// requests such as offsetPip that may have been called prior to the transition.
|
||||
mState = State.ENTERING_PIP;
|
||||
});
|
||||
}, null /* boundsChangeTransaction */);
|
||||
}
|
||||
|
||||
private void applyEnterPipSyncTransaction(Rect destinationBounds, Runnable runnable) {
|
||||
private void applyEnterPipSyncTransaction(Rect destinationBounds, Runnable runnable,
|
||||
@Nullable SurfaceControl.Transaction boundsChangeTransaction) {
|
||||
// PiP menu is attached late in the process here to avoid any artifacts on the leash
|
||||
// caused by addShellRoot when in gesture navigation mode.
|
||||
mPipMenuController.attach(mLeash);
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
|
||||
wct.setBounds(mToken, destinationBounds);
|
||||
if (boundsChangeTransaction != null) {
|
||||
wct.setBoundsChangeTransaction(mToken, boundsChangeTransaction);
|
||||
}
|
||||
wct.scheduleFinishEnterPip(mToken, destinationBounds);
|
||||
mSyncTransactionQueue.queue(wct);
|
||||
if (runnable != null) {
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.graphics.Matrix;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.view.Choreographer;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
/**
|
||||
@@ -91,24 +90,6 @@ public class PipSurfaceTransactionHelper {
|
||||
.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);
|
||||
}
|
||||
|
||||
public void resetScale(SurfaceControl.Transaction tx, SurfaceControl leash,
|
||||
Rect destinationBounds) {
|
||||
tx.setMatrix(leash, Matrix.IDENTITY_MATRIX, mTmpFloat9)
|
||||
.setPosition(leash, destinationBounds.left, destinationBounds.top);
|
||||
}
|
||||
|
||||
public void resetCornerRadius(SurfaceControl.Transaction tx, SurfaceControl leash) {
|
||||
tx.setCornerRadius(leash, 0);
|
||||
}
|
||||
|
||||
@@ -76,10 +76,14 @@ public class RecentsAnimationControllerCompat {
|
||||
* accordingly. This should be called before `finish`
|
||||
* @param taskId Task id of the Activity in PiP mode.
|
||||
* @param destinationBounds Bounds of the PiP window on home.
|
||||
* @param windowCrop bounds to crop as part of final transform.
|
||||
* @param float9 An array of 9 floats to be used as matrix transform.
|
||||
*/
|
||||
public void setFinishTaskBounds(int taskId, Rect destinationBounds) {
|
||||
public void setFinishTaskBounds(int taskId, Rect destinationBounds, Rect windowCrop,
|
||||
float[] float9) {
|
||||
try {
|
||||
mAnimationController.setFinishTaskBounds(taskId, destinationBounds);
|
||||
mAnimationController.setFinishTaskBounds(taskId, destinationBounds, windowCrop,
|
||||
float9);
|
||||
} catch (RemoteException e) {
|
||||
Log.d(TAG, "Failed to set finish task bounds", e);
|
||||
}
|
||||
|
||||
@@ -137,8 +137,11 @@ public class RemoteTransitionCompat implements Parcelable {
|
||||
mWrapped.hideCurrentInputMethod();
|
||||
}
|
||||
|
||||
@Override public void setFinishTaskBounds(int taskId, Rect destinationBounds) {
|
||||
if (mWrapped != null) mWrapped.setFinishTaskBounds(taskId, destinationBounds);
|
||||
@Override public void setFinishTaskBounds(int taskId, Rect destinationBounds,
|
||||
Rect windowCrop, float[] float9) {
|
||||
if (mWrapped != null) {
|
||||
mWrapped.setFinishTaskBounds(taskId, destinationBounds, windowCrop, float9);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void finish(boolean toHome, boolean sendUserLeaveHint) {
|
||||
|
||||
@@ -20,6 +20,10 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
import static android.graphics.Matrix.MSCALE_X;
|
||||
import static android.graphics.Matrix.MSCALE_Y;
|
||||
import static android.graphics.Matrix.MSKEW_X;
|
||||
import static android.graphics.Matrix.MSKEW_Y;
|
||||
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
|
||||
import static android.view.RemoteAnimationTarget.MODE_OPENING;
|
||||
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
|
||||
@@ -229,7 +233,8 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinishTaskBounds(int taskId, Rect destinationBounds) {
|
||||
public void setFinishTaskBounds(int taskId, Rect destinationBounds, Rect windowCrop,
|
||||
float[] float9) {
|
||||
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
|
||||
"setFinishTaskBounds(%d): bounds=%s", taskId, destinationBounds);
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
@@ -239,6 +244,8 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i);
|
||||
if (taskAdapter.mTask.mTaskId == taskId) {
|
||||
taskAdapter.mFinishBounds.set(destinationBounds);
|
||||
taskAdapter.mFinishWindowCrop.set(windowCrop);
|
||||
taskAdapter.mFinishTransform = float9;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1084,6 +1091,9 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
private final Rect mLocalBounds = new Rect();
|
||||
// The bounds of the target when animation is finished
|
||||
private final Rect mFinishBounds = new Rect();
|
||||
// Bounds and transform for the final transaction.
|
||||
private final Rect mFinishWindowCrop = new Rect();
|
||||
private float[] mFinishTransform;
|
||||
|
||||
TaskAnimationAdapter(Task task, boolean isRecentTaskInvisible) {
|
||||
mTask = task;
|
||||
@@ -1120,13 +1130,31 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
|
||||
void onCleanup() {
|
||||
if (!mFinishBounds.isEmpty()) {
|
||||
// Apply any pending bounds changes
|
||||
final SurfaceControl taskSurface = mTask.getSurfaceControl();
|
||||
mTask.getPendingTransaction()
|
||||
.setPosition(taskSurface, mFinishBounds.left, mFinishBounds.top)
|
||||
.setWindowCrop(taskSurface, mFinishBounds.width(), mFinishBounds.height())
|
||||
final SurfaceControl taskSurface = mTask.mSurfaceControl;
|
||||
final Transaction pendingTransaction = mTask.getPendingTransaction();
|
||||
if (mFinishTransform != null) {
|
||||
pendingTransaction
|
||||
.setMatrix(taskSurface,
|
||||
mFinishTransform[MSCALE_X], mFinishTransform[MSKEW_Y],
|
||||
mFinishTransform[MSKEW_X], mFinishTransform[MSCALE_Y]);
|
||||
}
|
||||
float left = mFinishBounds.left;
|
||||
float top = mFinishBounds.top;
|
||||
if (!mFinishWindowCrop.isEmpty()) {
|
||||
pendingTransaction.setWindowCrop(taskSurface, mFinishWindowCrop);
|
||||
if (mFinishTransform != null) {
|
||||
// adjust the position for insets.
|
||||
left -= mFinishWindowCrop.left * mFinishTransform[MSCALE_X];
|
||||
top -= mFinishWindowCrop.top * mFinishTransform[MSCALE_Y];
|
||||
}
|
||||
}
|
||||
pendingTransaction
|
||||
.setPosition(taskSurface, left, top)
|
||||
.apply();
|
||||
mTask.mLastRecentsAnimationBounds.set(mFinishBounds);
|
||||
// reset the variables
|
||||
mFinishTransform = null;
|
||||
mFinishWindowCrop.setEmpty();
|
||||
mFinishBounds.setEmpty();
|
||||
} else if (!mTask.isAttached()) {
|
||||
// Apply the task's pending transaction in case it is detached and its transaction
|
||||
|
||||
Reference in New Issue
Block a user