diff options
author | Jeff Brown <jeffbrown@google.com> | 2011-05-25 14:32:05 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-05-25 14:32:05 -0700 |
commit | 36001a9f48a1ff70504db4d2d8039f4a5f385caa (patch) | |
tree | 7d99e5800c6a485c89e5948359d2b136d86fcc96 /services | |
parent | c2d200d4fbf3b0a39bf7518cd9d97afec061c6bb (diff) | |
parent | 524ee64b91bc123e1ccfc881a0f1a1e84722251d (diff) | |
download | frameworks_base-36001a9f48a1ff70504db4d2d8039f4a5f385caa.zip frameworks_base-36001a9f48a1ff70504db4d2d8039f4a5f385caa.tar.gz frameworks_base-36001a9f48a1ff70504db4d2d8039f4a5f385caa.tar.bz2 |
Merge "Support chorded fallback keys. (DO NOT MERGE)" into honeycomb-mr2
Diffstat (limited to 'services')
-rw-r--r-- | services/input/InputDispatcher.cpp | 265 | ||||
-rw-r--r-- | services/input/InputDispatcher.h | 55 | ||||
-rw-r--r-- | services/jni/com_android_server_InputManager.cpp | 8 |
3 files changed, 227 insertions, 101 deletions
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp index b67929a..7ac2f13 100644 --- a/services/input/InputDispatcher.cpp +++ b/services/input/InputDispatcher.cpp @@ -565,18 +565,19 @@ void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropR } switch (entry->type) { - case EventEntry::TYPE_KEY: - synthesizeCancelationEventsForAllConnectionsLocked( - InputState::CANCEL_NON_POINTER_EVENTS, reason); + case EventEntry::TYPE_KEY: { + CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason); + synthesizeCancelationEventsForAllConnectionsLocked(options); break; + } case EventEntry::TYPE_MOTION: { MotionEntry* motionEntry = static_cast<MotionEntry*>(entry); if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) { - synthesizeCancelationEventsForAllConnectionsLocked( - InputState::CANCEL_POINTER_EVENTS, reason); + CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason); + synthesizeCancelationEventsForAllConnectionsLocked(options); } else { - synthesizeCancelationEventsForAllConnectionsLocked( - InputState::CANCEL_NON_POINTER_EVENTS, reason); + CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason); + synthesizeCancelationEventsForAllConnectionsLocked(options); } break; } @@ -869,8 +870,9 @@ bool InputDispatcher::dispatchMotionLocked( // Dispatch the motion. if (conflictingPointerActions) { - synthesizeCancelationEventsForAllConnectionsLocked( - InputState::CANCEL_POINTER_EVENTS, "Conflicting pointer actions."); + CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, + "conflicting pointer actions"); + synthesizeCancelationEventsForAllConnectionsLocked(options); } dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false); return true; @@ -1036,9 +1038,9 @@ void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout if (connectionIndex >= 0) { sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); if (connection->status == Connection::STATUS_NORMAL) { - synthesizeCancelationEventsForConnectionLocked( - connection, InputState::CANCEL_ALL_EVENTS, + CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "application not responding"); + synthesizeCancelationEventsForConnectionLocked(connection, options); } } } @@ -2080,26 +2082,24 @@ int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data } void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked( - InputState::CancelationOptions options, const char* reason) { + const CancelationOptions& options) { for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) { synthesizeCancelationEventsForConnectionLocked( - mConnectionsByReceiveFd.valueAt(i), options, reason); + mConnectionsByReceiveFd.valueAt(i), options); } } void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked( - const sp<InputChannel>& channel, InputState::CancelationOptions options, - const char* reason) { + const sp<InputChannel>& channel, const CancelationOptions& options) { ssize_t index = getConnectionIndexLocked(channel); if (index >= 0) { synthesizeCancelationEventsForConnectionLocked( - mConnectionsByReceiveFd.valueAt(index), options, reason); + mConnectionsByReceiveFd.valueAt(index), options); } } void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( - const sp<Connection>& connection, InputState::CancelationOptions options, - const char* reason) { + const sp<Connection>& connection, const CancelationOptions& options) { nsecs_t currentTime = now(); mTempCancelationEvents.clear(); @@ -2110,8 +2110,9 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( && connection->status != Connection::STATUS_BROKEN) { #if DEBUG_OUTBOUND_EVENT_DETAILS LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync " - "with reality: %s, options=%d.", - connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options); + "with reality: %s, mode=%d.", + connection->getInputChannelName(), mTempCancelationEvents.size(), + options.reason, options.mode); #endif for (size_t i = 0; i < mTempCancelationEvents.size(); i++) { EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i); @@ -2751,8 +2752,9 @@ void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) { LOGD("Focus left window: %s", oldFocusedWindowChannel->getName().string()); #endif - synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel, - InputState::CANCEL_NON_POINTER_EVENTS, "focus left window"); + CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, + "focus left window"); + synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel, options); oldFocusedWindowChannel.clear(); } } @@ -2773,8 +2775,9 @@ void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) { #if DEBUG_FOCUS LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string()); #endif - synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel, - InputState::CANCEL_POINTER_EVENTS, "touched window was removed"); + CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, + "touched window was removed"); + synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel, options); mTouchState.windows.removeAt(i); } } @@ -2910,9 +2913,9 @@ bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel, sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex); fromConnection->inputState.copyPointerStateTo(toConnection->inputState); - synthesizeCancelationEventsForConnectionLocked(fromConnection, - InputState::CANCEL_POINTER_EVENTS, + CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, "transferring touch focus from this window to another window"); + synthesizeCancelationEventsForConnectionLocked(fromConnection, options); } #if DEBUG_FOCUS @@ -2930,7 +2933,8 @@ void InputDispatcher::resetAndDropEverythingLocked(const char* reason) { LOGD("Resetting and dropping all events (%s).", reason); #endif - synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason); + CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason); + synthesizeCancelationEventsForAllConnectionsLocked(options); resetKeyRepeatLocked(); releasePendingEventLocked(); @@ -3261,58 +3265,49 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible( if (!connection->outboundQueue.isEmpty()) { DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next; if (dispatchEntry->inProgress - && dispatchEntry->hasForegroundTarget() && dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) { KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry); if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) { - if (handled) { - // If the application handled a non-fallback key, then immediately - // cancel all fallback keys previously dispatched to the application. - // This behavior will prevent chording with fallback keys (so they cannot - // be used as modifiers) but it will ensure that fallback keys do not - // get stuck. This takes care of the case where the application does not handle - // the original DOWN so we generate a fallback DOWN but it does handle - // the original UP in which case we want to send a fallback CANCEL. - synthesizeCancelationEventsForConnectionLocked(connection, - InputState::CANCEL_FALLBACK_EVENTS, - "application handled a non-fallback event, " - "canceling all fallback events"); - connection->originalKeyCodeForFallback = -1; + // Get the fallback key state. + // Clear it out after dispatching the UP. + int32_t originalKeyCode = keyEntry->keyCode; + int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode); + if (keyEntry->action == AKEY_EVENT_ACTION_UP) { + connection->inputState.removeFallbackKey(originalKeyCode); + } + + if (handled || !dispatchEntry->hasForegroundTarget()) { + // If the application handles the original key for which we previously + // generated a fallback or if the window is not a foreground window, + // then cancel the associated fallback key, if any. + if (fallbackKeyCode != -1) { + if (fallbackKeyCode != AKEYCODE_UNKNOWN) { + CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS, + "application handled the original non-fallback key " + "or is no longer a foreground target, " + "canceling previously dispatched fallback key"); + options.keyCode = fallbackKeyCode; + synthesizeCancelationEventsForConnectionLocked(connection, options); + } + connection->inputState.removeFallbackKey(originalKeyCode); + } } else { // If the application did not handle a non-fallback key, first check - // that we are in a good state to handle the fallback key. Then ask - // the policy what to do with it. - if (connection->originalKeyCodeForFallback < 0) { - if (keyEntry->action != AKEY_EVENT_ACTION_DOWN - || keyEntry->repeatCount != 0) { + // that we are in a good state to perform unhandled key event processing + // Then ask the policy what to do with it. + bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN + && keyEntry->repeatCount == 0; + if (fallbackKeyCode == -1 && !initialDown) { #if DEBUG_OUTBOUND_EVENT_DETAILS - LOGD("Unhandled key event: Skipping fallback since this " - "is not an initial down. " - "keyCode=%d, action=%d, repeatCount=%d", - keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount); + LOGD("Unhandled key event: Skipping unhandled key event processing " + "since this is not an initial down. " + "keyCode=%d, action=%d, repeatCount=%d", + originalKeyCode, keyEntry->action, keyEntry->repeatCount); #endif - goto SkipFallback; - } - - // Start handling the fallback key on DOWN. - connection->originalKeyCodeForFallback = keyEntry->keyCode; - } else { - if (keyEntry->keyCode != connection->originalKeyCodeForFallback) { -#if DEBUG_OUTBOUND_EVENT_DETAILS - LOGD("Unhandled key event: Skipping fallback since there is " - "already a different fallback in progress. " - "keyCode=%d, originalKeyCodeForFallback=%d", - keyEntry->keyCode, connection->originalKeyCodeForFallback); -#endif - goto SkipFallback; - } - - // Finish handling the fallback key on UP. - if (keyEntry->action == AKEY_EVENT_ACTION_UP) { - connection->originalKeyCodeForFallback = -1; - } + goto SkipFallback; } + // Dispatch the unhandled key to the policy. #if DEBUG_OUTBOUND_EVENT_DETAILS LOGD("Unhandled key event: Asking policy to perform fallback action. " "keyCode=%d, action=%d, repeatCount=%d", @@ -3329,18 +3324,78 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible( mLock.lock(); if (connection->status != Connection::STATUS_NORMAL) { + connection->inputState.removeFallbackKey(originalKeyCode); return; } assert(connection->outboundQueue.headSentinel.next == dispatchEntry); + // Latch the fallback keycode for this key on an initial down. + // The fallback keycode cannot change at any other point in the lifecycle. + if (initialDown) { + if (fallback) { + fallbackKeyCode = event.getKeyCode(); + } else { + fallbackKeyCode = AKEYCODE_UNKNOWN; + } + connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode); + } + + assert(fallbackKeyCode != -1); + + // Cancel the fallback key if the policy decides not to send it anymore. + // We will continue to dispatch the key to the policy but we will no + // longer dispatch a fallback key to the application. + if (fallbackKeyCode != AKEYCODE_UNKNOWN + && (!fallback || fallbackKeyCode != event.getKeyCode())) { +#if DEBUG_OUTBOUND_EVENT_DETAILS + if (fallback) { + LOGD("Unhandled key event: Policy requested to send key %d" + "as a fallback for %d, but on the DOWN it had requested " + "to send %d instead. Fallback canceled.", + event.getKeyCode(), originalKeyCode, fallbackKeyCode); + } else { + LOGD("Unhandled key event: Policy did not request fallback for %d," + "but on the DOWN it had requested to send %d. " + "Fallback canceled.", + originalKeyCode, fallbackKeyCode); + } +#endif + + CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS, + "canceling fallback, policy no longer desires it"); + options.keyCode = fallbackKeyCode; + synthesizeCancelationEventsForConnectionLocked(connection, options); + + fallback = false; + fallbackKeyCode = AKEYCODE_UNKNOWN; + if (keyEntry->action != AKEY_EVENT_ACTION_UP) { + connection->inputState.setFallbackKey(originalKeyCode, + fallbackKeyCode); + } + } + +#if DEBUG_OUTBOUND_EVENT_DETAILS + { + String8 msg; + const KeyedVector<int32_t, int32_t>& fallbackKeys = + connection->inputState.getFallbackKeys(); + for (size_t i = 0; i < fallbackKeys.size(); i++) { + msg.appendFormat(", %d->%d", fallbackKeys.keyAt(i), + fallbackKeys.valueAt(i)); + } + LOGD("Unhandled key event: %d currently tracked fallback keys%s.", + fallbackKeys.size(), msg.string()); + } +#endif + if (fallback) { // Restart the dispatch cycle using the fallback key. keyEntry->eventTime = event.getEventTime(); keyEntry->deviceId = event.getDeviceId(); keyEntry->source = event.getSource(); keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK; - keyEntry->keyCode = event.getKeyCode(); + keyEntry->keyCode = fallbackKeyCode; keyEntry->scanCode = event.getScanCode(); keyEntry->metaState = event.getMetaState(); keyEntry->repeatCount = event.getRepeatCount(); @@ -3349,13 +3404,17 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible( #if DEBUG_OUTBOUND_EVENT_DETAILS LOGD("Unhandled key event: Dispatching fallback key. " - "fallbackKeyCode=%d, fallbackMetaState=%08x", - keyEntry->keyCode, keyEntry->metaState); + "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x", + originalKeyCode, fallbackKeyCode, keyEntry->metaState); #endif dispatchEntry->inProgress = false; startDispatchCycleLocked(now(), connection); return; + } else { +#if DEBUG_OUTBOUND_EVENT_DETAILS + LOGD("Unhandled key event: No fallback key."); +#endif } } } @@ -3649,6 +3708,17 @@ void InputDispatcher::InputState::trackEvent( void InputDispatcher::InputState::trackKey( const KeyEntry* entry) { int32_t action = entry->action; + if (action == AKEY_EVENT_ACTION_UP + && (entry->flags & AKEY_EVENT_FLAG_FALLBACK)) { + for (size_t i = 0; i < mFallbackKeys.size(); ) { + if (mFallbackKeys.valueAt(i) == entry->keyCode) { + mFallbackKeys.removeItemsAt(i); + } else { + i += 1; + } + } + } + for (size_t i = 0; i < mKeyMementos.size(); i++) { KeyMemento& memento = mKeyMementos.editItemAt(i); if (memento.deviceId == entry->deviceId @@ -3736,7 +3806,7 @@ void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime, Allocator* allocator, Vector<EventEntry*>& outEvents, - CancelationOptions options) { + const CancelationOptions& options) { for (size_t i = 0; i < mKeyMementos.size(); ) { const KeyMemento& memento = mKeyMementos.itemAt(i); if (shouldCancelKey(memento, options)) { @@ -3768,6 +3838,7 @@ void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTim void InputDispatcher::InputState::clear() { mKeyMementos.clear(); mMotionMementos.clear(); + mFallbackKeys.clear(); } void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const { @@ -3788,13 +3859,36 @@ void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const { } } +int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) { + ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode); + return index >= 0 ? mFallbackKeys.valueAt(index) : -1; +} + +void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode, + int32_t fallbackKeyCode) { + ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode); + if (index >= 0) { + mFallbackKeys.replaceValueAt(index, fallbackKeyCode); + } else { + mFallbackKeys.add(originalKeyCode, fallbackKeyCode); + } +} + +void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) { + mFallbackKeys.removeItem(originalKeyCode); +} + bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento, - CancelationOptions options) { - switch (options) { - case CANCEL_ALL_EVENTS: - case CANCEL_NON_POINTER_EVENTS: + const CancelationOptions& options) { + if (options.keyCode != -1 && memento.keyCode != options.keyCode) { + return false; + } + + switch (options.mode) { + case CancelationOptions::CANCEL_ALL_EVENTS: + case CancelationOptions::CANCEL_NON_POINTER_EVENTS: return true; - case CANCEL_FALLBACK_EVENTS: + case CancelationOptions::CANCEL_FALLBACK_EVENTS: return memento.flags & AKEY_EVENT_FLAG_FALLBACK; default: return false; @@ -3802,13 +3896,13 @@ bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento, } bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento, - CancelationOptions options) { - switch (options) { - case CANCEL_ALL_EVENTS: + const CancelationOptions& options) { + switch (options.mode) { + case CancelationOptions::CANCEL_ALL_EVENTS: return true; - case CANCEL_POINTER_EVENTS: + case CancelationOptions::CANCEL_POINTER_EVENTS: return memento.source & AINPUT_SOURCE_CLASS_POINTER; - case CANCEL_NON_POINTER_EVENTS: + case CancelationOptions::CANCEL_NON_POINTER_EVENTS: return !(memento.source & AINPUT_SOURCE_CLASS_POINTER); default: return false; @@ -3822,8 +3916,7 @@ InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel, const sp<InputWindowHandle>& inputWindowHandle) : status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle), inputPublisher(inputChannel), - lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX), - originalKeyCodeForFallback(-1) { + lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) { } InputDispatcher::Connection::~Connection() { diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h index dd89328..27c5950 100644 --- a/services/input/InputDispatcher.h +++ b/services/input/InputDispatcher.h @@ -594,18 +594,32 @@ private: void releaseEventEntryInjectionState(EventEntry* entry); }; - /* Tracks dispatched key and motion event state so that cancelation events can be - * synthesized when events are dropped. */ - class InputState { - public: - // Specifies the sources to cancel. - enum CancelationOptions { + /* Specifies which events are to be canceled and why. */ + struct CancelationOptions { + enum Mode { CANCEL_ALL_EVENTS = 0, CANCEL_POINTER_EVENTS = 1, CANCEL_NON_POINTER_EVENTS = 2, CANCEL_FALLBACK_EVENTS = 3, }; + // The criterion to use to determine which events should be canceled. + Mode mode; + + // Descriptive reason for the cancelation. + const char* reason; + + // The specific keycode of the key event to cancel, or -1 to cancel any key event. + int32_t keyCode; + + CancelationOptions(Mode mode, const char* reason) : + mode(mode), reason(reason), keyCode(-1) { } + }; + + /* Tracks dispatched key and motion event state so that cancelation events can be + * synthesized when events are dropped. */ + class InputState { + public: InputState(); ~InputState(); @@ -623,7 +637,7 @@ private: // Synthesizes cancelation events for the current state and resets the tracked state. void synthesizeCancelationEvents(nsecs_t currentTime, Allocator* allocator, - Vector<EventEntry*>& outEvents, CancelationOptions options); + Vector<EventEntry*>& outEvents, const CancelationOptions& options); // Clears the current state. void clear(); @@ -631,6 +645,21 @@ private: // Copies pointer-related parts of the input state to another instance. void copyPointerStateTo(InputState& other) const; + // Gets the fallback key associated with a keycode. + // Returns -1 if none. + // Returns AKEYCODE_UNKNOWN if we are only dispatching the unhandled key to the policy. + int32_t getFallbackKey(int32_t originalKeyCode); + + // Sets the fallback key for a particular keycode. + void setFallbackKey(int32_t originalKeyCode, int32_t fallbackKeyCode); + + // Removes the fallback key for a particular keycode. + void removeFallbackKey(int32_t originalKeyCode); + + inline const KeyedVector<int32_t, int32_t>& getFallbackKeys() const { + return mFallbackKeys; + } + private: struct KeyMemento { int32_t deviceId; @@ -656,11 +685,12 @@ private: Vector<KeyMemento> mKeyMementos; Vector<MotionMemento> mMotionMementos; + KeyedVector<int32_t, int32_t> mFallbackKeys; static bool shouldCancelKey(const KeyMemento& memento, - CancelationOptions options); + const CancelationOptions& options); static bool shouldCancelMotion(const MotionMemento& memento, - CancelationOptions options); + const CancelationOptions& options); }; /* Manages the dispatch state associated with a single input channel. */ @@ -687,7 +717,6 @@ private: nsecs_t lastEventTime; // the time when the event was originally captured nsecs_t lastDispatchTime; // the time when the last event was dispatched - int32_t originalKeyCodeForFallback; // original keycode for fallback in progress, -1 if none explicit Connection(const sp<InputChannel>& inputChannel, const sp<InputWindowHandle>& inputWindowHandle); @@ -929,11 +958,11 @@ private: static int handleReceiveCallback(int receiveFd, int events, void* data); void synthesizeCancelationEventsForAllConnectionsLocked( - InputState::CancelationOptions options, const char* reason); + const CancelationOptions& options); void synthesizeCancelationEventsForInputChannelLocked(const sp<InputChannel>& channel, - InputState::CancelationOptions options, const char* reason); + const CancelationOptions& options); void synthesizeCancelationEventsForConnectionLocked(const sp<Connection>& connection, - InputState::CancelationOptions options, const char* reason); + const CancelationOptions& options); // Splitting motion events across windows. MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds); diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp index 3fb76e4..426197a 100644 --- a/services/jni/com_android_server_InputManager.cpp +++ b/services/jni/com_android_server_InputManager.cpp @@ -795,7 +795,9 @@ bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& input jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj, gCallbacksClassInfo.dispatchUnhandledKey, inputWindowHandleObj, keyEventObj, policyFlags); - checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey"); + if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) { + fallbackKeyEventObj = NULL; + } android_view_KeyEvent_recycle(env, keyEventObj); env->DeleteLocalRef(keyEventObj); @@ -826,7 +828,9 @@ bool NativeInputManager::checkInjectEventsPermissionNonReentrant( JNIEnv* env = jniEnv(); jboolean result = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid); - checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission"); + if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) { + result = false; + } return result; } |