summaryrefslogtreecommitdiff
path: root/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter_util_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter_util_unittest.cc')
-rw-r--r--ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter_util_unittest.cc268
1 files changed, 230 insertions, 38 deletions
diff --git a/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter_util_unittest.cc b/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter_util_unittest.cc
index fc5d367..e7019b0 100644
--- a/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter_util_unittest.cc
+++ b/ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter_util_unittest.cc
@@ -9,10 +9,11 @@
#include <utility>
#include <vector>
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#if defined(__ANDROID__)
+#if defined(__ANDROID__) || defined(__ANDROID_HOST__)
#include <linux/input-event-codes.h>
-#include "chrome_to_android_compatibility_test_support.h"
+#include "chrome_to_android_compatibility.h"
#else
#include "ui/events/ozone/evdev/event_device_test_util.h"
#endif
@@ -20,9 +21,12 @@
#include "ui/events/ozone/evdev/touch_filter/palm_detection_filter.h"
#include "ui/events/ozone/evdev/touch_filter/shared_palm_detection_filter_state.h"
+using ::testing::ElementsAre;
+using ::testing::IsEmpty;
+
namespace ui {
-#if defined(__ANDROID__)
+#if defined(__ANDROID__) || defined(__ANDROID_HOST__)
/**
* The tests that require an actual device (something that responds to ioctls)
* have been removed. The rest of the tests were simplified by modifying the
@@ -83,7 +87,13 @@ bool CapabilitiesToDeviceInfo(DeviceType, EventDeviceInfo*) {
}
#endif
-class NeuralStylusPalmDetectionFilterUtilTest : public testing::Test {
+MATCHER_P(SampleTime, time, "Does the sample have given time.") {
+ *result_listener << "Sample time" << arg.time << " is not " << time;
+ return time == arg.time;
+}
+
+class NeuralStylusPalmDetectionFilterUtilTest
+ : public testing::TestWithParam<bool> {
public:
NeuralStylusPalmDetectionFilterUtilTest() = default;
@@ -101,6 +111,11 @@ class NeuralStylusPalmDetectionFilterUtilTest : public testing::Test {
touch_.tracking_id = 22;
touch_.x = 21;
touch_.y = 20;
+ model_config_.max_sample_count = 3;
+ const bool resample_touch = GetParam();
+ if (resample_touch) {
+ model_config_.resample_period = base::Milliseconds(8);
+ }
}
protected:
@@ -109,8 +124,16 @@ class NeuralStylusPalmDetectionFilterUtilTest : public testing::Test {
NeuralStylusPalmDetectionFilterModelConfig model_config_;
};
-#if !defined(__ANDROID__)
-TEST_F(NeuralStylusPalmDetectionFilterUtilTest, DistilledNocturneTest) {
+INSTANTIATE_TEST_SUITE_P(ParametricUtilTest,
+ NeuralStylusPalmDetectionFilterUtilTest,
+ ::testing::Bool(),
+ [](const auto& paramInfo) {
+ return paramInfo.param ? "ResamplingEnabled"
+ : "ResamplingDisabled";
+ });
+
+#if !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
+TEST_P(NeuralStylusPalmDetectionFilterUtilTest, DistilledNocturneTest) {
const PalmFilterDeviceInfo nocturne_distilled =
CreatePalmFilterDeviceInfo(nocturne_touchscreen_);
EXPECT_FLOAT_EQ(nocturne_distilled.max_x,
@@ -128,9 +151,9 @@ TEST_F(NeuralStylusPalmDetectionFilterUtilTest, DistilledNocturneTest) {
nocturne_touchscreen_.GetAbsResolution(ABS_MT_TOUCH_MINOR));
}
-TEST_F(NeuralStylusPalmDetectionFilterUtilTest, NoMinorResTest) {
- // Nocturne has minor resolution: but lets pretend it didnt. we should recover
- // "1" as the resolution.
+TEST_P(NeuralStylusPalmDetectionFilterUtilTest, NoMinorResTest) {
+ // Nocturne has minor resolution, but let's pretend it doesn't. we should
+ // recover "1" as the resolution.
auto abs_info = nocturne_touchscreen_.GetAbsInfoByCode(ABS_MT_TOUCH_MINOR);
abs_info.resolution = 0;
nocturne_touchscreen_.SetAbsInfo(ABS_MT_TOUCH_MINOR, abs_info);
@@ -141,12 +164,12 @@ TEST_F(NeuralStylusPalmDetectionFilterUtilTest, NoMinorResTest) {
}
#endif
-TEST_F(NeuralStylusPalmDetectionFilterUtilTest, DistillerKohakuTest) {
+TEST_P(NeuralStylusPalmDetectionFilterUtilTest, DistillerKohakuTest) {
EventDeviceInfo kohaku_touchscreen;
ASSERT_TRUE(
CapabilitiesToDeviceInfo(kKohakuTouchscreen, &kohaku_touchscreen));
const PalmFilterDeviceInfo kohaku_distilled =
-#if !defined(__ANDROID__)
+#if !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
CreatePalmFilterDeviceInfo(kohaku_touchscreen);
#else
CreatePalmFilterDeviceInfo(kKohakuTouchscreen);
@@ -156,11 +179,11 @@ TEST_F(NeuralStylusPalmDetectionFilterUtilTest, DistillerKohakuTest) {
EXPECT_EQ(1, kohaku_distilled.y_res);
}
-TEST_F(NeuralStylusPalmDetectionFilterUtilTest, DistilledLinkTest) {
+TEST_P(NeuralStylusPalmDetectionFilterUtilTest, DistilledLinkTest) {
EventDeviceInfo link_touchscreen;
ASSERT_TRUE(CapabilitiesToDeviceInfo(kLinkTouchscreen, &link_touchscreen));
const PalmFilterDeviceInfo link_distilled =
-#if !defined(__ANDROID__)
+#if !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
CreatePalmFilterDeviceInfo(link_touchscreen);
#else
CreatePalmFilterDeviceInfo(kLinkTouchscreen);
@@ -171,10 +194,10 @@ TEST_F(NeuralStylusPalmDetectionFilterUtilTest, DistilledLinkTest) {
link_distilled.minor_radius_res);
}
-TEST_F(NeuralStylusPalmDetectionFilterUtilTest, PalmFilterSampleTest) {
+TEST_P(NeuralStylusPalmDetectionFilterUtilTest, PalmFilterSampleTest) {
base::TimeTicks time = base::TimeTicks() + base::Seconds(30);
const PalmFilterDeviceInfo nocturne_distilled =
-#if !defined(__ANDROID__)
+#if !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
CreatePalmFilterDeviceInfo(nocturne_touchscreen_);
#else
CreatePalmFilterDeviceInfo(kNocturneTouchScreen);
@@ -190,12 +213,12 @@ TEST_F(NeuralStylusPalmDetectionFilterUtilTest, PalmFilterSampleTest) {
EXPECT_EQ(0.5, sample.edge);
}
-TEST_F(NeuralStylusPalmDetectionFilterUtilTest, LinkTouchscreenSampleTest) {
+TEST_P(NeuralStylusPalmDetectionFilterUtilTest, LinkTouchscreenSampleTest) {
EventDeviceInfo link_touchscreen;
base::TimeTicks time = base::TimeTicks() + base::Seconds(30);
ASSERT_TRUE(CapabilitiesToDeviceInfo(kLinkTouchscreen, &link_touchscreen));
const PalmFilterDeviceInfo link_distilled =
-#if !defined(__ANDROID__)
+#if !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
CreatePalmFilterDeviceInfo(link_touchscreen);
#else
CreatePalmFilterDeviceInfo(kLinkTouchscreen);
@@ -210,15 +233,15 @@ TEST_F(NeuralStylusPalmDetectionFilterUtilTest, LinkTouchscreenSampleTest) {
EXPECT_FLOAT_EQ(12.5, sample.minor_radius);
}
-TEST_F(NeuralStylusPalmDetectionFilterUtilTest, PalmFilterStrokeTest) {
- PalmFilterStroke stroke(3); // maxsize: 3.
- EXPECT_EQ(0, stroke.tracking_id());
+TEST_P(NeuralStylusPalmDetectionFilterUtilTest, PalmFilterStrokeTest) {
+ PalmFilterStroke stroke(model_config_, /*tracking_id*/ 55);
+ touch_.tracking_id = 55;
// With no points, center is 0.
EXPECT_EQ(gfx::PointF(0., 0.), stroke.GetCentroid());
base::TimeTicks time = base::TimeTicks() + base::Seconds(30);
const PalmFilterDeviceInfo nocturne_distilled =
-#if !defined(__ANDROID__)
+#if !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
CreatePalmFilterDeviceInfo(nocturne_touchscreen_);
#else
CreatePalmFilterDeviceInfo(kNocturneTouchScreen);
@@ -228,7 +251,8 @@ TEST_F(NeuralStylusPalmDetectionFilterUtilTest, PalmFilterStrokeTest) {
touch_.x = 15 + i;
PalmFilterSample sample =
CreatePalmFilterSample(touch_, time, model_config_, nocturne_distilled);
- stroke.AddSample(std::move(sample));
+ time += base::Milliseconds(8);
+ stroke.ProcessSample(std::move(sample));
EXPECT_EQ(touch_.tracking_id, stroke.tracking_id());
if (i < 3) {
if (i == 0) {
@@ -248,19 +272,18 @@ TEST_F(NeuralStylusPalmDetectionFilterUtilTest, PalmFilterStrokeTest) {
ASSERT_FLOAT_EQ(expected_centroid.x(), stroke.GetCentroid().x())
<< "failed at i " << i;
}
- stroke.SetTrackingId(55);
- EXPECT_EQ(55, stroke.tracking_id());
}
-TEST_F(NeuralStylusPalmDetectionFilterUtilTest,
+TEST_P(NeuralStylusPalmDetectionFilterUtilTest,
PalmFilterStrokeBiggestSizeTest) {
- PalmFilterStroke stroke(3);
- PalmFilterStroke no_minor_stroke(3); // maxsize: 3.
+ PalmFilterStroke stroke(model_config_, /*tracking_id*/ 0);
+ PalmFilterStroke no_minor_stroke(model_config_, /*tracking_id*/ 0);
+ touch_.tracking_id = stroke.tracking_id();
EXPECT_EQ(0, stroke.BiggestSize());
base::TimeTicks time = base::TimeTicks() + base::Seconds(30);
const PalmFilterDeviceInfo nocturne_distilled =
-#if !defined(__ANDROID__)
+#if !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
CreatePalmFilterDeviceInfo(nocturne_touchscreen_);
#else
CreatePalmFilterDeviceInfo(kNocturneTouchScreen);
@@ -271,24 +294,44 @@ TEST_F(NeuralStylusPalmDetectionFilterUtilTest,
PalmFilterSample sample =
CreatePalmFilterSample(touch_, time, model_config_, nocturne_distilled);
EXPECT_EQ(static_cast<uint64_t>(i), stroke.samples_seen());
- stroke.AddSample(sample);
+ stroke.ProcessSample(sample);
EXPECT_FLOAT_EQ((1 + i) * (2 + i), stroke.BiggestSize());
PalmFilterSample second_sample =
CreatePalmFilterSample(touch_, time, model_config_, nocturne_distilled);
second_sample.minor_radius = 0;
- no_minor_stroke.AddSample(std::move(second_sample));
+ no_minor_stroke.ProcessSample(std::move(second_sample));
EXPECT_FLOAT_EQ((2 + i) * (2 + i), no_minor_stroke.BiggestSize());
- EXPECT_EQ(std::min(3ul, 1ul + i), stroke.samples().size());
+ ASSERT_EQ(std::min(3ul, 1ul + i), stroke.samples().size());
+ time += base::Milliseconds(8);
}
}
-TEST_F(NeuralStylusPalmDetectionFilterUtilTest, StrokeGetMaxMajorTest) {
- PalmFilterStroke stroke(3);
+TEST_P(NeuralStylusPalmDetectionFilterUtilTest, UnscaledMajorMinorResolution) {
+ model_config_.radius_polynomial_resize = {};
+ PalmFilterDeviceInfo device_info;
+ device_info.x_res = 2;
+ device_info.y_res = 5;
+ device_info.major_radius_res = 2;
+ device_info.minor_radius_res = 5;
+ device_info.minor_radius_supported = true;
+ touch_.major = 20;
+ touch_.minor = 10;
+ touch_.orientation = 0;
+ base::TimeTicks time = base::TimeTicks::UnixEpoch() + base::Seconds(30);
+ PalmFilterSample sample =
+ CreatePalmFilterSample(touch_, time, model_config_, device_info);
+ EXPECT_EQ(20 / 2, sample.major_radius);
+ EXPECT_EQ(10 / 5, sample.minor_radius);
+}
+
+TEST_P(NeuralStylusPalmDetectionFilterUtilTest, StrokeGetMaxMajorTest) {
+ PalmFilterStroke stroke(model_config_, /*tracking_id*/ 0);
+ touch_.tracking_id = stroke.tracking_id();
EXPECT_FLOAT_EQ(0, stroke.MaxMajorRadius());
base::TimeTicks time = base::TimeTicks::UnixEpoch() + base::Seconds(30);
const PalmFilterDeviceInfo nocturne_distilled =
-#if !defined(__ANDROID__)
+#if !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
CreatePalmFilterDeviceInfo(nocturne_touchscreen_);
#else
CreatePalmFilterDeviceInfo(kNocturneTouchScreen);
@@ -300,17 +343,17 @@ TEST_F(NeuralStylusPalmDetectionFilterUtilTest, StrokeGetMaxMajorTest) {
CreatePalmFilterSample(touch_, time, model_config_, nocturne_distilled);
time += base::Milliseconds(8);
EXPECT_EQ(static_cast<uint64_t>(i - 1), stroke.samples_seen());
- stroke.AddSample(sample);
+ stroke.ProcessSample(sample);
EXPECT_FLOAT_EQ(i, stroke.MaxMajorRadius());
}
}
-TEST_F(NeuralStylusPalmDetectionFilterUtilTest, SampleRadiusConversion) {
+TEST_P(NeuralStylusPalmDetectionFilterUtilTest, SampleRadiusConversion) {
// A single number: a _constant_.
model_config_.radius_polynomial_resize = {71.3};
base::TimeTicks time = base::TimeTicks::UnixEpoch() + base::Seconds(30);
const PalmFilterDeviceInfo nocturne_distilled =
-#if !defined(__ANDROID__)
+#if !defined(__ANDROID__) && !defined(__ANDROID_HOST__)
CreatePalmFilterDeviceInfo(nocturne_touchscreen_);
#else
CreatePalmFilterDeviceInfo(kNocturneTouchScreen);
@@ -328,4 +371,153 @@ TEST_F(NeuralStylusPalmDetectionFilterUtilTest, SampleRadiusConversion) {
EXPECT_FLOAT_EQ(0.1 * 24 * 24 + 0.4 * 24 - 5.0, sample.minor_radius);
}
-} // namespace ui \ No newline at end of file
+TEST(PalmFilterStrokeTest, NumberOfResampledValues) {
+ NeuralStylusPalmDetectionFilterModelConfig model_config_;
+ model_config_.max_sample_count = 3;
+ model_config_.resample_period = base::Milliseconds(8);
+ base::TimeTicks down_time = base::TimeTicks::UnixEpoch() + base::Seconds(30);
+
+ PalmFilterStroke stroke(model_config_, /*tracking_id*/ 0);
+ const PalmFilterDeviceInfo device_info;
+
+ // Initially, no samples
+ ASSERT_THAT(stroke.samples(), IsEmpty());
+ ASSERT_EQ(0u, stroke.samples_seen());
+
+ // Add first sample at time = T
+ InProgressTouchEvdev touch_;
+ touch_.tracking_id = stroke.tracking_id();
+ PalmFilterSample sample =
+ CreatePalmFilterSample(touch_, down_time, model_config_, device_info);
+ stroke.ProcessSample(sample);
+ ASSERT_THAT(stroke.samples(), ElementsAre(SampleTime(down_time)));
+ ASSERT_EQ(1u, stroke.samples_seen());
+
+ // Add second sample at time = T + 4ms. All samples are stored, even if it's
+ // before the next resample time.
+ base::TimeTicks time = down_time + base::Milliseconds(4);
+ sample = CreatePalmFilterSample(touch_, time, model_config_, device_info);
+ stroke.ProcessSample(sample);
+ ASSERT_THAT(stroke.samples(),
+ ElementsAre(SampleTime(down_time), SampleTime(time)));
+ ASSERT_EQ(2u, stroke.samples_seen());
+
+ // Add third sample at time = T + 10ms.
+ time = down_time + base::Milliseconds(10);
+ sample = CreatePalmFilterSample(touch_, time, model_config_, device_info);
+ stroke.ProcessSample(sample);
+ ASSERT_THAT(stroke.samples(),
+ ElementsAre(SampleTime(down_time),
+ SampleTime(down_time + base::Milliseconds(4)),
+ SampleTime(down_time + base::Milliseconds(10))));
+ ASSERT_EQ(3u, stroke.samples_seen());
+}
+
+TEST(PalmFilterStrokeTest, ResamplingTest) {
+ NeuralStylusPalmDetectionFilterModelConfig model_config_;
+ model_config_.max_sample_count = 3;
+ model_config_.resample_period = base::Milliseconds(8);
+
+ PalmFilterStroke stroke(model_config_, /*tracking_id*/ 0);
+ PalmFilterDeviceInfo device_info;
+ device_info.minor_radius_supported = true;
+
+ // Add first sample at time = T
+ InProgressTouchEvdev touch_;
+ touch_.tracking_id = stroke.tracking_id();
+ touch_.x = 1;
+ touch_.y = 2;
+ touch_.major = 4;
+ touch_.minor = 3;
+ base::TimeTicks down_time = base::TimeTicks::UnixEpoch() + base::Seconds(30);
+ PalmFilterSample sample1 =
+ CreatePalmFilterSample(touch_, down_time, model_config_, device_info);
+ stroke.ProcessSample(sample1);
+ // First sample should not be modified
+ ASSERT_THAT(stroke.samples(), ElementsAre(sample1));
+
+ // Add second sample at time = T + 2ms. It's not yet time for the new frame,
+ // so no new sample should be generated.
+ base::TimeTicks time = down_time + base::Milliseconds(4);
+ touch_.x = 100;
+ touch_.y = 20;
+ touch_.major = 12;
+ touch_.minor = 11;
+ PalmFilterSample sample2 =
+ CreatePalmFilterSample(touch_, time, model_config_, device_info);
+ stroke.ProcessSample(sample2);
+ // The samples should remain unchanged
+ ASSERT_THAT(stroke.samples(), ElementsAre(sample1, sample2));
+
+ // Add third sample at time = T + 12ms. A resampled event at time = T + 8ms
+ // should be generated.
+ time = down_time + base::Milliseconds(12);
+ touch_.x = 200;
+ touch_.y = 24;
+ touch_.major = 14;
+ touch_.minor = 13;
+ PalmFilterSample sample3 =
+ CreatePalmFilterSample(touch_, time, model_config_, device_info);
+ stroke.ProcessSample(sample3);
+ ASSERT_THAT(stroke.samples(), ElementsAre(sample1, sample2, sample3));
+}
+
+/**
+ * There should always be at least (max_sample_count - 1) * resample_period
+ * worth of samples. However, that's not sufficient. In the cases where the gap
+ * between samples is very large (larger than the sample horizon), there needs
+ * to be another sample in order to calculate resampled values throughout the
+ * entire range.
+ */
+TEST(PalmFilterStrokeTest, MultipleResampledValues) {
+ NeuralStylusPalmDetectionFilterModelConfig model_config_;
+ model_config_.max_sample_count = 3;
+ model_config_.resample_period = base::Milliseconds(8);
+
+ PalmFilterStroke stroke(model_config_, /*tracking_id*/ 0);
+ PalmFilterDeviceInfo device_info;
+ device_info.minor_radius_supported = true;
+
+ // Add first sample at time = T
+ InProgressTouchEvdev touch_;
+ touch_.tracking_id = stroke.tracking_id();
+ touch_.x = 0;
+ touch_.y = 10;
+ touch_.major = 200;
+ touch_.minor = 100;
+ base::TimeTicks down_time = base::TimeTicks::UnixEpoch() + base::Seconds(30);
+ PalmFilterSample sample1 =
+ CreatePalmFilterSample(touch_, down_time, model_config_, device_info);
+ stroke.ProcessSample(sample1);
+ // First sample should go in as is
+ ASSERT_THAT(stroke.samples(), ElementsAre(sample1));
+
+ // Add second sample at time = T + 20ms.
+ base::TimeTicks time = down_time + base::Milliseconds(20);
+ touch_.x = 20;
+ touch_.y = 30;
+ touch_.major = 220;
+ touch_.minor = 120;
+ PalmFilterSample sample2 =
+ CreatePalmFilterSample(touch_, time, model_config_, device_info);
+ stroke.ProcessSample(sample2);
+
+ ASSERT_THAT(stroke.samples(), ElementsAre(sample1, sample2));
+
+ // Verify resampled sample : time = T + 8ms
+ PalmFilterSample resampled_sample =
+ stroke.GetSampleAt(down_time + base::Milliseconds(8));
+ EXPECT_EQ(8, resampled_sample.point.x());
+ EXPECT_EQ(18, resampled_sample.point.y());
+ EXPECT_EQ(220, resampled_sample.major_radius);
+ EXPECT_EQ(120, resampled_sample.minor_radius);
+
+ // Verify resampled sample : time = T + 16ms
+ resampled_sample = stroke.GetSampleAt(down_time + base::Milliseconds(16));
+ EXPECT_EQ(16, resampled_sample.point.x());
+ EXPECT_EQ(26, resampled_sample.point.y());
+ EXPECT_EQ(220, resampled_sample.major_radius);
+ EXPECT_EQ(120, resampled_sample.minor_radius);
+}
+
+} // namespace ui