summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vaibhav Devmurari <vdevmurari@google.com> 2025-01-08 15:30:07 +0000
committer Vaibhav Devmurari <vdevmurari@google.com> 2025-01-09 04:40:24 -0800
commitaf01f6dff2792ce8c4b1817ce05964c96b1477a2 (patch)
tree4b0c0b952243a37606964e7b1bd03fc6f780f54d
parentcdcdd9e97c6da6ef8b1e0e521ed695694cd701a5 (diff)
Add new API to check if a custom gesture trigger is available
In order to notify user that a key combination is already taken, we need another API to check if a input gesture trigger is available. This is a new UX request allowing user to pre-emptively know if adding a custom gesture is allowed for a trigger or not. Bug: 381063978 Test: atest InputTests Flag: EXEMPT internal API addition only Change-Id: Id579fa179acabc783ab6ca61bf34b8b74dc5e1af
-rw-r--r--core/java/android/hardware/input/IInputManager.aidl5
-rw-r--r--core/java/android/hardware/input/InputManager.java24
-rw-r--r--core/java/android/hardware/input/KeyGestureEvent.java6
-rw-r--r--services/core/java/com/android/server/input/InputGestureManager.java25
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java10
-rw-r--r--services/core/java/com/android/server/input/KeyGestureController.java12
-rw-r--r--tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt27
7 files changed, 102 insertions, 7 deletions
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index ed510e467f82..2bb28a1b6b0b 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -266,6 +266,11 @@ interface IInputManager {
@PermissionManuallyEnforced
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ "android.Manifest.permission.MANAGE_KEY_GESTURES)")
+ AidlInputGestureData getInputGesture(int userId, in AidlInputGestureData.Trigger trigger);
+
+ @PermissionManuallyEnforced
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+ + "android.Manifest.permission.MANAGE_KEY_GESTURES)")
int addCustomInputGesture(int userId, in AidlInputGestureData data);
@PermissionManuallyEnforced
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 10224c1be788..cf41e138047a 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -1480,6 +1480,30 @@ public final class InputManager {
mGlobal.unregisterKeyGestureEventHandler(handler);
}
+ /**
+ * Find an input gesture mapped to a particular trigger.
+ *
+ * @param trigger to find the input gesture for
+ * @return input gesture mapped to the provided trigger, {@code null} if none found
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.MANAGE_KEY_GESTURES)
+ @UserHandleAware
+ @Nullable
+ public InputGestureData getInputGesture(@NonNull InputGestureData.Trigger trigger) {
+ try {
+ AidlInputGestureData result = mIm.getInputGesture(mContext.getUserId(),
+ trigger.getAidlTrigger());
+ if (result == null) {
+ return null;
+ }
+ return new InputGestureData(result);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
/** Adds a new custom input gesture
*
* @param inputGestureData gesture data to add as custom gesture
diff --git a/core/java/android/hardware/input/KeyGestureEvent.java b/core/java/android/hardware/input/KeyGestureEvent.java
index 66d073fa791e..63bfef92d8ca 100644
--- a/core/java/android/hardware/input/KeyGestureEvent.java
+++ b/core/java/android/hardware/input/KeyGestureEvent.java
@@ -43,6 +43,9 @@ public final class KeyGestureEvent {
private static final int LOG_EVENT_UNSPECIFIED =
FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED;
+ // Used as a placeholder to identify if a gesture is reserved for system
+ public static final int KEY_GESTURE_TYPE_SYSTEM_RESERVED = -1;
+
// These values should not change and values should not be re-used as this data is persisted to
// long term storage and must be kept backwards compatible.
public static final int KEY_GESTURE_TYPE_UNSPECIFIED = 0;
@@ -143,6 +146,7 @@ public final class KeyGestureEvent {
public static final int ACTION_GESTURE_COMPLETE = 2;
@IntDef(prefix = "KEY_GESTURE_TYPE_", value = {
+ KEY_GESTURE_TYPE_SYSTEM_RESERVED,
KEY_GESTURE_TYPE_UNSPECIFIED,
KEY_GESTURE_TYPE_HOME,
KEY_GESTURE_TYPE_RECENT_APPS,
@@ -643,6 +647,8 @@ public final class KeyGestureEvent {
private static String keyGestureTypeToString(@KeyGestureType int value) {
switch (value) {
+ case KEY_GESTURE_TYPE_SYSTEM_RESERVED:
+ return "KEY_GESTURE_TYPE_SYSTEM_RESERVED";
case KEY_GESTURE_TYPE_UNSPECIFIED:
return "KEY_GESTURE_TYPE_UNSPECIFIED";
case KEY_GESTURE_TYPE_HOME:
diff --git a/services/core/java/com/android/server/input/InputGestureManager.java b/services/core/java/com/android/server/input/InputGestureManager.java
index 9f785ac81398..ffa83ce254bb 100644
--- a/services/core/java/com/android/server/input/InputGestureManager.java
+++ b/services/core/java/com/android/server/input/InputGestureManager.java
@@ -308,6 +308,31 @@ final class InputGestureManager {
}
}
+ @Nullable
+ public InputGestureData getInputGesture(int userId, InputGestureData.Trigger trigger) {
+ synchronized (mGestureLock) {
+ if (mBlockListedTriggers.contains(trigger)) {
+ return new InputGestureData.Builder().setTrigger(trigger).setKeyGestureType(
+ KeyGestureEvent.KEY_GESTURE_TYPE_SYSTEM_RESERVED).build();
+ }
+ if (trigger instanceof InputGestureData.KeyTrigger keyTrigger) {
+ if (KeyEvent.isModifierKey(keyTrigger.getKeycode()) ||
+ KeyEvent.isSystemKey(keyTrigger.getKeycode())) {
+ return new InputGestureData.Builder().setTrigger(trigger).setKeyGestureType(
+ KeyGestureEvent.KEY_GESTURE_TYPE_SYSTEM_RESERVED).build();
+ }
+ }
+ InputGestureData gestureData = mSystemShortcuts.get(trigger);
+ if (gestureData != null) {
+ return gestureData;
+ }
+ if (!mCustomInputGestures.contains(userId)) {
+ return null;
+ }
+ return mCustomInputGestures.get(userId).get(trigger);
+ }
+ }
+
@InputManager.CustomInputGestureResult
public int addCustomInputGesture(int userId, InputGestureData newGesture) {
synchronized (mGestureLock) {
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 559b4ae64e50..6ae9b5c10d7c 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -3061,6 +3061,16 @@ public class InputManagerService extends IInputManager.Stub
@Override
@PermissionManuallyEnforced
+ public AidlInputGestureData getInputGesture(@UserIdInt int userId,
+ @NonNull AidlInputGestureData.Trigger trigger) {
+ enforceManageKeyGesturePermission();
+
+ Objects.requireNonNull(trigger);
+ return mKeyGestureController.getInputGesture(userId, trigger);
+ }
+
+ @Override
+ @PermissionManuallyEnforced
public int addCustomInputGesture(@UserIdInt int userId,
@NonNull AidlInputGestureData inputGestureData) {
enforceManageKeyGesturePermission();
diff --git a/services/core/java/com/android/server/input/KeyGestureController.java b/services/core/java/com/android/server/input/KeyGestureController.java
index 5f7ad2797368..c5c1528a40f0 100644
--- a/services/core/java/com/android/server/input/KeyGestureController.java
+++ b/services/core/java/com/android/server/input/KeyGestureController.java
@@ -1069,6 +1069,18 @@ final class KeyGestureController {
}
@BinderThread
+ @Nullable
+ public AidlInputGestureData getInputGesture(@UserIdInt int userId,
+ @NonNull AidlInputGestureData.Trigger trigger) {
+ InputGestureData gestureData = mInputGestureManager.getInputGesture(userId,
+ InputGestureData.createTriggerFromAidlTrigger(trigger));
+ if (gestureData == null) {
+ return null;
+ }
+ return gestureData.getAidlData();
+ }
+
+ @BinderThread
@InputManager.CustomInputGestureResult
public int addCustomInputGesture(@UserIdInt int userId,
@NonNull AidlInputGestureData inputGestureData) {
diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
index 4d7085feb98f..138251ab68a1 100644
--- a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
@@ -59,6 +59,7 @@ import junitparams.Parameters
import org.junit.After
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
@@ -1452,20 +1453,32 @@ class KeyGestureControllerTests {
@Parameters(method = "customInputGesturesTestArguments")
fun testCustomKeyGestures(test: TestData) {
setupKeyGestureController()
+ val trigger = InputGestureData.createKeyTrigger(
+ test.expectedKeys[0],
+ test.expectedModifierState
+ )
val builder = InputGestureData.Builder()
.setKeyGestureType(test.expectedKeyGestureType)
- .setTrigger(
- InputGestureData.createKeyTrigger(
- test.expectedKeys[0],
- test.expectedModifierState
- )
- )
+ .setTrigger(trigger)
if (test.expectedAppLaunchData != null) {
builder.setAppLaunchData(test.expectedAppLaunchData)
}
val inputGestureData = builder.build()
- keyGestureController.addCustomInputGesture(0, inputGestureData.aidlData)
+ assertNull(
+ test.toString(),
+ keyGestureController.getInputGesture(0, trigger.aidlTrigger)
+ )
+ assertEquals(
+ test.toString(),
+ InputManager.CUSTOM_INPUT_GESTURE_RESULT_SUCCESS,
+ keyGestureController.addCustomInputGesture(0, builder.build().aidlData)
+ )
+ assertEquals(
+ test.toString(),
+ inputGestureData.aidlData,
+ keyGestureController.getInputGesture(0, trigger.aidlTrigger)
+ )
testKeyGestureInternal(test)
}