summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2024-07-15 21:13:57 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-07-15 21:13:57 +0000
commit8980323fce89c2dadb2281b711b89087dd79c3df (patch)
treed7dcb5d429397cee4ec617080bfb736a6dc1fc6a
parenta0ecaa1899be2a3785a3f92dd4e3e1ae1539a999 (diff)
parente1855a9eb790988d0d58ff44b3616477547a336b (diff)
Merge "Return Error-wrapped injection result in dispatcher" into main
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp130
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.h11
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);