summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarry Cutts <hcutts@google.com>2024-03-13 15:10:32 +0000
committerHarry Cutts <hcutts@google.com>2024-03-13 15:26:07 +0000
commit6ec93b19a1b8ed00a228299db08c33fbed268d7e (patch)
tree80174cb1645877863c3d48298a5683a8adc109a0
parent0e7b5cb11ffdf27df6e5ef512fb71a9e134ecc9a (diff)
parentb824af1e782a4e741fbfe4b0c311de3bc161e2fc (diff)
downloadlibchrome-gestures-main.tar.gz
Merge various clean-ups from upstreamHEADmastermain
The only functionality change here is to mouse scroll handling, which won't affect Android as we don't use the library for mice. The other changes are assorted cleanups including for variable-length array issues, address sanitizer crashes, and various other small code issues. Bug: 314743031 Test: Treehugger Change-Id: I8655f873a13a9ba3b8ef437246c0c368f8bd1b76
-rw-r--r--METADATA4
-rw-r--r--Makefile12
-rw-r--r--include/finger_metrics.h6
-rw-r--r--include/immediate_interpreter.h1
-rw-r--r--include/mouse_interpreter.h17
-rw-r--r--include/string_util.h33
-rw-r--r--include/util.h11
-rw-r--r--src/activity_log.cc2
-rw-r--r--src/activity_replay_unittest.cc36
-rw-r--r--src/command_line.cc4
-rw-r--r--src/finger_metrics.cc26
-rw-r--r--src/gestures.cc7
-rw-r--r--src/gestures_unittest.cc13
-rw-r--r--src/iir_filter_interpreter.cc12
-rw-r--r--src/immediate_interpreter.cc205
-rw-r--r--src/immediate_interpreter_unittest.cc22
-rw-r--r--src/interpreter_unittest.cc162
-rw-r--r--src/lookahead_filter_interpreter.cc6
-rw-r--r--src/mouse_interpreter.cc72
-rw-r--r--src/mouse_interpreter_unittest.cc3
-rw-r--r--src/non_linearity_filter_interpreter.cc8
-rw-r--r--src/prop_registry.cc24
-rw-r--r--src/string_util.cc81
-rw-r--r--src/string_util_unittest.cc23
-rw-r--r--tools/touchtests-report.json7
25 files changed, 402 insertions, 395 deletions
diff --git a/METADATA b/METADATA
index c2fe6b5..4ab2fc3 100644
--- a/METADATA
+++ b/METADATA
@@ -6,7 +6,7 @@ third_party {
type: GIT
value: "https://chromium.googlesource.com/chromiumos/platform/gestures/"
}
- version: "b31ef0adcaff61c045e95158cb9720543b42b531"
- last_upgrade_date { year: 2023 month: 12 day: 13 }
+ version: "b824af1e782a4e741fbfe4b0c311de3bc161e2fc"
+ last_upgrade_date { year: 2024 month: 3 day: 13 }
license_type: NOTICE
}
diff --git a/Makefile b/Makefile
index d04ce98..9adcf1e 100644
--- a/Makefile
+++ b/Makefile
@@ -129,6 +129,15 @@ CXXFLAGS+=\
-DGESTURES_INTERNAL=1 \
-I.
+ifeq (yes,$(SANITIZE_GESTURES))
+CXXFLAGS+=\
+ -fsanitize=address,undefined \
+ -fno-sanitize-recover=all
+LINK_FLAGS+=\
+ -fsanitize=address,undefined \
+ -fno-sanitize-recover=all
+endif
+
# Local compilation needs these flags, esp for code coverage testing
ifeq (g++,$(CXX))
CXXFLAGS+=\
@@ -138,9 +147,6 @@ CXXFLAGS+=\
-ftest-coverage \
-fprofile-arcs
LINK_FLAGS+=-lgcov
-else
-CXXFLAGS+=\
- -DXLOGGING
endif
PKG_CONFIG ?= pkg-config
diff --git a/include/finger_metrics.h b/include/finger_metrics.h
index 1773a94..c1f33dd 100644
--- a/include/finger_metrics.h
+++ b/include/finger_metrics.h
@@ -6,10 +6,10 @@
#define GESTURES_FINGER_METRICS_H_
#include <cmath>
+#include <vector>
#include "include/gestures.h"
#include "include/prop_registry.h"
-#include "include/vector.h"
namespace gestures {
@@ -130,7 +130,7 @@ class Metrics {
// A collection of FingerMetrics describing the current hardware state.
// The collection is sorted to yield the oldest finger first.
- vector<FingerMetrics, kMaxFingers>& fingers() { return fingers_; }
+ std::vector<FingerMetrics>& fingers() { return fingers_; }
// Find a FingerMetrics instance by it's tracking id.
// Returns nullptr if not found.
@@ -156,7 +156,7 @@ class Metrics {
void SetFingerOriginTimestampForTesting(short tracking_id, stime_t time);
private:
- vector<FingerMetrics, kMaxFingers> fingers_;
+ std::vector<FingerMetrics> fingers_;
MetricsProperties* properties_;
std::unique_ptr<MetricsProperties> own_properties_;
diff --git a/include/immediate_interpreter.h b/include/immediate_interpreter.h
index 1be420e..7f2aa52 100644
--- a/include/immediate_interpreter.h
+++ b/include/immediate_interpreter.h
@@ -13,6 +13,7 @@
#include "include/macros.h"
#include "include/prop_registry.h"
#include "include/tracer.h"
+#include "include/vector.h"
#ifndef GESTURES_IMMEDIATE_INTERPRETER_H_
#define GESTURES_IMMEDIATE_INTERPRETER_H_
diff --git a/include/mouse_interpreter.h b/include/mouse_interpreter.h
index e56be37..d1e12a3 100644
--- a/include/mouse_interpreter.h
+++ b/include/mouse_interpreter.h
@@ -45,9 +45,9 @@ class MouseInterpreter : public Interpreter, public PropertyDelegate {
bool EmulateScrollWheel(const HardwareState& hwstate);
private:
struct WheelRecord {
- WheelRecord(float v, stime_t t): value(v), timestamp(t) {}
- WheelRecord(): value(0), timestamp(0) {}
- float value;
+ WheelRecord(float v, stime_t t): change(v), timestamp(t) {}
+ WheelRecord(): change(0), timestamp(0) {}
+ float change;
stime_t timestamp;
};
@@ -60,8 +60,8 @@ class MouseInterpreter : public Interpreter, public PropertyDelegate {
HardwareState prev_state_;
- // Records last scroll wheel event.
- WheelRecord last_wheel_, last_hwheel_;
+ // Records last scroll wheel events.
+ std::vector<WheelRecord> last_vertical_wheels_, last_horizontal_wheels_;
// Accumulators to measure scroll distance while doing scroll wheel emulation
double wheel_emulation_accu_x_;
@@ -85,6 +85,13 @@ class MouseInterpreter : public Interpreter, public PropertyDelegate {
// Enable high-resolution scrolling.
BoolProperty hi_res_scrolling_;
+ // When calculating scroll velocity for the purpose of acceleration, we
+ // use the average of this many events in the same direction. This is to avoid
+ // over-accelerating if we receive batched events with timestamps that are
+ // artificially close. If we don't have enough events, we won't accelerate at
+ // all.
+ IntProperty scroll_velocity_buffer_size_;
+
// We use normal CDF to simulate scroll wheel acceleration curve. Use the
// following method to generate the coefficients of a degree-4 polynomial
// regression for a specific normal cdf in Python.
diff --git a/include/string_util.h b/include/string_util.h
index 6e1a4ba..67fda6c 100644
--- a/include/string_util.h
+++ b/include/string_util.h
@@ -21,36 +21,9 @@ std::string StringPrintf(const char* format, ...)
void StringAppendV(std::string* dst, const char* format, va_list ap)
PRINTF_FORMAT(2, 0);
-// Trims any whitespace from either end of the input string. Returns where
-// whitespace was found.
-// The non-wide version has two functions:
-// * TrimWhitespaceASCII()
-// This function is for ASCII strings and only looks for ASCII whitespace;
-// Please choose the best one according to your usage.
-// NOTE: Safe to use the same variable for both input and output.
-enum TrimPositions {
- TRIM_NONE = 0,
- TRIM_LEADING = 1 << 0,
- TRIM_TRAILING = 1 << 1,
- TRIM_ALL = TRIM_LEADING | TRIM_TRAILING,
-};
-TrimPositions TrimWhitespaceASCII(const std::string& input,
- TrimPositions positions,
- std::string* output);
-
-// Returns true if str starts with search, or false otherwise.
-bool StartsWithASCII(const std::string& str,
- const std::string& search,
- bool case_sensitive);
-
-// |str| should not be in a multi-byte encoding like Shift-JIS or GBK in which
-// the trailing byte of a multi-byte character can be in the ASCII range.
-// UTF-8, and other single/multi-byte ASCII-compatible encodings are OK.
-// Note: |c| must be in the ASCII range.
-void SplitString(const std::string& str,
- char c,
- std::vector<std::string>* r);
-
+// Trims whitespace from the start and end of the input string. This function
+// is for ASCII strings and only looks for ASCII whitespace.
+std::string TrimWhitespaceASCII(const std::string& input);
} // namespace gestures
diff --git a/include/util.h b/include/util.h
index f0c2a39..9371327 100644
--- a/include/util.h
+++ b/include/util.h
@@ -8,6 +8,7 @@
#include <list>
#include <map>
#include <set>
+#include <vector>
#include <math.h>
@@ -78,14 +79,14 @@ void RemoveMissingIdsFromMap(std::map<short, Data>* the_map,
static inline
void RemoveMissingIdsFromSet(std::set<short>* the_set,
const HardwareState& hs) {
- short old_ids[the_set->size() + 1];
- size_t old_ids_len = 0;
+ std::vector<short> old_ids;
+ old_ids.reserve(the_set->size() + 1);
for (typename std::set<short>::const_iterator it = the_set->begin();
it != the_set->end(); ++it)
if (!hs.GetFingerState(*it))
- old_ids[old_ids_len++] = *it;
- for (size_t i = 0; i < old_ids_len; i++)
- the_set->erase(old_ids[i]);
+ old_ids.push_back(*it);
+ for (auto id : old_ids)
+ the_set->erase(id);
}
template<typename Set, typename Elt>
diff --git a/src/activity_log.cc b/src/activity_log.cc
index 9e6bfbf..d668f9c 100644
--- a/src/activity_log.cc
+++ b/src/activity_log.cc
@@ -579,7 +579,7 @@ void ActivityLog::AddEncodeInfo(Json::Value* root) {
string gestures_version = VCSID;
// Strip tailing whitespace.
- TrimWhitespaceASCII(gestures_version, TRIM_ALL, &gestures_version);
+ gestures_version = TrimWhitespaceASCII(gestures_version);
(*root)["gesturesVersion"] = Json::Value(gestures_version);
(*root)[kKeyProperties] = EncodePropRegistry();
}
diff --git a/src/activity_replay_unittest.cc b/src/activity_replay_unittest.cc
index ef75491..0dd2879 100644
--- a/src/activity_replay_unittest.cc
+++ b/src/activity_replay_unittest.cc
@@ -20,6 +20,42 @@ using std::string;
namespace gestures {
+namespace {
+
+template <typename STR>
+void SplitStringT(const STR& str,
+ const typename STR::value_type s,
+ bool trim_whitespace,
+ std::vector<STR>* r) {
+ r->clear();
+ size_t last = 0;
+ size_t c = str.size();
+ for (size_t i = 0; i <= c; ++i) {
+ if (i == c || str[i] == s) {
+ STR tmp(str, last, i - last);
+ if (trim_whitespace)
+ tmp = TrimWhitespaceASCII(tmp);
+ // Avoid converting an empty or all-whitespace source string into a vector
+ // of one empty string.
+ if (i != c || !r->empty() || !tmp.empty())
+ r->push_back(tmp);
+ last = i + 1;
+ }
+ }
+}
+
+// |str| should not be in a multi-byte encoding like Shift-JIS or GBK in which
+// the trailing byte of a multi-byte character can be in the ASCII range.
+// UTF-8, and other single/multi-byte ASCII-compatible encodings are OK.
+// Note: |c| must be in the ASCII range.
+void SplitString(const std::string& str,
+ char c,
+ std::vector<std::string>* r) {
+ SplitStringT(str, c, true, r);
+}
+
+} // namespace
+
class ActivityReplayTest : public ::testing::Test {};
// This test reads a log file and replays it. This test should be enabled for a
diff --git a/src/command_line.cc b/src/command_line.cc
index 7f309a2..2779b13 100644
--- a/src/command_line.cc
+++ b/src/command_line.cc
@@ -59,7 +59,7 @@ void AppendSwitchesAndArguments(CommandLine& command_line,
bool parse_switches = true;
for (size_t i = 1; i < argv.size(); ++i) {
std::string arg = argv[i];
- TrimWhitespaceASCII(arg, TRIM_ALL, &arg);
+ arg = TrimWhitespaceASCII(arg);
std::string switch_string;
std::string switch_value;
@@ -131,7 +131,7 @@ std::string CommandLine::GetProgram() const {
}
void CommandLine::SetProgram(const std::string& program) {
- TrimWhitespaceASCII(program, TRIM_ALL, &argv_[0]);
+ argv_[0] = TrimWhitespaceASCII(program);
}
bool CommandLine::HasSwitch(const std::string& switch_string) const {
diff --git a/src/finger_metrics.cc b/src/finger_metrics.cc
index a79ea10..4215196 100644
--- a/src/finger_metrics.cc
+++ b/src/finger_metrics.cc
@@ -76,14 +76,17 @@ bool Metrics::CloseEnoughToGesture(const Vector2& pos_a,
< vert_axis_sq * horiz_axis_sq;
}
-Metrics::Metrics(MetricsProperties* properties) : properties_(properties) {}
+Metrics::Metrics(MetricsProperties* properties) : properties_(properties) {
+ fingers_.reserve(kMaxFingers);
+}
const FingerMetrics* Metrics::GetFinger(short tracking_id) const {
- auto iter = fingers_.find(FingerMetrics(tracking_id));
- if (iter != fingers_.end())
- return iter;
- else
- return nullptr;
+ for (auto iter = fingers_.cbegin(); iter != fingers_.cend(); ++iter) {
+ if(iter->tracking_id() == tracking_id) {
+ return &(*iter);
+ }
+ }
+ return nullptr;
}
const FingerMetrics* Metrics::GetFinger(const FingerState& state) const {
@@ -98,8 +101,7 @@ void Metrics::Update(const HardwareState& hwstate) {
// create metrics for new fingers
for (int i=0; i<hwstate.finger_cnt; ++i) {
const FingerState& state = hwstate.fingers[i];
- auto iter = fingers_.find(FingerMetrics(state.tracking_id));
- if (iter == fingers_.end()) {
+ if (GetFinger(state.tracking_id) == nullptr) {
fingers_.push_back(FingerMetrics(state,
hwstate.timestamp));
++new_count;
@@ -138,9 +140,11 @@ void Metrics::Clear() {
void Metrics::SetFingerOriginTimestampForTesting(short tracking_id,
stime_t time) {
- if (auto iter = fingers_.find(FingerMetrics(tracking_id));
- iter != fingers_.end()) {
- fingers_.erase(iter);
+ for (auto iter = fingers_.begin(); iter != fingers_.end(); ++iter) {
+ if(iter->tracking_id() == tracking_id) {
+ fingers_.erase(iter);
+ break;
+ }
}
fingers_.push_back(FingerMetrics(tracking_id, time));
}
diff --git a/src/gestures.cc b/src/gestures.cc
index b4d5271..cd49c68 100644
--- a/src/gestures.cc
+++ b/src/gestures.cc
@@ -42,7 +42,6 @@
using std::string;
using std::min;
using gestures::StringPrintf;
-using gestures::StartsWithASCII;
// C API:
@@ -135,9 +134,9 @@ string FingerState::FlagsString(unsigned flags) {
if (flags) {
// prepend remaining number
ret = StringPrintf("%u%s", flags, ret.c_str());
- } else if (StartsWithASCII(ret, kPipeSeparator, false)) {
+ } else if (ret.rfind(kPipeSeparator, 0) == 0) {
// strip extra pipe
- ret = string(ret.c_str() + strlen(kPipeSeparator));
+ ret = ret.substr(strlen(kPipeSeparator));
} else {
ret = "0";
}
@@ -507,7 +506,7 @@ void GestureInterpreter::SetTimerProvider(GesturesTimerProvider* tp,
interpret_timer_ = nullptr;
}
if (interpret_timer_)
- Log("How was interpret_timer_ not null?!");
+ Err("How was interpret_timer_ not null?!");
timer_provider_ = tp;
timer_provider_data_ = data;
if (timer_provider_)
diff --git a/src/gestures_unittest.cc b/src/gestures_unittest.cc
index 6b00902..b11a339 100644
--- a/src/gestures_unittest.cc
+++ b/src/gestures_unittest.cc
@@ -411,6 +411,19 @@ TEST(GesturesTest, StimeFromTimespecTest) {
EXPECT_DOUBLE_EQ(2000000000.999999999, StimeFromTimespec(&tv));
}
+TEST(GesturesTest, FingerStateFlagsStringTest) {
+ EXPECT_EQ("0", FingerState::FlagsString(0));
+ EXPECT_EQ("GESTURES_FINGER_PALM",
+ FingerState::FlagsString(GESTURES_FINGER_PALM));
+ EXPECT_EQ("GESTURES_FINGER_PALM | GESTURES_FINGER_WARP_X_MOVE",
+ FingerState::FlagsString(
+ GESTURES_FINGER_PALM | GESTURES_FINGER_WARP_X_MOVE));
+ // 1 << 31 probably won't be used as a finger flag value anytime soon, so use
+ // it to test prepending the remaining number.
+ EXPECT_EQ("2147483648 | GESTURES_FINGER_PALM",
+ FingerState::FlagsString(GESTURES_FINGER_PALM | (1 << 31)));
+}
+
TEST(GesturesTest, HardwareStateGetFingerStateTest) {
FingerState fs[] = {
{ 0, 0, 0, 0, 1, 0, 150, 4000, 4, 0 },
diff --git a/src/iir_filter_interpreter.cc b/src/iir_filter_interpreter.cc
index 5ea513d..84a1faf 100644
--- a/src/iir_filter_interpreter.cc
+++ b/src/iir_filter_interpreter.cc
@@ -5,6 +5,7 @@
#include "include/iir_filter_interpreter.h"
#include <utility>
+#include <vector>
namespace gestures {
@@ -57,14 +58,15 @@ void IirFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
LogHardwareStatePre(name, hwstate);
// Delete old entries from map
- short dead_ids[histories_.size() + 1];
- size_t dead_ids_len = 0;
+ std::vector<short> dead_ids;
+ dead_ids.reserve(histories_.size());
+
for (std::map<short, IoHistory>::iterator it = histories_.begin(),
e = histories_.end(); it != e; ++it)
if (!hwstate.GetFingerState((*it).first))
- dead_ids[dead_ids_len++] = (*it).first;
- for (size_t i = 0; i < dead_ids_len; ++i)
- histories_.erase(dead_ids[i]);
+ dead_ids.push_back((*it).first);
+ for (auto dead_id : dead_ids)
+ histories_.erase(dead_id);
// Modify current hwstate
for (size_t i = 0; i < hwstate.finger_cnt; i++) {
diff --git a/src/immediate_interpreter.cc b/src/immediate_interpreter.cc
index c1aa568..9f63427 100644
--- a/src/immediate_interpreter.cc
+++ b/src/immediate_interpreter.cc
@@ -11,6 +11,7 @@
#include <functional>
#include <limits>
#include <tuple>
+#include <vector>
#include "include/gestures.h"
#include "include/logging.h"
@@ -61,9 +62,7 @@ void TapRecord::NoteTouch(short the_id, const FingerState& fs) {
// New finger must be close enough to an existing finger
if (!touched_.empty()) {
bool reject_new_finger = true;
- for (std::map<short, FingerState>::const_iterator it =
- touched_.begin(), e = touched_.end(); it != e; ++it) {
- const FingerState& existing_fs = (*it).second;
+ for (const auto& [tracking_id, existing_fs] : touched_) {
if (immediate_interpreter_->metrics_->CloseEnoughToGesture(
Vector2(existing_fs),
Vector2(fs))) {
@@ -113,28 +112,26 @@ void TapRecord::Update(const HardwareState& hwstate,
else if (diff < 0)
t5r2_released_size_ += -diff;
}
- for (std::set<short>::const_iterator it = added.begin(),
- e = added.end(); it != e; ++it)
- Log("TapRecord::Update: Added: %d", *it);
- for (std::set<short>::const_iterator it = removed.begin(),
- e = removed.end(); it != e; ++it)
- Log("TapRecord::Update: Removed: %d", *it);
- for (std::set<short>::const_iterator it = dead.begin(),
- e = dead.end(); it != e; ++it)
- Log("TapRecord::Update: Dead: %d", *it);
+ for (short tracking_id : added) {
+ Log("TapRecord::Update: Added: %d", tracking_id);
+ }
+ for (short tracking_id: removed) {
+ Log("TapRecord::Update: Removed: %d", tracking_id);
+ }
+ for (short tracking_id : dead) {
+ Log("TapRecord::Update: Dead: %d", tracking_id);
+ }
for_each(dead.begin(), dead.end(),
bind(&TapRecord::Remove, this, std::placeholders::_1));
- for (std::set<short>::const_iterator it = added.begin(),
- e = added.end(); it != e; ++it)
- NoteTouch(*it, *hwstate.GetFingerState(*it));
+ for (short tracking_id : added) {
+ NoteTouch(tracking_id, *hwstate.GetFingerState(tracking_id));
+ }
for_each(removed.begin(), removed.end(),
bind(&TapRecord::NoteRelease, this, std::placeholders::_1));
// Check if min tap/cotap pressure met yet
const float cotap_min_pressure = CotapMinPressure();
- for (std::map<short, FingerState>::iterator it =
- touched_.begin(), e = touched_.end();
- it != e; ++it) {
- const FingerState* fs = hwstate.GetFingerState((*it).first);
+ for (auto& [tracking_id, existing_fs] : touched_) {
+ const FingerState* fs = hwstate.GetFingerState(tracking_id);
if (fs) {
if (fs->pressure >= immediate_interpreter_->tap_min_pressure() ||
!immediate_interpreter_->device_reports_pressure())
@@ -142,11 +139,11 @@ void TapRecord::Update(const HardwareState& hwstate,
if (fs->pressure >= cotap_min_pressure ||
!immediate_interpreter_->device_reports_pressure()) {
min_cotap_pressure_met_.insert(fs->tracking_id);
- if ((*it).second.pressure < cotap_min_pressure &&
+ if (existing_fs.pressure < cotap_min_pressure &&
immediate_interpreter_->device_reports_pressure()) {
// Update existing record, since the old one hadn't met the cotap
// pressure
- (*it).second = *fs;
+ existing_fs = *fs;
}
}
stime_t finger_age = hwstate.timestamp -
@@ -171,20 +168,19 @@ void TapRecord::Clear() {
bool TapRecord::Moving(const HardwareState& hwstate,
const float dist_max) const {
const float cotap_min_pressure = CotapMinPressure();
- for (std::map<short, FingerState>::const_iterator it =
- touched_.begin(), e = touched_.end(); it != e; ++it) {
- const FingerState* fs = hwstate.GetFingerState((*it).first);
+ for (const auto& [tracking_id, existing_fs] : touched_) {
+ const FingerState* fs = hwstate.GetFingerState(tracking_id);
if (!fs)
continue;
// Only look for moving when current frame meets cotap pressure and
// our history contains a contact that's met cotap pressure.
if ((fs->pressure < cotap_min_pressure ||
- (*it).second.pressure < cotap_min_pressure) &&
+ existing_fs.pressure < cotap_min_pressure) &&
immediate_interpreter_->device_reports_pressure())
continue;
// Compute distance moved
- float dist_x = fs->position_x - (*it).second.position_x;
- float dist_y = fs->position_y - (*it).second.position_y;
+ float dist_x = fs->position_x - existing_fs.position_x;
+ float dist_y = fs->position_y - existing_fs.position_y;
// Respect WARP flags
if (fs->flags & GESTURES_FINGER_WARP_X_TAP_MOVE)
dist_x = 0.0;
@@ -202,10 +198,9 @@ bool TapRecord::Moving(const HardwareState& hwstate,
bool TapRecord::Motionless(const HardwareState& hwstate, const HardwareState&
prev_hwstate, const float max_speed) const {
const float cotap_min_pressure = CotapMinPressure();
- for (std::map<short, FingerState>::const_iterator it =
- touched_.begin(), e = touched_.end(); it != e; ++it) {
- const FingerState* fs = hwstate.GetFingerState((*it).first);
- const FingerState* prev_fs = prev_hwstate.GetFingerState((*it).first);
+ for (const auto& [tracking_id, _] : touched_) {
+ const FingerState* fs = hwstate.GetFingerState(tracking_id);
+ const FingerState* prev_fs = prev_hwstate.GetFingerState(tracking_id);
if (!fs || !prev_fs)
continue;
// Only look for moving when current frame meets cotap pressure and
@@ -233,12 +228,12 @@ bool TapRecord::TapComplete() const {
ret = t5r2_touched_size_ && t5r2_touched_size_ == t5r2_released_size_;
else
ret = !touched_.empty() && (touched_.size() == released_.size());
- for (std::map<short, FingerState>::const_iterator
- it = touched_.begin(), e = touched_.end(); it != e; ++it)
- Log("TapRecord::TapComplete: touched_: %d", (*it).first);
- for (std::set<short>::const_iterator it = released_.begin(),
- e = released_.end(); it != e; ++it)
- Log("TapRecord::TapComplete: released_: %d", *it);
+ for (const auto& [tracking_id, finger_state] : touched_) {
+ Log("TapRecord::TapComplete: touched_: %d", tracking_id);
+ }
+ for (short tracking_id : released_) {
+ Log("TapRecord::TapComplete: released_: %d", tracking_id);
+ }
return ret;
}
@@ -457,10 +452,9 @@ bool ScrollManager::FillResultScroll(
float dy = 0.0;
bool stationary = true;
bool pressure_changing = false;
- for (FingerMap::const_iterator it =
- gs_fingers.begin(), e = gs_fingers.end(); it != e; ++it) {
- const FingerState* fs = state_buffer.Get(0).GetFingerState(*it);
- const FingerState* prev = state_buffer.Get(1).GetFingerState(*it);
+ for (short tracking_id : gs_fingers) {
+ const FingerState* fs = state_buffer.Get(0).GetFingerState(tracking_id);
+ const FingerState* prev = state_buffer.Get(1).GetFingerState(tracking_id);
if (!prev)
return false;
const stime_t dt =
@@ -1687,9 +1681,9 @@ void ImmediateInterpreter::UpdateThumbState(const HardwareState& hwstate) {
thumb_eval_timer_[fs.tracking_id] = thumb_eval_timeout_.val_;
}
}
- for (std::map<short, stime_t>::const_iterator it = thumb_.begin();
- it != thumb_.end(); ++it)
- pointing_.erase((*it).first);
+ for (const auto& [tracking_id, _] : thumb_) {
+ pointing_.erase(tracking_id);
+ }
}
void ImmediateInterpreter::UpdateNonGsFingers(const HardwareState& hwstate) {
@@ -1733,7 +1727,7 @@ FingerMap ImmediateInterpreter::GetGesturingFingers(
return {};
}
- const FingerState* fs[hwstate.finger_cnt];
+ std::vector<FingerState*> fs(hwstate.finger_cnt);
for (size_t i = 0; i < hwstate.finger_cnt; ++i)
fs[i] = &hwstate.fingers[i];
@@ -1743,11 +1737,12 @@ FingerMap ImmediateInterpreter::GetGesturingFingers(
FingerMap ret;
size_t sorted_cnt;
if (hwstate.finger_cnt > kMaxGesturingFingers) {
- std::partial_sort(fs, fs + kMaxGesturingFingers, fs + hwstate.finger_cnt,
+ std::partial_sort(fs.begin(), fs.begin() + kMaxGesturingFingers,
+ fs.end(),
compare);
sorted_cnt = kMaxGesturingFingers;
} else {
- std::sort(fs, fs + hwstate.finger_cnt, compare);
+ std::sort(fs.begin(), fs.end(), compare);
sorted_cnt = hwstate.finger_cnt;
}
for (size_t i = 0; i < sorted_cnt; i++)
@@ -1883,9 +1878,7 @@ void ImmediateInterpreter::UpdateCurrentGestureType(
}
if (current_gesture_type_ != kGestureTypeNull) {
active_gs_fingers->clear();
- for (vector<short, kMaxGesturingFingers>::const_iterator it =
- sorted_ids.begin(), e = sorted_ids.end(); it != e; ++it)
- active_gs_fingers->insert(*it);
+ active_gs_fingers->insert(sorted_ids.begin(), sorted_ids.end());
break;
}
}
@@ -1975,8 +1968,10 @@ void ImmediateInterpreter::SortFingersByProximity(
// that until we have enough points
size_t dist_sq_capacity =
(finger_ids.size() * (finger_ids.size() - 1)) / 2;
- DistSqElt dist_sq[dist_sq_capacity];
- size_t dist_sq_len = 0;
+
+ std::vector<DistSqElt> dist_sq;
+ dist_sq.reserve(dist_sq_capacity);
+
for (size_t i = 0; i < hwstate.finger_cnt; i++) {
const FingerState& fs1 = hwstate.fingers[i];
if (!SetContainsValue(finger_ids, fs1.tracking_id))
@@ -1989,24 +1984,20 @@ void ImmediateInterpreter::SortFingersByProximity(
DistSq(fs1, fs2),
{ fs1.tracking_id, fs2.tracking_id }
};
- if (dist_sq_len >= dist_sq_capacity) {
- Err("%s: Array overrun", __func__);
- break;
- }
- dist_sq[dist_sq_len++] = elt;
+ dist_sq.push_back(elt);
}
}
DistSqCompare distSqCompare;
- std::sort(dist_sq, dist_sq + dist_sq_len, distSqCompare);
+ std::sort(dist_sq.begin(), dist_sq.end(), distSqCompare);
if (out_sorted_ids == nullptr) {
Err("out_sorted_ids became null");
return;
}
- for (size_t i = 0; i < dist_sq_len; i++) {
- short id1 = dist_sq[i].tracking_id[0];
- short id2 = dist_sq[i].tracking_id[1];
+ for (auto const & d: dist_sq) {
+ short id1 = d.tracking_id[0];
+ short id2 = d.tracking_id[1];
bool contains1 = out_sorted_ids->find(id1) != out_sorted_ids->end();
bool contains2 = out_sorted_ids->find(id2) != out_sorted_ids->end();
if (contains1 == contains2 && !out_sorted_ids->empty()) {
@@ -2222,9 +2213,8 @@ bool ImmediateInterpreter::PalmIsArrivingOrDeparting(
bool ImmediateInterpreter::IsTooCloseToThumb(const FingerState& finger) const {
const float kMin2fDistThreshSq = tapping_finger_min_separation_.val_ *
tapping_finger_min_separation_.val_;
- for (std::map<short, stime_t>::const_iterator it = thumb_.begin();
- it != thumb_.end(); ++it) {
- const FingerState* thumb = state_buffer_.Get(0).GetFingerState(it->first);
+ for (const auto& [tracking_id, _] : thumb_) {
+ const FingerState* thumb = state_buffer_.Get(0).GetFingerState(tracking_id);
float xdist = fabsf(finger.position_x - thumb->position_x);
float ydist = fabsf(finger.position_y - thumb->position_y);
if (xdist * xdist + ydist * ydist < kMin2fDistThreshSq)
@@ -2463,8 +2453,10 @@ GestureType ImmediateInterpreter::GetMultiFingerGestureType(
return kGestureTypeNull;
}
- const FingerState* x_fingers[num_fingers];
- const FingerState* y_fingers[num_fingers];
+ assert(num_fingers <= (int) kMaxGesturingFingers);
+
+ const FingerState* x_fingers[kMaxGesturingFingers];
+ const FingerState* y_fingers[kMaxGesturingFingers];
for (int i = 0; i < num_fingers; i++) {
x_fingers[i] = fingers[i];
y_fingers[i] = fingers[i];
@@ -2478,13 +2470,13 @@ GestureType ImmediateInterpreter::GetMultiFingerGestureType(
bool horizontal =
(x_fingers[num_fingers - 1]->position_x - x_fingers[0]->position_x) >=
(y_fingers[num_fingers -1]->position_y - y_fingers[0]->position_y);
- const FingerState* sorted_fingers[num_fingers];
+ const FingerState* sorted_fingers[4];
for (int i = 0; i < num_fingers; i++) {
sorted_fingers[i] = horizontal ? x_fingers[i] : y_fingers[i];
}
- float dx[num_fingers];
- float dy[num_fingers];
+ float dx[kMaxGesturingFingers];
+ float dy[kMaxGesturingFingers];
float dy_sum = 0;
float dx_sum = 0;
for (int i = 0; i < num_fingers; i++) {
@@ -2548,7 +2540,7 @@ stime_t ImmediateInterpreter::TimeoutForTtcState(TapToClickState state) {
case kTtcDragRelease: return tap_drag_timeout_.val_;
case kTtcDragRetouch: return tap_timeout_.val_;
default:
- Log("Unknown state!");
+ Err("Unknown TapToClickState %u!", state);
return 0.0;
}
}
@@ -2606,14 +2598,13 @@ void ImmediateInterpreter::UpdateTapState(
(GESTURES_FINGER_NO_TAP | GESTURES_FINGER_MERGE))
cancel_tapping = true;
}
- for (FingerMap::const_iterator it =
- gs_fingers.begin(), e = gs_fingers.end(); it != e; ++it) {
- const FingerState* fs = hwstate->GetFingerState(*it);
+ for (short tracking_id : gs_fingers) {
+ const FingerState* fs = hwstate->GetFingerState(tracking_id);
if (!fs) {
Err("Missing finger state?!");
continue;
}
- tap_gs_fingers.insert(*it);
+ tap_gs_fingers.insert(tracking_id);
}
}
std::set<short> added_fingers;
@@ -2638,40 +2629,37 @@ void ImmediateInterpreter::UpdateTapState(
if (hwstate && (!same_fingers || prev_tap_gs_fingers_ != tap_gs_fingers)) {
// See if fingers were added
- for (FingerMap::const_iterator it =
- tap_gs_fingers.begin(), e = tap_gs_fingers.end(); it != e; ++it) {
+ for (short tracking_id : tap_gs_fingers) {
// If the finger was marked as a thumb before, it is not new.
- if (hwstate->timestamp - finger_origin_timestamp(*it) >
+ if (hwstate->timestamp - finger_origin_timestamp(tracking_id) >
thumb_click_prevention_timeout_.val_)
continue;
- if (!SetContainsValue(prev_tap_gs_fingers_, *it)) {
+ if (!SetContainsValue(prev_tap_gs_fingers_, tracking_id)) {
// Gesturing finger wasn't in prev state. It's new.
- const FingerState* fs = hwstate->GetFingerState(*it);
+ const FingerState* fs = hwstate->GetFingerState(tracking_id);
if (FingerTooCloseToTap(*hwstate, *fs) ||
FingerTooCloseToTap(state_buffer_.Get(1), *fs) ||
SetContainsValue(tap_dead_fingers_, fs->tracking_id))
continue;
- added_fingers.insert(*it);
- Log("TTC: Added %d", *it);
+ added_fingers.insert(tracking_id);
+ Log("TTC: Added %d", tracking_id);
}
}
// See if fingers were removed or are now non-gesturing (dead)
- for (FingerMap::const_iterator it =
- prev_tap_gs_fingers_.begin(), e = prev_tap_gs_fingers_.end();
- it != e; ++it) {
- if (tap_gs_fingers.find(*it) != tap_gs_fingers.end())
+ for (short tracking_id : prev_tap_gs_fingers_) {
+ if (tap_gs_fingers.find(tracking_id) != tap_gs_fingers.end())
// still gesturing; neither removed nor dead
continue;
- if (!hwstate->GetFingerState(*it)) {
+ if (!hwstate->GetFingerState(tracking_id)) {
// Previously gesturing finger isn't in current state. It's gone.
- removed_fingers.insert(*it);
- Log("TTC: Removed %d", *it);
+ removed_fingers.insert(tracking_id);
+ Log("TTC: Removed %d", tracking_id);
} else {
// Previously gesturing finger is in current state. It's dead.
- dead_fingers.insert(*it);
- Log("TTC: Dead %d", *it);
+ dead_fingers.insert(tracking_id);
+ Log("TTC: Dead %d", tracking_id);
}
}
}
@@ -2747,7 +2735,7 @@ void ImmediateInterpreter::UpdateTapState(
break;
}
if (!hwstate) {
- Log("hwstate is null but no timeout?!");
+ Err("hwstate is null but not a timeout?!");
break;
}
tap_record_.Update(
@@ -2797,7 +2785,7 @@ void ImmediateInterpreter::UpdateTapState(
break;
case kTtcSubsequentTapBegan:
if (!is_timeout && !hwstate) {
- Log("hwstate is null but not a timeout?!");
+ Err("hwstate is null but not a timeout?!");
break;
}
if (hwstate)
@@ -2901,7 +2889,7 @@ void ImmediateInterpreter::UpdateTapState(
break;
}
if (!hwstate) {
- Log("not timeout but hwstate is null?!");
+ Err("hwstate is null but not a timeout?!");
break;
}
if (tap_record_.Moving(*hwstate, tap_move_dist_.val_))
@@ -3038,15 +3026,15 @@ void ImmediateInterpreter::UpdateStartedMovingTime(
const FingerMap& gs_fingers,
const FingerMap& newly_moving_fingers) {
// Update started moving time if any gesturing finger is newly moving.
- for (auto it = gs_fingers.begin(), e = gs_fingers.end(); it != e; ++it) {
- if (SetContainsValue(newly_moving_fingers, *it)) {
+ for (short gs_tracking_id : gs_fingers) {
+ if (SetContainsValue(newly_moving_fingers, gs_tracking_id)) {
started_moving_time_ = now;
// Extend the thumb evaluation period for any finger that is still under
// evaluation as there is a new moving finger.
- for (std::map<short, stime_t>::iterator it = thumb_.begin();
- it != thumb_.end(); ++it)
- if ((*it).second < thumb_eval_timeout_.val_ && (*it).second > 0.0)
- (*it).second = thumb_eval_timeout_.val_;
+ for (auto& [_, time] : thumb_) {
+ if (time < thumb_eval_timeout_.val_ && time > 0.0)
+ time = thumb_eval_timeout_.val_;
+ }
return;
}
}
@@ -3168,9 +3156,8 @@ void ImmediateInterpreter::FillResultGesture(
const HardwareState& prev_hs = state_buffer_.Get(1);
if (!current) {
float curr_dist_sq = -1;
- for (FingerMap::const_iterator it =
- fingers.begin(), e = fingers.end(); it != e; ++it) {
- const FingerState* fs = hwstate.GetFingerState(*it);
+ for (short tracking_id : fingers) {
+ const FingerState* fs = hwstate.GetFingerState(tracking_id);
const FingerState* prev_fs = prev_hs.GetFingerState(fs->tracking_id);
if (!prev_fs)
break;
@@ -3277,9 +3264,8 @@ void ImmediateInterpreter::FillResultGesture(
float finger_cnt[] = { 0.0, 0.0 };
float FingerState::*fields[] = { &FingerState::position_x,
&FingerState::position_y };
- for (FingerMap::const_iterator it =
- fingers.begin(), e = fingers.end(); it != e; ++it) {
- if (!state_buffer_.Get(1).GetFingerState(*it)) {
+ for (short tracking_id : fingers) {
+ if (!state_buffer_.Get(1).GetFingerState(tracking_id)) {
Err("missing prev state?");
continue;
}
@@ -3290,8 +3276,8 @@ void ImmediateInterpreter::FillResultGesture(
if (!valid[i] || !correct_axis)
continue;
float FingerState::*field = fields[i];
- float delta = hwstate.GetFingerState(*it)->*field -
- state_buffer_.Get(1).GetFingerState(*it)->*field;
+ float delta = hwstate.GetFingerState(tracking_id)->*field -
+ state_buffer_.Get(1).GetFingerState(tracking_id)->*field;
// The multiply is to see if they have the same sign:
if (sum_delta[i] == 0.0 || sum_delta[i] * delta > 0) {
sum_delta[i] += delta;
@@ -3430,9 +3416,8 @@ void ImmediateInterpreter::Initialize(const HardwareProperties* hwprops,
bool AnyGesturingFingerLeft(const HardwareState& state,
const FingerMap& prev_gs_fingers) {
- for (FingerMap::const_iterator it = prev_gs_fingers.begin(),
- e = prev_gs_fingers.end(); it != e; ++it) {
- if (!state.GetFingerState(*it)) {
+ for (short tracking_id : prev_gs_fingers) {
+ if (!state.GetFingerState(tracking_id)) {
return true;
}
}
diff --git a/src/immediate_interpreter_unittest.cc b/src/immediate_interpreter_unittest.cc
index c7c6db2..994b11c 100644
--- a/src/immediate_interpreter_unittest.cc
+++ b/src/immediate_interpreter_unittest.cc
@@ -28,31 +28,31 @@ TEST(ImmediateInterpreterTest, ScrollEventTest) {
EXPECT_EQ(22.0, ev3.dy);
EXPECT_EQ(33.0, ev3.dt);
- ScrollEventBuffer* evbuf = new ScrollEventBuffer(2);
- evbuf->Insert(1.0, 2.0, 3.0);
- ev1 = evbuf->Get(0);
+ ScrollEventBuffer evbuf(2);
+ evbuf.Insert(1.0, 2.0, 3.0);
+ ev1 = evbuf.Get(0);
EXPECT_EQ(1.0, ev1.dx);
EXPECT_EQ(2.0, ev1.dy);
EXPECT_EQ(3.0, ev1.dt);
- ev1 = evbuf->Get(3);
+ ev1 = evbuf.Get(3);
EXPECT_EQ(0.0, ev1.dx);
EXPECT_EQ(0.0, ev1.dy);
EXPECT_EQ(0.0, ev1.dt);
}
TEST(ImmediateInterpreterTest, HardwareStateBufferTest) {
- HardwareStateBuffer* hsb = new HardwareStateBuffer(10);
- hsb->Reset(0);
- EXPECT_EQ(hsb->Size(), 10);
+ HardwareStateBuffer hsb(10);
+ hsb.Reset(0);
+ EXPECT_EQ(hsb.Size(), 10);
}
TEST(ImmediateInterpreterTest, ScrollManagerTest) {
- PropRegistry* my_prop_reg = new PropRegistry();
- ScrollManager* sm = new ScrollManager(my_prop_reg);
- ScrollEventBuffer* scroll_buffer = new ScrollEventBuffer(2);
+ PropRegistry my_prop_reg;
+ ScrollManager sm(&my_prop_reg);
+ ScrollEventBuffer scroll_buffer(2);
ScrollEvent ev;
- sm->RegressScrollVelocity(*scroll_buffer, 1, &ev);
+ sm.RegressScrollVelocity(scroll_buffer, 1, &ev);
EXPECT_EQ(0.0, ev.dx);
EXPECT_EQ(0.0, ev.dy);
EXPECT_EQ(1.0, ev.dt);
diff --git a/src/interpreter_unittest.cc b/src/interpreter_unittest.cc
index e0d1cff..ff5e785 100644
--- a/src/interpreter_unittest.cc
+++ b/src/interpreter_unittest.cc
@@ -75,9 +75,8 @@ class InterpreterTestInterpreter : public Interpreter {
TEST(InterpreterTest, SimpleTest) {
PropRegistry prop_reg;
- InterpreterTestInterpreter* base_interpreter =
- new InterpreterTestInterpreter(&prop_reg);
- base_interpreter->SetEventLoggingEnabled(true);
+ InterpreterTestInterpreter base_interpreter(&prop_reg);
+ base_interpreter.SetEventLoggingEnabled(true);
MetricsProperties mprops(&prop_reg);
HardwareProperties hwprops = {
@@ -94,19 +93,19 @@ TEST(InterpreterTest, SimpleTest) {
.is_haptic_pad = 0,
};
- TestInterpreterWrapper wrapper(base_interpreter, &hwprops);
+ TestInterpreterWrapper wrapper(&base_interpreter, &hwprops);
- base_interpreter->bool_prop_.val_ = 1;
- base_interpreter->double_prop_.val_ = 1;
- base_interpreter->int_prop_.val_ = 1;
- base_interpreter->string_prop_.val_ = "x";
+ base_interpreter.bool_prop_.val_ = 1;
+ base_interpreter.double_prop_.val_ = 1;
+ base_interpreter.int_prop_.val_ = 1;
+ base_interpreter.string_prop_.val_ = "x";
//if (prop_reg)
- // prop_reg->set_activity_log(&(base_interpreter->log_));
+ // prop_reg->set_activity_log(&(base_interpreter.log_));
char interpreter_name[] = "InterpreterTestInterpreter";
- base_interpreter->expected_interpreter_name_ = interpreter_name;
- base_interpreter->return_value_ = Gesture(kGestureMove,
+ base_interpreter.expected_interpreter_name_ = interpreter_name;
+ base_interpreter.return_value_ = Gesture(kGestureMove,
0, // start time
1, // end time
-4, // dx
@@ -119,39 +118,38 @@ TEST(InterpreterTest, SimpleTest) {
HardwareState hardware_state = make_hwstate(200000, 0, 1, 1, &finger_state);
stime_t timeout = NO_DEADLINE;
- base_interpreter->expected_hwstate_ = &hardware_state;
+ base_interpreter.expected_hwstate_ = &hardware_state;
Gesture* result = wrapper.SyncInterpret(hardware_state, &timeout);
- EXPECT_TRUE(base_interpreter->return_value_ == *result);
+ EXPECT_TRUE(base_interpreter.return_value_ == *result);
ASSERT_GT(timeout, 0);
stime_t now = hardware_state.timestamp + timeout;
timeout = NO_DEADLINE;
result = wrapper.HandleTimer(now, &timeout);
- EXPECT_TRUE(base_interpreter->return_value_ == *result);
+ EXPECT_TRUE(base_interpreter.return_value_ == *result);
ASSERT_LT(timeout, 0);
- EXPECT_EQ(1, base_interpreter->interpret_call_count_);
- EXPECT_EQ(1, base_interpreter->handle_timer_call_count_);
+ EXPECT_EQ(1, base_interpreter.interpret_call_count_);
+ EXPECT_EQ(1, base_interpreter.handle_timer_call_count_);
// Now, get the log
- string initial_log = base_interpreter->Encode();
+ string initial_log = base_interpreter.Encode();
// Make a new interpreter and push the log through it
PropRegistry prop_reg2;
- InterpreterTestInterpreter* base_interpreter2 =
- new InterpreterTestInterpreter(&prop_reg2);
- base_interpreter2->SetEventLoggingEnabled(true);
- base_interpreter2->return_value_ = base_interpreter->return_value_;
- base_interpreter2->expected_interpreter_name_ = interpreter_name;
+ InterpreterTestInterpreter base_interpreter2(&prop_reg2);
+ base_interpreter2.SetEventLoggingEnabled(true);
+ base_interpreter2.return_value_ = base_interpreter.return_value_;
+ base_interpreter2.expected_interpreter_name_ = interpreter_name;
MetricsProperties mprops2(&prop_reg2);
ActivityReplay replay(&prop_reg2);
replay.Parse(initial_log);
- base_interpreter2->expected_hwstate_ = &hardware_state;
+ base_interpreter2.expected_hwstate_ = &hardware_state;
- replay.Replay(base_interpreter2, &mprops2);
- string final_log = base_interpreter2->Encode();
+ replay.Replay(&base_interpreter2, &mprops2);
+ string final_log = base_interpreter2.Encode();
EXPECT_EQ(initial_log, final_log);
- EXPECT_EQ(1, base_interpreter2->interpret_call_count_);
- EXPECT_EQ(1, base_interpreter2->handle_timer_call_count_);
+ EXPECT_EQ(1, base_interpreter2.interpret_call_count_);
+ EXPECT_EQ(1, base_interpreter2.handle_timer_call_count_);
}
class InterpreterResetLogTestInterpreter : public Interpreter {
@@ -168,10 +166,9 @@ class InterpreterResetLogTestInterpreter : public Interpreter {
TEST(InterpreterTest, ResetLogTest) {
PropRegistry prop_reg;
- InterpreterResetLogTestInterpreter* base_interpreter =
- new InterpreterResetLogTestInterpreter();
- base_interpreter->SetEventLoggingEnabled(true);
- TestInterpreterWrapper wrapper(base_interpreter);
+ InterpreterResetLogTestInterpreter base_interpreter;
+ base_interpreter.SetEventLoggingEnabled(true);
+ TestInterpreterWrapper wrapper(&base_interpreter);
FingerState finger_state = {
// TM, Tm, WM, Wm, Press, Orientation, X, Y, TrID
@@ -180,24 +177,23 @@ TEST(InterpreterTest, ResetLogTest) {
HardwareState hardware_state = make_hwstate(200000, 0, 1, 1, &finger_state);
stime_t timeout = NO_DEADLINE;
wrapper.SyncInterpret(hardware_state, &timeout);
- EXPECT_EQ(base_interpreter->log_->size(), 1);
+ EXPECT_EQ(base_interpreter.log_->size(), 1);
wrapper.SyncInterpret(hardware_state, &timeout);
- EXPECT_EQ(base_interpreter->log_->size(), 2);
+ EXPECT_EQ(base_interpreter.log_->size(), 2);
// Assume the ResetLog property is set.
- base_interpreter->Clear();
- EXPECT_EQ(base_interpreter->log_->size(), 0);
+ base_interpreter.Clear();
+ EXPECT_EQ(base_interpreter.log_->size(), 0);
wrapper.SyncInterpret(hardware_state, &timeout);
- EXPECT_EQ(base_interpreter->log_->size(), 1);
+ EXPECT_EQ(base_interpreter.log_->size(), 1);
}
TEST(InterpreterTest, LoggingDisabledByDefault) {
PropRegistry prop_reg;
- InterpreterResetLogTestInterpreter* base_interpreter =
- new InterpreterResetLogTestInterpreter();
- TestInterpreterWrapper wrapper(base_interpreter);
+ InterpreterResetLogTestInterpreter base_interpreter;
+ TestInterpreterWrapper wrapper(&base_interpreter);
FingerState finger_state = {
// TM, Tm, WM, Wm, Press, Orientation, X, Y, TrID
@@ -206,102 +202,98 @@ TEST(InterpreterTest, LoggingDisabledByDefault) {
HardwareState hardware_state = make_hwstate(200000, 0, 1, 1, &finger_state);
stime_t timeout = NO_DEADLINE;
wrapper.SyncInterpret(hardware_state, &timeout);
- EXPECT_EQ(base_interpreter->log_->size(), 0);
+ EXPECT_EQ(base_interpreter.log_->size(), 0);
wrapper.SyncInterpret(hardware_state, &timeout);
- EXPECT_EQ(base_interpreter->log_->size(), 0);
+ EXPECT_EQ(base_interpreter.log_->size(), 0);
}
TEST(InterpreterTest, EventDebugLoggingEnableTest) {
- InterpreterResetLogTestInterpreter* base_interpreter =
- new InterpreterResetLogTestInterpreter();
+ InterpreterResetLogTestInterpreter base_interpreter;
- base_interpreter->SetEventDebugLoggingEnabled(0);
- EXPECT_EQ(base_interpreter->GetEventDebugLoggingEnabled(), 0);
+ base_interpreter.SetEventDebugLoggingEnabled(0);
+ EXPECT_EQ(base_interpreter.GetEventDebugLoggingEnabled(), 0);
using EventDebug = ActivityLog::EventDebug;
- base_interpreter->EventDebugLoggingEnable(EventDebug::HardwareState);
- EXPECT_EQ(base_interpreter->GetEventDebugLoggingEnabled(),
+ base_interpreter.EventDebugLoggingEnable(EventDebug::HardwareState);
+ EXPECT_EQ(base_interpreter.GetEventDebugLoggingEnabled(),
1 << static_cast<int>(EventDebug::HardwareState));
- base_interpreter->EventDebugLoggingDisable(EventDebug::HardwareState);
- EXPECT_EQ(base_interpreter->GetEventDebugLoggingEnabled(), 0);
+ base_interpreter.EventDebugLoggingDisable(EventDebug::HardwareState);
+ EXPECT_EQ(base_interpreter.GetEventDebugLoggingEnabled(), 0);
}
TEST(InterpreterTest, LogHardwareStateTest) {
PropRegistry prop_reg;
- InterpreterResetLogTestInterpreter* base_interpreter =
- new InterpreterResetLogTestInterpreter();
+ InterpreterResetLogTestInterpreter base_interpreter;
FingerState fs = { 0.0, 0.0, 0.0, 0.0, 9.0, 0.0, 3.0, 4.0, 22, 0 };
HardwareState hs = make_hwstate(1.0, 0, 1, 1, &fs);
- base_interpreter->SetEventLoggingEnabled(false);
- base_interpreter->SetEventDebugLoggingEnabled(0);
+ base_interpreter.SetEventLoggingEnabled(false);
+ base_interpreter.SetEventDebugLoggingEnabled(0);
- base_interpreter->LogHardwareStatePre(
+ base_interpreter.LogHardwareStatePre(
"InterpreterTest_LogHardwareStateTest", hs);
- EXPECT_EQ(base_interpreter->log_->size(), 0);
+ EXPECT_EQ(base_interpreter.log_->size(), 0);
- base_interpreter->LogHardwareStatePost(
+ base_interpreter.LogHardwareStatePost(
"InterpreterTest_LogHardwareStateTest", hs);
- EXPECT_EQ(base_interpreter->log_->size(), 0);
+ EXPECT_EQ(base_interpreter.log_->size(), 0);
using EventDebug = ActivityLog::EventDebug;
- base_interpreter->SetEventLoggingEnabled(true);
- base_interpreter->EventDebugLoggingEnable(EventDebug::HardwareState);
+ base_interpreter.SetEventLoggingEnabled(true);
+ base_interpreter.EventDebugLoggingEnable(EventDebug::HardwareState);
- base_interpreter->LogHardwareStatePre(
+ base_interpreter.LogHardwareStatePre(
"InterpreterTest_LogHardwareStateTest", hs);
- EXPECT_EQ(base_interpreter->log_->size(), 1);
+ EXPECT_EQ(base_interpreter.log_->size(), 1);
- base_interpreter->LogHardwareStatePost(
+ base_interpreter.LogHardwareStatePost(
"InterpreterTest_LogHardwareStateTest", hs);
- EXPECT_EQ(base_interpreter->log_->size(), 2);
+ EXPECT_EQ(base_interpreter.log_->size(), 2);
}
TEST(InterpreterTest, LogGestureTest) {
PropRegistry prop_reg;
- InterpreterResetLogTestInterpreter* base_interpreter =
- new InterpreterResetLogTestInterpreter();
+ InterpreterResetLogTestInterpreter base_interpreter;
Gesture move(kGestureMove, 1.0, 2.0, 773, 4.0);
- base_interpreter->SetEventLoggingEnabled(false);
- base_interpreter->SetEventDebugLoggingEnabled(0);
- base_interpreter->LogGestureConsume("InterpreterTest_LogGestureTest", move);
- EXPECT_EQ(base_interpreter->log_->size(), 0);
- base_interpreter->LogGestureProduce("InterpreterTest_LogGestureTest", move);
- EXPECT_EQ(base_interpreter->log_->size(), 0);
+ base_interpreter.SetEventLoggingEnabled(false);
+ base_interpreter.SetEventDebugLoggingEnabled(0);
+ base_interpreter.LogGestureConsume("InterpreterTest_LogGestureTest", move);
+ EXPECT_EQ(base_interpreter.log_->size(), 0);
+ base_interpreter.LogGestureProduce("InterpreterTest_LogGestureTest", move);
+ EXPECT_EQ(base_interpreter.log_->size(), 0);
using EventDebug = ActivityLog::EventDebug;
- base_interpreter->SetEventLoggingEnabled(true);
- base_interpreter->EventDebugLoggingEnable(EventDebug::Gesture);
- base_interpreter->LogGestureConsume("InterpreterTest_LogGestureTest", move);
- EXPECT_EQ(base_interpreter->log_->size(), 1);
- base_interpreter->LogGestureProduce("InterpreterTest_LogGestureTest", move);
- EXPECT_EQ(base_interpreter->log_->size(), 2);
+ base_interpreter.SetEventLoggingEnabled(true);
+ base_interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
+ base_interpreter.LogGestureConsume("InterpreterTest_LogGestureTest", move);
+ EXPECT_EQ(base_interpreter.log_->size(), 1);
+ base_interpreter.LogGestureProduce("InterpreterTest_LogGestureTest", move);
+ EXPECT_EQ(base_interpreter.log_->size(), 2);
}
TEST(InterpreterTest, LogHandleTimerTest) {
PropRegistry prop_reg;
- InterpreterResetLogTestInterpreter* base_interpreter =
- new InterpreterResetLogTestInterpreter();
+ InterpreterResetLogTestInterpreter base_interpreter;
using EventDebug = ActivityLog::EventDebug;
- base_interpreter->SetEventLoggingEnabled(true);
- base_interpreter->EventDebugLoggingEnable(EventDebug::HandleTimer);
+ base_interpreter.SetEventLoggingEnabled(true);
+ base_interpreter.EventDebugLoggingEnable(EventDebug::HandleTimer);
stime_t timeout = 10;
- base_interpreter->LogHandleTimerPre("InterpreterTest_LogHandleTimerTest",
+ base_interpreter.LogHandleTimerPre("InterpreterTest_LogHandleTimerTest",
0, &timeout);
- EXPECT_EQ(base_interpreter->log_->size(), 1);
+ EXPECT_EQ(base_interpreter.log_->size(), 1);
- base_interpreter->LogHandleTimerPost("InterpreterTest_LogHandleTimerTest",
+ base_interpreter.LogHandleTimerPost("InterpreterTest_LogHandleTimerTest",
0, &timeout);
- EXPECT_EQ(base_interpreter->log_->size(), 2);
+ EXPECT_EQ(base_interpreter.log_->size(), 2);
}
} // namespace gestures
diff --git a/src/lookahead_filter_interpreter.cc b/src/lookahead_filter_interpreter.cc
index 7a5c8fd..767f350 100644
--- a/src/lookahead_filter_interpreter.cc
+++ b/src/lookahead_filter_interpreter.cc
@@ -5,6 +5,7 @@
#include "include/lookahead_filter_interpreter.h"
#include <algorithm>
+#include <memory>
#include <math.h>
#include "include/tracer.h"
@@ -472,7 +473,8 @@ void LookaheadFilterInterpreter::HandleTimerImpl(stime_t now,
// SyncInterpret
last_interpreted_time_ = node->state_.timestamp;
const size_t finger_cnt = node->state_.finger_cnt;
- FingerState fs_copy[std::max(finger_cnt,(size_t)1)];
+ auto fs_copy =
+ std::make_unique<FingerState[]>(std::max(finger_cnt, (size_t)1));
std::copy(&node->state_.fingers[0],
&node->state_.fingers[finger_cnt],
&fs_copy[0]);
@@ -481,7 +483,7 @@ void LookaheadFilterInterpreter::HandleTimerImpl(stime_t now,
node->state_.buttons_down,
node->state_.finger_cnt,
node->state_.touch_cnt,
- fs_copy,
+ fs_copy.get(),
node->state_.rel_x,
node->state_.rel_y,
node->state_.rel_wheel,
diff --git a/src/mouse_interpreter.cc b/src/mouse_interpreter.cc
index 6ed44e7..a281a9a 100644
--- a/src/mouse_interpreter.cc
+++ b/src/mouse_interpreter.cc
@@ -31,6 +31,7 @@ MouseInterpreter::MouseInterpreter(PropRegistry* prop_reg, Tracer* tracer)
scroll_sensitivity_(prop_reg,"Mouse Scroll Sensitivity",
kMouseScrollSensitivityDefaultValue),
hi_res_scrolling_(prop_reg, "Mouse High Resolution Scrolling", true),
+ scroll_velocity_buffer_size_(prop_reg, "Scroll Wheel Velocity Buffer", 3),
scroll_accel_curve_prop_(prop_reg, "Mouse Scroll Accel Curve",
scroll_accel_curve_, sizeof(scroll_accel_curve_) / sizeof(double)),
scroll_max_allowed_input_speed_(prop_reg,
@@ -49,8 +50,6 @@ MouseInterpreter::MouseInterpreter(PropRegistry* prop_reg, Tracer* tracer)
"Output Mouse Wheel Gestures", false) {
InitName();
memset(&prev_state_, 0, sizeof(prev_state_));
- memset(&last_wheel_, 0, sizeof(last_wheel_));
- memset(&last_hwheel_, 0, sizeof(last_hwheel_));
// Scroll acceleration curve coefficients. See the definition for more
// details on how to generate them.
scroll_accel_curve_[0] = 1.0374e+01;
@@ -168,60 +167,81 @@ void MouseInterpreter::InterpretScrollWheelEvent(const HardwareState& hwstate,
bool is_vertical) {
const char name[] = "MouseInterpreter::InterpretScrollWheelEvent";
- const float scroll_wheel_event_time_delta_min = 0.008;
+ const size_t max_buffer_size = scroll_velocity_buffer_size_.val_;
+ const float scroll_wheel_event_time_delta_min = 0.008 * max_buffer_size;
bool use_high_resolution =
is_vertical && hwprops_->wheel_is_hi_res
&& hi_res_scrolling_.val_;
// Vertical wheel or horizontal wheel.
- float current_wheel_value = hwstate.rel_hwheel;
- int ticks = hwstate.rel_hwheel * REL_WHEEL_HI_RES_UNITS_PER_NOTCH;
- WheelRecord* last_wheel_record = &last_hwheel_;
+ WheelRecord current_wheel;
+ current_wheel.timestamp = hwstate.timestamp;
+ int ticks;
+ std::vector<WheelRecord>* last_wheels;
if (is_vertical) {
// Only vertical high-res scrolling is supported for now.
if (use_high_resolution) {
- current_wheel_value = hwstate.rel_wheel_hi_res
+ current_wheel.change = hwstate.rel_wheel_hi_res
/ REL_WHEEL_HI_RES_UNITS_PER_NOTCH;
ticks = hwstate.rel_wheel_hi_res;
} else {
- current_wheel_value = hwstate.rel_wheel;
+ current_wheel.change = hwstate.rel_wheel;
ticks = hwstate.rel_wheel * REL_WHEEL_HI_RES_UNITS_PER_NOTCH;
}
- last_wheel_record = &last_wheel_;
+ last_wheels = &last_vertical_wheels_;
+ } else {
+ last_wheels = &last_horizontal_wheels_;
+ current_wheel.change = hwstate.rel_hwheel;
+ ticks = hwstate.rel_hwheel * REL_WHEEL_HI_RES_UNITS_PER_NOTCH;
}
// Check if the wheel is scrolled.
- if (current_wheel_value) {
+ if (current_wheel.change) {
stime_t start_time, end_time = hwstate.timestamp;
// Check if this scroll is in same direction as previous scroll event.
- if ((current_wheel_value < 0 && last_wheel_record->value < 0) ||
- (current_wheel_value > 0 && last_wheel_record->value > 0)) {
- start_time = last_wheel_record->timestamp;
+ if (!last_wheels->empty() &&
+ ((current_wheel.change < 0 && last_wheels->back().change < 0) ||
+ (current_wheel.change > 0 && last_wheels->back().change > 0))) {
+ start_time = last_wheels->begin()->timestamp;
} else {
+ last_wheels->clear();
start_time = end_time;
}
- // If start_time == end_time, compute velocity using dt = 1 second.
- // (this happens when the user initially starts scrolling)
- stime_t dt = (end_time - start_time) ?: 1.0;
- if (dt < scroll_wheel_event_time_delta_min) {
- // the first packet received after BT wakeup may be delayed, causing the
- // time delta between that and the subsequent packet to be very small.
- // Prevent small time deltas from triggering large amounts of acceleration
- // by enforcing a minimum time delta.
- dt = scroll_wheel_event_time_delta_min;
+ // We will only accelerate scrolls if we have filled our buffer of scroll
+ // events all in the same direction. If the buffer is full, then calculate
+ // scroll velocity using the average velocity of the entire buffer.
+ float velocity;
+ if (last_wheels->size() < max_buffer_size) {
+ velocity = 0.0;
+ } else {
+ stime_t dt = end_time - last_wheels->back().timestamp;
+ if (dt < scroll_wheel_event_time_delta_min) {
+ // The first packets received after BT wakeup may be delayed, causing
+ // the time delta between that and the subsequent packets to be
+ // artificially very small.
+ // Prevent small time deltas from triggering large amounts of
+ // acceleration by enforcing a minimum time delta.
+ dt = scroll_wheel_event_time_delta_min;
+ }
+
+ last_wheels->pop_back();
+ float buffer_scroll_distance = current_wheel.change;
+ for (auto wheel : *last_wheels) {
+ buffer_scroll_distance += wheel.change;
+ }
+
+ velocity = buffer_scroll_distance / dt;
}
+ last_wheels->insert(last_wheels->begin(), current_wheel);
// When scroll acceleration is off, the scroll factor does not relate to
// scroll velocity. It's simply a constant multiplier to the wheel value.
const double unaccel_scroll_factors[] = { 20.0, 36.0, 72.0, 112.0, 164.0 };
- float velocity = current_wheel_value / dt;
- float offset = current_wheel_value * (
+ float offset = current_wheel.change * (
scroll_acceleration_.val_?
ComputeScrollAccelFactor(velocity) :
unaccel_scroll_factors[scroll_sensitivity_.val_ - 1]);
- last_wheel_record->timestamp = hwstate.timestamp;
- last_wheel_record->value = current_wheel_value;
if (is_vertical) {
// For historical reasons the vertical wheel (REL_WHEEL) is inverted
diff --git a/src/mouse_interpreter_unittest.cc b/src/mouse_interpreter_unittest.cc
index 57267d8..520a455 100644
--- a/src/mouse_interpreter_unittest.cc
+++ b/src/mouse_interpreter_unittest.cc
@@ -103,6 +103,7 @@ TEST(MouseInterpreterTest, HighResolutionVerticalScrollTest) {
mi.output_mouse_wheel_gestures_.val_ = true;
mi.hi_res_scrolling_.val_ = 1;
+ mi.scroll_velocity_buffer_size_.val_ = 1;
gs = wrapper.SyncInterpret(hwstates[0], nullptr);
EXPECT_EQ(nullptr, gs);
@@ -157,6 +158,7 @@ TEST(MouseInterpreterTest, ScrollAccelerationOnAndOffTest) {
mi.scroll_acceleration_.val_ = true;
mi.output_mouse_wheel_gestures_.val_ = true;
mi.hi_res_scrolling_.val_ = false;
+ mi.scroll_velocity_buffer_size_.val_ = 1;
gs = wrapper.SyncInterpret(hwstates[0], nullptr);
EXPECT_EQ(nullptr, gs);
@@ -212,6 +214,7 @@ TEST(MouseInterpreterTest, JankyScrollTest) {
};
mi.output_mouse_wheel_gestures_.val_ = true;
+ mi.scroll_velocity_buffer_size_.val_ = 1;
gs = wrapper.SyncInterpret(hwstates[0], nullptr);
ASSERT_NE(nullptr, gs);
diff --git a/src/non_linearity_filter_interpreter.cc b/src/non_linearity_filter_interpreter.cc
index df0e765..4d5c1e4 100644
--- a/src/non_linearity_filter_interpreter.cc
+++ b/src/non_linearity_filter_interpreter.cc
@@ -4,6 +4,8 @@
#include "include/non_linearity_filter_interpreter.h"
+#include <cstring>
+
#include <linux/in.h>
namespace {
@@ -20,7 +22,7 @@ NonLinearityFilterInterpreter::NonLinearityFilterInterpreter(
: FilterInterpreter(nullptr, next, tracer, false),
x_range_len_(0), y_range_len_(0), p_range_len_(0),
enabled_(prop_reg, "Enable non-linearity correction", false),
- data_location_(prop_reg, "Non-linearity correction data file", "None") {
+ data_location_(prop_reg, "Non-linearity correction data file", "") {
InitName();
LoadData();
}
@@ -67,8 +69,12 @@ bool NonLinearityFilterInterpreter::LoadRange(std::unique_ptr<double[]>& arr,
}
void NonLinearityFilterInterpreter::LoadData() {
+ if (strlen(data_location_.val_) == 0) {
+ return;
+ }
FILE* data_fd = fopen(data_location_.val_, "rb");
if (!data_fd) {
+ // TODO(b/329268257): make this an Err, not a Log.
Log("Unable to open non-linearity filter data '%s'", data_location_.val_);
return;
}
diff --git a/src/prop_registry.cc b/src/prop_registry.cc
index 283db9d..d1aaf6e 100644
--- a/src/prop_registry.cc
+++ b/src/prop_registry.cc
@@ -106,22 +106,24 @@ void BoolProperty::HandleGesturesPropWritten() {
}
void BoolArrayProperty::CreatePropImpl() {
- GesturesPropBool orig_vals[count_];
- memcpy(orig_vals, vals_, sizeof(orig_vals));
+ auto orig_vals = std::make_unique<GesturesPropBool[]>(count_);
+
+ memcpy(orig_vals.get(), vals_, count_ * sizeof(GesturesPropBool));
gprop_ = parent_->PropProvider()->create_bool_fn(
parent_->PropProviderData(),
name(),
vals_,
count_,
vals_);
- if (delegate_ && memcmp(orig_vals, vals_, sizeof(orig_vals)))
+ if (delegate_ && memcmp(orig_vals.get(), vals_,
+ count_ * sizeof(GesturesPropBool)))
delegate_->BoolArrayWasWritten(this);
}
Json::Value BoolArrayProperty::NewValue() const {
Json::Value list(Json::arrayValue);
for (size_t i = 0; i < count_; i++)
- list.append(new Json::Value(vals_[i] != 0));
+ list.append(Json::Value(vals_[i] != 0));
return list;
}
@@ -182,15 +184,16 @@ void DoubleProperty::HandleGesturesPropWritten() {
}
void DoubleArrayProperty::CreatePropImpl() {
- float orig_vals[count_];
- memcpy(orig_vals, vals_, sizeof(orig_vals));
+ auto orig_vals = std::make_unique<float[]>(count_);
+
+ memcpy(orig_vals.get(), vals_, count_ * sizeof(float));
gprop_ = parent_->PropProvider()->create_real_fn(
parent_->PropProviderData(),
name(),
vals_,
count_,
vals_);
- if (delegate_ && memcmp(orig_vals, vals_, sizeof(orig_vals)))
+ if (delegate_ && memcmp(orig_vals.get(), vals_, count_ * sizeof(float)))
delegate_->DoubleArrayWasWritten(this);
}
@@ -263,15 +266,16 @@ void IntProperty::HandleGesturesPropWritten() {
}
void IntArrayProperty::CreatePropImpl() {
- int orig_vals[count_];
- memcpy(orig_vals, vals_, sizeof(orig_vals));
+ auto orig_vals = std::make_unique<int[]>(count_);
+
+ memcpy(orig_vals.get(), vals_, count_ * sizeof(int));
gprop_ = parent_->PropProvider()->create_int_fn(
parent_->PropProviderData(),
name(),
vals_,
count_,
vals_);
- if (delegate_ && memcmp(orig_vals, vals_, sizeof(orig_vals)))
+ if (delegate_ && memcmp(orig_vals.get(), vals_, count_ * sizeof(int)))
delegate_->IntArrayWasWritten(this);
}
diff --git a/src/string_util.cc b/src/string_util.cc
index 3e5b896..863399c 100644
--- a/src/string_util.cc
+++ b/src/string_util.cc
@@ -85,58 +85,24 @@ static void StringAppendVT(std::string* dst,
}
}
-template <typename STR>
-void SplitStringT(const STR& str,
- const typename STR::value_type s,
- bool trim_whitespace,
- std::vector<STR>* r) {
- r->clear();
- size_t last = 0;
- size_t c = str.size();
- for (size_t i = 0; i <= c; ++i) {
- if (i == c || str[i] == s) {
- STR tmp(str, last, i - last);
- if (trim_whitespace)
- TrimWhitespaceASCII(tmp, TRIM_ALL, &tmp);
- // Avoid converting an empty or all-whitespace source string into a vector
- // of one empty string.
- if (i != c || !r->empty() || !tmp.empty())
- r->push_back(tmp);
- last = i + 1;
- }
+template<typename STR>
+STR TrimStringT(const STR& input, const typename STR::value_type trim_chars[]) {
+ if (input.empty()) {
+ return "";
}
-}
-template<typename STR>
-TrimPositions TrimStringT(const STR& input,
- const typename STR::value_type trim_chars[],
- TrimPositions positions,
- STR* output) {
- // Find the edges of leading/trailing whitespace as desired.
- const typename STR::size_type last_char = input.length() - 1;
- const typename STR::size_type first_good_char = (positions & TRIM_LEADING) ?
- input.find_first_not_of(trim_chars) : 0;
- const typename STR::size_type last_good_char = (positions & TRIM_TRAILING) ?
- input.find_last_not_of(trim_chars) : last_char;
-
- // When the string was all whitespace, report that we stripped off whitespace
- // from whichever position the caller was interested in. For empty input, we
- // stripped no whitespace, but we still need to clear |output|.
- if (input.empty() ||
- (first_good_char == STR::npos) || (last_good_char == STR::npos)) {
- bool input_was_empty = input.empty(); // in case output == &input
- output->clear();
- return input_was_empty ? TRIM_NONE : positions;
+ // Find the edges of leading/trailing whitespace.
+ const typename STR::size_type first_good_char =
+ input.find_first_not_of(trim_chars);
+ const typename STR::size_type last_good_char =
+ input.find_last_not_of(trim_chars);
+
+ if (first_good_char == STR::npos || last_good_char == STR::npos) {
+ return "";
}
// Trim the whitespace.
- *output =
- input.substr(first_good_char, last_good_char - first_good_char + 1);
-
- // Return where we trimmed from.
- return static_cast<TrimPositions>(
- ((first_good_char == 0) ? TRIM_NONE : TRIM_LEADING) |
- ((last_good_char == last_char) ? TRIM_NONE : TRIM_TRAILING));
+ return input.substr(first_good_char, last_good_char - first_good_char + 1);
}
} // namespace
@@ -154,25 +120,8 @@ std::string StringPrintf(const char* format, ...) {
return result;
}
-bool StartsWithASCII(const std::string& str,
- const std::string& search,
- bool case_sensitive) {
- if (case_sensitive)
- return str.compare(0, search.length(), search) == 0;
- else
- return strncasecmp(str.c_str(), search.c_str(), search.length()) == 0;
-}
-
-void SplitString(const std::string& str,
- char c,
- std::vector<std::string>* r) {
- SplitStringT(str, c, true, r);
-}
-
-TrimPositions TrimWhitespaceASCII(const std::string& input,
- TrimPositions positions,
- std::string* output) {
- return TrimStringT(input, kWhitespaceASCII, positions, output);
+std::string TrimWhitespaceASCII(const std::string& input) {
+ return TrimStringT(input, kWhitespaceASCII);
}
} // namespace gestures
diff --git a/src/string_util_unittest.cc b/src/string_util_unittest.cc
index 0ce0b0c..b1edda6 100644
--- a/src/string_util_unittest.cc
+++ b/src/string_util_unittest.cc
@@ -13,9 +13,7 @@ namespace gestures {
class StringUtilTest : public ::testing::Test {};
-// This test adds code coverage to string_util.
-
-TEST(StringUtilTest, SimpleTest) {
+TEST(StringUtilTest, StringPrintfTest) {
const char *pstr =
"0123456789012345678901234567890123456789012345678901234567890123456789";
std::string str = StringPrintf(
@@ -26,17 +24,16 @@ TEST(StringUtilTest, SimpleTest) {
);
int expected_length = (70*15)+15+1;
EXPECT_EQ(str.size(), expected_length);
+}
- TrimPositions trimmed_from = TrimWhitespaceASCII(str, TRIM_ALL, &str);
- EXPECT_EQ(trimmed_from, TRIM_ALL);
- EXPECT_EQ(str.size(), expected_length-2);
-
- std::vector<std::string> split;
- SplitString(str, ' ', &split);
- EXPECT_EQ(split.size(), 15);
-
- bool matches = StartsWithASCII(split[0], pstr, true);
- EXPECT_TRUE(matches);
+TEST(StringUtilTest, TrimWhitespaceASCIITest) {
+ EXPECT_EQ(TrimWhitespaceASCII(""), "");
+ EXPECT_EQ(TrimWhitespaceASCII(" x "), "x");
+ EXPECT_EQ(TrimWhitespaceASCII("badger"), "badger");
+ EXPECT_EQ(TrimWhitespaceASCII("badger "), "badger");
+ EXPECT_EQ(TrimWhitespaceASCII(" badger"), "badger");
+ EXPECT_EQ(TrimWhitespaceASCII(" \t \n\r "), "");
+ EXPECT_EQ(TrimWhitespaceASCII(" Bees and ponies "), "Bees and ponies");
}
} // namespace gestures
diff --git a/tools/touchtests-report.json b/tools/touchtests-report.json
index 8340e7b..145f6aa 100644
--- a/tools/touchtests-report.json
+++ b/tools/touchtests-report.json
@@ -1798,6 +1798,13 @@
"result": "success",
"score": 1.0
},
+ "logitech-m650-1.0/fast_initial_scroll": {
+ "description": "",
+ "disabled": false,
+ "error": "",
+ "result": "success",
+ "score": 1.0
+ },
"logitech-t620/accidental_back_fling": {
"description": "",
"disabled": false,