summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-05-10 16:11:58 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-05-10 16:11:58 +0000
commitca8ce29a4adf39f65fbd522013f38b9b0a18030a (patch)
tree5cc65c6a06e2fa8e7e7b178485355ea72ef89627
parent2e3a4cbb7d911a8d74e1ef5243f73f55fd5ed9df (diff)
parent781b8df8fa3b02c22baf0b9e80c164c7e84e84a5 (diff)
downloadlibchrome-gestures-aml_tz5_341510010.tar.gz
Snap for 10103804 from 781b8df8fa3b02c22baf0b9e80c164c7e84e84a5 to mainline-tzdata5-releaseaml_tz5_341510070aml_tz5_341510050aml_tz5_341510010aml_tz5_341510010
Change-Id: I48363bd338bc2daf28cbd32ee9f96a8546f4d471
-rw-r--r--Android.bp1
-rw-r--r--METADATA.android4
-rw-r--r--Makefile3
-rw-r--r--include/gestures.h38
-rw-r--r--include/list.h138
-rw-r--r--include/lookahead_filter_interpreter.h9
-rw-r--r--include/memory_manager.h79
-rw-r--r--include/metrics_filter_interpreter.h32
-rw-r--r--include/prop_registry.h58
-rw-r--r--include/trend_classifying_filter_interpreter.h19
-rw-r--r--include/util.h48
-rw-r--r--src/iir_filter_interpreter.cc2
-rw-r--r--src/immediate_interpreter.cc3
-rw-r--r--src/list_unittest.cc93
-rw-r--r--src/logging_filter_interpreter.cc10
-rw-r--r--src/lookahead_filter_interpreter.cc182
-rw-r--r--src/lookahead_filter_interpreter_unittest.cc51
-rw-r--r--src/metrics_filter_interpreter.cc73
-rw-r--r--src/mouse_interpreter.cc4
-rw-r--r--src/prop_registry.cc12
-rw-r--r--src/prop_registry_unittest.cc65
-rw-r--r--src/scaling_filter_interpreter.cc9
-rw-r--r--src/scaling_filter_interpreter_unittest.cc43
-rw-r--r--src/trend_classifying_filter_interpreter.cc64
-rw-r--r--src/util_unittest.cc47
-rwxr-xr-xtools/local_coverage_rate.sh2
-rwxr-xr-xtools/regression_test.sh2
-rwxr-xr-xtools/replay_log2
-rwxr-xr-xtools/tplog.py4
29 files changed, 401 insertions, 696 deletions
diff --git a/Android.bp b/Android.bp
index eb7d8ac..8be85fa 100644
--- a/Android.bp
+++ b/Android.bp
@@ -132,7 +132,6 @@ cc_test {
"src/immediate_interpreter_unittest.cc",
"src/integral_gesture_filter_interpreter_unittest.cc",
"src/interpreter_unittest.cc",
- "src/list_unittest.cc",
"src/logging_filter_interpreter_unittest.cc",
"src/lookahead_filter_interpreter_unittest.cc",
"src/mouse_interpreter_unittest.cc",
diff --git a/METADATA.android b/METADATA.android
index 00233ca..f12b10f 100644
--- a/METADATA.android
+++ b/METADATA.android
@@ -6,7 +6,7 @@ third_party {
type: GIT
value: "https://chromium.googlesource.com/chromiumos/platform/gestures/"
}
- version: "3059225019e295de1138574a16c0102c6845fefb"
- last_upgrade_date { year: 2023 month: 02 day: 27 }
+ version: "b6ae21cf67acbc76254be3677264b0ea472fce09"
+ last_upgrade_date { year: 2023 month: 04 day: 05 }
license_type: NOTICE
}
diff --git a/Makefile b/Makefile
index c6165e9..d04ce98 100644
--- a/Makefile
+++ b/Makefile
@@ -60,7 +60,6 @@ TEST_OBJECTS=\
$(OBJDIR)/immediate_interpreter_unittest.o \
$(OBJDIR)/integral_gesture_filter_interpreter_unittest.o \
$(OBJDIR)/interpreter_unittest.o \
- $(OBJDIR)/list_unittest.o \
$(OBJDIR)/logging_filter_interpreter_unittest.o \
$(OBJDIR)/lookahead_filter_interpreter_unittest.o \
$(OBJDIR)/non_linearity_filter_interpreter_unittest.o \
@@ -112,7 +111,7 @@ DESTDIR = .
CXXFLAGS+=\
-g \
- -std=gnu++11 \
+ -std=gnu++17 \
-fno-exceptions \
-fno-strict-aliasing \
-fPIC \
diff --git a/include/gestures.h b/include/gestures.h
index e4f7cc2..f3005a0 100644
--- a/include/gestures.h
+++ b/include/gestures.h
@@ -55,7 +55,8 @@ struct HardwareProperties {
float right;
// The maximum Y coordinate that the device can report.
float bottom;
- // The resolutions of the X and Y axes, in units per mm.
+ // The resolutions of the X and Y axes, in units per mm. Set to 0 if the
+ // resolution is unknown.
float res_x;
float res_y;
@@ -105,15 +106,6 @@ struct HardwareProperties {
#endif // __cplusplus
};
-// position is the (x,y) cartesian coord of the finger on the trackpad.
-// touch_major/minor are the large/small radii of the ellipse of the touching
-// finger. width_major/minor are also radii, but of the finger itself,
-// including a little bit that isn't touching. So, width* is generally a tad
-// larger than touch*.
-// tracking_id: If a finger is the same physical finger across two
-// consecutive frames, it must have the same tracking id; if it's a different
-// finger, it may (should) have a different tracking id.
-
// Warp: If a finger has the 'warp' flag set for an axis, it means that while
// the finger may have moved, it should not cause any motion in that direction.
// This may occur is some situations where we thought a finger was in one place,
@@ -167,16 +159,27 @@ struct HardwareProperties {
#define GESTURES_FINGER_WARP_Y (GESTURES_FINGER_WARP_Y_NON_MOVE | \
GESTURES_FINGER_WARP_Y_MOVE)
-// Describes a single contact on a touch surface. Unless otherwise noted, the
-// fields have the same meaning as the equivalent ABS_MT_... axis in the Linux
-// evdev protocol.
+// Describes a single contact on a touch surface. Generally, the fields have the
+// same meaning as the equivalent ABS_MT_... axis in the Linux evdev protocol.
struct FingerState {
+ // The large and small radii of the ellipse of the finger touching the pad.
float touch_major, touch_minor;
+
+ // The large and small radii of the ellipse of the finger, including parts
+ // that are hovering over the pad but not quite touching. Devices normally
+ // don't report these values, in which case they should be left at 0.
float width_major, width_minor;
float pressure;
float orientation;
+
float position_x;
float position_y;
+
+ // A number that identifies a single physical finger across consecutive
+ // frames. If a finger is the same physical finger across two consecutive
+ // frames, it must have the same tracking ID; if it's a different finger, it
+ // should have a different tracking ID. It should be ≥ 0 (see documentation
+ // comment for HardwareState::fingers).
short tracking_id;
// A bit field of flags that are used internally by the library. (See the
@@ -228,8 +231,13 @@ struct HardwareState {
unsigned short finger_cnt;
// The number of fingers touching the pad, which may be more than finger_cnt.
unsigned short touch_cnt;
- // A pointer to finger_cnt FingerState structs representing the contacts
- // currently being tracked.
+ // A pointer to an array of FingerState structs with finger_cnt entries,
+ // representing the contacts currently being tracked. The order in which
+ // FingerStates appear need not be stable between HardwareStates — only the
+ // tracking ID is used to track individual contacts over time. Accordingly,
+ // when a finger is lifted from the pad (and therefore its ABS_MT_TRACKING_ID
+ // becomes -1), the client should simply stop including it in this array,
+ // rather than including a final FingerState for it.
struct FingerState* fingers;
// Mouse axes, which have the same meanings as the Linux evdev axes of the
diff --git a/include/list.h b/include/list.h
deleted file mode 100644
index d5d94c4..0000000
--- a/include/list.h
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2011 The ChromiumOS Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GESTURES_LIST_H__
-#define GESTURES_LIST_H__
-
-#include "include/logging.h"
-#include "include/memory_manager.h"
-
-namespace gestures {
-
-// Elt must have the following members:
-// Elt* next_;
-// Elt* prev_;
-
-template<typename Elt>
-class List {
- public:
- List() { Init(); }
- ~List() { DeleteAll(); }
-
- // inserts new_elt before existing. Assumes existing is in list already.
- void InsertBefore(Elt *existing, Elt* new_elt) {
- size_++;
- Elt* pre_new = existing->prev_;
- pre_new->next_ = new_elt;
- new_elt->prev_ = pre_new;
- new_elt->next_ = existing;
- existing->prev_ = new_elt;
- }
-
- Elt* Unlink(Elt* existing) {
- if (Empty()) {
- Err("Can't pop from empty list!");
- return NULL;
- }
- size_--;
- existing->prev_->next_ = existing->next_;
- existing->next_->prev_ = existing->prev_;
- existing->prev_ = existing->next_ = NULL;
- return existing;
- }
-
- void PushFront(Elt* elt) { InsertBefore(sentinel_.next_, elt); }
- Elt* PopFront() { return Unlink(sentinel_.next_); }
- void PushBack(Elt* elt) { InsertBefore(&sentinel_, elt); }
- Elt* PopBack() { return Unlink(sentinel_.prev_); }
-
- virtual void DeleteAll() {
- while (!Empty())
- delete PopFront();
- }
-
- Elt* Head() const { return sentinel_.next_; }
- Elt* Tail() const { return sentinel_.prev_; }
- size_t size() const { return size_; }
- bool Empty() const { return size() == 0; }
-
- // Iterator-like methods
- Elt* Begin() const { return Head(); }
- Elt* End() const { return const_cast<Elt*>(&sentinel_); }
-
- void Init() {
- size_ = 0;
- sentinel_.next_ = sentinel_.prev_ = &sentinel_;
- }
-
- private:
- // sentinel element
- Elt sentinel_;
-
- size_t size_;
-};
-
-
-template<typename Elt>
-class MemoryManagedList : public List<Elt> {
- public:
- using List<Elt>::Empty;
- using List<Elt>::PopBack;
- using List<Elt>::PopFront;
- using List<Elt>::PushBack;
- using List<Elt>::PushFront;
-
- MemoryManagedList() { };
- ~MemoryManagedList() { DeleteAll(); }
-
- void Init(MemoryManager<Elt>* memory_manager) {
- memory_manager_ = memory_manager;
- List<Elt>::Init();
- }
-
- Elt* NewElt() {
- Elt* elt = memory_manager_->Allocate();
- AssertWithReturnValue(elt, NULL);
- elt->next_ = elt->prev_ = NULL;
- return elt;
- }
-
- Elt* PushNewEltBack() {
- AssertWithReturnValue(memory_manager_, NULL);
- Elt* elt = NewElt();
- AssertWithReturnValue(elt, NULL);
- PushBack(elt);
- return elt;
- }
-
- Elt* PushNewEltFront() {
- AssertWithReturnValue(memory_manager_, NULL);
- Elt* elt = NewElt();
- AssertWithReturnValue(elt, NULL);
- PushFront(elt);
- return elt;
- }
-
- void DeleteFront() {
- AssertWithReturn(memory_manager_);
- memory_manager_->Free(PopFront());
- }
-
- void DeleteBack() {
- AssertWithReturn(memory_manager_);
- memory_manager_->Free(PopBack());
- }
-
- virtual void DeleteAll() {
- while (!Empty())
- DeleteFront();
- }
- private:
- MemoryManager<Elt>* memory_manager_;
-};
-
-
-} // namespace gestures
-
-#endif // GESTURES_LIST_H__
diff --git a/include/lookahead_filter_interpreter.h b/include/lookahead_filter_interpreter.h
index 33dcc9b..2658daa 100644
--- a/include/lookahead_filter_interpreter.h
+++ b/include/lookahead_filter_interpreter.h
@@ -11,9 +11,9 @@
#include "include/filter_interpreter.h"
#include "include/finger_metrics.h"
#include "include/gestures.h"
-#include "include/list.h"
#include "include/prop_registry.h"
#include "include/tracer.h"
+#include "include/util.h"
#ifndef GESTURES_LOOKAHEAD_FILTER_INTERPRETER_H_
#define GESTURES_LOOKAHEAD_FILTER_INTERPRETER_H_
@@ -33,6 +33,7 @@ class LookaheadFilterInterpreter : public FilterInterpreter {
FRIEND_TEST(LookaheadFilterInterpreterTest, SimpleTest);
FRIEND_TEST(LookaheadFilterInterpreterTest, SpuriousCallbackTest);
FRIEND_TEST(LookaheadFilterInterpreterTest, VariableDelayTest);
+
public:
LookaheadFilterInterpreter(PropRegistry* prop_reg, Interpreter* next,
Tracer* tracer);
@@ -62,10 +63,7 @@ class LookaheadFilterInterpreter : public FilterInterpreter {
std::map<short, short> output_ids_; // input tracking ids -> output
stime_t due_;
- bool completed_;
-
- QState* next_;
- QState* prev_;
+ bool completed_ = false;
};
void LogVectors();
@@ -109,7 +107,6 @@ class LookaheadFilterInterpreter : public FilterInterpreter {
stime_t ExtraVariableDelay() const;
List<QState> queue_;
- List<QState> free_list_;
// The last id assigned to a contact (part of drumroll suppression)
short last_id_;
diff --git a/include/memory_manager.h b/include/memory_manager.h
deleted file mode 100644
index 26e096a..0000000
--- a/include/memory_manager.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2011 The ChromiumOS Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GESTURES_MEMORY_MANAGER_H_
-#define GESTURES_MEMORY_MANAGER_H_
-
-#include <new>
-
-#include "include/logging.h"
-#include "include/macros.h"
-
-namespace gestures {
-
-// A simple memory manager class that pre-allocates a size of
-// buffer and garbage collects freed variables. It is not intended
-// to be used directly. User classes should inherit the
-// MemoryManaged wrapper class and use the provided Allocate/Free
-// interface instead (see below).
-
-template<typename T>
-class MemoryManager {
- public:
- explicit MemoryManager(size_t size) : buf_(new T[size]),
- free_slots_(new T *[size]), used_mark_(new bool[size]()),
- max_size_(size), head_(size) {
- for (size_t i = 0; i < max_size_; i++)
- free_slots_[i] = buf_.get() + i;
- }
-
- size_t Size() const { return max_size_ - head_; }
- size_t MaxSize() const { return max_size_; }
-
- T* Allocate() {
- if (!head_) {
- Err("MemoryManager::Allocate: out of space");
- return NULL;
- }
-
- T* ptr = free_slots_[--head_];
- used_mark_[ptr - buf_.get()] = true;
- return ptr;
- }
-
- bool Free(T* ptr) {
- // Check for invalid pointer and double-free
- if (ptr < buf_.get() || ptr >= buf_.get() + max_size_) {
- Err("MemoryManager::Free: pointer out of bounds");
- return false;
- }
- size_t offset_in_bytes = reinterpret_cast<size_t>(ptr) -
- reinterpret_cast<size_t>(buf_.get());
- if (offset_in_bytes % sizeof(T)) {
- Err("MemoryManager::Free: unaligned pointer");
- return false;
- }
- size_t offset = ptr - buf_.get();
- if (!used_mark_[offset]) {
- Err("MemoryManager::Free: double-free");
- return false;
- }
-
- free_slots_[head_++] = ptr;
- used_mark_[offset] = false;
- return true;
- }
-
- private:
- std::unique_ptr<T[]> buf_;
- std::unique_ptr<T*[]> free_slots_;
- std::unique_ptr<bool[]> used_mark_;
- size_t max_size_;
- size_t head_;
- DISALLOW_COPY_AND_ASSIGN(MemoryManager<T>);
-};
-
-} // namespace gestures
-
-#endif // MEMORY_MANAGER_H_
diff --git a/include/metrics_filter_interpreter.h b/include/metrics_filter_interpreter.h
index 60d5898..518a47a 100644
--- a/include/metrics_filter_interpreter.h
+++ b/include/metrics_filter_interpreter.h
@@ -2,16 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <map>
#include <gtest/gtest.h> // for FRIEND_TEST
+#include <map>
#include "include/filter_interpreter.h"
#include "include/finger_metrics.h"
#include "include/gestures.h"
-#include "include/list.h"
-#include "include/memory_manager.h"
#include "include/prop_registry.h"
#include "include/tracer.h"
+#include "include/util.h"
#ifndef GESTURES_METRICS_FILTER_INTERPRETER_H_
#define GESTURES_METRICS_FILTER_INTERPRETER_H_
@@ -43,31 +42,22 @@ class MetricsFilterInterpreter : public FilterInterpreter {
template <class DataType, size_t kHistorySize>
struct State {
State() {}
- State(const DataType& fs, const HardwareState& hwstate) {
- Init(fs, hwstate);
- }
-
- void Init(const DataType& fs, const HardwareState& hwstate) {
- timestamp = hwstate.timestamp;
- data = fs;
- }
+ State(const DataType& fs, const HardwareState& hwstate)
+ : timestamp(hwstate.timestamp), data(fs) {}
static size_t MaxHistorySize() { return kHistorySize; }
stime_t timestamp;
DataType data;
- State<DataType, kHistorySize>* next_;
- State<DataType, kHistorySize>* prev_;
};
// struct for one finger's data of one frame.
typedef State<FingerState, 3> MState;
- typedef MemoryManagedList<MState> FingerHistory;
+ typedef List<MState> FingerHistory;
// Push the new data into the buffer.
- template <class StateType, class DataType>
- void AddNewStateToBuffer(MemoryManagedList<StateType>* history,
- const DataType& data,
+ void AddNewStateToBuffer(FingerHistory& history,
+ const FingerState& data,
const HardwareState& hwstate);
// Update the class with new finger data, check if there is any interesting
@@ -75,7 +65,7 @@ class MetricsFilterInterpreter : public FilterInterpreter {
void UpdateFingerState(const HardwareState& hwstate);
// Detect the noisy ground pattern and send GestureMetrics
- bool DetectNoisyGround(const FingerHistory* history);
+ bool DetectNoisyGround(FingerHistory& history);
// Update the class with new mouse movement data.
void UpdateMouseMovementState(const HardwareState& hwstate);
@@ -83,12 +73,8 @@ class MetricsFilterInterpreter : public FilterInterpreter {
// Compute interested statistics for the mouse history, send GestureMetrics.
void ReportMouseStatistics();
- // memory managers to prevent malloc during interrupt calls
- MemoryManager<MState> mstate_mm_;
- MemoryManager<FingerHistory> history_mm_;
-
// A map to store each finger's past data
- typedef std::map<short, FingerHistory*> FingerHistoryMap;
+ typedef std::map<short, FingerHistory> FingerHistoryMap;
FingerHistoryMap histories_;
// Device class (e.g. touchpad, mouse).
diff --git a/include/prop_registry.h b/include/prop_registry.h
index 836b98b..4545a33 100644
--- a/include/prop_registry.h
+++ b/include/prop_registry.h
@@ -46,9 +46,8 @@ class PropertyDelegate;
class Property {
public:
- Property(PropRegistry* parent, const char* name,
- PropertyDelegate* delegate)
- : gprop_(NULL), parent_(parent), delegate_(delegate), name_(name) {}
+ Property(PropRegistry* parent, const char* name)
+ : parent_(parent), name_(name) {}
virtual ~Property() {
if (parent_)
@@ -59,18 +58,9 @@ class Property {
virtual void CreatePropImpl() = 0;
void DestroyProp();
- // b/253585974
- // delegate used to get passed as a constructor parameter but that
- // led to a chance that the delegate was 'this' and setting the
- // delegate to 'this' in the initializer list allowed the property
- // creation to use 'this' before it was initialized. This could
- // lead to unexpected behavior and if you were lucky to a crash.
- //
- // Now the delegate is always NULL on initilization of the property
- // instance and after the delegate and property are completely
- // created the user should set the delegate in the constructor
- // body. This will allow access to this in a safe manner.
- void SetDelegate(PropertyDelegate* delegate);
+ void SetDelegate(PropertyDelegate* delegate) {
+ delegate_ = delegate;
+ }
const char* name() { return name_; }
// Returns a newly allocated Value object
@@ -91,9 +81,9 @@ class Property {
virtual void HandleGesturesPropWritten() = 0;
protected:
- GesturesProp* gprop_;
+ GesturesProp* gprop_ = NULL;
PropRegistry* parent_;
- PropertyDelegate* delegate_;
+ PropertyDelegate* delegate_ = NULL;
private:
const char* name_;
@@ -101,9 +91,8 @@ class Property {
class BoolProperty : public Property {
public:
- BoolProperty(PropRegistry* reg, const char* name, GesturesPropBool val,
- PropertyDelegate* delegate = NULL)
- : Property(reg, name, delegate), val_(val) {
+ BoolProperty(PropRegistry* reg, const char* name, GesturesPropBool val)
+ : Property(reg, name), val_(val) {
if (parent_)
parent_->Register(this);
}
@@ -118,8 +107,8 @@ class BoolProperty : public Property {
class BoolArrayProperty : public Property {
public:
BoolArrayProperty(PropRegistry* reg, const char* name, GesturesPropBool* vals,
- size_t count, PropertyDelegate* delegate = NULL)
- : Property(reg, name, delegate), vals_(vals), count_(count) {
+ size_t count)
+ : Property(reg, name), vals_(vals), count_(count) {
if (parent_)
parent_->Register(this);
}
@@ -134,9 +123,8 @@ class BoolArrayProperty : public Property {
class DoubleProperty : public Property {
public:
- DoubleProperty(PropRegistry* reg, const char* name, double val,
- PropertyDelegate* delegate = NULL)
- : Property(reg, name, delegate), val_(val) {
+ DoubleProperty(PropRegistry* reg, const char* name, double val)
+ : Property(reg, name), val_(val) {
if (parent_)
parent_->Register(this);
}
@@ -151,8 +139,8 @@ class DoubleProperty : public Property {
class DoubleArrayProperty : public Property {
public:
DoubleArrayProperty(PropRegistry* reg, const char* name, double* vals,
- size_t count, PropertyDelegate* delegate = NULL)
- : Property(reg, name, delegate), vals_(vals), count_(count) {
+ size_t count)
+ : Property(reg, name), vals_(vals), count_(count) {
if (parent_)
parent_->Register(this);
}
@@ -167,9 +155,8 @@ class DoubleArrayProperty : public Property {
class IntProperty : public Property {
public:
- IntProperty(PropRegistry* reg, const char* name, int val,
- PropertyDelegate* delegate = NULL)
- : Property(reg, name, delegate), val_(val) {
+ IntProperty(PropRegistry* reg, const char* name, int val)
+ : Property(reg, name), val_(val) {
if (parent_)
parent_->Register(this);
}
@@ -183,9 +170,9 @@ class IntProperty : public Property {
class IntArrayProperty : public Property {
public:
- IntArrayProperty(PropRegistry* reg, const char* name, int* vals, size_t count,
- PropertyDelegate* delegate = NULL)
- : Property(reg, name, delegate), vals_(vals), count_(count) {
+ IntArrayProperty(PropRegistry* reg, const char* name, int* vals,
+ size_t count)
+ : Property(reg, name), vals_(vals), count_(count) {
if (parent_)
parent_->Register(this);
}
@@ -200,9 +187,8 @@ class IntArrayProperty : public Property {
class StringProperty : public Property {
public:
- StringProperty(PropRegistry* reg, const char* name, const char* val,
- PropertyDelegate* delegate = NULL)
- : Property(reg, name, delegate), val_(val) {
+ StringProperty(PropRegistry* reg, const char* name, const char* val)
+ : Property(reg, name), val_(val) {
if (parent_)
parent_->Register(this);
}
diff --git a/include/trend_classifying_filter_interpreter.h b/include/trend_classifying_filter_interpreter.h
index b2e8436..92ae3d2 100644
--- a/include/trend_classifying_filter_interpreter.h
+++ b/include/trend_classifying_filter_interpreter.h
@@ -2,17 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <map>
-#include <set>
#include <gtest/gtest.h> // for FRIEND_TEST
+#include <map>
#include "include/filter_interpreter.h"
#include "include/finger_metrics.h"
#include "include/gestures.h"
-#include "include/list.h"
-#include "include/memory_manager.h"
#include "include/prop_registry.h"
#include "include/tracer.h"
+#include "include/util.h"
#ifndef GESTURES_TREND_CLASSIFYING_FILTER_INTERPRETER_H_
#define GESTURES_TREND_CLASSIFYING_FILTER_INTERPRETER_H_
@@ -151,12 +149,9 @@ private:
GESTURES_FINGER_TREND_DEC_TOUCH_MAJOR };
return flags[idx];
}
-
- KState* next_;
- KState* prev_;
};
- typedef MemoryManagedList<KState> FingerHistory;
+ typedef List<KState> FingerHistory;
// Trend types for internal use
enum TrendType {
@@ -169,7 +164,7 @@ private:
void UpdateFingerState(const HardwareState& hwstate);
// Push new finger data into the buffer and update values
- void AddNewStateToBuffer(FingerHistory* history, const FingerState& fs);
+ void AddNewStateToBuffer(FingerHistory& history, const FingerState& fs);
// Assess statistical significance with a classic two-tail hypothesis test
TrendType RunKTTest(const KState::KAxis* current, const size_t n_samples);
@@ -220,13 +215,9 @@ private:
const unsigned flag_decreasing,
unsigned* flags);
- // memory managers to prevent malloc during interrupt calls
- MemoryManager<KState> kstate_mm_;
- MemoryManager<FingerHistory> history_mm_;
-
// A map to store each finger's past coordinates and calculation
// intermediates
- typedef std::map<short, FingerHistory*> FingerHistoryMap;
+ typedef std::map<short, FingerHistory> FingerHistoryMap;
FingerHistoryMap histories_;
// Flag to turn on/off the trend classifying filter
diff --git a/include/util.h b/include/util.h
index 2e87a7b..f0c2a39 100644
--- a/include/util.h
+++ b/include/util.h
@@ -5,6 +5,7 @@
#ifndef GESTURES_UTIL_H_
#define GESTURES_UTIL_H_
+#include <list>
#include <map>
#include <set>
@@ -61,28 +62,16 @@ bool MapContainsKey(const Map& the_map, const Key& the_key) {
}
// Removes any ids from the map that are not finger ids in hs.
-// This implementation supports returning removed elements for
-// further processing.
-template<typename Data>
-void RemoveMissingIdsFromMap(std::map<short, Data>* the_map,
- const HardwareState& hs,
- std::map<short, Data>* removed) {
- removed->clear();
- for (typename std::map<short, Data>::const_iterator it =
- the_map->begin(); it != the_map->end(); ++it)
- if (!hs.GetFingerState((*it).first))
- (*removed)[it->first] = it->second;
- for (typename std::map<short, Data>::const_iterator it =
- removed->begin(); it != removed->end(); ++it)
- the_map->erase(it->first);
-}
-
-// Removes any ids from the map that are not finger ids in hs.
template<typename Data>
void RemoveMissingIdsFromMap(std::map<short, Data>* the_map,
const HardwareState& hs) {
std::map<short, Data> removed;
- RemoveMissingIdsFromMap(the_map, hs, &removed);
+ for (const auto& [key, value] : *the_map) {
+ if (!hs.GetFingerState(key))
+ removed[key] = value;
+ }
+ for (const auto& [key, value] : removed)
+ the_map->erase(key);
}
// Removes any ids from the set that are not finger ids in hs.
@@ -105,6 +94,29 @@ inline bool SetContainsValue(const Set& the_set,
return the_set.find(elt) != the_set.end();
}
+template<typename Elem>
+class List : public std::list<Elem> {
+public:
+ Elem& at(int offset) {
+ // Traverse to the appropriate offset
+ if (offset < 0) {
+ // negative offset is from end to begin
+ for (auto iter = this->rbegin(); iter != this->rend(); ++iter) {
+ if (++offset == 0)
+ return *iter;
+ }
+ } else {
+ // positive offset is from begin to end
+ for (auto iter = this->begin(); iter != this->end(); ++iter) {
+ if (offset-- == 0)
+ return *iter;
+ }
+ }
+ // Invalid offset
+ abort();
+ }
+};
+
} // namespace gestures
#endif // GESTURES_UTIL_H_
diff --git a/src/iir_filter_interpreter.cc b/src/iir_filter_interpreter.cc
index 0558ef6..042e0f5 100644
--- a/src/iir_filter_interpreter.cc
+++ b/src/iir_filter_interpreter.cc
@@ -41,6 +41,7 @@ IirFilterInterpreter::IirFilterInterpreter(PropRegistry* prop_reg,
a2_(prop_reg, "IIR a2", 0.412801598096189),
iir_dist_thresh_(prop_reg, "IIR Distance Threshold", 10),
adjust_iir_on_warp_(prop_reg, "Adjust IIR History On Warp", false) {
+ InitName();
b0_.SetDelegate(this);
b1_.SetDelegate(this);
b2_.SetDelegate(this);
@@ -48,7 +49,6 @@ IirFilterInterpreter::IirFilterInterpreter(PropRegistry* prop_reg,
a1_.SetDelegate(this);
a2_.SetDelegate(this);
iir_dist_thresh_.SetDelegate(this);
- InitName();
}
void IirFilterInterpreter::SyncInterpretImpl(HardwareState* hwstate,
diff --git a/src/immediate_interpreter.cc b/src/immediate_interpreter.cc
index 70369eb..7af423c 100644
--- a/src/immediate_interpreter.cc
+++ b/src/immediate_interpreter.cc
@@ -1095,7 +1095,7 @@ ImmediateInterpreter::ImmediateInterpreter(PropRegistry* prop_reg,
keyboard_touched_timeval_high_(prop_reg, "Keyboard Touched Timeval High",
0),
keyboard_touched_timeval_low_(prop_reg, "Keyboard Touched Timeval Low",
- 0, this),
+ 0),
keyboard_palm_prevent_timeout_(prop_reg, "Keyboard Palm Prevent Timeout",
0.5),
motion_tap_prevent_timeout_(prop_reg, "Motion Tap Prevent Timeout",
@@ -1136,6 +1136,7 @@ ImmediateInterpreter::ImmediateInterpreter(PropRegistry* prop_reg,
quick_acceleration_factor_(prop_reg, "Quick Acceleration Factor", 0.0) {
InitName();
requires_metrics_ = true;
+ keyboard_touched_timeval_low_.SetDelegate(this);
}
void ImmediateInterpreter::SyncInterpretImpl(HardwareState* hwstate,
diff --git a/src/list_unittest.cc b/src/list_unittest.cc
deleted file mode 100644
index 9c8ea74..0000000
--- a/src/list_unittest.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2011 The ChromiumOS Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <algorithm>
-#include <set>
-
-#include <gtest/gtest.h>
-
-#include "include/list.h"
-#include "include/util.h"
-
-namespace gestures {
-
-class ListTest : public ::testing::Test {};
-
-namespace {
-struct Node {
- explicit Node() : val_(-1) {}
- explicit Node(int val) : val_(val) {}
- int val_;
- Node* next_;
- Node* prev_;
-};
-
-void VerifyList(List<Node>& list) {
- Node* first = list.Head()->prev_; // sentinel
- Node* second = list.Head(); // next elt (sentinel or first element)
- std::set<Node*> seen_nodes;
- if (!list.Empty())
- EXPECT_NE(first, second);
- else
- EXPECT_EQ(first, second);
- seen_nodes.insert(second);
- for (size_t i = 0; i <= list.size(); ++i) {
- EXPECT_EQ(first->next_, second);
- EXPECT_EQ(second->prev_, first);
- if (i < list.size()) {
- first = second;
- second = second->next_;
- EXPECT_FALSE(SetContainsValue(seen_nodes, second));
- seen_nodes.insert(second);
- }
- }
- EXPECT_EQ(seen_nodes.size(), list.size() + 1);
- // second should now be sentinal tail
- Node* sen_tail = list.Tail()->next_;
- EXPECT_EQ(second, sen_tail);
-}
-}
-
-TEST(ListTest, SimpleTest) {
- List<Node> list;
- VerifyList(list);
- EXPECT_TRUE(list.Empty());
- EXPECT_EQ(0, list.size());
- list.PushFront(new Node(4));
- VerifyList(list);
- EXPECT_FALSE(list.Empty());
- EXPECT_EQ(1, list.size());
- list.PushFront(new Node(5));
- VerifyList(list);
- EXPECT_EQ(2, list.size());
- EXPECT_EQ(4, list.Tail()->val_);
- EXPECT_EQ(5, list.Head()->val_);
- list.PushBack(new Node(3));
- VerifyList(list);
- EXPECT_EQ(3, list.size());
-
- Node* node = list.PopFront();
- VerifyList(list);
- ASSERT_TRUE(node);
- EXPECT_EQ(5, node->val_);
- delete node;
-
- node = list.PopBack();
- VerifyList(list);
- ASSERT_TRUE(node);
- EXPECT_EQ(3, node->val_);
- delete node;
-
- node = list.PopBack();
- VerifyList(list);
- ASSERT_TRUE(node);
- EXPECT_EQ(4, node->val_);
- delete node;
-
- node = list.PopBack();
- VerifyList(list);
- EXPECT_EQ(NULL, node);
-}
-
-} // namespace gestures
diff --git a/src/logging_filter_interpreter.cc b/src/logging_filter_interpreter.cc
index d504607..2c43238 100644
--- a/src/logging_filter_interpreter.cc
+++ b/src/logging_filter_interpreter.cc
@@ -17,15 +17,19 @@ LoggingFilterInterpreter::LoggingFilterInterpreter(PropRegistry* prop_reg,
Interpreter* next,
Tracer* tracer)
: FilterInterpreter(prop_reg, next, tracer, true),
- event_logging_enable_(prop_reg, "Event Logging Enable", false, this),
- logging_notify_(prop_reg, "Logging Notify", 0, this),
- logging_reset_(prop_reg, "Logging Reset", 0, this),
+ event_logging_enable_(prop_reg, "Event Logging Enable", false),
+ logging_notify_(prop_reg, "Logging Notify", 0),
+ logging_reset_(prop_reg, "Logging Reset", 0),
log_location_(prop_reg, "Log Path",
"/var/log/xorg/touchpad_activity_log.txt"),
integrated_touchpad_(prop_reg, "Integrated Touchpad", false) {
InitName();
if (prop_reg && log_.get())
prop_reg->set_activity_log(log_.get());
+ event_logging_enable_.SetDelegate(this);
+ BoolWasWritten(&event_logging_enable_);
+ logging_notify_.SetDelegate(this);
+ logging_reset_.SetDelegate(this);
}
void LoggingFilterInterpreter::IntWasWritten(IntProperty* prop) {
diff --git a/src/lookahead_filter_interpreter.cc b/src/lookahead_filter_interpreter.cc
index f7abaf5..fea2c47 100644
--- a/src/lookahead_filter_interpreter.cc
+++ b/src/lookahead_filter_interpreter.cc
@@ -45,41 +45,32 @@ LookaheadFilterInterpreter::LookaheadFilterInterpreter(
void LookaheadFilterInterpreter::SyncInterpretImpl(HardwareState* hwstate,
stime_t* timeout) {
- // Push back into queue
- if (free_list_.Empty()) {
- Err("Can't accept new hwstate b/c we're out of nodes!");
- Err("Now: %f, interpreter_due_ %f", hwstate->timestamp, interpreter_due_);
- Err("Dump of queue:");
- for (QState* it = queue_.Begin(); it != queue_.End(); it = it->next_)
- Err("Due: %f%s", it->due_, it->completed_ ? " (c)" : "");
- return;
- }
- QState* node = free_list_.PopFront();
- node->set_state(*hwstate);
+ // Keep track of where the last node is in the current queue_
+ auto const queue_was_not_empty = !queue_.empty();
+ QState* old_back_node = queue_was_not_empty ? &queue_.back() : nullptr;
+ // Allocate and initialize a new node on the end of the queue_
+ auto& new_node = queue_.emplace_back(hwprops_->max_finger_cnt);
+ new_node.set_state(*hwstate);
double delay = max(0.0, min<stime_t>(kMaxDelay, min_delay_.val_));
- node->due_ = hwstate->timestamp + delay;
- node->completed_ = false;
- if (queue_.Empty())
- node->output_ids_.clear();
- else
- node->output_ids_ = queue_.Tail()->output_ids_;
- // At this point, if ExtraVariableDelay() > 0, queue_.Tail()->due_ may have
- // ExtraVariableDelay() applied, but node->due_ does not, yet.
- if (!queue_.Empty() &&
- (queue_.Tail()->due_ - node->due_ > ExtraVariableDelay())) {
+ new_node.due_ = hwstate->timestamp + delay;
+ if (queue_was_not_empty)
+ new_node.output_ids_ = old_back_node->output_ids_;
+ // At this point, if ExtraVariableDelay() > 0, old_back_node.due_ may have
+ // ExtraVariableDelay() applied, but new_node.due_ does not, yet.
+ if (queue_was_not_empty &&
+ (old_back_node->due_ - new_node.due_ > ExtraVariableDelay())) {
Err("Clock changed backwards. Flushing queue.");
stime_t next_timeout = NO_DEADLINE;
- QState* q_node = queue_.Head();
+ auto q_node_iter = queue_.begin();
do {
- if (!q_node->completed_)
- next_->SyncInterpret(&q_node->state_, &next_timeout);
- q_node = q_node->next_;
- free_list_.PushBack(queue_.PopFront());
- } while (!queue_.Empty());
+ if (!(*q_node_iter).completed_)
+ next_->SyncInterpret(&(*q_node_iter).state_, &next_timeout);
+ ++q_node_iter;
+ queue_.pop_front();
+ } while (queue_.size() > 1);
interpreter_due_ = -1.0;
last_interpreted_time_ = -1.0;
}
- queue_.PushBack(node);
AssignTrackingIds();
AttemptInterpolation();
UpdateInterpreterDue(interpreter_due_ < 0.0 ?
@@ -88,10 +79,10 @@ void LookaheadFilterInterpreter::SyncInterpretImpl(HardwareState* hwstate,
HandleTimerImpl(hwstate->timestamp, timeout);
// Copy finger flags for upstream filters.
- QState* q_node = queue_.Head();
- if (q_node->state_.SameFingersAs(*hwstate)) {
+ QState& q_node = queue_.front();
+ if (q_node.state_.SameFingersAs(*hwstate)) {
for (size_t i = 0; i < hwstate->finger_cnt; i++) {
- hwstate->fingers[i].flags = q_node->state_.fingers[i].flags;
+ hwstate->fingers[i].flags = q_node.state_.fingers[i].flags;
}
}
}
@@ -143,27 +134,27 @@ void LookaheadFilterInterpreter::AssignTrackingIds() {
// Always reassign trackingID on the very first hwstate so that
// the next hwstate can inherit the trackingID mapping.
if (queue_.size() == 1) {
- QState* tail = queue_.Tail();
- HardwareState* hs = &tail->state_;
+ QState& tail = queue_.back();
+ HardwareState* hs = &tail.state_;
for (size_t i = 0; i < hs->finger_cnt; i++) {
FingerState* fs = &hs->fingers[i];
- tail->output_ids_[fs->tracking_id] = NextTrackingId();
- fs->tracking_id = tail->output_ids_[fs->tracking_id];
+ tail.output_ids_[fs->tracking_id] = NextTrackingId();
+ fs->tracking_id = tail.output_ids_[fs->tracking_id];
}
if (hs->finger_cnt > 0)
- tail->due_ += ExtraVariableDelay();
+ tail.due_ += ExtraVariableDelay();
}
return;
}
- QState* tail = queue_.Tail();
- HardwareState* hs = &tail->state_;
- QState* prev_qs = queue_.size() < 2 ? NULL : tail->prev_;
+ auto& tail = queue_.at(-1);
+ HardwareState* hs = &tail.state_;
+ QState* prev_qs = queue_.size() < 2 ? NULL : &(queue_.at(-2));
HardwareState* prev_hs = prev_qs ? &prev_qs->state_ : NULL;
- QState* prev2_qs = queue_.size() < 3 ? NULL : prev_qs->prev_;
+ QState* prev2_qs = queue_.size() < 3 ? NULL : &(queue_.at(-3));
HardwareState* prev2_hs = prev2_qs ? &prev2_qs->state_ : NULL;
- RemoveMissingIdsFromMap(&tail->output_ids_, *hs);
+ RemoveMissingIdsFromMap(&tail.output_ids_, *hs);
float dt = prev_hs ? hs->timestamp - prev_hs->timestamp : 1.0;
float prev_dt =
prev_hs && prev2_hs ? prev_hs->timestamp - prev2_hs->timestamp : 1.0;
@@ -186,11 +177,11 @@ void LookaheadFilterInterpreter::AssignTrackingIds() {
FingerState* fs = &hs->fingers[i];
const short old_id = fs->tracking_id;
bool new_finger = false;
- if (!MapContainsKey(tail->output_ids_, fs->tracking_id)) {
- tail->output_ids_[fs->tracking_id] = NextTrackingId();
+ if (!MapContainsKey(tail.output_ids_, fs->tracking_id)) {
+ tail.output_ids_[fs->tracking_id] = NextTrackingId();
new_finger_present = new_finger = true;
}
- fs->tracking_id = tail->output_ids_[fs->tracking_id];
+ fs->tracking_id = tail.output_ids_[fs->tracking_id];
if (new_finger)
continue;
if (!prev_hs) {
@@ -239,8 +230,8 @@ void LookaheadFilterInterpreter::AssignTrackingIds() {
if (prev_qs->output_ids_[old_id] != prev2_qs->output_ids_[old_id]) {
prev_qs->output_ids_[old_id] = prev2_qs->output_ids_[old_id];
prev_fs->tracking_id = prev_qs->output_ids_[old_id];
- tail->output_ids_[old_id] = prev2_qs->output_ids_[old_id];
- fs->tracking_id = tail->output_ids_[old_id];
+ tail.output_ids_[old_id] = prev2_qs->output_ids_[old_id];
+ fs->tracking_id = tail.output_ids_[old_id];
continue;
}
}
@@ -269,7 +260,7 @@ void LookaheadFilterInterpreter::AssignTrackingIds() {
continue;
}
separated_fingers.insert(old_id);
- SeparateFinger(tail, fs, old_id);
+ SeparateFinger(&tail, fs, old_id);
// Separating fingers shouldn't tap.
fs->flags |= GESTURES_FINGER_NO_TAP;
// Try to also flag the previous frame, if we didn't execute it yet
@@ -298,10 +289,10 @@ void LookaheadFilterInterpreter::AssignTrackingIds() {
Err("How is input ID missing from prev state? %d", input_id);
continue;
}
- short new_bad_output_id = tail->output_ids_[input_id];
+ short new_bad_output_id = tail.output_ids_[input_id];
short prev_output_id = prev_qs->output_ids_[input_id];
- tail->output_ids_[input_id] = prev_output_id;
- FingerState* fs = tail->state_.GetFingerState(new_bad_output_id);
+ tail.output_ids_[input_id] = prev_output_id;
+ FingerState* fs = tail.state_.GetFingerState(new_bad_output_id);
if (!fs) {
Err("Can't find finger state.");
continue;
@@ -316,7 +307,7 @@ void LookaheadFilterInterpreter::AssignTrackingIds() {
LiftoffJumpStarting(*hs, *prev_hs, *prev2_hs))) {
// Possibly add some extra delay to correct, incase this separation
// shouldn't have occurred or if the finger may be lifting from the pad.
- tail->due_ += ExtraVariableDelay();
+ tail.due_ += ExtraVariableDelay();
}
}
@@ -356,11 +347,12 @@ void LookaheadFilterInterpreter::TapDownOccurringGesture(stime_t now) {
return;
if (queue_.size() < 2)
return; // Not enough data to know
- HardwareState& hs = queue_.Tail()->state_;
- if (queue_.Tail()->state_.timestamp != now)
+ HardwareState& hs = queue_.back().state_;
+ if (queue_.back().state_.timestamp != now)
return; // We didn't push a new hardware state now
- // See if latest hwstate has finger that previous doesn't
- HardwareState& prev_hs = queue_.Tail()->prev_->state_;
+ // See if latest hwstate has finger that previous doesn't.
+ // Get the state_ of back->prev
+ HardwareState& prev_hs = queue_.at(-2).state_;
if (hs.finger_cnt > prev_hs.finger_cnt) {
// Finger was added.
ProduceGesture(Gesture(kGestureFling, prev_hs.timestamp, hs.timestamp,
@@ -396,33 +388,26 @@ short LookaheadFilterInterpreter::NextTrackingId() {
void LookaheadFilterInterpreter::AttemptInterpolation() {
if (queue_.size() < 2)
return;
- QState* new_node = queue_.Tail();
- QState* prev = new_node->prev_;
- if (new_node->state_.timestamp - prev->state_.timestamp <
- split_min_period_.val_)
+ QState& new_node = queue_.at(-1);
+ QState& prev = queue_.at(-2);
+ if (new_node.state_.timestamp - prev.state_.timestamp <
+ split_min_period_.val_) {
return; // Nodes came in too quickly to need interpolation
- if (!prev->state_.SameFingersAs(new_node->state_))
- return;
- QState* node = free_list_.PopFront();
- if (!node) {
- Err("out of nodes?");
- return;
}
- node->state_.fingers = node->fs_.get();
- node->completed_ = false;
- Interpolate(prev->state_, new_node->state_, &node->state_);
+ if (!prev.state_.SameFingersAs(new_node.state_))
+ return;
+ auto node = QState(hwprops_->max_finger_cnt);
+ node.state_.fingers = node.fs_.get();
+ node.completed_ = false;
+ Interpolate(prev.state_, new_node.state_, &node.state_);
double delay = max(0.0, min<stime_t>(kMaxDelay, min_delay_.val_));
- node->due_ = node->state_.timestamp + delay;
+ node.due_ = node.state_.timestamp + delay;
- if (node->state_.timestamp <= last_interpreted_time_) {
- // Time wouldn't seem monotonically increasing w/ this new event, so
- // discard it.
- free_list_.PushBack(node);
- return;
+ // Make sure time seems monotonically increasing w/ this new event
+ if (node.state_.timestamp > last_interpreted_time_) {
+ queue_.insert(--queue_.end(), std::move(node));
}
-
- queue_.InsertBefore(new_node, node);
}
void LookaheadFilterInterpreter::HandleTimerImpl(stime_t now,
@@ -440,12 +425,16 @@ void LookaheadFilterInterpreter::HandleTimerImpl(stime_t now,
last_interpreted_time_ = now;
next_->HandleTimer(now, &next_timeout);
} else {
- if (queue_.Empty())
+ if (queue_.empty())
break;
// Get next uncompleted and overdue hwstate
- QState* node = queue_.Head();
- while (node != queue_.Tail() && node->completed_)
- node = node->next_;
+ auto node = &queue_.back();
+ for (auto& elem : queue_) {
+ if (!elem.completed_) {
+ node = &elem;
+ break;
+ }
+ }
if (node->completed_ || node->due_ > now)
break;
next_timeout = NO_DEADLINE;
@@ -471,8 +460,9 @@ void LookaheadFilterInterpreter::HandleTimerImpl(stime_t now,
next_->SyncInterpret(&hs_copy, &next_timeout);
// Clear previously completed nodes, but keep at least two nodes.
- while (queue_.size() > 2 && queue_.Head()->completed_)
- free_list_.PushBack(queue_.PopFront());
+ while (queue_.size() > 2 && queue_.front().completed_) {
+ queue_.pop_front();
+ }
// Mark current node completed. This should be the only completed
// node in the queue.
@@ -489,7 +479,7 @@ void LookaheadFilterInterpreter::HandleTimerImpl(stime_t now,
}
void LookaheadFilterInterpreter::ConsumeGesture(const Gesture& gesture) {
- QState* node = queue_.Head();
+ QState& node = queue_.front();
float distance_sq = 0.0;
// Slow movements should potentially be suppressed
@@ -516,10 +506,11 @@ void LookaheadFilterInterpreter::ConsumeGesture(const Gesture& gesture) {
return;
}
// Speed is slow. Suppress if fingers have changed.
- for (QState* iter = node->next_; iter != queue_.End(); iter = iter->next_)
- if (!node->state_.SameFingersAs(iter->state_) ||
- (node->state_.buttons_down != iter->state_.buttons_down))
+ for (auto iter = ++queue_.begin(); iter != queue_.end(); ++iter) {
+ if (!node.state_.SameFingersAs((*iter).state_) ||
+ (node.state_.buttons_down != (*iter).state_.buttons_down))
return; // suppress
+ }
ProduceGesture(gesture);
}
@@ -532,11 +523,10 @@ void LookaheadFilterInterpreter::UpdateInterpreterDue(
// timeout, so we use -DBL_MAX as the invalid value.
stime_t next_hwstate_timeout = -DBL_MAX;
// Scan queue_ to find when next hwstate is due.
- for (QState* node = queue_.Begin(); node != queue_.End();
- node = node->next_) {
- if (node->completed_)
+ for (auto& elem : queue_) {
+ if (elem.completed_)
continue;
- next_hwstate_timeout = node->due_ - now;
+ next_hwstate_timeout = elem.due_ - now;
break;
}
@@ -557,13 +547,7 @@ void LookaheadFilterInterpreter::Initialize(
MetricsProperties* mprops,
GestureConsumer* consumer) {
FilterInterpreter::Initialize(hwprops, NULL, mprops, consumer);
- const size_t kMaxQNodes = 16;
- queue_.DeleteAll();
- free_list_.DeleteAll();
- for (size_t i = 0; i < kMaxQNodes; ++i) {
- QState* node = new QState(hwprops_->max_finger_cnt);
- free_list_.PushBack(node);
- }
+ queue_.clear();
}
stime_t LookaheadFilterInterpreter::ExtraVariableDelay() const {
@@ -571,13 +555,13 @@ stime_t LookaheadFilterInterpreter::ExtraVariableDelay() const {
}
LookaheadFilterInterpreter::QState::QState()
- : max_fingers_(0), completed_(false), next_(NULL), prev_(NULL) {
+ : max_fingers_(0) {
fs_.reset();
state_.fingers = NULL;
}
LookaheadFilterInterpreter::QState::QState(unsigned short max_fingers)
- : max_fingers_(max_fingers), completed_(false), next_(NULL), prev_(NULL) {
+ : max_fingers_(max_fingers) {
fs_.reset(new FingerState[max_fingers]);
state_.fingers = fs_.get();
}
diff --git a/src/lookahead_filter_interpreter_unittest.cc b/src/lookahead_filter_interpreter_unittest.cc
index 788d785..1345daf 100644
--- a/src/lookahead_filter_interpreter_unittest.cc
+++ b/src/lookahead_filter_interpreter_unittest.cc
@@ -175,7 +175,7 @@ TEST(LookaheadFilterInterpreterTest, SimpleTest) {
if (newtimeout < 0.0)
EXPECT_DOUBLE_EQ(NO_DEADLINE, newtimeout);
if (i == 5) {
- EXPECT_EQ(reinterpret_cast<Gesture*>(NULL), out);
+ EXPECT_EQ(nullptr, out);
} else {
// Expect movement
ASSERT_TRUE(out);
@@ -389,19 +389,19 @@ TEST(LookaheadFilterInterpreterTest, SpuriousCallbackTest) {
stime_t timeout = NO_DEADLINE;
Gesture* out = wrapper.SyncInterpret(&hs, &timeout);
- EXPECT_EQ(reinterpret_cast<Gesture*>(NULL), out);
+ EXPECT_EQ(nullptr, out);
EXPECT_FLOAT_EQ(interpreter->min_delay_.val_, timeout);
out = wrapper.HandleTimer(hs.timestamp + interpreter->min_delay_.val_,
&timeout);
- EXPECT_EQ(reinterpret_cast<Gesture*>(NULL), out);
+ EXPECT_EQ(nullptr, out);
EXPECT_FLOAT_EQ(1.0, timeout);
out = wrapper.HandleTimer(hs.timestamp + interpreter->min_delay_.val_ +
0.25,
&timeout);
- EXPECT_EQ(reinterpret_cast<Gesture*>(NULL), out);
+ EXPECT_EQ(nullptr, out);
EXPECT_FLOAT_EQ(0.75, timeout);
}
@@ -640,20 +640,20 @@ TEST(LookaheadFilterInterpreterTest, InterpolationOverdueTest) {
stime_t timeout = NO_DEADLINE;
Gesture* out = wrapper.SyncInterpret(&hs[0], &timeout);
- EXPECT_EQ(reinterpret_cast<Gesture*>(NULL), out);
+ EXPECT_EQ(nullptr, out);
EXPECT_FLOAT_EQ(timeout, interpreter->min_delay_.val_);
stime_t now = hs[0].timestamp + timeout;
timeout = NO_DEADLINE;
out = wrapper.HandleTimer(now, &timeout);
- ASSERT_NE(reinterpret_cast<Gesture*>(NULL), out);
+ ASSERT_NE(nullptr, out);
EXPECT_EQ(kGestureTypeMove, out->type);
EXPECT_EQ(1, out->details.move.dy);
EXPECT_DOUBLE_EQ(timeout, 0.700);
timeout = NO_DEADLINE;
out = wrapper.SyncInterpret(&hs[1], &timeout);
- ASSERT_NE(reinterpret_cast<Gesture*>(NULL), out);
+ ASSERT_NE(nullptr, out);
EXPECT_EQ(kGestureTypeMove, out->type);
EXPECT_EQ(2, out->details.move.dy);
EXPECT_GE(timeout, 0.0);
@@ -788,42 +788,42 @@ TEST(LookaheadFilterInterpreterTest, QuickMoveTest) {
wrapper.Reset(interpreter.get());
stime_t timeout = NO_DEADLINE;
- List<LookaheadFilterInterpreter::QState>* queue = &interpreter->queue_;
+ const auto& queue = interpreter->queue_;
// Pushing the first event
wrapper.SyncInterpret(&hs[0], &timeout);
- EXPECT_EQ(queue->size(), 1);
- EXPECT_EQ(queue->Tail()->fs_[0].tracking_id, 1);
+ EXPECT_EQ(queue.size(), 1);
+ EXPECT_EQ(queue.back().fs_[0].tracking_id, 1);
// Expecting Drumroll detected and ID reassigned 1 -> 2.
wrapper.SyncInterpret(&hs[1], &timeout);
- EXPECT_EQ(queue->size(), 2);
- EXPECT_EQ(queue->Tail()->fs_[0].tracking_id, 2);
+ EXPECT_EQ(queue.size(), 2);
+ EXPECT_EQ(queue.back().fs_[0].tracking_id, 2);
// Expecting Drumroll detected and ID reassigned 1 -> 3.
wrapper.SyncInterpret(&hs[2], &timeout);
- EXPECT_EQ(queue->size(), 3);
- EXPECT_EQ(queue->Tail()->fs_[0].tracking_id, 3);
+ EXPECT_EQ(queue.size(), 3);
+ EXPECT_EQ(queue.back().fs_[0].tracking_id, 3);
// Removing the touch.
wrapper.SyncInterpret(&hs[3], &timeout);
- EXPECT_EQ(queue->size(), 4);
+ EXPECT_EQ(queue.size(), 4);
// New event comes, old events removed from the queue.
// New finger tracking ID assigned 2 - > 4.
wrapper.SyncInterpret(&hs[4], &timeout);
- EXPECT_EQ(queue->size(), 2);
- EXPECT_EQ(queue->Tail()->fs_[0].tracking_id, 4);
+ EXPECT_EQ(queue.size(), 2);
+ EXPECT_EQ(queue.back().fs_[0].tracking_id, 4);
// Expecting Drumroll detected and ID reassigned 2 -> 5.
wrapper.SyncInterpret(&hs[5], &timeout);
- EXPECT_EQ(queue->Tail()->fs_[0].tracking_id, 5);
+ EXPECT_EQ(queue.back().fs_[0].tracking_id, 5);
// Expecting Quick movement detected and ID correction 5 -> 4.
wrapper.SyncInterpret(&hs[6], &timeout);
- EXPECT_EQ(queue->Tail()->fs_[0].tracking_id, 4);
- EXPECT_EQ(queue->Tail()->prev_->fs_[0].tracking_id, 4);
- EXPECT_EQ(queue->Tail()->prev_->prev_->fs_[0].tracking_id, 4);
+ EXPECT_EQ(interpreter->queue_.at(-1).fs_[0].tracking_id, 4);
+ EXPECT_EQ(interpreter->queue_.at(-2).fs_[0].tracking_id, 4);
+ EXPECT_EQ(interpreter->queue_.at(-3).fs_[0].tracking_id, 4);
}
struct QuickSwipeTestInputs {
@@ -1263,16 +1263,17 @@ TEST(LookaheadFilterInterpreterTest, SemiMtNoTrackingIdAssignmentTest) {
wrapper.Reset(interpreter.get());
stime_t timeout = NO_DEADLINE;
- List<LookaheadFilterInterpreter::QState>* queue = &interpreter->queue_;
+ const auto& queue = interpreter->queue_;
wrapper.SyncInterpret(&hs[0], &timeout);
- EXPECT_EQ(queue->Tail()->fs_[0].tracking_id, 20);
+ EXPECT_EQ(queue.back().fs_[0].tracking_id, 20);
// Test if the fingers in queue have the same tracking ids from input.
for (size_t i = 1; i < arraysize(hs); i++) {
wrapper.SyncInterpret(&hs[i], &timeout);
- EXPECT_EQ(queue->Tail()->fs_[0].tracking_id, 20); // the same input id
- EXPECT_EQ(queue->Tail()->fs_[1].tracking_id, 21);
+ EXPECT_EQ(queue.back().fs_[0].tracking_id, 20); // the same input id
+ EXPECT_EQ(queue.back().fs_[1].tracking_id, 21);
}
}
+
} // namespace gestures
diff --git a/src/metrics_filter_interpreter.cc b/src/metrics_filter_interpreter.cc
index e608f23..a19b814 100644
--- a/src/metrics_filter_interpreter.cc
+++ b/src/metrics_filter_interpreter.cc
@@ -22,8 +22,6 @@ MetricsFilterInterpreter::MetricsFilterInterpreter(
Tracer* tracer,
GestureInterpreterDeviceClass devclass)
: FilterInterpreter(NULL, next, tracer, false),
- mstate_mm_(kMaxFingers * MState::MaxHistorySize()),
- history_mm_(kMaxFingers),
devclass_(devclass),
mouse_movement_session_index_(0),
mouse_movement_current_session_length(0),
@@ -44,7 +42,7 @@ MetricsFilterInterpreter::MetricsFilterInterpreter(
}
void MetricsFilterInterpreter::SyncInterpretImpl(HardwareState* hwstate,
- stime_t* timeout) {
+ stime_t* timeout) {
if (devclass_ == GESTURES_DEVCLASS_TOUCHPAD) {
// Right now, we only want to update finger states for built-in touchpads
// because all the generated metrics gestures would be put under each
@@ -66,22 +64,16 @@ void MetricsFilterInterpreter::SyncInterpretImpl(HardwareState* hwstate,
next_->SyncInterpret(hwstate, timeout);
}
-template <class StateType, class DataType>
void MetricsFilterInterpreter::AddNewStateToBuffer(
- MemoryManagedList<StateType>* history,
- const DataType& data,
+ FingerHistory& history,
+ const FingerState& data,
const HardwareState& hwstate) {
// The history buffer is already full, pop one
- if (history->size() == StateType::MaxHistorySize())
- history->DeleteFront();
+ if (history.size() == MState::MaxHistorySize())
+ history.pop_front();
// Push the new finger state to the back of buffer
- StateType* current = history->PushNewEltBack();
- if (!current) {
- Err("MetricsFilterInterpreter buffer out of space");
- return;
- }
- current->Init(data, hwstate);
+ (void)history.emplace_back(data, hwstate);
}
void MetricsFilterInterpreter::UpdateMouseMovementState(
@@ -138,67 +130,48 @@ void MetricsFilterInterpreter::ReportMouseStatistics() {
void MetricsFilterInterpreter::UpdateFingerState(
const HardwareState& hwstate) {
- FingerHistoryMap removed;
- RemoveMissingIdsFromMap(&histories_, hwstate, &removed);
- for (FingerHistoryMap::const_iterator it =
- removed.begin(); it != removed.end(); ++it) {
- it->second->DeleteAll();
- history_mm_.Free(it->second);
-}
+ RemoveMissingIdsFromMap(&histories_, hwstate);
FingerState *fs = hwstate.fingers;
for (short i = 0; i < hwstate.finger_cnt; i++) {
- FingerHistory* hp;
-
// Update the map if the contact is new
if (!MapContainsKey(histories_, fs[i].tracking_id)) {
- hp = history_mm_.Allocate();
- if (!hp) {
- Err("FingerHistory out of space");
- continue;
- }
- hp->Init(&mstate_mm_);
- histories_[fs[i].tracking_id] = hp;
- } else {
- hp = histories_[fs[i].tracking_id];
+ histories_[fs[i].tracking_id] = FingerHistory{};
}
+ auto& href = histories_[fs[i].tracking_id];
// Check if the finger history contains interesting patterns
- AddNewStateToBuffer(hp, fs[i], hwstate);
- DetectNoisyGround(hp);
+ AddNewStateToBuffer(href, fs[i], hwstate);
+ DetectNoisyGround(href);
}
}
-bool MetricsFilterInterpreter::DetectNoisyGround(
- const FingerHistory* history) {
- MState* current = history->Tail();
- size_t n_samples = history->size();
+bool MetricsFilterInterpreter::DetectNoisyGround(FingerHistory& history) {
// Noise pattern takes 3 samples
- if (n_samples < 3)
+ if (history.size() < 3)
return false;
- MState* past_1 = current->prev_;
- MState* past_2 = past_1->prev_;
+ auto current = history.at(-1);
+ auto past_1 = history.at(-2);
+ auto past_2 = history.at(-3);
// Noise pattern needs to happen in a short period of time
- if(current->timestamp - past_2->timestamp >
- noisy_ground_time_threshold_.val_) {
+ if (current.timestamp - past_2.timestamp > noisy_ground_time_threshold_.val_)
return false;
- }
// vec[when][x,y]
float vec[2][2];
- vec[0][0] = current->data.position_x - past_1->data.position_x;
- vec[0][1] = current->data.position_y - past_1->data.position_y;
- vec[1][0] = past_1->data.position_x - past_2->data.position_x;
- vec[1][1] = past_1->data.position_y - past_2->data.position_y;
+ vec[0][0] = current.data.position_x - past_1.data.position_x;
+ vec[0][1] = current.data.position_y - past_1.data.position_y;
+ vec[1][0] = past_1.data.position_x - past_2.data.position_x;
+ vec[1][1] = past_1.data.position_y - past_2.data.position_y;
const float thr = noisy_ground_distance_threshold_.val_;
// We dictate the noise pattern as two consecutive big moves in
// opposite directions in either X or Y
for (size_t i = 0; i < arraysize(vec[0]); i++)
if ((vec[0][i] < -thr && vec[1][i] > thr) ||
(vec[0][i] > thr && vec[1][i] < -thr)) {
- ProduceGesture(Gesture(kGestureMetrics, past_2->timestamp,
- current->timestamp, kGestureMetricsTypeNoisyGround,
+ ProduceGesture(Gesture(kGestureMetrics, past_2.timestamp,
+ current.timestamp, kGestureMetricsTypeNoisyGround,
vec[0][i], vec[1][i]));
return true;
}
diff --git a/src/mouse_interpreter.cc b/src/mouse_interpreter.cc
index b26de8f..f3055b3 100644
--- a/src/mouse_interpreter.cc
+++ b/src/mouse_interpreter.cc
@@ -29,8 +29,7 @@ MouseInterpreter::MouseInterpreter(PropRegistry* prop_reg, Tracer* tracer)
scroll_accel_curve_, sizeof(scroll_accel_curve_) / sizeof(double)),
scroll_max_allowed_input_speed_(prop_reg,
"Mouse Scroll Max Input Speed",
- 177.0,
- this),
+ 177.0),
force_scroll_wheel_emulation_(prop_reg,
"Force Scroll Wheel Emulation",
false),
@@ -53,6 +52,7 @@ MouseInterpreter::MouseInterpreter(PropRegistry* prop_reg, Tracer* tracer)
scroll_accel_curve_[2] = 2.5737e-02;
scroll_accel_curve_[3] = 8.0428e-05;
scroll_accel_curve_[4] = -9.1149e-07;
+ scroll_max_allowed_input_speed_.SetDelegate(this);
}
void MouseInterpreter::SyncInterpretImpl(HardwareState* hwstate,
diff --git a/src/prop_registry.cc b/src/prop_registry.cc
index 58e3a1a..2d9d454 100644
--- a/src/prop_registry.cc
+++ b/src/prop_registry.cc
@@ -70,18 +70,6 @@ void Property::DestroyProp() {
gprop_ = NULL;
}
-void Property::SetDelegate(PropertyDelegate* delegate) {
- bool delegate_was_late_set = !delegate_ && delegate;
- delegate_ = delegate;
- // In the normal path of creation of a property with a parent, the
- // delegate is set late and the CreatePropImpl will not call the
- // WasWritten method. So catch the transition from NULL to not
- // NULL in this condition and make sure to call the initial
- // WasWritten to mimick the original code.
- if (delegate_was_late_set && parent_ && parent_->PropProvider())
- HandleGesturesPropWritten();
-}
-
void BoolProperty::CreatePropImpl() {
GesturesPropBool orig_val = val_;
gprop_ = parent_->PropProvider()->create_bool_fn(
diff --git a/src/prop_registry_unittest.cc b/src/prop_registry_unittest.cc
index 23ba9d8..503a552 100644
--- a/src/prop_registry_unittest.cc
+++ b/src/prop_registry_unittest.cc
@@ -48,7 +48,8 @@ TEST(PropRegistryTest, SimpleTest) {
PropRegistryTestDelegate delegate;
int expected_call_cnt = 0;
- BoolProperty bp1(&reg, "hi", false, &delegate);
+ BoolProperty bp1(&reg, "hi", false);
+ bp1.SetDelegate(&delegate);
EXPECT_TRUE(strstr(ValueForProperty(bp1).c_str(), "false"));
bp1.HandleGesturesPropWritten();
EXPECT_EQ(++expected_call_cnt, delegate.call_cnt_);
@@ -58,7 +59,8 @@ TEST(PropRegistryTest, SimpleTest) {
bp2.HandleGesturesPropWritten();
EXPECT_EQ(expected_call_cnt, delegate.call_cnt_);
- DoubleProperty dp1(&reg, "hi", 2721.0, &delegate);
+ DoubleProperty dp1(&reg, "hi", 2721.0);
+ dp1.SetDelegate(&delegate);
EXPECT_TRUE(strstr(ValueForProperty(dp1).c_str(), "2721"));
dp1.HandleGesturesPropWritten();
EXPECT_EQ(++expected_call_cnt, delegate.call_cnt_);
@@ -68,7 +70,8 @@ TEST(PropRegistryTest, SimpleTest) {
dp2.HandleGesturesPropWritten();
EXPECT_EQ(expected_call_cnt, delegate.call_cnt_);
- IntProperty ip1(&reg, "hi", 567, &delegate);
+ IntProperty ip1(&reg, "hi", 567);
+ ip1.SetDelegate(&delegate);
EXPECT_TRUE(strstr(ValueForProperty(ip1).c_str(), "567"));
ip1.HandleGesturesPropWritten();
EXPECT_EQ(++expected_call_cnt, delegate.call_cnt_);
@@ -78,7 +81,8 @@ TEST(PropRegistryTest, SimpleTest) {
ip2.HandleGesturesPropWritten();
EXPECT_EQ(expected_call_cnt, delegate.call_cnt_);
- StringProperty stp1(&reg, "hi", "foo", &delegate);
+ StringProperty stp1(&reg, "hi", "foo");
+ stp1.SetDelegate(&delegate);
EXPECT_TRUE(strstr(ValueForProperty(stp1).c_str(), "foo"));
stp1.HandleGesturesPropWritten();
EXPECT_EQ(++expected_call_cnt, delegate.call_cnt_);
@@ -194,29 +198,31 @@ TEST(PropRegistryTest, SetAtCreateShouldNotifyTest) {
PropRegistry reg;
PropRegistryTestDelegate delegate;
- BoolProperty my_bool(&reg, "MyBool", 0, &delegate);
- DoubleProperty my_double(&reg, "MyDouble", 0.0, &delegate);
- IntProperty my_int(&reg, "MyInt", 0, &delegate);
- IntProperty my_int_no_change(&reg, "MyIntNoChange", 1, &delegate);
- StringProperty my_string(&reg, "MyString", "mine", &delegate);
+ BoolProperty my_bool(&reg, "MyBool", 0);
+ my_bool.SetDelegate(&delegate);
+ DoubleProperty my_double(&reg, "MyDouble", 0.0);
+ my_double.SetDelegate(&delegate);
+ IntProperty my_int(&reg, "MyInt", 0);
+ my_int.SetDelegate(&delegate);
+ IntProperty my_int_no_change(&reg, "MyIntNoChange", 1);
+ my_int_no_change.SetDelegate(&delegate);
+ StringProperty my_string(&reg, "MyString", "mine");
+ my_string.SetDelegate(&delegate);
EXPECT_EQ(0, delegate.call_cnt_);
reg.SetPropProvider(&mock_gestures_props_provider, NULL);
EXPECT_EQ(4, delegate.call_cnt_);
-
- BoolProperty my_bool2(&reg, "MyBool2", 1);
- EXPECT_EQ(4, delegate.call_cnt_);
- my_bool2.SetDelegate(&delegate);
- EXPECT_EQ(5, delegate.call_cnt_);
}
TEST(PropRegistryTest, DoublePromoteIntTest) {
PropRegistry reg;
PropRegistryTestDelegate delegate;
- DoubleProperty my_double(&reg, "MyDouble", 1234.5, &delegate);
+ DoubleProperty my_double(&reg, "MyDouble", 1234.5);
+ my_double.SetDelegate(&delegate);
EXPECT_TRUE(strstr(ValueForProperty(my_double).c_str(), "1234.5"));
- IntProperty my_int(&reg, "MyInt", 321, &delegate);
+ IntProperty my_int(&reg, "MyInt", 321);
+ my_int.SetDelegate(&delegate);
Json::Value my_int_val = my_int.NewValue();
EXPECT_TRUE(my_double.SetValue(my_int_val));
EXPECT_TRUE(strstr(ValueForProperty(my_double).c_str(), "321"));
@@ -229,15 +235,18 @@ TEST(PropRegistryTest, BoolArrayTest) {
GesturesPropBool vals[] = { false, true };
BoolArrayProperty my_bool_array_w_delegate(
- &reg, "MyBoolArray", vals, 2, &delegate);
+ &reg, "MyBoolArray", vals, 2);
+ my_bool_array_w_delegate.SetDelegate(&delegate);
EXPECT_EQ(0, delegate.call_cnt_);
my_bool_array_w_delegate.HandleGesturesPropWritten();
EXPECT_EQ(1, delegate.call_cnt_);
delegate.BoolArrayWasWritten(&my_bool_array_w_delegate);
EXPECT_EQ(2, delegate.call_cnt_);
- IntProperty ip1(&reg, "hi", 567, &delegate);
- StringProperty stp1(&reg, "hi", "foo", &delegate);
+ IntProperty ip1(&reg, "hi", 567);
+ ip1.SetDelegate(&delegate);
+ StringProperty stp1(&reg, "hi", "foo");
+ stp1.SetDelegate(&delegate);
Json::Value my_bool_array_val = my_bool_array_w_delegate.NewValue();
Json::Value my_int_val = ip1.NewValue();
Json::Value my_str_val = stp1.NewValue();
@@ -261,15 +270,18 @@ TEST(PropRegistryTest, DoubleArrayTest) {
double vals[] = { 0.0, 1.0 };
DoubleArrayProperty my_double_array_w_delegate(
- &reg, "MyDoubleArray", vals, 2, &delegate);
+ &reg, "MyDoubleArray", vals, 2);
+ my_double_array_w_delegate.SetDelegate(&delegate);
EXPECT_EQ(0, delegate.call_cnt_);
my_double_array_w_delegate.HandleGesturesPropWritten();
EXPECT_EQ(1, delegate.call_cnt_);
delegate.DoubleArrayWasWritten(&my_double_array_w_delegate);
EXPECT_EQ(2, delegate.call_cnt_);
- IntProperty ip1(&reg, "hi", 567, &delegate);
- StringProperty stp1(&reg, "hi", "foo", &delegate);
+ IntProperty ip1(&reg, "hi", 567);
+ ip1.SetDelegate(&delegate);
+ StringProperty stp1(&reg, "hi", "foo");
+ stp1.SetDelegate(&delegate);
Json::Value my_double_array_val = my_double_array_w_delegate.NewValue();
Json::Value my_int_val = ip1.NewValue();
Json::Value my_str_val = stp1.NewValue();
@@ -293,15 +305,18 @@ TEST(PropRegistryTest, IntArrayTest) {
int vals[] = { 0, 1 };
IntArrayProperty my_int_array_w_delegate(
- &reg, "MyIntArray", vals, 2, &delegate);
+ &reg, "MyIntArray", vals, 2);
+ my_int_array_w_delegate.SetDelegate(&delegate);
EXPECT_EQ(0, delegate.call_cnt_);
my_int_array_w_delegate.HandleGesturesPropWritten();
EXPECT_EQ(1, delegate.call_cnt_);
delegate.IntArrayWasWritten(&my_int_array_w_delegate);
EXPECT_EQ(2, delegate.call_cnt_);
- IntProperty ip1(&reg, "hi", 567, &delegate);
- StringProperty stp1(&reg, "hi", "foo", &delegate);
+ IntProperty ip1(&reg, "hi", 567);
+ ip1.SetDelegate(&delegate);
+ StringProperty stp1(&reg, "hi", "foo");
+ stp1.SetDelegate(&delegate);
Json::Value my_int_array_val = my_int_array_w_delegate.NewValue();
Json::Value my_int_val = ip1.NewValue();
Json::Value my_str_val = stp1.NewValue();
diff --git a/src/scaling_filter_interpreter.cc b/src/scaling_filter_interpreter.cc
index 1094455..2d2aad9 100644
--- a/src/scaling_filter_interpreter.cc
+++ b/src/scaling_filter_interpreter.cc
@@ -318,8 +318,13 @@ void ScalingFilterInterpreter::Initialize(const HardwareProperties* hwprops,
Metrics* metrics,
MetricsProperties* mprops,
GestureConsumer* consumer) {
- tp_x_scale_ = 1.0 / hwprops->res_x;
- tp_y_scale_ = 1.0 / hwprops->res_y;
+ // If the touchpad doesn't specify its resolution in one or both axes, use a
+ // reasonable default instead.
+ float res_x = hwprops->res_x != 0 ? hwprops->res_x : 32;
+ float res_y = hwprops->res_y != 0 ? hwprops->res_y : 32;
+
+ tp_x_scale_ = 1.0 / res_x;
+ tp_y_scale_ = 1.0 / res_y;
tp_x_translate_ = -1.0 * (hwprops->left * tp_x_scale_);
tp_y_translate_ = -1.0 * (hwprops->top * tp_y_scale_);
diff --git a/src/scaling_filter_interpreter_unittest.cc b/src/scaling_filter_interpreter_unittest.cc
index d701c7f..93f8e79 100644
--- a/src/scaling_filter_interpreter_unittest.cc
+++ b/src/scaling_filter_interpreter_unittest.cc
@@ -68,7 +68,7 @@ class ScalingFilterInterpreterTestInterpreter : public Interpreter {
EXPECT_FLOAT_EQ(expected_pressures_.front(),
hwstate->fingers[0].pressure);
expected_pressures_.pop_front();
- } else {
+ } else if (!expected_finger_cnt_.empty() && !expected_touch_cnt_.empty()) {
// Test if the low pressure event is dropped
EXPECT_EQ(expected_finger_cnt_.front(), hwstate->finger_cnt);
expected_finger_cnt_.pop_front();
@@ -272,6 +272,47 @@ TEST(ScalingFilterInterpreterTest, SimpleTest) {
out = wrapper.SyncInterpret(&hs2[2], NULL);
}
+TEST(ScalingFilterInterpreterTest, ResolutionFallback) {
+ ScalingFilterInterpreterTestInterpreter* base_interpreter =
+ new ScalingFilterInterpreterTestInterpreter;
+ ScalingFilterInterpreter interpreter(NULL, base_interpreter, NULL,
+ GESTURES_DEVCLASS_TOUCHPAD);
+ HardwareProperties initial_hwprops = {
+ 0, 0, 2000, 1000, // left, top, right, bottom
+ 0, 0, // X/Y resolutions (pixels/mm)
+ 0, 0, // screen DPI X, Y (deprecated)
+ -1, // orientation minimum
+ 2, // orientation maximum
+ 2, 5, // max fingers, max_touch
+ 0, 0, 0, // t5r2, semi, button pad
+ 0, 0, // has wheel, vertical wheel is high resolution
+ 0, // haptic pad
+ };
+ HardwareProperties expected_hwprops = {
+ 0, 0, 2000 / 32.0, 1000 / 32.0, // left, top, right, bottom
+ 1, 1, // X/Y resolutions (pixels/mm)
+ 25.4, 25.4, // x DPI, y DPI
+ -M_PI_4, // orientation minimum (1 tick above X-axis)
+ M_PI_2, // orientation maximum
+ 2, 5, 0, 0, 0, // max_fingers, max_touch, t5r2, semi_mt, is button pad
+ 0, 0, // has wheel, vertical wheel is high resolution
+ 0, // is haptic pad
+ };
+ base_interpreter->expected_hwprops_ = expected_hwprops;
+
+ TestInterpreterWrapper wrapper(&interpreter, &initial_hwprops);
+ EXPECT_TRUE(base_interpreter->initialize_called_);
+
+ FingerState fs = { 1, 0, 0, 0, 1, 0, 1000, 500, 1, 0 };
+ HardwareState hs = make_hwstate(10000, 0, 1, 1, &fs);
+
+ base_interpreter->expected_coordinates_.push_back(
+ std::vector<pair<float, float>>(1, make_pair(
+ static_cast<float>(1000 / 32.0), static_cast<float>(500 / 32.0))));
+
+ wrapper.SyncInterpret(&hs, NULL);
+}
+
static void RunTouchMajorAndMinorTest(
ScalingFilterInterpreterTestInterpreter* base_interpreter,
ScalingFilterInterpreter* interpreter,
diff --git a/src/trend_classifying_filter_interpreter.cc b/src/trend_classifying_filter_interpreter.cc
index 45699a9..714cb68 100644
--- a/src/trend_classifying_filter_interpreter.cc
+++ b/src/trend_classifying_filter_interpreter.cc
@@ -30,8 +30,6 @@ namespace gestures {
TrendClassifyingFilterInterpreter::TrendClassifyingFilterInterpreter(
PropRegistry* prop_reg, Interpreter* next, Tracer* tracer)
: FilterInterpreter(NULL, next, tracer, false),
- kstate_mm_(kMaxFingers * kNumOfSamples),
- history_mm_(kMaxFingers),
trend_classifying_filter_enable_(
prop_reg, "Trend Classifying Filter Enabled", true),
second_order_enable_(
@@ -72,37 +70,32 @@ void TrendClassifyingFilterInterpreter::InterpretTestResult(
}
void TrendClassifyingFilterInterpreter::AddNewStateToBuffer(
- FingerHistory* history, const FingerState& fs) {
+ FingerHistory& history, const FingerState& fs) {
// The history buffer is already full, pop one
- if (history->size() == static_cast<size_t>(num_of_samples_.val_))
- history->DeleteFront();
+ if (history.size() == static_cast<size_t>(num_of_samples_.val_))
+ history.pop_front();
// Push the new finger state to the back of buffer
- KState* previous_end = history->Tail();
- KState* current = history->PushNewEltBack();
- if (!current) {
- Err("KState buffer out of space");
- return;
- }
- current->Init(fs);
- if (history->size() == 1)
+ auto& current = history.emplace_back(fs);
+ if (history.size() == 1)
return;
+ auto& previous_end = history.at(-2);
- current->DxAxis()->val = current->XAxis()->val - previous_end->XAxis()->val;
- current->DyAxis()->val = current->YAxis()->val - previous_end->YAxis()->val;
+ current.DxAxis()->val = current.XAxis()->val - previous_end.XAxis()->val;
+ current.DyAxis()->val = current.YAxis()->val - previous_end.YAxis()->val;
// Update the nodes already in the buffer and compute the Kendall score/
// variance along the way. Complexity is O(|buffer|) per finger.
int tie_n2[KState::n_axes_] = { 0, 0, 0, 0, 0, 0 };
int tie_n3[KState::n_axes_] = { 0, 0, 0, 0, 0, 0 };
- for (KState* it = history->Begin(); it != history->Tail(); it = it->next_)
+ for (auto it = history.begin(); it != history.end(); ++it)
for (size_t i = 0; i < KState::n_axes_; i++)
- if(it != history->Begin() || !KState::IsDelta(i)) {
- UpdateKTValuePair(&it->axes_[i], &current->axes_[i],
+ if (it != history.begin() || !KState::IsDelta(i)) {
+ UpdateKTValuePair(&it->axes_[i], &current.axes_[i],
&tie_n2[i], &tie_n3[i]);
}
- size_t n_samples = history->size();
+ size_t n_samples = history.size();
for (size_t i = 0; i < KState::n_axes_; i++) {
- current->axes_[i].var = ComputeKTVariance(tie_n2[i], tie_n3[i],
+ current.axes_[i].var = ComputeKTVariance(tie_n2[i], tie_n3[i],
KState::IsDelta(i) ? n_samples - 1 : n_samples);
}
}
@@ -132,38 +125,23 @@ TrendClassifyingFilterInterpreter::RunKTTest(const KState::KAxis* current,
void TrendClassifyingFilterInterpreter::UpdateFingerState(
const HardwareState& hwstate) {
- FingerHistoryMap removed;
- RemoveMissingIdsFromMap(&histories_, hwstate, &removed);
- for (FingerHistoryMap::const_iterator it =
- removed.begin(); it != removed.end(); ++it) {
- it->second->DeleteAll();
- history_mm_.Free(it->second);
- }
+ RemoveMissingIdsFromMap(&histories_, hwstate);
- FingerState *fs = hwstate.fingers;
+ FingerState* fs = hwstate.fingers;
for (short i = 0; i < hwstate.finger_cnt; i++) {
- FingerHistory* hp;
-
// Update the map if the contact is new
if (!MapContainsKey(histories_, fs[i].tracking_id)) {
- hp = history_mm_.Allocate();
- if (!hp) {
- Err("FingerHistory out of space");
- continue;
- }
- hp->Init(&kstate_mm_);
- histories_[fs[i].tracking_id] = hp;
- } else {
- hp = histories_[fs[i].tracking_id];
+ histories_[fs[i].tracking_id] = FingerHistory{};
}
+ auto& history = histories_[fs[i].tracking_id];
// Check if the score demonstrates statistical significance
- AddNewStateToBuffer(hp, fs[i]);
- KState* current = hp->Tail();
- size_t n_samples = hp->size();
+ AddNewStateToBuffer(history, fs[i]);
+ const auto& current = history.back();
+ const size_t n_samples = history.size();
for (size_t idx = 0; idx < KState::n_axes_; idx++)
if (second_order_enable_.val_ || !KState::IsDelta(idx)) {
- TrendType result = RunKTTest(&current->axes_[idx],
+ TrendType result = RunKTTest(&current.axes_[idx],
KState::IsDelta(idx) ? n_samples - 1 : n_samples);
InterpretTestResult(result, KState::IncFlag(idx),
KState::DecFlag(idx), &(fs[i].flags));
diff --git a/src/util_unittest.cc b/src/util_unittest.cc
index 5d0a435..f19fe1f 100644
--- a/src/util_unittest.cc
+++ b/src/util_unittest.cc
@@ -21,4 +21,51 @@ TEST(UtilTest, DistSqTest) {
EXPECT_FLOAT_EQ(DistSqXY(fs[0], 4, 6), 25);
}
+TEST(UtilTest, ListAtTest) {
+ const int kMaxElements = 3;
+ struct element {
+ int x;
+ };
+
+ List<element> list;
+
+ for (auto i = 0; i < kMaxElements; ++i) {
+ auto& elem = list.emplace_back();
+ elem.x = i;
+ }
+ EXPECT_EQ(list.at(-1).x, list.at(list.size() - 1).x);
+
+ for (auto i = 0; i < kMaxElements; ++i) {
+ for (auto j = 0; j < kMaxElements; ++j) {
+ if (i == j) {
+ EXPECT_EQ(list.at(i).x, list.at(j).x);
+ EXPECT_EQ(&(list.at(i)), &(list.at(j)));
+ } else {
+ EXPECT_NE(list.at(i).x, list.at(j).x);
+ EXPECT_NE(&(list.at(i)), &(list.at(j)));
+ }
+ }
+ }
+}
+
+TEST(UtilTest, ListAtDeathForwardTest) {
+ List<int> list;
+ const int kMaxElements = 3;
+
+ for (auto i = 0; i < kMaxElements; ++i) {
+ list.emplace_back(i);
+ }
+ EXPECT_DEATH(list.at(kMaxElements+1), "");
+}
+
+TEST(UtilTest, ListAtDeathBackwardTest) {
+ List<int> list;
+ const int kMaxElements = 3;
+
+ for (auto i = 0; i < kMaxElements; ++i) {
+ list.emplace_back(i);
+ }
+ EXPECT_DEATH(list.at(-(kMaxElements+1)), "");
+}
+
} // namespace gestures
diff --git a/tools/local_coverage_rate.sh b/tools/local_coverage_rate.sh
index 710d91c..d1f9fff 100755
--- a/tools/local_coverage_rate.sh
+++ b/tools/local_coverage_rate.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+# Copyright 2011 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/tools/regression_test.sh b/tools/regression_test.sh
index db7535b..f97118a 100755
--- a/tools/regression_test.sh
+++ b/tools/regression_test.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+# Copyright 2012 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/tools/replay_log b/tools/replay_log
index bfdca70..76ddbbd 100755
--- a/tools/replay_log
+++ b/tools/replay_log
@@ -1,6 +1,6 @@
#!/bin/sh
-# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+# Copyright 2012 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/tools/tplog.py b/tools/tplog.py
index b2a685f..7df13f8 100755
--- a/tools/tplog.py
+++ b/tools/tplog.py
@@ -1,6 +1,6 @@
#!/usr/bin/python
#
-# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+# Copyright 2012 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -8,9 +8,9 @@
import getopt
+import json
import logging
import os
-import simplejson as json
import sys
from operator import ge, lt