diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java index 48f1b76c1d503..5cca4a6a65f05 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java @@ -40,4 +40,14 @@ public interface RecentsAnimationListener { * was running becomes ready for control. */ void onTasksAppeared(RemoteAnimationTargetCompat[] app); + + /** + * Called to request that the current task tile be switched out for a screenshot (if not + * already). Once complete, onFinished should be called. + * @return true if this impl will call onFinished. No other onSwitchToScreenshot impls will + * be called afterwards (to avoid multiple calls to onFinished). + */ + default boolean onSwitchToScreenshot(Runnable onFinished) { + return false; + } } 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 51001a7a4c8eb..4894c498ec581 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 @@ -18,6 +18,7 @@ package com.android.systemui.shared.system; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_OPEN; @@ -244,6 +245,8 @@ public class RemoteTransitionCompat implements Parcelable { RecentsAnimationListener recents) { ArrayList openingTasks = null; boolean cancelRecents = false; + boolean homeGoingAway = false; + boolean hasChangingApp = false; for (int i = info.getChanges().size() - 1; i >= 0; --i) { final TransitionInfo.Change change = info.getChanges().get(i); if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) { @@ -257,8 +260,28 @@ public class RemoteTransitionCompat implements Parcelable { } openingTasks.add(change); } + } else if (change.getMode() == TRANSIT_CLOSE + || change.getMode() == TRANSIT_TO_BACK) { + if (mRecentsTask.equals(change.getContainer())) { + homeGoingAway = true; + } + } else if (change.getMode() == TRANSIT_CHANGE) { + hasChangingApp = true; } } + if (hasChangingApp && homeGoingAway) { + // This happens when a visible app is expanding (usually PiP). In this case, + // The transition probably has a special-purpose animation, so finish recents + // now and let it do its animation (since recents is going to be occluded). + if (!recents.onSwitchToScreenshot(() -> { + finish(true /* toHome */, false /* userLeaveHint */); + })) { + Log.w(TAG, "Recents callback doesn't support support switching to screenshot" + + ", there might be a flicker."); + finish(true /* toHome */, false /* userLeaveHint */); + } + return false; + } if (openingTasks == null) return false; int pauseMatches = 0; if (!cancelRecents) {