diff options
Diffstat (limited to 'services')
| -rw-r--r-- | services/java/com/android/server/InputManager.java | 64 | ||||
| -rw-r--r-- | services/java/com/android/server/WindowManagerService.java | 8 | ||||
| -rw-r--r-- | services/jni/com_android_server_InputManager.cpp | 179 |
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; } |
