diff options
6 files changed, 61 insertions, 33 deletions
diff --git a/core/java/android/view/IRecentsAnimationController.aidl b/core/java/android/view/IRecentsAnimationController.aidl index ddb49786dce6..10721ad30525 100644 --- a/core/java/android/view/IRecentsAnimationController.aidl +++ b/core/java/android/view/IRecentsAnimationController.aidl @@ -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 diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index 9ec7c0d173dd..36dc4e409f98 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -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) { diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java index 72e4061829fa..f50c3c925a1c 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java @@ -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); } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java index c2d52a7855f4..bf0d29a59bea 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java @@ -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); } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java index 7ba906986fa3..06155bc7100c 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java @@ -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) { diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 914e45641b45..64ff1084a6b8 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -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 |