Change isStylusEvent behaviour
This function is now getting moved to Input.h.
We are also making its behaviour deterministic: if at least one pointer
is stylus, then the event is a stylus event (unless the source wasn't
set to "stylus").
This way, an event with 1 finger and 1 stylus pointers will have the
same consistent behaviour, regardless of the order that the pointers are
stored inside the event.
Bug: 211379801
Test: TEST=inputflinger_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST
Change-Id: Ie164e32b7c0e9cf21b3819b01a03ac2885666191
diff --git a/include/input/Input.h b/include/input/Input.h
index 567361d..bd544b5 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -257,6 +257,10 @@
bool isStylusToolType(ToolType toolType);
+struct PointerProperties;
+
+bool isStylusEvent(uint32_t source, const std::vector<PointerProperties>& properties);
+
/*
* Flags that flow alongside events in the input dispatch system to help with certain
* policy decisions such as waking from device sleep.
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index c127411..bd5b67b 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -217,6 +217,19 @@
return toolType == ToolType::STYLUS || toolType == ToolType::ERASER;
}
+bool isStylusEvent(uint32_t source, const std::vector<PointerProperties>& properties) {
+ if (!isFromSource(source, AINPUT_SOURCE_STYLUS)) {
+ return false;
+ }
+ // Need at least one stylus pointer for this event to be considered a stylus event
+ for (const PointerProperties& pointerProperties : properties) {
+ if (isStylusToolType(pointerProperties.toolType)) {
+ return true;
+ }
+ }
+ return false;
+}
+
VerifiedKeyEvent verifiedKeyEventFromKeyEvent(const KeyEvent& event) {
return {{VerifiedInputEvent::Type::KEY, event.getDeviceId(), event.getEventTime(),
event.getSource(), event.getDisplayId()},
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 90bd7c9..3c26d1d 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -3782,34 +3782,26 @@
return out;
}
-static bool isStylusEvent(uint32_t source, int32_t action, const PointerProperties* properties) {
- if (!isFromSource(source, AINPUT_SOURCE_STYLUS)) {
- return false;
- }
- const auto actionIndex = action >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
- return isStylusToolType(properties[actionIndex].toolType);
-}
-
NotifyMotionArgs TouchInputMapper::dispatchMotion(
nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action,
int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState,
int32_t edgeFlags, const PropertiesArray& properties, const CoordsArray& coords,
const IdToIndexArray& idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision,
float yPrecision, nsecs_t downTime, MotionClassification classification) {
- PointerCoords pointerCoords[MAX_POINTERS];
- PointerProperties pointerProperties[MAX_POINTERS];
+ std::vector<PointerCoords> pointerCoords;
+ std::vector<PointerProperties> pointerProperties;
uint32_t pointerCount = 0;
while (!idBits.isEmpty()) {
uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = idToIndex[id];
- pointerProperties[pointerCount] = properties[index];
- pointerCoords[pointerCount] = coords[index];
+ pointerProperties.push_back(properties[index]);
+ pointerCoords.push_back(coords[index]);
if (changedId >= 0 && id == uint32_t(changedId)) {
action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
}
- pointerCount += 1;
+ pointerCount++;
}
ALOG_ASSERT(pointerCount != 0);
@@ -3837,7 +3829,7 @@
const int32_t displayId = getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE);
const bool showDirectStylusPointer = mConfig.stylusPointerIconEnabled &&
- mDeviceMode == DeviceMode::DIRECT && isStylusEvent(source, action, pointerProperties) &&
+ mDeviceMode == DeviceMode::DIRECT && isStylusEvent(source, pointerProperties) &&
mPointerController && displayId != ADISPLAY_ID_NONE &&
displayId == mPointerController->getDisplayId();
if (showDirectStylusPointer) {
@@ -3869,9 +3861,9 @@
[this](TouchVideoFrame& frame) { frame.rotate(this->mInputDeviceOrientation); });
return NotifyMotionArgs(getContext()->getNextId(), when, readTime, deviceId, source, displayId,
policyFlags, action, actionButton, flags, metaState, buttonState,
- classification, edgeFlags, pointerCount, pointerProperties,
- pointerCoords, xPrecision, yPrecision, xCursorPosition, yCursorPosition,
- downTime, std::move(frames));
+ classification, edgeFlags, pointerCount, pointerProperties.data(),
+ pointerCoords.data(), xPrecision, yPrecision, xCursorPosition,
+ yCursorPosition, downTime, std::move(frames));
}
std::list<NotifyArgs> TouchInputMapper::cancelTouch(nsecs_t when, nsecs_t readTime) {