summaryrefslogtreecommitdiff
path: root/services/inputflinger/UnwantedInteractionBlocker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/inputflinger/UnwantedInteractionBlocker.cpp')
-rw-r--r--services/inputflinger/UnwantedInteractionBlocker.cpp123
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;
}