Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2aae7b84 authored by Johannes Gallmann's avatar Johannes Gallmann
Browse files

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
parent c4b9427f
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -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;
    }

+1 −0
Original line number Diff line number Diff line
@@ -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());
            }
        }
+4 −0
Original line number Diff line number Diff line
@@ -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