Loading services/inputflinger/dispatcher/InputDispatcher.cpp +88 −124 Original line number Diff line number Diff line Loading @@ -1152,14 +1152,16 @@ bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* ent } setInjectionResult(entry, injectionResult); if (injectionResult == INPUT_EVENT_INJECTION_PERMISSION_DENIED) { ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent)); return true; } if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) { if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) { CancelationOptions::Mode mode(isPointerEvent ? CancelationOptions::CANCEL_POINTER_EVENTS : CancelationOptions::CANCEL_NON_POINTER_EVENTS); CancelationOptions options(mode, "input event injection failed"); synthesizeCancelationEventsForMonitorsLocked(options); } return true; } Loading Loading @@ -1345,13 +1347,6 @@ void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked( } } nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) { if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) { return currentTime - mInputTargetWaitStartTime; } return 0; } void InputDispatcher::resetAnrTimeoutsLocked() { if (DEBUG_FOCUS) { ALOGD("Resetting ANR timeouts."); Loading Loading @@ -1394,7 +1389,6 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) { int32_t injectionResult; std::string reason; int32_t displayId = getTargetDisplayId(entry); Loading @@ -1407,54 +1401,38 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime, // then drop the event. if (focusedWindowHandle == nullptr) { if (focusedApplicationHandle != nullptr) { injectionResult = handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle, return handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle, nullptr, nextWakeupTime, "Waiting because no window has focus but there is " "a focused application that may eventually add a " "window when it finishes starting up."); goto Unresponsive; } ALOGI("Dropping event because there is no focused window or focused application in display " "%" PRId32 ".", displayId); injectionResult = INPUT_EVENT_INJECTION_FAILED; goto Failed; return INPUT_EVENT_INJECTION_FAILED; } // Check permissions. if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) { injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED; goto Failed; return INPUT_EVENT_INJECTION_PERMISSION_DENIED; } // Check whether the window is ready for more input. reason = checkWindowReadyForMoreInputLocked(currentTime, focusedWindowHandle, entry, "focused"); if (!reason.empty()) { injectionResult = handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle, return handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle, focusedWindowHandle, nextWakeupTime, reason.c_str()); goto Unresponsive; } // Success! Output targets. injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED; addWindowTargetLocked(focusedWindowHandle, InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0), inputTargets); // Done. Failed: Unresponsive: nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime); updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication); if (DEBUG_FOCUS) { ALOGD("findFocusedWindow finished: injectionResult=%d, " "timeSpentWaitingForApplication=%0.1fms", injectionResult, timeSpentWaitingForApplication / 1000000.0); } return injectionResult; return INPUT_EVENT_INJECTION_SUCCEEDED; } int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, Loading Loading @@ -1751,10 +1729,9 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, checkWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle, entry, "touched"); if (!reason.empty()) { injectionResult = handleTargetsNotReadyLocked(currentTime, entry, nullptr, touchedWindow.windowHandle, nextWakeupTime, reason.c_str()); goto Unresponsive; return handleTargetsNotReadyLocked(currentTime, entry, nullptr, touchedWindow.windowHandle, nextWakeupTime, reason.c_str()); } } } Loading Loading @@ -1814,8 +1791,11 @@ Failed: } } if (injectionPermission != INJECTION_PERMISSION_GRANTED) { return injectionResult; } // Update final pieces of touch state if the injector had permission. if (injectionPermission == INJECTION_PERMISSION_GRANTED) { if (!wrongDevice) { if (switchedDevice) { if (DEBUG_FOCUS) { Loading Loading @@ -1889,23 +1869,7 @@ Failed: // Update hover state. mLastHoverWindowHandle = newHoverWindowHandle; } } else { if (DEBUG_FOCUS) { ALOGD("Not updating touch focus because injection was denied."); } } Unresponsive: // Reset temporary touch state to ensure we release unnecessary references to input channels. mTempTouchState.reset(); nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime); updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication); if (DEBUG_FOCUS) { ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, " "timeSpentWaitingForApplication=%0.1fms", injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0); } return injectionResult; } Loading Loading @@ -4664,6 +4628,7 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* c dispatchEntry->eventEntry->appendDescription(msg); ALOGI("%s", msg.c_str()); } reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled); bool restartEvent; if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) { Loading Loading @@ -4898,9 +4863,8 @@ KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) { return event; } void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry& entry, int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) { void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration, const Connection& connection, bool handled) { // TODO Write some statistics about how long we spend waiting. } Loading services/inputflinger/dispatcher/InputDispatcher.h +2 −2 Original line number Diff line number Diff line Loading @@ -497,8 +497,8 @@ private: LatencyStatistics mTouchStatistics{TOUCH_STATS_REPORT_PERIOD}; void reportTouchEventForStatistics(const MotionEntry& entry); void updateDispatchStatistics(nsecs_t currentTime, const EventEntry& entry, int32_t injectionResult, nsecs_t timeSpentWaitingForApplication); void reportDispatchStatistics(std::chrono::nanoseconds eventDuration, const Connection& connection, bool handled); void traceInboundQueueLengthLocked() REQUIRES(mLock); void traceOutboundQueueLength(const sp<Connection>& connection); void traceWaitQueueLength(const sp<Connection>& connection); Loading Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +88 −124 Original line number Diff line number Diff line Loading @@ -1152,14 +1152,16 @@ bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* ent } setInjectionResult(entry, injectionResult); if (injectionResult == INPUT_EVENT_INJECTION_PERMISSION_DENIED) { ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent)); return true; } if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) { if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED) { CancelationOptions::Mode mode(isPointerEvent ? CancelationOptions::CANCEL_POINTER_EVENTS : CancelationOptions::CANCEL_NON_POINTER_EVENTS); CancelationOptions options(mode, "input event injection failed"); synthesizeCancelationEventsForMonitorsLocked(options); } return true; } Loading Loading @@ -1345,13 +1347,6 @@ void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked( } } nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) { if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) { return currentTime - mInputTargetWaitStartTime; } return 0; } void InputDispatcher::resetAnrTimeoutsLocked() { if (DEBUG_FOCUS) { ALOGD("Resetting ANR timeouts."); Loading Loading @@ -1394,7 +1389,6 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) { int32_t injectionResult; std::string reason; int32_t displayId = getTargetDisplayId(entry); Loading @@ -1407,54 +1401,38 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime, // then drop the event. if (focusedWindowHandle == nullptr) { if (focusedApplicationHandle != nullptr) { injectionResult = handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle, return handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle, nullptr, nextWakeupTime, "Waiting because no window has focus but there is " "a focused application that may eventually add a " "window when it finishes starting up."); goto Unresponsive; } ALOGI("Dropping event because there is no focused window or focused application in display " "%" PRId32 ".", displayId); injectionResult = INPUT_EVENT_INJECTION_FAILED; goto Failed; return INPUT_EVENT_INJECTION_FAILED; } // Check permissions. if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) { injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED; goto Failed; return INPUT_EVENT_INJECTION_PERMISSION_DENIED; } // Check whether the window is ready for more input. reason = checkWindowReadyForMoreInputLocked(currentTime, focusedWindowHandle, entry, "focused"); if (!reason.empty()) { injectionResult = handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle, return handleTargetsNotReadyLocked(currentTime, entry, focusedApplicationHandle, focusedWindowHandle, nextWakeupTime, reason.c_str()); goto Unresponsive; } // Success! Output targets. injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED; addWindowTargetLocked(focusedWindowHandle, InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0), inputTargets); // Done. Failed: Unresponsive: nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime); updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication); if (DEBUG_FOCUS) { ALOGD("findFocusedWindow finished: injectionResult=%d, " "timeSpentWaitingForApplication=%0.1fms", injectionResult, timeSpentWaitingForApplication / 1000000.0); } return injectionResult; return INPUT_EVENT_INJECTION_SUCCEEDED; } int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, Loading Loading @@ -1751,10 +1729,9 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, checkWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle, entry, "touched"); if (!reason.empty()) { injectionResult = handleTargetsNotReadyLocked(currentTime, entry, nullptr, touchedWindow.windowHandle, nextWakeupTime, reason.c_str()); goto Unresponsive; return handleTargetsNotReadyLocked(currentTime, entry, nullptr, touchedWindow.windowHandle, nextWakeupTime, reason.c_str()); } } } Loading Loading @@ -1814,8 +1791,11 @@ Failed: } } if (injectionPermission != INJECTION_PERMISSION_GRANTED) { return injectionResult; } // Update final pieces of touch state if the injector had permission. if (injectionPermission == INJECTION_PERMISSION_GRANTED) { if (!wrongDevice) { if (switchedDevice) { if (DEBUG_FOCUS) { Loading Loading @@ -1889,23 +1869,7 @@ Failed: // Update hover state. mLastHoverWindowHandle = newHoverWindowHandle; } } else { if (DEBUG_FOCUS) { ALOGD("Not updating touch focus because injection was denied."); } } Unresponsive: // Reset temporary touch state to ensure we release unnecessary references to input channels. mTempTouchState.reset(); nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime); updateDispatchStatistics(currentTime, entry, injectionResult, timeSpentWaitingForApplication); if (DEBUG_FOCUS) { ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, " "timeSpentWaitingForApplication=%0.1fms", injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0); } return injectionResult; } Loading Loading @@ -4664,6 +4628,7 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* c dispatchEntry->eventEntry->appendDescription(msg); ALOGI("%s", msg.c_str()); } reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled); bool restartEvent; if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) { Loading Loading @@ -4898,9 +4863,8 @@ KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) { return event; } void InputDispatcher::updateDispatchStatistics(nsecs_t currentTime, const EventEntry& entry, int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) { void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration, const Connection& connection, bool handled) { // TODO Write some statistics about how long we spend waiting. } Loading
services/inputflinger/dispatcher/InputDispatcher.h +2 −2 Original line number Diff line number Diff line Loading @@ -497,8 +497,8 @@ private: LatencyStatistics mTouchStatistics{TOUCH_STATS_REPORT_PERIOD}; void reportTouchEventForStatistics(const MotionEntry& entry); void updateDispatchStatistics(nsecs_t currentTime, const EventEntry& entry, int32_t injectionResult, nsecs_t timeSpentWaitingForApplication); void reportDispatchStatistics(std::chrono::nanoseconds eventDuration, const Connection& connection, bool handled); void traceInboundQueueLengthLocked() REQUIRES(mLock); void traceOutboundQueueLength(const sp<Connection>& connection); void traceWaitQueueLength(const sp<Connection>& connection); Loading