Commit 1b217d23 authored by Findit's avatar Findit

Revert "Add PalmDetectionFilter and 2 initial implemenations."

This reverts commit afca3680.

Reason for revert:

Findit (https://goo.gl/kROfz5) identified CL at revision 680248 as the
culprit for failures in the build cycles as shown on:
https://analysis.chromium.org/waterfall/culprit?key=ag9zfmZpbmRpdC1mb3ItbWVyRAsSDVdmU3VzcGVjdGVkQ0wiMWNocm9taXVtL2FmY2EzNjgwOGUxMTIyYzEzZDk2ZjhkMDQyZjA1OGY0NDgxZGZlYzEM

Sample Failed Build: https://ci.chromium.org/buildbot/chromium.linux/Cast%20Linux/77963

Sample Failed Step: events_unittests

Original change's description:
> Add PalmDetectionFilter and 2 initial implemenations.
> 
> This adds a palm detection filter that interacts with the concept of
> "held" items. The filters will be used in TouchEventConverterEvdev to
> either hold or cancel touches, in addition to the behavior from device
> firmware.
> 
> The two implementations are:
> 1. An always "open" detection, that doesn't mark anything to hold/cancel.
> 2. A simple heuristic that is based on interaction with stylus touches.
> 
> Both implementations have unit tests that cover 100% of the code.
> 
> 
> Bug: 982118
> Change-Id: I9f50b98be434ba5c767d9392c0a470262cf5e603
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1708148
> Reviewed-by: Michael Spang <spang@chromium.org>
> Commit-Queue: Rob Schonberger <robsc@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#680248}


Change-Id: I898da8f080c3b007e542918e74602750044c2af2
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 982118
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1716389
Cr-Commit-Position: refs/heads/master@{#680289}
parent b758c4b4
......@@ -618,8 +618,6 @@ if (!is_ios) {
"ozone/evdev/testing/fake_cursor_delegate_evdev.h",
"ozone/evdev/touch_event_converter_evdev_unittest.cc",
"ozone/evdev/touch_filter/false_touch_finder_unittest.cc",
"ozone/evdev/touch_filter/heuristic_stylus_palm_detection_filter_unittest.cc",
"ozone/evdev/touch_filter/open_palm_detection_filter_unittest.cc",
"ozone/gamepad/generic_gamepad_mapping_unittest.cc",
]
......
......@@ -116,17 +116,10 @@ if (use_ozone) {
"evdev/touch_filter/false_touch_finder.h",
"evdev/touch_filter/far_apart_taps_touch_noise_filter.cc",
"evdev/touch_filter/far_apart_taps_touch_noise_filter.h",
"evdev/touch_filter/heuristic_stylus_palm_detection_filter.cc",
"evdev/touch_filter/heuristic_stylus_palm_detection_filter.h",
"evdev/touch_filter/horizontally_aligned_touch_noise_filter.cc",
"evdev/touch_filter/horizontally_aligned_touch_noise_filter.h",
"evdev/touch_filter/low_pressure_filter.cc",
"evdev/touch_filter/low_pressure_filter.h",
"evdev/touch_filter/open_palm_detection_filter.cc",
"evdev/touch_filter/open_palm_detection_filter.h",
"evdev/touch_filter/palm_detection_filter.cc",
"evdev/touch_filter/palm_detection_filter.h",
"evdev/touch_filter/shared_palm_detection_filter_state.h",
"evdev/touch_filter/single_position_touch_noise_filter.cc",
"evdev/touch_filter/single_position_touch_noise_filter.h",
"evdev/touch_filter/touch_filter.h",
......
// 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>
namespace ui {
void HeuristicStylusPalmDetectionFilter::Filter(
const std::vector<InProgressTouchEvdev>& touches,
base::TimeTicks time,
std::bitset<kNumTouchEvdevSlots>* slots_to_hold,
std::bitset<kNumTouchEvdevSlots>* slots_to_suppress) {
slots_to_hold->reset();
slots_to_suppress->reset();
base::TimeTicks latest_stylus_time =
shared_palm_state_->latest_stylus_touch_time_;
for (int i = 0; i < kNumTouchEvdevSlots; ++i) {
const auto& touch = touches[i];
if (touch.tool_code == BTN_TOOL_PEN) {
// We detect BTN_TOOL_PEN whenever a pen is even hovering. This is
// mutually exclusive with finger touches, which is what we're interested
// in. So we update latest_time.
shared_palm_state_->latest_stylus_touch_time_ = time;
return;
}
if (!touch.touching) {
stroke_length_[i] = 0;
continue;
}
if (stroke_length_[i] == 0) {
// new touch!
touch_started_time_[i] = time;
}
stroke_length_[i]++;
base::TimeDelta time_since_stylus_for_touch_start =
touch_started_time_[i] - latest_stylus_time;
if (time_since_stylus_for_touch_start < time_after_stylus_to_cancel_) {
slots_to_suppress->set(i, 1);
} else if (time_since_stylus_for_touch_start < time_after_stylus_to_hold_ &&
stroke_length_[i] <= hold_stroke_count_) {
slots_to_hold->set(i, 1);
}
}
}
HeuristicStylusPalmDetectionFilter::HeuristicStylusPalmDetectionFilter(
SharedPalmDetectionFilterState* shared_palm_state,
int hold_stroke_count,
base::TimeDelta hold,
base::TimeDelta cancel)
: PalmDetectionFilter(shared_palm_state),
hold_stroke_count_(hold_stroke_count),
time_after_stylus_to_hold_(hold),
time_after_stylus_to_cancel_(cancel) {
touch_started_time_.resize(kNumTouchEvdevSlots, base::TimeTicks::UnixEpoch());
stroke_length_.resize(kNumTouchEvdevSlots, 0);
DCHECK(hold >= cancel) << "Expected hold time to be longer than cancel time.";
}
HeuristicStylusPalmDetectionFilter::~HeuristicStylusPalmDetectionFilter() {}
} // namespace ui
// 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.
#ifndef UI_EVENTS_OZONE_EVDEV_TOUCH_FILTER_HEURISTIC_STYLUS_PALM_DETECTION_FILTER_H_
#define UI_EVENTS_OZONE_EVDEV_TOUCH_FILTER_HEURISTIC_STYLUS_PALM_DETECTION_FILTER_H_
#include <bitset>
#include <vector>
#include "base/time/time.h"
#include "ui/events/ozone/evdev/touch_evdev_types.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 {
// A heuristic implementation of PalmDetectionFilter.
// Relies on firmware palm detection, but modifies behavior _after_ a stylus
// touch since our mutual-exclusion of stylus/touch means that we do not trust
// the device right after stylus.
// Configured with 3 inputs:
// 1. How many strokes to hold on to when holding.
// 2. TimeDelta for cancellation: any strokes started within this delta are
// cancelled automatically.
// 3. TimeDelta for hold: any strokes started after the cancellation and before
// this are held for the stroke count (as above). If they're cancelled
// externally, we never report them. If they terminate before the count, we
// output all items.
class EVENTS_OZONE_EVDEV_EXPORT HeuristicStylusPalmDetectionFilter
: public PalmDetectionFilter {
public:
HeuristicStylusPalmDetectionFilter(
SharedPalmDetectionFilterState* shared_palm_state,
int hold_stroke_count,
base::TimeDelta hold,
base::TimeDelta cancel);
~HeuristicStylusPalmDetectionFilter() override;
void Filter(const std::vector<InProgressTouchEvdev>& touches,
base::TimeTicks time,
std::bitset<kNumTouchEvdevSlots>* slots_to_hold,
std::bitset<kNumTouchEvdevSlots>* slots_to_suppress) override;
private:
const int hold_stroke_count_;
const base::TimeDelta time_after_stylus_to_hold_;
const base::TimeDelta time_after_stylus_to_cancel_;
std::vector<base::TimeTicks> touch_started_time_;
// How many items have we seen in this stroke so far?
std::vector<int> stroke_length_;
DISALLOW_COPY_AND_ASSIGN(HeuristicStylusPalmDetectionFilter);
};
} // namespace ui
#endif // UI_EVENTS_OZONE_EVDEV_TOUCH_FILTER_HEURISTIC_STYLUS_PALM_DETECTION_FILTER_H_
// 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 "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;
void SetUp() override {
shared_palm_state.reset(new SharedPalmDetectionFilterState);
palm_detection_filter_.reset(new 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::TimeDelta::FromSecondsD(1.0);
const base::TimeDelta suppress_time = base::TimeDelta::FromSecondsD(0.4);
const base::TimeDelta sample_interval =
base::TimeDelta::FromMillisecondsD(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_;
DISALLOW_COPY_AND_ASSIGN(HeuristicStylusPalmDetectionFilterTest);
};
class HeuristicStylusPalmDetectionFilterDeathTest
: public HeuristicStylusPalmDetectionFilterTest {};
TEST_F(HeuristicStylusPalmDetectionFilterDeathTest, TestDCheck) {
// We run with a time where hold_time < suppress_time, which should DCHECK.
EXPECT_DEATH(
palm_detection_filter_.reset(new HeuristicStylusPalmDetectionFilter(
shared_palm_state.get(), hold_sample_count, hold_time,
hold_time + base::TimeDelta::FromMillisecondsD(0.1))),
"Expected hold time to be longer than cancel time.");
}
TEST_F(HeuristicStylusPalmDetectionFilterTest, TestSetsToZero) {
std::bitset<kNumTouchEvdevSlots> suppress, hold;
suppress.set(kNumTouchEvdevSlots - 1, 1);
hold.set(0, 1);
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::TimeDelta::FromMillisecondsD(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());
// 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());
} else {
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::TimeDelta::FromMillisecondsD(1e-2);
palm_detection_filter_->Filter(touches_, start_time, &hold, &suppress);
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::TimeDelta::FromMillisecondsD(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
// 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/open_palm_detection_filter.h"
namespace ui {
OpenPalmDetectionFilter::OpenPalmDetectionFilter(
SharedPalmDetectionFilterState* shared_palm_state)
: PalmDetectionFilter(shared_palm_state) {}
void OpenPalmDetectionFilter::Filter(
const std::vector<InProgressTouchEvdev>& touches,
base::TimeTicks time,
std::bitset<kNumTouchEvdevSlots>* slots_to_hold,
std::bitset<kNumTouchEvdevSlots>* slots_to_suppress) {
slots_to_hold->reset();
slots_to_suppress->reset();
}
OpenPalmDetectionFilter::~OpenPalmDetectionFilter() {}
} // namespace ui
// 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.
#ifndef UI_EVENTS_OZONE_EVDEV_TOUCH_FILTER_OPEN_PALM_DETECTION_FILTER_H_
#define UI_EVENTS_OZONE_EVDEV_TOUCH_FILTER_OPEN_PALM_DETECTION_FILTER_H_
#include <bitset>
#include <vector>
#include "base/time/time.h"
#include "ui/events/ozone/evdev/touch_evdev_types.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 {
// A simple implementation of PalmDetectionFilter.
// Does not delay or set anything to palm.
class EVENTS_OZONE_EVDEV_EXPORT OpenPalmDetectionFilter
: public PalmDetectionFilter {
public:
explicit OpenPalmDetectionFilter(
SharedPalmDetectionFilterState* shared_palm_state);
~OpenPalmDetectionFilter() override;
void Filter(const std::vector<InProgressTouchEvdev>& touches,
base::TimeTicks time,
std::bitset<kNumTouchEvdevSlots>* slots_to_hold,
std::bitset<kNumTouchEvdevSlots>* slots_to_suppress) override;
private:
DISALLOW_COPY_AND_ASSIGN(OpenPalmDetectionFilter);
};
} // namespace ui
#endif // UI_EVENTS_OZONE_EVDEV_TOUCH_FILTER_OPEN_PALM_DETECTION_FILTER_H_
// 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/open_palm_detection_filter.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 OpenPalmDetectionFilterTest : public testing::Test {
public:
OpenPalmDetectionFilterTest() = default;
void SetUp() override {
shared_palm_state.reset(new SharedPalmDetectionFilterState);
palm_detection_filter_.reset(
new OpenPalmDetectionFilter(shared_palm_state.get()));
}
protected:
std::unique_ptr<SharedPalmDetectionFilterState> shared_palm_state;
std::unique_ptr<PalmDetectionFilter> palm_detection_filter_;
DISALLOW_COPY_AND_ASSIGN(OpenPalmDetectionFilterTest);
};
TEST_F(OpenPalmDetectionFilterTest, TestSetsToZero) {
std::bitset<kNumTouchEvdevSlots> suppress, hold;
suppress.set(kNumTouchEvdevSlots - 1, 1);
hold.set(0, 1);
std::vector<InProgressTouchEvdev> inputs;
inputs.resize(kNumTouchEvdevSlots);
palm_detection_filter_->Filter(inputs, base::TimeTicks::Now(), &hold,
&suppress);
EXPECT_TRUE(hold.none());
EXPECT_TRUE(suppress.none());
}
} // namespace ui
// 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/palm_detection_filter.h"
namespace ui {
PalmDetectionFilter::PalmDetectionFilter(
SharedPalmDetectionFilterState* shared_palm_state)
: shared_palm_state_(shared_palm_state) {
DCHECK(shared_palm_state != nullptr);
}
PalmDetectionFilter::~PalmDetectionFilter() {}
} // namespace ui
// 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.
#ifndef UI_EVENTS_OZONE_EVDEV_TOUCH_FILTER_PALM_DETECTION_FILTER_H_
#define UI_EVENTS_OZONE_EVDEV_TOUCH_FILTER_PALM_DETECTION_FILTER_H_
#include <bitset>
#include <vector>
#include "base/time/time.h"
#include "ui/events/ozone/evdev/touch_evdev_types.h"
#include "ui/events/ozone/evdev/touch_filter/shared_palm_detection_filter_state.h"
namespace ui {
// An abstract palm detection filter. It has two functions:
// 1. To decide which touches to "hold"
// 2. To decide which touches to suppress / "cancel".
// Interface is similar to that of TouchFilter but enshrines the "hold" as a
// first class citizen.
class EVENTS_OZONE_EVDEV_EXPORT PalmDetectionFilter {
public:
// shared_palm_state is not owned!
explicit PalmDetectionFilter(
SharedPalmDetectionFilterState* shared_palm_state);
// Execute a filter event. Expected to be executed on every update to touches.
// Arguments are:
// 1. touches: a vector of kNumTouchEvdevSlots touches.
// 2. time: the latest event time in touches.
// 3. slots_to_hold: output bitset of slots to hold. Must not be null.
// 4. slots_to_suppress: output bitset of slots to suppress/cancel. Must not
// be null.
//
// Note that if a slot is marked as both suppress and hold, we expect the
// suppress to override the hold.
virtual void Filter(const std::vector<InProgressTouchEvdev>& touches,
base::TimeTicks time,
std::bitset<kNumTouchEvdevSlots>* slots_to_hold,
std::bitset<kNumTouchEvdevSlots>* slots_to_suppress) = 0;
virtual ~PalmDetectionFilter();
protected:
// Not owned!
SharedPalmDetectionFilterState* shared_palm_state_;
};
} // namespace ui
#endif // UI_EVENTS_OZONE_EVDEV_TOUCH_FILTER_PALM_DETECTION_FILTER_H_
// 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.
#ifndef UI_EVENTS_OZONE_EVDEV_TOUCH_FILTER_SHARED_PALM_DETECTION_FILTER_STATE_H_
#define UI_EVENTS_OZONE_EVDEV_TOUCH_FILTER_SHARED_PALM_DETECTION_FILTER_STATE_H_
#include "base/time/time.h"
namespace ui {
struct SharedPalmDetectionFilterState {
// The latest stylus touch time. Note that this can include "hover".
base::TimeTicks latest_stylus_touch_time_ = base::TimeTicks::UnixEpoch();
};
} // namespace ui
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment