From 2e6148a4307aaf19d80f11f9b1f622201529d955 Mon Sep 17 00:00:00 2001 From: Schneider Victor-Tulias Date: Fri, 16 May 2025 15:39:09 -0400 Subject: [PATCH] Prevent adding duplicate TaskAnimationManager launcher destroyed callbacks Flag: EXEMPT code cleanup Bug: 416536400 Test: TaskAnimationManagerTest; ran test with and without change Change-Id: I8bdee3adeeca07e386f3058910d5e2160359f7e9 --- .../com/android/quickstep/TaskAnimationManager.java | 11 ++++++++++- .../android/quickstep/TaskAnimationManagerTest.java | 8 ++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index 9396529fb1..9b7ff0089a 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -16,6 +16,7 @@ package com.android.quickstep; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; +import static android.view.Display.DEFAULT_DISPLAY; import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; @@ -26,7 +27,6 @@ import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_INITIAL import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_STARTED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED; -import static android.view.Display.DEFAULT_DISPLAY; import android.app.ActivityManager; import android.app.ActivityOptions; @@ -86,6 +86,8 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn private boolean mShouldIgnoreMotionEvents = false; private final int mDisplayId; + private boolean mLauncherDestroyCallbackSet = false; + public static final DaggerSingletonObject> REPOSITORY_INSTANCE = new DaggerSingletonObject<>( QuickstepBaseAppComponent::getTaskAnimationManagerRepository); @@ -180,6 +182,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn RecentsAnimationCallbacks newCallbacks = new RecentsAnimationCallbacks( containerInterface.getCreatedContainer()); mCallbacks = newCallbacks; + mLauncherDestroyCallbackSet = false; mCallbacks.addListener(new RecentsAnimationCallbacks.RecentsAnimationListener() { @Override public void onRecentsAnimationStart(RecentsAnimationController controller, @@ -509,7 +512,11 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn if (mCallbacks == null) { return; } + if (mLauncherDestroyCallbackSet) { + return; + } ActiveGestureProtoLogProxy.logQueuingForceFinishRecentsAnimation(); + mLauncherDestroyCallbackSet = true; mCallbacks.addListener(new RecentsAnimationCallbacks.RecentsAnimationListener() { @Override public void onRecentsAnimationStart( @@ -521,6 +528,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn /* forceFinish= */ true, /* forceFinishCb= */ null, controller); + mLauncherDestroyCallbackSet = false; } }); } @@ -552,6 +560,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn mController = null; mCallbacks = null; + mLauncherDestroyCallbackSet = false; mTargets = null; mTransitionInfo = null; mLastGestureState = null; diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/TaskAnimationManagerTest.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/TaskAnimationManagerTest.java index dc7d5c751f..5cecde479b 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/TaskAnimationManagerTest.java +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/TaskAnimationManagerTest.java @@ -17,8 +17,6 @@ package com.android.quickstep; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; @@ -148,6 +146,10 @@ public class TaskAnimationManagerTest { gestureState, new Intent(), mock(RecentsAnimationCallbacks.RecentsAnimationListener.class)); + + // Simulate multiple launcher destroyed events before the recents animation start + mTaskAnimationManager.onLauncherDestroyed(); + mTaskAnimationManager.onLauncherDestroyed(); mTaskAnimationManager.onLauncherDestroyed(); listenerCaptor.getValue().onAnimationStart( controllerCompat, @@ -158,6 +160,8 @@ public class TaskAnimationManagerTest { new Bundle(), new TransitionInfo(0, 0)); }); + + // Verify checks that finish was only called once runOnMainSync(() -> verify(controllerCompat) .finish(/* toHome= */ eq(false), anyBoolean(), any())); }