Extract a11y from NavigationBar to share with TaskbarDelegate

When taskbar is showing, navigation bar isn't created which
means all of the a11y registers are never registered.
NavigationBarA11yHelper maintains existing a11y flag logic from
NavigationBar but any class can register with it to get updates.

Bug: 180046394
Test: A11y works as expected on 3 button phone
Right events getting pass through to launcher when on larger
device

Change-Id: I9eeb566fca0e5142b38127aa8f32c21632c33caa
This commit is contained in:
Vinit Nayak
2021-06-07 14:07:47 -07:00
parent 472d4ccab0
commit a9bf9c8312
11 changed files with 223 additions and 123 deletions

View File

@@ -76,25 +76,18 @@ oneway interface IOverviewProxy {
*/
void onSplitScreenSecondaryBoundsChanged(in Rect bounds, in Rect insets) = 17;
/**
* Sent when IME status changes
*/
void onImeWindowStatusChanged(int displayId, IBinder token, int vis, int backDisposition,
boolean showImeSwitcher) = 18;
/**
* Sent when suggested rotation button could be shown
*/
void onRotationProposal(int rotation, boolean isValid) = 19;
void onRotationProposal(int rotation, boolean isValid) = 18;
/**
* Sent when disable flags change
*/
void disable(int displayId, int state1, int state2, boolean animate) = 20;
void disable(int displayId, int state1, int state2, boolean animate) = 19;
/**
* Sent when behavior changes. See WindowInsetsController#@Behavior
*/
void onSystemBarAttributesChanged(int displayId, int behavior) = 21;
void onSystemBarAttributesChanged(int displayId, int behavior) = 20;
}

View File

@@ -16,11 +16,14 @@
package com.android.systemui.shared.recents.utilities;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
import android.graphics.Color;
import android.inputmethodservice.InputMethodService;
import android.os.Handler;
import android.os.Message;
import android.view.Surface;
import android.view.View;
/* Common code */
public class Utilities {
@@ -77,4 +80,34 @@ public class Utilities {
public static float clamp(float value, float min, float max) {
return Math.max(min, Math.min(max, value));
}
/**
* @return updated set of flags from InputMethodService based off {@param oldHints}
* Leaves original hints unmodified
*/
public static int calculateBackDispositionHints(int oldHints, int backDisposition,
boolean imeShown, boolean showImeSwitcher) {
int hints = oldHints;
switch (backDisposition) {
case InputMethodService.BACK_DISPOSITION_DEFAULT:
case InputMethodService.BACK_DISPOSITION_WILL_NOT_DISMISS:
case InputMethodService.BACK_DISPOSITION_WILL_DISMISS:
if (imeShown) {
hints |= NAVIGATION_HINT_BACK_ALT;
} else {
hints &= ~NAVIGATION_HINT_BACK_ALT;
}
break;
case InputMethodService.BACK_DISPOSITION_ADJUST_NOTHING:
hints &= ~NAVIGATION_HINT_BACK_ALT;
break;
}
if (showImeSwitcher) {
hints |= NAVIGATION_HINT_IME_SHOWN;
} else {
hints &= ~NAVIGATION_HINT_IME_SHOWN;
}
return hints;
}
}

View File

@@ -112,6 +112,8 @@ public class QuickStepContract {
public static final int SYSUI_STATE_IME_SHOWING = 1 << 18;
// The window magnification is overlapped with system gesture insets at the bottom.
public static final int SYSUI_STATE_MAGNIFICATION_OVERLAP = 1 << 19;
// ImeSwitcher is showing
public static final int SYSUI_STATE_IME_SWITCHER_SHOWING = 1 << 20;
@Retention(RetentionPolicy.SOURCE)
@IntDef({SYSUI_STATE_SCREEN_PINNING,
@@ -133,7 +135,8 @@ public class QuickStepContract {
SYSUI_STATE_ONE_HANDED_ACTIVE,
SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY,
SYSUI_STATE_IME_SHOWING,
SYSUI_STATE_MAGNIFICATION_OVERLAP
SYSUI_STATE_MAGNIFICATION_OVERLAP,
SYSUI_STATE_IME_SWITCHER_SHOWING
})
public @interface SystemUiStateFlags {}
@@ -162,6 +165,7 @@ public class QuickStepContract {
? "allow_gesture" : "");
str.add((flags & SYSUI_STATE_IME_SHOWING) != 0 ? "ime_visible" : "");
str.add((flags & SYSUI_STATE_MAGNIFICATION_OVERLAP) != 0 ? "magnification_overlap" : "");
str.add((flags & SYSUI_STATE_IME_SWITCHER_SHOWING) != 0 ? "ime_switcher_showing" : "");
return str.toString();
}

View File

@@ -60,6 +60,7 @@ import com.android.systemui.doze.AlwaysOnDisplayPolicy;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.model.SysUiState;
import com.android.systemui.navigationbar.NavigationBarA11yHelper;
import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.navigationbar.NavigationBarOverlayController;
import com.android.systemui.navigationbar.NavigationModeController;
@@ -231,7 +232,8 @@ public class DependencyProvider {
@Main Handler mainHandler,
UiEventLogger uiEventLogger,
NavigationBarOverlayController navBarOverlayController,
ConfigurationController configurationController) {
ConfigurationController configurationController,
NavigationBarA11yHelper navigationBarA11yHelper) {
return new NavigationBarController(context,
windowManager,
assistManagerLazy,
@@ -256,7 +258,8 @@ public class DependencyProvider {
mainHandler,
uiEventLogger,
navBarOverlayController,
configurationController);
configurationController,
navigationBarA11yHelper);
}
/** */

View File

@@ -44,6 +44,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
@@ -54,9 +55,7 @@ import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode
import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_WINDOW_STATE;
import static com.android.systemui.statusbar.phone.StatusBar.dumpBarTransitions;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.annotation.IdRes;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
@@ -101,7 +100,6 @@ import android.view.WindowInsetsController.Behavior;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
import android.view.inputmethod.InputMethodManager;
import androidx.annotation.VisibleForTesting;
@@ -129,6 +127,7 @@ import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.AutoHideUiElement;
@@ -149,7 +148,6 @@ import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
import com.android.wm.shell.pip.Pip;
import java.io.PrintWriter;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.function.Consumer;
@@ -160,8 +158,7 @@ import dagger.Lazy;
* Contains logic for a navigation bar view.
*/
public class NavigationBar implements View.OnAttachStateChangeListener,
Callbacks, NavigationModeController.ModeChangedListener,
AccessibilityButtonModeObserver.ModeChangedListener {
Callbacks, NavigationModeController.ModeChangedListener {
public static final String TAG = "NavigationBar";
private static final boolean DEBUG = false;
@@ -178,7 +175,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
private final Context mContext;
private final WindowManager mWindowManager;
private final AccessibilityManager mAccessibilityManager;
private final AccessibilityManagerWrapper mAccessibilityManagerWrapper;
private final DeviceProvisionedController mDeviceProvisionedController;
private final StatusBarStateController mStatusBarStateController;
private final MetricsLogger mMetricsLogger;
@@ -199,6 +195,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
private final Handler mHandler;
private final NavigationBarOverlayController mNavbarOverlayController;
private final UiEventLogger mUiEventLogger;
private final NavigationBarA11yHelper mNavigationBarA11yHelper;
private Bundle mSavedState;
private NavigationBarView mNavigationBarView;
@@ -232,7 +229,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
private boolean mTransientShown;
private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
private int mA11yBtnMode;
private LightBarController mLightBarController;
private AutoHideController mAutoHideController;
@@ -459,11 +455,11 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
SystemActions systemActions,
@Main Handler mainHandler,
NavigationBarOverlayController navbarOverlayController,
UiEventLogger uiEventLogger) {
UiEventLogger uiEventLogger,
NavigationBarA11yHelper navigationBarA11yHelper) {
mContext = context;
mWindowManager = windowManager;
mAccessibilityManager = accessibilityManager;
mAccessibilityManagerWrapper = accessibilityManagerWrapper;
mDeviceProvisionedController = deviceProvisionedController;
mStatusBarStateController = statusBarStateController;
mMetricsLogger = metricsLogger;
@@ -484,10 +480,8 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mHandler = mainHandler;
mNavbarOverlayController = navbarOverlayController;
mUiEventLogger = uiEventLogger;
mNavigationBarA11yHelper = navigationBarA11yHelper;
mNavBarMode = mNavigationModeController.addListener(this);
mAccessibilityButtonModeObserver.addListener(this);
mA11yBtnMode = mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode();
}
public NavigationBarView getView() {
@@ -578,9 +572,8 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mContext.getSystemService(WindowManager.class).removeViewImmediate(
mNavigationBarView.getRootView());
mNavigationModeController.removeListener(this);
mAccessibilityButtonModeObserver.removeListener(this);
mAccessibilityManagerWrapper.removeCallback(mAccessibilityListener);
mNavigationBarA11yHelper.removeA11yEventListener(mAccessibilityListener);
mContentResolver.unregisterContentObserver(mAssistContentObserver);
mDeviceProvisionedController.removeCallback(mUserSetupListener);
@@ -601,7 +594,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mNavigationBarView.setWindowVisible(isNavBarWindowVisible());
mNavigationBarView.setBehavior(mBehavior);
mAccessibilityManagerWrapper.addCallback(mAccessibilityListener);
mNavigationBarA11yHelper.registerA11yEventListener(mAccessibilityListener);
mSplitScreenOptional.ifPresent(mNavigationBarView::registerDockedListener);
mPipOptional.ifPresent(mNavigationBarView::registerPipExclusionBoundsChangeListener);
@@ -861,26 +854,8 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
return;
}
boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
int hints = mNavigationIconHints;
switch (backDisposition) {
case InputMethodService.BACK_DISPOSITION_DEFAULT:
case InputMethodService.BACK_DISPOSITION_WILL_NOT_DISMISS:
case InputMethodService.BACK_DISPOSITION_WILL_DISMISS:
if (imeShown) {
hints |= NAVIGATION_HINT_BACK_ALT;
} else {
hints &= ~NAVIGATION_HINT_BACK_ALT;
}
break;
case InputMethodService.BACK_DISPOSITION_ADJUST_NOTHING:
hints &= ~NAVIGATION_HINT_BACK_ALT;
break;
}
if (showImeSwitcher) {
hints |= NAVIGATION_HINT_IME_SHOWN;
} else {
hints &= ~NAVIGATION_HINT_IME_SHOWN;
}
int hints = Utilities.calculateBackDispositionHints(mNavigationIconHints, backDisposition,
imeShown, showImeSwitcher);
if (hints == mNavigationIconHints) return;
mNavigationIconHints = hints;
@@ -1140,7 +1115,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton();
accessibilityButton.setOnClickListener(this::onAccessibilityClick);
accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
updateAccessibilityServicesState(mAccessibilityManager);
updateAccessibilityServicesState();
ButtonDispatcher imeSwitcherButton = mNavigationBarView.getImeSwitchButton();
imeSwitcherButton.setOnClickListener(this::onImeSwitcherClick);
@@ -1361,9 +1336,8 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
return true;
}
void updateAccessibilityServicesState(AccessibilityManager accessibilityManager) {
boolean[] feedbackEnabled = new boolean[1];
int a11yFlags = getA11yButtonState(feedbackEnabled);
void updateAccessibilityServicesState() {
int a11yFlags = mNavigationBarA11yHelper.getA11yButtonState();
boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
@@ -1381,7 +1355,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
public void updateSystemUiStateFlags(int a11yFlags) {
if (a11yFlags < 0) {
a11yFlags = getA11yButtonState(null);
a11yFlags = mNavigationBarA11yHelper.getA11yButtonState();
}
boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
@@ -1391,6 +1365,8 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
.setFlag(SYSUI_STATE_NAV_BAR_HIDDEN, !isNavBarWindowVisible())
.setFlag(SYSUI_STATE_IME_SHOWING,
(mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0)
.setFlag(SYSUI_STATE_IME_SWITCHER_SHOWING,
(mNavigationIconHints & NAVIGATION_HINT_IME_SHOWN) != 0)
.setFlag(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY,
allowSystemGestureIgnoringBarVisibility())
.commitUpdate(mDisplayId);
@@ -1406,44 +1382,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
}
}
/**
* Returns the system UI flags corresponding the the current accessibility button state
*
* @param outFeedbackEnabled if non-null, sets it to true if accessibility feedback is enabled.
*/
public int getA11yButtonState(@Nullable boolean[] outFeedbackEnabled) {
boolean feedbackEnabled = false;
// AccessibilityManagerService resolves services for the current user since the local
// AccessibilityManager is created from a Context with the INTERACT_ACROSS_USERS permission
final List<AccessibilityServiceInfo> services =
mAccessibilityManager.getEnabledAccessibilityServiceList(
AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
final List<String> a11yButtonTargets =
mAccessibilityManager.getAccessibilityShortcutTargets(
AccessibilityManager.ACCESSIBILITY_BUTTON);
final int requestingServices = a11yButtonTargets.size();
for (int i = services.size() - 1; i >= 0; --i) {
AccessibilityServiceInfo info = services.get(i);
if (info.feedbackType != 0 && info.feedbackType !=
AccessibilityServiceInfo.FEEDBACK_GENERIC) {
feedbackEnabled = true;
}
}
if (outFeedbackEnabled != null) {
outFeedbackEnabled[0] = feedbackEnabled;
}
// If accessibility button is floating menu mode, click and long click state should be
// disabled.
if (mA11yBtnMode == ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU) {
return 0;
}
return (requestingServices >= 1 ? SYSUI_STATE_A11Y_BUTTON_CLICKABLE : 0)
| (requestingServices >= 2 ? SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE : 0);
}
private void updateAssistantEntrypoints() {
mAssistantAvailable = mAssistManagerLazy.get()
.getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
@@ -1539,12 +1477,6 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
}
}
@Override
public void onAccessibilityButtonModeChanged(int mode) {
mA11yBtnMode = mode;
updateAccessibilityServicesState(mAccessibilityManager);
}
public void disableAnimationsDuringHide(long delay) {
mNavigationBarView.setLayoutTransitionsEnabled(false);
mHandler.postDelayed(mEnableLayoutTransitions,
@@ -1569,7 +1501,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mNavigationBarView.getBarTransitions().finishAnimations();
}
private final AccessibilityServicesStateChangeListener mAccessibilityListener =
private final NavigationBarA11yHelper.NavA11yEventListener mAccessibilityListener =
this::updateAccessibilityServicesState;
private boolean canShowSecondaryHandle() {
@@ -1600,7 +1532,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
}
if (Intent.ACTION_USER_SWITCHED.equals(action)) {
// The accessibility settings may be different for the new user
updateAccessibilityServicesState(mAccessibilityManager);
updateAccessibilityServicesState();
}
}
};

View File

@@ -0,0 +1,89 @@
package com.android.systemui.navigationbar;
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
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;
import android.view.accessibility.AccessibilityManager;
import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
/**
* Extracts shared elements of a11y necessary between navbar and taskbar delegate
*/
@SysUISingleton
public final class NavigationBarA11yHelper implements
AccessibilityButtonModeObserver.ModeChangedListener {
private int mA11yBtnMode;
private final AccessibilityManager mAccessibilityManager;
private final List<NavA11yEventListener> mA11yEventListeners = new ArrayList<>();
@Inject
public NavigationBarA11yHelper(AccessibilityManager accessibilityManager,
AccessibilityManagerWrapper accessibilityManagerWrapper,
AccessibilityButtonModeObserver accessibilityButtonModeObserver) {
mAccessibilityManager = accessibilityManager;
mA11yBtnMode = accessibilityButtonModeObserver.getCurrentAccessibilityButtonMode();
accessibilityManagerWrapper.addCallback(
accessibilityManager1 -> NavigationBarA11yHelper.this.dispatchEventUpdate());
accessibilityButtonModeObserver.addListener(this);
}
public void registerA11yEventListener(NavA11yEventListener listener) {
mA11yEventListeners.add(listener);
}
public void removeA11yEventListener(NavA11yEventListener listener) {
mA11yEventListeners.remove(listener);
}
private void dispatchEventUpdate() {
for (NavA11yEventListener listener : mA11yEventListeners) {
listener.updateAccessibilityServicesState();
}
}
@Override
public void onAccessibilityButtonModeChanged(int mode) {
mA11yBtnMode = mode;
dispatchEventUpdate();
}
/**
* 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() {
// AccessibilityManagerService resolves services for the current user since the local
// 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 (mA11yBtnMode == ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU) {
return 0;
}
return (requestingServices >= 1 ? SYSUI_STATE_A11Y_BUTTON_CLICKABLE : 0)
| (requestingServices >= 2 ? SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE : 0);
}
public interface NavA11yEventListener {
void updateAccessibilityServicesState();
}
}

View File

@@ -111,6 +111,7 @@ public class NavigationBarController implements Callbacks,
private final SystemActions mSystemActions;
private final UiEventLogger mUiEventLogger;
private final Handler mHandler;
private final NavigationBarA11yHelper mNavigationBarA11yHelper;
private final DisplayManager mDisplayManager;
private final NavigationBarOverlayController mNavBarOverlayController;
private final TaskbarDelegate mTaskbarDelegate;
@@ -151,7 +152,8 @@ public class NavigationBarController implements Callbacks,
@Main Handler mainHandler,
UiEventLogger uiEventLogger,
NavigationBarOverlayController navBarOverlayController,
ConfigurationController configurationController) {
ConfigurationController configurationController,
NavigationBarA11yHelper navigationBarA11yHelper) {
mContext = context;
mWindowManager = windowManager;
mAssistManagerLazy = assistManagerLazy;
@@ -175,6 +177,7 @@ public class NavigationBarController implements Callbacks,
mSystemActions = systemActions;
mUiEventLogger = uiEventLogger;
mHandler = mainHandler;
mNavigationBarA11yHelper = navigationBarA11yHelper;
mDisplayManager = mContext.getSystemService(DisplayManager.class);
commandQueue.addCallback(this);
configurationController.addCallback(this);
@@ -182,7 +185,8 @@ public class NavigationBarController implements Callbacks,
mNavBarOverlayController = navBarOverlayController;
mNavMode = mNavigationModeController.addListener(this);
mNavigationModeController.addListener(this);
mTaskbarDelegate = new TaskbarDelegate(mOverviewProxyService);
mTaskbarDelegate = new TaskbarDelegate(mOverviewProxyService,
navigationBarA11yHelper, mSysUiFlagsContainer);
mIsTablet = isTablet(mContext.getResources().getConfiguration());
}
@@ -241,10 +245,12 @@ public class NavigationBarController implements Callbacks,
// Remove navigation bar when taskbar is showing, currently only for 3 button mode
removeNavigationBar(mContext.getDisplayId());
mCommandQueue.addCallback(mTaskbarDelegate);
mTaskbarDelegate.init(mContext.getDisplayId());
} else if (mNavigationBars.get(mContext.getDisplayId()) == null) {
// Add navigation bar after taskbar goes away
createNavigationBar(mContext.getDisplay(), null, null);
mCommandQueue.removeCallback(mTaskbarDelegate);
mTaskbarDelegate.destroy();
}
return true;
@@ -361,7 +367,8 @@ public class NavigationBarController implements Callbacks,
mSystemActions,
mHandler,
mNavBarOverlayController,
mUiEventLogger);
mUiEventLogger,
mNavigationBarA11yHelper);
mNavigationBars.put(displayId, navBar);
View navigationBarView = navBar.createView(savedState);

View File

@@ -16,25 +16,76 @@
package com.android.systemui.navigationbar;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
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;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
import android.inputmethodservice.InputMethodService;
import android.os.IBinder;
import com.android.internal.view.AppearanceRegion;
import com.android.systemui.model.SysUiState;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.statusbar.CommandQueue;
public class TaskbarDelegate implements CommandQueue.Callbacks {
private final OverviewProxyService mOverviewProxyService;
private final NavigationBarA11yHelper mNavigationBarA11yHelper;
private final SysUiState mSysUiState;
private int mDisplayId;
private int mNavigationIconHints;
private final NavigationBarA11yHelper.NavA11yEventListener mNavA11yEventListener =
this::updateSysuiFlags;
public TaskbarDelegate(OverviewProxyService overviewProxyService) {
public TaskbarDelegate(OverviewProxyService overviewProxyService,
NavigationBarA11yHelper navigationBarA11yHelper,
SysUiState sysUiState) {
mOverviewProxyService = overviewProxyService;
mNavigationBarA11yHelper = navigationBarA11yHelper;
mSysUiState = sysUiState;
}
public void destroy() {
mNavigationBarA11yHelper.removeA11yEventListener(mNavA11yEventListener);
}
public void init(int displayId) {
mDisplayId = displayId;
mNavigationBarA11yHelper.registerA11yEventListener(mNavA11yEventListener);
// Set initial state for any listeners
updateSysuiFlags();
}
private void updateSysuiFlags() {
int a11yFlags = mNavigationBarA11yHelper.getA11yButtonState();
boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
mSysUiState.setFlag(SYSUI_STATE_A11Y_BUTTON_CLICKABLE, clickable)
.setFlag(SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE, longClickable)
.setFlag(SYSUI_STATE_IME_SHOWING,
(mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0)
.setFlag(SYSUI_STATE_IME_SWITCHER_SHOWING,
(mNavigationIconHints & NAVIGATION_HINT_IME_SHOWN) != 0)
.commitUpdate(mDisplayId);
}
@Override
public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
boolean showImeSwitcher) {
mOverviewProxyService.notifyImeWindowStatus(displayId, token, vis, backDisposition,
showImeSwitcher);
boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
int hints = Utilities.calculateBackDispositionHints(mNavigationIconHints, backDisposition,
imeShown, showImeSwitcher);
if (hints != mNavigationIconHints) {
mNavigationIconHints = hints;
updateSysuiFlags();
}
}
@Override

View File

@@ -974,20 +974,6 @@ public class OverviewProxyService extends CurrentUserTracker implements
}
}
public void notifyImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
boolean showImeSwitcher) {
try {
if (mOverviewProxy != null) {
mOverviewProxy.onImeWindowStatusChanged(displayId, token, vis, backDisposition,
showImeSwitcher);
} else {
Log.e(TAG_OPS, "Failed to get overview proxy for setting IME status.");
}
} catch (RemoteException e) {
Log.e(TAG_OPS, "Failed to call notifyImeWindowStatus()", e);
}
}
public void onRotationProposal(int rotation, boolean isValid) {
try {
if (mOverviewProxy != null) {

View File

@@ -108,7 +108,8 @@ public class NavigationBarControllerTest extends SysuiTestCase {
Dependency.get(Dependency.MAIN_HANDLER),
mock(UiEventLogger.class),
mock(NavigationBarOverlayController.class),
mock(ConfigurationController.class)));
mock(ConfigurationController.class),
mock(NavigationBarA11yHelper.class)));
initializeNavigationBars();
}

View File

@@ -276,7 +276,8 @@ public class NavigationBarTest extends SysuiTestCase {
mock(SystemActions.class),
mHandler,
mock(NavigationBarOverlayController.class),
mUiEventLogger));
mUiEventLogger,
mock(NavigationBarA11yHelper.class)));
}
private void processAllMessages() {