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

Commit 8f44e78f authored by Johannes Gallmann's avatar Johannes Gallmann Committed by Android (Google) Code Review
Browse files

Merge "Add new PRIORITY_SYSTEM_NAVIGATION_OBSERVER to OnBackInvokedDispatcher" into main

parents 0506a46f ebaebbd4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -61658,6 +61658,7 @@ package android.window {
    method public void unregisterOnBackInvokedCallback(@NonNull android.window.OnBackInvokedCallback);
    field public static final int PRIORITY_DEFAULT = 0; // 0x0
    field public static final int PRIORITY_OVERLAY = 1000000; // 0xf4240
    field @FlaggedApi("com.android.window.flags.predictive_back_priority_system_navigation_observer") public static final int PRIORITY_SYSTEM_NAVIGATION_OBSERVER = -2; // 0xfffffffe
  }
  public interface SplashScreen {
+2 −0
Original line number Diff line number Diff line
@@ -7531,6 +7531,7 @@ public final class ViewRootImpl implements ViewParent,
                        if (keyEvent.isCanceled()) {
                            animationCallback.onBackCancelled();
                        } else {
                            dispatcher.tryInvokeSystemNavigationObserverCallback();
                            topCallback.onBackInvoked();
                        }
                        break;
@@ -7538,6 +7539,7 @@ public final class ViewRootImpl implements ViewParent,
            } else if (topCallback != null) {
                if (keyEvent.getAction() == KeyEvent.ACTION_UP) {
                    if (!keyEvent.isCanceled()) {
                        dispatcher.tryInvokeSystemNavigationObserverCallback();
                        topCallback.onBackInvoked();
                    } else {
                        Log.d(mTag, "Skip onBackInvoked(), reason: keyEvent.isCanceled=true");
+18 −0
Original line number Diff line number Diff line
@@ -16,11 +16,14 @@

package android.window;

import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.SuppressLint;

import com.android.window.flags.Flags;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@@ -43,6 +46,7 @@ public interface OnBackInvokedDispatcher {
    @IntDef({
            PRIORITY_DEFAULT,
            PRIORITY_OVERLAY,
            PRIORITY_SYSTEM_NAVIGATION_OBSERVER,
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface Priority{}
@@ -66,6 +70,20 @@ public interface OnBackInvokedDispatcher {
     */
    int PRIORITY_SYSTEM = -1;

    /**
     * Priority level of {@link OnBackInvokedCallback}s designed to observe system-level back
     * handling.
     *
     * <p>Callbacks registered with this priority do not consume back events. They receive back
     * events whenever the system handles a back navigation and have no impact on the normal back
     * navigation flow. Useful for logging or analytics.
     *
     * <p>Only one callback with {@link #PRIORITY_SYSTEM_NAVIGATION_OBSERVER} can be registered at a
     * time.
     */
    @FlaggedApi(Flags.FLAG_PREDICTIVE_BACK_PRIORITY_SYSTEM_NAVIGATION_OBSERVER)
    int PRIORITY_SYSTEM_NAVIGATION_OBSERVER = -2;

    /**
     * Registers a {@link OnBackInvokedCallback}.
     *
+15 −4
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.window;

import static com.android.window.flags.Flags.predictiveBackPrioritySystemNavigationObserver;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -95,7 +97,7 @@ public class ProxyOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
        synchronized (mLock) {
            mCallbacks.add(Pair.create(callback, priority));
            if (mActualDispatcher != null) {
                if (priority <= PRIORITY_SYSTEM) {
                if (priority == PRIORITY_SYSTEM) {
                    mActualDispatcher.registerSystemOnBackInvokedCallback(callback);
                } else {
                    mActualDispatcher.registerOnBackInvokedCallback(priority, callback);
@@ -123,12 +125,21 @@ public class ProxyOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
        }
        for (Pair<OnBackInvokedCallback, Integer> callbackPair : mCallbacks) {
            int priority = callbackPair.second;
            if (predictiveBackPrioritySystemNavigationObserver()) {
                if (priority >= PRIORITY_DEFAULT
                        || priority == PRIORITY_SYSTEM_NAVIGATION_OBSERVER) {
                    mActualDispatcher.registerOnBackInvokedCallback(priority, callbackPair.first);
                } else {
                    mActualDispatcher.registerSystemOnBackInvokedCallback(callbackPair.first);
                }
            } else {
                if (priority >= PRIORITY_DEFAULT) {
                    mActualDispatcher.registerOnBackInvokedCallback(priority, callbackPair.first);
                } else {
                    mActualDispatcher.registerSystemOnBackInvokedCallback(callbackPair.first);
                }
            }
        }
        mCallbacks.clear();
        mImeDispatcher = null;
    }
+112 −25
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.window;

import static com.android.window.flags.Flags.predictiveBackPrioritySystemNavigationObserver;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
@@ -103,6 +105,9 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
    public final TreeMap<Integer, ArrayList<OnBackInvokedCallback>>
            mOnBackInvokedCallbacks = new TreeMap<>();

    @VisibleForTesting
    public OnBackInvokedCallback mSystemNavigationObserverCallback = null;

    private Checker mChecker;
    private final Object mLock = new Object();
    // The threshold for back swipe full progress.
@@ -170,6 +175,20 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
        }
    }

    private void registerSystemNavigationObserverCallback(@NonNull OnBackInvokedCallback callback) {
        synchronized (mLock) {
            // If callback has already been added as regular callback, remove it.
            if (mAllCallbacks.containsKey(callback)) {
                if (DEBUG) {
                    Log.i(TAG, "Callback already added. Removing and re-adding it as "
                            + "system-navigation-observer-callback.");
                }
                removeCallbackInternal(callback);
            }
            mSystemNavigationObserverCallback = callback;
        }
    }

    /**
     * Register a callback bypassing platform checks. This is used to register compatibility
     * callbacks.
@@ -181,6 +200,12 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
                mImeDispatcher.registerOnBackInvokedCallback(priority, callback);
                return;
            }
            if (predictiveBackPrioritySystemNavigationObserver()) {
                if (priority == PRIORITY_SYSTEM_NAVIGATION_OBSERVER) {
                    registerSystemNavigationObserverCallback(callback);
                    return;
                }
            }
            if (callback instanceof ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback) {
                if (callback instanceof ImeOnBackInvokedDispatcher.DefaultImeOnBackAnimationCallback
                        && mImeBackAnimationController != null) {
@@ -202,6 +227,13 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
                Integer prevPriority = mAllCallbacks.get(callback);
                mOnBackInvokedCallbacks.get(prevPriority).remove(callback);
            }
            if (mSystemNavigationObserverCallback == callback) {
                mSystemNavigationObserverCallback = null;
                if (DEBUG) {
                    Log.i(TAG, "Callback already registered (as system-navigation-observer "
                            + "callback). Removing and re-adding it.");
                }
            }

            OnBackInvokedCallback previousTopCallback = getTopCallback();
            callbacks.add(callback);
@@ -221,6 +253,10 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
                mImeDispatcher.unregisterOnBackInvokedCallback(callback);
                return;
            }
            if (mSystemNavigationObserverCallback == callback) {
                mSystemNavigationObserverCallback = null;
                return;
            }
            if (callback instanceof ImeOnBackInvokedDispatcher.DefaultImeOnBackAnimationCallback) {
                callback = mImeBackAnimationController;
            }
@@ -230,6 +266,11 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
                }
                return;
            }
            removeCallbackInternal(callback);
        }
    }

    private void removeCallbackInternal(@NonNull OnBackInvokedCallback callback) {
        OnBackInvokedCallback previousTopCallback = getTopCallback();
        Integer priority = mAllCallbacks.get(callback);
        ArrayList<OnBackInvokedCallback> callbacks = mOnBackInvokedCallbacks.get(priority);
@@ -250,7 +291,6 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
            setTopOnBackInvokedCallback(getTopCallback());
        }
    }
    }

    /**
     * Indicates if a user gesture is currently in progress.
@@ -304,6 +344,7 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
            mHandler.post(mProgressAnimator::reset);
            mAllCallbacks.clear();
            mOnBackInvokedCallbacks.clear();
            mSystemNavigationObserverCallback = null;
        }
    }

@@ -315,6 +356,25 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
        }
    }

    /**
     * Tries to call {@link OnBackInvokedCallback#onBackInvoked} on the system navigation observer
     * callback (if one is set and if the top-most regular callback has
     * {@link OnBackInvokedDispatcher#PRIORITY_SYSTEM})
     */
    public void tryInvokeSystemNavigationObserverCallback() {
        OnBackInvokedCallback topCallback = getTopCallback();
        Integer callbackPriority = mAllCallbacks.getOrDefault(topCallback, null);
        if (callbackPriority != null && callbackPriority == PRIORITY_SYSTEM) {
            invokeSystemNavigationObserverCallback();
        }
    }

    private void invokeSystemNavigationObserverCallback() {
        if (mSystemNavigationObserverCallback != null) {
            mSystemNavigationObserverCallback.onBackInvoked();
        }
    }

    private void setTopOnBackInvokedCallback(@Nullable OnBackInvokedCallback callback) {
        if (mWindowSession == null || mWindow == null) {
            return;
@@ -324,7 +384,9 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
            if (callback != null) {
                int priority = mAllCallbacks.get(callback);
                final IOnBackInvokedCallback iCallback = new OnBackInvokedCallbackWrapper(callback,
                        mTouchTracker, mProgressAnimator, mHandler, this::callOnKeyPreIme);
                        mTouchTracker, mProgressAnimator, mHandler, this::callOnKeyPreIme,
                        this::invokeSystemNavigationObserverCallback,
                        /*isSystemCallback*/ priority == PRIORITY_SYSTEM);
                callbackInfo = new OnBackInvokedCallbackInfo(
                        iCallback,
                        priority,
@@ -416,18 +478,26 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
        private final Handler mHandler;
        @NonNull
        private final BooleanSupplier mOnKeyPreIme;
        @NonNull
        private final Runnable mSystemNavigationObserverCallbackRunnable;
        private final boolean mIsSystemCallback;

        OnBackInvokedCallbackWrapper(
                @NonNull OnBackInvokedCallback callback,
                @NonNull BackTouchTracker touchTracker,
                @NonNull BackProgressAnimator progressAnimator,
                @NonNull Handler handler,
                @NonNull BooleanSupplier onKeyPreIme) {
                @NonNull BooleanSupplier onKeyPreIme,
                @NonNull Runnable systemNavigationObserverCallbackRunnable,
                boolean isSystemCallback
        ) {
            mCallback = new WeakReference<>(callback);
            mTouchTracker = touchTracker;
            mProgressAnimator = progressAnimator;
            mHandler = handler;
            mOnKeyPreIme = onKeyPreIme;
            mSystemNavigationObserverCallbackRunnable = systemNavigationObserverCallbackRunnable;
            mIsSystemCallback = isSystemCallback;
        }

        @Override
@@ -494,9 +564,17 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
                OnBackAnimationCallback animationCallback = getBackAnimationCallback();
                if (animationCallback != null
                        && !(callback instanceof ImeBackAnimationController)) {
                    mProgressAnimator.onBackInvoked(callback::onBackInvoked);
                    mProgressAnimator.onBackInvoked(() -> {
                        if (mIsSystemCallback) {
                            mSystemNavigationObserverCallbackRunnable.run();
                        }
                        callback.onBackInvoked();
                    });
                } else {
                    mProgressAnimator.reset();
                    if (mIsSystemCallback) {
                        mSystemNavigationObserverCallbackRunnable.run();
                    }
                    callback.onBackInvoked();
                }
            });
@@ -597,9 +675,18 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
                                + " application manifest.");
                return false;
            }
            if (predictiveBackPrioritySystemNavigationObserver()) {
                if (priority < 0 && priority != PRIORITY_SYSTEM_NAVIGATION_OBSERVER) {
                    throw new IllegalArgumentException("Application registered "
                            + "OnBackInvokedCallback cannot have negative priority. Priority: "
                            + priority);
                }
            } else {
                if (priority < 0) {
                throw new IllegalArgumentException("Application registered OnBackInvokedCallback "
                        + "cannot have negative priority. Priority: " + priority);
                    throw new IllegalArgumentException("Application registered "
                            + "OnBackInvokedCallback cannot have negative priority. Priority: "
                            + priority);
                }
            }
            Objects.requireNonNull(callback);
            return true;
Loading