b/12068020 Make kb layouts only unique to vendor/product
Instead of storing a kb layout per device descriptor (which is expected
to be unique), store it for each vendor/product. This way we can keep
a consistent layout between identical but physically different keyboards.
There are some corner cases this is expected to fail on, namely devices
that incorrectly have the same vendor/product id. Devices that don't
define a vendor/product id will continue to use the descriptor to store
layout files.
Change-Id: Id0890d13e1c859eaf993d4831b7b1acbaf5df80f
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 4ab2086..12a1c7a 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -99,6 +99,12 @@
jclass clazz;
} gMotionEventClassInfo;
+static struct {
+ jclass clazz;
+ jmethodID constructor;
+} gInputDeviceIdentifierInfo;
+
+
// --- Global functions ---
@@ -183,7 +189,7 @@
virtual void getReaderConfiguration(InputReaderConfiguration* outConfig);
virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices);
- virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const String8& inputDeviceDescriptor);
+ virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier& identifier);
virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier);
/* --- InputDispatcherPolicyInterface implementation --- */
@@ -492,13 +498,16 @@
}
sp<KeyCharacterMap> NativeInputManager::getKeyboardLayoutOverlay(
- const String8& inputDeviceDescriptor) {
+ const InputDeviceIdentifier& identifier) {
JNIEnv* env = jniEnv();
sp<KeyCharacterMap> result;
- ScopedLocalRef<jstring> descriptorObj(env, env->NewStringUTF(inputDeviceDescriptor.string()));
+ ScopedLocalRef<jstring> descriptor(env, env->NewStringUTF(identifier.descriptor.string()));
+ ScopedLocalRef<jobject> identifierObj(env, env->NewObject(gInputDeviceIdentifierInfo.clazz,
+ gInputDeviceIdentifierInfo.constructor, descriptor.get(),
+ identifier.vendor, identifier.product));
ScopedLocalRef<jobjectArray> arrayObj(env, jobjectArray(env->CallObjectMethod(mServiceObj,
- gServiceClassInfo.getKeyboardLayoutOverlay, descriptorObj.get())));
+ gServiceClassInfo.getKeyboardLayoutOverlay, identifierObj.get())));
if (arrayObj.get()) {
ScopedLocalRef<jstring> filenameObj(env,
jstring(env->GetObjectArrayElement(arrayObj.get(), 0)));
@@ -1438,7 +1447,8 @@
"getPointerIcon", "()Landroid/view/PointerIcon;");
GET_METHOD_ID(gServiceClassInfo.getKeyboardLayoutOverlay, clazz,
- "getKeyboardLayoutOverlay", "(Ljava/lang/String;)[Ljava/lang/String;");
+ "getKeyboardLayoutOverlay",
+ "(Landroid/hardware/input/InputDeviceIdentifier;)[Ljava/lang/String;");
GET_METHOD_ID(gServiceClassInfo.getDeviceAlias, clazz,
"getDeviceAlias", "(Ljava/lang/String;)Ljava/lang/String;");
@@ -1458,6 +1468,13 @@
FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
+ // InputDeviceIdentifier
+
+ FIND_CLASS(gInputDeviceIdentifierInfo.clazz, "android/hardware/input/InputDeviceIdentifier");
+ gInputDeviceIdentifierInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceIdentifierInfo.clazz));
+ GET_METHOD_ID(gInputDeviceIdentifierInfo.constructor, gInputDeviceIdentifierInfo.clazz,
+ "<init>", "(Ljava/lang/String;II)V");
+
return 0;
}