diff options
-rw-r--r-- | core/jni/android_view_InputEventReceiver.cpp | 2 | ||||
-rw-r--r-- | core/jni/android_view_InputEventSender.cpp | 3 | ||||
-rw-r--r-- | core/jni/android_view_InputQueue.cpp | 7 | ||||
-rw-r--r-- | core/jni/android_view_KeyCharacterMap.cpp | 2 | ||||
-rw-r--r-- | core/jni/android_view_KeyEvent.cpp | 26 | ||||
-rw-r--r-- | core/jni/android_view_KeyEvent.h | 5 | ||||
-rw-r--r-- | native/android/input.cpp | 7 | ||||
-rw-r--r-- | services/core/jni/com_android_server_input_InputManagerService.cpp | 282 |
8 files changed, 155 insertions, 179 deletions
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp index 6fcff990974a..0f41229dd0c1 100644 --- a/core/jni/android_view_InputEventReceiver.cpp +++ b/core/jni/android_view_InputEventReceiver.cpp @@ -374,7 +374,7 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, } inputEventObj = android_view_KeyEvent_fromNative(env, - static_cast<KeyEvent*>(inputEvent)); + static_cast<KeyEvent&>(*inputEvent)); break; case InputEventType::MOTION: { diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp index ad54004ec81c..15270efbde57 100644 --- a/core/jni/android_view_InputEventSender.cpp +++ b/core/jni/android_view_InputEventSender.cpp @@ -353,8 +353,7 @@ static jboolean nativeSendKeyEvent(JNIEnv* env, jclass clazz, jlong senderPtr, jint seq, jobject eventObj) { sp<NativeInputEventSender> sender = reinterpret_cast<NativeInputEventSender*>(senderPtr); - KeyEvent event; - android_view_KeyEvent_toNative(env, eventObj, &event); + const KeyEvent event = android_view_KeyEvent_toNative(env, eventObj); status_t status = sender->sendKeyEvent(seq, &event); return !status; } diff --git a/core/jni/android_view_InputQueue.cpp b/core/jni/android_view_InputQueue.cpp index 2c4966eaf408..21db37e1ef7c 100644 --- a/core/jni/android_view_InputQueue.cpp +++ b/core/jni/android_view_InputQueue.cpp @@ -221,12 +221,7 @@ static jlong nativeSendKeyEvent(JNIEnv* env, jobject clazz, jlong ptr, jobject e jboolean predispatch) { InputQueue* queue = reinterpret_cast<InputQueue*>(ptr); KeyEvent* event = queue->createKeyEvent(); - status_t status = android_view_KeyEvent_toNative(env, eventObj, event); - if (status) { - queue->recycleInputEvent(event); - jniThrowRuntimeException(env, "Could not read contents of KeyEvent object."); - return -1; - } + *event = android_view_KeyEvent_toNative(env, eventObj); if (predispatch) { event->setFlags(event->getFlags() | AKEY_EVENT_FLAG_PREDISPATCH); diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp index 469e577829d8..8fa03cfc5b6f 100644 --- a/core/jni/android_view_KeyCharacterMap.cpp +++ b/core/jni/android_view_KeyCharacterMap.cpp @@ -217,7 +217,7 @@ static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jlong ptr, result = env->NewObjectArray(jsize(events.size()), gKeyEventClassInfo.clazz, NULL); if (result) { for (size_t i = 0; i < events.size(); i++) { - jobject keyEventObj = android_view_KeyEvent_fromNative(env, &events.itemAt(i)); + jobject keyEventObj = android_view_KeyEvent_fromNative(env, events.itemAt(i)); if (!keyEventObj) break; // threw OOM exception env->SetObjectArrayElement(result, jsize(i), keyEventObj); env->DeleteLocalRef(keyEventObj); diff --git a/core/jni/android_view_KeyEvent.cpp b/core/jni/android_view_KeyEvent.cpp index d5568df14aad..a9c991919361 100644 --- a/core/jni/android_view_KeyEvent.cpp +++ b/core/jni/android_view_KeyEvent.cpp @@ -94,16 +94,16 @@ static struct { // ---------------------------------------------------------------------------- -jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) { - ScopedLocalRef<jbyteArray> hmac = toJbyteArray(env, event->getHmac()); +jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent& event) { + ScopedLocalRef<jbyteArray> hmac = toJbyteArray(env, event.getHmac()); jobject eventObj = env->CallStaticObjectMethod(gKeyEventClassInfo.clazz, gKeyEventClassInfo.obtain, - event->getId(), event->getDownTime(), event->getEventTime(), - event->getAction(), event->getKeyCode(), - event->getRepeatCount(), event->getMetaState(), - event->getDeviceId(), event->getScanCode(), - event->getFlags(), event->getSource(), - event->getDisplayId(), hmac.get(), nullptr); + event.getId(), event.getDownTime(), event.getEventTime(), + event.getAction(), event.getKeyCode(), + event.getRepeatCount(), event.getMetaState(), + event.getDeviceId(), event.getScanCode(), event.getFlags(), + event.getSource(), event.getDisplayId(), hmac.get(), + nullptr); if (env->ExceptionCheck()) { ALOGE("An exception occurred while obtaining a key event."); LOGE_EX(env); @@ -113,8 +113,7 @@ jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) { return eventObj; } -status_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, - KeyEvent* event) { +KeyEvent android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj) { jint id = env->GetIntField(eventObj, gKeyEventClassInfo.mId); jint deviceId = env->GetIntField(eventObj, gKeyEventClassInfo.mDeviceId); jint source = env->GetIntField(eventObj, gKeyEventClassInfo.mSource); @@ -133,9 +132,10 @@ status_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, jlong downTime = env->GetLongField(eventObj, gKeyEventClassInfo.mDownTime); jlong eventTime = env->GetLongField(eventObj, gKeyEventClassInfo.mEventTime); - event->initialize(id, deviceId, source, displayId, *hmac, action, flags, keyCode, scanCode, - metaState, repeatCount, downTime, eventTime); - return OK; + KeyEvent event; + event.initialize(id, deviceId, source, displayId, *hmac, action, flags, keyCode, scanCode, + metaState, repeatCount, downTime, eventTime); + return event; } status_t android_view_KeyEvent_recycle(JNIEnv* env, jobject eventObj) { diff --git a/core/jni/android_view_KeyEvent.h b/core/jni/android_view_KeyEvent.h index dab6bb75c91e..bc4876a7a835 100644 --- a/core/jni/android_view_KeyEvent.h +++ b/core/jni/android_view_KeyEvent.h @@ -27,12 +27,11 @@ class KeyEvent; /* Obtains an instance of a DVM KeyEvent object as a copy of a native KeyEvent instance. * Returns NULL on error. */ -extern jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event); +extern jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent& event); /* Copies the contents of a DVM KeyEvent object to a native KeyEvent instance. * Returns non-zero on error. */ -extern status_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, - KeyEvent* event); +extern KeyEvent android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj); /* Recycles a DVM KeyEvent object. * Key events should only be recycled if they are owned by the system since user diff --git a/native/android/input.cpp b/native/android/input.cpp index 1bff97dfdada..64e8efeaa4e8 100644 --- a/native/android/input.cpp +++ b/native/android/input.cpp @@ -87,11 +87,8 @@ int64_t AKeyEvent_getDownTime(const AInputEvent* key_event) { const AInputEvent* AKeyEvent_fromJava(JNIEnv* env, jobject keyEvent) { std::unique_ptr<KeyEvent> event = std::make_unique<KeyEvent>(); - android::status_t ret = android::android_view_KeyEvent_toNative(env, keyEvent, event.get()); - if (ret == android::OK) { - return event.release(); - } - return nullptr; + *event = android::android_view_KeyEvent_toNative(env, keyEvent); + return event.release(); } int64_t AKeyEvent_getEventTime(const AInputEvent* key_event) { diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 369c97470245..f0d718a30535 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -342,15 +342,15 @@ public: void notifySensorAccuracy(int32_t deviceId, InputDeviceSensorType sensorType, InputDeviceSensorAccuracy accuracy) override; void notifyVibratorState(int32_t deviceId, bool isOn) override; - bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override; - void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) override; - void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) override; - void interceptMotionBeforeQueueing(const int32_t displayId, nsecs_t when, + bool filterInputEvent(const InputEvent& inputEvent, uint32_t policyFlags) override; + InputDispatcherConfiguration getDispatcherConfiguration() override; + void interceptKeyBeforeQueueing(const KeyEvent& keyEvent, uint32_t& policyFlags) override; + void interceptMotionBeforeQueueing(int32_t displayId, nsecs_t when, uint32_t& policyFlags) override; - nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token, const KeyEvent* keyEvent, + nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token, const KeyEvent& keyEvent, uint32_t policyFlags) override; - bool dispatchUnhandledKey(const sp<IBinder>& token, const KeyEvent* keyEvent, - uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) override; + std::optional<KeyEvent> dispatchUnhandledKey(const sp<IBinder>& token, const KeyEvent& keyEvent, + uint32_t policyFlags) override; void pokeUserActivity(nsecs_t eventTime, int32_t eventType, int32_t displayId) override; void onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) override; void setPointerCapture(const PointerCaptureRequest& request) override; @@ -450,7 +450,7 @@ NativeInputManager::NativeInputManager(jobject serviceObj, const sp<Looper>& loo mServiceObj = env->NewGlobalRef(serviceObj); - InputManager* im = new InputManager(this, this); + InputManager* im = new InputManager(this, *this); mInputManager = im; defaultServiceManager()->addService(String16("inputflinger"), im); } @@ -1007,21 +1007,22 @@ void NativeInputManager::notifyVibratorState(int32_t deviceId, bool isOn) { checkAndClearExceptionFromCallback(env, "notifyVibratorState"); } -void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) { +InputDispatcherConfiguration NativeInputManager::getDispatcherConfiguration() { ATRACE_CALL(); + InputDispatcherConfiguration config; JNIEnv* env = jniEnv(); - jint keyRepeatTimeout = env->CallIntMethod(mServiceObj, - gServiceClassInfo.getKeyRepeatTimeout); + jint keyRepeatTimeout = env->CallIntMethod(mServiceObj, gServiceClassInfo.getKeyRepeatTimeout); if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) { - outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout); + config.keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout); } - jint keyRepeatDelay = env->CallIntMethod(mServiceObj, - gServiceClassInfo.getKeyRepeatDelay); + jint keyRepeatDelay = env->CallIntMethod(mServiceObj, gServiceClassInfo.getKeyRepeatDelay); if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) { - outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay); + config.keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay); } + + return config; } void NativeInputManager::displayRemoved(JNIEnv* env, int32_t displayId) { @@ -1294,110 +1295,112 @@ void NativeInputManager::notifyStylusGestureStarted(int32_t deviceId, nsecs_t ev checkAndClearExceptionFromCallback(env, "notifyStylusGestureStarted"); } -bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) { +bool NativeInputManager::filterInputEvent(const InputEvent& inputEvent, uint32_t policyFlags) { ATRACE_CALL(); - jobject inputEventObj; - JNIEnv* env = jniEnv(); - switch (inputEvent->getType()) { + + ScopedLocalRef<jobject> inputEventObj(env); + switch (inputEvent.getType()) { case InputEventType::KEY: - inputEventObj = - android_view_KeyEvent_fromNative(env, static_cast<const KeyEvent*>(inputEvent)); + inputEventObj.reset( + android_view_KeyEvent_fromNative(env, + static_cast<const KeyEvent&>(inputEvent))); break; case InputEventType::MOTION: - inputEventObj = android_view_MotionEvent_obtainAsCopy(env, - static_cast<const MotionEvent&>( - *inputEvent)); + inputEventObj.reset( + android_view_MotionEvent_obtainAsCopy(env, + static_cast<const MotionEvent&>( + inputEvent))); break; default: return true; // dispatch the event normally } - if (!inputEventObj) { + if (!inputEventObj.get()) { ALOGE("Failed to obtain input event object for filterInputEvent."); return true; // dispatch the event normally } // The callee is responsible for recycling the event. - jboolean pass = env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent, - inputEventObj, policyFlags); + const jboolean continueEventDispatch = + env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent, + inputEventObj.get(), policyFlags); if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) { - pass = true; + return true; // dispatch the event normally } - env->DeleteLocalRef(inputEventObj); - return pass; + return continueEventDispatch; } -void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent, - uint32_t& policyFlags) { +void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent& keyEvent, + uint32_t& policyFlags) { ATRACE_CALL(); // Policy: // - Ignore untrusted events and pass them along. // - Ask the window manager what to do with normal events and trusted injected events. // - For normal events wake and brighten the screen if currently off or dim. - bool interactive = mInteractive.load(); + const bool interactive = mInteractive.load(); if (interactive) { policyFlags |= POLICY_FLAG_INTERACTIVE; } - if ((policyFlags & POLICY_FLAG_TRUSTED)) { - nsecs_t when = keyEvent->getEventTime(); - JNIEnv* env = jniEnv(); - jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent); - jint wmActions; - if (keyEventObj) { - wmActions = env->CallIntMethod(mServiceObj, - gServiceClassInfo.interceptKeyBeforeQueueing, - keyEventObj, policyFlags); - if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) { - wmActions = 0; - } - android_view_KeyEvent_recycle(env, keyEventObj); - env->DeleteLocalRef(keyEventObj); - } else { - ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing."); - wmActions = 0; - } - handleInterceptActions(wmActions, when, /*byref*/ policyFlags); - } else { + if ((policyFlags & POLICY_FLAG_TRUSTED) == 0) { if (interactive) { policyFlags |= POLICY_FLAG_PASS_TO_USER; } + return; + } + + const nsecs_t when = keyEvent.getEventTime(); + JNIEnv* env = jniEnv(); + ScopedLocalRef<jobject> keyEventObj(env, android_view_KeyEvent_fromNative(env, keyEvent)); + if (!keyEventObj.get()) { + ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing."); + return; + } + + jint wmActions = env->CallIntMethod(mServiceObj, gServiceClassInfo.interceptKeyBeforeQueueing, + keyEventObj.get(), policyFlags); + if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) { + wmActions = 0; } + android_view_KeyEvent_recycle(env, keyEventObj.get()); + handleInterceptActions(wmActions, when, /*byref*/ policyFlags); } -void NativeInputManager::interceptMotionBeforeQueueing(const int32_t displayId, nsecs_t when, - uint32_t& policyFlags) { +void NativeInputManager::interceptMotionBeforeQueueing(int32_t displayId, nsecs_t when, + uint32_t& policyFlags) { ATRACE_CALL(); // Policy: // - Ignore untrusted events and pass them along. // - No special filtering for injected events required at this time. // - Filter normal events based on screen state. // - For normal events brighten (but do not wake) the screen if currently dim. - bool interactive = mInteractive.load(); + const bool interactive = mInteractive.load(); if (interactive) { policyFlags |= POLICY_FLAG_INTERACTIVE; } - if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) { - if (policyFlags & POLICY_FLAG_INTERACTIVE) { - policyFlags |= POLICY_FLAG_PASS_TO_USER; - } else { - JNIEnv* env = jniEnv(); - jint wmActions = env->CallIntMethod(mServiceObj, - gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive, - displayId, when, policyFlags); - if (checkAndClearExceptionFromCallback(env, - "interceptMotionBeforeQueueingNonInteractive")) { - wmActions = 0; - } - handleInterceptActions(wmActions, when, /*byref*/ policyFlags); - } - } else { + if ((policyFlags & POLICY_FLAG_TRUSTED) == 0 || (policyFlags & POLICY_FLAG_INJECTED)) { if (interactive) { policyFlags |= POLICY_FLAG_PASS_TO_USER; } + return; } + + if (policyFlags & POLICY_FLAG_INTERACTIVE) { + policyFlags |= POLICY_FLAG_PASS_TO_USER; + return; + } + + JNIEnv* env = jniEnv(); + const jint wmActions = + env->CallIntMethod(mServiceObj, + gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive, + displayId, when, policyFlags); + if (checkAndClearExceptionFromCallback(env, "interceptMotionBeforeQueueingNonInteractive")) { + return; + } + handleInterceptActions(wmActions, when, /*byref*/ policyFlags); } void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when, @@ -1411,81 +1414,76 @@ void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when, } } -nsecs_t NativeInputManager::interceptKeyBeforeDispatching( - const sp<IBinder>& token, - const KeyEvent* keyEvent, uint32_t policyFlags) { +nsecs_t NativeInputManager::interceptKeyBeforeDispatching(const sp<IBinder>& token, + const KeyEvent& keyEvent, + uint32_t policyFlags) { ATRACE_CALL(); // Policy: // - Ignore untrusted events and pass them along. // - Filter normal events and trusted injected events through the window manager policy to // handle the HOME key and the like. - nsecs_t result = 0; - if (policyFlags & POLICY_FLAG_TRUSTED) { - JNIEnv* env = jniEnv(); - ScopedLocalFrame localFrame(env); - - // Token may be null - jobject tokenObj = javaObjectForIBinder(env, token); - - jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent); - if (keyEventObj) { - jlong delayMillis = env->CallLongMethod(mServiceObj, - gServiceClassInfo.interceptKeyBeforeDispatching, - tokenObj, keyEventObj, policyFlags); - bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching"); - android_view_KeyEvent_recycle(env, keyEventObj); - env->DeleteLocalRef(keyEventObj); - if (!error) { - if (delayMillis < 0) { - result = -1; - } else if (delayMillis > 0) { - result = milliseconds_to_nanoseconds(delayMillis); - } - } - } else { - ALOGE("Failed to obtain key event object for interceptKeyBeforeDispatching."); - } + if ((policyFlags & POLICY_FLAG_TRUSTED) == 0) { + return 0; } - return result; + + JNIEnv* env = jniEnv(); + ScopedLocalFrame localFrame(env); + + // Token may be null + ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token)); + ScopedLocalRef<jobject> keyEventObj(env, android_view_KeyEvent_fromNative(env, keyEvent)); + if (!keyEventObj.get()) { + ALOGE("Failed to obtain key event object for interceptKeyBeforeDispatching."); + return 0; + } + + const jlong delayMillis = + env->CallLongMethod(mServiceObj, gServiceClassInfo.interceptKeyBeforeDispatching, + tokenObj.get(), keyEventObj.get(), policyFlags); + android_view_KeyEvent_recycle(env, keyEventObj.get()); + if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching")) { + return 0; + } + return delayMillis < 0 ? -1 : milliseconds_to_nanoseconds(delayMillis); } -bool NativeInputManager::dispatchUnhandledKey(const sp<IBinder>& token, - const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) { +std::optional<KeyEvent> NativeInputManager::dispatchUnhandledKey(const sp<IBinder>& token, + const KeyEvent& keyEvent, + uint32_t policyFlags) { ATRACE_CALL(); // Policy: // - Ignore untrusted events and do not perform default handling. - bool result = false; - if (policyFlags & POLICY_FLAG_TRUSTED) { - JNIEnv* env = jniEnv(); - ScopedLocalFrame localFrame(env); - - // Note: tokenObj may be null. - jobject tokenObj = javaObjectForIBinder(env, token); - jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent); - if (keyEventObj) { - jobject fallbackKeyEventObj = env->CallObjectMethod(mServiceObj, - gServiceClassInfo.dispatchUnhandledKey, - tokenObj, keyEventObj, policyFlags); - if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) { - fallbackKeyEventObj = nullptr; - } - android_view_KeyEvent_recycle(env, keyEventObj); - env->DeleteLocalRef(keyEventObj); - - if (fallbackKeyEventObj) { - // Note: outFallbackKeyEvent may be the same object as keyEvent. - if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj, - outFallbackKeyEvent)) { - result = true; - } - android_view_KeyEvent_recycle(env, fallbackKeyEventObj); - env->DeleteLocalRef(fallbackKeyEventObj); - } - } else { - ALOGE("Failed to obtain key event object for dispatchUnhandledKey."); - } + if ((policyFlags & POLICY_FLAG_TRUSTED) == 0) { + return {}; } - return result; + + JNIEnv* env = jniEnv(); + ScopedLocalFrame localFrame(env); + + // Note: tokenObj may be null. + ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token)); + ScopedLocalRef<jobject> keyEventObj(env, android_view_KeyEvent_fromNative(env, keyEvent)); + if (!keyEventObj.get()) { + ALOGE("Failed to obtain key event object for dispatchUnhandledKey."); + return {}; + } + + ScopedLocalRef<jobject> + fallbackKeyEventObj(env, + env->CallObjectMethod(mServiceObj, + gServiceClassInfo.dispatchUnhandledKey, + tokenObj.get(), keyEventObj.get(), + policyFlags)); + + android_view_KeyEvent_recycle(env, keyEventObj.get()); + if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey") || + !fallbackKeyEventObj.get()) { + return {}; + } + + const KeyEvent fallbackEvent = android_view_KeyEvent_toNative(env, fallbackKeyEventObj.get()); + android_view_KeyEvent_recycle(env, fallbackKeyEventObj.get()); + return fallbackEvent; } void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType, int32_t displayId) { @@ -1876,13 +1874,7 @@ static jint nativeInjectInputEvent(JNIEnv* env, jobject nativeImplObj, jobject i InputEventInjectionSync mode = static_cast<InputEventInjectionSync>(syncMode); if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) { - KeyEvent keyEvent; - status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent); - if (status) { - jniThrowRuntimeException(env, "Could not read contents of KeyEvent object."); - return static_cast<jint>(InputEventInjectionResult::FAILED); - } - + const KeyEvent keyEvent = android_view_KeyEvent_toNative(env, inputEventObj); const InputEventInjectionResult result = im->getInputManager()->getDispatcher().injectInputEvent(&keyEvent, targetUid, mode, std::chrono::milliseconds( @@ -1913,13 +1905,7 @@ static jobject nativeVerifyInputEvent(JNIEnv* env, jobject nativeImplObj, jobjec NativeInputManager* im = getNativeInputManager(env, nativeImplObj); if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) { - KeyEvent keyEvent; - status_t status = android_view_KeyEvent_toNative(env, inputEventObj, &keyEvent); - if (status) { - jniThrowRuntimeException(env, "Could not read contents of KeyEvent object."); - return nullptr; - } - + const KeyEvent keyEvent = android_view_KeyEvent_toNative(env, inputEventObj); std::unique_ptr<VerifiedInputEvent> verifiedEvent = im->getInputManager()->getDispatcher().verifyInputEvent(keyEvent); if (verifiedEvent == nullptr) { |