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

Commit 032e2676 authored by Arthur Hung's avatar Arthur Hung
Browse files

Add enableOnBackInvokedCallaback manifest attribute for activity

Currently, there is already a flag for an application to opt-in of the
new back navigation system.
This will add a new manifest flag for an activity could opt-out/opt-in
of the new behavior.

When the attribute has set, it will add a private flag to ActivityInfo
to identify current activity will opt-in or opt-out the new back
navigation system.

If no attribute set for activity, it will still check the attribute of
application info.

Test: atest BackNavigationControllerTests
Test: atest BackNavigationLegacyGestureTest BackNavigationLegacyTest
Test: atest BackNavigationTests
Test: atest WindowOnBackInvokedDispatcherTest BackNavigationTest
Test: atset BackAnimationControllerTest
Bug: 256536263
Change-Id: Ic126c0d4ce54d146698766154e22a18ccb0042eb
parent b99d5ea6
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -2761,6 +2761,7 @@ public class Activity extends ContextThemeWrapper
            getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mDefaultBackCallback);
            mDefaultBackCallback = null;
        }

        if (mCallbacksController != null) {
            mCallbacksController.clearCallbacks();
        }
@@ -8338,6 +8339,7 @@ public class Activity extends ContextThemeWrapper
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);
        mActivityInfo = info;

        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowControllerCallback(mWindowControllerCallback);
@@ -8362,7 +8364,6 @@ public class Activity extends ContextThemeWrapper
        mIntent = intent;
        mReferrer = referrer;
        mComponent = intent.getComponent();
        mActivityInfo = info;
        mTitle = title;
        mParent = parent;
        mEmbeddedID = id;
+50 −2
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.os.Parcelable;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Printer;
import android.window.OnBackInvokedCallback;

import com.android.internal.util.Parcelling;

@@ -624,7 +625,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
     * See {@link android.R.attr#inheritShowWhenLocked}.
     * @hide
     */
    public static final int FLAG_INHERIT_SHOW_WHEN_LOCKED = 0x1;
    public static final int FLAG_INHERIT_SHOW_WHEN_LOCKED = 1 << 0;

    /**
     * Bit in {@link #privateFlags} indicating whether a home sound effect should be played if the
@@ -632,13 +633,34 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
     * Set from the {@link android.R.attr#playHomeTransitionSound} attribute.
     * @hide
     */
    public static final int PRIVATE_FLAG_HOME_TRANSITION_SOUND = 0x2;
    public static final int PRIVATE_FLAG_HOME_TRANSITION_SOUND = 1 << 1;

    /**
     * Bit in {@link #privateFlags} indicating {@link android.view.KeyEvent#KEYCODE_BACK} related
     * events will be replaced by a call to {@link OnBackInvokedCallback#onBackInvoked()} on the
     * focused window.
     * @hide
     * @see android.R.styleable.AndroidManifestActivity_enableOnBackInvokedCallback
     */
    public static final int PRIVATE_FLAG_ENABLE_ON_BACK_INVOKED_CALLBACK = 1 << 2;

    /**
     * Bit in {@link #privateFlags} indicating {@link android.view.KeyEvent#KEYCODE_BACK} related
     * events will be forwarded to the Activity and its dialogs and views and
     * the {@link android.app.Activity#onBackPressed()}, {@link android.app.Dialog#onBackPressed}
     * will be called.
     * @hide
     * @see android.R.styleable.AndroidManifestActivity_enableOnBackInvokedCallback
     */
    public static final int PRIVATE_FLAG_DISABLE_ON_BACK_INVOKED_CALLBACK = 1 << 3;

    /**
     * Options that have been set in the activity declaration in the manifest.
     * These include:
     * {@link #FLAG_INHERIT_SHOW_WHEN_LOCKED},
     * {@link #PRIVATE_FLAG_HOME_TRANSITION_SOUND}.
     * {@link #PRIVATE_FLAG_ENABLE_ON_BACK_INVOKED_CALLBACK}
     * {@link #PRIVATE_FLAG_DISABLE_ON_BACK_INVOKED_CALLBACK}
     * @hide
     */
    public int privateFlags;
@@ -1618,6 +1640,32 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
        return isChangeEnabled(CHECK_MIN_WIDTH_HEIGHT_FOR_MULTI_WINDOW);
    }

    /**
     * Returns whether the activity will set the
     * {@link R.styleable.AndroidManifestActivity_enableOnBackInvokedCallback} attribute.
     *
     * @hide
     */
    public boolean hasOnBackInvokedCallbackEnabled() {
        return (privateFlags & (PRIVATE_FLAG_ENABLE_ON_BACK_INVOKED_CALLBACK
                | PRIVATE_FLAG_DISABLE_ON_BACK_INVOKED_CALLBACK)) != 0;
    }

    /**
     * Returns whether the activity will use the {@link android.window.OnBackInvokedCallback}
     * navigation system instead of the {@link android.view.KeyEvent#KEYCODE_BACK} and related
     * callbacks.
     *
     * Valid when the {@link R.styleable.AndroidManifestActivity_enableOnBackInvokedCallback}
     * attribute has been set, or it won't indicate if the activity should use the
     * navigation system and the {@link hasOnBackInvokedCallbackEnabled} will return false.
     * @hide
     */
    public boolean isOnBackInvokedCallbackEnabled() {
        return hasOnBackInvokedCallbackEnabled()
                && (privateFlags & PRIVATE_FLAG_ENABLE_ON_BACK_INVOKED_CALLBACK) != 0;
    }

    public void dump(Printer pw, String prefix) {
        dump(pw, prefix, DUMP_FLAG_ALL);
    }
+10 −11
Original line number Diff line number Diff line
@@ -1000,8 +1000,7 @@ public final class ViewRootImpl implements ViewParent,
        mFastScrollSoundEffectsEnabled = audioManager.areNavigationRepeatSoundEffectsEnabled();

        mScrollCaptureRequestTimeout = SCROLL_CAPTURE_REQUEST_TIMEOUT_MILLIS;
        mOnBackInvokedDispatcher = new WindowOnBackInvokedDispatcher(
                context.getApplicationInfo().isOnBackInvokedCallbackEnabled());
        mOnBackInvokedDispatcher = new WindowOnBackInvokedDispatcher(context);
    }

    public static void addFirstDrawHandler(Runnable callback) {
@@ -1307,14 +1306,6 @@ public final class ViewRootImpl implements ViewParent,
                        mTmpFrames);
                setFrame(mTmpFrames.frame);
                registerBackCallbackOnWindow();
                if (!WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) {
                    // For apps requesting legacy back behavior, we add a compat callback that
                    // dispatches {@link KeyEvent#KEYCODE_BACK} to their root views.
                    // This way from system point of view, these apps are providing custom
                    // {@link OnBackInvokedCallback}s, and will not play system back animations
                    // for them.
                    registerCompatOnBackInvokedCallback();
                }
                if (DEBUG_LAYOUT) Log.v(mTag, "Added window " + mWindow);
                if (res < WindowManagerGlobal.ADD_OKAY) {
                    mAttachInfo.mRootView = null;
@@ -2907,6 +2898,14 @@ public final class ViewRootImpl implements ViewParent,
            host.dispatchAttachedToWindow(mAttachInfo, 0);
            mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);
            dispatchApplyInsets(host);
            if (!mOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled()) {
                // For apps requesting legacy back behavior, we add a compat callback that
                // dispatches {@link KeyEvent#KEYCODE_BACK} to their root views.
                // This way from system point of view, these apps are providing custom
                // {@link OnBackInvokedCallback}s, and will not play system back animations
                // for them.
                registerCompatOnBackInvokedCallback();
            }
        } else {
            desiredWindowWidth = frame.width();
            desiredWindowHeight = frame.height();
@@ -6362,7 +6361,7 @@ public final class ViewRootImpl implements ViewParent,
                // view tree or IME, and invoke the appropriate {@link OnBackInvokedCallback}.
                if (isBack(event)
                        && mContext != null
                        && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) {
                        && mOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled()) {
                    OnBackInvokedCallback topCallback =
                            getOnBackInvokedDispatcher().getTopCallback();
                    if (event.getAction() == KeyEvent.ACTION_UP) {
+2 −5
Original line number Diff line number Diff line
@@ -133,7 +133,6 @@ import android.widget.TextView.Drawables;
import android.widget.TextView.OnEditorActionListener;
import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;
import android.window.WindowOnBackInvokedDispatcher;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.EditableInputConnection;
@@ -770,8 +769,7 @@ public class Editor {
        }
        ViewRootImpl viewRootImpl = getTextView().getViewRootImpl();
        if (viewRootImpl != null
                && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(
                        viewRootImpl.mContext)) {
                && viewRootImpl.getOnBackInvokedDispatcher().isOnBackInvokedCallbackEnabled()) {
            viewRootImpl.getOnBackInvokedDispatcher()
                    .unregisterOnBackInvokedCallback(mBackCallback);
            mBackCallbackRegistered = false;
@@ -784,8 +782,7 @@ public class Editor {
        }
        ViewRootImpl viewRootImpl = mTextView.getViewRootImpl();
        if (viewRootImpl != null
                && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(
                        viewRootImpl.mContext)) {
                && viewRootImpl.getOnBackInvokedDispatcher().isOnBackInvokedCallbackEnabled()) {
            viewRootImpl.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
                    OnBackInvokedDispatcher.PRIORITY_DEFAULT, mBackCallback);
            mBackCallbackRegistered = true;
+2 −5
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ import android.view.accessibility.AccessibilityManager;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;
import android.window.WindowOnBackInvokedDispatcher;

import com.android.internal.policy.PhoneWindow;

@@ -748,8 +747,7 @@ public class MediaController extends FrameLayout {
        }
        ViewRootImpl viewRootImpl = mDecor.getViewRootImpl();
        if (viewRootImpl != null
                && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(
                viewRootImpl.mContext)) {
                && viewRootImpl.getOnBackInvokedDispatcher().isOnBackInvokedCallbackEnabled()) {
            viewRootImpl.getOnBackInvokedDispatcher()
                    .unregisterOnBackInvokedCallback(mBackCallback);
        }
@@ -763,8 +761,7 @@ public class MediaController extends FrameLayout {

        ViewRootImpl viewRootImpl = mDecor.getViewRootImpl();
        if (viewRootImpl != null
                && WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(
                viewRootImpl.mContext)) {
                && viewRootImpl.getOnBackInvokedDispatcher().isOnBackInvokedCallbackEnabled()) {
            viewRootImpl.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
                    OnBackInvokedDispatcher.PRIORITY_DEFAULT, mBackCallback);
            mBackCallbackRegistered = true;
Loading