summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/java/com/android/server/InputManager.java64
-rw-r--r--services/java/com/android/server/WindowManagerService.java8
-rw-r--r--services/jni/com_android_server_InputManager.cpp179
3 files changed, 242 insertions, 9 deletions
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index f330d40..314dd8a 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -30,6 +30,7 @@ import android.os.SystemProperties;
import android.util.Slog;
import android.util.Xml;
import android.view.InputChannel;
+import android.view.InputDevice;
import android.view.InputEvent;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -45,6 +46,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Properties;
/*
* Wraps the C++ InputManager and provides its callbacks.
@@ -82,6 +84,8 @@ public class InputManager {
private static native void nativeSetInputDispatchMode(boolean enabled, boolean frozen);
private static native void nativeSetFocusedApplication(InputApplication application);
private static native void nativePreemptInputDispatch();
+ private static native InputDevice nativeGetInputDevice(int deviceId);
+ private static native int[] nativeGetInputDeviceIds();
private static native String nativeDump();
// Input event injection constants defined in InputDispatcher.h.
@@ -302,6 +306,23 @@ public class InputManager {
return nativeInjectInputEvent(event, injectorPid, injectorUid, syncMode, timeoutMillis);
}
+ /**
+ * Gets information about the input device with the specified id.
+ * @param id The device id.
+ * @return The input device or null if not found.
+ */
+ public InputDevice getInputDevice(int deviceId) {
+ return nativeGetInputDevice(deviceId);
+ }
+
+ /**
+ * Gets the ids of all input devices in the system.
+ * @return The input device ids.
+ */
+ public int[] getInputDeviceIds() {
+ return nativeGetInputDeviceIds();
+ }
+
public void setInputWindows(InputWindow[] windows) {
nativeSetInputWindows(windows);
}
@@ -335,6 +356,11 @@ public class InputManager {
public int height;
}
+ private static final class InputDeviceCalibration {
+ public String[] keys;
+ public String[] values;
+ }
+
/*
* Callbacks from native.
*/
@@ -343,6 +369,7 @@ public class InputManager {
private static final boolean DEBUG_VIRTUAL_KEYS = false;
private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
+ private static final String CALIBRATION_DIR_PATH = "usr/idc/";
@SuppressWarnings("unused")
public void virtualKeyDownFeedback() {
@@ -438,8 +465,8 @@ public class InputManager {
final int N = it.length-6;
for (int i=0; i<=N; i+=6) {
if (!"0x01".equals(it[i])) {
- Slog.w(TAG, "Unknown virtual key type at elem #" + i
- + ": " + it[i]);
+ Slog.w(TAG, "Unknown virtual key type at elem #"
+ + i + ": " + it[i] + " for device " + deviceName);
continue;
}
try {
@@ -455,22 +482,47 @@ public class InputManager {
+ key.height);
keys.add(key);
} catch (NumberFormatException e) {
- Slog.w(TAG, "Bad number at region " + i + " in: "
- + str, e);
+ Slog.w(TAG, "Bad number in virtual key definition at region "
+ + i + " in: " + str + " for device " + deviceName, e);
}
}
}
br.close();
} catch (FileNotFoundException e) {
- Slog.i(TAG, "No virtual keys found");
+ Slog.i(TAG, "No virtual keys found for device " + deviceName + ".");
} catch (IOException e) {
- Slog.w(TAG, "Error reading virtual keys", e);
+ Slog.w(TAG, "Error reading virtual keys for device " + deviceName + ".", e);
}
return keys.toArray(new VirtualKeyDefinition[keys.size()]);
}
@SuppressWarnings("unused")
+ public InputDeviceCalibration getInputDeviceCalibration(String deviceName) {
+ // Calibration is specified as a sequence of colon-delimited key value pairs.
+ Properties properties = new Properties();
+ File calibrationFile = new File(Environment.getRootDirectory(),
+ CALIBRATION_DIR_PATH + deviceName + ".idc");
+ if (calibrationFile.exists()) {
+ try {
+ properties.load(new FileInputStream(calibrationFile));
+ } catch (IOException ex) {
+ Slog.w(TAG, "Error reading input device calibration properties for device "
+ + deviceName + " from " + calibrationFile + ".", ex);
+ }
+ } else {
+ Slog.i(TAG, "No input device calibration properties found for device "
+ + deviceName + ".");
+ return null;
+ }
+
+ InputDeviceCalibration calibration = new InputDeviceCalibration();
+ calibration.keys = properties.keySet().toArray(new String[properties.size()]);
+ calibration.values = properties.values().toArray(new String[properties.size()]);
+ return calibration;
+ }
+
+ @SuppressWarnings("unused")
public String[] getExcludedDeviceNames() {
ArrayList<String> names = new ArrayList<String>();
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 9b9d950..3841f75 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -4392,6 +4392,14 @@ public class WindowManagerService extends IWindowManager.Stub
return mInputManager.monitorInput(inputChannelName);
}
+ public InputDevice getInputDevice(int deviceId) {
+ return mInputManager.getInputDevice(deviceId);
+ }
+
+ public int[] getInputDeviceIds() {
+ return mInputManager.getInputDeviceIds();
+ }
+
public void enableScreenAfterBoot() {
synchronized(mWindowMap) {
if (mSystemBooted) {
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 3addc0d..a237ee9 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -138,6 +138,7 @@ static struct {
jmethodID filterTouchEvents;
jmethodID filterJumpyTouchEvents;
jmethodID getVirtualKeyDefinitions;
+ jmethodID getInputDeviceCalibration;
jmethodID getExcludedDeviceNames;
jmethodID getMaxEventsPerSecond;
} gCallbacksClassInfo;
@@ -155,6 +156,13 @@ static struct {
static struct {
jclass clazz;
+ jfieldID keys;
+ jfieldID values;
+} gInputDeviceCalibrationClassInfo;
+
+static struct {
+ jclass clazz;
+
jfieldID inputChannel;
jfieldID layoutParamsFlags;
jfieldID layoutParamsType;
@@ -189,6 +197,19 @@ static struct {
jclass clazz;
} gMotionEventClassInfo;
+static struct {
+ jclass clazz;
+
+ jmethodID ctor;
+ jmethodID addMotionRange;
+
+ jfieldID mId;
+ jfieldID mName;
+ jfieldID mSources;
+ jfieldID mKeyboardType;
+ jfieldID mMotionRanges;
+} gInputDeviceClassInfo;
+
// ----------------------------------------------------------------------------
static inline nsecs_t now() {
@@ -235,7 +256,9 @@ public:
virtual bool filterTouchEvents();
virtual bool filterJumpyTouchEvents();
virtual void getVirtualKeyDefinitions(const String8& deviceName,
- Vector<InputReaderPolicyInterface::VirtualKeyDefinition>& outVirtualKeyDefinitions);
+ Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions);
+ virtual void getInputDeviceCalibration(const String8& deviceName,
+ InputDeviceCalibration& outCalibration);
virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
/* --- InputDispatcherPolicyInterface implementation --- */
@@ -761,7 +784,9 @@ bool NativeInputManager::filterJumpyTouchEvents() {
}
void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
- Vector<InputReaderPolicyInterface::VirtualKeyDefinition>& outVirtualKeyDefinitions) {
+ Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
+ outVirtualKeyDefinitions.clear();
+
JNIEnv* env = jniEnv();
jstring deviceNameStr = env->NewStringUTF(deviceName.string());
@@ -793,7 +818,51 @@ void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
}
}
+void NativeInputManager::getInputDeviceCalibration(const String8& deviceName,
+ InputDeviceCalibration& outCalibration) {
+ outCalibration.clear();
+
+ JNIEnv* env = jniEnv();
+
+ jstring deviceNameStr = env->NewStringUTF(deviceName.string());
+ if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration")) {
+ jobject result = env->CallObjectMethod(mCallbacksObj,
+ gCallbacksClassInfo.getInputDeviceCalibration, deviceNameStr);
+ if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration") && result) {
+ jobjectArray keys = jobjectArray(env->GetObjectField(result,
+ gInputDeviceCalibrationClassInfo.keys));
+ jobjectArray values = jobjectArray(env->GetObjectField(result,
+ gInputDeviceCalibrationClassInfo.values));
+
+ jsize length = env->GetArrayLength(keys);
+ for (jsize i = 0; i < length; i++) {
+ jstring keyStr = jstring(env->GetObjectArrayElement(keys, i));
+ jstring valueStr = jstring(env->GetObjectArrayElement(values, i));
+
+ const char* keyChars = env->GetStringUTFChars(keyStr, NULL);
+ String8 key(keyChars);
+ env->ReleaseStringUTFChars(keyStr, keyChars);
+
+ const char* valueChars = env->GetStringUTFChars(valueStr, NULL);
+ String8 value(valueChars);
+ env->ReleaseStringUTFChars(valueStr, valueChars);
+
+ outCalibration.addProperty(key, value);
+
+ env->DeleteLocalRef(keyStr);
+ env->DeleteLocalRef(valueStr);
+ }
+ env->DeleteLocalRef(keys);
+ env->DeleteLocalRef(values);
+ env->DeleteLocalRef(result);
+ }
+ env->DeleteLocalRef(deviceNameStr);
+ }
+}
+
void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
+ outExcludedDeviceNames.clear();
+
JNIEnv* env = jniEnv();
jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
@@ -2199,6 +2268,66 @@ static void android_server_InputManager_nativePreemptInputDispatch(JNIEnv* env,
gNativeInputManager->preemptInputDispatch();
}
+static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
+ jclass clazz, jint deviceId) {
+ if (checkInputManagerUnitialized(env)) {
+ return NULL;
+ }
+
+ InputDeviceInfo deviceInfo;
+ status_t status = gNativeInputManager->getInputManager()->getInputDeviceInfo(
+ deviceId, & deviceInfo);
+ if (status) {
+ return NULL;
+ }
+
+ jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
+ if (! deviceObj) {
+ return NULL;
+ }
+
+ jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
+ if (! deviceNameObj) {
+ return NULL;
+ }
+
+ env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
+ env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
+ env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
+ env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
+
+ const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
+ for (size_t i = 0; i < ranges.size(); i++) {
+ int rangeType = ranges.keyAt(i);
+ const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
+ env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
+ rangeType, range.min, range.max, range.flat, range.fuzz);
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
+ }
+
+ return deviceObj;
+}
+
+static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
+ jclass clazz) {
+ if (checkInputManagerUnitialized(env)) {
+ return NULL;
+ }
+
+ Vector<int> deviceIds;
+ gNativeInputManager->getInputManager()->getInputDeviceIds(deviceIds);
+
+ jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
+ if (! deviceIdsObj) {
+ return NULL;
+ }
+
+ env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
+ return deviceIdsObj;
+}
+
static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
if (checkInputManagerUnitialized(env)) {
return NULL;
@@ -2242,6 +2371,10 @@ static JNINativeMethod gInputManagerMethods[] = {
(void*) android_server_InputManager_nativeSetInputDispatchMode },
{ "nativePreemptInputDispatch", "()V",
(void*) android_server_InputManager_nativePreemptInputDispatch },
+ { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
+ (void*) android_server_InputManager_nativeGetInputDevice },
+ { "nativeGetInputDeviceIds", "()[I",
+ (void*) android_server_InputManager_nativeGetInputDeviceIds },
{ "nativeDump", "()Ljava/lang/String;",
(void*) android_server_InputManager_nativeDump },
};
@@ -2311,6 +2444,10 @@ int register_android_server_InputManager(JNIEnv* env) {
"getVirtualKeyDefinitions",
"(Ljava/lang/String;)[Lcom/android/server/InputManager$VirtualKeyDefinition;");
+ GET_METHOD_ID(gCallbacksClassInfo.getInputDeviceCalibration, gCallbacksClassInfo.clazz,
+ "getInputDeviceCalibration",
+ "(Ljava/lang/String;)Lcom/android/server/InputManager$InputDeviceCalibration;");
+
GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
"getExcludedDeviceNames", "()[Ljava/lang/String;");
@@ -2337,6 +2474,17 @@ int register_android_server_InputManager(JNIEnv* env) {
GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.height, gVirtualKeyDefinitionClassInfo.clazz,
"height", "I");
+ // InputDeviceCalibration
+
+ FIND_CLASS(gInputDeviceCalibrationClassInfo.clazz,
+ "com/android/server/InputManager$InputDeviceCalibration");
+
+ GET_FIELD_ID(gInputDeviceCalibrationClassInfo.keys, gInputDeviceCalibrationClassInfo.clazz,
+ "keys", "[Ljava/lang/String;");
+
+ GET_FIELD_ID(gInputDeviceCalibrationClassInfo.values, gInputDeviceCalibrationClassInfo.clazz,
+ "values", "[Ljava/lang/String;");
+
// InputWindow
FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");
@@ -2407,10 +2555,35 @@ int register_android_server_InputManager(JNIEnv* env) {
FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
- // MotionEVent
+ // MotionEvent
FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
+ // InputDevice
+
+ FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
+
+ GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
+ "<init>", "()V");
+
+ GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
+ "addMotionRange", "(IFFFF)V");
+
+ GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
+ "mId", "I");
+
+ GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
+ "mName", "Ljava/lang/String;");
+
+ GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
+ "mSources", "I");
+
+ GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
+ "mKeyboardType", "I");
+
+ GET_FIELD_ID(gInputDeviceClassInfo.mMotionRanges, gInputDeviceClassInfo.clazz,
+ "mMotionRanges", "[Landroid/view/InputDevice$MotionRange;");
+
return 0;
}