diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h index e466ddd9e..96b4faedb 100644 --- a/include/ui/InputDispatcher.h +++ b/include/ui/InputDispatcher.h @@ -851,8 +851,8 @@ private: // Inbound event processing. void drainInboundQueueLocked(); - void releasePendingEventLocked(bool wasDropped); - void releaseInboundEventLocked(EventEntry* entry, bool wasDropped); + void releasePendingEventLocked(); + void releaseInboundEventLocked(EventEntry* entry); bool isEventFromReliableSourceLocked(EventEntry* entry); // Dispatch state. @@ -886,10 +886,10 @@ private: nsecs_t currentTime, ConfigurationChangedEntry* entry); bool dispatchKeyLocked( nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout, - nsecs_t* nextWakeupTime); + bool dropEvent, nsecs_t* nextWakeupTime); bool dispatchMotionLocked( nsecs_t currentTime, MotionEntry* entry, - nsecs_t* nextWakeupTime); + bool dropEvent, nsecs_t* nextWakeupTime); void dispatchEventToCurrentInputTargetsLocked( nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample); @@ -914,8 +914,8 @@ private: bool mInputTargetWaitTimeoutExpired; // Finding targets for input events. - void startFindingTargetsLocked(); - void finishFindingTargetsLocked(const InputWindow* window); + void resetTargetsLocked(); + void commitTargetsLocked(const InputWindow* window); int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry, const InputApplication* application, const InputWindow* window, nsecs_t* nextWakeupTime); diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp index 67138174c..1cf7592ff 100644 --- a/libs/ui/InputDispatcher.cpp +++ b/libs/ui/InputDispatcher.cpp @@ -122,7 +122,7 @@ InputDispatcher::~InputDispatcher() { AutoMutex _l(mLock); resetKeyRepeatLocked(); - releasePendingEventLocked(true); + releasePendingEventLocked(); drainInboundQueueLocked(); } @@ -174,7 +174,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout, if (! mDispatchEnabled) { if (mPendingEvent || ! mInboundQueue.isEmpty()) { LOGI("Dropping pending events because input dispatch is disabled."); - releasePendingEventLocked(true); + releasePendingEventLocked(); drainInboundQueueLocked(); } return; @@ -281,51 +281,50 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout, // Now we have an event to dispatch. assert(mPendingEvent != NULL); - bool wasDispatched = false; - bool wasDropped = false; + bool done = false; switch (mPendingEvent->type) { case EventEntry::TYPE_CONFIGURATION_CHANGED: { ConfigurationChangedEntry* typedEntry = static_cast(mPendingEvent); - wasDispatched = dispatchConfigurationChangedLocked(currentTime, typedEntry); + done = dispatchConfigurationChangedLocked(currentTime, typedEntry); break; } case EventEntry::TYPE_KEY: { KeyEntry* typedEntry = static_cast(mPendingEvent); - if (isAppSwitchPendingLocked()) { - if (isAppSwitchKey(typedEntry->keyCode)) { + bool appSwitchKey = isAppSwitchKey(typedEntry->keyCode); + bool dropEvent = isAppSwitchDue && ! appSwitchKey; + done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout, dropEvent, + nextWakeupTime); + if (done) { + if (dropEvent) { + LOGI("Dropped key because of pending overdue app switch."); + } else if (appSwitchKey) { resetPendingAppSwitchLocked(true); - } else if (isAppSwitchDue) { - LOGI("Dropping key because of pending overdue app switch."); - wasDropped = true; - break; } } - wasDispatched = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout, - nextWakeupTime); break; } case EventEntry::TYPE_MOTION: { MotionEntry* typedEntry = static_cast(mPendingEvent); - if (isAppSwitchDue) { - LOGI("Dropping motion because of pending overdue app switch."); - wasDropped = true; - break; + bool dropEvent = isAppSwitchDue; + done = dispatchMotionLocked(currentTime, typedEntry, dropEvent, nextWakeupTime); + if (done) { + if (dropEvent) { + LOGI("Dropped motion because of pending overdue app switch."); + } } - wasDispatched = dispatchMotionLocked(currentTime, typedEntry, nextWakeupTime); break; } default: assert(false); - wasDropped = true; break; } - if (wasDispatched || wasDropped) { - releasePendingEventLocked(wasDropped); + if (done) { + releasePendingEventLocked(); *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately } } @@ -403,21 +402,21 @@ InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command comman void InputDispatcher::drainInboundQueueLocked() { while (! mInboundQueue.isEmpty()) { EventEntry* entry = mInboundQueue.dequeueAtHead(); - releaseInboundEventLocked(entry, true /*wasDropped*/); + releaseInboundEventLocked(entry); } } -void InputDispatcher::releasePendingEventLocked(bool wasDropped) { +void InputDispatcher::releasePendingEventLocked() { if (mPendingEvent) { - releaseInboundEventLocked(mPendingEvent, wasDropped); + releaseInboundEventLocked(mPendingEvent); mPendingEvent = NULL; } } -void InputDispatcher::releaseInboundEventLocked(EventEntry* entry, bool wasDropped) { - if (wasDropped) { +void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) { + if (entry->injectionResult == INPUT_EVENT_INJECTION_PENDING) { #if DEBUG_DISPATCH_CYCLE - LOGD("Pending event was dropped."); + LOGD("Inbound event was dropped. Setting injection result to failed."); #endif setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED); } @@ -492,7 +491,41 @@ bool InputDispatcher::dispatchConfigurationChangedLocked( bool InputDispatcher::dispatchKeyLocked( nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout, - nsecs_t* nextWakeupTime) { + bool dropEvent, nsecs_t* nextWakeupTime) { + // Give the policy a chance to intercept the key. + if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) { + bool trusted; + if (! dropEvent && mFocusedWindow) { + trusted = checkInjectionPermission(mFocusedWindow, + entry->injectorPid, entry->injectorUid); + } else { + trusted = isEventFromReliableSourceLocked(entry); + } + if (trusted) { + CommandEntry* commandEntry = postCommandLocked( + & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible); + if (! dropEvent && mFocusedWindow) { + commandEntry->inputChannel = mFocusedWindow->inputChannel; + } + commandEntry->keyEntry = entry; + entry->refCount += 1; + return false; // wait for the command to run + } else { + entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE; + } + } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) { + resetTargetsLocked(); + setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED); + return true; + } + + // Clean up if dropping the event. + if (dropEvent) { + resetTargetsLocked(); + setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED); + return true; + } + // Preprocessing. if (! entry->dispatchInProgress) { logOutboundKeyDetailsLocked("dispatchKey - ", entry); @@ -521,7 +554,7 @@ bool InputDispatcher::dispatchKeyLocked( } entry->dispatchInProgress = true; - startFindingTargetsLocked(); // resets mCurrentInputTargetsValid + resetTargetsLocked(); } // Identify targets. @@ -539,20 +572,7 @@ bool InputDispatcher::dispatchKeyLocked( } addMonitoringTargetsLocked(); - finishFindingTargetsLocked(window); - } - - // Give the policy a chance to intercept the key. - if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) { - CommandEntry* commandEntry = postCommandLocked( - & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible); - commandEntry->inputChannel = mCurrentInputChannel; - commandEntry->keyEntry = entry; - entry->refCount += 1; - return false; // wait for the command to run - } - if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) { - return true; + commitTargetsLocked(window); } // Dispatch the key. @@ -576,13 +596,20 @@ void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyE } bool InputDispatcher::dispatchMotionLocked( - nsecs_t currentTime, MotionEntry* entry, nsecs_t* nextWakeupTime) { + nsecs_t currentTime, MotionEntry* entry, bool dropEvent, nsecs_t* nextWakeupTime) { + // Clean up if dropping the event. + if (dropEvent) { + resetTargetsLocked(); + setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED); + return true; + } + // Preprocessing. if (! entry->dispatchInProgress) { logOutboundMotionDetailsLocked("dispatchMotion - ", entry); entry->dispatchInProgress = true; - startFindingTargetsLocked(); // resets mCurrentInputTargetsValid + resetTargetsLocked(); } bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER; @@ -610,7 +637,7 @@ bool InputDispatcher::dispatchMotionLocked( } addMonitoringTargetsLocked(); - finishFindingTargetsLocked(window); + commitTargetsLocked(window); } // Dispatch the motion. @@ -705,14 +732,14 @@ void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTi } } -void InputDispatcher::startFindingTargetsLocked() { +void InputDispatcher::resetTargetsLocked() { mCurrentInputTargetsValid = false; mCurrentInputTargets.clear(); mCurrentInputChannel.clear(); mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE; } -void InputDispatcher::finishFindingTargetsLocked(const InputWindow* window) { +void InputDispatcher::commitTargetsLocked(const InputWindow* window) { mCurrentInputWindowType = window->layoutParamsType; mCurrentInputChannel = window->inputChannel; mCurrentInputTargetsValid = true;