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

Commit 2dfd2061 authored by Winson Chung's avatar Winson Chung Committed by Android (Google) Code Review
Browse files

Merge "Cache accessibility info in NavBarHelper to reduce binder calls"

parents 5c5e7b91 62f47683
Loading
Loading
Loading
Loading
+74 −23
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.systemui.navigationbar;

import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;

import static com.android.systemui.accessibility.SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON;
import static com.android.systemui.accessibility.SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;

@@ -39,6 +41,8 @@ import androidx.annotation.NonNull;

import com.android.systemui.Dumpable;
import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
import com.android.systemui.accessibility.SystemActions;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
@@ -70,13 +74,16 @@ import dagger.Lazy;
@SysUISingleton
public final class NavBarHelper implements
        AccessibilityButtonModeObserver.ModeChangedListener,
        AccessibilityButtonTargetsObserver.TargetsChangedListener,
        OverviewProxyService.OverviewProxyListener, NavigationModeController.ModeChangedListener,
        Dumpable {
    private final AccessibilityManager mAccessibilityManager;
    private final Lazy<AssistManager> mAssistManagerLazy;
    private final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
    private final UserTracker mUserTracker;
    private final SystemActions mSystemActions;
    private final AccessibilityButtonModeObserver mAccessibilityButtonModeObserver;
    private final AccessibilityButtonTargetsObserver mAccessibilityButtonTargetsObserver;
    private final List<NavbarTaskbarStateUpdater> mA11yEventListeners = new ArrayList<>();
    private final Context mContext;
    private ContentResolver mContentResolver;
@@ -84,12 +91,13 @@ public final class NavBarHelper implements
    private boolean mLongPressHomeEnabled;
    private boolean mAssistantTouchGestureEnabled;
    private int mNavBarMode;
    private int mA11yButtonState;

    private final ContentObserver mAssistContentObserver = new ContentObserver(
            new Handler(Looper.getMainLooper())) {
        @Override
        public void onChange(boolean selfChange, Uri uri) {
            updateAssitantAvailability();
            updateAssistantAvailability();
        }
    };

@@ -100,8 +108,9 @@ public final class NavBarHelper implements
     */
    @Inject
    public NavBarHelper(Context context, AccessibilityManager accessibilityManager,
            AccessibilityManagerWrapper accessibilityManagerWrapper,
            AccessibilityButtonModeObserver accessibilityButtonModeObserver,
            AccessibilityButtonTargetsObserver accessibilityButtonTargetsObserver,
            SystemActions systemActions,
            OverviewProxyService overviewProxyService,
            Lazy<AssistManager> assistManagerLazy,
            Lazy<Optional<StatusBar>> statusBarOptionalLazy,
@@ -114,11 +123,14 @@ public final class NavBarHelper implements
        mAssistManagerLazy = assistManagerLazy;
        mStatusBarOptionalLazy = statusBarOptionalLazy;
        mUserTracker = userTracker;
        accessibilityManagerWrapper.addCallback(
        mSystemActions = systemActions;
        accessibilityManager.addAccessibilityServicesStateChangeListener(
                accessibilityManager1 -> NavBarHelper.this.dispatchA11yEventUpdate());
        mAccessibilityButtonModeObserver = accessibilityButtonModeObserver;
        mAccessibilityButtonTargetsObserver = accessibilityButtonTargetsObserver;

        mAccessibilityButtonModeObserver.addListener(this);
        mAccessibilityButtonTargetsObserver.addListener(this);
        mNavBarMode = navigationModeController.addListener(this);
        overviewProxyService.addCallback(this);
        dumpManager.registerDumpable(this);
@@ -134,7 +146,7 @@ public final class NavBarHelper implements
        mContentResolver.registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED),
                false, mAssistContentObserver, UserHandle.USER_ALL);
        updateAssitantAvailability();
        updateAssistantAvailability();
    }

    public void destroy() {
@@ -168,43 +180,82 @@ public final class NavBarHelper implements

    @Override
    public void onAccessibilityButtonModeChanged(int mode) {
        updateA11yState();
        dispatchA11yEventUpdate();
    }

    @Override
    public void onAccessibilityButtonTargetsChanged(String targets) {
        updateA11yState();
        dispatchA11yEventUpdate();
    }

    /**
     * See {@link QuickStepContract#SYSUI_STATE_A11Y_BUTTON_CLICKABLE} and
     * {@link QuickStepContract#SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE}
     *
     * @return the a11y button clickable and long_clickable states, or 0 if there is no
     *         a11y button in the navbar
     * Updates the current accessibility button state.
     */
    public int getA11yButtonState() {
    private void updateA11yState() {
        final int prevState = mA11yButtonState;
        final boolean clickable;
        final boolean longClickable;
        if (mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode()
                == ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU) {
            // If accessibility button is floating menu mode, click and long click state should be
            // disabled.
            clickable = false;
            longClickable = false;
            mA11yButtonState = 0;
        } else {
            // AccessibilityManagerService resolves services for the current user since the local
        // AccessibilityManager is created from a Context with the INTERACT_ACROSS_USERS permission
            // AccessibilityManager is created from a Context with the INTERACT_ACROSS_USERS
            // permission
            final List<String> a11yButtonTargets =
                    mAccessibilityManager.getAccessibilityShortcutTargets(
                            AccessibilityManager.ACCESSIBILITY_BUTTON);
            final int requestingServices = a11yButtonTargets.size();

        // If accessibility button is floating menu mode, click and long click state should be
        // disabled.
        if (mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode()
                == ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU) {
            return 0;
            clickable = requestingServices >= 1;
            longClickable = requestingServices >= 2;
            mA11yButtonState = (clickable ? SYSUI_STATE_A11Y_BUTTON_CLICKABLE : 0)
                    | (longClickable ? SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE : 0);
        }

        // Update the system actions if the state has changed
        if (prevState != mA11yButtonState) {
            updateSystemAction(clickable, SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON);
            updateSystemAction(longClickable, SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER);
        }
    }

    /**
     * Registers/unregisters the given system action id.
     */
    private void updateSystemAction(boolean register, int actionId) {
        if (register) {
            mSystemActions.register(actionId);
        } else {
            mSystemActions.unregister(actionId);
        }
    }

        return (requestingServices >= 1 ? SYSUI_STATE_A11Y_BUTTON_CLICKABLE : 0)
                | (requestingServices >= 2 ? SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE : 0);
    /**
     * See {@link QuickStepContract#SYSUI_STATE_A11Y_BUTTON_CLICKABLE} and
     * {@link QuickStepContract#SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE}
     *
     * @return the a11y button clickable and long_clickable states, or 0 if there is no
     *         a11y button in the navbar
     */
    public int getA11yButtonState() {
        return mA11yButtonState;
    }

    @Override
    public void onConnectionChanged(boolean isConnected) {
        if (isConnected) {
            updateAssitantAvailability();
            updateAssistantAvailability();
        }
    }

    private void updateAssitantAvailability() {
    private void updateAssistantAvailability() {
        boolean assistantAvailableForUser = mAssistManagerLazy.get()
                .getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
        boolean longPressDefault = mContext.getResources().getBoolean(
@@ -236,7 +287,7 @@ public final class NavBarHelper implements
    @Override
    public void onNavigationModeChanged(int mode) {
        mNavBarMode = mode;
        updateAssitantAvailability();
        updateAssistantAvailability();
    }

    /**
+14 −39
Original line number Diff line number Diff line
@@ -110,7 +110,6 @@ import com.android.internal.util.LatencyTracker;
import com.android.internal.view.AppearanceRegion;
import com.android.systemui.R;
import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
import com.android.systemui.accessibility.SystemActions;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
@@ -122,7 +121,6 @@ import com.android.systemui.navigationbar.gestural.QuickswitchOrientedNavHandle;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.rotation.RotationButton;
import com.android.systemui.shared.rotation.RotationButtonController;
@@ -192,7 +190,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
    private final Optional<LegacySplitScreen> mSplitScreenOptional;
    private final Optional<Recents> mRecentsOptional;
    private final Optional<BackAnimation> mBackAnimation;
    private final SystemActions mSystemActions;
    private final Handler mHandler;
    private final NavigationBarOverlayController mNavbarOverlayController;
    private final UiEventLogger mUiEventLogger;
@@ -307,7 +304,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
            new NavBarHelper.NavbarTaskbarStateUpdater() {
                @Override
                public void updateAccessibilityServicesState() {
                    updateAcessibilityStateFlags();
                    updateAccessibilityStateFlags();
                }

                @Override
@@ -495,12 +492,10 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
            ShadeController shadeController,
            NotificationRemoteInputManager notificationRemoteInputManager,
            NotificationShadeDepthController notificationShadeDepthController,
            SystemActions systemActions,
            @Main Handler mainHandler,
            NavigationBarOverlayController navbarOverlayController,
            UiEventLogger uiEventLogger,
            NavBarHelper navBarHelper,
            UserTracker userTracker,
            LightBarController mainLightBarController,
            LightBarController.Factory lightBarControllerFactory,
            AutoHideController mainAutoHideController,
@@ -528,7 +523,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
        mSplitScreenOptional = splitScreenOptional;
        mRecentsOptional = recentsOptional;
        mBackAnimation = backAnimation;
        mSystemActions = systemActions;
        mHandler = mainHandler;
        mNavbarOverlayController = navbarOverlayController;
        mUiEventLogger = uiEventLogger;
@@ -646,7 +640,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
        notifyNavigationBarScreenOn();

        mOverviewProxyService.addCallback(mOverviewProxyListener);
        updateSystemUiStateFlags(-1);
        updateSystemUiStateFlags();

        // Currently there is no accelerometer sensor on non-default display.
        if (mIsOnDefaultDisplay) {
@@ -904,7 +898,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
            mNavigationBarView.setNavigationIconHints(hints);
        }
        checkBarModes();
        updateSystemUiStateFlags(-1);
        updateSystemUiStateFlags();
    }

    @Override
@@ -914,7 +908,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
                && window == StatusBarManager.WINDOW_NAVIGATION_BAR
                && mNavigationBarWindowState != state) {
            mNavigationBarWindowState = state;
            updateSystemUiStateFlags(-1);
            updateSystemUiStateFlags();
            mShowOrientedHandleForImmersiveMode = state == WINDOW_STATE_HIDDEN;
            if (mOrientationHandle != null
                    && mStartingQuickSwitchRotation != -1) {
@@ -993,7 +987,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
        if (mBehavior != behavior) {
            mBehavior = behavior;
            mNavigationBarView.setBehavior(behavior);
            updateSystemUiStateFlags(-1);
            updateSystemUiStateFlags();
        }
    }

@@ -1160,7 +1154,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
        ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton();
        accessibilityButton.setOnClickListener(this::onAccessibilityClick);
        accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
        updateAcessibilityStateFlags();
        updateAccessibilityStateFlags();

        ButtonDispatcher imeSwitcherButton = mNavigationBarView.getImeSwitchButton();
        imeSwitcherButton.setOnClickListener(this::onImeSwitcherClick);
@@ -1386,21 +1380,18 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
        return true;
    }

    void updateAcessibilityStateFlags() {
        int a11yFlags = mNavBarHelper.getA11yButtonState();

    void updateAccessibilityStateFlags() {
        if (mNavigationBarView != null) {
            int a11yFlags = mNavBarHelper.getA11yButtonState();
            boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
            boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
            mNavigationBarView.setAccessibilityButtonState(clickable, longClickable);
        }
        updateSystemUiStateFlags(a11yFlags);
        updateSystemUiStateFlags();
    }

    public void updateSystemUiStateFlags(int a11yFlags) {
        if (a11yFlags < 0) {
            a11yFlags = mNavBarHelper.getA11yButtonState();
        }
    public void updateSystemUiStateFlags() {
        int a11yFlags = mNavBarHelper.getA11yButtonState();
        boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
        boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;

@@ -1414,16 +1405,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
                .setFlag(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY,
                        allowSystemGestureIgnoringBarVisibility())
                .commitUpdate(mDisplayId);
        registerAction(clickable, SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON);
        registerAction(longClickable, SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER);
    }

    private void registerAction(boolean register, int actionId) {
        if (register) {
            mSystemActions.register(actionId);
        } else {
            mSystemActions.unregister(actionId);
        }
    }

    private void updateAssistantEntrypoints(boolean assistantAvailable) {
@@ -1641,7 +1622,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
            }
            if (Intent.ACTION_USER_SWITCHED.equals(action)) {
                // The accessibility settings may be different for the new user
                updateAcessibilityStateFlags();
                updateAccessibilityStateFlags();
            }
        }
    };
@@ -1673,12 +1654,10 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
        private final ShadeController mShadeController;
        private final NotificationRemoteInputManager mNotificationRemoteInputManager;
        private final NotificationShadeDepthController mNotificationShadeDepthController;
        private final SystemActions mSystemActions;
        private final Handler mMainHandler;
        private final NavigationBarOverlayController mNavbarOverlayController;
        private final UiEventLogger mUiEventLogger;
        private final NavBarHelper mNavBarHelper;
        private final UserTracker mUserTracker;
        private final LightBarController mMainLightBarController;
        private final LightBarController.Factory mLightBarControllerFactory;
        private final AutoHideController mMainAutoHideController;
@@ -1707,12 +1686,10 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
                ShadeController shadeController,
                NotificationRemoteInputManager notificationRemoteInputManager,
                NotificationShadeDepthController notificationShadeDepthController,
                SystemActions systemActions,
                @Main Handler mainHandler,
                NavigationBarOverlayController navbarOverlayController,
                UiEventLogger uiEventLogger,
                NavBarHelper navBarHelper,
                UserTracker userTracker,
                LightBarController mainLightBarController,
                LightBarController.Factory lightBarControllerFactory,
                AutoHideController mainAutoHideController,
@@ -1738,12 +1715,10 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
            mShadeController = shadeController;
            mNotificationRemoteInputManager = notificationRemoteInputManager;
            mNotificationShadeDepthController = notificationShadeDepthController;
            mSystemActions = systemActions;
            mMainHandler = mainHandler;
            mNavbarOverlayController = navbarOverlayController;
            mUiEventLogger = uiEventLogger;
            mNavBarHelper = navBarHelper;
            mUserTracker = userTracker;
            mMainLightBarController = mainLightBarController;
            mLightBarControllerFactory = lightBarControllerFactory;
            mMainAutoHideController = mainAutoHideController;
@@ -1763,9 +1738,9 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
                    mSysUiFlagsContainer, mBroadcastDispatcher, mCommandQueue, mPipOptional,
                    mSplitScreenOptional, mRecentsOptional, mStatusBarOptionalLazy,
                    mShadeController, mNotificationRemoteInputManager,
                    mNotificationShadeDepthController, mSystemActions, mMainHandler,
                    mNotificationShadeDepthController, mMainHandler,
                    mNavbarOverlayController, mUiEventLogger, mNavBarHelper,
                    mUserTracker, mMainLightBarController, mLightBarControllerFactory,
                    mMainLightBarController, mLightBarControllerFactory,
                    mMainAutoHideController, mAutoHideControllerFactory, mTelecomManagerOptional,
                    mInputMethodManager, mBackAnimation);
        }
+1 −1
Original line number Diff line number Diff line
@@ -685,7 +685,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
        }

        if (navBarFragment != null) {
            navBarFragment.updateSystemUiStateFlags(-1);
            navBarFragment.updateSystemUiStateFlags();
        }
        if (navBarView != null) {
            navBarView.updateDisabledSystemUiStateFlags();
+9 −4
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ import androidx.test.runner.AndroidJUnit4;

import com.android.systemui.SysuiTestCase;
import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
import com.android.systemui.accessibility.SystemActions;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.recents.OverviewProxyService;
@@ -55,10 +57,12 @@ public class NavBarHelperTest extends SysuiTestCase {
    @Mock
    AccessibilityManager mAccessibilityManager;
    @Mock
    AccessibilityManagerWrapper mAccessibilityManagerWrapper;
    @Mock
    AccessibilityButtonModeObserver mAccessibilityButtonModeObserver;
    @Mock
    AccessibilityButtonTargetsObserver mAccessibilityButtonTargetObserver;
    @Mock
    SystemActions mSystemActions;
    @Mock
    OverviewProxyService mOverviewProxyService;
    @Mock
    Lazy<AssistManager> mAssistManagerLazy;
@@ -85,8 +89,9 @@ public class NavBarHelperTest extends SysuiTestCase {
        when(mUserTracker.getUserId()).thenReturn(1);

        mNavBarHelper = new NavBarHelper(mContext, mAccessibilityManager,
                mAccessibilityManagerWrapper, mAccessibilityButtonModeObserver,
                mOverviewProxyService, mAssistManagerLazy, () -> Optional.of(mock(StatusBar.class)),
                mAccessibilityButtonModeObserver, mAccessibilityButtonTargetObserver,
                mSystemActions, mOverviewProxyService, mAssistManagerLazy,
                () -> Optional.of(mock(StatusBar.class)),
                mNavigationModeController, mUserTracker, mDumpManager);

    }
+7 −5
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import com.android.internal.logging.UiEventLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestableContext;
import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
import com.android.systemui.accessibility.SystemActions;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -121,6 +122,8 @@ public class NavigationBarTest extends SysuiTestCase {

    private SysuiTestableContext mSysuiTestableContextExternal;
    @Mock
    private SystemActions mSystemActions;
    @Mock
    private OverviewProxyService mOverviewProxyService;
    @Mock
    private StatusBarStateController mStatusBarStateController;
@@ -183,8 +186,9 @@ public class NavigationBarTest extends SysuiTestCase {
        mDependency.injectTestDependency(NavigationModeController.class, mNavigationModeController);
        TestableLooper.get(this).runWithLooper(() -> {
            mNavBarHelper = spy(new NavBarHelper(mContext, mock(AccessibilityManager.class),
                    mock(AccessibilityManagerWrapper.class),
                    mock(AccessibilityButtonModeObserver.class), mOverviewProxyService,
                    mock(AccessibilityButtonModeObserver.class),
                    mock(AccessibilityButtonTargetsObserver.class),
                    mSystemActions, mOverviewProxyService,
                    () -> mock(AssistManager.class), () -> Optional.of(mStatusBar),
                    mock(NavigationModeController.class), mock(UserTracker.class),
                    mock(DumpManager.class)));
@@ -359,7 +363,7 @@ public class NavigationBarTest extends SysuiTestCase {
                NavBarHelper.NavbarTaskbarStateUpdater.class));

        // Should be safe even though the internal view is now null.
        mNavigationBar.updateAcessibilityStateFlags();
        mNavigationBar.updateAccessibilityStateFlags();
    }

    private NavigationBar createNavBar(Context context) {
@@ -385,12 +389,10 @@ public class NavigationBarTest extends SysuiTestCase {
                mock(ShadeController.class),
                mock(NotificationRemoteInputManager.class),
                mock(NotificationShadeDepthController.class),
                mock(SystemActions.class),
                mHandler,
                mock(NavigationBarOverlayController.class),
                mUiEventLogger,
                mNavBarHelper,
                mock(UserTracker.class),
                mLightBarController,
                mLightBarcontrollerFactory,
                mAutoHideController,