Merge "Separate logic for publishing motion events"
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 51ad82d..694c127 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -541,6 +541,17 @@
entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y)));
}
+std::optional<nsecs_t> getDownTime(const EventEntry& eventEntry) {
+ if (eventEntry.type == EventEntry::Type::KEY) {
+ const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
+ return keyEntry.downTime;
+ } else if (eventEntry.type == EventEntry::Type::MOTION) {
+ const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
+ return motionEntry.downTime;
+ }
+ return std::nullopt;
+}
+
} // namespace
// --- InputDispatcher ---
@@ -1568,9 +1579,10 @@
}
// Identify targets.
- std::vector<InputTarget> inputTargets;
- InputEventInjectionResult injectionResult =
- findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
+ InputEventInjectionResult injectionResult;
+ sp<WindowInfoHandle> focusedWindow =
+ findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime,
+ /*byref*/ injectionResult);
if (injectionResult == InputEventInjectionResult::PENDING) {
return false;
}
@@ -1579,6 +1591,12 @@
if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
return true;
}
+ LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
+
+ std::vector<InputTarget> inputTargets;
+ addWindowTargetLocked(focusedWindow,
+ InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
+ BitSet32(0), getDownTime(*entry), inputTargets);
// Add monitor channels from event's or focused display.
addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
@@ -1673,13 +1691,27 @@
pilferPointersLocked(mDragState->dragWindow->getToken());
}
- injectionResult =
- findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
- &conflictingPointerActions);
+ std::vector<TouchedWindow> touchedWindows =
+ findTouchedWindowTargetsLocked(currentTime, *entry, nextWakeupTime,
+ &conflictingPointerActions,
+ /*byref*/ injectionResult);
+ for (const TouchedWindow& touchedWindow : touchedWindows) {
+ LOG_ALWAYS_FATAL_IF(injectionResult != InputEventInjectionResult::SUCCEEDED,
+ "Shouldn't be adding window if the injection didn't succeed.");
+ addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
+ touchedWindow.pointerIds, touchedWindow.firstDownTimeInTarget,
+ inputTargets);
+ }
} else {
// Non touch event. (eg. trackball)
- injectionResult =
- findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
+ sp<WindowInfoHandle> focusedWindow =
+ findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime, injectionResult);
+ if (injectionResult == InputEventInjectionResult::SUCCEEDED) {
+ LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
+ addWindowTargetLocked(focusedWindow,
+ InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
+ BitSet32(0), getDownTime(*entry), inputTargets);
+ }
}
if (injectionResult == InputEventInjectionResult::PENDING) {
return false;
@@ -1881,21 +1913,11 @@
return false;
}
-static std::optional<nsecs_t> getDownTime(const EventEntry& eventEntry) {
- if (eventEntry.type == EventEntry::Type::KEY) {
- const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
- return keyEntry.downTime;
- } else if (eventEntry.type == EventEntry::Type::MOTION) {
- const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
- return motionEntry.downTime;
- }
- return std::nullopt;
-}
-
-InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
- nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
- nsecs_t* nextWakeupTime) {
+sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked(
+ nsecs_t currentTime, const EventEntry& entry, nsecs_t* nextWakeupTime,
+ InputEventInjectionResult& outInjectionResult) {
std::string reason;
+ outInjectionResult = InputEventInjectionResult::FAILED; // Default result
int32_t displayId = getTargetDisplayId(entry);
sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
@@ -1908,12 +1930,12 @@
ALOGI("Dropping %s event because there is no focused window or focused application in "
"display %" PRId32 ".",
ftl::enum_string(entry.type).c_str(), displayId);
- return InputEventInjectionResult::FAILED;
+ return nullptr;
}
// Drop key events if requested by input feature
if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
- return InputEventInjectionResult::FAILED;
+ return nullptr;
}
// Compatibility behavior: raise ANR if there is a focused application, but no focused window.
@@ -1933,15 +1955,17 @@
"window when it finishes starting up. Will wait for %" PRId64 "ms",
mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
*nextWakeupTime = *mNoFocusedWindowTimeoutTime;
- return InputEventInjectionResult::PENDING;
+ outInjectionResult = InputEventInjectionResult::PENDING;
+ return nullptr;
} 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 InputEventInjectionResult::FAILED;
+ return nullptr;
} else {
// Still waiting for the focused window
- return InputEventInjectionResult::PENDING;
+ outInjectionResult = InputEventInjectionResult::PENDING;
+ return nullptr;
}
}
@@ -1951,13 +1975,15 @@
// Verify targeted injection.
if (const auto err = verifyTargetedInjection(focusedWindowHandle, entry); err) {
ALOGW("Dropping injected event: %s", (*err).c_str());
- return InputEventInjectionResult::TARGET_MISMATCH;
+ outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
+ return nullptr;
}
if (focusedWindowHandle->getInfo()->inputConfig.test(
WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
- return InputEventInjectionResult::PENDING;
+ outInjectionResult = InputEventInjectionResult::PENDING;
+ return nullptr;
}
// If the event is a key event, then we must wait for all previous events to
@@ -1974,17 +2000,13 @@
if (entry.type == EventEntry::Type::KEY) {
if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
*nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
- return InputEventInjectionResult::PENDING;
+ outInjectionResult = InputEventInjectionResult::PENDING;
+ return nullptr;
}
}
- // Success! Output targets.
- addWindowTargetLocked(focusedWindowHandle,
- InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
- BitSet32(0), getDownTime(entry), inputTargets);
-
- // Done.
- return InputEventInjectionResult::SUCCEEDED;
+ outInjectionResult = InputEventInjectionResult::SUCCEEDED;
+ return focusedWindowHandle;
}
/**
@@ -2013,11 +2035,12 @@
return responsiveMonitors;
}
-InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
- nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
- nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
+std::vector<TouchedWindow> InputDispatcher::findTouchedWindowTargetsLocked(
+ nsecs_t currentTime, const MotionEntry& entry, nsecs_t* nextWakeupTime,
+ bool* outConflictingPointerActions, InputEventInjectionResult& outInjectionResult) {
ATRACE_CALL();
+ std::vector<TouchedWindow> touchedWindows;
// For security reasons, we defer updating the touch state until we are sure that
// event injection will be allowed.
const int32_t displayId = entry.displayId;
@@ -2025,7 +2048,7 @@
const int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
// Update the touch state as needed based on the properties of the touch event.
- InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
+ outInjectionResult = InputEventInjectionResult::PENDING;
sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
sp<WindowInfoHandle> newTouchedWindowHandle;
@@ -2058,7 +2081,7 @@
"in display %" PRId32,
displayId);
// TODO: test multiple simultaneous input streams.
- injectionResult = InputEventInjectionResult::FAILED;
+ outInjectionResult = InputEventInjectionResult::FAILED;
switchedDevice = false;
wrongDevice = true;
goto Failed;
@@ -2074,7 +2097,7 @@
"in display %" PRId32,
displayId);
// TODO: test multiple simultaneous input streams.
- injectionResult = InputEventInjectionResult::FAILED;
+ outInjectionResult = InputEventInjectionResult::FAILED;
switchedDevice = false;
wrongDevice = true;
goto Failed;
@@ -2100,7 +2123,7 @@
// Verify targeted injection.
if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
ALOGW("Dropping injected touch event: %s", (*err).c_str());
- injectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
+ outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
newTouchedWindowHandle = nullptr;
goto Failed;
}
@@ -2141,7 +2164,7 @@
if (newTouchedWindows.empty()) {
ALOGI("Dropping event because there is no touchable window at (%d, %d) on display %d.",
x, y, displayId);
- injectionResult = InputEventInjectionResult::FAILED;
+ outInjectionResult = InputEventInjectionResult::FAILED;
goto Failed;
}
@@ -2193,7 +2216,7 @@
"dropped the pointer down event in display %" PRId32,
displayId);
}
- injectionResult = InputEventInjectionResult::FAILED;
+ outInjectionResult = InputEventInjectionResult::FAILED;
goto Failed;
}
@@ -2212,7 +2235,7 @@
// Verify targeted injection.
if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
ALOGW("Dropping injected event: %s", (*err).c_str());
- injectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
+ outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
newTouchedWindowHandle = nullptr;
goto Failed;
}
@@ -2303,7 +2326,7 @@
})) {
ALOGI("Dropping event because there is no touched window on display %d to receive it: %s",
displayId, entry.getDescription().c_str());
- injectionResult = InputEventInjectionResult::FAILED;
+ outInjectionResult = InputEventInjectionResult::FAILED;
goto Failed;
}
@@ -2323,7 +2346,7 @@
ALOGW("Dropping targeted injection: At least one touched window is not owned by uid "
"%d:%s",
*entry.injectionState->targetUid, errs.c_str());
- injectionResult = InputEventInjectionResult::TARGET_MISMATCH;
+ outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
goto Failed;
}
}
@@ -2380,13 +2403,8 @@
}
// Success! Output targets.
- injectionResult = InputEventInjectionResult::SUCCEEDED;
-
- for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
- addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
- touchedWindow.pointerIds, touchedWindow.firstDownTimeInTarget,
- inputTargets);
- }
+ touchedWindows = tempTouchState.windows;
+ outInjectionResult = InputEventInjectionResult::SUCCEEDED;
// Drop the outside or hover touch windows since we will not care about them
// in the next iteration.
@@ -2471,7 +2489,7 @@
mLastHoverWindowHandle = newHoverWindowHandle;
}
- return injectionResult;
+ return touchedWindows;
}
void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 14f12b2..dea2cae 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -542,12 +542,13 @@
void resetNoFocusedWindowTimeoutLocked() REQUIRES(mLock);
int32_t getTargetDisplayId(const EventEntry& entry);
- android::os::InputEventInjectionResult findFocusedWindowTargetsLocked(
- nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
- nsecs_t* nextWakeupTime) REQUIRES(mLock);
- android::os::InputEventInjectionResult findTouchedWindowTargetsLocked(
- nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
- nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) REQUIRES(mLock);
+ sp<android::gui::WindowInfoHandle> findFocusedWindowTargetLocked(
+ nsecs_t currentTime, const EventEntry& entry, nsecs_t* nextWakeupTime,
+ android::os::InputEventInjectionResult& outInjectionResult) REQUIRES(mLock);
+ std::vector<TouchedWindow> findTouchedWindowTargetsLocked(
+ nsecs_t currentTime, const MotionEntry& entry, nsecs_t* nextWakeupTime,
+ bool* outConflictingPointerActions,
+ android::os::InputEventInjectionResult& outInjectionResult) REQUIRES(mLock);
std::vector<Monitor> selectResponsiveMonitorsLocked(
const std::vector<Monitor>& gestureMonitors) const REQUIRES(mLock);