diff --git a/core/api/current.txt b/core/api/current.txt index 89b994189e92..1b07593f4cbf 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -57974,7 +57974,7 @@ package android.widget.inline { package android.window { public interface OnBackInvokedCallback { - method public default void onBackInvoked(); + method public void onBackInvoked(); } public interface OnBackInvokedDispatcher { diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index dff3c076727d..5537b075d42f 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -1663,12 +1663,7 @@ public class Activity extends ContextThemeWrapper .isOnBackInvokedCallbackEnabled(this); if (aheadOfTimeBack) { // Add onBackPressed as default back behavior. - mDefaultBackCallback = new OnBackInvokedCallback() { - @Override - public void onBackInvoked() { - navigateBack(); - } - }; + mDefaultBackCallback = this::navigateBack; getOnBackInvokedDispatcher().registerSystemOnBackInvokedCallback(mDefaultBackCallback); } } diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java index 72c7fe4c5b40..51b71f0c5d52 100644 --- a/core/java/android/app/Dialog.java +++ b/core/java/android/app/Dialog.java @@ -459,12 +459,7 @@ public class Dialog implements DialogInterface, Window.Callback, if (mContext != null && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) { // Add onBackPressed as default back behavior. - mDefaultBackCallback = new OnBackInvokedCallback() { - @Override - public void onBackInvoked() { - onBackPressed(); - } - }; + mDefaultBackCallback = this::onBackPressed; getOnBackInvokedDispatcher().registerOnBackInvokedCallback( OnBackInvokedDispatcher.PRIORITY_DEFAULT, mDefaultBackCallback); mDefaultBackCallback = null; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 931ae2748785..900aa23d0347 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -10765,12 +10765,9 @@ public final class ViewRootImpl implements ViewParent, } private void registerCompatOnBackInvokedCallback() { - mCompatOnBackInvokedCallback = new OnBackInvokedCallback() { - @Override - public void onBackInvoked() { + mCompatOnBackInvokedCallback = () -> { sendBackKeyEvent(KeyEvent.ACTION_DOWN); sendBackKeyEvent(KeyEvent.ACTION_UP); - } }; mOnBackInvokedDispatcher.registerOnBackInvokedCallback( OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCompatOnBackInvokedCallback); diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index dbfcca9d632a..285a40779b90 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -240,12 +240,7 @@ public class Editor { private final boolean mHapticTextHandleEnabled; /** Handles OnBackInvokedCallback back dispatch */ - private final OnBackInvokedCallback mBackCallback = new OnBackInvokedCallback() { - @Override - public void onBackInvoked() { - stopTextActionMode(); - } - }; + private final OnBackInvokedCallback mBackCallback = this::stopTextActionMode; private boolean mBackCallbackRegistered; @Nullable diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java index f1dc5e7050fb..ab2d0056df6b 100644 --- a/core/java/android/widget/MediaController.java +++ b/core/java/android/widget/MediaController.java @@ -122,12 +122,7 @@ public class MediaController extends FrameLayout { private final AccessibilityManager mAccessibilityManager; private boolean mBackCallbackRegistered; /** Handles back invocation */ - private final OnBackInvokedCallback mBackCallback = new OnBackInvokedCallback() { - @Override - public void onBackInvoked() { - hide(); - } - }; + private final OnBackInvokedCallback mBackCallback = this::hide; /** Handles decor view attach state change */ private final OnAttachStateChangeListener mAttachStateListener = new OnAttachStateChangeListener() { diff --git a/core/java/android/window/OnBackAnimationCallback.java b/core/java/android/window/OnBackAnimationCallback.java new file mode 100644 index 000000000000..1a37e57df403 --- /dev/null +++ b/core/java/android/window/OnBackAnimationCallback.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.window; + +import android.annotation.NonNull; +import android.app.Activity; +import android.app.Dialog; +import android.view.View; + +/** + * Interface for applications to register back animation callbacks along their custom back + * handling. + *
+ * This allows the client to customize various back behaviors by overriding the corresponding + * callback methods. + *
+ * Callback instances can be added to and removed from {@link OnBackInvokedDispatcher}, held + * by classes that implement {@link OnBackInvokedDispatcherOwner} (such as {@link Activity}, + * {@link Dialog} and {@link View}). + *
+ * When back is triggered, callbacks on the in-focus window are invoked in reverse order in which + * they are added within the same priority. Between different priorities, callbacks with higher + * priority are invoked first. + *
+ * @see OnBackInvokedCallback + * @hide + */ +public interface OnBackAnimationCallback extends OnBackInvokedCallback { + /** + * Called when a back gesture has been started, or back button has been pressed down. + */ + default void onBackStarted() { } + + /** + * Called on back gesture progress. + * + * @param backEvent An {@link BackEvent} object describing the progress event. + * + * @see BackEvent + */ + default void onBackProgressed(@NonNull BackEvent backEvent) { } + + /** + * Called when a back gesture or back button press has been cancelled. + */ + default void onBackCancelled() { } +} diff --git a/core/java/android/window/OnBackInvokedCallback.java b/core/java/android/window/OnBackInvokedCallback.java index 400a56f2c485..7b8cc0ae6de7 100644 --- a/core/java/android/window/OnBackInvokedCallback.java +++ b/core/java/android/window/OnBackInvokedCallback.java @@ -21,49 +21,29 @@ import android.app.Dialog; import android.view.View; /** - * Interface for applications to register back invocation callbacks. This allows the client - * to customize various back behaviors by overriding the corresponding callback methods. - * + * Callback allowing applications to handle back events in place of the system. + *
* Callback instances can be added to and removed from {@link OnBackInvokedDispatcher}, held * by classes that implement {@link OnBackInvokedDispatcherOwner} (such as {@link Activity}, * {@link Dialog} and {@link View}). - * + *
* Under the hood callbacks are registered at window level. When back is triggered, * callbacks on the in-focus window are invoked in reverse order in which they are added * within the same priority. Between different pirorities, callbacks with higher priority * are invoked first. + *
+ * This replaces {@link Activity#onBackPressed()}, {@link Dialog#onBackPressed()} and + * {@link android.view.KeyEvent#KEYCODE_BACK} * - * See {@link OnBackInvokedDispatcher#registerOnBackInvokedCallback(int, OnBackInvokedCallback)} - * for specifying callback priority. + * @see OnBackInvokedDispatcher#registerOnBackInvokedCallback(int, OnBackInvokedCallback) + * registerOnBackInvokedCallback(priority, OnBackInvokedCallback) + * to specify callback priority. */ +@SuppressWarnings("deprecation") public interface OnBackInvokedCallback { - /** - * Called when a back gesture has been started, or back button has been pressed down. - * - * @hide - */ - default void onBackStarted() { }; - - /** - * Called on back gesture progress. - * - * @param backEvent An {@link android.window.BackEvent} object describing the progress event. - * - * @see android.window.BackEvent - * @hide - */ - default void onBackProgressed(BackEvent backEvent) { }; - - /** - * Called when a back gesture or back button press has been cancelled. - * - * @hide - */ - default void onBackCancelled() { }; - /** * Called when a back gesture has been completed and committed, or back button pressed * has been released and committed. */ - default void onBackInvoked() { }; + void onBackInvoked(); } diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java index 8811116b25ad..77031d93f943 100644 --- a/core/java/android/window/WindowOnBackInvokedDispatcher.java +++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java @@ -199,36 +199,30 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { @Override public void onBackStarted() { Handler.getMain().post(() -> { - final OnBackInvokedCallback callback = mCallback.get(); - if (callback == null) { - return; + final OnBackAnimationCallback callback = getBackAnimationCallback(); + if (callback != null) { + callback.onBackStarted(); } - - callback.onBackStarted(); }); } @Override public void onBackProgressed(BackEvent backEvent) { Handler.getMain().post(() -> { - final OnBackInvokedCallback callback = mCallback.get(); - if (callback == null) { - return; + final OnBackAnimationCallback callback = getBackAnimationCallback(); + if (callback != null) { + callback.onBackProgressed(backEvent); } - - callback.onBackProgressed(backEvent); }); } @Override public void onBackCancelled() { Handler.getMain().post(() -> { - final OnBackInvokedCallback callback = mCallback.get(); - if (callback == null) { - return; + final OnBackAnimationCallback callback = getBackAnimationCallback(); + if (callback != null) { + callback.onBackCancelled(); } - - callback.onBackCancelled(); }); } @@ -243,6 +237,13 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { callback.onBackInvoked(); }); } + + @Nullable + private OnBackAnimationCallback getBackAnimationCallback() { + OnBackInvokedCallback callback = mCallback.get(); + return callback instanceof OnBackAnimationCallback ? (OnBackAnimationCallback) callback + : null; + } } /** diff --git a/core/tests/coretests/src/android/window/BackNavigationTest.java b/core/tests/coretests/src/android/window/BackNavigationTest.java index 94a149b09d54..678eef557fed 100644 --- a/core/tests/coretests/src/android/window/BackNavigationTest.java +++ b/core/tests/coretests/src/android/window/BackNavigationTest.java @@ -111,12 +111,7 @@ public class BackNavigationTest { CountDownLatch backRegisteredLatch = new CountDownLatch(1); mScenario.onActivity(activity -> { activity.getOnBackInvokedDispatcher().registerOnBackInvokedCallback( - 0, new OnBackInvokedCallback() { - @Override - public void onBackInvoked() { - backInvokedLatch.countDown(); - } - } + 0, backInvokedLatch::countDown ); backRegisteredLatch.countDown(); }); diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java index 212f4ed92b8c..6aa5be5c1a1b 100644 --- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java +++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java @@ -56,9 +56,9 @@ public class WindowOnBackInvokedDispatcherTest { private IWindow mWindow; private WindowOnBackInvokedDispatcher mDispatcher; @Mock - private OnBackInvokedCallback mCallback1; + private OnBackAnimationCallback mCallback1; @Mock - private OnBackInvokedCallback mCallback2; + private OnBackAnimationCallback mCallback2; @Before public void setUp() throws Exception {