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

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

Merge "Add a11y voice access keyboard shortcut" into main

parents 23861847 8fbb84d4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ public final class KeyGestureEvent {
    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT = 79;
    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP = 80;
    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN = 81;
    public static final int KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS = 82;

    public static final int FLAG_CANCELLED = 1;

@@ -225,6 +226,7 @@ public final class KeyGestureEvent {
            KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT,
            KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP,
            KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN,
            KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface KeyGestureType {
@@ -807,6 +809,8 @@ public final class KeyGestureEvent {
                return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP";
            case KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN:
                return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN";
            case KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS:
                return "KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS";
            default:
                return Integer.toHexString(value);
        }
+21 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Build;
import android.os.UserHandle;
import android.provider.Settings;
@@ -351,4 +352,24 @@ public final class AccessibilityUtils {
        }
        return result;
    }

    /** Returns the {@link ComponentName} of an installed accessibility service by label. */
    @Nullable
    public static ComponentName getInstalledAccessibilityServiceComponentNameByLabel(
            Context context, String label) {
        AccessibilityManager accessibilityManager =
                context.getSystemService(AccessibilityManager.class);
        List<AccessibilityServiceInfo> serviceInfos =
                accessibilityManager.getInstalledAccessibilityServiceList();

        for (AccessibilityServiceInfo service : serviceInfos) {
            final ServiceInfo serviceInfo = service.getResolveInfo().serviceInfo;
            if (label.equals(serviceInfo.loadLabel(context.getPackageManager()).toString())
                    && (serviceInfo.applicationInfo.isSystemApp()
                            || serviceInfo.applicationInfo.isUpdatedSystemApp())) {
                return new ComponentName(serviceInfo.packageName, serviceInfo.name);
            }
        }
        return null;
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.input;
import static android.hardware.input.InputGestureData.createKeyTrigger;

import static com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures;
import static com.android.hardware.input.Flags.enableVoiceAccessKeyGestures;
import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
import static com.android.server.flags.Flags.newBugreportKeyboardShortcut;
import static com.android.window.flags.Flags.enableMoveToNextDisplayShortcut;
@@ -240,6 +241,13 @@ final class InputGestureManager {
                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
                    KeyGestureEvent.KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK));
        }
        if (enableVoiceAccessKeyGestures()) {
            systemShortcuts.add(
                    createKeyGesture(
                            KeyEvent.KEYCODE_V,
                            KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
                            KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS));
        }
        if (enableTaskResizingKeyboardShortcuts()) {
            systemShortcuts.add(createKeyGesture(
                    KeyEvent.KEYCODE_LEFT_BRACKET,
+19 −1
Original line number Diff line number Diff line
@@ -85,15 +85,16 @@ import static android.view.contentprotection.flags.Flags.createAccessibilityOver

import static com.android.hardware.input.Flags.enableNew25q2Keycodes;
import static com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures;
import static com.android.hardware.input.Flags.enableVoiceAccessKeyGestures;
import static com.android.hardware.input.Flags.inputManagerLifecycleSupport;
import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
import static com.android.hardware.input.Flags.modifierShortcutDump;
import static com.android.hardware.input.Flags.overridePowerKeyBehaviorInFocusedWindow;
import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_KEYCHORD_DELAY;
import static com.android.server.GestureLauncherService.DOUBLE_POWER_TAP_COUNT_THRESHOLD;
import static com.android.server.flags.Flags.modifierShortcutManagerMultiuser;
import static com.android.server.flags.Flags.newBugreportKeyboardShortcut;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_KEYCHORD_DELAY;
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;
@@ -502,6 +503,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    private TalkbackShortcutController mTalkbackShortcutController;

    private VoiceAccessShortcutController mVoiceAccessShortcutController;

    private WindowWakeUpPolicy mWindowWakeUpPolicy;

    /**
@@ -2265,6 +2268,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            return new TalkbackShortcutController(mContext);
        }

        VoiceAccessShortcutController getVoiceAccessShortcutController() {
            return new VoiceAccessShortcutController(mContext);
        }

        WindowWakeUpPolicy getWindowWakeUpPolicy() {
            return new WindowWakeUpPolicy(mContext);
        }
@@ -2512,6 +2519,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                com.android.internal.R.integer.config_keyguardDrawnTimeout);
        mKeyguardDelegate = injector.getKeyguardServiceDelegate();
        mTalkbackShortcutController = injector.getTalkbackShortcutController();
        mVoiceAccessShortcutController = injector.getVoiceAccessShortcutController();
        mWindowWakeUpPolicy = injector.getWindowWakeUpPolicy();
        initKeyCombinationRules();
        initSingleKeyGestureRules(injector.getLooper());
@@ -4262,6 +4270,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                                .isAccessibilityShortcutAvailable(false);
                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
                        return enableTalkbackAndMagnifierKeyGestures();
                    case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS:
                        return enableVoiceAccessKeyGestures();
                    default:
                        return false;
                }
@@ -4492,6 +4502,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    return true;
                }
                break;
            case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS:
                if (enableVoiceAccessKeyGestures()) {
                    if (complete) {
                        mVoiceAccessShortcutController.toggleVoiceAccess(mCurrentUserId);
                    }
                    return true;
                }
                break;
            case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION:
                AppLaunchData data = event.getAppLaunchData();
                if (complete && canLaunchApp && data != null
+4 −28
Original line number Diff line number Diff line
@@ -18,20 +18,15 @@ package com.android.server.policy;

import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_WEAR_TRIPLE_PRESS_GESTURE;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.os.UserHandle;
import android.provider.Settings;
import android.view.accessibility.AccessibilityManager;

import com.android.internal.accessibility.util.AccessibilityStatsLogUtils;
import com.android.internal.accessibility.util.AccessibilityUtils;
import com.android.internal.annotations.VisibleForTesting;

import java.util.List;
import java.util.Set;

/**
@@ -42,7 +37,6 @@ import java.util.Set;
class TalkbackShortcutController {
    private static final String TALKBACK_LABEL = "TalkBack";
    private final Context mContext;
    private final PackageManager mPackageManager;

    public enum ShortcutSource {
        GESTURE,
@@ -51,7 +45,6 @@ class TalkbackShortcutController {

    TalkbackShortcutController(Context context) {
        mContext = context;
        mPackageManager = mContext.getPackageManager();
    }

    /**
@@ -63,7 +56,10 @@ class TalkbackShortcutController {
    boolean toggleTalkback(int userId, ShortcutSource source) {
        final Set<ComponentName> enabledServices =
                AccessibilityUtils.getEnabledServicesFromSettings(mContext, userId);
        ComponentName componentName = getTalkbackComponent();
        ComponentName componentName =
                AccessibilityUtils.getInstalledAccessibilityServiceComponentNameByLabel(
                        mContext, TALKBACK_LABEL);
        ;
        if (componentName == null) {
            return false;
        }
@@ -83,21 +79,6 @@ class TalkbackShortcutController {
        return isTalkbackAlreadyEnabled;
    }

    private ComponentName getTalkbackComponent() {
        AccessibilityManager accessibilityManager = mContext.getSystemService(
                AccessibilityManager.class);
        List<AccessibilityServiceInfo> serviceInfos =
                accessibilityManager.getInstalledAccessibilityServiceList();

        for (AccessibilityServiceInfo service : serviceInfos) {
            final ServiceInfo serviceInfo = service.getResolveInfo().serviceInfo;
            if (isTalkback(serviceInfo)) {
                return new ComponentName(serviceInfo.packageName, serviceInfo.name);
            }
        }
        return null;
    }

    boolean isTalkBackShortcutGestureEnabled() {
        return Settings.System.getIntForUser(mContext.getContentResolver(),
                Settings.System.WEAR_ACCESSIBILITY_GESTURE_ENABLED,
@@ -120,9 +101,4 @@ class TalkbackShortcutController {
                ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_WEAR_TRIPLE_PRESS_GESTURE,
                /* serviceEnabled= */ true);
    }

    private boolean isTalkback(ServiceInfo info) {
        return TALKBACK_LABEL.equals(info.loadLabel(mPackageManager).toString())
            && (info.applicationInfo.isSystemApp() || info.applicationInfo.isUpdatedSystemApp());
    }
}
Loading