Merge "Implement toggle talkback shortcut" into main
diff --git a/core/java/android/hardware/input/KeyGestureEvent.java b/core/java/android/hardware/input/KeyGestureEvent.java
index 2df5418..71d17eb 100644
--- a/core/java/android/hardware/input/KeyGestureEvent.java
+++ b/core/java/android/hardware/input/KeyGestureEvent.java
@@ -100,6 +100,7 @@
public static final int KEY_GESTURE_TYPE_ACCESSIBILITY_SHORTCUT = 60;
public static final int KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS = 61;
public static final int KEY_GESTURE_TYPE_MOVE_TO_NEXT_DISPLAY = 62;
+ public static final int KEY_GESTURE_TYPE_TOGGLE_TALKBACK = 63;
public static final int FLAG_CANCELLED = 1;
@@ -177,6 +178,7 @@
KEY_GESTURE_TYPE_ACCESSIBILITY_SHORTCUT,
KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS,
KEY_GESTURE_TYPE_MOVE_TO_NEXT_DISPLAY,
+ KEY_GESTURE_TYPE_TOGGLE_TALKBACK,
})
@Retention(RetentionPolicy.SOURCE)
public @interface KeyGestureType {
@@ -597,6 +599,8 @@
return "KEY_GESTURE_TYPE_ACCESSIBILITY_SHORTCUT";
case KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS:
return "KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS";
+ case KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
+ return "KEY_GESTURE_TYPE_TOGGLE_TALKBACK";
default:
return Integer.toHexString(value);
}
diff --git a/services/core/java/com/android/server/input/KeyGestureController.java b/services/core/java/com/android/server/input/KeyGestureController.java
index 2f5236f..bd1625e 100644
--- a/services/core/java/com/android/server/input/KeyGestureController.java
+++ b/services/core/java/com/android/server/input/KeyGestureController.java
@@ -20,6 +20,7 @@
import static android.content.pm.PackageManager.FEATURE_WATCH;
import static android.view.WindowManagerPolicyConstants.FLAG_INTERACTIVE;
+import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
import static com.android.hardware.input.Flags.useKeyGestureEventHandlerMultiPressGestures;
import static com.android.server.flags.Flags.newBugreportKeyboardShortcut;
@@ -577,6 +578,17 @@
focusedToken, /* flags = */0);
}
break;
+ case KeyEvent.KEYCODE_T:
+ if (keyboardA11yShortcutControl()) {
+ if (firstDown && event.isMetaPressed() && event.isAltPressed()) {
+ return handleKeyGesture(deviceId, new int[]{keyCode},
+ KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK,
+ KeyGestureEvent.ACTION_GESTURE_COMPLETE, displayId,
+ focusedToken, /* flags = */0);
+ }
+ }
+ break;
case KeyEvent.KEYCODE_DEL:
if (newBugreportKeyboardShortcut()) {
if (firstDown && mEnableBugReportKeyboardShortcut && event.isMetaPressed()
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index ad5c840..0b5b0d2 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -84,6 +84,7 @@
import static android.view.contentprotection.flags.Flags.createAccessibilityOverlayAppOpEnabled;
import static com.android.hardware.input.Flags.emojiAndScreenshotKeycodesAvailable;
+import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
import static com.android.hardware.input.Flags.modifierShortcutDump;
import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
import static com.android.hardware.input.Flags.useKeyGestureEventHandlerMultiPressGestures;
@@ -1615,7 +1616,8 @@
case TRIPLE_PRESS_PRIMARY_NOTHING:
break;
case TRIPLE_PRESS_PRIMARY_TOGGLE_ACCESSIBILITY:
- mTalkbackShortcutController.toggleTalkback(mCurrentUserId);
+ mTalkbackShortcutController.toggleTalkback(mCurrentUserId,
+ TalkbackShortcutController.ShortcutSource.GESTURE);
if (mTalkbackShortcutController.isTalkBackShortcutGestureEnabled()) {
performHapticFeedback(HapticFeedbackConstants.CONFIRM,
"Stem primary - Triple Press - Toggle Accessibility");
@@ -3603,6 +3605,17 @@
return true;
}
break;
+ case KeyEvent.KEYCODE_T:
+ if (keyboardA11yShortcutControl()) {
+ if (firstDown && event.isMetaPressed() && event.isAltPressed()) {
+ mTalkbackShortcutController.toggleTalkback(mCurrentUserId,
+ TalkbackShortcutController.ShortcutSource.KEYBOARD);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK);
+ return true;
+ }
+ }
+ break;
case KeyEvent.KEYCODE_DEL:
if (newBugreportKeyboardShortcut()) {
if (mEnableBugReportKeyboardShortcut && firstDown
@@ -4034,6 +4047,8 @@
case KeyGestureEvent.KEY_GESTURE_TYPE_TV_ACCESSIBILITY_SHORTCUT_CHORD:
return mDefaultDisplayPolicy.isAwake() && mAccessibilityShortcutController
.isAccessibilityShortcutAvailable(false);
+ case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
+ return keyboardA11yShortcutControl();
default:
return false;
}
@@ -4251,6 +4266,15 @@
mContext.closeSystemDialogs();
}
return true;
+ case KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK:
+ if (keyboardA11yShortcutControl()) {
+ if (complete) {
+ mTalkbackShortcutController.toggleTalkback(mCurrentUserId,
+ TalkbackShortcutController.ShortcutSource.KEYBOARD);
+ }
+ return true;
+ }
+ break;
}
return false;
}
diff --git a/services/core/java/com/android/server/policy/TalkbackShortcutController.java b/services/core/java/com/android/server/policy/TalkbackShortcutController.java
index e544ae6..9e16a7d 100644
--- a/services/core/java/com/android/server/policy/TalkbackShortcutController.java
+++ b/services/core/java/com/android/server/policy/TalkbackShortcutController.java
@@ -44,6 +44,11 @@
private final Context mContext;
private final PackageManager mPackageManager;
+ public enum ShortcutSource {
+ GESTURE,
+ KEYBOARD,
+ }
+
TalkbackShortcutController(Context context) {
mContext = context;
mPackageManager = mContext.getPackageManager();
@@ -55,7 +60,7 @@
* @return talkback state after toggle. {@code true} if talkback is enabled, {@code false} if
* talkback is disabled
*/
- boolean toggleTalkback(int userId) {
+ boolean toggleTalkback(int userId, ShortcutSource source) {
final Set<ComponentName> enabledServices =
AccessibilityUtils.getEnabledServicesFromSettings(mContext, userId);
ComponentName componentName = getTalkbackComponent();
@@ -65,13 +70,13 @@
boolean isTalkbackAlreadyEnabled = enabledServices.contains(componentName);
- if (isTalkBackShortcutGestureEnabled()) {
+ if (source == ShortcutSource.KEYBOARD || isTalkBackShortcutGestureEnabled()) {
isTalkbackAlreadyEnabled = !isTalkbackAlreadyEnabled;
AccessibilityUtils.setAccessibilityServiceState(mContext, componentName,
- isTalkbackAlreadyEnabled);
+ isTalkbackAlreadyEnabled, userId);
// log stem triple press telemetry if it's a talkback enabled event.
- if (isTalkbackAlreadyEnabled) {
+ if (source == ShortcutSource.GESTURE && isTalkbackAlreadyEnabled) {
logStemTriplePressAccessibilityTelemetry(componentName);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
index cdb4542..d83ffd1 100644
--- a/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
@@ -35,6 +35,7 @@
import androidx.test.filters.MediumTest;
+import com.android.hardware.input.Flags;
import com.android.internal.annotations.Keep;
import junit.framework.Assert;
@@ -393,6 +394,17 @@
META_ON | CTRL_ON);
}
+ @Test
+ @EnableFlags(Flags.FLAG_KEYBOARD_A11Y_SHORTCUT_CONTROL)
+ @DisableFlags(com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
+ public void testToggleTalkbackPress() {
+ testShortcutInternal("Meta + Alt + T -> Toggle talkback",
+ new int[]{META_KEY, ALT_KEY, KeyEvent.KEYCODE_T},
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK,
+ KeyEvent.KEYCODE_T,
+ META_ON | ALT_ON);
+ }
+
private void testShortcutInternal(String testName, int[] testKeys,
@KeyGestureEvent.KeyGestureType int expectedKeyGestureType, int expectedKey,
int expectedModifierState) {
@@ -699,4 +711,16 @@
sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_CLOSE_ALL_DIALOGS));
mPhoneWindowManager.assertCloseAllDialogs();
}
+
+ @Test
+ @EnableFlags(com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_SHORTCUT_CONTROL)
+ public void testKeyGestureToggleTalkback() {
+ Assert.assertTrue(
+ sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK));
+ mPhoneWindowManager.assertTalkBack(true);
+
+ Assert.assertTrue(
+ sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK));
+ mPhoneWindowManager.assertTalkBack(false);
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index a85f866..62670b4 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -197,7 +197,7 @@
}
@Override
- boolean toggleTalkback(int currentUserId) {
+ boolean toggleTalkback(int currentUserId, ShortcutSource source) {
mIsTalkBackEnabled = !mIsTalkBackEnabled;
return mIsTalkBackEnabled;
}