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

Commit 6c9e8790 authored by Wenyu Zhang's avatar Wenyu Zhang Committed by Android (Google) Code Review
Browse files

Merge changes from topic "refactor-talkback-shortcut" into main

* changes:
  a11y: Handle screen reader keyboard shortcut in A11yManagerService
  a11y: Remove TalkBack keyboard shortcut handling from PhoneWindowManager
parents aa8330a5 bb99a9c0
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -659,6 +659,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        if (enableTalkbackAndMagnifierKeyGestures()) {
            supportedGestures.add(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION);
            supportedGestures.add(KeyGestureEvent.KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK);
            supportedGestures.add(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK);
        }
        if (enableVoiceAccessKeyGestures()) {
            supportedGestures.add(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS);
@@ -719,6 +720,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
                    R.string.config_defaultSelectToSpeakService);
            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS -> mContext.getString(
                    R.string.config_defaultVoiceAccessService);
            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK -> mContext.getString(
                    R.string.config_defaultAccessibilityService);
            default -> "";
        };
    }
@@ -740,6 +743,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
                break;
            case KeyGestureEvent.KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK:
            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS:
            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
                targetName = getTargetNameFromKeyGestureType(gestureType);
                if (targetName.isEmpty()) {
                    return;
@@ -4390,10 +4394,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
            if(!enableTalkbackAndMagnifierKeyGestures() &&
                    (shortcutTargets.contains(MAGNIFICATION_CONTROLLER_NAME) ||
                            shortcutTargets.contains(mContext.getString(
                                    R.string.config_defaultSelectToSpeakService)))) {
                                    R.string.config_defaultSelectToSpeakService)) ||
                            shortcutTargets.contains(mContext.getString(
                                    R.string.config_defaultAccessibilityService)))) {
                Slog.w(LOG_TAG,
                        "KEY_GESTURE type magnification and select to speak shortcuts are "
                                + "disabled by feature flag");
                        "KEY_GESTURE type magnification, select to speak and TalkBack shortcuts"
                                + "are disabled by feature flag");
                return;
            }
            if (!enableVoiceAccessKeyGestures() && shortcutTargets.contains(mContext.getString(
+1 −12
Original line number Diff line number Diff line
@@ -79,7 +79,6 @@ import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED;
import static android.view.contentprotection.flags.Flags.createAccessibilityOverlayAppOpEnabled;

import static com.android.hardware.input.Flags.enableNew25q2Keycodes;
import static com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED;
@@ -1654,8 +1653,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            case TRIPLE_PRESS_PRIMARY_NOTHING:
                break;
            case TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY:
                mTalkbackShortcutController.toggleTalkback(mCurrentUserId,
                        TalkbackShortcutController.ShortcutSource.GESTURE);
                mTalkbackShortcutController.toggleTalkback(mCurrentUserId);
                if (mTalkbackShortcutController.isTalkBackShortcutGestureEnabled()) {
                    performHapticFeedback(HapticFeedbackConstants.CONFIRM,
                            "Stem primary - Triple Press - Toggle Accessibility");
@@ -3360,9 +3358,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        if (!delegateBackGestureToShell()) {
            supportedGestures.add(KeyGestureEvent.KEY_GESTURE_TYPE_BACK);
        }
        if (enableTalkbackAndMagnifierKeyGestures()) {
            supportedGestures.add(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK);
        }
        if (!com.android.window.flags.Flags.grantManageKeyGesturesToRecents()) {
            // When grantManageKeyGesturesToRecents is enabled, the event is handled in the
            // recents app.
@@ -3549,12 +3544,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    closeSystemDialogsAsUser(UserHandle.CURRENT_OR_SELF);
                }
                break;
            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
                if (complete) {
                    mTalkbackShortcutController.toggleTalkback(mCurrentUserId,
                            TalkbackShortcutController.ShortcutSource.KEYBOARD);
                }
                break;
            case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION:
                AppLaunchData data = event.getAppLaunchData();
                if (complete && canLaunchApp && data != null) {
+3 −8
Original line number Diff line number Diff line
@@ -38,11 +38,6 @@ class TalkbackShortcutController {
    private static final String TALKBACK_LABEL = "TalkBack";
    private final Context mContext;

    public enum ShortcutSource {
        GESTURE,
        KEYBOARD,
    }

    TalkbackShortcutController(Context context) {
        mContext = context;
    }
@@ -53,7 +48,7 @@ class TalkbackShortcutController {
     * @return talkback state after toggle. {@code true} if talkback is enabled, {@code false} if
     * talkback is disabled
     */
    boolean toggleTalkback(int userId, ShortcutSource source) {
    boolean toggleTalkback(int userId) {
        final Set<ComponentName> enabledServices =
                AccessibilityUtils.getEnabledServicesFromSettings(mContext, userId);
        ComponentName componentName =
@@ -66,13 +61,13 @@ class TalkbackShortcutController {

        boolean isTalkbackAlreadyEnabled = enabledServices.contains(componentName);

        if (source == ShortcutSource.KEYBOARD || isTalkBackShortcutGestureEnabled()) {
        if (isTalkBackShortcutGestureEnabled()) {
            isTalkbackAlreadyEnabled = !isTalkbackAlreadyEnabled;
            AccessibilityUtils.setAccessibilityServiceState(mContext, componentName,
                    isTalkbackAlreadyEnabled, userId);

            // log stem triple press telemetry if it's a talkback enabled event.
            if (source == ShortcutSource.GESTURE && isTalkbackAlreadyEnabled) {
            if (isTalkbackAlreadyEnabled) {
                logStemTriplePressAccessibilityTelemetry(componentName);
            }
        }
+30 −0
Original line number Diff line number Diff line
@@ -2294,6 +2294,36 @@ public class AccessibilityManagerServiceTest {
                trustedService.getComponentName().flattenToString());
    }

    @Test
    @EnableFlags(com.android.hardware.input.Flags.FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES)
    public void handleKeyGestureEvent_activateTalkBack_trustedService() {
        setupAccessibilityServiceConnection(FLAG_REQUEST_ACCESSIBILITY_BUTTON);
        mFakePermissionEnforcer.grant(Manifest.permission.MANAGE_ACCESSIBILITY);

        final AccessibilityServiceInfo trustedService = mockAccessibilityServiceInfo(
                new ComponentName("package_a", "class_a"),
                /* isSystemApp= */ true, /* isAlwaysOnService= */ true);
        AccessibilityUserState userState = mA11yms.getCurrentUserState();
        userState.mInstalledServices.add(trustedService);
        mTestableContext.getOrCreateTestableResources().addOverride(
                R.string.config_defaultAccessibilityService,
                trustedService.getComponentName().flattenToString());
        mTestableContext.getOrCreateTestableResources().addOverride(
                R.array.config_trustedAccessibilityServices,
                new String[]{trustedService.getComponentName().flattenToString()});

        assertThat(ShortcutUtils.getShortcutTargetsFromSettings(mTestableContext, KEY_GESTURE,
                mA11yms.getCurrentUserIdLocked())).isEmpty();

        mA11yms.handleKeyGestureEvent(new KeyGestureEvent.Builder().setKeyGestureType(
                KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK).setAction(
                KeyGestureEvent.ACTION_GESTURE_COMPLETE).build());

        assertThat(ShortcutUtils.getShortcutTargetsFromSettings(mTestableContext, KEY_GESTURE,
                mA11yms.getCurrentUserIdLocked())).containsExactly(
                trustedService.getComponentName().flattenToString());
    }

    @Test
    public void displayListReturnsDisplays() {
        mTestDisplayManagerWrapper.mDisplays = createFakeDisplayList(
+0 −9
Original line number Diff line number Diff line
@@ -395,15 +395,6 @@ public class KeyGestureEventTests extends ShortcutKeyTestBase {
        mPhoneWindowManager.assertCloseAllDialogs();
    }

    @Test
    public void testKeyGestureToggleTalkback() {
        sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK);
        mPhoneWindowManager.assertTalkBack(true);

        sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK);
        mPhoneWindowManager.assertTalkBack(false);
    }

    @Test
    public void testKeyGestureToggleDoNotDisturb() {
        mPhoneWindowManager.overrideZenMode(Settings.Global.ZEN_MODE_OFF);
Loading