diff --git a/core/api/current.txt b/core/api/current.txt index e9749228b85c6..5dce6c00a20e5 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -48358,6 +48358,7 @@ package android.view { method public static int[] getDeviceIds(); method public int getId(); method public android.view.KeyCharacterMap getKeyCharacterMap(); + method public int getKeyCodeForKeyLocation(int); method public int getKeyboardType(); method @NonNull public android.hardware.lights.LightsManager getLightsManager(); method public android.view.InputDevice.MotionRange getMotionRange(int); diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index 2ac194b671923..0304815ef8fe2 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -50,6 +50,10 @@ interface IInputManager { // Reports whether the hardware supports the given keys; returns true if successful boolean hasKeys(int deviceId, int sourceMask, in int[] keyCodes, out boolean[] keyExists); + // Returns the keyCode produced when pressing the key at the specified location, given the + // active keyboard layout. + int getKeyCodeForKeyLocation(int deviceId, in int locationKeyCode); + // Temporarily changes the pointer speed. void tryPointerSpeed(int speed); diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index ef349a96ee17e..df59fefbf6d35 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -58,6 +58,7 @@ import android.util.SparseArray; import android.view.InputDevice; import android.view.InputEvent; import android.view.InputMonitor; +import android.view.KeyEvent; import android.view.MotionEvent; import android.view.PointerIcon; import android.view.VerifiedInputEvent; @@ -1044,6 +1045,27 @@ public final class InputManager { return ret; } + /** + * Gets the key code produced by the specified location on a US keyboard layout. + * Key code as defined in {@link android.view.KeyEvent}. + * This API is only functional for devices with {@link InputDevice#SOURCE_KEYBOARD} available + * which can alter their key mapping using country specific keyboard layouts. + * + * @param deviceId The input device id. + * @param locationKeyCode The location of a key on a US keyboard layout. + * @return The key code produced when pressing the key at the specified location, given the + * active keyboard layout. Returns {@link KeyEvent#KEYCODE_UNKNOWN} if the requested + * mapping could not be determined, or if an error occurred. + * @hide + */ + public int getKeyCodeForKeyLocation(int deviceId, int locationKeyCode) { + try { + return mIm.getKeyCodeForKeyLocation(deviceId, locationKeyCode); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Injects an input event into the event system on behalf of an application. diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java index 4f1354d7eee6a..cadff69ffd253 100644 --- a/core/java/android/view/InputDevice.java +++ b/core/java/android/view/InputDevice.java @@ -734,6 +734,21 @@ public final class InputDevice implements Parcelable { return InputManager.getInstance().deviceHasKeys(mId, keys); } + /** + * Gets the key code produced by the specified location on a US keyboard layout. + * Key code as defined in {@link android.view.KeyEvent}. + * This API is only functional for devices with {@link InputDevice#SOURCE_KEYBOARD} available + * which can alter their key mapping using country specific keyboard layouts. + * + * @param locationKeyCode The location of a key on a US keyboard layout. + * @return The key code produced when pressing the key at the specified location, given the + * active keyboard layout. Returns {@link KeyEvent#KEYCODE_UNKNOWN} if the requested + * mapping could not be determined, or if an error occurred. + */ + public int getKeyCodeForKeyLocation(int locationKeyCode) { + return InputManager.getInstance().getKeyCodeForKeyLocation(mId, locationKeyCode); + } + /** * Gets information about the range of values for a particular {@link MotionEvent} axis. * If the device supports multiple sources, the same axis may have different meanings diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 261aa32f093eb..ef0c716e32db9 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -16,6 +16,8 @@ package com.android.server.input; +import static android.view.KeyEvent.KEYCODE_UNKNOWN; + import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Notification; @@ -284,6 +286,8 @@ public class InputManagerService extends IInputManager.Stub int deviceId, int sourceMask, int sw); private static native boolean nativeHasKeys(long ptr, int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists); + private static native int nativeGetKeyCodeForKeyLocation(long ptr, int deviceId, + int locationKeyCode); private static native InputChannel nativeCreateInputChannel(long ptr, String name); private static native InputChannel nativeCreateInputMonitor(long ptr, int displayId, boolean isGestureMonitor, String name, int pid); @@ -657,6 +661,22 @@ public class InputManagerService extends IInputManager.Stub return nativeHasKeys(mPtr, deviceId, sourceMask, keyCodes, keyExists); } + /** + * Returns the keyCode generated by the specified location on a US keyboard layout. + * This takes into consideration the currently active keyboard layout. + * + * @param deviceId The input device id. + * @param locationKeyCode The location of a key on a US keyboard layout. + * @return The KeyCode this physical key location produces. + */ + @Override // Binder call + public int getKeyCodeForKeyLocation(int deviceId, int locationKeyCode) { + if (locationKeyCode <= KEYCODE_UNKNOWN || locationKeyCode > KeyEvent.getMaxKeyCode()) { + return KEYCODE_UNKNOWN; + } + return nativeGetKeyCodeForKeyLocation(mPtr, deviceId, locationKeyCode); + } + /** * Transfer the current touch gesture to the provided window. * diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 3cd4e5ee82cf1..a2475d95c0080 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -1573,6 +1573,13 @@ static jboolean nativeHasKeys(JNIEnv* env, jclass /* clazz */, return result; } +static jint nativeGetKeyCodeForKeyLocation(JNIEnv* env, jclass /* clazz */, jlong ptr, + jint deviceId, jint locationKeyCode) { + NativeInputManager* im = reinterpret_cast(ptr); + return (jint)im->getInputManager()->getReader().getKeyCodeForKeyLocation(deviceId, + locationKeyCode); +} + static void handleInputChannelDisposed(JNIEnv* env, jobject /* inputChannelObj */, const std::shared_ptr& inputChannel, void* data) { @@ -2312,6 +2319,7 @@ static const JNINativeMethod gInputManagerMethods[] = { {"nativeGetKeyCodeState", "(JIII)I", (void*)nativeGetKeyCodeState}, {"nativeGetSwitchState", "(JIII)I", (void*)nativeGetSwitchState}, {"nativeHasKeys", "(JII[I[Z)Z", (void*)nativeHasKeys}, + {"nativeGetKeyCodeForKeyLocation", "(JII)I", (void*)nativeGetKeyCodeForKeyLocation}, {"nativeCreateInputChannel", "(JLjava/lang/String;)Landroid/view/InputChannel;", (void*)nativeCreateInputChannel}, {"nativeCreateInputMonitor", "(JIZLjava/lang/String;I)Landroid/view/InputChannel;",