From ec111e24e5851fd57096d3c3055a904662d19082 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Mon, 11 Nov 2024 10:51:43 -0800 Subject: [PATCH] Check if all apps are translucent when finishing recents animation. If true, then launcher will be finished at the end of the animation. This fixes the issue where taskbar will stash in overview because we assumed the app was fully opaque. Bug: 354627538 Test: open app, go to overview, tap icon, pause app, note no issue Flag: EXEMPT bugfix Change-Id: Id51e0d9f63c9615127e27455f7edf171381c2011 --- .../TaskbarLauncherStateController.java | 28 +++++++++++++++---- .../quickstep/RecentsAnimationController.java | 27 +++++++++++++++++- .../android/quickstep/views/RecentsView.java | 13 +++++++-- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index 29988927bb..dce377d5d7 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -1009,7 +1009,12 @@ public class TaskbarLauncherStateController { @Override public void onRecentsAnimationFinished(RecentsAnimationController controller) { - endGestureStateOverride(!controller.getFinishTargetIsLauncher(), false /*canceled*/); + endGestureStateOverride(!controller.getFinishTargetIsLauncher(), + controller.getLauncherIsVisibleAtFinish(), false /*canceled*/); + } + + private void endGestureStateOverride(boolean finishedToApp, boolean canceled) { + endGestureStateOverride(finishedToApp, finishedToApp, canceled); } /** @@ -1019,11 +1024,13 @@ public class TaskbarLauncherStateController { * * @param finishedToApp {@code true} if the recents animation finished to showing an app and * not workspace or overview + * @param launcherIsVisible {code true} if launcher is visible at finish * @param canceled {@code true} if the recents animation was canceled instead of * finishing * to completion */ - private void endGestureStateOverride(boolean finishedToApp, boolean canceled) { + private void endGestureStateOverride(boolean finishedToApp, boolean launcherIsVisible, + boolean canceled) { mCallbacks.removeListener(this); mTaskBarRecentsAnimationListener = null; ((RecentsView) mLauncher.getOverviewPanel()).setTaskLaunchListener(null); @@ -1032,18 +1039,27 @@ public class TaskbarLauncherStateController { mSkipNextRecentsAnimEnd = false; return; } - updateStateForUserFinishedToApp(finishedToApp); + updateStateForUserFinishedToApp(finishedToApp, launcherIsVisible); } } + /** + * @see #updateStateForUserFinishedToApp(boolean, boolean) + */ + private void updateStateForUserFinishedToApp(boolean finishedToApp) { + updateStateForUserFinishedToApp(finishedToApp, !finishedToApp); + } + /** * Updates the visible state immediately to ensure a seamless handoff. * * @param finishedToApp True iff user is in an app. + * @param launcherIsVisible True iff launcher is still visible (ie. transparent app) */ - private void updateStateForUserFinishedToApp(boolean finishedToApp) { + private void updateStateForUserFinishedToApp(boolean finishedToApp, + boolean launcherIsVisible) { // Update the visible state immediately to ensure a seamless handoff - boolean launcherVisible = !finishedToApp; + boolean launcherVisible = !finishedToApp || launcherIsVisible; updateStateForFlag(FLAG_TRANSITION_TO_VISIBLE, false); updateStateForFlag(FLAG_VISIBLE, launcherVisible); applyState(); @@ -1052,7 +1068,7 @@ public class TaskbarLauncherStateController { if (DEBUG) { Log.d(TAG, "endGestureStateOverride - FLAG_IN_APP: " + finishedToApp); } - controller.updateStateForFlag(FLAG_IN_APP, finishedToApp); + controller.updateStateForFlag(FLAG_IN_APP, finishedToApp && !launcherIsVisible); controller.applyState(); } diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java index dcb01087ee..60fcff86f3 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java @@ -53,6 +53,8 @@ public class RecentsAnimationController { private boolean mFinishRequested = false; // Only valid when mFinishRequested == true. private boolean mFinishTargetIsLauncher; + // Only valid when mFinishRequested == true + private boolean mLauncherIsVisibleAtFinish; private RunnableList mPendingFinishCallbacks = new RunnableList(); public RecentsAnimationController(RecentsAnimationControllerCompat controller, @@ -116,14 +118,28 @@ public class RecentsAnimationController { finishController(toRecents, onFinishComplete, sendUserLeaveHint); } + @UiThread + public void finish(boolean toRecents, boolean launcherIsVisibleAtFinish, + Runnable onFinishComplete, boolean sendUserLeaveHint) { + Preconditions.assertUIThread(); + finishController(toRecents, launcherIsVisibleAtFinish, onFinishComplete, sendUserLeaveHint, + false); + } + @UiThread public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) { - finishController(toRecents, callback, sendUserLeaveHint, false /* forceFinish */); + finishController(toRecents, false, callback, sendUserLeaveHint, false /* forceFinish */); } @UiThread public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint, boolean forceFinish) { + finishController(toRecents, toRecents, callback, sendUserLeaveHint, forceFinish); + } + + @UiThread + public void finishController(boolean toRecents, boolean launcherIsVisibleAtFinish, + Runnable callback, boolean sendUserLeaveHint, boolean forceFinish) { mPendingFinishCallbacks.add(callback); if (!forceFinish && mFinishRequested) { // If finish has already been requested, then add the callback to the pending list. @@ -135,6 +151,7 @@ public class RecentsAnimationController { // Finish not yet requested mFinishRequested = true; mFinishTargetIsLauncher = toRecents; + mLauncherIsVisibleAtFinish = launcherIsVisibleAtFinish; mOnFinishedListener.accept(this); Runnable finishCb = () -> { mController.finish(toRecents, sendUserLeaveHint, new IResultReceiver.Stub() { @@ -211,6 +228,14 @@ public class RecentsAnimationController { return mFinishTargetIsLauncher; } + /** + * RecentsAnimationListeners can check this in onRecentsAnimationFinished() to determine whether + * the animation was finished to launcher vs an app. + */ + public boolean getLauncherIsVisibleAtFinish() { + return mLauncherIsVisibleAtFinish; + } + public void dump(String prefix, PrintWriter pw) { pw.println(prefix + "RecentsAnimationController:"); diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 8982850532..92c93ff9ee 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -5854,15 +5854,22 @@ public abstract class RecentsView< * Finish recents animation. */ public void finishRecentsAnimation(boolean toRecents, @Nullable Runnable onFinishComplete) { - finishRecentsAnimation(toRecents, true /* shouldPip */, onFinishComplete); + finishRecentsAnimation(toRecents, false, true /* shouldPip */, onFinishComplete); } + /** + * Finish recents animation. + */ + public void finishRecentsAnimation(boolean toRecents, boolean shouldPip, + @Nullable Runnable onFinishComplete) { + finishRecentsAnimation(toRecents, shouldPip, false, onFinishComplete); + } /** * NOTE: Whatever value gets passed through to the toRecents param may need to also be set on * {@link #mRecentsAnimationController#setWillFinishToHome}. */ public void finishRecentsAnimation(boolean toRecents, boolean shouldPip, - @Nullable Runnable onFinishComplete) { + boolean allAppTargetsAreTranslucent, @Nullable Runnable onFinishComplete) { Log.d(TAG, "finishRecentsAnimation - mRecentsAnimationController: " + mRecentsAnimationController); // TODO(b/197232424#comment#10) Move this back into onRecentsAnimationComplete(). Maybe? @@ -5894,7 +5901,7 @@ public abstract class RecentsView< tx, null /* overlay */); } } - mRecentsAnimationController.finish(toRecents, () -> { + mRecentsAnimationController.finish(toRecents, allAppTargetsAreTranslucent, () -> { if (onFinishComplete != null) { onFinishComplete.run(); }