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

Commit 667d4cf9 authored by Shan Huang's avatar Shan Huang Committed by Android (Google) Code Review
Browse files

Merge "Drop KEYCODE_BACK if a callback is already receiving dispatch." into main

parents e0c5ca85 8ddc2236
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -6943,7 +6943,11 @@ public final class ViewRootImpl implements ViewParent,
        }
        private int doOnBackKeyEvent(KeyEvent keyEvent) {
            OnBackInvokedCallback topCallback = getOnBackInvokedDispatcher().getTopCallback();
            WindowOnBackInvokedDispatcher dispatcher = getOnBackInvokedDispatcher();
            OnBackInvokedCallback topCallback = dispatcher.getTopCallback();
            if (dispatcher.isDispatching()) {
                return FINISH_NOT_HANDLED;
            }
            if (topCallback instanceof OnBackAnimationCallback) {
                final OnBackAnimationCallback animationCallback =
                        (OnBackAnimationCallback) topCallback;
+40 −3
Original line number Diff line number Diff line
@@ -174,6 +174,21 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
        }
    }

    /**
     * Indicates if the dispatcher is actively dispatching to a callback.
     */
    public boolean isDispatching() {
        return mIsDispatching;
    }

    private void onStartDispatching() {
        mIsDispatching = true;
    }

    private void onStopDispatching() {
        mIsDispatching = false;
    }

    private void sendCancelledIfInProgress(@NonNull OnBackInvokedCallback callback) {
        boolean isInProgress = mProgressAnimator.isBackAnimationInProgress();
        if (isInProgress && callback instanceof OnBackAnimationCallback) {
@@ -231,7 +246,7 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
                                    .ImeOnBackInvokedCallback
                                ? ((ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback)
                                        callback).getIOnBackInvokedCallback()
                                : new OnBackInvokedCallbackWrapper(callback);
                                : new OnBackInvokedCallbackWrapper(callback, this);
                callbackInfo = new OnBackInvokedCallbackInfo(
                        iCallback,
                        priority,
@@ -258,6 +273,7 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {

    @NonNull
    private static final BackProgressAnimator mProgressAnimator = new BackProgressAnimator();
    private boolean mIsDispatching = false;

    /**
     * The {@link Context} in ViewRootImp and Activity could be different, this will make sure it
@@ -317,18 +333,33 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
            }
        }
        final CallbackRef mCallbackRef;
        /**
         * The dispatcher this callback is registered with.
         * This can be null for callbacks on {@link ImeOnBackInvokedDispatcher} because they are
         * forwarded and registered on the app's {@link WindowOnBackInvokedDispatcher}. */
        @Nullable
        private final WindowOnBackInvokedDispatcher mDispatcher;

        OnBackInvokedCallbackWrapper(@NonNull OnBackInvokedCallback callback) {
        OnBackInvokedCallbackWrapper(
                @NonNull OnBackInvokedCallback callback,
                WindowOnBackInvokedDispatcher dispatcher) {
            mCallbackRef = new CallbackRef(callback, true /* useWeakRef */);
            mDispatcher = dispatcher;
        }

        OnBackInvokedCallbackWrapper(@NonNull OnBackInvokedCallback callback, boolean useWeakRef) {
        OnBackInvokedCallbackWrapper(
                @NonNull OnBackInvokedCallback callback,
                boolean useWeakRef) {
            mCallbackRef = new CallbackRef(callback, useWeakRef);
            mDispatcher = null;
        }

        @Override
        public void onBackStarted(BackMotionEvent backEvent) {
            Handler.getMain().post(() -> {
                if (mDispatcher != null) {
                    mDispatcher.onStartDispatching();
                }
                final OnBackAnimationCallback callback = getBackAnimationCallback();
                if (callback != null) {
                    mProgressAnimator.onBackStarted(backEvent, event ->
@@ -353,6 +384,9 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
        @Override
        public void onBackCancelled() {
            Handler.getMain().post(() -> {
                if (mDispatcher != null) {
                    mDispatcher.onStopDispatching();
                }
                mProgressAnimator.onBackCancelled(() -> {
                    final OnBackAnimationCallback callback = getBackAnimationCallback();
                    if (callback != null) {
@@ -365,6 +399,9 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
        @Override
        public void onBackInvoked() throws RemoteException {
            Handler.getMain().post(() -> {
                if (mDispatcher != null) {
                    mDispatcher.onStopDispatching();
                }
                boolean isInProgress = mProgressAnimator.isBackAnimationInProgress();
                mProgressAnimator.reset();
                final OnBackInvokedCallback callback = mCallbackRef.get();
+27 −9
Original line number Diff line number Diff line
@@ -403,8 +403,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
        mCurrentTracker.updateStartLocation();
        // Dispatch onBackStarted, only to app callbacks.
        // System callbacks will receive onBackStarted when the remote animation starts.
        if (!shouldDispatchToAnimator()) {
            tryDispatchOnBackStarted(mActiveCallback, mCurrentTracker.createStartEvent(null));
        if (!shouldDispatchToAnimator() && mActiveCallback != null) {
            tryDispatchAppOnBackStarted(mActiveCallback, mCurrentTracker.createStartEvent(null));
        }
    }

@@ -507,7 +507,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
            mActiveCallback = mBackNavigationInfo.getOnBackInvokedCallback();
            // App is handling back animation. Cancel system animation latency tracking.
            cancelLatencyTracking();
            tryDispatchOnBackStarted(mActiveCallback, touchTracker.createStartEvent(null));
            tryDispatchAppOnBackStarted(mActiveCallback, touchTracker.createStartEvent(null));
        }
    }

@@ -551,14 +551,24 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
                && mBackNavigationInfo.isPrepareRemoteAnimation();
    }

    private void tryDispatchOnBackStarted(IOnBackInvokedCallback callback,
    private void tryDispatchAppOnBackStarted(
            IOnBackInvokedCallback callback,
            BackMotionEvent backEvent) {
        if (callback == null || mOnBackStartDispatched) {
        if (mOnBackStartDispatched && callback != null) {
            return;
        }
        dispatchOnBackStarted(callback, backEvent);
        mOnBackStartDispatched = true;
    }

    private void dispatchOnBackStarted(
            IOnBackInvokedCallback callback,
            BackMotionEvent backEvent) {
        if (callback == null) {
            return;
        }
        try {
            callback.onBackStarted(backEvent);
            mOnBackStartDispatched = true;
        } catch (RemoteException e) {
            Log.e(TAG, "dispatchOnBackStarted error: ", e);
        }
@@ -940,9 +950,17 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont

                                    if (apps.length >= 1) {
                                        mCurrentTracker.updateStartLocation();
                                        tryDispatchOnBackStarted(
                                                mActiveCallback,
                                                mCurrentTracker.createStartEvent(apps[0]));
                                        BackMotionEvent startEvent =
                                                mCurrentTracker.createStartEvent(apps[0]);
                                        // {@code mActiveCallback} is the callback from
                                        // the BackAnimationRunners and not a real app-side
                                        // callback. We also dispatch to the app-side callback
                                        // (which should be a system callback with PRIORITY_SYSTEM)
                                        // to keep consistent with app registered callbacks.
                                        dispatchOnBackStarted(mActiveCallback, startEvent);
                                        tryDispatchAppOnBackStarted(
                                                mBackNavigationInfo.getOnBackInvokedCallback(),
                                                startEvent);
                                    }

                                    // Dispatch the first progress after animation start for