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

Commit 025b9e5c authored by Shan Huang's avatar Shan Huang
Browse files

Add compatibility back callbacks.

For pre-T apps, the default back callback dispatches KEYCODE_BACK to the
application's root view.
For T+ apps, the default KEYCODE_BACK listener invokes the registered
OnBackInvokedCallback.

Test: m -j
Bug: 195946584
Change-Id: I62342b249e6cd6f8b036f7e950cc3f9754418ee4
parent 40818219
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -48898,10 +48898,9 @@ package android.view {
    method public default void onBackInvoked();
  }
  public abstract class OnBackInvokedDispatcher {
    ctor public OnBackInvokedDispatcher();
    method public abstract void registerOnBackInvokedCallback(@NonNull android.view.OnBackInvokedCallback, int);
    method public abstract void unregisterOnBackInvokedCallback(@NonNull android.view.OnBackInvokedCallback);
  public interface OnBackInvokedDispatcher {
    method public void registerOnBackInvokedCallback(@NonNull android.view.OnBackInvokedCallback, @IntRange(from=0) int);
    method public void unregisterOnBackInvokedCallback(@NonNull android.view.OnBackInvokedCallback);
    field public static final int PRIORITY_DEFAULT = 0; // 0x0
    field public static final int PRIORITY_OVERLAY = 1000000; // 0xf4240
  }
+4 −0
Original line number Diff line number Diff line
@@ -2800,6 +2800,10 @@ package android.view {
    field public static final int FLAG_IS_ACCESSIBILITY_EVENT = 2048; // 0x800
  }

  public interface OnBackInvokedDispatcher {
    field public static final long DISPATCH_BACK_INVOCATION_AHEAD_OF_TIME = 195946584L; // 0xbade858L
  }

  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface RemotableViewMethod {
    method public abstract String asyncImpl() default "";
  }
+28 −5
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.OnBackInvokedCallback;
import android.view.OnBackInvokedDispatcher;
import android.view.OnBackInvokedDispatcherOwner;
import android.view.RemoteAnimationDefinition;
@@ -144,6 +145,7 @@ import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.Toolbar;
import android.window.SplashScreen;
import android.window.WindowOnBackInvokedDispatcher;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -791,6 +793,7 @@ public class Activity extends ContextThemeWrapper
    private static final int LOG_AM_ON_ACTIVITY_RESULT_CALLED = 30062;
    private static final int LOG_AM_ON_TOP_RESUMED_GAINED_CALLED = 30064;
    private static final int LOG_AM_ON_TOP_RESUMED_LOST_CALLED = 30065;
    private OnBackInvokedCallback mDefaultBackCallback;

    /**
     * After {@link Build.VERSION_CODES#TIRAMISU},
@@ -1617,7 +1620,16 @@ public class Activity extends ContextThemeWrapper
        }
        mRestoredFromBundle = savedInstanceState != null;
        mCalled = true;

        if (!WindowOnBackInvokedDispatcher.shouldUseLegacyBack()) {
            // Add onBackPressed as default back behavior.
            mDefaultBackCallback = new OnBackInvokedCallback() {
                @Override
                public void onBackInvoked() {
                    navigateBack();
                }
            };
            getOnBackInvokedDispatcher().registerSystemOnBackInvokedCallback(mDefaultBackCallback);
        }
    }

    /**
@@ -2653,6 +2665,10 @@ public class Activity extends ContextThemeWrapper
        if (mUiTranslationController != null) {
            mUiTranslationController.onActivityDestroyed();
        }

        if (mDefaultBackCallback != null) {
            getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mDefaultBackCallback);
        }
    }

    /**
@@ -3773,10 +3789,13 @@ public class Activity extends ContextThemeWrapper
     * @see KeyEvent
     */
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (getApplicationInfo().targetSdkVersion
                >= Build.VERSION_CODES.ECLAIR) {
            if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
                    && !event.isCanceled()) {
        int sdkVersion = getApplicationInfo().targetSdkVersion;
        if (sdkVersion >= Build.VERSION_CODES.ECLAIR) {
            if (keyCode == KeyEvent.KEYCODE_BACK
                    && event.isTracking()
                    && !event.isCanceled()
                    && mDefaultBackCallback == null) {
                // Using legacy back handling.
                onBackPressed();
                return true;
            }
@@ -3841,6 +3860,10 @@ public class Activity extends ContextThemeWrapper
        if (!fragmentManager.isStateSaved() && fragmentManager.popBackStackImmediate()) {
            return;
        }
        navigateBack();
    }

    private void navigateBack() {
        if (!isTaskRoot()) {
            // If the activity is not the root of the task, allow finish to proceed normally.
            finishAfterTransition();
+18 −1
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.OnBackInvokedCallback;
import android.view.OnBackInvokedDispatcher;
import android.view.OnBackInvokedDispatcherOwner;
import android.view.SearchEvent;
@@ -62,6 +63,7 @@ import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.window.WindowOnBackInvokedDispatcher;

import com.android.internal.R;
import com.android.internal.app.WindowDecorActionBar;
@@ -156,6 +158,7 @@ public class Dialog implements DialogInterface, Window.Callback,

    /** A {@link Runnable} to run instead of dismissing when {@link #dismiss()} is called. */
    private Runnable mDismissOverride;
    private OnBackInvokedCallback mDefaultBackCallback;

    /**
     * Creates a dialog window that uses the default dialog theme.
@@ -453,6 +456,16 @@ public class Dialog implements DialogInterface, Window.Callback,
     */
    protected void onStart() {
        if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(true);
        if (mContext != null && !WindowOnBackInvokedDispatcher.shouldUseLegacyBack()) {
            // Add onBackPressed as default back behavior.
            mDefaultBackCallback = new OnBackInvokedCallback() {
                @Override
                public void onBackInvoked() {
                    onBackPressed();
                }
            };
            getOnBackInvokedDispatcher().registerSystemOnBackInvokedCallback(mDefaultBackCallback);
        }
    }

    /**
@@ -460,6 +473,9 @@ public class Dialog implements DialogInterface, Window.Callback,
     */
    protected void onStop() {
        if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
        if (mDefaultBackCallback != null) {
            getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mDefaultBackCallback);
        }
    }

    private static final String DIALOG_SHOWING_TAG = "android:dialogShowing";
@@ -685,7 +701,8 @@ public class Dialog implements DialogInterface, Window.Callback,
    public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE)
                && event.isTracking()
                && !event.isCanceled()) {
                && !event.isCanceled()
                && WindowOnBackInvokedDispatcher.shouldUseLegacyBack()) {
            onBackPressed();
            return true;
        }
+54 −9
Original line number Diff line number Diff line
@@ -17,8 +17,13 @@
package android.view;

import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.TestApi;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.os.Build;

import java.lang.annotation.Retention;
@@ -32,13 +37,29 @@ import java.lang.annotation.RetentionPolicy;
 * Attribute updates are proactively pushed to the window manager if they change the dispatch
 * target (a.k.a. the callback to be invoked next), or its behavior.
 */
public abstract class OnBackInvokedDispatcher {
public interface OnBackInvokedDispatcher {
    /**
     * Enables dispatching the "back" action via {@link android.view.OnBackInvokedDispatcher}.
     *
     * When enabled, the following APIs are no longer invoked:
     * <ul>
     * <li> {@link android.app.Activity#onBackPressed}
     * <li> {@link android.app.Dialog#onBackPressed}
     * <li> {@link android.view.KeyEvent#KEYCODE_BACK} is no longer dispatched.
     * </ul>
     *
     * @hide
     */
    @TestApi
    @ChangeId
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
    long DISPATCH_BACK_INVOCATION_AHEAD_OF_TIME = 195946584L;

    /** @hide */
    public static final String TAG = "OnBackInvokedDispatcher";
    String TAG = "OnBackInvokedDispatcher";

    /** @hide */
    public static final boolean DEBUG = Build.isDebuggable();
    boolean DEBUG = Build.isDebuggable();

    /** @hide */
    @IntDef({
@@ -46,18 +67,26 @@ public abstract class OnBackInvokedDispatcher {
            PRIORITY_OVERLAY,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Priority{}
    @interface Priority{}

    /**
     * Priority level of {@link OnBackInvokedCallback}s for overlays such as menus and
     * navigation drawers that should receive back dispatch before non-overlays.
     */
    public static final int PRIORITY_OVERLAY = 1000000;
    int PRIORITY_OVERLAY = 1000000;

    /**
     * Default priority level of {@link OnBackInvokedCallback}s.
     */
    public static final int PRIORITY_DEFAULT = 0;
    int PRIORITY_DEFAULT = 0;

    /**
     * Priority level of {@link OnBackInvokedCallback}s registered by the system.
     *
     * System back animation will play when the callback to receive dispatch has this priority.
     * @hide
     */
    int PRIORITY_SYSTEM = -1;

    /**
     * Registers a {@link OnBackInvokedCallback}.
@@ -69,10 +98,11 @@ public abstract class OnBackInvokedDispatcher {
     *                 registered, the existing instance (no matter its priority) will be
     *                 unregistered and registered again.
     * @param priority The priority of the callback.
     * @throws {@link IllegalArgumentException} if the priority is negative.
     */
    @SuppressLint("SamShouldBeLast")
    public abstract void registerOnBackInvokedCallback(
            @NonNull OnBackInvokedCallback callback, @Priority int priority);
    void registerOnBackInvokedCallback(
            @NonNull OnBackInvokedCallback callback, @Priority @IntRange(from = 0) int priority);

    /**
     * Unregisters a {@link OnBackInvokedCallback}.
@@ -80,5 +110,20 @@ public abstract class OnBackInvokedDispatcher {
     * @param callback The callback to be unregistered. Does nothing if the callback has not been
     *                 registered.
     */
    public abstract void unregisterOnBackInvokedCallback(@NonNull OnBackInvokedCallback callback);
    void unregisterOnBackInvokedCallback(@NonNull OnBackInvokedCallback callback);

    /**
     * Returns the most prioritized callback to receive back dispatch next.
     * @hide
     */
    @Nullable
    default OnBackInvokedCallback getTopCallback() {
        return null;
    }

    /**
     * Registers a {@link OnBackInvokedCallback} with system priority.
     * @hide
     */
    default void registerSystemOnBackInvokedCallback(@NonNull OnBackInvokedCallback callback) { }
}
Loading