DO NOT MERGE: Fix input event injection ANRs on UI thread.
Added a new asynchronous injection mode and made the existing
synchronization mechanism more robust.
Change-Id: Ia4aa04fd9b75ea2461a844c5b7933c831c1027e6
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index a332376..0982b32 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -180,6 +180,14 @@
jfieldID token;
} gInputApplicationClassInfo;
+static struct {
+ jclass clazz;
+} gKeyEventClassInfo;
+
+static struct {
+ jclass clazz;
+} gMotionEventClassInfo;
+
// ----------------------------------------------------------------------------
static inline nsecs_t now() {
@@ -2051,32 +2059,29 @@
}
}
-static jint android_server_InputManager_nativeInjectKeyEvent(JNIEnv* env, jclass clazz,
- jobject keyEventObj, jint injectorPid, jint injectorUid,
- jboolean sync, jint timeoutMillis) {
+static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
+ jobject inputEventObj, jint injectorPid, jint injectorUid,
+ jint syncMode, jint timeoutMillis) {
if (checkInputManagerUnitialized(env)) {
return INPUT_EVENT_INJECTION_FAILED;
}
- KeyEvent keyEvent;
- android_view_KeyEvent_toNative(env, keyEventObj, & keyEvent);
+ if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
+ KeyEvent keyEvent;
+ android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
- return gNativeInputManager->getInputManager()->injectInputEvent(& keyEvent,
- injectorPid, injectorUid, sync, timeoutMillis);
-}
+ return gNativeInputManager->getInputManager()->injectInputEvent(& keyEvent,
+ injectorPid, injectorUid, syncMode, timeoutMillis);
+ } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
+ MotionEvent motionEvent;
+ android_view_MotionEvent_toNative(env, inputEventObj, & motionEvent);
-static jint android_server_InputManager_nativeInjectMotionEvent(JNIEnv* env, jclass clazz,
- jobject motionEventObj, jint injectorPid, jint injectorUid,
- jboolean sync, jint timeoutMillis) {
- if (checkInputManagerUnitialized(env)) {
+ return gNativeInputManager->getInputManager()->injectInputEvent(& motionEvent,
+ injectorPid, injectorUid, syncMode, timeoutMillis);
+ } else {
+ jniThrowRuntimeException(env, "Invalid input event type.");
return INPUT_EVENT_INJECTION_FAILED;
}
-
- MotionEvent motionEvent;
- android_view_MotionEvent_toNative(env, motionEventObj, & motionEvent);
-
- return gNativeInputManager->getInputManager()->injectInputEvent(& motionEvent,
- injectorPid, injectorUid, sync, timeoutMillis);
}
static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
@@ -2148,10 +2153,8 @@
(void*) android_server_InputManager_nativeRegisterInputChannel },
{ "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
(void*) android_server_InputManager_nativeUnregisterInputChannel },
- { "nativeInjectKeyEvent", "(Landroid/view/KeyEvent;IIZI)I",
- (void*) android_server_InputManager_nativeInjectKeyEvent },
- { "nativeInjectMotionEvent", "(Landroid/view/MotionEvent;IIZI)I",
- (void*) android_server_InputManager_nativeInjectMotionEvent },
+ { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
+ (void*) android_server_InputManager_nativeInjectInputEvent },
{ "nativeSetInputWindows", "([Lcom/android/server/InputWindow;)V",
(void*) android_server_InputManager_nativeSetInputWindows },
{ "nativeSetFocusedApplication", "(Lcom/android/server/InputApplication;)V",
@@ -2318,6 +2321,14 @@
GET_FIELD_ID(gInputApplicationClassInfo.token, gInputApplicationClassInfo.clazz,
"token", "Ljava/lang/Object;");
+ // KeyEvent
+
+ FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
+
+ // MotionEVent
+
+ FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
+
return 0;
}