summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/input/AidlKeyGestureEvent.aidl29
-rw-r--r--core/java/android/hardware/input/IInputManager.aidl11
-rw-r--r--core/java/android/hardware/input/IKeyGestureEventListener.aidl4
-rw-r--r--core/java/android/hardware/input/IKeyGestureHandler.aidl42
-rw-r--r--core/java/android/hardware/input/InputManager.java58
-rw-r--r--core/java/android/hardware/input/InputManagerGlobal.java109
-rw-r--r--core/java/android/hardware/input/KeyGestureEvent.java883
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt12
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java52
-rw-r--r--services/core/java/com/android/server/input/KeyGestureController.java236
-rw-r--r--services/core/java/com/android/server/input/KeyboardMetricsCollector.java15
-rw-r--r--tests/Input/src/android/hardware/input/KeyGestureEventHandlerTest.kt236
-rw-r--r--tests/Input/src/android/hardware/input/KeyGestureEventListenerTest.kt27
-rw-r--r--tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt162
14 files changed, 1349 insertions, 527 deletions
diff --git a/core/java/android/hardware/input/AidlKeyGestureEvent.aidl b/core/java/android/hardware/input/AidlKeyGestureEvent.aidl
new file mode 100644
index 000000000000..7cf8795085e3
--- /dev/null
+++ b/core/java/android/hardware/input/AidlKeyGestureEvent.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input;
+
+/** @hide */
+@JavaDerive(equals=true)
+parcelable AidlKeyGestureEvent {
+ int deviceId;
+ int[] keycodes;
+ int modifierState;
+ int gestureType;
+ int action;
+ int displayId;
+ int flags;
+}
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 2d96bbaae901..102f56e4672b 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -26,6 +26,7 @@ import android.hardware.input.IInputDeviceBatteryState;
import android.hardware.input.IKeyboardBacklightListener;
import android.hardware.input.IKeyboardBacklightState;
import android.hardware.input.IKeyGestureEventListener;
+import android.hardware.input.IKeyGestureHandler;
import android.hardware.input.IStickyModifierStateListener;
import android.hardware.input.ITabletModeChangedListener;
import android.hardware.input.KeyboardLayoutSelectionResult;
@@ -250,4 +251,14 @@ interface IInputManager {
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ "android.Manifest.permission.MANAGE_KEY_GESTURES)")
void unregisterKeyGestureEventListener(IKeyGestureEventListener listener);
+
+ @PermissionManuallyEnforced
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ + "android.Manifest.permission.MANAGE_KEY_GESTURES)")
+ void registerKeyGestureHandler(IKeyGestureHandler handler);
+
+ @PermissionManuallyEnforced
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ + "android.Manifest.permission.MANAGE_KEY_GESTURES)")
+ void unregisterKeyGestureHandler(IKeyGestureHandler handler);
}
diff --git a/core/java/android/hardware/input/IKeyGestureEventListener.aidl b/core/java/android/hardware/input/IKeyGestureEventListener.aidl
index 2c430f1a1c9d..6b5f83758a11 100644
--- a/core/java/android/hardware/input/IKeyGestureEventListener.aidl
+++ b/core/java/android/hardware/input/IKeyGestureEventListener.aidl
@@ -16,11 +16,13 @@
package android.hardware.input;
+import android.hardware.input.AidlKeyGestureEvent;
+
/** @hide */
oneway interface IKeyGestureEventListener {
/**
* Called when a key gesture event occurs.
*/
- void onKeyGestureEvent(int deviceId, in int[] keycodes, int modifierState, int shortcut);
+ void onKeyGestureEvent(in AidlKeyGestureEvent event);
}
diff --git a/core/java/android/hardware/input/IKeyGestureHandler.aidl b/core/java/android/hardware/input/IKeyGestureHandler.aidl
new file mode 100644
index 000000000000..509b9482154e
--- /dev/null
+++ b/core/java/android/hardware/input/IKeyGestureHandler.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input;
+
+import android.hardware.input.AidlKeyGestureEvent;
+import android.os.IBinder;
+
+/** @hide */
+interface IKeyGestureHandler {
+
+ /**
+ * Called when a key gesture starts, ends, or is cancelled. If a handler returns {@code true},
+ * it means they intend to handle the full gesture and should handle all the events pertaining
+ * to that gesture.
+ */
+ boolean handleKeyGesture(in AidlKeyGestureEvent event, in IBinder focusedToken);
+
+ /**
+ * Called to know if a particular gesture type is supported by the handler.
+ *
+ * TODO(b/358569822): Remove this call to reduce the binder calls to single call for
+ * handleKeyGesture. For this we need to remove dependency of multi-key gestures to identify if
+ * a key gesture is supported on first relevant key down.
+ * Also, for now we prioritize handlers in the system server process above external handlers to
+ * reduce IPC binder calls.
+ */
+ boolean isKeyGestureSupported(int gestureType);
+}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 04cfcd880f52..22728f7a5ad3 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -1406,6 +1406,33 @@ public final class InputManager {
}
/**
+ * Registers a key gesture event handler for {@link KeyGestureEvent} handling.
+ *
+ * @param handler the {@link KeyGestureEventHandler}
+ * @throws IllegalArgumentException if {@code handler} has already been registered previously.
+ * @throws NullPointerException if {@code handler} or {@code executor} is null.
+ * @hide
+ * @see #unregisterKeyGestureEventHandler(KeyGestureEventHandler)
+ */
+ @RequiresPermission(Manifest.permission.MANAGE_KEY_GESTURES)
+ public void registerKeyGestureEventHandler(@NonNull KeyGestureEventHandler handler)
+ throws IllegalArgumentException {
+ mGlobal.registerKeyGestureEventHandler(handler);
+ }
+
+ /**
+ * Unregisters a previously added key gesture event handler.
+ *
+ * @param handler the {@link KeyGestureEventHandler}
+ * @hide
+ * @see #registerKeyGestureEventHandler(KeyGestureEventHandler)
+ */
+ @RequiresPermission(Manifest.permission.MANAGE_KEY_GESTURES)
+ public void unregisterKeyGestureEventHandler(@NonNull KeyGestureEventHandler handler) {
+ mGlobal.unregisterKeyGestureEventHandler(handler);
+ }
+
+ /**
* A callback used to be notified about battery state changes for an input device. The
* {@link #onBatteryStateChanged(int, long, BatteryState)} method will be called once after the
* listener is successfully registered to provide the initial battery state of the device.
@@ -1522,4 +1549,35 @@ public final class InputManager {
*/
void onKeyGestureEvent(@NonNull KeyGestureEvent event);
}
+
+ /**
+ * A callback used to notify about key gesture event start, complete and cancel. Unlike
+ * {@see KeyGestureEventListener} which is to listen to successfully handled key gestures, this
+ * interface allows system components to register handler for handling key gestures.
+ *
+ * @see #registerKeyGestureEventHandler(KeyGestureEventHandler)
+ * @see #unregisterKeyGestureEventHandler(KeyGestureEventHandler)
+ *
+ * <p> NOTE: All callbacks will occur on system main and input threads, so the caller needs
+ * to move time-consuming operations to appropriate handler threads.
+ * @hide
+ */
+ public interface KeyGestureEventHandler {
+ /**
+ * Called when a key gesture event starts, is completed, or is cancelled. If a handler
+ * returns {@code true}, it implies that the handler intends to handle the key gesture and
+ * only this handler will receive the future events for this key gesture.
+ *
+ * @param event the gesture event
+ */
+ boolean handleKeyGestureEvent(@NonNull KeyGestureEvent event,
+ @Nullable IBinder focusedToken);
+
+ /**
+ * Called to identify if a particular gesture is of interest to a handler.
+ *
+ * NOTE: If no active handler supports certain gestures, the gestures will not be captured.
+ */
+ boolean isKeyGestureSupported(@KeyGestureEvent.KeyGestureType int gestureType);
+ }
}
diff --git a/core/java/android/hardware/input/InputManagerGlobal.java b/core/java/android/hardware/input/InputManagerGlobal.java
index 2a362381a003..5c11346df1c3 100644
--- a/core/java/android/hardware/input/InputManagerGlobal.java
+++ b/core/java/android/hardware/input/InputManagerGlobal.java
@@ -25,6 +25,7 @@ import android.hardware.BatteryState;
import android.hardware.SensorManager;
import android.hardware.input.InputManager.InputDeviceBatteryListener;
import android.hardware.input.InputManager.InputDeviceListener;
+import android.hardware.input.InputManager.KeyGestureEventHandler;
import android.hardware.input.InputManager.KeyGestureEventListener;
import android.hardware.input.InputManager.KeyboardBacklightListener;
import android.hardware.input.InputManager.OnTabletModeChangedListener;
@@ -119,6 +120,14 @@ public final class InputManagerGlobal {
@Nullable
private IKeyGestureEventListener mKeyGestureEventListener;
+ private final Object mKeyGestureEventHandlerLock = new Object();
+ @GuardedBy("mKeyGestureEventHandlerLock")
+ @Nullable
+ private ArrayList<KeyGestureEventHandler> mKeyGestureEventHandlers;
+ @GuardedBy("mKeyGestureEventHandlerLock")
+ @Nullable
+ private IKeyGestureHandler mKeyGestureHandler;
+
// InputDeviceSensorManager gets notified synchronously from the binder thread when input
// devices change, so it must be synchronized with the input device listeners.
@GuardedBy("mInputDeviceListeners")
@@ -1080,18 +1089,14 @@ public final class InputManagerGlobal {
}
private class LocalKeyGestureEventListener extends IKeyGestureEventListener.Stub {
-
@Override
- public void onKeyGestureEvent(int deviceId, int[] keycodes, int modifierState,
- int gestureType) {
+ public void onKeyGestureEvent(@NonNull AidlKeyGestureEvent ev) {
synchronized (mKeyGestureEventListenerLock) {
if (mKeyGestureEventListeners == null) return;
final int numListeners = mKeyGestureEventListeners.size();
+ final KeyGestureEvent event = new KeyGestureEvent(ev);
for (int i = 0; i < numListeners; i++) {
- mKeyGestureEventListeners.get(i)
- .onKeyGestureEvent(
- new KeyGestureEvent(deviceId, keycodes, modifierState,
- gestureType));
+ mKeyGestureEventListeners.get(i).onKeyGestureEvent(event);
}
}
}
@@ -1154,6 +1159,96 @@ public final class InputManagerGlobal {
}
}
+ private class LocalKeyGestureHandler extends IKeyGestureHandler.Stub {
+ @Override
+ public boolean handleKeyGesture(@NonNull AidlKeyGestureEvent ev, IBinder focusedToken) {
+ synchronized (mKeyGestureEventHandlerLock) {
+ if (mKeyGestureEventHandlers == null) {
+ return false;
+ }
+ final int numHandlers = mKeyGestureEventHandlers.size();
+ final KeyGestureEvent event = new KeyGestureEvent(ev);
+ for (int i = 0; i < numHandlers; i++) {
+ KeyGestureEventHandler handler = mKeyGestureEventHandlers.get(i);
+ if (handler.handleKeyGestureEvent(event, focusedToken)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isKeyGestureSupported(@KeyGestureEvent.KeyGestureType int gestureType) {
+ synchronized (mKeyGestureEventHandlerLock) {
+ if (mKeyGestureEventHandlers == null) {
+ return false;
+ }
+ final int numHandlers = mKeyGestureEventHandlers.size();
+ for (int i = 0; i < numHandlers; i++) {
+ KeyGestureEventHandler handler = mKeyGestureEventHandlers.get(i);
+ if (handler.isKeyGestureSupported(gestureType)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * @see InputManager#registerKeyGestureEventHandler(KeyGestureEventHandler)
+ */
+ @RequiresPermission(Manifest.permission.MANAGE_KEY_GESTURES)
+ void registerKeyGestureEventHandler(@NonNull KeyGestureEventHandler handler)
+ throws IllegalArgumentException {
+ Objects.requireNonNull(handler, "handler should not be null");
+
+ synchronized (mKeyGestureEventHandlerLock) {
+ if (mKeyGestureHandler == null) {
+ mKeyGestureEventHandlers = new ArrayList<>();
+ mKeyGestureHandler = new LocalKeyGestureHandler();
+
+ try {
+ mIm.registerKeyGestureHandler(mKeyGestureHandler);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ final int numHandlers = mKeyGestureEventHandlers.size();
+ for (int i = 0; i < numHandlers; i++) {
+ if (mKeyGestureEventHandlers.get(i) == handler) {
+ throw new IllegalArgumentException("Handler has already been registered!");
+ }
+ }
+ mKeyGestureEventHandlers.add(handler);
+ }
+ }
+
+ /**
+ * @see InputManager#unregisterKeyGestureEventHandler(KeyGestureEventHandler)
+ */
+ @RequiresPermission(Manifest.permission.MANAGE_KEY_GESTURES)
+ void unregisterKeyGestureEventHandler(@NonNull KeyGestureEventHandler handler) {
+ Objects.requireNonNull(handler, "handler should not be null");
+
+ synchronized (mKeyGestureEventHandlerLock) {
+ if (mKeyGestureEventHandlers == null) {
+ return;
+ }
+ mKeyGestureEventHandlers.removeIf(existingHandler -> existingHandler == handler);
+ if (mKeyGestureEventHandlers.isEmpty()) {
+ try {
+ mIm.unregisterKeyGestureHandler(mKeyGestureHandler);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ mKeyGestureEventHandlers = null;
+ mKeyGestureHandler = null;
+ }
+ }
+ }
+
/**
* TODO(b/330517633): Cleanup the unsupported API
*/
diff --git a/core/java/android/hardware/input/KeyGestureEvent.java b/core/java/android/hardware/input/KeyGestureEvent.java
index 7a8dd3395d21..c7ebc63a3d15 100644
--- a/core/java/android/hardware/input/KeyGestureEvent.java
+++ b/core/java/android/hardware/input/KeyGestureEvent.java
@@ -19,8 +19,11 @@ package android.hardware.input;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.view.Display;
+import android.view.KeyCharacterMap;
-import com.android.internal.util.DataClass;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.AnnotationValidations;
import com.android.internal.util.FrameworkStatsLog;
import java.lang.annotation.Retention;
@@ -31,501 +34,511 @@ import java.lang.annotation.RetentionPolicy;
*
* @hide
*/
-@DataClass(genToString = true, genEqualsHashCode = true)
-public class KeyGestureEvent {
+public final class KeyGestureEvent {
- private final int mDeviceId;
@NonNull
- private final int[] mKeycodes;
- private final int mModifierState;
- @KeyGestureType
- private final int mKeyGestureType;
-
-
- public static final int KEY_GESTURE_TYPE_UNSPECIFIED =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED;
- public static final int KEY_GESTURE_TYPE_HOME =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__HOME;
- public static final int KEY_GESTURE_TYPE_RECENT_APPS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__RECENT_APPS;
- public static final int KEY_GESTURE_TYPE_BACK =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BACK;
- public static final int KEY_GESTURE_TYPE_APP_SWITCH =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__APP_SWITCH;
- public static final int KEY_GESTURE_TYPE_LAUNCH_ASSISTANT =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_ASSISTANT;
- public static final int KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_VOICE_ASSISTANT;
- public static final int KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_SYSTEM_SETTINGS;
- public static final int KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_NOTIFICATION_PANEL;
- public static final int KEY_GESTURE_TYPE_TOGGLE_TASKBAR =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_TASKBAR;
- public static final int KEY_GESTURE_TYPE_TAKE_SCREENSHOT =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TAKE_SCREENSHOT;
- public static final int KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__OPEN_SHORTCUT_HELPER;
- public static final int KEY_GESTURE_TYPE_BRIGHTNESS_UP =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BRIGHTNESS_UP;
- public static final int KEY_GESTURE_TYPE_BRIGHTNESS_DOWN =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BRIGHTNESS_DOWN;
- public static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_UP;
- public static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_DOWN;
- public static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_TOGGLE;
- public static final int KEY_GESTURE_TYPE_VOLUME_UP =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_UP;
- public static final int KEY_GESTURE_TYPE_VOLUME_DOWN =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_DOWN;
- public static final int KEY_GESTURE_TYPE_VOLUME_MUTE =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_MUTE;
- public static final int KEY_GESTURE_TYPE_ALL_APPS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__ALL_APPS;
- public static final int KEY_GESTURE_TYPE_LAUNCH_SEARCH =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_SEARCH;
- public static final int KEY_GESTURE_TYPE_LANGUAGE_SWITCH =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LANGUAGE_SWITCH;
- public static final int KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__ACCESSIBILITY_ALL_APPS;
- public static final int KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_CAPS_LOCK;
- public static final int KEY_GESTURE_TYPE_SYSTEM_MUTE =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SYSTEM_MUTE;
- public static final int KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SPLIT_SCREEN_NAVIGATION;
- public static final int KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__CHANGE_SPLITSCREEN_FOCUS;
- public static final int KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TRIGGER_BUG_REPORT;
- public static final int KEY_GESTURE_TYPE_LOCK_SCREEN =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LOCK_SCREEN;
- public static final int KEY_GESTURE_TYPE_OPEN_NOTES =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__OPEN_NOTES;
- public static final int KEY_GESTURE_TYPE_TOGGLE_POWER =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_POWER;
- public static final int KEY_GESTURE_TYPE_SYSTEM_NAVIGATION =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SYSTEM_NAVIGATION;
- public static final int KEY_GESTURE_TYPE_SLEEP =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SLEEP;
- public static final int KEY_GESTURE_TYPE_WAKEUP =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__WAKEUP;
- public static final int KEY_GESTURE_TYPE_MEDIA_KEY =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MEDIA_KEY;
- public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_BROWSER;
- public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_EMAIL;
- public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CONTACTS;
- public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALENDAR;
- public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALCULATOR;
- public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MUSIC;
- public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MAPS;
- public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MESSAGING;
- public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_GALLERY;
- public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FILES;
- public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_WEATHER;
- public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FITNESS;
- public static final int KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_APPLICATION_BY_PACKAGE_NAME;
- public static final int KEY_GESTURE_TYPE_DESKTOP_MODE =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__DESKTOP_MODE;
- public static final int KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MULTI_WINDOW_NAVIGATION;
-
-
-
- // Code below generated by codegen v1.0.23.
- //
- // DO NOT MODIFY!
- // CHECKSTYLE:OFF Generated code
- //
- // To regenerate run:
- // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/hardware/input/KeyGestureEvent.java
- //
- // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
- // Settings > Editor > Code Style > Formatter Control
- //@formatter:off
-
+ private AidlKeyGestureEvent mKeyGestureEvent;
+
+ public static final int KEY_GESTURE_TYPE_UNSPECIFIED = 0;
+ public static final int KEY_GESTURE_TYPE_HOME = 1;
+ public static final int KEY_GESTURE_TYPE_RECENT_APPS = 2;
+ public static final int KEY_GESTURE_TYPE_BACK = 3;
+ public static final int KEY_GESTURE_TYPE_APP_SWITCH = 4;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_ASSISTANT = 5;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT = 6;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS = 7;
+ public static final int KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL = 8;
+ public static final int KEY_GESTURE_TYPE_TOGGLE_TASKBAR = 9;
+ public static final int KEY_GESTURE_TYPE_TAKE_SCREENSHOT = 10;
+ public static final int KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER = 11;
+ public static final int KEY_GESTURE_TYPE_BRIGHTNESS_UP = 12;
+ public static final int KEY_GESTURE_TYPE_BRIGHTNESS_DOWN = 13;
+ public static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP = 14;
+ public static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN = 15;
+ public static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE = 16;
+ public static final int KEY_GESTURE_TYPE_VOLUME_UP = 17;
+ public static final int KEY_GESTURE_TYPE_VOLUME_DOWN = 18;
+ public static final int KEY_GESTURE_TYPE_VOLUME_MUTE = 19;
+ public static final int KEY_GESTURE_TYPE_ALL_APPS = 20;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_SEARCH = 21;
+ public static final int KEY_GESTURE_TYPE_LANGUAGE_SWITCH = 22;
+ public static final int KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS = 23;
+ public static final int KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK = 24;
+ public static final int KEY_GESTURE_TYPE_SYSTEM_MUTE = 25;
+ public static final int KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION = 26;
+ public static final int KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS = 27;
+ public static final int KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT = 28;
+ public static final int KEY_GESTURE_TYPE_LOCK_SCREEN = 29;
+ public static final int KEY_GESTURE_TYPE_OPEN_NOTES = 30;
+ public static final int KEY_GESTURE_TYPE_TOGGLE_POWER = 31;
+ public static final int KEY_GESTURE_TYPE_SYSTEM_NAVIGATION = 32;
+ public static final int KEY_GESTURE_TYPE_SLEEP = 33;
+ public static final int KEY_GESTURE_TYPE_WAKEUP = 34;
+ public static final int KEY_GESTURE_TYPE_MEDIA_KEY = 35;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER = 36;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL = 37;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS = 38;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR = 39;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR = 40;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC = 41;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS = 42;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING = 43;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY = 44;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES = 45;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER = 46;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS = 47;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME = 48;
+ public static final int KEY_GESTURE_TYPE_DESKTOP_MODE = 49;
+ public static final int KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION = 50;
+
+ public static final int FLAG_CANCELLED = 1;
+
+ // NOTE: Valid KeyGestureEvent streams:
+ // - GESTURE_START -> GESTURE_CANCEL
+ // - GESTURE_START -> GESTURE_COMPLETE
+ // - GESTURE_COMPLETE
+
+ /** Key gesture started (e.g. Key down of the relevant key) */
+ public static final int ACTION_GESTURE_START = 1;
+ /** Key gesture completed (e.g. Key up of the relevant key) */
+ public static final int ACTION_GESTURE_COMPLETE = 2;
@IntDef(prefix = "KEY_GESTURE_TYPE_", value = {
- KEY_GESTURE_TYPE_UNSPECIFIED,
- KEY_GESTURE_TYPE_HOME,
- KEY_GESTURE_TYPE_RECENT_APPS,
- KEY_GESTURE_TYPE_BACK,
- KEY_GESTURE_TYPE_APP_SWITCH,
- KEY_GESTURE_TYPE_LAUNCH_ASSISTANT,
- KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT,
- KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS,
- KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL,
- KEY_GESTURE_TYPE_TOGGLE_TASKBAR,
- KEY_GESTURE_TYPE_TAKE_SCREENSHOT,
- KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER,
- KEY_GESTURE_TYPE_BRIGHTNESS_UP,
- KEY_GESTURE_TYPE_BRIGHTNESS_DOWN,
- KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP,
- KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN,
- KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE,
- KEY_GESTURE_TYPE_VOLUME_UP,
- KEY_GESTURE_TYPE_VOLUME_DOWN,
- KEY_GESTURE_TYPE_VOLUME_MUTE,
- KEY_GESTURE_TYPE_ALL_APPS,
- KEY_GESTURE_TYPE_LAUNCH_SEARCH,
- KEY_GESTURE_TYPE_LANGUAGE_SWITCH,
- KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS,
- KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK,
- KEY_GESTURE_TYPE_SYSTEM_MUTE,
- KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION,
- KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS,
- KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT,
- KEY_GESTURE_TYPE_LOCK_SCREEN,
- KEY_GESTURE_TYPE_OPEN_NOTES,
- KEY_GESTURE_TYPE_TOGGLE_POWER,
- KEY_GESTURE_TYPE_SYSTEM_NAVIGATION,
- KEY_GESTURE_TYPE_SLEEP,
- KEY_GESTURE_TYPE_WAKEUP,
- KEY_GESTURE_TYPE_MEDIA_KEY,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS,
- KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME,
- KEY_GESTURE_TYPE_DESKTOP_MODE,
- KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION
+ KEY_GESTURE_TYPE_UNSPECIFIED,
+ KEY_GESTURE_TYPE_HOME,
+ KEY_GESTURE_TYPE_RECENT_APPS,
+ KEY_GESTURE_TYPE_BACK,
+ KEY_GESTURE_TYPE_APP_SWITCH,
+ KEY_GESTURE_TYPE_LAUNCH_ASSISTANT,
+ KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT,
+ KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS,
+ KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL,
+ KEY_GESTURE_TYPE_TOGGLE_TASKBAR,
+ KEY_GESTURE_TYPE_TAKE_SCREENSHOT,
+ KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER,
+ KEY_GESTURE_TYPE_BRIGHTNESS_UP,
+ KEY_GESTURE_TYPE_BRIGHTNESS_DOWN,
+ KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP,
+ KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN,
+ KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE,
+ KEY_GESTURE_TYPE_VOLUME_UP,
+ KEY_GESTURE_TYPE_VOLUME_DOWN,
+ KEY_GESTURE_TYPE_VOLUME_MUTE,
+ KEY_GESTURE_TYPE_ALL_APPS,
+ KEY_GESTURE_TYPE_LAUNCH_SEARCH,
+ KEY_GESTURE_TYPE_LANGUAGE_SWITCH,
+ KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS,
+ KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK,
+ KEY_GESTURE_TYPE_SYSTEM_MUTE,
+ KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION,
+ KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS,
+ KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT,
+ KEY_GESTURE_TYPE_LOCK_SCREEN,
+ KEY_GESTURE_TYPE_OPEN_NOTES,
+ KEY_GESTURE_TYPE_TOGGLE_POWER,
+ KEY_GESTURE_TYPE_SYSTEM_NAVIGATION,
+ KEY_GESTURE_TYPE_SLEEP,
+ KEY_GESTURE_TYPE_WAKEUP,
+ KEY_GESTURE_TYPE_MEDIA_KEY,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS,
+ KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME,
+ KEY_GESTURE_TYPE_DESKTOP_MODE,
+ KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION,
})
@Retention(RetentionPolicy.SOURCE)
- @DataClass.Generated.Member
- public @interface KeyGestureType {}
+ public @interface KeyGestureType {
+ }
+
+ public KeyGestureEvent(@NonNull AidlKeyGestureEvent keyGestureEvent) {
+ this.mKeyGestureEvent = keyGestureEvent;
+ }
+
+ /**
+ * Key gesture event builder used to create a KeyGestureEvent for tests in Java.
+ *
+ * @hide
+ */
+ public static class Builder {
+ private int mDeviceId = KeyCharacterMap.VIRTUAL_KEYBOARD;
+ private int[] mKeycodes = new int[0];
+ private int mModifierState = 0;
+ @KeyGestureType
+ private int mKeyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED;
+ private int mAction = KeyGestureEvent.ACTION_GESTURE_COMPLETE;
+ private int mDisplayId = Display.DEFAULT_DISPLAY;
+ private int mFlags = 0;
+
+ /**
+ * @see KeyGestureEvent#getDeviceId()
+ */
+ public Builder setDeviceId(int deviceId) {
+ mDeviceId = deviceId;
+ return this;
+ }
+
+ /**
+ * @see KeyGestureEvent#getKeycodes()
+ */
+ public Builder setKeycodes(@NonNull int[] keycodes) {
+ mKeycodes = keycodes;
+ return this;
+ }
+
+ /**
+ * @see KeyGestureEvent#getModifierState()
+ */
+ public Builder setModifierState(int modifierState) {
+ mModifierState = modifierState;
+ return this;
+ }
+
+ /**
+ * @see KeyGestureEvent#getKeyGestureType()
+ */
+ public Builder setKeyGestureType(@KeyGestureEvent.KeyGestureType int keyGestureType) {
+ mKeyGestureType = keyGestureType;
+ return this;
+ }
+
+ /**
+ * @see KeyGestureEvent#getAction()
+ */
+ public Builder setAction(int action) {
+ mAction = action;
+ return this;
+ }
+
+ /**
+ * @see KeyGestureEvent#getDisplayId()
+ */
+ public Builder setDisplayId(int displayId) {
+ mDisplayId = displayId;
+ return this;
+ }
+
+ /**
+ * @see KeyGestureEvent#getFlags()
+ */
+ public Builder setFlags(int flags) {
+ mFlags = flags;
+ return this;
+ }
+
+ /**
+ * Build {@link KeyGestureEvent}
+ */
+ public KeyGestureEvent build() {
+ AidlKeyGestureEvent event = new AidlKeyGestureEvent();
+ event.deviceId = mDeviceId;
+ event.keycodes = mKeycodes;
+ event.modifierState = mModifierState;
+ event.gestureType = mKeyGestureType;
+ event.action = mAction;
+ event.displayId = mDisplayId;
+ event.flags = mFlags;
+ return new KeyGestureEvent(event);
+ }
+ }
+
+ public int getDeviceId() {
+ return mKeyGestureEvent.deviceId;
+ }
+
+ public @NonNull int[] getKeycodes() {
+ return mKeyGestureEvent.keycodes;
+ }
+
+ public int getModifierState() {
+ return mKeyGestureEvent.modifierState;
+ }
+
+ public @KeyGestureType int getKeyGestureType() {
+ return mKeyGestureEvent.gestureType;
+ }
+
+ public int getAction() {
+ return mKeyGestureEvent.action;
+ }
+
+ public int getDisplayId() {
+ return mKeyGestureEvent.displayId;
+ }
- @DataClass.Generated.Member
- public static String keyGestureTypeToString(@KeyGestureType int value) {
+ public int getFlags() {
+ return mKeyGestureEvent.flags;
+ }
+
+ public boolean isCancelled() {
+ return (mKeyGestureEvent.flags & FLAG_CANCELLED) != 0;
+ }
+
+ @Override
+ public String toString() {
+ return "KeyGestureEvent { "
+ + "deviceId = " + mKeyGestureEvent.deviceId + ", "
+ + "keycodes = " + java.util.Arrays.toString(mKeyGestureEvent.keycodes) + ", "
+ + "modifierState = " + mKeyGestureEvent.modifierState + ", "
+ + "keyGestureType = " + keyGestureTypeToString(mKeyGestureEvent.gestureType) + ", "
+ + "action = " + mKeyGestureEvent.action + ", "
+ + "displayId = " + mKeyGestureEvent.displayId + ", "
+ + "flags = " + mKeyGestureEvent.flags
+ + " }";
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ KeyGestureEvent that = (KeyGestureEvent) o;
+ return mKeyGestureEvent.deviceId == that.mKeyGestureEvent.deviceId
+ && java.util.Arrays.equals(mKeyGestureEvent.keycodes, that.mKeyGestureEvent.keycodes)
+ && mKeyGestureEvent.modifierState == that.mKeyGestureEvent.modifierState
+ && mKeyGestureEvent.gestureType == that.mKeyGestureEvent.gestureType
+ && mKeyGestureEvent.action == that.mKeyGestureEvent.action
+ && mKeyGestureEvent.displayId == that.mKeyGestureEvent.displayId
+ && mKeyGestureEvent.flags == that.mKeyGestureEvent.flags;
+ }
+
+ @Override
+ public int hashCode() {
+ int _hash = 1;
+ _hash = 31 * _hash + mKeyGestureEvent.deviceId;
+ _hash = 31 * _hash + java.util.Arrays.hashCode(mKeyGestureEvent.keycodes);
+ _hash = 31 * _hash + mKeyGestureEvent.modifierState;
+ _hash = 31 * _hash + mKeyGestureEvent.gestureType;
+ _hash = 31 * _hash + mKeyGestureEvent.action;
+ _hash = 31 * _hash + mKeyGestureEvent.displayId;
+ _hash = 31 * _hash + mKeyGestureEvent.flags;
+ return _hash;
+ }
+
+ /**
+ * Convert KeyGestureEvent type to corresponding log event got KeyboardSystemsEvent
+ */
+ public static int keyGestureTypeToLogEvent(@KeyGestureType int value) {
switch (value) {
- case KEY_GESTURE_TYPE_UNSPECIFIED:
- return "KEY_GESTURE_TYPE_UNSPECIFIED";
case KEY_GESTURE_TYPE_HOME:
- return "KEY_GESTURE_TYPE_HOME";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__HOME;
case KEY_GESTURE_TYPE_RECENT_APPS:
- return "KEY_GESTURE_TYPE_RECENT_APPS";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__RECENT_APPS;
case KEY_GESTURE_TYPE_BACK:
- return "KEY_GESTURE_TYPE_BACK";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BACK;
case KEY_GESTURE_TYPE_APP_SWITCH:
- return "KEY_GESTURE_TYPE_APP_SWITCH";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__APP_SWITCH;
case KEY_GESTURE_TYPE_LAUNCH_ASSISTANT:
- return "KEY_GESTURE_TYPE_LAUNCH_ASSISTANT";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_ASSISTANT;
case KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT:
- return "KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_VOICE_ASSISTANT;
case KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS:
- return "KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_SYSTEM_SETTINGS;
case KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL:
- return "KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_NOTIFICATION_PANEL;
case KEY_GESTURE_TYPE_TOGGLE_TASKBAR:
- return "KEY_GESTURE_TYPE_TOGGLE_TASKBAR";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_TASKBAR;
case KEY_GESTURE_TYPE_TAKE_SCREENSHOT:
- return "KEY_GESTURE_TYPE_TAKE_SCREENSHOT";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TAKE_SCREENSHOT;
case KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER:
- return "KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__OPEN_SHORTCUT_HELPER;
case KEY_GESTURE_TYPE_BRIGHTNESS_UP:
- return "KEY_GESTURE_TYPE_BRIGHTNESS_UP";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BRIGHTNESS_UP;
case KEY_GESTURE_TYPE_BRIGHTNESS_DOWN:
- return "KEY_GESTURE_TYPE_BRIGHTNESS_DOWN";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BRIGHTNESS_DOWN;
case KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP:
- return "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_UP;
case KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN:
- return "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_DOWN;
case KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE:
- return "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_TOGGLE;
case KEY_GESTURE_TYPE_VOLUME_UP:
- return "KEY_GESTURE_TYPE_VOLUME_UP";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_UP;
case KEY_GESTURE_TYPE_VOLUME_DOWN:
- return "KEY_GESTURE_TYPE_VOLUME_DOWN";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_DOWN;
case KEY_GESTURE_TYPE_VOLUME_MUTE:
- return "KEY_GESTURE_TYPE_VOLUME_MUTE";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_MUTE;
case KEY_GESTURE_TYPE_ALL_APPS:
- return "KEY_GESTURE_TYPE_ALL_APPS";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__ALL_APPS;
case KEY_GESTURE_TYPE_LAUNCH_SEARCH:
- return "KEY_GESTURE_TYPE_LAUNCH_SEARCH";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_SEARCH;
case KEY_GESTURE_TYPE_LANGUAGE_SWITCH:
- return "KEY_GESTURE_TYPE_LANGUAGE_SWITCH";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LANGUAGE_SWITCH;
case KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS:
- return "KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__ACCESSIBILITY_ALL_APPS;
case KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK:
- return "KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_CAPS_LOCK;
case KEY_GESTURE_TYPE_SYSTEM_MUTE:
- return "KEY_GESTURE_TYPE_SYSTEM_MUTE";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SYSTEM_MUTE;
case KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION:
- return "KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SPLIT_SCREEN_NAVIGATION;
case KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS:
- return "KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__CHANGE_SPLITSCREEN_FOCUS;
case KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT:
- return "KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TRIGGER_BUG_REPORT;
case KEY_GESTURE_TYPE_LOCK_SCREEN:
- return "KEY_GESTURE_TYPE_LOCK_SCREEN";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LOCK_SCREEN;
case KEY_GESTURE_TYPE_OPEN_NOTES:
- return "KEY_GESTURE_TYPE_OPEN_NOTES";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__OPEN_NOTES;
case KEY_GESTURE_TYPE_TOGGLE_POWER:
- return "KEY_GESTURE_TYPE_TOGGLE_POWER";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_POWER;
case KEY_GESTURE_TYPE_SYSTEM_NAVIGATION:
- return "KEY_GESTURE_TYPE_SYSTEM_NAVIGATION";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SYSTEM_NAVIGATION;
case KEY_GESTURE_TYPE_SLEEP:
- return "KEY_GESTURE_TYPE_SLEEP";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SLEEP;
case KEY_GESTURE_TYPE_WAKEUP:
- return "KEY_GESTURE_TYPE_WAKEUP";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__WAKEUP;
case KEY_GESTURE_TYPE_MEDIA_KEY:
- return "KEY_GESTURE_TYPE_MEDIA_KEY";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MEDIA_KEY;
case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER:
- return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_BROWSER;
case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL:
- return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_EMAIL;
case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS:
- return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CONTACTS;
case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR:
- return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALENDAR;
case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR:
- return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALCULATOR;
case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC:
- return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MUSIC;
case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS:
- return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MAPS;
case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING:
- return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MESSAGING;
case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY:
- return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_GALLERY;
case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES:
- return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FILES;
case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER:
- return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_WEATHER;
case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS:
- return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FITNESS;
case KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME:
- return "KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_APPLICATION_BY_PACKAGE_NAME;
case KEY_GESTURE_TYPE_DESKTOP_MODE:
- return "KEY_GESTURE_TYPE_DESKTOP_MODE";
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__DESKTOP_MODE;
case KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION:
- return "KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION";
- default: return Integer.toHexString(value);
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MULTI_WINDOW_NAVIGATION;
+ default:
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED;
}
}
- @DataClass.Generated.Member
- public KeyGestureEvent(
- int deviceId,
- @NonNull int[] keycodes,
- int modifierState,
- @KeyGestureType int keyGestureType) {
- this.mDeviceId = deviceId;
- this.mKeycodes = keycodes;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mKeycodes);
- this.mModifierState = modifierState;
- this.mKeyGestureType = keyGestureType;
-
- if (!(mKeyGestureType == KEY_GESTURE_TYPE_UNSPECIFIED)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_HOME)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_RECENT_APPS)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_BACK)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_APP_SWITCH)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_ASSISTANT)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_TOGGLE_TASKBAR)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_TAKE_SCREENSHOT)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_BRIGHTNESS_UP)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_BRIGHTNESS_DOWN)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_VOLUME_UP)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_VOLUME_DOWN)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_VOLUME_MUTE)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_ALL_APPS)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_SEARCH)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LANGUAGE_SWITCH)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_SYSTEM_MUTE)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LOCK_SCREEN)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_OPEN_NOTES)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_TOGGLE_POWER)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_SYSTEM_NAVIGATION)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_SLEEP)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_WAKEUP)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_MEDIA_KEY)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_DESKTOP_MODE)
- && !(mKeyGestureType == KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION)) {
- throw new java.lang.IllegalArgumentException(
- "keyGestureType was " + mKeyGestureType + " but must be one of: "
- + "KEY_GESTURE_TYPE_UNSPECIFIED(" + KEY_GESTURE_TYPE_UNSPECIFIED + "), "
- + "KEY_GESTURE_TYPE_HOME(" + KEY_GESTURE_TYPE_HOME + "), "
- + "KEY_GESTURE_TYPE_RECENT_APPS(" + KEY_GESTURE_TYPE_RECENT_APPS + "), "
- + "KEY_GESTURE_TYPE_BACK(" + KEY_GESTURE_TYPE_BACK + "), "
- + "KEY_GESTURE_TYPE_APP_SWITCH(" + KEY_GESTURE_TYPE_APP_SWITCH + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_ASSISTANT(" + KEY_GESTURE_TYPE_LAUNCH_ASSISTANT + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT(" + KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS(" + KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS + "), "
- + "KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL(" + KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL + "), "
- + "KEY_GESTURE_TYPE_TOGGLE_TASKBAR(" + KEY_GESTURE_TYPE_TOGGLE_TASKBAR + "), "
- + "KEY_GESTURE_TYPE_TAKE_SCREENSHOT(" + KEY_GESTURE_TYPE_TAKE_SCREENSHOT + "), "
- + "KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER(" + KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER + "), "
- + "KEY_GESTURE_TYPE_BRIGHTNESS_UP(" + KEY_GESTURE_TYPE_BRIGHTNESS_UP + "), "
- + "KEY_GESTURE_TYPE_BRIGHTNESS_DOWN(" + KEY_GESTURE_TYPE_BRIGHTNESS_DOWN + "), "
- + "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP(" + KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP + "), "
- + "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN(" + KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN + "), "
- + "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE(" + KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE + "), "
- + "KEY_GESTURE_TYPE_VOLUME_UP(" + KEY_GESTURE_TYPE_VOLUME_UP + "), "
- + "KEY_GESTURE_TYPE_VOLUME_DOWN(" + KEY_GESTURE_TYPE_VOLUME_DOWN + "), "
- + "KEY_GESTURE_TYPE_VOLUME_MUTE(" + KEY_GESTURE_TYPE_VOLUME_MUTE + "), "
- + "KEY_GESTURE_TYPE_ALL_APPS(" + KEY_GESTURE_TYPE_ALL_APPS + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_SEARCH(" + KEY_GESTURE_TYPE_LAUNCH_SEARCH + "), "
- + "KEY_GESTURE_TYPE_LANGUAGE_SWITCH(" + KEY_GESTURE_TYPE_LANGUAGE_SWITCH + "), "
- + "KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS(" + KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS + "), "
- + "KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK(" + KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK + "), "
- + "KEY_GESTURE_TYPE_SYSTEM_MUTE(" + KEY_GESTURE_TYPE_SYSTEM_MUTE + "), "
- + "KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION(" + KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION + "), "
- + "KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS(" + KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS + "), "
- + "KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT(" + KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT + "), "
- + "KEY_GESTURE_TYPE_LOCK_SCREEN(" + KEY_GESTURE_TYPE_LOCK_SCREEN + "), "
- + "KEY_GESTURE_TYPE_OPEN_NOTES(" + KEY_GESTURE_TYPE_OPEN_NOTES + "), "
- + "KEY_GESTURE_TYPE_TOGGLE_POWER(" + KEY_GESTURE_TYPE_TOGGLE_POWER + "), "
- + "KEY_GESTURE_TYPE_SYSTEM_NAVIGATION(" + KEY_GESTURE_TYPE_SYSTEM_NAVIGATION + "), "
- + "KEY_GESTURE_TYPE_SLEEP(" + KEY_GESTURE_TYPE_SLEEP + "), "
- + "KEY_GESTURE_TYPE_WAKEUP(" + KEY_GESTURE_TYPE_WAKEUP + "), "
- + "KEY_GESTURE_TYPE_MEDIA_KEY(" + KEY_GESTURE_TYPE_MEDIA_KEY + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS + "), "
- + "KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME(" + KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME + "), "
- + "KEY_GESTURE_TYPE_DESKTOP_MODE(" + KEY_GESTURE_TYPE_DESKTOP_MODE + "), "
- + "KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION(" + KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION + ")");
+ private static String keyGestureTypeToString(@KeyGestureType int value) {
+ switch (value) {
+ case KEY_GESTURE_TYPE_UNSPECIFIED:
+ return "KEY_GESTURE_TYPE_UNSPECIFIED";
+ case KEY_GESTURE_TYPE_HOME:
+ return "KEY_GESTURE_TYPE_HOME";
+ case KEY_GESTURE_TYPE_RECENT_APPS:
+ return "KEY_GESTURE_TYPE_RECENT_APPS";
+ case KEY_GESTURE_TYPE_BACK:
+ return "KEY_GESTURE_TYPE_BACK";
+ case KEY_GESTURE_TYPE_APP_SWITCH:
+ return "KEY_GESTURE_TYPE_APP_SWITCH";
+ case KEY_GESTURE_TYPE_LAUNCH_ASSISTANT:
+ return "KEY_GESTURE_TYPE_LAUNCH_ASSISTANT";
+ case KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT:
+ return "KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT";
+ case KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS:
+ return "KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS";
+ case KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL:
+ return "KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL";
+ case KEY_GESTURE_TYPE_TOGGLE_TASKBAR:
+ return "KEY_GESTURE_TYPE_TOGGLE_TASKBAR";
+ case KEY_GESTURE_TYPE_TAKE_SCREENSHOT:
+ return "KEY_GESTURE_TYPE_TAKE_SCREENSHOT";
+ case KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER:
+ return "KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER";
+ case KEY_GESTURE_TYPE_BRIGHTNESS_UP:
+ return "KEY_GESTURE_TYPE_BRIGHTNESS_UP";
+ case KEY_GESTURE_TYPE_BRIGHTNESS_DOWN:
+ return "KEY_GESTURE_TYPE_BRIGHTNESS_DOWN";
+ case KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP:
+ return "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP";
+ case KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN:
+ return "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN";
+ case KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE:
+ return "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE";
+ case KEY_GESTURE_TYPE_VOLUME_UP:
+ return "KEY_GESTURE_TYPE_VOLUME_UP";
+ case KEY_GESTURE_TYPE_VOLUME_DOWN:
+ return "KEY_GESTURE_TYPE_VOLUME_DOWN";
+ case KEY_GESTURE_TYPE_VOLUME_MUTE:
+ return "KEY_GESTURE_TYPE_VOLUME_MUTE";
+ case KEY_GESTURE_TYPE_ALL_APPS:
+ return "KEY_GESTURE_TYPE_ALL_APPS";
+ case KEY_GESTURE_TYPE_LAUNCH_SEARCH:
+ return "KEY_GESTURE_TYPE_LAUNCH_SEARCH";
+ case KEY_GESTURE_TYPE_LANGUAGE_SWITCH:
+ return "KEY_GESTURE_TYPE_LANGUAGE_SWITCH";
+ case KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS:
+ return "KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS";
+ case KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK:
+ return "KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK";
+ case KEY_GESTURE_TYPE_SYSTEM_MUTE:
+ return "KEY_GESTURE_TYPE_SYSTEM_MUTE";
+ case KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION:
+ return "KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION";
+ case KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS:
+ return "KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS";
+ case KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT:
+ return "KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT";
+ case KEY_GESTURE_TYPE_LOCK_SCREEN:
+ return "KEY_GESTURE_TYPE_LOCK_SCREEN";
+ case KEY_GESTURE_TYPE_OPEN_NOTES:
+ return "KEY_GESTURE_TYPE_OPEN_NOTES";
+ case KEY_GESTURE_TYPE_TOGGLE_POWER:
+ return "KEY_GESTURE_TYPE_TOGGLE_POWER";
+ case KEY_GESTURE_TYPE_SYSTEM_NAVIGATION:
+ return "KEY_GESTURE_TYPE_SYSTEM_NAVIGATION";
+ case KEY_GESTURE_TYPE_SLEEP:
+ return "KEY_GESTURE_TYPE_SLEEP";
+ case KEY_GESTURE_TYPE_WAKEUP:
+ return "KEY_GESTURE_TYPE_WAKEUP";
+ case KEY_GESTURE_TYPE_MEDIA_KEY:
+ return "KEY_GESTURE_TYPE_MEDIA_KEY";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS";
+ case KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME:
+ return "KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME";
+ case KEY_GESTURE_TYPE_DESKTOP_MODE:
+ return "KEY_GESTURE_TYPE_DESKTOP_MODE";
+ case KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION:
+ return "KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION";
+ default:
+ return Integer.toHexString(value);
}
-
-
- // onConstructed(); // You can define this method to get a callback
- }
-
- @DataClass.Generated.Member
- public int getDeviceId() {
- return mDeviceId;
}
-
- @DataClass.Generated.Member
- public @NonNull int[] getKeycodes() {
- return mKeycodes;
- }
-
- @DataClass.Generated.Member
- public int getModifierState() {
- return mModifierState;
- }
-
- @DataClass.Generated.Member
- public @KeyGestureType int getKeyGestureType() {
- return mKeyGestureType;
- }
-
- @Override
- @DataClass.Generated.Member
- public String toString() {
- // You can override field toString logic by defining methods like:
- // String fieldNameToString() { ... }
-
- return "KeyGestureEvent { " +
- "deviceId = " + mDeviceId + ", " +
- "keycodes = " + java.util.Arrays.toString(mKeycodes) + ", " +
- "modifierState = " + mModifierState + ", " +
- "keyGestureType = " + keyGestureTypeToString(mKeyGestureType) +
- " }";
- }
-
- @Override
- @DataClass.Generated.Member
- public boolean equals(@Nullable Object o) {
- // You can override field equality logic by defining either of the methods like:
- // boolean fieldNameEquals(KeyGestureEvent other) { ... }
- // boolean fieldNameEquals(FieldType otherValue) { ... }
-
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- @SuppressWarnings("unchecked")
- KeyGestureEvent that = (KeyGestureEvent) o;
- //noinspection PointlessBooleanExpression
- return true
- && mDeviceId == that.mDeviceId
- && java.util.Arrays.equals(mKeycodes, that.mKeycodes)
- && mModifierState == that.mModifierState
- && mKeyGestureType == that.mKeyGestureType;
- }
-
- @Override
- @DataClass.Generated.Member
- public int hashCode() {
- // You can override field hashCode logic by defining methods like:
- // int fieldNameHashCode() { ... }
-
- int _hash = 1;
- _hash = 31 * _hash + mDeviceId;
- _hash = 31 * _hash + java.util.Arrays.hashCode(mKeycodes);
- _hash = 31 * _hash + mModifierState;
- _hash = 31 * _hash + mKeyGestureType;
- return _hash;
- }
-
- @DataClass.Generated(
- time = 1723409092192L,
- codegenVersion = "1.0.23",
- sourceFile = "frameworks/base/core/java/android/hardware/input/KeyGestureEvent.java",
- inputSignatures = "private final int mDeviceId\nprivate final @android.annotation.NonNull int[] mKeycodes\nprivate final int mModifierState\nprivate final @android.hardware.input.KeyGestureEvent.KeyGestureType int mKeyGestureType\npublic static final int KEY_GESTURE_TYPE_UNSPECIFIED\npublic static final int KEY_GESTURE_TYPE_HOME\npublic static final int KEY_GESTURE_TYPE_RECENT_APPS\npublic static final int KEY_GESTURE_TYPE_BACK\npublic static final int KEY_GESTURE_TYPE_APP_SWITCH\npublic static final int KEY_GESTURE_TYPE_LAUNCH_ASSISTANT\npublic static final int KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT\npublic static final int KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS\npublic static final int KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL\npublic static final int KEY_GESTURE_TYPE_TOGGLE_TASKBAR\npublic static final int KEY_GESTURE_TYPE_TAKE_SCREENSHOT\npublic static final int KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER\npublic static final int KEY_GESTURE_TYPE_BRIGHTNESS_UP\npublic static final int KEY_GESTURE_TYPE_BRIGHTNESS_DOWN\npublic static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP\npublic static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN\npublic static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE\npublic static final int KEY_GESTURE_TYPE_VOLUME_UP\npublic static final int KEY_GESTURE_TYPE_VOLUME_DOWN\npublic static final int KEY_GESTURE_TYPE_VOLUME_MUTE\npublic static final int KEY_GESTURE_TYPE_ALL_APPS\npublic static final int KEY_GESTURE_TYPE_LAUNCH_SEARCH\npublic static final int KEY_GESTURE_TYPE_LANGUAGE_SWITCH\npublic static final int KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS\npublic static final int KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK\npublic static final int KEY_GESTURE_TYPE_SYSTEM_MUTE\npublic static final int KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION\npublic static final int KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS\npublic static final int KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT\npublic static final int KEY_GESTURE_TYPE_LOCK_SCREEN\npublic static final int KEY_GESTURE_TYPE_OPEN_NOTES\npublic static final int KEY_GESTURE_TYPE_TOGGLE_POWER\npublic static final int KEY_GESTURE_TYPE_SYSTEM_NAVIGATION\npublic static final int KEY_GESTURE_TYPE_SLEEP\npublic static final int KEY_GESTURE_TYPE_WAKEUP\npublic static final int KEY_GESTURE_TYPE_MEDIA_KEY\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS\npublic static final int KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME\npublic static final int KEY_GESTURE_TYPE_DESKTOP_MODE\npublic static final int KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION\nclass KeyGestureEvent extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true)")
- @Deprecated
- private void __metadata() {}
-
-
- //@formatter:on
- // End of generated code
-
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
index 25c533685ba7..64915fbf551f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
@@ -261,12 +261,12 @@ class KeyboardTouchpadEduInteractorTest : SysuiTestCase() {
.registerKeyGestureEventListener(any(), listenerCaptor.capture())
val allAppsKeyGestureEvent =
- KeyGestureEvent(
- /* deviceId= */ 1,
- IntArray(0),
- KeyEvent.META_META_ON,
- KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS
- )
+ KeyGestureEvent.Builder()
+ .setDeviceId(1)
+ .setModifierState(KeyEvent.META_META_ON)
+ .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS)
+ .setAction(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
+ .build()
listenerCaptor.value.onKeyGestureEvent(allAppsKeyGestureEvent)
val model by
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 1285a61d08f2..5dc1dda3b5ab 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -52,6 +52,7 @@ import android.hardware.input.IInputDevicesChangedListener;
import android.hardware.input.IInputManager;
import android.hardware.input.IInputSensorEventListener;
import android.hardware.input.IKeyGestureEventListener;
+import android.hardware.input.IKeyGestureHandler;
import android.hardware.input.IKeyboardBacklightListener;
import android.hardware.input.IStickyModifierStateListener;
import android.hardware.input.ITabletModeChangedListener;
@@ -164,7 +165,6 @@ public class InputManagerService extends IInputManager.Stub
private static final int MSG_DELIVER_INPUT_DEVICES_CHANGED = 1;
private static final int MSG_RELOAD_DEVICE_ALIASES = 2;
private static final int MSG_DELIVER_TABLET_MODE_CHANGED = 3;
- private static final int MSG_KEY_GESTURE_COMPLETED = 4;
private static final int DEFAULT_VIBRATION_MAGNITUDE = 192;
private static final AdditionalDisplayInputProperties
@@ -476,7 +476,7 @@ public class InputManagerService extends IInputManager.Stub
injector.getLooper(), injector.getUEventManager())
: new KeyboardBacklightControllerInterface() {};
mStickyModifierStateController = new StickyModifierStateController();
- mKeyGestureController = new KeyGestureController();
+ mKeyGestureController = new KeyGestureController(mContext, injector.getLooper());
mKeyboardLedController = new KeyboardLedController(mContext, injector.getLooper(),
mNative);
mKeyRemapper = new KeyRemapper(mContext, mNative, mDataStore, injector.getLooper());
@@ -2464,6 +2464,11 @@ public class InputManagerService extends IInputManager.Stub
// Native callback.
@SuppressWarnings("unused")
private long interceptKeyBeforeDispatching(IBinder focus, KeyEvent event, int policyFlags) {
+ // TODO(b/358569822): Move shortcut trigger logic from PWM to KeyGestureController
+ long value = mKeyGestureController.interceptKeyBeforeDispatching(focus, event, policyFlags);
+ if (value != 0) { // If key is consumed (i.e. non-zero value)
+ return value;
+ }
return mWindowManagerCallbacks.interceptKeyBeforeDispatching(focus, event, policyFlags);
}
@@ -2769,33 +2774,38 @@ public class InputManagerService extends IInputManager.Stub
@Override
@PermissionManuallyEnforced
- public void registerKeyGestureEventListener(
- @NonNull IKeyGestureEventListener listener) {
+ public void registerKeyGestureEventListener(@NonNull IKeyGestureEventListener listener) {
enforceManageKeyGesturePermission();
Objects.requireNonNull(listener);
- mKeyGestureController.registerKeyGestureEventListener(listener,
- Binder.getCallingPid());
+ mKeyGestureController.registerKeyGestureEventListener(listener, Binder.getCallingPid());
}
@Override
@PermissionManuallyEnforced
- public void unregisterKeyGestureEventListener(
- @NonNull IKeyGestureEventListener listener) {
+ public void unregisterKeyGestureEventListener(@NonNull IKeyGestureEventListener listener) {
enforceManageKeyGesturePermission();
Objects.requireNonNull(listener);
- mKeyGestureController.unregisterKeyGestureEventListener(listener,
- Binder.getCallingPid());
+ mKeyGestureController.unregisterKeyGestureEventListener(listener, Binder.getCallingPid());
}
- private void handleKeyGestureCompleted(KeyGestureEvent event) {
- InputDevice device = getInputDevice(event.getDeviceId());
- if (device == null || device.isVirtual()) {
- return;
- }
- KeyboardMetricsCollector.logKeyboardSystemsEventReportedAtom(device, event);
- mKeyGestureController.onKeyGestureEvent(event);
+ @Override
+ @PermissionManuallyEnforced
+ public void registerKeyGestureHandler(@NonNull IKeyGestureHandler handler) {
+ enforceManageKeyGesturePermission();
+
+ Objects.requireNonNull(handler);
+ mKeyGestureController.registerKeyGestureHandler(handler, Binder.getCallingPid());
+ }
+
+ @Override
+ @PermissionManuallyEnforced
+ public void unregisterKeyGestureHandler(@NonNull IKeyGestureHandler handler) {
+ enforceManageKeyGesturePermission();
+
+ Objects.requireNonNull(handler);
+ mKeyGestureController.unregisterKeyGestureHandler(handler, Binder.getCallingPid());
}
/**
@@ -2966,9 +2976,6 @@ public class InputManagerService extends IInputManager.Stub
boolean inTabletMode = (boolean) args.arg1;
deliverTabletModeChanged(whenNanos, inTabletMode);
break;
- case MSG_KEY_GESTURE_COMPLETED:
- KeyGestureEvent event = (KeyGestureEvent) msg.obj;
- handleKeyGestureCompleted(event);
}
}
}
@@ -3298,9 +3305,8 @@ public class InputManagerService extends IInputManager.Stub
@Override
public void notifyKeyGestureCompleted(int deviceId, int[] keycodes, int modifierState,
@KeyGestureEvent.KeyGestureType int gestureType) {
- mHandler.obtainMessage(MSG_KEY_GESTURE_COMPLETED,
- new KeyGestureEvent(deviceId, keycodes, modifierState,
- gestureType)).sendToTarget();
+ mKeyGestureController.notifyKeyGestureCompleted(deviceId, keycodes, modifierState,
+ gestureType);
}
}
diff --git a/services/core/java/com/android/server/input/KeyGestureController.java b/services/core/java/com/android/server/input/KeyGestureController.java
index 674d3c448c86..bfdb1c1f4ea9 100644
--- a/services/core/java/com/android/server/input/KeyGestureController.java
+++ b/services/core/java/com/android/server/input/KeyGestureController.java
@@ -17,15 +17,32 @@
package com.android.server.input;
import android.annotation.BinderThread;
+import android.annotation.MainThread;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.input.AidlKeyGestureEvent;
import android.hardware.input.IKeyGestureEventListener;
+import android.hardware.input.IKeyGestureHandler;
+import android.hardware.input.InputManager;
import android.hardware.input.KeyGestureEvent;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
+import android.view.Display;
+import android.view.InputDevice;
+import android.view.KeyEvent;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Objects;
+import java.util.TreeMap;
/**
* A thread-safe component of {@link InputManagerService} responsible for managing callbacks when a
@@ -39,12 +56,101 @@ final class KeyGestureController {
// 'adb shell setprop log.tag.KeyGestureController DEBUG' (requires restart)
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final int MSG_NOTIFY_KEY_GESTURE_EVENT = 1;
+
+ private final Context mContext;
+ private final Handler mHandler;
+ private final int mSystemPid;
+
// List of currently registered key gesture event listeners keyed by process pid
@GuardedBy("mKeyGestureEventListenerRecords")
private final SparseArray<KeyGestureEventListenerRecord>
mKeyGestureEventListenerRecords = new SparseArray<>();
- public void onKeyGestureEvent(KeyGestureEvent event) {
+ // List of currently registered key gesture event handler keyed by process pid. The map sorts
+ // in the order of preference of the handlers, and we prioritize handlers in system server
+ // over external handlers..
+ @GuardedBy("mKeyGestureHandlerRecords")
+ private final TreeMap<Integer, KeyGestureHandlerRecord> mKeyGestureHandlerRecords;
+
+ KeyGestureController(Context context, Looper looper) {
+ mContext = context;
+ mHandler = new Handler(looper, this::handleMessage);
+ mSystemPid = Process.myPid();
+ mKeyGestureHandlerRecords = new TreeMap<>((p1, p2) -> {
+ if (Objects.equals(p1, p2)) {
+ return 0;
+ }
+ if (p1 == mSystemPid) {
+ return -1;
+ } else if (p2 == mSystemPid) {
+ return 1;
+ } else {
+ return Integer.compare(p1, p2);
+ }
+ });
+ }
+
+ public int interceptKeyBeforeDispatching(IBinder focus, KeyEvent event, int policyFlags) {
+ // TODO(b/358569822): Handle shortcuts trigger logic here and pass it to appropriate
+ // KeyGestureHandler (PWM is one of the handlers)
+ return 0;
+ }
+
+ @VisibleForTesting
+ boolean handleKeyGesture(int deviceId, int[] keycodes, int modifierState,
+ @KeyGestureEvent.KeyGestureType int gestureType, int action, int displayId,
+ IBinder focusedToken, int flags) {
+ AidlKeyGestureEvent event = createKeyGestureEvent(deviceId, keycodes,
+ modifierState, gestureType, action, displayId, flags);
+ synchronized (mKeyGestureHandlerRecords) {
+ for (KeyGestureHandlerRecord handler : mKeyGestureHandlerRecords.values()) {
+ if (handler.handleKeyGesture(event, focusedToken)) {
+ Message msg = Message.obtain(mHandler, MSG_NOTIFY_KEY_GESTURE_EVENT, event);
+ mHandler.sendMessage(msg);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean isKeyGestureSupported(@KeyGestureEvent.KeyGestureType int gestureType) {
+ synchronized (mKeyGestureHandlerRecords) {
+ for (KeyGestureHandlerRecord handler : mKeyGestureHandlerRecords.values()) {
+ if (handler.isKeyGestureSupported(gestureType)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public void notifyKeyGestureCompleted(int deviceId, int[] keycodes, int modifierState,
+ @KeyGestureEvent.KeyGestureType int gestureType) {
+ // TODO(b/358569822): Once we move the gesture detection logic to IMS, we ideally
+ // should not rely on PWM to tell us about the gesture start and end.
+ AidlKeyGestureEvent event = createKeyGestureEvent(deviceId, keycodes, modifierState,
+ gestureType, KeyGestureEvent.ACTION_GESTURE_COMPLETE, Display.DEFAULT_DISPLAY, 0);
+ mHandler.obtainMessage(MSG_NOTIFY_KEY_GESTURE_EVENT, event).sendToTarget();
+ }
+
+ @MainThread
+ private void notifyKeyGestureEvent(AidlKeyGestureEvent event) {
+ InputDevice device = getInputDevice(event.deviceId);
+ if (device == null || device.isVirtual()) {
+ return;
+ }
+ if (event.action == KeyGestureEvent.ACTION_GESTURE_COMPLETE) {
+ KeyboardMetricsCollector.logKeyboardSystemsEventReportedAtom(device, event.keycodes,
+ event.modifierState,
+ KeyGestureEvent.keyGestureTypeToLogEvent(event.gestureType));
+ }
+ notifyAllListeners(event);
+ }
+
+ @MainThread
+ private void notifyAllListeners(AidlKeyGestureEvent event) {
if (DEBUG) {
Slog.d(TAG, "Key gesture event occurred, event = " + event);
}
@@ -56,17 +162,26 @@ final class KeyGestureController {
}
}
+ @MainThread
+ private boolean handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_NOTIFY_KEY_GESTURE_EVENT:
+ AidlKeyGestureEvent event = (AidlKeyGestureEvent) msg.obj;
+ notifyKeyGestureEvent(event);
+ break;
+ }
+ return true;
+ }
+
/** Register the key gesture event listener for a process. */
@BinderThread
- public void registerKeyGestureEventListener(IKeyGestureEventListener listener,
- int pid) {
+ public void registerKeyGestureEventListener(IKeyGestureEventListener listener, int pid) {
synchronized (mKeyGestureEventListenerRecords) {
if (mKeyGestureEventListenerRecords.get(pid) != null) {
throw new IllegalStateException("The calling process has already registered "
+ "a KeyGestureEventListener.");
}
- KeyGestureEventListenerRecord record = new KeyGestureEventListenerRecord(
- pid, listener);
+ KeyGestureEventListenerRecord record = new KeyGestureEventListenerRecord(pid, listener);
try {
listener.asBinder().linkToDeath(record, 0);
} catch (RemoteException ex) {
@@ -78,8 +193,7 @@ final class KeyGestureController {
/** Unregister the key gesture event listener for a process. */
@BinderThread
- public void unregisterKeyGestureEventListener(IKeyGestureEventListener listener,
- int pid) {
+ public void unregisterKeyGestureEventListener(IKeyGestureEventListener listener, int pid) {
synchronized (mKeyGestureEventListenerRecords) {
KeyGestureEventListenerRecord record =
mKeyGestureEventListenerRecords.get(pid);
@@ -120,10 +234,9 @@ final class KeyGestureController {
onKeyGestureEventListenerDied(mPid);
}
- public void onKeyGestureEvent(KeyGestureEvent event) {
+ public void onKeyGestureEvent(AidlKeyGestureEvent event) {
try {
- mListener.onKeyGestureEvent(event.getDeviceId(), event.getKeycodes(),
- event.getModifierState(), event.getKeyGestureType());
+ mListener.onKeyGestureEvent(event);
} catch (RemoteException ex) {
Slog.w(TAG, "Failed to notify process " + mPid
+ " that key gesture event occurred, assuming it died.", ex);
@@ -131,4 +244,107 @@ final class KeyGestureController {
}
}
}
+
+ /** Register the key gesture event handler for a process. */
+ @BinderThread
+ public void registerKeyGestureHandler(IKeyGestureHandler handler, int pid) {
+ synchronized (mKeyGestureHandlerRecords) {
+ if (mKeyGestureHandlerRecords.get(pid) != null) {
+ throw new IllegalStateException("The calling process has already registered "
+ + "a KeyGestureHandler.");
+ }
+ KeyGestureHandlerRecord record = new KeyGestureHandlerRecord(pid, handler);
+ try {
+ handler.asBinder().linkToDeath(record, 0);
+ } catch (RemoteException ex) {
+ throw new RuntimeException(ex);
+ }
+ mKeyGestureHandlerRecords.put(pid, record);
+ }
+ }
+
+ /** Unregister the key gesture event handler for a process. */
+ @BinderThread
+ public void unregisterKeyGestureHandler(IKeyGestureHandler handler, int pid) {
+ synchronized (mKeyGestureHandlerRecords) {
+ KeyGestureHandlerRecord record = mKeyGestureHandlerRecords.get(pid);
+ if (record == null) {
+ throw new IllegalStateException("The calling process has no registered "
+ + "KeyGestureHandler.");
+ }
+ if (record.mKeyGestureHandler.asBinder() != handler.asBinder()) {
+ throw new IllegalStateException("The calling process has a different registered "
+ + "KeyGestureHandler.");
+ }
+ record.mKeyGestureHandler.asBinder().unlinkToDeath(record, 0);
+ mKeyGestureHandlerRecords.remove(pid);
+ }
+ }
+
+ private void onKeyGestureHandlerDied(int pid) {
+ synchronized (mKeyGestureHandlerRecords) {
+ mKeyGestureHandlerRecords.remove(pid);
+ }
+ }
+
+ // A record of a registered key gesture event listener from one process.
+ private class KeyGestureHandlerRecord implements IBinder.DeathRecipient {
+ public final int mPid;
+ public final IKeyGestureHandler mKeyGestureHandler;
+
+ KeyGestureHandlerRecord(int pid, IKeyGestureHandler keyGestureHandler) {
+ mPid = pid;
+ mKeyGestureHandler = keyGestureHandler;
+ }
+
+ @Override
+ public void binderDied() {
+ if (DEBUG) {
+ Slog.d(TAG, "Key gesture event handler for pid " + mPid + " died.");
+ }
+ onKeyGestureHandlerDied(mPid);
+ }
+
+ public boolean handleKeyGesture(AidlKeyGestureEvent event, IBinder focusedToken) {
+ try {
+ return mKeyGestureHandler.handleKeyGesture(event, focusedToken);
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Failed to send key gesture to process " + mPid
+ + ", assuming it died.", ex);
+ binderDied();
+ }
+ return false;
+ }
+
+ public boolean isKeyGestureSupported(@KeyGestureEvent.KeyGestureType int gestureType) {
+ try {
+ return mKeyGestureHandler.isKeyGestureSupported(gestureType);
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Failed to identify if key gesture type is supported by the "
+ + "process " + mPid + ", assuming it died.", ex);
+ binderDied();
+ }
+ return false;
+ }
+ }
+
+ @Nullable
+ private InputDevice getInputDevice(int deviceId) {
+ InputManager inputManager = mContext.getSystemService(InputManager.class);
+ return inputManager != null ? inputManager.getInputDevice(deviceId) : null;
+ }
+
+ private AidlKeyGestureEvent createKeyGestureEvent(int deviceId, int[] keycodes,
+ int modifierState, @KeyGestureEvent.KeyGestureType int gestureType, int action,
+ int displayId, int flags) {
+ AidlKeyGestureEvent event = new AidlKeyGestureEvent();
+ event.deviceId = deviceId;
+ event.keycodes = keycodes;
+ event.modifierState = modifierState;
+ event.gestureType = gestureType;
+ event.action = action;
+ event.displayId = displayId;
+ event.flags = flags;
+ return event;
+ }
}
diff --git a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
index 1daf4db699aa..609164a48687 100644
--- a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
+++ b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
@@ -24,7 +24,6 @@ import static android.hardware.input.KeyboardLayoutSelectionResult.layoutSelecti
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.hardware.input.KeyGestureEvent;
import android.hardware.input.KeyboardLayout;
import android.hardware.input.KeyboardLayoutSelectionResult.LayoutSelectionCriteria;
import android.icu.util.ULocale;
@@ -41,6 +40,7 @@ import com.android.internal.os.KeyboardConfiguredProto.RepeatedKeyboardLayoutCon
import com.android.internal.util.FrameworkStatsLog;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -60,23 +60,26 @@ public final class KeyboardMetricsCollector {
@VisibleForTesting
public static final String DEFAULT_LANGUAGE_TAG = "None";
+ private static final int INVALID_SYSTEMS_EVENT = FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED;
+
/**
* Log keyboard system shortcuts for the proto
* {@link com.android.os.input.KeyboardSystemsEventReported}
* defined in "stats/atoms/input/input_extension_atoms.proto"
*/
public static void logKeyboardSystemsEventReportedAtom(@NonNull InputDevice inputDevice,
- @NonNull KeyGestureEvent keyGestureEvent) {
- if (inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) {
+ int[] keycodes, int modifierState, int systemsEvent) {
+ if (systemsEvent == INVALID_SYSTEMS_EVENT || inputDevice.isVirtual()
+ || !inputDevice.isFullKeyboard()) {
return;
}
FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED,
inputDevice.getVendorId(), inputDevice.getProductId(),
- keyGestureEvent.getKeyGestureType(), keyGestureEvent.getKeycodes(),
- keyGestureEvent.getModifierState(), inputDevice.getDeviceBus());
+ systemsEvent, keycodes, modifierState, inputDevice.getDeviceBus());
if (DEBUG) {
- Slog.d(TAG, "Logging Keyboard system event: " + keyGestureEvent);
+ Slog.d(TAG, "Logging Keyboard system event: " + modifierState + " + " + Arrays.toString(
+ keycodes) + " -> " + systemsEvent);
}
}
diff --git a/tests/Input/src/android/hardware/input/KeyGestureEventHandlerTest.kt b/tests/Input/src/android/hardware/input/KeyGestureEventHandlerTest.kt
new file mode 100644
index 000000000000..072341dcefae
--- /dev/null
+++ b/tests/Input/src/android/hardware/input/KeyGestureEventHandlerTest.kt
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input
+
+import android.content.Context
+import android.content.ContextWrapper
+import android.os.Handler
+import android.os.IBinder
+import android.os.test.TestLooper
+import android.platform.test.annotations.Presubmit
+import android.platform.test.flag.junit.SetFlagsRule
+import android.view.KeyEvent
+import androidx.test.core.app.ApplicationProvider
+import com.android.server.testutils.any
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.doAnswer
+import org.mockito.Mockito.`when`
+import org.mockito.junit.MockitoJUnitRunner
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+import kotlin.test.assertNull
+import kotlin.test.fail
+
+/**
+ * Tests for [InputManager.KeyGestureEventHandler].
+ *
+ * Build/Install/Run:
+ * atest InputTests:KeyGestureEventHandlerTest
+ */
+@Presubmit
+@RunWith(MockitoJUnitRunner::class)
+class KeyGestureEventHandlerTest {
+
+ companion object {
+ const val DEVICE_ID = 1
+ val HOME_GESTURE_EVENT = KeyGestureEvent.Builder()
+ .setDeviceId(DEVICE_ID)
+ .setKeycodes(intArrayOf(KeyEvent.KEYCODE_H))
+ .setModifierState(KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON)
+ .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_HOME)
+ .build()
+ val BACK_GESTURE_EVENT = KeyGestureEvent.Builder()
+ .setDeviceId(DEVICE_ID)
+ .setKeycodes(intArrayOf(KeyEvent.KEYCODE_DEL))
+ .setModifierState(KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON)
+ .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_BACK)
+ .build()
+ }
+
+ @get:Rule
+ val rule = SetFlagsRule()
+
+ private val testLooper = TestLooper()
+ private var registeredListener: IKeyGestureHandler? = null
+ private lateinit var context: Context
+ private lateinit var inputManager: InputManager
+ private lateinit var inputManagerGlobalSession: InputManagerGlobal.TestSession
+
+ @Mock
+ private lateinit var iInputManagerMock: IInputManager
+
+ @Before
+ fun setUp() {
+ context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
+ inputManagerGlobalSession = InputManagerGlobal.createTestSession(iInputManagerMock)
+ inputManager = InputManager(context)
+ `when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE)))
+ .thenReturn(inputManager)
+
+ // Handle key gesture handler registration.
+ doAnswer {
+ val listener = it.getArgument(0) as IKeyGestureHandler
+ if (registeredListener != null &&
+ registeredListener!!.asBinder() != listener.asBinder()) {
+ // There can only be one registered key gesture handler per process.
+ fail("Trying to register a new listener when one already exists")
+ }
+ registeredListener = listener
+ null
+ }.`when`(iInputManagerMock).registerKeyGestureHandler(any())
+
+ // Handle key gesture handler being unregistered.
+ doAnswer {
+ val listener = it.getArgument(0) as IKeyGestureHandler
+ if (registeredListener == null ||
+ registeredListener!!.asBinder() != listener.asBinder()) {
+ fail("Trying to unregister a listener that is not registered")
+ }
+ registeredListener = null
+ null
+ }.`when`(iInputManagerMock).unregisterKeyGestureHandler(any())
+ }
+
+ @After
+ fun tearDown() {
+ if (this::inputManagerGlobalSession.isInitialized) {
+ inputManagerGlobalSession.close()
+ }
+ }
+
+ private fun handleKeyGestureEvent(event: KeyGestureEvent) {
+ val eventToSend = AidlKeyGestureEvent()
+ eventToSend.deviceId = event.deviceId
+ eventToSend.keycodes = event.keycodes
+ eventToSend.modifierState = event.modifierState
+ eventToSend.gestureType = event.keyGestureType
+ eventToSend.action = event.action
+ eventToSend.displayId = event.displayId
+ eventToSend.flags = event.flags
+ registeredListener!!.handleKeyGesture(eventToSend, null)
+ }
+
+ @Test
+ fun testHandlerHasCorrectGestureNotified() {
+ var callbackCount = 0
+
+ // Add a key gesture event listener
+ inputManager.registerKeyGestureEventHandler(KeyGestureHandler { event, _ ->
+ assertEquals(HOME_GESTURE_EVENT, event)
+ callbackCount++
+ true
+ })
+
+ // Request handling for key gesture event will notify the handler.
+ handleKeyGestureEvent(HOME_GESTURE_EVENT)
+ assertEquals(1, callbackCount)
+ }
+
+ @Test
+ fun testAddingHandlersRegistersInternalCallbackHandler() {
+ // Set up two callbacks.
+ val callback1 = KeyGestureHandler { _, _ -> false }
+ val callback2 = KeyGestureHandler { _, _ -> false }
+
+ assertNull(registeredListener)
+
+ // Adding the handler should register the callback with InputManagerService.
+ inputManager.registerKeyGestureEventHandler(callback1)
+ assertNotNull(registeredListener)
+
+ // Adding another handler should not register new internal listener.
+ val currListener = registeredListener
+ inputManager.registerKeyGestureEventHandler(callback2)
+ assertEquals(currListener, registeredListener)
+ }
+
+ @Test
+ fun testRemovingHandlersUnregistersInternalCallbackHandler() {
+ // Set up two callbacks.
+ val callback1 = KeyGestureHandler { _, _ -> false }
+ val callback2 = KeyGestureHandler { _, _ -> false }
+
+ inputManager.registerKeyGestureEventHandler(callback1)
+ inputManager.registerKeyGestureEventHandler(callback2)
+
+ // Only removing all handlers should remove the internal callback
+ inputManager.unregisterKeyGestureEventHandler(callback1)
+ assertNotNull(registeredListener)
+ inputManager.unregisterKeyGestureEventHandler(callback2)
+ assertNull(registeredListener)
+ }
+
+ @Test
+ fun testMultipleHandlers() {
+ // Set up two callbacks.
+ var callbackCount1 = 0
+ var callbackCount2 = 0
+ // Handler 1 captures all home gestures
+ val callback1 = KeyGestureHandler { event, _ ->
+ callbackCount1++
+ event.keyGestureType == KeyGestureEvent.KEY_GESTURE_TYPE_HOME
+ }
+ // Handler 2 captures all gestures
+ val callback2 = KeyGestureHandler { _, _ ->
+ callbackCount2++
+ true
+ }
+
+ // Add both key gesture event handlers
+ inputManager.registerKeyGestureEventHandler(callback1)
+ inputManager.registerKeyGestureEventHandler(callback2)
+
+ // Request handling for key gesture event, should notify callbacks in order. So, only the
+ // first handler should receive a callback since it captures the event.
+ handleKeyGestureEvent(HOME_GESTURE_EVENT)
+ assertEquals(1, callbackCount1)
+ assertEquals(0, callbackCount2)
+
+ // Second handler should receive the event since the first handler doesn't capture the event
+ handleKeyGestureEvent(BACK_GESTURE_EVENT)
+ assertEquals(2, callbackCount1)
+ assertEquals(1, callbackCount2)
+
+ inputManager.unregisterKeyGestureEventHandler(callback1)
+ // Request handling for key gesture event, should still trigger callback2 but not callback1.
+ handleKeyGestureEvent(HOME_GESTURE_EVENT)
+ assertEquals(2, callbackCount1)
+ assertEquals(2, callbackCount2)
+ }
+
+ inner class KeyGestureHandler(
+ private var handler: (event: KeyGestureEvent, token: IBinder?) -> Boolean
+ ) : InputManager.KeyGestureEventHandler {
+
+ override fun handleKeyGestureEvent(
+ event: KeyGestureEvent,
+ focusedToken: IBinder?
+ ): Boolean {
+ return handler(event, focusedToken)
+ }
+
+ override fun isKeyGestureSupported(gestureType: Int): Boolean {
+ return true
+ }
+ }
+}
diff --git a/tests/Input/src/android/hardware/input/KeyGestureEventListenerTest.kt b/tests/Input/src/android/hardware/input/KeyGestureEventListenerTest.kt
index 14aac6637d4f..ca9de6000a5a 100644
--- a/tests/Input/src/android/hardware/input/KeyGestureEventListenerTest.kt
+++ b/tests/Input/src/android/hardware/input/KeyGestureEventListenerTest.kt
@@ -53,12 +53,12 @@ class KeyGestureEventListenerTest {
companion object {
const val DEVICE_ID = 1
- val HOME_GESTURE_EVENT = KeyGestureEvent(
- DEVICE_ID,
- intArrayOf(KeyEvent.KEYCODE_H),
- KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON,
- KeyGestureEvent.KEY_GESTURE_TYPE_HOME
- )
+ val HOME_GESTURE_EVENT = KeyGestureEvent.Builder()
+ .setDeviceId(DEVICE_ID)
+ .setKeycodes(intArrayOf(KeyEvent.KEYCODE_H))
+ .setModifierState(KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON)
+ .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_HOME)
+ .build()
}
@get:Rule
@@ -114,12 +114,15 @@ class KeyGestureEventListenerTest {
}
private fun notifyKeyGestureEvent(event: KeyGestureEvent) {
- registeredListener!!.onKeyGestureEvent(
- event.deviceId,
- event.keycodes,
- event.modifierState,
- event.keyGestureType
- )
+ val eventToSend = AidlKeyGestureEvent()
+ eventToSend.deviceId = event.deviceId
+ eventToSend.keycodes = event.keycodes
+ eventToSend.modifierState = event.modifierState
+ eventToSend.gestureType = event.keyGestureType
+ eventToSend.action = event.action
+ eventToSend.displayId = event.displayId
+ eventToSend.flags = event.flags
+ registeredListener!!.onKeyGestureEvent(eventToSend)
}
@Test
diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
index 3f611e0ead53..e12679742224 100644
--- a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
@@ -18,18 +18,28 @@ package com.android.server.input
import android.content.Context
import android.content.ContextWrapper
+import android.hardware.input.IInputManager
+import android.hardware.input.AidlKeyGestureEvent
import android.hardware.input.IKeyGestureEventListener
+import android.hardware.input.IKeyGestureHandler
+import android.hardware.input.InputManager
+import android.hardware.input.InputManagerGlobal
import android.hardware.input.KeyGestureEvent
+import android.os.IBinder
+import android.os.Process
+import android.os.test.TestLooper
import android.platform.test.annotations.Presubmit
+import android.view.InputDevice
import android.view.KeyEvent
import androidx.test.core.app.ApplicationProvider
+import com.android.internal.util.FrameworkStatsLog
+import com.android.modules.utils.testing.ExtendedMockitoRule
import org.junit.Assert.assertEquals
-import org.junit.Assert.assertNull
import org.junit.Before
import org.junit.Rule
import org.junit.Test
+import org.mockito.Mock
import org.mockito.Mockito
-import org.mockito.junit.MockitoJUnit
/**
* Tests for {@link KeyGestureController}.
@@ -41,26 +51,55 @@ import org.mockito.junit.MockitoJUnit
class KeyGestureControllerTests {
companion object {
- val DEVICE_ID = 1
- val HOME_GESTURE_EVENT = KeyGestureEvent(
- DEVICE_ID,
- intArrayOf(KeyEvent.KEYCODE_H),
- KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON,
- KeyGestureEvent.KEY_GESTURE_TYPE_HOME
- )
+ const val DEVICE_ID = 1
+ val HOME_GESTURE_COMPLETE_EVENT = KeyGestureEvent.Builder()
+ .setDeviceId(DEVICE_ID)
+ .setKeycodes(intArrayOf(KeyEvent.KEYCODE_H))
+ .setModifierState(KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON)
+ .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_HOME)
+ .setAction(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
+ .build()
}
- @get:Rule
- val rule = MockitoJUnit.rule()!!
+ @JvmField
+ @Rule
+ val extendedMockitoRule = ExtendedMockitoRule.Builder(this)
+ .mockStatic(FrameworkStatsLog::class.java).build()!!
+
+ @Mock
+ private lateinit var iInputManager: IInputManager
+ private var currentPid = 0
private lateinit var keyGestureController: KeyGestureController
private lateinit var context: Context
- private var lastEvent: KeyGestureEvent? = null
+ private lateinit var inputManagerGlobalSession: InputManagerGlobal.TestSession
+ private lateinit var testLooper: TestLooper
+ private var events = mutableListOf<KeyGestureEvent>()
@Before
fun setup() {
context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
- keyGestureController = KeyGestureController()
+ inputManagerGlobalSession = InputManagerGlobal.createTestSession(iInputManager)
+ setupInputDevices()
+ testLooper = TestLooper()
+ currentPid = Process.myPid()
+ keyGestureController = KeyGestureController(context, testLooper.looper)
+ }
+
+ private fun setupInputDevices() {
+ val inputManager = InputManager(context)
+ Mockito.`when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE)))
+ .thenReturn(inputManager)
+
+ val keyboardDevice = InputDevice.Builder().setId(DEVICE_ID).build()
+ Mockito.`when`(iInputManager.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID))
+ Mockito.`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardDevice)
+ }
+
+ private fun notifyHomeGestureCompleted() {
+ keyGestureController.notifyKeyGestureCompleted(DEVICE_ID, intArrayOf(KeyEvent.KEYCODE_H),
+ KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON,
+ KeyGestureEvent.KEY_GESTURE_TYPE_HOME)
}
@Test
@@ -69,28 +108,97 @@ class KeyGestureControllerTests {
// Register key gesture event listener
keyGestureController.registerKeyGestureEventListener(listener, 0)
- keyGestureController.onKeyGestureEvent(HOME_GESTURE_EVENT)
+ notifyHomeGestureCompleted()
+ testLooper.dispatchAll()
assertEquals(
- "Listener should get callback on key gesture event",
- HOME_GESTURE_EVENT,
- lastEvent!!
+ "Listener should get callbacks on key gesture event completed",
+ 1,
+ events.size
+ )
+ assertEquals(
+ "Listener should get callback for key gesture complete event",
+ HOME_GESTURE_COMPLETE_EVENT,
+ events[0]
)
// Unregister listener
- lastEvent = null
+ events.clear()
keyGestureController.unregisterKeyGestureEventListener(listener, 0)
- keyGestureController.onKeyGestureEvent(HOME_GESTURE_EVENT)
- assertNull("Listener should not get callback after being unregistered", lastEvent)
+ notifyHomeGestureCompleted()
+ testLooper.dispatchAll()
+ assertEquals(
+ "Listener should not get callback after being unregistered",
+ 0,
+ events.size
+ )
+ }
+
+ @Test
+ fun testKeyGestureEvent_multipleGestureHandlers() {
+ // Set up two callbacks.
+ var callbackCount1 = 0
+ var callbackCount2 = 0
+ var selfCallback = 0
+ val externalHandler1 = KeyGestureHandler { _, _ ->
+ callbackCount1++;
+ true
+ }
+ val externalHandler2 = KeyGestureHandler { _, _ ->
+ callbackCount2++;
+ true
+ }
+ val selfHandler = KeyGestureHandler { _, _ ->
+ selfCallback++;
+ false
+ }
+
+ // Register key gesture handler: External process (last in priority)
+ keyGestureController.registerKeyGestureHandler(externalHandler1, currentPid + 1)
+
+ // Register key gesture handler: External process (second in priority)
+ keyGestureController.registerKeyGestureHandler(externalHandler2, currentPid - 1)
+
+ // Register key gesture handler: Self process (first in priority)
+ keyGestureController.registerKeyGestureHandler(selfHandler, currentPid)
+
+ keyGestureController.handleKeyGesture(/* deviceId = */ 0, intArrayOf(KeyEvent.KEYCODE_HOME),
+ /* modifierState = */ 0, KeyGestureEvent.KEY_GESTURE_TYPE_HOME,
+ KeyGestureEvent.ACTION_GESTURE_COMPLETE, /* displayId */ 0,
+ /* focusedToken = */ null, /* flags = */ 0
+ )
+
+ assertEquals(
+ "Self handler should get callbacks first",
+ 1,
+ selfCallback
+ )
+ assertEquals(
+ "Higher priority handler should get callbacks first",
+ 1,
+ callbackCount2
+ )
+ assertEquals(
+ "Lower priority handler should not get callbacks if already handled",
+ 0,
+ callbackCount1
+ )
}
inner class KeyGestureEventListener : IKeyGestureEventListener.Stub() {
- override fun onKeyGestureEvent(
- deviceId: Int,
- keycodes: IntArray,
- modifierState: Int,
- gestureType: Int
- ) {
- lastEvent = KeyGestureEvent(deviceId, keycodes, modifierState, gestureType)
+ override fun onKeyGestureEvent(event: AidlKeyGestureEvent) {
+ events.add(KeyGestureEvent(event))
+ }
+ }
+
+ inner class KeyGestureHandler(
+ private var handler: (event: AidlKeyGestureEvent, token: IBinder?) -> Boolean
+ ) : IKeyGestureHandler.Stub() {
+ override fun handleKeyGesture(event: AidlKeyGestureEvent, token: IBinder?): Boolean {
+ return handler(event, token)
+ }
+
+ override fun isKeyGestureSupported(gestureType: Int): Boolean {
+ return true
}
}
} \ No newline at end of file