From 0b99849797d2259fd1e16764635e9598bcf7efcf Mon Sep 17 00:00:00 2001 From: Thomas Leu Date: Thu, 16 Mar 2023 14:45:51 +0100 Subject: [PATCH] Add the DPAD device flag when injecting accessibility DPAD events. For the global DPAD actions GLOBAL_ACTION_DPAD_UP/DOWN/LEFT/RIGHT/CENTER, set the event source to both SOURCE_KEYBOARD and SOURCE_DPAD to match the event we would get with a real DPAD of a TV remote control. Bug: b/273880258 Test: Locally tested on adt4-userdebug with the same sample accessibility service used in the video attached to b/273880258. (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4df28baa74d2dbde690d5357f1807e59f4eadd6d) Merged-In: Icc194345bca7220927f98ae67379c27a9e8c32ba Change-Id: Icc194345bca7220927f98ae67379c27a9e8c32ba --- .../accessibility/SystemActionPerformer.java | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java index eba92305dd7b6..c89b9b8517423 100644 --- a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java +++ b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java @@ -266,11 +266,11 @@ public class SystemActionPerformer { // actions. switch (actionId) { case AccessibilityService.GLOBAL_ACTION_BACK: { - sendDownAndUpKeyEvents(KeyEvent.KEYCODE_BACK); + sendDownAndUpKeyEvents(KeyEvent.KEYCODE_BACK, InputDevice.SOURCE_KEYBOARD); return true; } case AccessibilityService.GLOBAL_ACTION_HOME: { - sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HOME); + sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HOME, InputDevice.SOURCE_KEYBOARD); return true; } case AccessibilityService.GLOBAL_ACTION_RECENTS: @@ -291,23 +291,29 @@ public class SystemActionPerformer { return lockScreen(); case AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT: return takeScreenshot(); - case AccessibilityService.GLOBAL_ACTION_KEYCODE_HEADSETHOOK : - sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HEADSETHOOK); + case AccessibilityService.GLOBAL_ACTION_KEYCODE_HEADSETHOOK: + sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HEADSETHOOK, + InputDevice.SOURCE_KEYBOARD); return true; case AccessibilityService.GLOBAL_ACTION_DPAD_UP: - sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_UP); + sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_UP, + InputDevice.SOURCE_KEYBOARD | InputDevice.SOURCE_DPAD); return true; case AccessibilityService.GLOBAL_ACTION_DPAD_DOWN: - sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_DOWN); + sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_DOWN, + InputDevice.SOURCE_KEYBOARD | InputDevice.SOURCE_DPAD); return true; case AccessibilityService.GLOBAL_ACTION_DPAD_LEFT: - sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT); + sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT, + InputDevice.SOURCE_KEYBOARD | InputDevice.SOURCE_DPAD); return true; case AccessibilityService.GLOBAL_ACTION_DPAD_RIGHT: - sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT); + sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT, + InputDevice.SOURCE_KEYBOARD | InputDevice.SOURCE_DPAD); return true; case AccessibilityService.GLOBAL_ACTION_DPAD_CENTER: - sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_CENTER); + sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_CENTER, + InputDevice.SOURCE_KEYBOARD | InputDevice.SOURCE_DPAD); return true; default: Slog.e(TAG, "Invalid action id: " + actionId); @@ -318,23 +324,24 @@ public class SystemActionPerformer { } } - private void sendDownAndUpKeyEvents(int keyCode) { + private void sendDownAndUpKeyEvents(int keyCode, int source) { final long token = Binder.clearCallingIdentity(); try { // Inject down. final long downTime = SystemClock.uptimeMillis(); - sendKeyEventIdentityCleared(keyCode, KeyEvent.ACTION_DOWN, downTime, downTime); + sendKeyEventIdentityCleared(keyCode, KeyEvent.ACTION_DOWN, downTime, downTime, source); sendKeyEventIdentityCleared( - keyCode, KeyEvent.ACTION_UP, downTime, SystemClock.uptimeMillis()); + keyCode, KeyEvent.ACTION_UP, downTime, SystemClock.uptimeMillis(), source); } finally { Binder.restoreCallingIdentity(token); } } - private void sendKeyEventIdentityCleared(int keyCode, int action, long downTime, long time) { + private void sendKeyEventIdentityCleared(int keyCode, int action, long downTime, long time, + int source) { KeyEvent event = KeyEvent.obtain(downTime, time, action, keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM, - InputDevice.SOURCE_KEYBOARD, null); + source, null); mContext.getSystemService(InputManager.class) .injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); event.recycle();