[go: nahoru, domu]

blob: d35f568035bb0b900d04276b2bc5ef4045cc12ce [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/events/ozone/evdev/touch_filter/heuristic_stylus_palm_detection_filter.h"
#include <linux/input.h>
#include "base/test/gtest_util.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/ozone/evdev/touch_filter/palm_detection_filter.h"
#include "ui/events/ozone/evdev/touch_filter/shared_palm_detection_filter_state.h"
namespace ui {
class HeuristicStylusPalmDetectionFilterTest : public testing::Test {
public:
HeuristicStylusPalmDetectionFilterTest() = default;
HeuristicStylusPalmDetectionFilterTest(
const HeuristicStylusPalmDetectionFilterTest&) = delete;
HeuristicStylusPalmDetectionFilterTest& operator=(
const HeuristicStylusPalmDetectionFilterTest&) = delete;
void SetUp() override {
shared_palm_state = std::make_unique<SharedPalmDetectionFilterState>();
palm_detection_filter_ =
std::make_unique<HeuristicStylusPalmDetectionFilter>(
shared_palm_state.get(), hold_sample_count, hold_time,
suppress_time);
touches_.resize(kNumTouchEvdevSlots);
test_start_time_ = base::TimeTicks::Now();
}
protected:
const int hold_sample_count = 5;
const base::TimeDelta hold_time = base::Seconds(1.0);
const base::TimeDelta suppress_time = base::Seconds(0.4);
const base::TimeDelta sample_interval = base::Milliseconds(7.5);
std::unique_ptr<SharedPalmDetectionFilterState> shared_palm_state;
std::unique_ptr<PalmDetectionFilter> palm_detection_filter_;
std::vector<InProgressTouchEvdev> touches_;
base::TimeTicks test_start_time_;
};
class HeuristicStylusPalmDetectionFilterDeathTest
: public HeuristicStylusPalmDetectionFilterTest {};
TEST_F(HeuristicStylusPalmDetectionFilterDeathTest, TestDCheck) {
// We run with a time where hold_time < suppress_time, which should DCHECK.
EXPECT_DCHECK_DEATH(palm_detection_filter_ =
std::make_unique<HeuristicStylusPalmDetectionFilter>(
shared_palm_state.get(), hold_sample_count,
hold_time, hold_time + base::Milliseconds(0.1)));
}
TEST_F(HeuristicStylusPalmDetectionFilterTest, TestSetsToZero) {
std::bitset<kNumTouchEvdevSlots> suppress, hold;
suppress.set(kNumTouchEvdevSlots - 1, true);
hold.set(0, true);
palm_detection_filter_->Filter(touches_, test_start_time_, &hold, &suppress);
EXPECT_TRUE(hold.none());
EXPECT_TRUE(suppress.none());
}
TEST_F(HeuristicStylusPalmDetectionFilterTest, TestCancelAfterStylus) {
touches_[0].touching = true;
touches_[0].tool_code = BTN_TOOL_PEN;
std::bitset<kNumTouchEvdevSlots> suppress, hold;
// Set Palm as test_start_time_;
palm_detection_filter_->Filter(touches_, test_start_time_, &hold, &suppress);
EXPECT_TRUE(hold.none());
EXPECT_TRUE(suppress.none());
// Now, lets start two touches 7.5ms afterwards.
touches_[0].tool_code = 0;
touches_[1].touching = true;
base::TimeTicks start_time = test_start_time_ + sample_interval;
palm_detection_filter_->Filter(touches_, start_time, &hold, &suppress);
// expect none held, 0 and 1 cancelled, and others untouched.
EXPECT_TRUE(hold.none());
EXPECT_TRUE(suppress.test(0));
EXPECT_TRUE(suppress.test(1));
suppress.reset(0);
suppress.reset(1);
EXPECT_TRUE(suppress.none());
// Now, what if we keep going with these strokes for a long time.
for (; start_time < test_start_time_ + base::Milliseconds(1000);
start_time += sample_interval) {
palm_detection_filter_->Filter(touches_, start_time, &hold, &suppress);
EXPECT_TRUE(hold.none());
EXPECT_TRUE(suppress.test(0));
EXPECT_TRUE(suppress.test(1));
suppress.reset(0);
suppress.reset(1);
EXPECT_TRUE(suppress.none());
}
}
TEST_F(HeuristicStylusPalmDetectionFilterTest, TestHoldAfterStylus) {
touches_[0].touching = true;
touches_[0].tool_code = BTN_TOOL_PEN;
std::bitset<kNumTouchEvdevSlots> suppress, hold;
// Set Palm as test_start_time_;
palm_detection_filter_->Filter(touches_, test_start_time_, &hold, &suppress);
EXPECT_TRUE(hold.none());
EXPECT_TRUE(suppress.none());
EXPECT_EQ(0u, shared_palm_state->active_finger_touches);
// Now, lets start two touches a little before end of hold time.
touches_[0].tool_code = 0;
touches_[1].touching = true;
base::TimeTicks start_time =
test_start_time_ + hold_time - (hold_sample_count - 2) * sample_interval;
palm_detection_filter_->Filter(touches_, start_time, &hold, &suppress);
EXPECT_TRUE(suppress.none());
EXPECT_TRUE(hold.test(0));
EXPECT_TRUE(hold.test(1));
hold.reset(0);
hold.reset(1);
EXPECT_TRUE(hold.none());
for (int i = 0; i < 10; ++i) {
start_time += sample_interval;
palm_detection_filter_->Filter(touches_, start_time, &hold, &suppress);
EXPECT_TRUE(suppress.none());
// We've already held one item, so we expect 1 - the sample count to get
// held. Note that 1 of these falls _after_ the overall hold time, but we
// hold it since we depend on touch start.
if (i < hold_sample_count - 1) {
EXPECT_TRUE(hold.test(0)) << "Failed at i = " << i;
EXPECT_TRUE(hold.test(1)) << "Failed at i = " << i;
hold.reset(0);
hold.reset(1);
EXPECT_TRUE(hold.none());
ASSERT_EQ(0u, shared_palm_state->active_finger_touches)
<< " Failed at i = " << i;
} else {
ASSERT_EQ(2u, shared_palm_state->active_finger_touches)
<< " Failed at i = " << i;
EXPECT_TRUE(hold.none());
}
}
}
TEST_F(HeuristicStylusPalmDetectionFilterTest, TestNothingLongAfterStylus) {
touches_[0].touching = true;
touches_[0].tool_code = BTN_TOOL_PEN;
std::bitset<kNumTouchEvdevSlots> suppress, hold;
// Set Palm as test_start_time_;
palm_detection_filter_->Filter(touches_, test_start_time_, &hold, &suppress);
EXPECT_TRUE(hold.none());
EXPECT_TRUE(suppress.none());
touches_[0].tool_code = 0;
touches_[1].touching = true;
base::TimeTicks start_time =
test_start_time_ + hold_time + base::Milliseconds(1e-2);
palm_detection_filter_->Filter(touches_, start_time, &hold, &suppress);
EXPECT_EQ(2u, shared_palm_state->active_finger_touches);
EXPECT_TRUE(hold.none());
EXPECT_TRUE(suppress.none());
}
TEST_F(HeuristicStylusPalmDetectionFilterTest, TestHover) {
touches_[0].touching = false;
touches_[0].tool_code = BTN_TOOL_PEN;
std::bitset<kNumTouchEvdevSlots> suppress, hold;
// Set Palm as test_start_time_;
palm_detection_filter_->Filter(touches_, test_start_time_, &hold, &suppress);
EXPECT_TRUE(hold.none());
EXPECT_TRUE(suppress.none());
// Now, do we filter a finger?
touches_[0].tool_code = 0;
touches_[0].touching = true;
base::TimeTicks start_time =
test_start_time_ + hold_time - base::Milliseconds(1e-2);
palm_detection_filter_->Filter(touches_, start_time, &hold, &suppress);
EXPECT_TRUE(hold.test(0));
EXPECT_TRUE(suppress.none());
hold.reset(0);
EXPECT_TRUE(hold.none());
}
} // namespace ui