Skip to content

Commit 7438201

Browse files
prabirmspAndroid (Google) Code Review
authored andcommitted
Merge changes I2ab660ed,I308c12e2,I8c50a597,I14f77d61 into main
* changes: InputDispatcher_test: Verify all traced events match exactly InputDispatcher_test: Consume all moves to prevent events from batching InputDispatcher: Create new EventEntries for events with zero-ed coords InputDispatcher: Improve pointer transform mapping in InputTarget
2 parents 77add0b + 65a071a commit 7438201

8 files changed

Lines changed: 236 additions & 105 deletions

File tree

include/input/Input.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ static constexpr size_t MAX_POINTERS = 16;
180180
* Declare a concrete type for the NDK's input event forward declaration.
181181
*/
182182
struct AInputEvent {
183-
virtual ~AInputEvent() { }
183+
virtual ~AInputEvent() {}
184+
bool operator==(const AInputEvent&) const = default;
184185
};
185186

186187
/*
@@ -545,6 +546,8 @@ class InputEvent : public AInputEvent {
545546

546547
static int32_t nextId();
547548

549+
bool operator==(const InputEvent&) const = default;
550+
548551
protected:
549552
void initialize(int32_t id, DeviceId deviceId, uint32_t source, int32_t displayId,
550553
std::array<uint8_t, 32> hmac);
@@ -598,6 +601,8 @@ class KeyEvent : public InputEvent {
598601

599602
static const char* actionToString(int32_t action);
600603

604+
bool operator==(const KeyEvent&) const = default;
605+
601606
protected:
602607
int32_t mAction;
603608
int32_t mFlags;
@@ -917,6 +922,9 @@ class MotionEvent : public InputEvent {
917922
// The rounding precision for transformed motion events.
918923
static constexpr float ROUNDING_PRECISION = 0.001f;
919924

925+
bool operator==(const MotionEvent&) const;
926+
inline bool operator!=(const MotionEvent& o) const { return !(*this == o); };
927+
920928
protected:
921929
int32_t mAction;
922930
int32_t mActionButton;

libs/input/Input.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,33 @@ PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source,
10071007
return out;
10081008
}
10091009

1010+
bool MotionEvent::operator==(const android::MotionEvent& o) const {
1011+
// We use NaN values to represent invalid cursor positions. Since NaN values are not equal
1012+
// to themselves according to IEEE 754, we cannot use the default equality operator to compare
1013+
// MotionEvents. Therefore we define a custom equality operator with special handling for NaNs.
1014+
// clang-format off
1015+
return InputEvent::operator==(static_cast<const InputEvent&>(o)) &&
1016+
mAction == o.mAction &&
1017+
mActionButton == o.mActionButton &&
1018+
mFlags == o.mFlags &&
1019+
mEdgeFlags == o.mEdgeFlags &&
1020+
mMetaState == o.mMetaState &&
1021+
mButtonState == o.mButtonState &&
1022+
mClassification == o.mClassification &&
1023+
mTransform == o.mTransform &&
1024+
mXPrecision == o.mXPrecision &&
1025+
mYPrecision == o.mYPrecision &&
1026+
((std::isnan(mRawXCursorPosition) && std::isnan(o.mRawXCursorPosition)) ||
1027+
mRawXCursorPosition == o.mRawXCursorPosition) &&
1028+
((std::isnan(mRawYCursorPosition) && std::isnan(o.mRawYCursorPosition)) ||
1029+
mRawYCursorPosition == o.mRawYCursorPosition) &&
1030+
mRawTransform == o.mRawTransform && mDownTime == o.mDownTime &&
1031+
mPointerProperties == o.mPointerProperties &&
1032+
mSampleEventTimes == o.mSampleEventTimes &&
1033+
mSamplePointerCoords == o.mSamplePointerCoords;
1034+
// clang-format on
1035+
}
1036+
10101037
std::ostream& operator<<(std::ostream& out, const MotionEvent& event) {
10111038
out << "MotionEvent { action=" << MotionEvent::actionToString(event.getAction());
10121039
if (event.getActionButton() != 0) {

services/inputflinger/dispatcher/InputDispatcher.cpp

Lines changed: 49 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -365,17 +365,20 @@ size_t firstMarkedBit(T set) {
365365
return i;
366366
}
367367

368-
std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
368+
std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerator,
369+
const InputTarget& inputTarget,
369370
std::shared_ptr<const EventEntry> eventEntry,
370371
ftl::Flags<InputTarget::Flags> inputTargetFlags,
371372
int64_t vsyncId) {
373+
const bool zeroCoords = inputTargetFlags.test(InputTarget::Flags::ZERO_COORDS);
372374
const sp<WindowInfoHandle> win = inputTarget.windowHandle;
373375
const std::optional<int32_t> windowId =
374376
win ? std::make_optional(win->getInfo()->id) : std::nullopt;
375377
// Assume the only targets that are not associated with a window are global monitors, and use
376378
// the system UID for global monitors for tracing purposes.
377379
const gui::Uid uid = win ? win->getInfo()->ownerUid : gui::Uid(AID_SYSTEM);
378-
if (inputTarget.useDefaultPointerTransform()) {
380+
381+
if (inputTarget.useDefaultPointerTransform() && !zeroCoords) {
379382
const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
380383
return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
381384
inputTarget.displayTransform,
@@ -386,33 +389,39 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarge
386389
ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
387390
const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
388391

389-
std::vector<PointerCoords> pointerCoords;
390-
pointerCoords.resize(motionEntry.getPointerCount());
391-
392-
// Use the first pointer information to normalize all other pointers. This could be any pointer
393-
// as long as all other pointers are normalized to the same value and the final DispatchEntry
394-
// uses the transform for the normalized pointer.
395-
const ui::Transform& firstPointerTransform =
396-
inputTarget.pointerTransforms[firstMarkedBit(inputTarget.pointerIds)];
397-
ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
398-
399-
// Iterate through all pointers in the event to normalize against the first.
400-
for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount(); pointerIndex++) {
401-
const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
402-
uint32_t pointerId = uint32_t(pointerProperties.id);
403-
const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
392+
std::vector<PointerCoords> pointerCoords{motionEntry.getPointerCount()};
404393

405-
pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
406-
// First, apply the current pointer's transform to update the coordinates into
407-
// window space.
408-
pointerCoords[pointerIndex].transform(currTransform);
409-
// Next, apply the inverse transform of the normalized coordinates so the
410-
// current coordinates are transformed into the normalized coordinate space.
411-
pointerCoords[pointerIndex].transform(inverseFirstTransform);
394+
const ui::Transform* transform = &kIdentityTransform;
395+
const ui::Transform* displayTransform = &kIdentityTransform;
396+
if (zeroCoords) {
397+
std::for_each(pointerCoords.begin(), pointerCoords.end(), [](auto& pc) { pc.clear(); });
398+
} else {
399+
// Use the first pointer information to normalize all other pointers. This could be any
400+
// pointer as long as all other pointers are normalized to the same value and the final
401+
// DispatchEntry uses the transform for the normalized pointer.
402+
transform =
403+
&inputTarget.getTransformForPointer(firstMarkedBit(inputTarget.getPointerIds()));
404+
const ui::Transform inverseTransform = transform->inverse();
405+
displayTransform = &inputTarget.displayTransform;
406+
407+
// Iterate through all pointers in the event to normalize against the first.
408+
for (size_t i = 0; i < motionEntry.getPointerCount(); i++) {
409+
PointerCoords& newCoords = pointerCoords[i];
410+
const auto pointerId = motionEntry.pointerProperties[i].id;
411+
const ui::Transform& currTransform = inputTarget.getTransformForPointer(pointerId);
412+
413+
newCoords.copyFrom(motionEntry.pointerCoords[i]);
414+
// First, apply the current pointer's transform to update the coordinates into
415+
// window space.
416+
newCoords.transform(currTransform);
417+
// Next, apply the inverse transform of the normalized coordinates so the
418+
// current coordinates are transformed into the normalized coordinate space.
419+
newCoords.transform(inverseTransform);
420+
}
412421
}
413422

414423
std::unique_ptr<MotionEntry> combinedMotionEntry =
415-
std::make_unique<MotionEntry>(motionEntry.id, motionEntry.injectionState,
424+
std::make_unique<MotionEntry>(idGenerator.nextId(), motionEntry.injectionState,
416425
motionEntry.eventTime, motionEntry.deviceId,
417426
motionEntry.source, motionEntry.displayId,
418427
motionEntry.policyFlags, motionEntry.action,
@@ -426,7 +435,7 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarge
426435

427436
std::unique_ptr<DispatchEntry> dispatchEntry =
428437
std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
429-
firstPointerTransform, inputTarget.displayTransform,
438+
*transform, *displayTransform,
430439
inputTarget.globalScaleFactor, uid, vsyncId, windowId);
431440
return dispatchEntry;
432441
}
@@ -1630,14 +1639,12 @@ void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime,
16301639
if (connection == nullptr) {
16311640
return; // Connection has gone away
16321641
}
1633-
InputTarget target;
1634-
target.connection = connection;
16351642
entry->dispatchInProgress = true;
16361643
std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
16371644
connection->getInputChannelName();
16381645
std::string reason = std::string("reason=").append(entry->reason);
16391646
android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
1640-
dispatchEventLocked(currentTime, entry, {target});
1647+
dispatchEventLocked(currentTime, entry, {{connection}});
16411648
}
16421649

16431650
void InputDispatcher::dispatchPointerCaptureChangedLocked(
@@ -1703,10 +1710,8 @@ void InputDispatcher::dispatchPointerCaptureChangedLocked(
17031710
}
17041711
return;
17051712
}
1706-
InputTarget target;
1707-
target.connection = connection;
17081713
entry->dispatchInProgress = true;
1709-
dispatchEventLocked(currentTime, entry, {target});
1714+
dispatchEventLocked(currentTime, entry, {{connection}});
17101715

17111716
dropReason = DropReason::NOT_DROPPED;
17121717
}
@@ -1739,9 +1744,7 @@ std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked
17391744
if (connection == nullptr) {
17401745
continue; // Connection has gone away
17411746
}
1742-
InputTarget target;
1743-
target.connection = connection;
1744-
inputTargets.push_back(target);
1747+
inputTargets.emplace_back(connection);
17451748
}
17461749
return inputTargets;
17471750
}
@@ -2022,10 +2025,8 @@ void InputDispatcher::dispatchDragLocked(nsecs_t currentTime,
20222025
if (connection == nullptr) {
20232026
return; // Connection has gone away
20242027
}
2025-
InputTarget target;
2026-
target.connection = connection;
20272028
entry->dispatchInProgress = true;
2028-
dispatchEventLocked(currentTime, entry, {target});
2029+
dispatchEventLocked(currentTime, entry, {{connection}});
20292030
}
20302031

20312032
void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
@@ -2868,8 +2869,7 @@ std::optional<InputTarget> InputDispatcher::createInputTargetLocked(
28682869
ALOGW("Not creating InputTarget for %s, no input channel", windowHandle->getName().c_str());
28692870
return {};
28702871
}
2871-
InputTarget inputTarget;
2872-
inputTarget.connection = connection;
2872+
InputTarget inputTarget{connection};
28732873
inputTarget.windowHandle = windowHandle;
28742874
inputTarget.dispatchMode = dispatchMode;
28752875
inputTarget.flags = targetFlags;
@@ -2982,8 +2982,7 @@ void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>&
29822982
if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
29832983

29842984
for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
2985-
InputTarget target;
2986-
target.connection = monitor.connection;
2985+
InputTarget target{monitor.connection};
29872986
// target.firstDownTimeInTarget is not set for global monitors. It is only required in split
29882987
// touch and global monitoring works as intended even without setting firstDownTimeInTarget
29892988
if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
@@ -3275,7 +3274,7 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
32753274
ALOGD("channel '%s' ~ prepareDispatchCycle - flags=%s, "
32763275
"globalScaleFactor=%f, pointerIds=%s %s",
32773276
connection->getInputChannelName().c_str(), inputTarget.flags.string().c_str(),
3278-
inputTarget.globalScaleFactor, bitsetToString(inputTarget.pointerIds).c_str(),
3277+
inputTarget.globalScaleFactor, bitsetToString(inputTarget.getPointerIds()).c_str(),
32793278
inputTarget.getPointerInfoString().c_str());
32803279
}
32813280

@@ -3297,7 +3296,7 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
32973296
ftl::enum_string(eventEntry->type).c_str());
32983297

32993298
const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
3300-
if (inputTarget.pointerIds.count() != originalMotionEntry.getPointerCount()) {
3299+
if (inputTarget.getPointerIds().count() != originalMotionEntry.getPointerCount()) {
33013300
if (!inputTarget.firstDownTimeInTarget.has_value()) {
33023301
logDispatchStateLocked();
33033302
LOG(FATAL) << "Splitting motion events requires a down time to be set for the "
@@ -3306,7 +3305,7 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
33063305
<< originalMotionEntry.getDescription();
33073306
}
33083307
std::unique_ptr<MotionEntry> splitMotionEntry =
3309-
splitMotionEvent(originalMotionEntry, inputTarget.pointerIds,
3308+
splitMotionEvent(originalMotionEntry, inputTarget.getPointerIds(),
33103309
inputTarget.firstDownTimeInTarget.value());
33113310
if (!splitMotionEntry) {
33123311
return; // split event was dropped
@@ -3364,7 +3363,8 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio
33643363
// This is a new event.
33653364
// Enqueue a new dispatch entry onto the outbound queue for this connection.
33663365
std::unique_ptr<DispatchEntry> dispatchEntry =
3367-
createDispatchEntry(inputTarget, eventEntry, inputTarget.flags, mWindowInfosVsyncId);
3366+
createDispatchEntry(mIdGenerator, inputTarget, eventEntry, inputTarget.flags,
3367+
mWindowInfosVsyncId);
33683368

33693369
// Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
33703370
// different EventEntry than what was passed in.
@@ -3485,7 +3485,7 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio
34853485
<< connection->getInputChannelName() << " with event "
34863486
<< cancelEvent->getDescription();
34873487
std::unique_ptr<DispatchEntry> cancelDispatchEntry =
3488-
createDispatchEntry(inputTarget, std::move(cancelEvent),
3488+
createDispatchEntry(mIdGenerator, inputTarget, std::move(cancelEvent),
34893489
ftl::Flags<InputTarget::Flags>(), mWindowInfosVsyncId);
34903490

34913491
// Send these cancel events to the queue before sending the event from the new
@@ -3664,12 +3664,6 @@ status_t InputDispatcher::publishMotionEvent(Connection& connection,
36643664
}
36653665
usingCoords = scaledCoords;
36663666
}
3667-
} else if (dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS)) {
3668-
// We don't want the dispatch target to know the coordinates
3669-
for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
3670-
scaledCoords[i].clear();
3671-
}
3672-
usingCoords = scaledCoords;
36733667
}
36743668

36753669
std::array<uint8_t, 32> hmac = getSignature(motionEntry, dispatchEntry);
@@ -4109,7 +4103,7 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
41094103

41104104
const bool wasEmpty = connection->outboundQueue.empty();
41114105
// The target to use if we don't find a window associated with the channel.
4112-
const InputTarget fallbackTarget{.connection = connection};
4106+
const InputTarget fallbackTarget{connection};
41134107
const auto& token = connection->getToken();
41144108

41154109
for (size_t i = 0; i < cancelationEvents.size(); i++) {
@@ -4227,8 +4221,7 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
42274221
targetFlags, pointerIds, motionEntry.downTime,
42284222
targets);
42294223
} else {
4230-
targets.emplace_back(
4231-
InputTarget{.connection = connection, .flags = targetFlags});
4224+
targets.emplace_back(connection, targetFlags);
42324225
const auto it = mDisplayInfos.find(motionEntry.displayId);
42334226
if (it != mDisplayInfos.end()) {
42344227
targets.back().displayTransform = it->second.transform;

0 commit comments

Comments
 (0)