diff options
| author | 2022-08-09 19:18:37 +0000 | |
|---|---|---|
| committer | 2022-08-13 01:35:02 +0000 | |
| commit | 6573583a3b304dce8ff334df8d48d01b58ab2c84 (patch) | |
| tree | b1cac2ea0506244effdb725a6e04e0b073ae0aa4 /services/inputflinger/UnwantedInteractionBlocker.cpp | |
| parent | e491fb5ae1c602bc09271b8fa3456ee9af8a5a64 (diff) | |
Allow stylus events in PalmRejector
After some recent changes, the touchscreen input device has source that
is a combination of SOURCE_TOUCHSCREEN and SOURCE_STYLUS.
Before this CL, this source is rejected, and therefore palm rejection
feature is not enabled.
With this CL, any source that has SOURCE_TOUCHSCREEN is allowed. That
also means that we potentially would invoke the model for stylus events,
especially if simultaneous touch and stylus are enabled.
The model, however, was never trained on stylus, and is not designed to
work with it. In preparation to upcoming simultaneous touch+stylus
feature, in this CL we also remove the stylus pointers before sending
the data to the model.
The only case where we need to be careful is pointer-down and pointer-up
events with stylus. In this CL, we drop these events, which should be a
no-op from the palm rejection model's perpective.
Bug: 241935838
Test: atest libpalmrejection_test inputflinger_tests
Change-Id: I760207a82807e03802e72a318fca8b97a4fd7a24
Diffstat (limited to 'services/inputflinger/UnwantedInteractionBlocker.cpp')
| -rw-r--r-- | services/inputflinger/UnwantedInteractionBlocker.cpp | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/services/inputflinger/UnwantedInteractionBlocker.cpp b/services/inputflinger/UnwantedInteractionBlocker.cpp index fc8dfe678b..ec41025e9d 100644 --- a/services/inputflinger/UnwantedInteractionBlocker.cpp +++ b/services/inputflinger/UnwantedInteractionBlocker.cpp @@ -77,8 +77,7 @@ static std::string toLower(std::string s) { } static bool isFromTouchscreen(int32_t source) { - return isFromSource(source, AINPUT_SOURCE_TOUCHSCREEN) && - !isFromSource(source, AINPUT_SOURCE_STYLUS); + return isFromSource(source, AINPUT_SOURCE_TOUCHSCREEN); } static ::base::TimeTicks toChromeTimestamp(nsecs_t eventTime) { @@ -142,23 +141,6 @@ static int32_t resolveActionForPointer(uint8_t pointerIndex, int32_t action) { return AMOTION_EVENT_ACTION_MOVE; } -/** - * Remove the data for the provided pointers from the args. The pointers are identified by their - * pointerId, not by the index inside the array. - * Return the new NotifyMotionArgs struct that has the remaining pointers. - * The only fields that may be different in the returned args from the provided args are: - * - action - * - pointerCount - * - pointerProperties - * - pointerCoords - * Action might change because it contains a pointer index. If another pointer is removed, the - * active pointer index would be shifted. - * Do not call this function for events with POINTER_UP or POINTER_DOWN events when removed pointer - * id is the acting pointer id. - * - * @param args the args from which the pointers should be removed - * @param pointerIds the pointer ids of the pointers that should be removed - */ NotifyMotionArgs removePointerIds(const NotifyMotionArgs& args, const std::set<int32_t>& pointerIds) { const uint8_t actionIndex = MotionEvent::getActionIndex(args.action); @@ -204,6 +186,26 @@ NotifyMotionArgs removePointerIds(const NotifyMotionArgs& args, return newArgs; } +/** + * Remove stylus pointers from the provided NotifyMotionArgs. + * + * Return NotifyMotionArgs where the stylus pointers have been removed. + * If this results in removal of the active pointer, then return nullopt. + */ +static std::optional<NotifyMotionArgs> removeStylusPointerIds(const NotifyMotionArgs& args) { + std::set<int32_t> stylusPointerIds; + for (uint32_t i = 0; i < args.pointerCount; i++) { + if (args.pointerProperties[i].toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS) { + stylusPointerIds.insert(args.pointerProperties[i].id); + } + } + NotifyMotionArgs withoutStylusPointers = removePointerIds(args, stylusPointerIds); + if (withoutStylusPointers.pointerCount == 0 || withoutStylusPointers.action == ACTION_UNKNOWN) { + return std::nullopt; + } + return withoutStylusPointers; +} + std::optional<AndroidPalmFilterDeviceInfo> createPalmFilterDeviceInfo( const InputDeviceInfo& deviceInfo) { if (!isFromTouchscreen(deviceInfo.getSources())) { @@ -678,7 +680,15 @@ std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs std::set<int32_t> oldSuppressedIds; std::swap(oldSuppressedIds, mSuppressedPointerIds); - mSuppressedPointerIds = detectPalmPointers(args); + + std::optional<NotifyMotionArgs> touchOnlyArgs = removeStylusPointerIds(args); + if (touchOnlyArgs) { + mSuppressedPointerIds = detectPalmPointers(*touchOnlyArgs); + } else { + // This is a stylus-only event. + // We can skip this event and just keep the suppressed pointer ids the same as before. + mSuppressedPointerIds = oldSuppressedIds; + } std::vector<NotifyMotionArgs> argsWithoutUnwantedPointers = cancelSuppressedPointers(args, oldSuppressedIds, mSuppressedPointerIds); |