InputDispatcher: Use correct coordinate space when synthesizing down
Input targets for synthesized down events were not created using the
same pipeline as normal dispatching. Due to this, things like window and
display transforms were not being applied to the events. This means the
ACTION_DOWN event did not have the correct coordinates in many cases.
Here, we fix that by attempting to use the same pipeline as normal
dispatching for creating the input target. When it's not possible to do
due to there being no window (e.g. for global monitors), we fall back to
creating the target ourselves.
Bug: 287908447
Test: atest inputflinger_tests
Change-Id: I6987619c91e458249aa7c7be884566e4b21363c4
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 7fbd322..be57932 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -4041,23 +4041,33 @@
connection->getInputChannelName().c_str(), downEvents.size());
}
- InputTarget target;
sp<WindowInfoHandle> windowHandle =
getWindowHandleLocked(connection->inputChannel->getConnectionToken());
- if (windowHandle != nullptr) {
- const WindowInfo* windowInfo = windowHandle->getInfo();
- target.setDefaultPointerTransform(windowInfo->transform);
- target.globalScaleFactor = windowInfo->globalScaleFactor;
- }
- target.inputChannel = connection->inputChannel;
- target.flags = targetFlags;
const bool wasEmpty = connection->outboundQueue.empty();
for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
+ std::vector<InputTarget> targets{};
switch (downEventEntry->type) {
case EventEntry::Type::MOTION: {
- logOutboundMotionDetails("down - ",
- static_cast<const MotionEntry&>(*downEventEntry));
+ const auto& motionEntry = static_cast<const MotionEntry&>(*downEventEntry);
+ if (windowHandle != nullptr) {
+ std::bitset<MAX_POINTER_ID + 1> pointerIds;
+ for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount;
+ pointerIndex++) {
+ pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
+ }
+ addWindowTargetLocked(windowHandle, targetFlags, pointerIds,
+ motionEntry.downTime, targets);
+ } else {
+ targets.emplace_back(InputTarget{.inputChannel = connection->inputChannel,
+ .flags = targetFlags});
+ const auto it = mDisplayInfos.find(motionEntry.displayId);
+ if (it != mDisplayInfos.end()) {
+ targets.back().displayTransform = it->second.transform;
+ targets.back().setDefaultPointerTransform(it->second.transform);
+ }
+ }
+ logOutboundMotionDetails("down - ", motionEntry);
break;
}
@@ -4075,7 +4085,8 @@
}
}
- enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
+ if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
+ enqueueDispatchEntryLocked(connection, std::move(downEventEntry), targets[0],
InputTarget::Flags::DISPATCH_AS_IS);
}