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
This commit is contained in:
Jon Miranda
2024-11-15 23:47:48 +00:00
parent a9095ca0c8
commit ec111e24e5
3 changed files with 58 additions and 10 deletions
@@ -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();
}
@@ -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:");
@@ -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();
}