Eliminate hw.keyboards system properties.
Stop using system properties to publish information about
the key character map path. Instead, we can retrieve it
on demand by asking the window manager.
It was possible to exhaust the supply of system properties
when repeatedly adding and removing input devices.
Bug: 5532806
Change-Id: Idd361a24ad7db2edc185c8546db7fb05f9c28669
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index bfc7c31..8115b36 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -19,7 +19,6 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
-import android.os.ServiceManager;
import java.util.ArrayList;
import java.util.List;
@@ -44,6 +43,7 @@
private String mName;
private int mSources;
private int mKeyboardType;
+ private String mKeyCharacterMapFile;
private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>();
@@ -360,6 +360,10 @@
return KeyCharacterMap.load(mId);
}
+ String getKeyCharacterMapFile() {
+ return mKeyCharacterMapFile;
+ }
+
/**
* 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
@@ -532,6 +536,7 @@
mName = in.readString();
mSources = in.readInt();
mKeyboardType = in.readInt();
+ mKeyCharacterMapFile = in.readString();
for (;;) {
int axis = in.readInt();
@@ -549,6 +554,7 @@
out.writeString(mName);
out.writeInt(mSources);
out.writeInt(mKeyboardType);
+ out.writeString(mKeyCharacterMapFile);
final int numRanges = mMotionRanges.size();
for (int i = 0; i < numRanges; i++) {
@@ -587,6 +593,8 @@
}
description.append("\n");
+ description.append(" Key Character Map: ").append(mKeyCharacterMapFile).append("\n");
+
description.append(" Sources: 0x").append(Integer.toHexString(mSources)).append(" (");
appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard");
appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad");
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 885a75f..575af3b 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -20,7 +20,6 @@
import android.util.AndroidRuntimeException;
import android.util.SparseIntArray;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.util.SparseArray;
import java.lang.Character;
@@ -140,7 +139,7 @@
private final int mDeviceId;
private int mPtr;
- private static native int nativeLoad(int id);
+ private static native int nativeLoad(String file);
private static native void nativeDispose(int ptr);
private static native char nativeGetCharacter(int ptr, int keyCode, int metaState);
@@ -178,7 +177,17 @@
synchronized (sInstances) {
KeyCharacterMap map = sInstances.get(deviceId);
if (map == null) {
- int ptr = nativeLoad(deviceId); // might throw
+ String kcm = null;
+ if (deviceId != VIRTUAL_KEYBOARD) {
+ InputDevice device = InputDevice.getDevice(deviceId);
+ if (device != null) {
+ kcm = device.getKeyCharacterMapFile();
+ }
+ }
+ if (kcm == null || kcm.length() == 0) {
+ kcm = "/system/usr/keychars/Virtual.kcm";
+ }
+ int ptr = nativeLoad(kcm); // might throw
map = new KeyCharacterMap(deviceId, ptr);
sInstances.put(deviceId, map);
}
diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp
index aba3a72..b9f3738 100644
--- a/core/jni/android_view_KeyCharacterMap.cpp
+++ b/core/jni/android_view_KeyCharacterMap.cpp
@@ -35,18 +35,25 @@
} gFallbackActionClassInfo;
-static jint nativeLoad(JNIEnv *env, jobject clazz, jint deviceId) {
+static jint nativeLoad(JNIEnv *env, jobject clazz, jstring fileStr) {
+ const char* file = env->GetStringUTFChars(fileStr, NULL);
+
KeyCharacterMap* map;
- status_t status = KeyCharacterMap::loadByDeviceId(deviceId, &map);
+ status_t status = KeyCharacterMap::load(String8(file), &map);
+ jint result;
if (status) {
String8 msg;
- msg.appendFormat("Could not load key character map for device %d due to error %d. "
- "Refer to the log for details.", deviceId, status);
+ msg.appendFormat("Could not load key character map '%s' due to error %d. "
+ "Refer to the log for details.", file, status);
jniThrowException(env, "android/view/KeyCharacterMap$KeyCharacterMapUnavailableException",
msg.string());
- return 0;
+ result = 0;
+ } else {
+ result = reinterpret_cast<jint>(map);
}
- return reinterpret_cast<jint>(map);
+
+ env->ReleaseStringUTFChars(fileStr, file);
+ return result;
}
static void nativeDispose(JNIEnv *env, jobject clazz, jint ptr) {
@@ -141,7 +148,7 @@
static JNINativeMethod g_methods[] = {
/* name, signature, funcPtr */
- { "nativeLoad", "(I)I",
+ { "nativeLoad", "(Ljava/lang/String;)I",
(void*)nativeLoad },
{ "nativeDispose", "(I)V",
(void*)nativeDispose },