diff options
| author | 2024-07-15 21:13:57 +0000 | |
|---|---|---|
| committer | 2024-07-15 21:13:57 +0000 | |
| commit | 8980323fce89c2dadb2281b711b89087dd79c3df (patch) | |
| tree | d7dcb5d429397cee4ec617080bfb736a6dc1fc6a | |
| parent | a0ecaa1899be2a3785a3f92dd4e3e1ae1539a999 (diff) | |
| parent | e1855a9eb790988d0d58ff44b3616477547a336b (diff) | |
Merge "Return Error-wrapped injection result in dispatcher" into main
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 130 | ||||
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.h | 11 |
2 files changed, 72 insertions, 69 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 7edbda08d2..5ed4e691f2 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -901,6 +901,24 @@ private: const nsecs_t mProcessingTimestamp; }; +/** + * This is needed to help use "InputEventInjectionResult" with base::Result. + */ +template <typename T> +struct EnumErrorWrapper { + T mVal; + EnumErrorWrapper(T&& e) : mVal(std::forward<T>(e)) {} + operator const T&() const { return mVal; } + T value() const { return mVal; } + std::string print() const { return ftl::enum_string(mVal); } +}; + +Error<EnumErrorWrapper<InputEventInjectionResult>> injectionError(InputEventInjectionResult&& e) { + LOG_ALWAYS_FATAL_IF(e == InputEventInjectionResult::SUCCEEDED); + return Error<EnumErrorWrapper<InputEventInjectionResult>>( + std::forward<InputEventInjectionResult>(e)); +} + } // namespace // --- InputDispatcher --- @@ -1929,20 +1947,21 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<con } // Identify targets. - InputEventInjectionResult injectionResult; - sp<WindowInfoHandle> focusedWindow = - findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime, - /*byref*/ injectionResult); - if (injectionResult == InputEventInjectionResult::PENDING) { - return false; - } + Result<sp<WindowInfoHandle>, InputEventInjectionResult> result = + findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime); - setInjectionResult(*entry, injectionResult); - if (injectionResult != InputEventInjectionResult::SUCCEEDED) { + if (!result.ok()) { + if (result.error().code() == InputEventInjectionResult::PENDING) { + return false; + } + setInjectionResult(*entry, result.error().code()); return true; } + sp<WindowInfoHandle>& focusedWindow = *result; LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr); + setInjectionResult(*entry, InputEventInjectionResult::SUCCEEDED); + std::vector<InputTarget> inputTargets; addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS, InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets); @@ -2047,19 +2066,28 @@ bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, pilferPointersLocked(mDragState->dragWindow->getToken()); } - inputTargets = - findTouchedWindowTargetsLocked(currentTime, *entry, /*byref*/ injectionResult); - LOG_ALWAYS_FATAL_IF(injectionResult != InputEventInjectionResult::SUCCEEDED && - !inputTargets.empty()); + Result<std::vector<InputTarget>, InputEventInjectionResult> result = + findTouchedWindowTargetsLocked(currentTime, *entry); + + if (result.ok()) { + inputTargets = std::move(*result); + injectionResult = InputEventInjectionResult::SUCCEEDED; + } else { + injectionResult = result.error().code(); + } } else { // Non touch event. (eg. trackball) - sp<WindowInfoHandle> focusedWindow = - findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime, injectionResult); - if (injectionResult == InputEventInjectionResult::SUCCEEDED) { + Result<sp<WindowInfoHandle>, InputEventInjectionResult> result = + findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime); + if (result.ok()) { + sp<WindowInfoHandle>& focusedWindow = *result; LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr); addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS, InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets); + injectionResult = InputEventInjectionResult::SUCCEEDED; + } else { + injectionResult = result.error().code(); } } if (injectionResult == InputEventInjectionResult::PENDING) { @@ -2266,11 +2294,9 @@ bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime, return false; } -sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked( - nsecs_t currentTime, const EventEntry& entry, nsecs_t& nextWakeupTime, - InputEventInjectionResult& outInjectionResult) { - outInjectionResult = InputEventInjectionResult::FAILED; // Default result - +Result<sp<WindowInfoHandle>, InputEventInjectionResult> +InputDispatcher::findFocusedWindowTargetLocked(nsecs_t currentTime, const EventEntry& entry, + nsecs_t& nextWakeupTime) { ui::LogicalDisplayId displayId = getTargetDisplayId(entry); sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId); std::shared_ptr<InputApplicationHandle> focusedApplicationHandle = @@ -2282,12 +2308,12 @@ sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked( ALOGI("Dropping %s event because there is no focused window or focused application in " "display %s.", ftl::enum_string(entry.type).c_str(), displayId.toString().c_str()); - return nullptr; + return injectionError(InputEventInjectionResult::FAILED); } // Drop key events if requested by input feature if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) { - return nullptr; + return injectionError(InputEventInjectionResult::FAILED); } // Compatibility behavior: raise ANR if there is a focused application, but no focused window. @@ -2307,17 +2333,15 @@ sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked( "window when it finishes starting up. Will wait for %" PRId64 "ms", mAwaitedFocusedApplication->getName().c_str(), millis(timeout)); nextWakeupTime = std::min(nextWakeupTime, *mNoFocusedWindowTimeoutTime); - outInjectionResult = InputEventInjectionResult::PENDING; - return nullptr; + return injectionError(InputEventInjectionResult::PENDING); } else if (currentTime > *mNoFocusedWindowTimeoutTime) { // Already raised ANR. Drop the event ALOGE("Dropping %s event because there is no focused window", ftl::enum_string(entry.type).c_str()); - return nullptr; + return injectionError(InputEventInjectionResult::FAILED); } else { // Still waiting for the focused window - outInjectionResult = InputEventInjectionResult::PENDING; - return nullptr; + return injectionError(InputEventInjectionResult::PENDING); } } @@ -2327,15 +2351,13 @@ sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked( // Verify targeted injection. if (const auto err = verifyTargetedInjection(focusedWindowHandle, entry); err) { ALOGW("Dropping injected event: %s", (*err).c_str()); - outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH; - return nullptr; + return injectionError(InputEventInjectionResult::TARGET_MISMATCH); } if (focusedWindowHandle->getInfo()->inputConfig.test( WindowInfo::InputConfig::PAUSE_DISPATCHING)) { ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str()); - outInjectionResult = InputEventInjectionResult::PENDING; - return nullptr; + return injectionError(InputEventInjectionResult::PENDING); } // If the event is a key event, then we must wait for all previous events to @@ -2352,12 +2374,10 @@ sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked( if (entry.type == EventEntry::Type::KEY) { if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) { nextWakeupTime = std::min(nextWakeupTime, *mKeyIsWaitingForEventsTimeout); - outInjectionResult = InputEventInjectionResult::PENDING; - return nullptr; + return injectionError(InputEventInjectionResult::PENDING); } } - - outInjectionResult = InputEventInjectionResult::SUCCEEDED; + // Success! return focusedWindowHandle; } @@ -2381,9 +2401,8 @@ std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked( return responsiveMonitors; } -std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( - nsecs_t currentTime, const MotionEntry& entry, - InputEventInjectionResult& outInjectionResult) { +base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult> +InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) { ATRACE_CALL(); std::vector<InputTarget> targets; @@ -2393,9 +2412,6 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( const int32_t action = entry.action; const int32_t maskedAction = MotionEvent::getActionMasked(action); - // Update the touch state as needed based on the properties of the touch event. - outInjectionResult = InputEventInjectionResult::PENDING; - // Copy current touch state into tempTouchState. // This state will be used to update mTouchStatesByDisplay at the end of this function. // If no state for the specified display exists, then our initial state will be empty. @@ -2435,8 +2451,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // Started hovering, but the device is already down: reject the hover event LOG(ERROR) << "Got hover event " << entry.getDescription() << " but the device is already down " << oldState->dump(); - outInjectionResult = InputEventInjectionResult::FAILED; - return {}; + return injectionError(InputEventInjectionResult::FAILED); } // For hover actions, we will treat 'tempTouchState' as a new state, so let's erase // all of the existing hovering pointers and recompute. @@ -2468,9 +2483,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // Verify targeted injection. if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) { ALOGW("Dropping injected touch event: %s", (*err).c_str()); - outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH; - newTouchedWindowHandle = nullptr; - return {}; + return injectionError(InputEventInjectionResult::TARGET_MISMATCH); } // Figure out whether splitting will be allowed for this window. @@ -2502,8 +2515,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( if (newTouchedWindows.empty()) { LOG(INFO) << "Dropping event because there is no touchable window at (" << x << ", " << y << ") on display " << displayId << ": " << entry; - outInjectionResult = InputEventInjectionResult::FAILED; - return {}; + return injectionError(InputEventInjectionResult::FAILED); } for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) { @@ -2603,8 +2615,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( << " is not down or we previously dropped the pointer down event in " << "display " << displayId << ": " << entry.getDescription(); } - outInjectionResult = InputEventInjectionResult::FAILED; - return {}; + return injectionError(InputEventInjectionResult::FAILED); } // If the pointer is not currently hovering, then ignore the event. @@ -2615,8 +2626,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( LOG(INFO) << "Dropping event because the hovering pointer is not in any windows in " "display " << displayId << ": " << entry.getDescription(); - outInjectionResult = InputEventInjectionResult::FAILED; - return {}; + return injectionError(InputEventInjectionResult::FAILED); } tempTouchState.removeHoveringPointer(entry.deviceId, pointerId); } @@ -2637,8 +2647,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // Verify targeted injection. if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) { ALOGW("Dropping injected event: %s", (*err).c_str()); - outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH; - return {}; + return injectionError(InputEventInjectionResult::TARGET_MISMATCH); } // Do not slide events to the window which can not receive motion event @@ -2741,8 +2750,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( ALOGW("Dropping targeted injection: At least one touched window is not owned by uid " "%s:%s", entry.injectionState->targetUid->toString().c_str(), errs.c_str()); - outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH; - return {}; + return injectionError(InputEventInjectionResult::TARGET_MISMATCH); } } @@ -2799,8 +2807,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( if (targets.empty()) { LOG(INFO) << "Dropping event because no targets were found: " << entry.getDescription(); - outInjectionResult = InputEventInjectionResult::FAILED; - return {}; + return injectionError(InputEventInjectionResult::FAILED); } // If we only have windows getting ACTION_OUTSIDE, then drop the event, because there is no @@ -2810,12 +2817,9 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( })) { LOG(INFO) << "Dropping event because all windows would just receive ACTION_OUTSIDE: " << entry.getDescription(); - outInjectionResult = InputEventInjectionResult::FAILED; - return {}; + return injectionError(InputEventInjectionResult::FAILED); } - outInjectionResult = InputEventInjectionResult::SUCCEEDED; - // Now that we have generated all of the input targets for this event, reset the dispatch // mode for all touched window to AS_IS. for (TouchedWindow& touchedWindow : tempTouchState.windows) { diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index 212522661c..3c2f3e9f67 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -537,12 +537,11 @@ private: void resetNoFocusedWindowTimeoutLocked() REQUIRES(mLock); ui::LogicalDisplayId getTargetDisplayId(const EventEntry& entry); - sp<android::gui::WindowInfoHandle> findFocusedWindowTargetLocked( - nsecs_t currentTime, const EventEntry& entry, nsecs_t& nextWakeupTime, - android::os::InputEventInjectionResult& outInjectionResult) REQUIRES(mLock); - std::vector<InputTarget> findTouchedWindowTargetsLocked( - nsecs_t currentTime, const MotionEntry& entry, - android::os::InputEventInjectionResult& outInjectionResult) REQUIRES(mLock); + base::Result<sp<android::gui::WindowInfoHandle>, android::os::InputEventInjectionResult> + findFocusedWindowTargetLocked(nsecs_t currentTime, const EventEntry& entry, + nsecs_t& nextWakeupTime) REQUIRES(mLock); + base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult> + findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) REQUIRES(mLock); std::vector<Monitor> selectResponsiveMonitorsLocked( const std::vector<Monitor>& gestureMonitors) const REQUIRES(mLock); |