Expose flag to report palm detected by firmware to gestures-lib
We currently don't report palms detected by firmware to gestures-lib,
this leads to situations where gesture lib consideres a touch to be
lifted if its reported as palm by firmware. This can also cause
unintended tap-to-click, and prevent bottom-right click from working as
intended.
BUG=b:302505955
TEST=atest libchrome-gestures_test
Change-Id: I172af6b3d46997bfefe68b4bede5c80d522bad3d
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/gestures/+/4974106
Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com>
Reviewed-by: Harry Cutts <hcutts@chromium.org>
Tested-by: Arpit Singh <arpitks@google.com>
Reviewed-by: Sean O'Brien <seobrien@chromium.org>
Commit-Queue: Harry Cutts <hcutts@chromium.org>
diff --git a/include/gestures.h b/include/gestures.h
index 83924cd..1a0a9b3 100644
--- a/include/gestures.h
+++ b/include/gestures.h
@@ -165,6 +165,10 @@
// Describes a single contact on a touch surface. Generally, the fields have the
// same meaning as the equivalent ABS_MT_... axis in the Linux evdev protocol.
struct FingerState {
+ enum class ToolType {
+ kFinger = 0,
+ kPalm,
+ };
// The large and small radii of the ellipse of the finger touching the pad.
float touch_major, touch_minor;
@@ -188,6 +192,8 @@
// A bit field of flags that are used internally by the library. (See the
// GESTURES_FINGER_* constants.) Should be set to 0 on incoming FingerStates.
unsigned flags;
+
+ ToolType tool_type = ToolType::kFinger;
#ifdef __cplusplus
bool NonFlagsEquals(const FingerState& that) const {
return touch_major == that.touch_major &&
diff --git a/include/palm_classifying_filter_interpreter.h b/include/palm_classifying_filter_interpreter.h
index 4ef88bd..53fcafe 100644
--- a/include/palm_classifying_filter_interpreter.h
+++ b/include/palm_classifying_filter_interpreter.h
@@ -25,6 +25,7 @@
// bottom area of the pad.
class PalmClassifyingFilterInterpreter : public FilterInterpreter {
+ FRIEND_TEST(PalmClassifyingFilterInterpreterTest, ExternallyMarkedPalmTest);
FRIEND_TEST(PalmClassifyingFilterInterpreterTest, PalmAtEdgeTest);
FRIEND_TEST(PalmClassifyingFilterInterpreterTest, PalmReevaluateTest);
FRIEND_TEST(PalmClassifyingFilterInterpreterTest, PalmTest);
diff --git a/src/palm_classifying_filter_interpreter.cc b/src/palm_classifying_filter_interpreter.cc
index 2dfe58e..1551f94 100644
--- a/src/palm_classifying_filter_interpreter.cc
+++ b/src/palm_classifying_filter_interpreter.cc
@@ -191,6 +191,11 @@
pointing_.erase(fs.tracking_id);
continue;
}
+ // Mark externally reported palms
+ if(fs.tool_type == FingerState::ToolType::kPalm){
+ palm_.insert(fs.tracking_id);
+ pointing_.erase(fs.tracking_id);
+ }
}
if (hwstate.finger_cnt == 1 &&
diff --git a/src/palm_classifying_filter_interpreter_unittest.cc b/src/palm_classifying_filter_interpreter_unittest.cc
index b0a2ca6..6d667ad 100644
--- a/src/palm_classifying_filter_interpreter_unittest.cc
+++ b/src/palm_classifying_filter_interpreter_unittest.cc
@@ -12,6 +12,7 @@
#include "include/gestures.h"
#include "include/palm_classifying_filter_interpreter.h"
+#include "include/string_util.h"
#include "include/unittest_util.h"
#include "include/util.h"
@@ -119,6 +120,68 @@
}
}
+TEST(PalmClassifyingFilterInterpreterTest, ExternallyMarkedPalmTest) {
+ PalmClassifyingFilterInterpreterTestInterpreter* base_interpreter =
+ new PalmClassifyingFilterInterpreterTestInterpreter;
+ PalmClassifyingFilterInterpreter pci(nullptr, base_interpreter, nullptr);
+ HardwareProperties hwprops = {
+ .right = 1000,
+ .bottom = 1000,
+ .res_x = 500,
+ .res_y = 500,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
+ };
+
+ TestInterpreterWrapper wrapper(&pci, &hwprops);
+
+ const float kPr = pci.palm_pressure_.val_ / 2;
+
+ FingerState finger_states[] = {
+ // TM, Tm, WM, Wm, Press, Orientation, X, Y, TrID, flags, ToolType
+ {0, 0, 0, 0, kPr, 0, 600, 500, 1, 0},
+ {0, 0, 0, 0, kPr, 0, 600, 500, 1, 0},
+ // mark the touch as palm
+ {0, 0, 0, 0, kPr, 0, 600, 500, 1, 0, FingerState::ToolType::kPalm},
+ {0, 0, 0, 0, kPr, 0, 600, 500, 1, 0, FingerState::ToolType::kPalm},
+ };
+ HardwareState hardware_state[] = {
+ // time, buttons, finger count, touch count, finger states pointer
+ make_hwstate(0.00, 0, 1, 1, &finger_states[0]),
+ make_hwstate(4.00, 0, 1, 1, &finger_states[1]),
+ make_hwstate(5.00, 0, 1, 1, &finger_states[2]),
+ make_hwstate(5.01, 0, 1, 1, &finger_states[3]),
+ };
+
+ for (size_t i = 0; i < arraysize(hardware_state); ++i) {
+ SCOPED_TRACE(StringPrintf("i = %zu", i));
+ if(i > 1) {
+ base_interpreter->expected_flags_ = GESTURES_FINGER_PALM;
+ }
+ else {
+ base_interpreter->expected_flags_ = 0;
+ }
+ wrapper.SyncInterpret(hardware_state[i], nullptr);
+ if (i > 1) {
+ // After the second frame finger is marked as palm
+ EXPECT_FALSE(SetContainsValue(pci.pointing_, 1));
+ EXPECT_TRUE(SetContainsValue(pci.palm_, 1));
+ }
+ else {
+ EXPECT_TRUE(SetContainsValue(pci.pointing_, 1));
+ EXPECT_FALSE(SetContainsValue(pci.palm_, 1));
+ }
+ }
+}
+
TEST(PalmClassifyingFilterInterpreterTest, StationaryPalmTest) {
PalmClassifyingFilterInterpreter pci(nullptr, nullptr, nullptr);
HardwareProperties hwprops = {