diff options
Diffstat (limited to 'services/inputflinger/UnwantedInteractionBlocker.cpp')
| -rw-r--r-- | services/inputflinger/UnwantedInteractionBlocker.cpp | 123 |
1 files changed, 70 insertions, 53 deletions
diff --git a/services/inputflinger/UnwantedInteractionBlocker.cpp b/services/inputflinger/UnwantedInteractionBlocker.cpp index 4e0f0c3bf5..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) { @@ -99,17 +98,15 @@ static bool isPalmRejectionEnabled() { return false; } -static int getLinuxToolType(int32_t toolType) { - switch (toolType) { - case AMOTION_EVENT_TOOL_TYPE_FINGER: - return MT_TOOL_FINGER; - case AMOTION_EVENT_TOOL_TYPE_STYLUS: - return MT_TOOL_PEN; - case AMOTION_EVENT_TOOL_TYPE_PALM: - return MT_TOOL_PALM; +static int getLinuxToolCode(int toolType) { + if (toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS) { + return BTN_TOOL_PEN; } - ALOGW("Got tool type %" PRId32 ", converting to MT_TOOL_FINGER", toolType); - return MT_TOOL_FINGER; + if (toolType == AMOTION_EVENT_TOOL_TYPE_FINGER) { + return BTN_TOOL_FINGER; + } + ALOGW("Got tool type %" PRId32 ", converting to BTN_TOOL_FINGER", toolType); + return BTN_TOOL_FINGER; } static int32_t getActionUpForPointerId(const NotifyMotionArgs& args, int32_t pointerId) { @@ -144,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); @@ -206,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())) { @@ -562,7 +562,7 @@ std::vector<::ui::InProgressTouchEvdev> getTouches(const NotifyMotionArgs& args, touches.emplace_back(::ui::InProgressTouchEvdev()); touches.back().major = args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR); touches.back().minor = args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR); - touches.back().tool_type = getLinuxToolType(args.pointerProperties[i].toolType); + // The field 'tool_type' is not used for palm rejection // Whether there is new information for the touch. touches.back().altered = true; @@ -609,32 +609,16 @@ std::vector<::ui::InProgressTouchEvdev> getTouches(const NotifyMotionArgs& args, // The fields 'radius_x' and 'radius_x' are not used for palm rejection touches.back().pressure = args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE); - touches.back().tool_code = BTN_TOOL_FINGER; + touches.back().tool_code = getLinuxToolCode(args.pointerProperties[i].toolType); // The field 'orientation' is not used for palm rejection // The fields 'tilt_x' and 'tilt_y' are not used for palm rejection - touches.back().reported_tool_type = ::ui::EventPointerType::kTouch; + // The field 'reported_tool_type' is not used for palm rejection touches.back().stylus_button = false; } return touches; } -std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs& args) { - if (mPalmDetectionFilter == nullptr) { - return {args}; - } - const bool skipThisEvent = args.action == AMOTION_EVENT_ACTION_HOVER_ENTER || - args.action == AMOTION_EVENT_ACTION_HOVER_MOVE || - args.action == AMOTION_EVENT_ACTION_HOVER_EXIT || - args.action == AMOTION_EVENT_ACTION_BUTTON_PRESS || - args.action == AMOTION_EVENT_ACTION_BUTTON_RELEASE || - args.action == AMOTION_EVENT_ACTION_SCROLL; - if (skipThisEvent) { - // Lets not process hover events, button events, or scroll for now. - return {args}; - } - if (args.action == AMOTION_EVENT_ACTION_DOWN) { - mSuppressedPointerIds.clear(); - } +std::set<int32_t> PalmRejector::detectPalmPointers(const NotifyMotionArgs& args) { std::bitset<::ui::kNumTouchEvdevSlots> slotsToHold; std::bitset<::ui::kNumTouchEvdevSlots> slotsToSuppress; @@ -642,6 +626,7 @@ std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs // the slots that have been removed due to the incoming event. SlotState oldSlotState = mSlotState; mSlotState.update(args); + std::vector<::ui::InProgressTouchEvdev> touches = getTouches(args, mDeviceInfo, oldSlotState, mSlotState); ::base::TimeTicks chromeTimestamp = toChromeTimestamp(args.eventTime); @@ -653,14 +638,14 @@ std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs } ALOGD("Filter: touches = %s", touchesStream.str().c_str()); } + mPalmDetectionFilter->Filter(touches, chromeTimestamp, &slotsToHold, &slotsToSuppress); ALOGD_IF(DEBUG_MODEL, "Response: slotsToHold = %s, slotsToSuppress = %s", slotsToHold.to_string().c_str(), slotsToSuppress.to_string().c_str()); // Now that we know which slots should be suppressed, let's convert those to pointer id's. - std::set<int32_t> oldSuppressedIds; - std::swap(oldSuppressedIds, mSuppressedPointerIds); + std::set<int32_t> newSuppressedIds; for (size_t i = 0; i < args.pointerCount; i++) { const int32_t pointerId = args.pointerProperties[i].id; std::optional<size_t> slot = oldSlotState.getSlotForPointerId(pointerId); @@ -669,9 +654,41 @@ std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs LOG_ALWAYS_FATAL_IF(!slot, "Could not find slot for pointer id %" PRId32, pointerId); } if (slotsToSuppress.test(*slot)) { - mSuppressedPointerIds.insert(pointerId); + newSuppressedIds.insert(pointerId); } } + return newSuppressedIds; +} + +std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs& args) { + if (mPalmDetectionFilter == nullptr) { + return {args}; + } + const bool skipThisEvent = args.action == AMOTION_EVENT_ACTION_HOVER_ENTER || + args.action == AMOTION_EVENT_ACTION_HOVER_MOVE || + args.action == AMOTION_EVENT_ACTION_HOVER_EXIT || + args.action == AMOTION_EVENT_ACTION_BUTTON_PRESS || + args.action == AMOTION_EVENT_ACTION_BUTTON_RELEASE || + args.action == AMOTION_EVENT_ACTION_SCROLL; + if (skipThisEvent) { + // Lets not process hover events, button events, or scroll for now. + return {args}; + } + if (args.action == AMOTION_EVENT_ACTION_DOWN) { + mSuppressedPointerIds.clear(); + } + + std::set<int32_t> oldSuppressedIds; + std::swap(oldSuppressedIds, mSuppressedPointerIds); + + 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); @@ -691,7 +708,7 @@ std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs return argsWithoutUnwantedPointers; } -const AndroidPalmFilterDeviceInfo& PalmRejector::getPalmFilterDeviceInfo() { +const AndroidPalmFilterDeviceInfo& PalmRejector::getPalmFilterDeviceInfo() const { return mDeviceInfo; } |