From 8aa6016bb3c00b66afa8483bb2bdf78494c45d4b Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 6 Apr 2021 14:50:50 -0700 Subject: [PATCH] Add fallback animation for auto-enter without source rect hint - Launcher will create a new surface which is faded in over the app, and as it finishes the recents animation, we transfer the overlay from the leash to the task (as with the transform), and when the pip task organizer receives it, it can fade out and remove the surface - Fixes flash of status bar colors when going from light status bar to home (dark status bar) by deferring whether a task affects the sysui flag until it enters pip (only for autoenter) https://recall.googleplex.com/projects/e3f080d7-2818-43f0-a087-405000b8fdf5/sessions/971a84c8-a622-4b34-a9de-4e595595da42 Bug: 184703546 Test: Swipe up from app with auto-enter but no source hint rect Change-Id: I0a00cdb98d0a599ef065206e0cd2cfc0e6cc72b1 --- .../view/IRecentsAnimationController.aidl | 4 +- .../WindowManager/Shell/res/values/config.xml | 3 + .../wm/shell/FullscreenTaskListener.java | 46 ++++++++----- .../src/com/android/wm/shell/pip/IPip.aidl | 5 +- .../wm/shell/pip/PipTaskOrganizer.java | 69 +++++++++++++------ .../wm/shell/pip/phone/PipController.java | 11 +-- .../RecentsAnimationControllerCompat.java | 7 +- .../shared/system/RemoteTransitionCompat.java | 4 +- .../server/wm/RecentsAnimationController.java | 27 +++++++- .../server/wm/RootWindowContainer.java | 3 +- .../core/java/com/android/server/wm/Task.java | 17 ++++- 11 files changed, 143 insertions(+), 53 deletions(-) diff --git a/core/java/android/view/IRecentsAnimationController.aidl b/core/java/android/view/IRecentsAnimationController.aidl index 7125232005c4e..6a2b723f905b7 100644 --- a/core/java/android/view/IRecentsAnimationController.aidl +++ b/core/java/android/view/IRecentsAnimationController.aidl @@ -18,6 +18,7 @@ package android.view; import android.app.ActivityManager; import android.view.IRemoteAnimationFinishedCallback; +import android.view.SurfaceControl; import android.graphics.GraphicBuffer; import android.window.PictureInPictureSurfaceTransaction; import android.window.TaskSnapshot; @@ -43,9 +44,10 @@ interface IRecentsAnimationController { * updated accordingly. This should be called before `finish` * @param taskId for which the leash should be updated * @param finishTransaction leash operations for the final transform. + * @param overlay the surface control for an overlay being shown above the pip (can be null) */ void setFinishTaskTransaction(int taskId, - in PictureInPictureSurfaceTransaction finishTransaction); + in PictureInPictureSurfaceTransaction finishTransaction, in SurfaceControl overlay); /** * Notifies to the system that the animation into Recents should end, and all leashes associated diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml index 26f98d8aeddb0..4c2863e4f5947 100644 --- a/libs/WindowManager/Shell/res/values/config.xml +++ b/libs/WindowManager/Shell/res/values/config.xml @@ -24,6 +24,9 @@ 425 + + 150 + true diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java index 6984ea458ccfd..006730d333eb3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java @@ -42,7 +42,7 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { private final SyncTransactionQueue mSyncQueue; - private final SparseArray mLeashByTaskId = new SparseArray<>(); + private final SparseArray mDataByTaskId = new SparseArray<>(); public FullscreenTaskListener(SyncTransactionQueue syncQueue) { mSyncQueue = syncQueue; @@ -50,14 +50,14 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { @Override public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) { - if (mLeashByTaskId.get(taskInfo.taskId) != null) { + if (mDataByTaskId.get(taskInfo.taskId) != null) { throw new IllegalStateException("Task appeared more than once: #" + taskInfo.taskId); } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Appeared: #%d", taskInfo.taskId); - mLeashByTaskId.put(taskInfo.taskId, leash); - if (Transitions.ENABLE_SHELL_TRANSITIONS) return; final Point positionInParent = taskInfo.positionInParent; + mDataByTaskId.put(taskInfo.taskId, new TaskData(leash, positionInParent)); + if (Transitions.ENABLE_SHELL_TRANSITIONS) return; mSyncQueue.runInSync(t -> { // Reset several properties back to fullscreen (PiP, for example, leaves all these // properties in a bad state). @@ -72,45 +72,57 @@ public class FullscreenTaskListener implements ShellTaskOrganizer.TaskListener { @Override public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { if (Transitions.ENABLE_SHELL_TRANSITIONS) return; - final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId); + final TaskData data = mDataByTaskId.get(taskInfo.taskId); final Point positionInParent = taskInfo.positionInParent; - mSyncQueue.runInSync(t -> { - // Reset several properties back. For instance, when an Activity enters PiP with - // multiple activities in the same task, a new task will be created from that Activity - // and we want reset the leash of the original task. - t.setPosition(leash, positionInParent.x, positionInParent.y); - t.setWindowCrop(leash, null); - }); + if (!positionInParent.equals(data.positionInParent)) { + data.positionInParent.set(positionInParent.x, positionInParent.y); + mSyncQueue.runInSync(t -> { + t.setPosition(data.surface, positionInParent.x, positionInParent.y); + }); + } } @Override public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { - if (mLeashByTaskId.get(taskInfo.taskId) == null) { + if (mDataByTaskId.get(taskInfo.taskId) == null) { Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId); return; } - mLeashByTaskId.remove(taskInfo.taskId); + mDataByTaskId.remove(taskInfo.taskId); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d", taskInfo.taskId); } @Override public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) { - if (!mLeashByTaskId.contains(taskId)) { + if (!mDataByTaskId.contains(taskId)) { throw new IllegalArgumentException("There is no surface for taskId=" + taskId); } - b.setParent(mLeashByTaskId.get(taskId)); + b.setParent(mDataByTaskId.get(taskId).surface); } @Override public void dump(@NonNull PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; pw.println(prefix + this); - pw.println(innerPrefix + mLeashByTaskId.size() + " Tasks"); + pw.println(innerPrefix + mDataByTaskId.size() + " Tasks"); } @Override public String toString() { return TAG + ":" + taskListenerTypeToString(TASK_LISTENER_TYPE_FULLSCREEN); } + + /** + * Per-task data for each managed task. + */ + private static class TaskData { + public final SurfaceControl surface; + public final Point positionInParent; + + public TaskData(SurfaceControl surface, Point positionInParent) { + this.surface = surface; + this.positionInParent = positionInParent; + } + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl index a6ffa6e445846..ddc85f758916a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl @@ -17,6 +17,7 @@ package com.android.wm.shell.pip; import android.app.PictureInPictureParams; +import android.view.SurfaceControl; import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.graphics.Rect; @@ -48,8 +49,10 @@ interface IPip { * * @param componentName ComponentName represents the Activity * @param destinationBounds the destination bounds the PiP window lands into + * @param overlay an optional overlay to fade out after entering PiP */ - oneway void stopSwipePipToHome(in ComponentName componentName, in Rect destinationBounds) = 2; + oneway void stopSwipePipToHome(in ComponentName componentName, in Rect destinationBounds, + in SurfaceControl overlay) = 2; /** * Sets listener to get pinned stack animation callbacks. 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 4ce6c9e35e9ee..e7d2d14d792eb 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 @@ -147,6 +147,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private final PipUiEventLogger mPipUiEventLoggerLogger; private final int mEnterAnimationDuration; private final int mExitAnimationDuration; + private final int mCrossFadeAnimationDuration; private final PipSurfaceTransactionHelper mSurfaceTransactionHelper; private final Optional mSplitScreenOptional; protected final ShellTaskOrganizer mTaskOrganizer; @@ -244,6 +245,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, */ private boolean mInSwipePipToHomeTransition; + /** + * An optional overlay used to mask content changing between an app in/out of PiP, only set if + * {@link #mInSwipePipToHomeTransition} is true. + */ + private SurfaceControl mSwipePipToHomeOverlay; + public PipTaskOrganizer(Context context, @NonNull SyncTransactionQueue syncTransactionQueue, @NonNull PipBoundsState pipBoundsState, @@ -267,6 +274,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, .getInteger(R.integer.config_pipEnterAnimationDuration); mExitAnimationDuration = context.getResources() .getInteger(R.integer.config_pipExitAnimationDuration); + mCrossFadeAnimationDuration = context.getResources() + .getInteger(R.integer.config_pipCrossfadeAnimationDuration); mSurfaceTransactionHelper = surfaceTransactionHelper; mPipAnimationController = pipAnimationController; mPipUiEventLoggerLogger = pipUiEventLogger; @@ -337,10 +346,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, * Callback when launcher finishes swipe-pip-to-home operation. * Expect {@link #onTaskAppeared(ActivityManager.RunningTaskInfo, SurfaceControl)} afterwards. */ - public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) { + public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds, + SurfaceControl overlay) { // do nothing if there is no startSwipePipToHome being called before if (mInSwipePipToHomeTransition) { mPipBoundsState.setBounds(destinationBounds); + mSwipePipToHomeOverlay = overlay; } } @@ -583,6 +594,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private void onEndOfSwipePipToHomeTransition() { final Rect destinationBounds = mPipBoundsState.getBounds(); + final SurfaceControl swipeToHomeOverlay = mSwipePipToHomeOverlay; final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); mSurfaceTransactionHelper.resetScale(tx, mLeash, destinationBounds); mSurfaceTransactionHelper.crop(tx, mLeash, destinationBounds); @@ -591,8 +603,14 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, // Ensure menu's settled in its final bounds first. finishResizeForMenu(destinationBounds); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); + + // Remove the swipe to home overlay + if (swipeToHomeOverlay != null) { + fadeOutAndRemoveOverlay(swipeToHomeOverlay); + } }, tx); mInSwipePipToHomeTransition = false; + mSwipePipToHomeOverlay = null; } private void applyEnterPipSyncTransaction(Rect destinationBounds, Runnable runnable, @@ -1122,25 +1140,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mSurfaceTransactionHelper.scale(t, snapshotSurface, snapshotSrc, snapshotDest); // Start animation to fade out the snapshot. - final ValueAnimator animator = ValueAnimator.ofFloat(1.0f, 0.0f); - animator.setDuration(mEnterAnimationDuration); - animator.addUpdateListener(animation -> { - final float alpha = (float) animation.getAnimatedValue(); - final SurfaceControl.Transaction transaction = - mSurfaceControlTransactionFactory.getTransaction(); - transaction.setAlpha(snapshotSurface, alpha); - transaction.apply(); - }); - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - final SurfaceControl.Transaction tx = - mSurfaceControlTransactionFactory.getTransaction(); - tx.remove(snapshotSurface); - tx.apply(); - } - }); - animator.start(); + fadeOutAndRemoveOverlay(snapshotSurface); }); } else { applyFinishBoundsResize(wct, direction); @@ -1282,6 +1282,35 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, return true; } + /** + * Fades out and removes an overlay surface. + */ + private void fadeOutAndRemoveOverlay(SurfaceControl surface) { + if (surface == null) { + return; + } + + final ValueAnimator animator = ValueAnimator.ofFloat(1.0f, 0.0f); + animator.setDuration(mCrossFadeAnimationDuration); + animator.addUpdateListener(animation -> { + final float alpha = (float) animation.getAnimatedValue(); + final SurfaceControl.Transaction transaction = + mSurfaceControlTransactionFactory.getTransaction(); + transaction.setAlpha(surface, alpha); + transaction.apply(); + }); + animator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + final SurfaceControl.Transaction tx = + mSurfaceControlTransactionFactory.getTransaction(); + tx.remove(surface); + tx.apply(); + } + }); + animator.start(); + } + /** * Dumps internal states. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 29a483bd7ae30..d07992a4de00c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -44,6 +44,7 @@ import android.util.Pair; import android.util.Size; import android.util.Slog; import android.view.DisplayInfo; +import android.view.SurfaceControl; import android.view.WindowManagerGlobal; import android.window.WindowContainerTransaction; @@ -559,8 +560,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb return entryBounds; } - private void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) { - mPipTaskOrganizer.stopSwipePipToHome(componentName, destinationBounds); + private void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds, + SurfaceControl overlay) { + mPipTaskOrganizer.stopSwipePipToHome(componentName, destinationBounds, overlay); } @Override @@ -852,10 +854,11 @@ public class PipController implements PipTransitionController.PipTransitionCallb } @Override - public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) { + public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds, + SurfaceControl overlay) { executeRemoteCallWithTaskPermission(mController, "stopSwipePipToHome", (controller) -> { - controller.stopSwipePipToHome(componentName, destinationBounds); + controller.stopSwipePipToHome(componentName, destinationBounds, overlay); }); } 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 1cc488fc6df07..700ec49fc795c 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 @@ -19,6 +19,7 @@ package com.android.systemui.shared.system; import android.os.RemoteException; import android.util.Log; import android.view.IRecentsAnimationController; +import android.view.SurfaceControl; import android.window.PictureInPictureSurfaceTransaction; import android.window.TaskSnapshot; @@ -76,11 +77,13 @@ public class RecentsAnimationControllerCompat { * updated accordingly. This should be called before `finish` * @param taskId Task id of the Activity in PiP mode. * @param finishTransaction leash operations for the final transform. + * @param overlay the surface control for an overlay being shown above the pip (can be null) */ public void setFinishTaskTransaction(int taskId, - PictureInPictureSurfaceTransaction finishTransaction) { + PictureInPictureSurfaceTransaction finishTransaction, + SurfaceControl overlay) { try { - mAnimationController.setFinishTaskTransaction(taskId, finishTransaction); + mAnimationController.setFinishTaskTransaction(taskId, finishTransaction, overlay); } 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 5708855b0a4f9..1729997ac8730 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 @@ -236,9 +236,9 @@ public class RemoteTransitionCompat implements Parcelable { } @Override public void setFinishTaskTransaction(int taskId, - PictureInPictureSurfaceTransaction finishTransaction) { + PictureInPictureSurfaceTransaction finishTransaction, SurfaceControl overlay) { if (mWrapped != null) { - mWrapped.setFinishTaskTransaction(taskId, finishTransaction); + mWrapped.setFinishTaskTransaction(taskId, finishTransaction, overlay); } } diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index dec6460147cfb..627de2c750d0a 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -231,7 +231,8 @@ public class RecentsAnimationController implements DeathRecipient { @Override public void setFinishTaskTransaction(int taskId, - PictureInPictureSurfaceTransaction finishTransaction) { + PictureInPictureSurfaceTransaction finishTransaction, + SurfaceControl overlay) { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "setFinishTaskTransaction(%d): transaction=%s", taskId, finishTransaction); final long token = Binder.clearCallingIdentity(); @@ -241,6 +242,7 @@ public class RecentsAnimationController implements DeathRecipient { final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i); if (taskAdapter.mTask.mTaskId == taskId) { taskAdapter.mFinishTransaction = finishTransaction; + taskAdapter.mFinishOverlay = overlay; break; } } @@ -518,7 +520,6 @@ public class RecentsAnimationController implements DeathRecipient { void removeAnimation(TaskAnimationAdapter taskAdapter) { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "removeAnimation(%d)", taskAdapter.mTask.mTaskId); - taskAdapter.mTask.setCanAffectSystemUiFlags(true); taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter.mLastAnimationType, taskAdapter); mPendingAnimations.remove(taskAdapter); @@ -1106,6 +1107,8 @@ public class RecentsAnimationController implements DeathRecipient { private final Rect mLocalBounds = new Rect(); // The final surface transaction when animation is finished. private PictureInPictureSurfaceTransaction mFinishTransaction; + // An overlay used to mask the content as an app goes into PIP + private SurfaceControl mFinishOverlay; TaskAnimationAdapter(Task task, boolean isRecentTaskInvisible) { mTask = task; @@ -1143,20 +1146,38 @@ public class RecentsAnimationController implements DeathRecipient { void onCleanup() { if (mFinishTransaction != null) { final Transaction pendingTransaction = mTask.getPendingTransaction(); + + // Reparent the overlay + if (mFinishOverlay != null) { + pendingTransaction.reparent(mFinishOverlay, mTask.mSurfaceControl); + } + + // Transfer the transform from the leash to the task PictureInPictureSurfaceTransaction.apply(mFinishTransaction, mTask.mSurfaceControl, pendingTransaction); - mTask.setLastRecentsAnimationTransaction(mFinishTransaction); + mTask.setLastRecentsAnimationTransaction(mFinishTransaction, mFinishOverlay); if (mDisplayContent.isFixedRotationLaunchingApp(mTargetActivityRecord)) { // The transaction is needed for position when rotating the display. mDisplayContent.mPinnedTaskController.setEnterPipTransaction( mFinishTransaction); } mFinishTransaction = null; + mFinishOverlay = null; pendingTransaction.apply(); + + // In the case where we are transferring the transform to the task in preparation + // for entering PIP, we disable the task being able to affect sysui flags otherwise + // it may cause a flash + if (mTask.getActivityType() != mTargetActivityType) { + mTask.setCanAffectSystemUiFlags(false); + } } else if (!mTask.isAttached()) { // Apply the task's pending transaction in case it is detached and its transaction // is not reachable. mTask.getPendingTransaction().apply(); + + // Reset whether this task can affect the sysui flags + mTask.setCanAffectSystemUiFlags(true); } } diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index ab7e65cc64e8b..f4002b408429f 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2139,7 +2139,8 @@ class RootWindowContainer extends WindowContainer // Move the last recents animation transaction from original task to the new one. if (task.mLastRecentsAnimationTransaction != null) { rootTask.setLastRecentsAnimationTransaction( - task.mLastRecentsAnimationTransaction); + task.mLastRecentsAnimationTransaction, + task.mLastRecentsAnimationOverlay); task.clearLastRecentsAnimationTransaction(); } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index be01173415a57..ca40f4d20fe64 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -482,6 +482,9 @@ class Task extends WindowContainer { // Do not forget to reset this after reparenting. // TODO: remove this once the recents animation is moved to the Shell PictureInPictureSurfaceTransaction mLastRecentsAnimationTransaction; + // The content overlay to be applied with mLastRecentsAnimationTransaction + // TODO: remove this once the recents animation is moved to the Shell + SurfaceControl mLastRecentsAnimationOverlay; static final int LAYER_RANK_INVISIBLE = -1; // Ranking (from top) of this task among all visible tasks. (-1 means it's not visible) @@ -5396,6 +5399,10 @@ class Task extends WindowContainer { : WINDOWING_MODE_FULLSCREEN; } if (currentMode == WINDOWING_MODE_PINNED) { + // In the case that we've disabled affecting the SysUI flags as a part of seamlessly + // transferring the transform on the leash to the task, reset this state once we've + // actually entered pip + setCanAffectSystemUiFlags(true); mRootWindowContainer.notifyActivityPipModeChanged(null); } if (likelyResolvedMode == WINDOWING_MODE_PINNED @@ -7712,22 +7719,28 @@ class Task extends WindowContainer { reparent(newParent, onTop ? POSITION_TOP : POSITION_BOTTOM); } - void setLastRecentsAnimationTransaction( - @NonNull PictureInPictureSurfaceTransaction transaction) { + void setLastRecentsAnimationTransaction(@NonNull PictureInPictureSurfaceTransaction transaction, + @Nullable SurfaceControl overlay) { mLastRecentsAnimationTransaction = new PictureInPictureSurfaceTransaction(transaction); + mLastRecentsAnimationOverlay = overlay; } void clearLastRecentsAnimationTransaction() { mLastRecentsAnimationTransaction = null; + mLastRecentsAnimationOverlay = null; // reset also the transform introduced by mLastRecentsAnimationTransaction getPendingTransaction().setMatrix(mSurfaceControl, Matrix.IDENTITY_MATRIX, new float[9]); } void maybeApplyLastRecentsAnimationTransaction() { if (mLastRecentsAnimationTransaction != null) { + if (mLastRecentsAnimationOverlay != null) { + getPendingTransaction().reparent(mLastRecentsAnimationOverlay, mSurfaceControl); + } PictureInPictureSurfaceTransaction.apply(mLastRecentsAnimationTransaction, mSurfaceControl, getPendingTransaction()); mLastRecentsAnimationTransaction = null; + mLastRecentsAnimationOverlay = null; } }