Merge "Extract a11y from NavigationBar to share with TaskbarDelegate" into sc-v2-dev

This commit is contained in:
Vinit Nayak
2021-06-08 22:07:52 +00:00
committed by Android (Google) Code Review
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;
@@ -1543,12 +1481,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,
@@ -1573,7 +1505,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mNavigationBarView.getBarTransitions().finishAnimations();
}
private final AccessibilityServicesStateChangeListener mAccessibilityListener =
private final NavigationBarA11yHelper.NavA11yEventListener mAccessibilityListener =
this::updateAccessibilityServicesState;
private boolean canShowSecondaryHandle() {
@@ -1604,7 +1536,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() {