Loading core/api/current.txt +3 −4 Original line number Diff line number Diff line Loading @@ -48950,10 +48950,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 } core/api/test-current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -2802,6 +2802,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 ""; } Loading core/java/android/app/Activity.java +28 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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}, Loading Loading @@ -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); } } /** Loading Loading @@ -2653,6 +2665,10 @@ public class Activity extends ContextThemeWrapper if (mUiTranslationController != null) { mUiTranslationController.onActivityDestroyed(); } if (mDefaultBackCallback != null) { getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mDefaultBackCallback); } } /** Loading Loading @@ -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; } Loading Loading @@ -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(); Loading core/java/android/app/Dialog.java +18 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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); } } /** Loading @@ -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"; Loading Loading @@ -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; } Loading core/java/android/view/OnBackInvokedDispatcher.java +54 −9 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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({ Loading @@ -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}. Loading @@ -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}. Loading @@ -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
core/api/current.txt +3 −4 Original line number Diff line number Diff line Loading @@ -48950,10 +48950,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 }
core/api/test-current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -2802,6 +2802,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 ""; } Loading
core/java/android/app/Activity.java +28 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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}, Loading Loading @@ -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); } } /** Loading Loading @@ -2653,6 +2665,10 @@ public class Activity extends ContextThemeWrapper if (mUiTranslationController != null) { mUiTranslationController.onActivityDestroyed(); } if (mDefaultBackCallback != null) { getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mDefaultBackCallback); } } /** Loading Loading @@ -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; } Loading Loading @@ -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(); Loading
core/java/android/app/Dialog.java +18 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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); } } /** Loading @@ -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"; Loading Loading @@ -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; } Loading
core/java/android/view/OnBackInvokedDispatcher.java +54 −9 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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({ Loading @@ -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}. Loading @@ -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}. Loading @@ -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) { } }