Add DPAD keys into Accessibility GlobalAction and SystemAction.

Also add the missing headset hook into SystemAction.

Test: local test.
Bug: 214164075
Change-Id: I8c8ad18990111737722274ca8410cc538b208167
diff --git a/core/api/current.txt b/core/api/current.txt
index e2325b0..efd6788 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -3122,6 +3122,11 @@
     field public static final int GLOBAL_ACTION_ACCESSIBILITY_SHORTCUT = 13; // 0xd
     field public static final int GLOBAL_ACTION_BACK = 1; // 0x1
     field public static final int GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE = 15; // 0xf
+    field public static final int GLOBAL_ACTION_DPAD_CENTER = 20; // 0x14
+    field public static final int GLOBAL_ACTION_DPAD_DOWN = 17; // 0x11
+    field public static final int GLOBAL_ACTION_DPAD_LEFT = 18; // 0x12
+    field public static final int GLOBAL_ACTION_DPAD_RIGHT = 19; // 0x13
+    field public static final int GLOBAL_ACTION_DPAD_UP = 16; // 0x10
     field public static final int GLOBAL_ACTION_HOME = 2; // 0x2
     field public static final int GLOBAL_ACTION_KEYCODE_HEADSETHOOK = 10; // 0xa
     field public static final int GLOBAL_ACTION_LOCK_SCREEN = 8; // 0x8
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 6b0aef8..42d2d28 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -571,6 +571,31 @@
      */
     public static final int GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE = 15;
 
+    /**
+     * Action to trigger dpad up keyevent.
+     */
+    public static final int GLOBAL_ACTION_DPAD_UP = 16;
+
+    /**
+     * Action to trigger dpad down keyevent.
+     */
+    public static final int GLOBAL_ACTION_DPAD_DOWN = 17;
+
+    /**
+     * Action to trigger dpad left keyevent.
+     */
+    public static final int GLOBAL_ACTION_DPAD_LEFT = 18;
+
+    /**
+     * Action to trigger dpad right keyevent.
+     */
+    public static final int GLOBAL_ACTION_DPAD_RIGHT = 19;
+
+    /**
+     * Action to trigger dpad center keyevent.
+     */
+    public static final int GLOBAL_ACTION_DPAD_CENTER = 20;
+
     private static final String LOG_TAG = "AccessibilityService";
 
     /**
@@ -2328,10 +2353,16 @@
      * @param action The action to perform.
      * @return Whether the action was successfully performed.
      *
+     * Perform actions using ids like the id constants referenced below:
      * @see #GLOBAL_ACTION_BACK
      * @see #GLOBAL_ACTION_HOME
      * @see #GLOBAL_ACTION_NOTIFICATIONS
      * @see #GLOBAL_ACTION_RECENTS
+     * @see #GLOBAL_ACTION_DPAD_UP
+     * @see #GLOBAL_ACTION_DPAD_DOWN
+     * @see #GLOBAL_ACTION_DPAD_LEFT
+     * @see #GLOBAL_ACTION_DPAD_RIGHT
+     * @see #GLOBAL_ACTION_DPAD_CENTER
      */
     public final boolean performGlobalAction(int action) {
         IAccessibilityServiceConnection connection =
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 610c6a6..2e4b783a 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5857,6 +5857,8 @@
     <string name="accessibility_system_action_lock_screen_label">Lock Screen</string>
     <!-- Label for taking screenshot action [CHAR LIMIT=NONE] -->
     <string name="accessibility_system_action_screenshot_label">Screenshot</string>
+    <!-- Label for headset hook action [CHAR LIMIT=NONE] -->
+    <string name="accessibility_system_action_headset_hook_label">Headset Hook</string>
     <!-- Label for triggering on-screen accessibility shortcut action [CHAR LIMIT=NONE] -->
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label">On-screen Accessibility Shortcut</string>
     <!-- Label for showing on-screen accessibility shortcut chooser action [CHAR LIMIT=NONE] -->
@@ -5865,6 +5867,16 @@
     <string name="accessibility_system_action_hardware_a11y_shortcut_label">Accessibility Shortcut</string>
     <!-- Label for dismissing the notification shade [CHAR LIMIT=NONE] -->
     <string name="accessibility_system_action_dismiss_notification_shade">Dismiss Notification Shade</string>
+    <!-- Label for Dpad up action [CHAR LIMIT=NONE] -->
+    <string name="accessibility_system_action_dpad_up_label">Dpad Up</string>
+    <!-- Label for Dpad down action [CHAR LIMIT=NONE] -->
+    <string name="accessibility_system_action_dpad_down_label">Dpad Down</string>
+    <!-- Label for Dpad left action [CHAR LIMIT=NONE] -->
+    <string name="accessibility_system_action_dpad_left_label">Dpad Left</string>
+    <!-- Label for Dpad right action [CHAR LIMIT=NONE] -->
+    <string name="accessibility_system_action_dpad_right_label">Dpad Right</string>
+    <!-- Label for Dpad center action [CHAR LIMIT=NONE] -->
+    <string name="accessibility_system_action_dpad_center_label">Dpad Center</string>
     <!-- Accessibility description of caption view -->
     <string name="accessibility_freeform_caption">Caption bar of <xliff:g id="app_name">%1$s</xliff:g>.</string>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4c1cc4d..7873a1b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4129,10 +4129,16 @@
   <java-symbol type="string" name="accessibility_system_action_quick_settings_label" />
   <java-symbol type="string" name="accessibility_system_action_recents_label" />
   <java-symbol type="string" name="accessibility_system_action_screenshot_label" />
+  <java-symbol type="string" name="accessibility_system_action_headset_hook_label" />
   <java-symbol type="string" name="accessibility_system_action_on_screen_a11y_shortcut_label" />
   <java-symbol type="string" name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" />
   <java-symbol type="string" name="accessibility_system_action_hardware_a11y_shortcut_label" />
   <java-symbol type="string" name="accessibility_system_action_dismiss_notification_shade" />
+  <java-symbol type="string" name="accessibility_system_action_dpad_up_label" />
+  <java-symbol type="string" name="accessibility_system_action_dpad_down_label" />
+  <java-symbol type="string" name="accessibility_system_action_dpad_left_label" />
+  <java-symbol type="string" name="accessibility_system_action_dpad_right_label" />
+  <java-symbol type="string" name="accessibility_system_action_dpad_center_label" />
 
   <java-symbol type="string" name="accessibility_freeform_caption" />
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
index 20d6e32..881e6a9 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
@@ -120,6 +120,13 @@
             AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT; // = 9
 
     /**
+     * Action ID to send the KEYCODE_HEADSETHOOK KeyEvent, which is used to answer/hang up calls and
+     * play/stop media
+     */
+    private static final int SYSTEM_ACTION_ID_KEYCODE_HEADSETHOOK =
+            AccessibilityService.GLOBAL_ACTION_KEYCODE_HEADSETHOOK; // = 10
+
+    /**
      * Action ID to trigger the accessibility button
      */
     public static final int SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON =
@@ -137,6 +144,36 @@
     public static final int SYSTEM_ACTION_ID_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE =
             AccessibilityService.GLOBAL_ACTION_DISMISS_NOTIFICATION_SHADE; // 15
 
+    /**
+     * Action ID to trigger the dpad up button
+     */
+    private static final int SYSTEM_ACTION_ID_DPAD_UP =
+            AccessibilityService.GLOBAL_ACTION_DPAD_UP; // 16
+
+    /**
+     * Action ID to trigger the dpad down button
+     */
+    private static final int SYSTEM_ACTION_ID_DPAD_DOWN =
+            AccessibilityService.GLOBAL_ACTION_DPAD_DOWN; // 17
+
+    /**
+     * Action ID to trigger the dpad left button
+     */
+    private static final int SYSTEM_ACTION_ID_DPAD_LEFT =
+            AccessibilityService.GLOBAL_ACTION_DPAD_LEFT; // 18
+
+    /**
+     * Action ID to trigger the dpad right button
+     */
+    private static final int SYSTEM_ACTION_ID_DPAD_RIGHT =
+            AccessibilityService.GLOBAL_ACTION_DPAD_RIGHT; // 19
+
+    /**
+     * Action ID to trigger dpad center keyevent
+     */
+    private static final int SYSTEM_ACTION_ID_DPAD_CENTER =
+            AccessibilityService.GLOBAL_ACTION_DPAD_CENTER; // 20
+
     private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
 
     private final SystemActionsBroadcastReceiver mReceiver;
@@ -222,10 +259,34 @@
                 R.string.accessibility_system_action_screenshot_label,
                 SystemActionsBroadcastReceiver.INTENT_ACTION_TAKE_SCREENSHOT);
 
+        RemoteAction actionHeadsetHook = createRemoteAction(
+                R.string.accessibility_system_action_headset_hook_label,
+                SystemActionsBroadcastReceiver.INTENT_ACTION_HEADSET_HOOK);
+
         RemoteAction actionAccessibilityShortcut = createRemoteAction(
                 R.string.accessibility_system_action_hardware_a11y_shortcut_label,
                 SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_SHORTCUT);
 
+        RemoteAction actionDpadUp = createRemoteAction(
+                R.string.accessibility_system_action_dpad_up_label,
+                SystemActionsBroadcastReceiver.INTENT_ACTION_DPAD_UP);
+
+        RemoteAction actionDpadDown = createRemoteAction(
+                R.string.accessibility_system_action_dpad_down_label,
+                SystemActionsBroadcastReceiver.INTENT_ACTION_DPAD_DOWN);
+
+        RemoteAction actionDpadLeft = createRemoteAction(
+                R.string.accessibility_system_action_dpad_left_label,
+                SystemActionsBroadcastReceiver.INTENT_ACTION_DPAD_LEFT);
+
+        RemoteAction actionDpadRight = createRemoteAction(
+                R.string.accessibility_system_action_dpad_right_label,
+                SystemActionsBroadcastReceiver.INTENT_ACTION_DPAD_RIGHT);
+
+        RemoteAction actionDpadCenter = createRemoteAction(
+                R.string.accessibility_system_action_dpad_center_label,
+                SystemActionsBroadcastReceiver.INTENT_ACTION_DPAD_CENTER);
+
         mA11yManager.registerSystemAction(actionBack, SYSTEM_ACTION_ID_BACK);
         mA11yManager.registerSystemAction(actionHome, SYSTEM_ACTION_ID_HOME);
         mA11yManager.registerSystemAction(actionRecents, SYSTEM_ACTION_ID_RECENTS);
@@ -234,8 +295,14 @@
         mA11yManager.registerSystemAction(actionPowerDialog, SYSTEM_ACTION_ID_POWER_DIALOG);
         mA11yManager.registerSystemAction(actionLockScreen, SYSTEM_ACTION_ID_LOCK_SCREEN);
         mA11yManager.registerSystemAction(actionTakeScreenshot, SYSTEM_ACTION_ID_TAKE_SCREENSHOT);
+        mA11yManager.registerSystemAction(actionHeadsetHook, SYSTEM_ACTION_ID_KEYCODE_HEADSETHOOK);
         mA11yManager.registerSystemAction(
                 actionAccessibilityShortcut, SYSTEM_ACTION_ID_ACCESSIBILITY_SHORTCUT);
+        mA11yManager.registerSystemAction(actionDpadUp, SYSTEM_ACTION_ID_DPAD_UP);
+        mA11yManager.registerSystemAction(actionDpadDown, SYSTEM_ACTION_ID_DPAD_DOWN);
+        mA11yManager.registerSystemAction(actionDpadLeft, SYSTEM_ACTION_ID_DPAD_LEFT);
+        mA11yManager.registerSystemAction(actionDpadRight, SYSTEM_ACTION_ID_DPAD_RIGHT);
+        mA11yManager.registerSystemAction(actionDpadCenter, SYSTEM_ACTION_ID_DPAD_CENTER);
         registerOrUnregisterDismissNotificationShadeAction();
     }
 
@@ -305,6 +372,10 @@
                 labelId = R.string.accessibility_system_action_screenshot_label;
                 intent = SystemActionsBroadcastReceiver.INTENT_ACTION_TAKE_SCREENSHOT;
                 break;
+            case SYSTEM_ACTION_ID_KEYCODE_HEADSETHOOK:
+                labelId = R.string.accessibility_system_action_headset_hook_label;
+                intent = SystemActionsBroadcastReceiver.INTENT_ACTION_HEADSET_HOOK;
+                break;
             case SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON:
                 labelId = R.string.accessibility_system_action_on_screen_a11y_shortcut_label;
                 intent = SystemActionsBroadcastReceiver.INTENT_ACTION_ACCESSIBILITY_BUTTON;
@@ -323,6 +394,26 @@
                 intent = SystemActionsBroadcastReceiver
                         .INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE;
                 break;
+            case SYSTEM_ACTION_ID_DPAD_UP:
+                labelId = R.string.accessibility_system_action_dpad_up_label;
+                intent = SystemActionsBroadcastReceiver.INTENT_ACTION_DPAD_UP;
+                break;
+            case SYSTEM_ACTION_ID_DPAD_DOWN:
+                labelId = R.string.accessibility_system_action_dpad_down_label;
+                intent = SystemActionsBroadcastReceiver.INTENT_ACTION_DPAD_DOWN;
+                break;
+            case SYSTEM_ACTION_ID_DPAD_LEFT:
+                labelId = R.string.accessibility_system_action_dpad_left_label;
+                intent = SystemActionsBroadcastReceiver.INTENT_ACTION_DPAD_LEFT;
+                break;
+            case SYSTEM_ACTION_ID_DPAD_RIGHT:
+                labelId = R.string.accessibility_system_action_dpad_right_label;
+                intent = SystemActionsBroadcastReceiver.INTENT_ACTION_DPAD_RIGHT;
+                break;
+            case SYSTEM_ACTION_ID_DPAD_CENTER:
+                labelId = R.string.accessibility_system_action_dpad_center_label;
+                intent = SystemActionsBroadcastReceiver.INTENT_ACTION_DPAD_CENTER;
+                break;
             default:
                 return;
         }
@@ -411,6 +502,10 @@
                 SCREENSHOT_ACCESSIBILITY_ACTIONS, new Handler(Looper.getMainLooper()), null);
     }
 
+    private void handleHeadsetHook() {
+        sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HEADSETHOOK);
+    }
+
     private void handleAccessibilityButton() {
         AccessibilityManager.getInstance(mContext).notifyAccessibilityButtonClicked(
                 Display.DEFAULT_DISPLAY);
@@ -434,6 +529,26 @@
                         CommandQueue.FLAG_EXCLUDE_NONE, false /* force */));
     }
 
+    private void handleDpadUp() {
+        sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_UP);
+    }
+
+    private void handleDpadDown() {
+        sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_DOWN);
+    }
+
+    private void handleDpadLeft() {
+        sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT);
+    }
+
+    private void handleDpadRight() {
+        sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT);
+    }
+
+    private void handleDpadCenter() {
+        sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_CENTER);
+    }
+
     private class SystemActionsBroadcastReceiver extends BroadcastReceiver {
         private static final String INTENT_ACTION_BACK = "SYSTEM_ACTION_BACK";
         private static final String INTENT_ACTION_HOME = "SYSTEM_ACTION_HOME";
@@ -443,6 +558,7 @@
         private static final String INTENT_ACTION_POWER_DIALOG = "SYSTEM_ACTION_POWER_DIALOG";
         private static final String INTENT_ACTION_LOCK_SCREEN = "SYSTEM_ACTION_LOCK_SCREEN";
         private static final String INTENT_ACTION_TAKE_SCREENSHOT = "SYSTEM_ACTION_TAKE_SCREENSHOT";
+        private static final String INTENT_ACTION_HEADSET_HOOK = "SYSTEM_ACTION_HEADSET_HOOK";
         private static final String INTENT_ACTION_ACCESSIBILITY_BUTTON =
                 "SYSTEM_ACTION_ACCESSIBILITY_BUTTON";
         private static final String INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER =
@@ -451,6 +567,11 @@
                 "SYSTEM_ACTION_ACCESSIBILITY_SHORTCUT";
         private static final String INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE =
                 "SYSTEM_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE";
+        private static final String INTENT_ACTION_DPAD_UP = "SYSTEM_ACTION_DPAD_UP";
+        private static final String INTENT_ACTION_DPAD_DOWN = "SYSTEM_ACTION_DPAD_DOWN";
+        private static final String INTENT_ACTION_DPAD_LEFT = "SYSTEM_ACTION_DPAD_LEFT";
+        private static final String INTENT_ACTION_DPAD_RIGHT = "SYSTEM_ACTION_DPAD_RIGHT";
+        private static final String INTENT_ACTION_DPAD_CENTER = "SYSTEM_ACTION_DPAD_CENTER";
 
         private PendingIntent createPendingIntent(Context context, String intentAction) {
             switch (intentAction) {
@@ -462,10 +583,16 @@
                 case INTENT_ACTION_POWER_DIALOG:
                 case INTENT_ACTION_LOCK_SCREEN:
                 case INTENT_ACTION_TAKE_SCREENSHOT:
+                case INTENT_ACTION_HEADSET_HOOK:
                 case INTENT_ACTION_ACCESSIBILITY_BUTTON:
                 case INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER:
                 case INTENT_ACTION_ACCESSIBILITY_SHORTCUT:
-                case INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE: {
+                case INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE:
+                case INTENT_ACTION_DPAD_UP:
+                case INTENT_ACTION_DPAD_DOWN:
+                case INTENT_ACTION_DPAD_LEFT:
+                case INTENT_ACTION_DPAD_RIGHT:
+                case INTENT_ACTION_DPAD_CENTER: {
                     Intent intent = new Intent(intentAction);
                     intent.setPackage(context.getPackageName());
                     return PendingIntent.getBroadcast(context, 0, intent,
@@ -487,10 +614,16 @@
             intentFilter.addAction(INTENT_ACTION_POWER_DIALOG);
             intentFilter.addAction(INTENT_ACTION_LOCK_SCREEN);
             intentFilter.addAction(INTENT_ACTION_TAKE_SCREENSHOT);
+            intentFilter.addAction(INTENT_ACTION_HEADSET_HOOK);
             intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_BUTTON);
             intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_BUTTON_CHOOSER);
             intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_SHORTCUT);
             intentFilter.addAction(INTENT_ACTION_ACCESSIBILITY_DISMISS_NOTIFICATION_SHADE);
+            intentFilter.addAction(INTENT_ACTION_DPAD_UP);
+            intentFilter.addAction(INTENT_ACTION_DPAD_DOWN);
+            intentFilter.addAction(INTENT_ACTION_DPAD_LEFT);
+            intentFilter.addAction(INTENT_ACTION_DPAD_RIGHT);
+            intentFilter.addAction(INTENT_ACTION_DPAD_CENTER);
             return intentFilter;
         }
 
@@ -530,6 +663,10 @@
                     handleTakeScreenshot();
                     break;
                 }
+                case INTENT_ACTION_HEADSET_HOOK: {
+                    handleHeadsetHook();
+                    break;
+                }
                 case INTENT_ACTION_ACCESSIBILITY_BUTTON: {
                     handleAccessibilityButton();
                     break;
@@ -546,6 +683,26 @@
                     handleAccessibilityDismissNotificationShade();
                     break;
                 }
+                case INTENT_ACTION_DPAD_UP: {
+                    handleDpadUp();
+                    break;
+                }
+                case INTENT_ACTION_DPAD_DOWN: {
+                    handleDpadDown();
+                    break;
+                }
+                case INTENT_ACTION_DPAD_LEFT: {
+                    handleDpadLeft();
+                    break;
+                }
+                case INTENT_ACTION_DPAD_RIGHT: {
+                    handleDpadRight();
+                    break;
+                }
+                case INTENT_ACTION_DPAD_CENTER: {
+                    handleDpadCenter();
+                    break;
+                }
                 default:
                     break;
             }
diff --git a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
index 6744ea8..803177b 100644
--- a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
+++ b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
@@ -295,6 +295,21 @@
                 case AccessibilityService.GLOBAL_ACTION_KEYCODE_HEADSETHOOK :
                     sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HEADSETHOOK);
                     return true;
+                case AccessibilityService.GLOBAL_ACTION_DPAD_UP:
+                    sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_UP);
+                    return true;
+                case AccessibilityService.GLOBAL_ACTION_DPAD_DOWN:
+                    sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_DOWN);
+                    return true;
+                case AccessibilityService.GLOBAL_ACTION_DPAD_LEFT:
+                    sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT);
+                    return true;
+                case AccessibilityService.GLOBAL_ACTION_DPAD_RIGHT:
+                    sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT);
+                    return true;
+                case AccessibilityService.GLOBAL_ACTION_DPAD_CENTER:
+                    sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_CENTER);
+                    return true;
                 default:
                     Slog.e(TAG, "Invalid action id: " + actionId);
                     return false;