Merge "Extract a11y from NavigationBar to share with TaskbarDelegate" into sc-v2-dev
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -276,7 +276,8 @@ public class NavigationBarTest extends SysuiTestCase {
|
||||
mock(SystemActions.class),
|
||||
mHandler,
|
||||
mock(NavigationBarOverlayController.class),
|
||||
mUiEventLogger));
|
||||
mUiEventLogger,
|
||||
mock(NavigationBarA11yHelper.class)));
|
||||
}
|
||||
|
||||
private void processAllMessages() {
|
||||
|
||||
Reference in New Issue
Block a user