Snap for 7486544 from 2d1ee7de713a93d08677e19e93a5a2ced82afaa5 to sc-release
Change-Id: Idd9887512ce164ecd335922809d8c22ebff78a0a
diff --git a/OWNERS b/OWNERS
index 64b0ed4..4d45629 100644
--- a/OWNERS
+++ b/OWNERS
@@ -4,3 +4,4 @@
depstein@google.com
yabinh@google.com
agathaman@google.com
+hseog@google.com
diff --git a/src/com/android/car/rotary/RotaryService.java b/src/com/android/car/rotary/RotaryService.java
index ae2b425..7f26275 100644
--- a/src/com/android/car/rotary/RotaryService.java
+++ b/src/com/android/car/rotary/RotaryService.java
@@ -17,6 +17,7 @@
import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS;
import static android.car.CarOccupantZoneManager.DisplayTypeEnum;
+import static android.car.settings.CarSettings.Secure.KEY_ROTARY_KEY_EVENT_FILTER;
import static android.provider.Settings.Secure.DEFAULT_INPUT_METHOD;
import static android.provider.Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS;
import static android.provider.Settings.Secure.ENABLED_INPUT_METHODS;
@@ -324,6 +325,9 @@
/** Observer to update {@link #mTouchInputMethod} when the user switches IMEs. */
private ContentObserver mInputMethodObserver;
+ /** Observer to update service info when the developer toggles key event filtering. */
+ private ContentObserver mKeyEventFilterObserver;
+
private SharedPreferences mPrefs;
private UserManager mUserManager;
@@ -444,6 +448,11 @@
*/
@Nullable private Context mWindowContext;
+ /**
+ * Mapping from test keycodes to production keycodes. During development, you can use a USB
+ * keyboard as a stand-in for rotary hardware. To enable this: {@code adb shell settings put
+ * secure android.car.ROTARY_KEY_EVENT_FILTER 1}.
+ */
private static final Map<Integer, Integer> TEST_TO_REAL_KEYCODE_MAP;
private static final Map<Integer, Integer> DIRECTION_TO_KEYCODE_MAP;
@@ -697,12 +706,7 @@
}
});
- if (Build.IS_DEBUGGABLE) {
- AccessibilityServiceInfo serviceInfo = getServiceInfo();
- // Filter testing KeyEvents from a keyboard.
- serviceInfo.flags |= FLAG_REQUEST_FILTER_KEY_EVENTS;
- setServiceInfo(serviceInfo);
- }
+ updateServiceInfo();
mInputManager = getSystemService(InputManager.class);
@@ -711,6 +715,10 @@
// Register an observer to update mTouchInputMethod whenever the user switches IMEs.
registerInputMethodObserver();
+
+ // Register an observer to update the service info when the developer changes the filter
+ // setting.
+ registerFilterObserver();
}
@Override
@@ -724,6 +732,7 @@
getWindowContext().unregisterReceiver(mHomeButtonReceiver);
unregisterInputMethodObserver();
+ unregisterFilterObserver();
if (mCarInputManager != null) {
mCarInputManager.releaseInputEventCapture(CarOccupantZoneManager.DISPLAY_TYPE_MAIN);
}
@@ -911,6 +920,30 @@
}
/**
+ * Updates this accessibility service's info, enabling or disabling key event filtering
+ * depending on a setting.
+ */
+ private void updateServiceInfo() {
+ AccessibilityServiceInfo serviceInfo = getServiceInfo();
+ if (serviceInfo == null) {
+ L.w("Service info not available");
+ return;
+ }
+ int flags = serviceInfo.flags;
+ boolean filterKeyEvents = Settings.Secure.getInt(getContentResolver(),
+ KEY_ROTARY_KEY_EVENT_FILTER, /* def= */ 0) != 0;
+ if (filterKeyEvents) {
+ flags |= FLAG_REQUEST_FILTER_KEY_EVENTS;
+ } else {
+ flags &= ~FLAG_REQUEST_FILTER_KEY_EVENTS;
+ }
+ if (flags == serviceInfo.flags) return;
+ L.d((filterKeyEvents ? "Enabling" : "Disabling") + " key event filtering");
+ serviceInfo.flags = flags;
+ setServiceInfo(serviceInfo);
+ }
+
+ /**
* Registers an observer to updates {@link #mTouchInputMethod} whenever the user switches IMEs.
*/
private void registerInputMethodObserver() {
@@ -947,6 +980,34 @@
}
}
+ /**
+ * Registers an observer to update our accessibility service info whenever the developer changes
+ * the key event filter setting.
+ */
+ private void registerFilterObserver() {
+ if (mKeyEventFilterObserver != null) {
+ throw new IllegalStateException("Filter observer already registered");
+ }
+ mKeyEventFilterObserver = new ContentObserver(new Handler(Looper.myLooper())) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateServiceInfo();
+ }
+ };
+ getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(KEY_ROTARY_KEY_EVENT_FILTER),
+ /* notifyForDescendants= */ false,
+ mKeyEventFilterObserver);
+ }
+
+ /** Unregisters the observer registered by {@link #registerFilterObserver}. */
+ private void unregisterFilterObserver() {
+ if (mKeyEventFilterObserver != null) {
+ getContentResolver().unregisterContentObserver(mKeyEventFilterObserver);
+ mKeyEventFilterObserver = null;
+ }
+ }
+
private static boolean isValidDisplayType(int displayType) {
if (displayType == CarOccupantZoneManager.DISPLAY_TYPE_MAIN) {
return true;