diff options
| author | 2024-07-08 12:10:13 +0000 | |
|---|---|---|
| committer | 2024-07-08 12:11:13 +0000 | |
| commit | 2aae7b8444c4fe7c3d6679b41cd6d2117e49ecc1 (patch) | |
| tree | 85a21d4f455e5db2c99dff24d02d2c0a532375b3 | |
| parent | c4b9427f2f79d5da7631b02c700c93201252fd6d (diff) | |
Ensure no more callback invocations after onBackCancelled
When unregistering a back callback which is currently in-progress, onBackCancelled is dispatched. After dispatching onBackCancelled, it must be ensured that no more callback invocations to that same callback happen.
Bug: 351777537
Flag: com.android.window.flags.predictive_back_system_anims
Test: atest WindowOnBackInvokedDispatcherTest
Test: Manual, i.e. unregistering a callback during an active back gesture in a test app and verifying that after onBackCancelled no more onBackProgressed or other events are dispatched
Change-Id: I9a0b3a7c19e565070abc550cd02b520c693c443e
3 files changed, 10 insertions, 1 deletions
diff --git a/core/java/android/window/BackProgressAnimator.java b/core/java/android/window/BackProgressAnimator.java index d28500c0a1ea..12d4ab8bc963 100644 --- a/core/java/android/window/BackProgressAnimator.java +++ b/core/java/android/window/BackProgressAnimator.java @@ -16,12 +16,15 @@ package android.window; +import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; + import android.annotation.NonNull; import android.annotation.Nullable; import android.util.FloatProperty; import android.util.TimeUtils; import android.view.Choreographer; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.dynamicanimation.animation.DynamicAnimation; import com.android.internal.dynamicanimation.animation.FlingAnimation; import com.android.internal.dynamicanimation.animation.FloatValueHolder; @@ -210,7 +213,8 @@ public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateL } /** Returns true if the back animation is in progress. */ - boolean isBackAnimationInProgress() { + @VisibleForTesting(visibility = PACKAGE) + public boolean isBackAnimationInProgress() { return mBackAnimationInProgress; } diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java index 9b87e2351e3f..7bbc3dbb29db 100644 --- a/core/java/android/window/WindowOnBackInvokedDispatcher.java +++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java @@ -244,6 +244,7 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { // We should call onBackCancelled() when an active callback is removed from // dispatcher. sendCancelledIfInProgress(callback); + mHandler.post(mProgressAnimator::reset); setTopOnBackInvokedCallback(getTopCallback()); } } diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java index d4482f243939..9ae96a0fc9d8 100644 --- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java +++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java @@ -348,12 +348,16 @@ public class WindowOnBackInvokedDispatcherTest { waitForIdle(); verify(mCallback1).onBackStarted(any(BackEvent.class)); + assertTrue(mDispatcher.mProgressAnimator.isBackAnimationInProgress()); mDispatcher.unregisterOnBackInvokedCallback(mCallback1); waitForIdle(); verify(mCallback1).onBackCancelled(); verify(mWindowSession).setOnBackInvokedCallbackInfo(Mockito.eq(mWindow), isNull()); + // Verify that ProgressAnimator is reset (and thus does not cause further callback event + // dispatching) + assertFalse(mDispatcher.mProgressAnimator.isBackAnimationInProgress()); } @Test |