summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-02 23:49:05 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-02 23:49:05 +0000
commitad4fde5e2f19c1cf1961c3b13410cd5e93a0738d (patch)
treeffff4c26722421cd89f9fa94770ca0ea9b71f6cc
parent0ea5089e9e2084084c73e759ccab0044c1d2a601 (diff)
parentff1aa200b87ad5497d844a9a41c9756f7deb28b4 (diff)
downloadlibchrome-gestures-simpleperf-release.tar.gz
Snap for 11400057 from ff1aa200b87ad5497d844a9a41c9756f7deb28b4 to simpleperf-releasesimpleperf-release
Change-Id: Ife6d4db27bf1d0bfce5d63849b948217030a1798
-rw-r--r--Android.bp38
-rw-r--r--METADATA (renamed from METADATA.android)4
-rw-r--r--include/accel_filter_interpreter.h20
-rw-r--r--include/activity_log.h220
-rw-r--r--include/box_filter_interpreter.h1
-rw-r--r--include/finger_metrics.h7
-rw-r--r--include/fling_stop_filter_interpreter.h2
-rw-r--r--include/gestures.h28
-rw-r--r--include/haptic_button_generator_filter_interpreter.h2
-rw-r--r--include/immediate_interpreter.h20
-rw-r--r--include/integral_gesture_filter_interpreter.h1
-rw-r--r--include/interpreter.h25
-rw-r--r--include/logging_filter_interpreter.h1
-rw-r--r--include/lookahead_filter_interpreter.h4
-rw-r--r--include/mouse_interpreter.h1
-rw-r--r--include/palm_classifying_filter_interpreter.h1
-rw-r--r--include/timestamp_filter_interpreter.h17
-rw-r--r--src/accel_filter_interpreter.cc83
-rw-r--r--src/accel_filter_interpreter_unittest.cc272
-rw-r--r--src/activity_log.cc325
-rw-r--r--src/activity_log_unittest.cc310
-rw-r--r--src/activity_replay.cc60
-rw-r--r--src/box_filter_interpreter.cc5
-rw-r--r--src/box_filter_interpreter_unittest.cc62
-rw-r--r--src/click_wiggle_filter_interpreter.cc4
-rw-r--r--src/click_wiggle_filter_interpreter_unittest.cc170
-rw-r--r--src/finger_merge_filter_interpreter.cc5
-rw-r--r--src/finger_merge_filter_interpreter_unittest.cc18
-rw-r--r--src/finger_metrics.cc13
-rw-r--r--src/fling_stop_filter_interpreter.cc40
-rw-r--r--src/fling_stop_filter_interpreter_unittest.cc44
-rw-r--r--src/gestures.cc11
-rw-r--r--src/gestures_unittest.cc68
-rw-r--r--src/haptic_button_generator_filter_interpreter.cc15
-rw-r--r--src/haptic_button_generator_filter_interpreter_unittest.cc159
-rw-r--r--src/iir_filter_interpreter.cc4
-rw-r--r--src/iir_filter_interpreter_unittest.cc16
-rw-r--r--src/immediate_interpreter.cc205
-rw-r--r--src/immediate_interpreter_unittest.cc1426
-rw-r--r--src/integral_gesture_filter_interpreter.cc26
-rw-r--r--src/integral_gesture_filter_interpreter_unittest.cc24
-rw-r--r--src/interpreter.cc70
-rw-r--r--src/interpreter_unittest.cc115
-rw-r--r--src/logging_filter_interpreter.cc10
-rw-r--r--src/logging_filter_interpreter_unittest.cc45
-rw-r--r--src/lookahead_filter_interpreter.cc32
-rw-r--r--src/lookahead_filter_interpreter_unittest.cc442
-rw-r--r--src/metrics_filter_interpreter.cc5
-rw-r--r--src/metrics_filter_interpreter_unittest.cc49
-rw-r--r--src/mouse_interpreter.cc73
-rw-r--r--src/mouse_interpreter_unittest.cc110
-rw-r--r--src/multitouch_mouse_interpreter.cc59
-rw-r--r--src/multitouch_mouse_interpreter_unittest.cc21
-rw-r--r--src/non_linearity_filter_interpreter.cc4
-rw-r--r--src/palm_classifying_filter_interpreter.cc10
-rw-r--r--src/palm_classifying_filter_interpreter_unittest.cc235
-rw-r--r--src/scaling_filter_interpreter.cc10
-rw-r--r--src/scaling_filter_interpreter_unittest.cc113
-rw-r--r--src/sensor_jump_filter_interpreter.cc4
-rw-r--r--src/sensor_jump_filter_interpreter_unittest.cc36
-rw-r--r--src/split_correcting_filter_interpreter.cc4
-rw-r--r--src/split_correcting_filter_interpreter_unittest.cc94
-rw-r--r--src/stationary_wiggle_filter_interpreter.cc5
-rw-r--r--src/stationary_wiggle_filter_interpreter_unittest.cc18
-rw-r--r--src/stuck_button_inhibitor_filter_interpreter.cc23
-rw-r--r--src/stuck_button_inhibitor_filter_interpreter_unittest.cc21
-rw-r--r--src/t5r2_correcting_filter_interpreter.cc5
-rw-r--r--src/t5r2_correcting_filter_interpreter_unittest.cc21
-rw-r--r--src/timestamp_filter_interpreter.cc44
-rw-r--r--src/timestamp_filter_interpreter_unittest.cc97
-rw-r--r--src/trend_classifying_filter_interpreter.cc5
-rw-r--r--src/trend_classifying_filter_interpreter_unittest.cc18
72 files changed, 3816 insertions, 1739 deletions
diff --git a/Android.bp b/Android.bp
index 8be85fa..d8ac05d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -18,7 +18,7 @@ license {
}
cc_defaults {
- name: "libchrome-gestures_cflags",
+ name: "libchrome-gestures_defaults",
cflags: [
"-fno-exceptions",
"-fno-strict-aliasing",
@@ -39,6 +39,27 @@ cc_defaults {
"-D_FILE_OFFSET_BITS=64",
"-DGESTURES_INTERNAL=1",
],
+ sanitize: {
+ all_undefined: true,
+ integer_overflow: true,
+ undefined: true,
+ },
+ arch: {
+ x86_64: {
+ sanitize: {
+ all_undefined: false,
+ integer_overflow: false,
+ undefined: false,
+ },
+ }
+ },
+ target: {
+ host: {
+ sanitize: {
+ address: true,
+ },
+ },
+ },
}
cc_library_headers {
@@ -52,7 +73,7 @@ cc_library_headers {
cc_library_static {
name: "libchrome-gestures",
defaults: [
- "libchrome-gestures_cflags",
+ "libchrome-gestures_defaults",
],
local_include_dirs: ["."],
header_libs: [
@@ -102,18 +123,13 @@ cc_library_static {
"//frameworks/native/services/inputflinger:__subpackages__",
],
rtti: true,
- sanitize: {
- cfi: true,
- integer_overflow: true,
- misc_undefined: ["bounds"],
- },
host_supported: true,
}
cc_test {
name: "libchrome-gestures_test",
defaults: [
- "libchrome-gestures_cflags",
+ "libchrome-gestures_defaults",
],
srcs: [
"src/accel_filter_interpreter_unittest.cc",
@@ -168,5 +184,11 @@ cc_test {
"-Wno-sign-compare",
],
host_supported: false,
+ sanitize: {
+ hwaddress: true,
+ diag: {
+ integer_overflow: true,
+ },
+ },
test_suites: ["general-tests"],
}
diff --git a/METADATA.android b/METADATA
index 3fbc1b0..c2fe6b5 100644
--- a/METADATA.android
+++ b/METADATA
@@ -6,7 +6,7 @@ third_party {
type: GIT
value: "https://chromium.googlesource.com/chromiumos/platform/gestures/"
}
- version: "4c2dbaf9f9f64e07edcd46b161fe0e4bc62b950c"
- last_upgrade_date { year: 2023 month: 8 day: 21 }
+ version: "b31ef0adcaff61c045e95158cb9720543b42b531"
+ last_upgrade_date { year: 2023 month: 12 day: 13 }
license_type: NOTICE
}
diff --git a/include/accel_filter_interpreter.h b/include/accel_filter_interpreter.h
index 024abb7..6e5fd47 100644
--- a/include/accel_filter_interpreter.h
+++ b/include/accel_filter_interpreter.h
@@ -30,10 +30,15 @@ class AccelFilterInterpreter : public FilterInterpreter {
FRIEND_TEST(AccelFilterInterpreterTest, NotSmoothingTest);
FRIEND_TEST(AccelFilterInterpreterTest, SmoothingTest);
FRIEND_TEST(AccelFilterInterpreterTest, TinyMoveTest);
+ FRIEND_TEST(AccelFilterInterpreterTest, BadGestureTest);
+ FRIEND_TEST(AccelFilterInterpreterTest, BadDeltaTTest);
+ FRIEND_TEST(AccelFilterInterpreterTest, BadSpeedFlingTest);
+ FRIEND_TEST(AccelFilterInterpreterTest, BadSpeedMoveTest);
FRIEND_TEST(AccelFilterInterpreterTest, UnacceleratedMouseTest);
FRIEND_TEST(AccelFilterInterpreterTest, UnacceleratedTouchpadTest);
FRIEND_TEST(AccelFilterInterpreterTest, TouchpadPointAccelCurveTest);
FRIEND_TEST(AccelFilterInterpreterTest, TouchpadScrollAccelCurveTest);
+ FRIEND_TEST(AccelFilterInterpreterTest, AccelDebugDataTest);
public:
// Takes ownership of |next|:
AccelFilterInterpreter(PropRegistry* prop_reg, Interpreter* next,
@@ -116,16 +121,23 @@ class AccelFilterInterpreter : public FilterInterpreter {
// means of the smooth_accel_ Property.
// in: gs, provided Gesture
// inout: speed, actual speed on input and smoothed on output
- void smooth_speed(Gesture& gs, float& speed);
+ void smooth_speed(const Gesture& gs, float& speed);
// Map a speed on a given CurveSegment array to a ratio multiplier.
// in: segs, address of CurveSegment array being used
// in: max_segs, number of array entries in segs
// in: speed, actual distance/delta time value
// ret: determined gain to apply
- float RatioFromAccelCurve(CurveSegment const * segs,
- size_t const max_segs,
- float const speed);
+ float RatioFromAccelCurve(const CurveSegment* segs,
+ const size_t max_segs,
+ const float speed);
+
+ template<typename T>
+ void LogDebugData(const T& debug_data) {
+ using EventDebug = ActivityLog::EventDebug;
+ if (EventDebugLoggingIsEnabled(EventDebug::Accel))
+ log_->LogDebugData(debug_data);
+ }
//**************************************************************************
diff --git a/include/activity_log.h b/include/activity_log.h
index d5d6b43..a5ebde3 100644
--- a/include/activity_log.h
+++ b/include/activity_log.h
@@ -13,6 +13,11 @@
#include <gtest/gtest.h> // For FRIEND_TEST
#include <json/value.h>
+// This should be set by build system:
+#ifndef VCSID
+#define VCSID "Unknown"
+#endif // VCSID
+
// This is a class that circularly buffers all incoming and outgoing activity
// so that end users can report issues and engineers can reproduce them.
@@ -28,6 +33,10 @@ class ActivityLog {
FRIEND_TEST(ActivityLogTest, EncodePropChangeDoubleTest);
FRIEND_TEST(ActivityLogTest, EncodePropChangeIntTest);
FRIEND_TEST(ActivityLogTest, EncodePropChangeShortTest);
+ FRIEND_TEST(ActivityLogTest, GestureConsumeTest);
+ FRIEND_TEST(ActivityLogTest, GestureProduceTest);
+ FRIEND_TEST(ActivityLogTest, HardwareStatePreTest);
+ FRIEND_TEST(ActivityLogTest, HardwareStatePostTest);
FRIEND_TEST(LoggingFilterInterpreterTest, SimpleTest);
FRIEND_TEST(PropRegistryTest, PropChangeTest);
public:
@@ -38,19 +47,126 @@ class ActivityLog {
stime_t timestamp;
};
struct PropChangeEntry {
- const char* name;
+ std::string name;
// No string variant because string values can't change
std::variant<GesturesPropBool,
double,
int,
short> value;
};
+
+ struct HardwareStatePre {
+ std::string name;
+ HardwareState hwstate;
+ };
+ struct HardwareStatePost {
+ std::string name;
+ HardwareState hwstate;
+ };
+ struct GestureConsume {
+ std::string name;
+ Gesture gesture;
+ };
+ struct GestureProduce {
+ std::string name;
+ Gesture gesture;
+ };
+ struct HandleTimerPre {
+ std::string name;
+ bool timeout_is_present;
+ stime_t now;
+ stime_t timeout;
+ };
+ struct HandleTimerPost {
+ std::string name;
+ bool timeout_is_present;
+ stime_t now;
+ stime_t timeout;
+ };
+ struct AccelGestureDebug {
+ bool no_accel_for_gesture_type;
+ bool no_accel_for_small_dt;
+ bool no_accel_for_small_speed;
+ bool no_accel_for_bad_gain;
+ bool dropped_gesture;
+ bool x_y_are_velocity;
+ float x_scale, y_scale;
+ float dt;
+ float adjusted_dt;
+ float speed;
+ float smoothed_speed;
+ float gain_x, gain_y;
+ };
+ struct TimestampGestureDebug {
+ stime_t skew;
+ };
+ struct TimestampHardwareStateDebug {
+ bool is_using_fake;
+ union {
+ struct {
+ bool was_first_or_backward;
+ stime_t prev_msc_timestamp_in;
+ stime_t prev_msc_timestamp_out;
+ };
+ struct {
+ bool was_divergence_reset;
+ stime_t fake_timestamp_in;
+ stime_t fake_timestamp_delta;
+ stime_t fake_timestamp_out;
+ };
+ };
+ stime_t skew;
+ stime_t max_skew;
+ };
+
struct Entry {
std::variant<HardwareState,
TimerCallbackEntry,
CallbackRequestEntry,
Gesture,
- PropChangeEntry> details;
+ PropChangeEntry,
+ HardwareStatePre,
+ HardwareStatePost,
+ GestureConsume,
+ GestureProduce,
+ HandleTimerPre,
+ HandleTimerPost,
+ AccelGestureDebug,
+ TimestampGestureDebug,
+ TimestampHardwareStateDebug> details;
+ };
+
+ enum class EventDebug {
+ // Base Event Types
+ Gesture = 0,
+ HardwareState,
+ HandleTimer,
+ // FilterInterpreter Debug Detail Event Types
+ Accel,
+ Box,
+ ClickWiggle,
+ FingerMerge,
+ FlingStop,
+ HapticButtonGenerator,
+ Iir,
+ IntegratGesture,
+ Logging,
+ Lookahead,
+ Metrics,
+ NonLinearity,
+ PalmClassifying,
+ Scaling,
+ SensorJump,
+ SplitCorrecting,
+ StationaryWiggle,
+ StuckButtonInhibitor,
+ T5R2Correcting,
+ Timestamp,
+ TrendClassifying,
+ // Interpreter Debug Detail Event Types
+ ImmediateInterpreter,
+ MouseInterpreter,
+ MultitouchMouseInterpreter,
};
explicit ActivityLog(PropRegistry* prop_reg);
@@ -63,6 +179,24 @@ class ActivityLog {
void LogGesture(const Gesture& gesture);
void LogPropChange(const PropChangeEntry& prop_change);
+ // Debug extensions for Log*()
+ void LogGestureConsume(const std::string& name, const Gesture& gesture);
+ void LogGestureProduce(const std::string& name, const Gesture& gesture);
+ void LogHardwareStatePre(const std::string& name,
+ const HardwareState& hwstate);
+ void LogHardwareStatePost(const std::string& name,
+ const HardwareState& hwstate);
+ void LogHandleTimerPre(const std::string& name,
+ stime_t now, const stime_t* timeout);
+ void LogHandleTimerPost(const std::string& name,
+ stime_t now, const stime_t* timeout);
+
+ template<typename T>
+ void LogDebugData(const T& debug_data) {
+ Entry* entry = PushBack();
+ entry->details = debug_data;
+ }
+
// Dump allocates, and thus must not be called on a signal handler.
void Dump(const char* filename);
void Clear() { head_idx_ = size_ = 0; }
@@ -81,11 +215,18 @@ class ActivityLog {
static const char kKeyNext[];
static const char kKeyRoot[];
static const char kKeyType[];
+ static const char kKeyMethodName[];
static const char kKeyHardwareState[];
+ static const char kKeyHardwareStatePre[];
+ static const char kKeyHardwareStatePost[];
static const char kKeyTimerCallback[];
static const char kKeyCallbackRequest[];
static const char kKeyGesture[];
+ static const char kKeyGestureConsume[];
+ static const char kKeyGestureProduce[];
static const char kKeyPropChange[];
+ static const char kKeyHandleTimerPre[];
+ static const char kKeyHandleTimerPost[];
// HardwareState keys:
static const char kKeyHardwareStateTimestamp[];
static const char kKeyHardwareStateButtonsDown[];
@@ -106,9 +247,9 @@ class ActivityLog {
static const char kKeyFingerStatePositionY[];
static const char kKeyFingerStateTrackingId[];
static const char kKeyFingerStateFlags[];
- // TimerCallback keys:
- static const char kKeyTimerCallbackNow[];
- // CallbackRequest keys:
+ // Timer/Callback keys:
+ static const char kKeyTimerNow[];
+ static const char kKeyHandleTimerTimeout[];
static const char kKeyCallbackRequestWhen[];
// Gesture keys:
static const char kKeyGestureType[];
@@ -126,16 +267,10 @@ class ActivityLog {
static const char kValueGestureTypeMetrics[];
static const char kKeyGestureStartTime[];
static const char kKeyGestureEndTime[];
- static const char kKeyGestureMoveDX[];
- static const char kKeyGestureMoveDY[];
- static const char kKeyGestureMoveOrdinalDX[];
- static const char kKeyGestureMoveOrdinalDY[];
- static const char kKeyGestureScrollDX[];
- static const char kKeyGestureScrollDY[];
- static const char kKeyGestureScrollOrdinalDX[];
- static const char kKeyGestureScrollOrdinalDY[];
- static const char kKeyGestureMouseWheelDX[];
- static const char kKeyGestureMouseWheelDY[];
+ static const char kKeyGestureDX[];
+ static const char kKeyGestureDY[];
+ static const char kKeyGestureOrdinalDX[];
+ static const char kKeyGestureOrdinalDY[];
static const char kKeyGestureMouseWheelTicksDX[];
static const char kKeyGestureMouseWheelTicksDY[];
static const char kKeyGesturePinchDZ[];
@@ -148,14 +283,6 @@ class ActivityLog {
static const char kKeyGestureFlingOrdinalVX[];
static const char kKeyGestureFlingOrdinalVY[];
static const char kKeyGestureFlingState[];
- static const char kKeyGestureSwipeDX[];
- static const char kKeyGestureSwipeDY[];
- static const char kKeyGestureSwipeOrdinalDX[];
- static const char kKeyGestureSwipeOrdinalDY[];
- static const char kKeyGestureFourFingerSwipeDX[];
- static const char kKeyGestureFourFingerSwipeDY[];
- static const char kKeyGestureFourFingerSwipeOrdinalDX[];
- static const char kKeyGestureFourFingerSwipeOrdinalDY[];
static const char kKeyGestureMetricsType[];
static const char kKeyGestureMetricsData1[];
static const char kKeyGestureMetricsData2[];
@@ -189,6 +316,37 @@ class ActivityLog {
static const char kKeyProperties[];
+ // AccelFilterInterpreter Debug Data keys:
+ static const char kKeyAccelGestureDebug[];
+ static const char kKeyAccelDebugNoAccelBadGain[];
+ static const char kKeyAccelDebugNoAccelGestureType[];
+ static const char kKeyAccelDebugNoAccelSmallDt[];
+ static const char kKeyAccelDebugNoAccelSmallSpeed[];
+ static const char kKeyAccelDebugDroppedGesture[];
+ static const char kKeyAccelDebugXYAreVelocity[];
+ static const char kKeyAccelDebugXScale[];
+ static const char kKeyAccelDebugYScale[];
+ static const char kKeyAccelDebugDt[];
+ static const char kKeyAccelDebugAdjustedDt[];
+ static const char kKeyAccelDebugSpeed[];
+ static const char kKeyAccelDebugSmoothSpeed[];
+ static const char kKeyAccelDebugGainX[];
+ static const char kKeyAccelDebugGainY[];
+
+ // Timestamp Debug Data keys:
+ static const char kKeyTimestampGestureDebug[];
+ static const char kKeyTimestampHardwareStateDebug[];
+ static const char kKeyTimestampDebugIsUsingFake[];
+ static const char kKeyTimestampDebugWasFirstOrBackward[];
+ static const char kKeyTimestampDebugPrevMscTimestampIn[];
+ static const char kKeyTimestampDebugPrevMscTimestampOut[];
+ static const char kKeyTimestampDebugWasDivergenceReset[];
+ static const char kKeyTimestampDebugFakeTimestampIn[];
+ static const char kKeyTimestampDebugFakeTimestampDelta[];
+ static const char kKeyTimestampDebugFakeTimestampOut[];
+ static const char kKeyTimestampDebugSkew[];
+ static const char kKeyTimestampDebugMaxSkew[];
+
private:
// Extends the tail of the buffer by one element and returns that new element.
// This may cause an older element to be overwritten if the buffer is full.
@@ -198,10 +356,26 @@ class ActivityLog {
// JSON-encoders for various types
Json::Value EncodeHardwareProperties() const;
+
+ Json::Value EncodeHardwareStateCommon(const HardwareState& hwstate);
Json::Value EncodeHardwareState(const HardwareState& hwstate);
+ Json::Value EncodeHardwareState(const HardwareStatePre& hwstate);
+ Json::Value EncodeHardwareState(const HardwareStatePost& hwstate);
+ Json::Value EncodeHardwareStateDebug(
+ const TimestampHardwareStateDebug& debug_data);
+
Json::Value EncodeTimerCallback(stime_t timestamp);
+ Json::Value EncodeHandleTimer(const HandleTimerPre& handle);
+ Json::Value EncodeHandleTimer(const HandleTimerPost& handle);
Json::Value EncodeCallbackRequest(stime_t timestamp);
+
+ Json::Value EncodeGestureCommon(const Gesture& gesture);
Json::Value EncodeGesture(const Gesture& gesture);
+ Json::Value EncodeGesture(const GestureConsume& gesture);
+ Json::Value EncodeGesture(const GestureProduce& gesture);
+ Json::Value EncodeGestureDebug(const AccelGestureDebug& debug_data);
+ Json::Value EncodeGestureDebug(const TimestampGestureDebug& debug_data);
+
Json::Value EncodePropChange(const PropChangeEntry& prop_change);
// Encode user-configurable properties
diff --git a/include/box_filter_interpreter.h b/include/box_filter_interpreter.h
index 4316e00..7155125 100644
--- a/include/box_filter_interpreter.h
+++ b/include/box_filter_interpreter.h
@@ -35,6 +35,7 @@ namespace gestures {
class BoxFilterInterpreter : public FilterInterpreter, public PropertyDelegate {
FRIEND_TEST(BoxFilterInterpreterTest, SimpleTest);
+ FRIEND_TEST(BoxFilterInterpreterTest, ZeroSizeBoxTest);
public:
// Takes ownership of |next|:
BoxFilterInterpreter(PropRegistry* prop_reg, Interpreter* next,
diff --git a/include/finger_metrics.h b/include/finger_metrics.h
index d518641..1773a94 100644
--- a/include/finger_metrics.h
+++ b/include/finger_metrics.h
@@ -74,6 +74,7 @@ class FingerMetrics {
public:
FingerMetrics();
explicit FingerMetrics(short tracking_id);
+ FingerMetrics(short tracking_id, stime_t timestamp);
FingerMetrics(const FingerState& state, stime_t timestamp);
// Update the finger metrics from a FingerState.
@@ -148,6 +149,12 @@ class Metrics {
// Clear all finger information
void Clear();
+ // Set the origin timestamp for a particular finger for testing purposes.
+ // Prefer calling Update with a whole HardwareState instead.
+ // TODO(b/307933752): remove this method once its last usage (in
+ // TapToClickStateMachineTest::check_hwstates) is removed.
+ void SetFingerOriginTimestampForTesting(short tracking_id, stime_t time);
+
private:
vector<FingerMetrics, kMaxFingers> fingers_;
diff --git a/include/fling_stop_filter_interpreter.h b/include/fling_stop_filter_interpreter.h
index 62c5ae0..577cebd 100644
--- a/include/fling_stop_filter_interpreter.h
+++ b/include/fling_stop_filter_interpreter.h
@@ -22,6 +22,8 @@ namespace gestures {
class FlingStopFilterInterpreter : public FilterInterpreter {
FRIEND_TEST(FlingStopFilterInterpreterTest, SimpleTest);
+ FRIEND_TEST(FlingStopFilterInterpreterTest, FlingGestureTest);
+ FRIEND_TEST(FlingStopFilterInterpreterTest, FlingStopMultimouseMoveTest);
public:
// Takes ownership of |next|:
FlingStopFilterInterpreter(PropRegistry* prop_reg,
diff --git a/include/gestures.h b/include/gestures.h
index 318a22c..3ccaa20 100644
--- a/include/gestures.h
+++ b/include/gestures.h
@@ -48,9 +48,9 @@ stime_t StimeFromTimespec(const struct timespec*);
struct HardwareProperties {
// Touch properties
// The minimum X coordinate that the device can report.
- float left;
+ float left = 0;
// The minimum Y coordinate that the device can report.
- float top;
+ float top = 0;
// The maximum X coordinate that the device can report.
float right;
// The maximum Y coordinate that the device can report.
@@ -165,6 +165,10 @@ struct HardwareProperties {
// 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 {
+ enum class ToolType {
+ kFinger = 0,
+ kPalm,
+ };
// The large and small radii of the ellipse of the finger touching the pad.
float touch_major, touch_minor;
@@ -188,6 +192,8 @@ struct FingerState {
// A bit field of flags that are used internally by the library. (See the
// GESTURES_FINGER_* constants.) Should be set to 0 on incoming FingerStates.
unsigned flags;
+
+ ToolType tool_type = ToolType::kFinger;
#ifdef __cplusplus
bool NonFlagsEquals(const FingerState& that) const {
return touch_major == that.touch_major &&
@@ -215,6 +221,8 @@ struct FingerState {
#define GESTURES_BUTTON_RIGHT 4
#define GESTURES_BUTTON_BACK 8
#define GESTURES_BUTTON_FORWARD 16
+#define GESTURES_BUTTON_SIDE 32
+#define GESTURES_BUTTON_EXTRA 64
// Describes one frame of data from the input device.
struct HardwareState {
@@ -235,12 +243,14 @@ struct HardwareState {
// The number of fingers touching the pad, which may be more than finger_cnt.
unsigned short touch_cnt;
// 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.
+ // representing the contacts currently being tracked. If finger_cnt is 0, this
+ // pointer will be null.
+ //
+ // 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
@@ -657,6 +667,7 @@ typedef struct GesturesPropProvider {
namespace gestures {
class Interpreter;
+class IntProperty;
class PropRegistry;
class LoggingFilterInterpreter;
class Tracer;
@@ -702,6 +713,7 @@ struct GestureInterpreter {
std::unique_ptr<Tracer> tracer_;
std::unique_ptr<Interpreter> interpreter_;
std::unique_ptr<MetricsProperties> mprops_;
+ std::unique_ptr<IntProperty> stack_version_;
GesturesTimerProvider* timer_provider_;
void* timer_provider_data_;
diff --git a/include/haptic_button_generator_filter_interpreter.h b/include/haptic_button_generator_filter_interpreter.h
index 90632b5..4f17780 100644
--- a/include/haptic_button_generator_filter_interpreter.h
+++ b/include/haptic_button_generator_filter_interpreter.h
@@ -23,6 +23,8 @@ class HapticButtonGeneratorFilterInterpreter : public FilterInterpreter {
FRIEND_TEST(HapticButtonGeneratorFilterInterpreterTest, SimpleTest);
FRIEND_TEST(HapticButtonGeneratorFilterInterpreterTest, NotHapticTest);
FRIEND_TEST(HapticButtonGeneratorFilterInterpreterTest,
+ NotHapticConsumeGestureTest);
+ FRIEND_TEST(HapticButtonGeneratorFilterInterpreterTest,
GesturePreventsButtonDownTest);
FRIEND_TEST(HapticButtonGeneratorFilterInterpreterTest, DynamicThresholdTest);
FRIEND_TEST(HapticButtonGeneratorFilterInterpreterTest, PalmTest);
diff --git a/include/immediate_interpreter.h b/include/immediate_interpreter.h
index 7f7ed61..1be420e 100644
--- a/include/immediate_interpreter.h
+++ b/include/immediate_interpreter.h
@@ -127,12 +127,12 @@ class HardwareStateBuffer {
// Pops most recently pushed state
void PopState();
- const HardwareState* Get(size_t idx) const {
- return &states_[(idx + newest_index_) % size_];
+ const HardwareState& Get(size_t idx) const {
+ return states_[(idx + newest_index_) % size_];
}
- HardwareState* Get(size_t idx) {
- return const_cast<HardwareState*>(
+ HardwareState& Get(size_t idx) {
+ return const_cast<HardwareState&>(
const_cast<const HardwareStateBuffer*>(this)->Get(idx));
}
@@ -344,6 +344,7 @@ class ImmediateInterpreter : public Interpreter, public PropertyDelegate {
FRIEND_TEST(ImmediateInterpreterTest, ClickTest);
FRIEND_TEST(ImmediateInterpreterTest, FlingDepthTest);
FRIEND_TEST(ImmediateInterpreterTest, GetGesturingFingersTest);
+ FRIEND_TEST(ImmediateInterpreterTest, GetGesturingFingersWithEmptyStateTest);
FRIEND_TEST(ImmediateInterpreterTest, PalmAtEdgeTest);
FRIEND_TEST(ImmediateInterpreterTest, PalmReevaluateTest);
FRIEND_TEST(ImmediateInterpreterTest, PalmTest);
@@ -355,13 +356,13 @@ class ImmediateInterpreter : public Interpreter, public PropertyDelegate {
FRIEND_TEST(ImmediateInterpreterTest, StationaryPalmTest);
FRIEND_TEST(ImmediateInterpreterTest, SwipeTest);
FRIEND_TEST(ImmediateInterpreterTest, TapRecordTest);
- FRIEND_TEST(ImmediateInterpreterTest, TapToClickEnableTest);
FRIEND_TEST(ImmediateInterpreterTest, TapToClickKeyboardTest);
FRIEND_TEST(ImmediateInterpreterTest, TapToClickLowPressureBeginOrEndTest);
FRIEND_TEST(ImmediateInterpreterTest, ThumbRetainReevaluateTest);
FRIEND_TEST(ImmediateInterpreterTest, ThumbRetainTest);
FRIEND_TEST(ImmediateInterpreterTest, WarpedFingersTappingTest);
FRIEND_TEST(ImmediateInterpreterTest, ZeroClickInitializationTest);
+ FRIEND_TEST(ImmediateInterpreterTtcEnableTest, TapToClickEnableTest);
friend class TapRecord;
friend class TapToClickStateMachineTest;
friend class FingerButtonClick;
@@ -398,8 +399,8 @@ class ImmediateInterpreter : public Interpreter, public PropertyDelegate {
bool device_reports_pressure() const { return hwprops_->reports_pressure; }
- stime_t finger_origin_timestamp(short finger_id) const {
- return origin_timestamps_.at(finger_id);
+ stime_t finger_origin_timestamp(short tracking_id) const {
+ return metrics_->GetFinger(tracking_id)->origin_time();
}
private:
@@ -627,10 +628,7 @@ class ImmediateInterpreter : public Interpreter, public PropertyDelegate {
Gesture result_;
Gesture prev_result_;
- // Time when a contact arrived. Persists even when fingers change.
- std::map<short, stime_t> origin_timestamps_;
-
- // Total distance travelled by a finger since the origin_timestamps_.
+ // Total distance travelled by a finger since its origin timestamp.
std::map<short, float> distance_walked_;
// Button data
diff --git a/include/integral_gesture_filter_interpreter.h b/include/integral_gesture_filter_interpreter.h
index 97f466c..7add202 100644
--- a/include/integral_gesture_filter_interpreter.h
+++ b/include/integral_gesture_filter_interpreter.h
@@ -18,6 +18,7 @@ namespace gestures {
// can be accumulated and together create a move of a single pixel.
class IntegralGestureFilterInterpreter : public FilterInterpreter {
+ FRIEND_TEST(IntegralGestureFilterInterpreterTestInterpreter, ConsumeGesture);
public:
// Takes ownership of |next|:
explicit IntegralGestureFilterInterpreter(Interpreter* next, Tracer* tracer);
diff --git a/include/interpreter.h b/include/interpreter.h
index f293580..4481f2d 100644
--- a/include/interpreter.h
+++ b/include/interpreter.h
@@ -38,6 +38,11 @@ class Interpreter {
FRIEND_TEST(InterpreterTest, ResetLogTest);
FRIEND_TEST(InterpreterTest, LoggingDisabledByDefault);
FRIEND_TEST(LoggingFilterInterpreterTest, LogResetHandlerTest);
+ FRIEND_TEST(InterpreterTest, EventDebugLoggingEnableTest);
+ FRIEND_TEST(InterpreterTest, LogHardwareStateTest);
+ FRIEND_TEST(InterpreterTest, LogGestureTest);
+ FRIEND_TEST(InterpreterTest, LogHandleTimerTest);
+ FRIEND_TEST(TimestampFilterInterpreterParmTest, TimestampDebugLoggingTest);
public:
Interpreter(PropRegistry* prop_reg, Tracer* tracer, bool force_log_creation);
virtual ~Interpreter();
@@ -90,12 +95,32 @@ class Interpreter {
stime_t* timeout) {}
virtual void HandleTimerImpl(stime_t now, stime_t* timeout) {}
+ bool EventLoggingIsEnabled();
void SetEventLoggingEnabled(bool enabled);
+ bool EventDebugLoggingIsEnabled(ActivityLog::EventDebug event);
+ uint32_t GetEventDebugLoggingEnabled();
+ void SetEventDebugLoggingEnabled(uint32_t enabled);
+ void EventDebugLoggingDisable(ActivityLog::EventDebug event);
+ void EventDebugLoggingEnable(ActivityLog::EventDebug event);
+
+ void LogGestureConsume(const std::string& name, const Gesture& gesture);
+ void LogGestureProduce(const std::string& name, const Gesture& gesture);
+ void LogHardwareStatePre(const std::string& name,
+ const HardwareState& hwstate);
+ void LogHardwareStatePost(const std::string& name,
+ const HardwareState& hwstate);
+ void LogHandleTimerPre(const std::string& name,
+ stime_t now, const stime_t* timeout);
+ void LogHandleTimerPost(const std::string& name,
+ stime_t now, const stime_t* timeout);
+
private:
const char* name_;
Tracer* tracer_;
+
bool enable_event_logging_ = false;
+ uint32_t enable_event_debug_logging_ = 0;
void LogOutputs(const Gesture* result, stime_t* timeout, const char* action);
};
diff --git a/include/logging_filter_interpreter.h b/include/logging_filter_interpreter.h
index ffc1685..5718d97 100644
--- a/include/logging_filter_interpreter.h
+++ b/include/logging_filter_interpreter.h
@@ -36,6 +36,7 @@ class LoggingFilterInterpreter : public FilterInterpreter,
private:
void Dump(const char* filename);
+ IntProperty event_debug_logging_enable_;
BoolProperty event_logging_enable_;
IntProperty logging_notify_;
// Reset the log by setting the property value.
diff --git a/include/lookahead_filter_interpreter.h b/include/lookahead_filter_interpreter.h
index 3eab4ad..19c536e 100644
--- a/include/lookahead_filter_interpreter.h
+++ b/include/lookahead_filter_interpreter.h
@@ -30,9 +30,11 @@ class LookaheadFilterInterpreter : public FilterInterpreter {
FRIEND_TEST(LookaheadFilterInterpreterTest, QuickMoveTest);
FRIEND_TEST(LookaheadFilterInterpreterTest, QuickSwipeTest);
FRIEND_TEST(LookaheadFilterInterpreterTest, SemiMtNoTrackingIdAssignmentTest);
- FRIEND_TEST(LookaheadFilterInterpreterTest, SimpleTest);
+ FRIEND_TEST(LookaheadFilterInterpreterParmTest, SimpleTest);
FRIEND_TEST(LookaheadFilterInterpreterTest, SpuriousCallbackTest);
FRIEND_TEST(LookaheadFilterInterpreterTest, VariableDelayTest);
+ FRIEND_TEST(LookaheadFilterInterpreterTest, AddFingerFlingTest);
+ FRIEND_TEST(LookaheadFilterInterpreterTest, ConsumeGestureTest);
public:
LookaheadFilterInterpreter(PropRegistry* prop_reg, Interpreter* next,
diff --git a/include/mouse_interpreter.h b/include/mouse_interpreter.h
index dc024b2..e56be37 100644
--- a/include/mouse_interpreter.h
+++ b/include/mouse_interpreter.h
@@ -21,6 +21,7 @@ class MouseInterpreter : public Interpreter, public PropertyDelegate {
FRIEND_TEST(MouseInterpreterTest, JankyScrollTest);
FRIEND_TEST(MouseInterpreterTest, WheelTickReportingHighResTest);
FRIEND_TEST(MouseInterpreterTest, WheelTickReportingLowResTest);
+ FRIEND_TEST(MouseInterpreterTest, EmulateScrollWheelTest);
public:
MouseInterpreter(PropRegistry* prop_reg, Tracer* tracer);
virtual ~MouseInterpreter() {};
diff --git a/include/palm_classifying_filter_interpreter.h b/include/palm_classifying_filter_interpreter.h
index 4ef88bd..53fcafe 100644
--- a/include/palm_classifying_filter_interpreter.h
+++ b/include/palm_classifying_filter_interpreter.h
@@ -25,6 +25,7 @@ namespace gestures {
// bottom area of the pad.
class PalmClassifyingFilterInterpreter : public FilterInterpreter {
+ FRIEND_TEST(PalmClassifyingFilterInterpreterTest, ExternallyMarkedPalmTest);
FRIEND_TEST(PalmClassifyingFilterInterpreterTest, PalmAtEdgeTest);
FRIEND_TEST(PalmClassifyingFilterInterpreterTest, PalmReevaluateTest);
FRIEND_TEST(PalmClassifyingFilterInterpreterTest, PalmTest);
diff --git a/include/timestamp_filter_interpreter.h b/include/timestamp_filter_interpreter.h
index 9e95a4d..6604efa 100644
--- a/include/timestamp_filter_interpreter.h
+++ b/include/timestamp_filter_interpreter.h
@@ -27,6 +27,8 @@ class TimestampFilterInterpreter : public FilterInterpreter {
FRIEND_TEST(TimestampFilterInterpreterTest, FakeTimestampTest);
FRIEND_TEST(TimestampFilterInterpreterTest, FakeTimestampJumpForwardTest);
FRIEND_TEST(TimestampFilterInterpreterTest, FakeTimestampFallBackwardTest);
+ FRIEND_TEST(TimestampFilterInterpreterTest, GestureDebugTest);
+ FRIEND_TEST(TimestampFilterInterpreterParmTest, TimestampDebugLoggingTest);
public:
// Takes ownership of |next|:
explicit TimestampFilterInterpreter(PropRegistry* prop_reg,
@@ -56,16 +58,27 @@ class TimestampFilterInterpreter : public FilterInterpreter {
// - hwstate.timestamp uses CLOCK_MONOTONIC as the time base, possibly with
// fine tuning provided by MSC_TIMESTAMP.
// - hwstate.msc_timestamp should not be used.
- void ChangeTimestampDefault(HardwareState& hwstate);
+ void ChangeTimestampDefault(
+ HardwareState& hwstate,
+ ActivityLog::TimestampHardwareStateDebug& debug_data);
// If neither hwstate.timestamp nor hwstate.msc_timestamp has reliable
// deltas, we use fake_timestamp_delta_ as the delta between consecutive
// reports, but don't allow our faked timestamp to diverge too far from
// hwstate.timestamp.
- void ChangeTimestampUsingFake(HardwareState& hwstate);
+ void ChangeTimestampUsingFake(
+ HardwareState& hwstate,
+ ActivityLog::TimestampHardwareStateDebug& debug_data);
void ConsumeGesture(const Gesture& gs);
+ template<typename T>
+ void LogDebugData(const T& debug_data) {
+ using EventDebug = ActivityLog::EventDebug;
+ if (EventDebugLoggingIsEnabled(EventDebug::Timestamp))
+ log_->LogDebugData(debug_data);
+ }
+
stime_t prev_msc_timestamp_;
// Difference between msc_timestamp and timestamp as of last timestamp reset.
diff --git a/src/accel_filter_interpreter.cc b/src/accel_filter_interpreter.cc
index 99bd298..23f7ac3 100644
--- a/src/accel_filter_interpreter.cc
+++ b/src/accel_filter_interpreter.cc
@@ -161,12 +161,15 @@ AccelFilterInterpreter::AccelFilterInterpreter(PropRegistry* prop_reg,
}
void AccelFilterInterpreter::ConsumeGesture(const Gesture& gs) {
+ const char name[] = "AccelFilterInterpreter::ConsumeGesture";
+ LogGestureConsume(name, gs);
+ auto debug_data = ActivityLog::AccelGestureDebug{};
+
// Use a copy of the gesture gs during the calculations and
// adjustments so the original is left alone.
Gesture gs_copy = gs;
- // Setup the parameters for acceleration calculations based on gesture
- // type.
+ // Setup the parameters for acceleration calculations based on gesture type.
float* dx;
float* dy;
float x_scale;
@@ -185,42 +188,68 @@ void AccelFilterInterpreter::ConsumeGesture(const Gesture& gs) {
scale_out_x_ordinal, scale_out_y_ordinal,
segs, max_segs)) {
// It was determined no acceleration was required.
+ debug_data.no_accel_for_gesture_type = true;
+ LogDebugData(debug_data);
+ LogGestureProduce(name, gs);
ProduceGesture(gs);
return;
}
+ debug_data.x_y_are_velocity = (dx == nullptr || dy == nullptr);
+ debug_data.x_scale = x_scale;
+ debug_data.y_scale = y_scale;
+ debug_data.dt = get_dt(gs);
+ debug_data.adjusted_dt = get_adjusted_dt(gs);
float speed;
if (!get_actual_speed(dx, dy,
- gs_copy.details.fling.vx, gs_copy.details.fling.vy,
+ gs.details.fling.vx, gs.details.fling.vy,
get_adjusted_dt(gs),
speed)) {
// dt was too small, don't accelerate.
+ debug_data.no_accel_for_small_dt = true;
+ LogDebugData(debug_data);
+ LogGestureProduce(name, gs);
ProduceGesture(gs);
return;
}
- smooth_speed(gs_copy, speed);
+ debug_data.speed = speed;
+ smooth_speed(gs, speed);
+ debug_data.smoothed_speed = speed;
// Avoid scaling if the speed is too small.
if (speed < 0.00001) {
- if (gs.type == kGestureTypeFling)
- ProduceGesture(gs); // Filter out zero length gestures.
- return; // Avoid division by 0.
- }
-
- // Find the appropriate ratio and apply scaling.
- auto ratio = RatioFromAccelCurve(segs, max_segs, speed);
- if (ratio > 0.0) {
- *scale_out_x *= ratio * x_scale;
- *scale_out_y *= ratio * y_scale;
-
- if (gs.type == kGestureTypeFling ||
- gs.type == kGestureTypeScroll) {
- // We don't accelerate the ordinal values as we do for normal ones
- // because this is how the Chrome needs it.
- *scale_out_x_ordinal *= x_scale;
- *scale_out_y_ordinal *= y_scale;
+ debug_data.no_accel_for_small_speed = true;
+ if (gs.type != kGestureTypeFling)
+ debug_data.dropped_gesture = true;
+ LogDebugData(debug_data);
+ if (gs.type == kGestureTypeFling) {
+ LogGestureProduce(name, gs);
+ ProduceGesture(gs); // Filter out zero length gestures.
+ }
+ } else {
+ // Find the appropriate ratio and apply scaling.
+ auto ratio = RatioFromAccelCurve(segs, max_segs, speed);
+ debug_data.gain_x = ratio;
+ debug_data.gain_y = ratio;
+ if (ratio > 0.0) {
+ *scale_out_x *= ratio * x_scale;
+ *scale_out_y *= ratio * y_scale;
+
+ if (gs.type == kGestureTypeFling ||
+ gs.type == kGestureTypeScroll) {
+ // We don't accelerate the ordinal values as we do for normal ones
+ // because this is how the Chrome needs it.
+ *scale_out_x_ordinal *= x_scale;
+ *scale_out_y_ordinal *= y_scale;
+ }
+ LogDebugData(debug_data);
+ LogGestureProduce(name, gs_copy);
+ ProduceGesture(gs_copy);
+ } else {
+ debug_data.no_accel_for_bad_gain = true;
+ debug_data.dropped_gesture = true;
+ LogDebugData(debug_data);
}
- ProduceGesture(gs_copy);
}
}
@@ -383,7 +412,7 @@ bool AccelFilterInterpreter::get_actual_speed(
return true;
}
-void AccelFilterInterpreter::smooth_speed(Gesture& gs, float& speed) {
+void AccelFilterInterpreter::smooth_speed(const Gesture& gs, float& speed) {
// Perform smoothing, if it is enabled.
if (smooth_accel_.val_) {
// Check if clock changed backwards.
@@ -408,14 +437,14 @@ void AccelFilterInterpreter::smooth_speed(Gesture& gs, float& speed) {
}
float AccelFilterInterpreter::RatioFromAccelCurve(
- CurveSegment const* segs,
- size_t const max_segs,
- float const speed) {
+ const CurveSegment* segs,
+ const size_t max_segs,
+ const float speed) {
if (speed <= 0.0)
return 0.0;
for (size_t i = 0; i < max_segs; ++i) {
- CurveSegment const & seg = segs[i];
+ const CurveSegment& seg = segs[i];
if (speed <= seg.x_) {
return (seg.sqr_ * speed) + seg.mul_ + (seg.int_ / speed);
}
diff --git a/src/accel_filter_interpreter_unittest.cc b/src/accel_filter_interpreter_unittest.cc
index b5ee16f..58e634d 100644
--- a/src/accel_filter_interpreter_unittest.cc
+++ b/src/accel_filter_interpreter_unittest.cc
@@ -22,6 +22,8 @@ using std::vector;
namespace gestures {
+using EventDebug = ActivityLog::EventDebug;
+
class AccelFilterInterpreterTest : public ::testing::Test {
protected:
HardwareState empty_hwstate_ = {};
@@ -177,6 +179,225 @@ TEST_F(AccelFilterInterpreterTest, TinyMoveTest) {
out->details.scroll.dx);
}
+TEST_F(AccelFilterInterpreterTest, BadGestureTest) {
+ PropRegistry prop_reg;
+ AccelFilterInterpreterTestInterpreter* base_interpreter =
+ new AccelFilterInterpreterTestInterpreter;
+ AccelFilterInterpreter accel_interpreter(&prop_reg, base_interpreter,
+ nullptr);
+ TestInterpreterWrapper interpreter(&accel_interpreter);
+
+ accel_interpreter.SetEventLoggingEnabled(true);
+ accel_interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
+ accel_interpreter.EventDebugLoggingEnable(EventDebug::Accel);
+ accel_interpreter.log_.reset(new ActivityLog(&prop_reg));
+
+ // AccelFilterInterpreter should not add gain to a ButtonsChange gesture.
+ base_interpreter->return_values_.push_back(Gesture(kGestureButtonsChange,
+ 1, // start time
+ 2, // end time
+ 0, // down
+ 0, // up
+ false)); // is_tap
+
+ // Send the ButtonsChange into AccelFilterInterpreter. The filter
+ // should send it right back out.
+ EXPECT_EQ(accel_interpreter.log_->size(), 0);
+ Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
+ ASSERT_NE(nullptr, out);
+ EXPECT_EQ(kGestureTypeButtonsChange, out->type);
+
+ // Encode the log into Json
+ Json::Value node;
+ Json::Value tree = accel_interpreter.log_->EncodeCommonInfo();
+
+ // Verify the Json information
+ EXPECT_EQ(accel_interpreter.log_->size(), 5);
+ node = tree[ActivityLog::kKeyRoot][0];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyHardwareState));
+ node = tree[ActivityLog::kKeyRoot][1];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGestureConsume));
+ node = tree[ActivityLog::kKeyRoot][2];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyAccelGestureDebug));
+ node = tree[ActivityLog::kKeyRoot][3];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGestureProduce));
+ node = tree[ActivityLog::kKeyRoot][4];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGesture));
+ accel_interpreter.log_->Clear();
+}
+
+TEST_F(AccelFilterInterpreterTest, BadDeltaTTest) {
+ PropRegistry prop_reg;
+ AccelFilterInterpreterTestInterpreter* base_interpreter =
+ new AccelFilterInterpreterTestInterpreter;
+ AccelFilterInterpreter accel_interpreter(&prop_reg, base_interpreter,
+ nullptr);
+ TestInterpreterWrapper interpreter(&accel_interpreter);
+
+ accel_interpreter.SetEventLoggingEnabled(true);
+ accel_interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
+ accel_interpreter.EventDebugLoggingEnable(EventDebug::Accel);
+ accel_interpreter.log_.reset(new ActivityLog(&prop_reg));
+
+ // Change the bounds for reasonable minimum Dt. This will allow the filter
+ // to keep a very small Dt without adjusting it.
+ accel_interpreter.min_reasonable_dt_.val_ = 0;
+
+ // Send the filter a very small Dt and have the logic catch that it
+ // is too small. This will not allow a fictitious Dt to be used but
+ // will just not apply gain to this specific gesture.
+ base_interpreter->return_values_.push_back(Gesture(kGestureMove,
+ 1, // start time
+ 1.000001, // end time
+ 4, // dx
+ 0)); // dy
+
+ // Send the Move into AccelFilterInterpreter. No gain should be applied
+ // to Dx, even though this small of a Dt would normally have added a lot
+ // of gain.
+ EXPECT_EQ(accel_interpreter.log_->size(), 0);
+ Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
+ ASSERT_NE(nullptr, out);
+ EXPECT_EQ(kGestureTypeMove, out->type);
+ EXPECT_EQ(fabsf(out->details.move.dx), 4);
+
+ // Encode the log into Json
+ Json::Value node;
+ Json::Value tree = accel_interpreter.log_->EncodeCommonInfo();
+
+ // Verify the Json information
+ EXPECT_EQ(accel_interpreter.log_->size(), 5);
+ node = tree[ActivityLog::kKeyRoot][0];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyHardwareState));
+ node = tree[ActivityLog::kKeyRoot][1];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGestureConsume));
+ node = tree[ActivityLog::kKeyRoot][2];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyAccelGestureDebug));
+ node = tree[ActivityLog::kKeyRoot][3];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGestureProduce));
+ node = tree[ActivityLog::kKeyRoot][4];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGesture));
+ accel_interpreter.log_->Clear();
+}
+
+TEST_F(AccelFilterInterpreterTest, BadSpeedFlingTest) {
+ PropRegistry prop_reg;
+ AccelFilterInterpreterTestInterpreter* base_interpreter =
+ new AccelFilterInterpreterTestInterpreter;
+ AccelFilterInterpreter accel_interpreter(&prop_reg, base_interpreter,
+ nullptr);
+ TestInterpreterWrapper interpreter(&accel_interpreter);
+
+ accel_interpreter.SetEventLoggingEnabled(true);
+ accel_interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
+ accel_interpreter.EventDebugLoggingEnable(EventDebug::Accel);
+ accel_interpreter.log_.reset(new ActivityLog(&prop_reg));
+
+ // Change the bounds for reasonable maximum Dt. This will allow the filter
+ // to keep a large Dt without adjusting it.
+ accel_interpreter.max_reasonable_dt_.val_ = 1000;
+
+ // Send the filter a Fling with a large Dt and have the logic catch that it
+ // is too big. This will not allow a fictitious Dt to be used but will
+ // just not apply gain to this specific gesture.
+ base_interpreter->return_values_.push_back(Gesture(kGestureFling,
+ 1, // start time
+ 2, // end time
+ 0.000001, // vx
+ 0, // vy
+ 0)); // state
+
+ // Send the Fling into AccelFilterInterpreter. No gain should be applied
+ // to Vx.
+ EXPECT_EQ(accel_interpreter.log_->size(), 0);
+ Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
+ ASSERT_NE(nullptr, out);
+ EXPECT_EQ(kGestureTypeFling, out->type);
+ EXPECT_NEAR(fabsf(out->details.fling.vx), 0.000001, 0.0000001);
+
+ // Encode the log into Json
+ Json::Value node;
+ Json::Value tree = accel_interpreter.log_->EncodeCommonInfo();
+
+ // Verify the Json information
+ EXPECT_EQ(accel_interpreter.log_->size(), 5);
+ node = tree[ActivityLog::kKeyRoot][0];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyHardwareState));
+ node = tree[ActivityLog::kKeyRoot][1];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGestureConsume));
+ node = tree[ActivityLog::kKeyRoot][2];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyAccelGestureDebug));
+ node = tree[ActivityLog::kKeyRoot][3];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGestureProduce));
+ node = tree[ActivityLog::kKeyRoot][4];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGesture));
+ accel_interpreter.log_->Clear();
+}
+
+TEST_F(AccelFilterInterpreterTest, BadSpeedMoveTest) {
+ PropRegistry prop_reg;
+ AccelFilterInterpreterTestInterpreter* base_interpreter =
+ new AccelFilterInterpreterTestInterpreter;
+ AccelFilterInterpreter accel_interpreter(&prop_reg, base_interpreter,
+ nullptr);
+ TestInterpreterWrapper interpreter(&accel_interpreter);
+
+ accel_interpreter.SetEventLoggingEnabled(true);
+ accel_interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
+ accel_interpreter.EventDebugLoggingEnable(EventDebug::Accel);
+ accel_interpreter.log_.reset(new ActivityLog(&prop_reg));
+
+ // Change the bounds for reasonable maximum Dt. This will allow the filter
+ // to keep a large Dt without adjusting it.
+ accel_interpreter.max_reasonable_dt_.val_ = 1000;
+
+ // Send the filter a Move with a large Dt and have the logic catch that it
+ // is too big. This will not allow a fictitious Dt to be used but will
+ // just not apply gain to this specific gesture.
+ base_interpreter->return_values_.push_back(Gesture(kGestureMove,
+ 1, // start time
+ 1000, // end time
+ 0.0001, // dx
+ 0)); // dy
+
+ // Send the Move into AccelFilterInterpreter. The gesture should be dropped.
+ EXPECT_EQ(accel_interpreter.log_->size(), 0);
+ Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
+ ASSERT_EQ(nullptr, out);
+
+ // Encode the log into Json
+ Json::Value node;
+ Json::Value tree = accel_interpreter.log_->EncodeCommonInfo();
+
+ // Verify the Json information
+ EXPECT_EQ(accel_interpreter.log_->size(), 3);
+ node = tree[ActivityLog::kKeyRoot][0];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyHardwareState));
+ node = tree[ActivityLog::kKeyRoot][1];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGestureConsume));
+ node = tree[ActivityLog::kKeyRoot][2];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyAccelGestureDebug));
+ accel_interpreter.log_->Clear();
+}
+
TEST_F(AccelFilterInterpreterTest, TimingTest) {
AccelFilterInterpreterTestInterpreter* base_interpreter =
new AccelFilterInterpreterTestInterpreter;
@@ -889,4 +1110,55 @@ TEST_F(AccelFilterInterpreterTest, TouchpadScrollAccelCurveTest) {
}
}
+TEST_F(AccelFilterInterpreterTest, AccelDebugDataTest) {
+ PropRegistry prop_reg;
+ AccelFilterInterpreterTestInterpreter* base_interpreter =
+ new AccelFilterInterpreterTestInterpreter;
+ AccelFilterInterpreter accel_interpreter(&prop_reg, base_interpreter,
+ nullptr);
+ TestInterpreterWrapper interpreter(&accel_interpreter);
+
+ accel_interpreter.SetEventLoggingEnabled(true);
+ accel_interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
+ accel_interpreter.EventDebugLoggingEnable(EventDebug::HardwareState);
+ accel_interpreter.EventDebugLoggingEnable(EventDebug::Accel);
+ accel_interpreter.log_.reset(new ActivityLog(&prop_reg));
+
+ accel_interpreter.scroll_x_out_scale_.val_ =
+ accel_interpreter.scroll_y_out_scale_.val_ = 1.0;
+
+ base_interpreter->return_values_.push_back(Gesture(kGestureScroll,
+ 2, // start time
+ 2.1, // end time
+ 4.1, // dx
+ -10.3)); // dy
+
+ Gesture* out = interpreter.SyncInterpret(empty_hwstate_, nullptr);
+ ASSERT_NE(nullptr, out);
+ EXPECT_EQ(kGestureTypeScroll, out->type);
+
+ // Encode the log into Json
+ Json::Value node;
+ Json::Value tree = accel_interpreter.log_->EncodeCommonInfo();
+
+ // Verify the Json information
+ EXPECT_EQ(accel_interpreter.log_->size(), 5);
+ node = tree[ActivityLog::kKeyRoot][0];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyHardwareState));
+ node = tree[ActivityLog::kKeyRoot][1];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGestureConsume));
+ node = tree[ActivityLog::kKeyRoot][2];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyAccelGestureDebug));
+ node = tree[ActivityLog::kKeyRoot][3];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGestureProduce));
+ node = tree[ActivityLog::kKeyRoot][4];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGesture));
+ accel_interpreter.log_->Clear();
+}
+
} // namespace gestures
diff --git a/src/activity_log.cc b/src/activity_log.cc
index 249ad45..9e6bfbf 100644
--- a/src/activity_log.cc
+++ b/src/activity_log.cc
@@ -19,11 +19,6 @@
#include "include/prop_registry.h"
#include "include/string_util.h"
-// This should be set by build system:
-#ifndef VCSID
-#define VCSID "Unknown"
-#endif // VCSID
-
#define QUINTTAP_COUNT 5 /* BTN_TOOL_QUINTTAP - Five fingers on trackpad */
using std::set;
@@ -33,7 +28,9 @@ namespace {
// Helper to std::visit with lambdas.
template <typename... V>
-struct Visitor : V... {};
+struct Visitor : V... {
+ using V::operator()...;
+};
// Explicit deduction guide (not needed as of C++20).
template <typename... V>
Visitor(V...) -> Visitor<V...>;
@@ -104,6 +101,56 @@ void ActivityLog::LogPropChange(const PropChangeEntry& prop_change) {
entry->details = prop_change;
}
+void ActivityLog::LogGestureConsume(
+ const std::string& name, const Gesture& gesture) {
+ GestureConsume gesture_consume { name, gesture };
+ Entry* entry = PushBack();
+ entry->details = gesture_consume;
+}
+
+void ActivityLog::LogGestureProduce(
+ const std::string& name, const Gesture& gesture) {
+ GestureProduce gesture_produce { name, gesture };
+ Entry* entry = PushBack();
+ entry->details = gesture_produce;
+}
+
+void ActivityLog::LogHardwareStatePre(const std::string& name,
+ const HardwareState& hwstate) {
+ HardwareStatePre hwstate_pre { name, hwstate };
+ Entry* entry = PushBack();
+ entry->details = hwstate_pre;
+}
+
+void ActivityLog::LogHardwareStatePost(const std::string& name,
+ const HardwareState& hwstate) {
+ HardwareStatePost hwstate_post { name, hwstate };
+ Entry* entry = PushBack();
+ entry->details = hwstate_post;
+}
+
+void ActivityLog::LogHandleTimerPre(const std::string& name,
+ stime_t now, const stime_t* timeout) {
+ HandleTimerPre handle;
+ handle.name = name;
+ handle.now = now;
+ handle.timeout_is_present = (timeout != nullptr);
+ handle.timeout = (timeout == nullptr) ? 0 : *timeout;
+ Entry* entry = PushBack();
+ entry->details = handle;
+}
+
+void ActivityLog::LogHandleTimerPost(const std::string& name,
+ stime_t now, const stime_t* timeout) {
+ HandleTimerPost handle;
+ handle.name = name;
+ handle.now = now;
+ handle.timeout_is_present = (timeout != nullptr);
+ handle.timeout = (timeout == nullptr) ? 0 : *timeout;
+ Entry* entry = PushBack();
+ entry->details = handle;
+}
+
void ActivityLog::Dump(const char* filename) {
string data = Encode();
WriteFile(filename, data.c_str(), data.size());
@@ -143,9 +190,9 @@ Json::Value ActivityLog::EncodeHardwareProperties() const {
return ret;
}
-Json::Value ActivityLog::EncodeHardwareState(const HardwareState& hwstate) {
+Json::Value ActivityLog::EncodeHardwareStateCommon(
+ const HardwareState& hwstate) {
Json::Value ret(Json::objectValue);
- ret[kKeyType] = Json::Value(kKeyHardwareState);
ret[kKeyHardwareStateButtonsDown] = Json::Value(hwstate.buttons_down);
ret[kKeyHardwareStateTouchCnt] = Json::Value(hwstate.touch_cnt);
ret[kKeyHardwareStateTimestamp] = Json::Value(hwstate.timestamp);
@@ -177,10 +224,52 @@ Json::Value ActivityLog::EncodeHardwareState(const HardwareState& hwstate) {
return ret;
}
+Json::Value ActivityLog::EncodeHardwareState(const HardwareState& hwstate) {
+ auto ret = EncodeHardwareStateCommon(hwstate);
+ ret[kKeyType] = Json::Value(kKeyHardwareState);
+ return ret;
+}
+
+Json::Value ActivityLog::EncodeHardwareState(
+ const HardwareStatePre& pre_hwstate) {
+ auto ret = EncodeHardwareStateCommon(pre_hwstate.hwstate);
+ ret[kKeyType] = Json::Value(kKeyHardwareStatePre);
+ ret[kKeyMethodName] = Json::Value(pre_hwstate.name);
+ return ret;
+}
+
+Json::Value ActivityLog::EncodeHardwareState(
+ const HardwareStatePost& post_hwstate) {
+ auto ret = EncodeHardwareStateCommon(post_hwstate.hwstate);
+ ret[kKeyType] = Json::Value(kKeyHardwareStatePost);
+ ret[kKeyMethodName] = Json::Value(post_hwstate.name);
+ return ret;
+}
+
+Json::Value ActivityLog::EncodeHandleTimer(const HandleTimerPre& handle) {
+ Json::Value ret(Json::objectValue);
+ ret[kKeyType] = Json::Value(kKeyHandleTimerPre);
+ ret[kKeyMethodName] = Json::Value(handle.name);
+ ret[kKeyTimerNow] = Json::Value(handle.now);
+ if (handle.timeout_is_present)
+ ret[kKeyHandleTimerTimeout] = Json::Value(handle.timeout);
+ return ret;
+}
+
+Json::Value ActivityLog::EncodeHandleTimer(const HandleTimerPost& handle) {
+ Json::Value ret(Json::objectValue);
+ ret[kKeyType] = Json::Value(kKeyHandleTimerPost);
+ ret[kKeyMethodName] = Json::Value(handle.name);
+ ret[kKeyTimerNow] = Json::Value(handle.now);
+ if (handle.timeout_is_present)
+ ret[kKeyHandleTimerTimeout] = Json::Value(handle.timeout);
+ return ret;
+}
+
Json::Value ActivityLog::EncodeTimerCallback(stime_t timestamp) {
Json::Value ret(Json::objectValue);
ret[kKeyType] = Json::Value(kKeyTimerCallback);
- ret[kKeyTimerCallbackNow] = Json::Value(timestamp);
+ ret[kKeyTimerNow] = Json::Value(timestamp);
return ret;
}
@@ -191,9 +280,8 @@ Json::Value ActivityLog::EncodeCallbackRequest(stime_t timestamp) {
return ret;
}
-Json::Value ActivityLog::EncodeGesture(const Gesture& gesture) {
+Json::Value ActivityLog::EncodeGestureCommon(const Gesture& gesture) {
Json::Value ret(Json::objectValue);
- ret[kKeyType] = Json::Value(kKeyGesture);
ret[kKeyGestureStartTime] = Json::Value(gesture.start_time);
ret[kKeyGestureEndTime] = Json::Value(gesture.end_time);
@@ -206,26 +294,24 @@ Json::Value ActivityLog::EncodeGesture(const Gesture& gesture) {
break;
case kGestureTypeMove:
ret[kKeyGestureType] = Json::Value(kValueGestureTypeMove);
- ret[kKeyGestureMoveDX] = Json::Value(gesture.details.move.dx);
- ret[kKeyGestureMoveDY] = Json::Value(gesture.details.move.dy);
- ret[kKeyGestureMoveOrdinalDX] =
- Json::Value(gesture.details.move.ordinal_dx);
- ret[kKeyGestureMoveOrdinalDY] =
- Json::Value(gesture.details.move.ordinal_dy);
+ ret[kKeyGestureDX] = Json::Value(gesture.details.move.dx);
+ ret[kKeyGestureDY] = Json::Value(gesture.details.move.dy);
+ ret[kKeyGestureOrdinalDX] = Json::Value(gesture.details.move.ordinal_dx);
+ ret[kKeyGestureOrdinalDY] = Json::Value(gesture.details.move.ordinal_dy);
break;
case kGestureTypeScroll:
ret[kKeyGestureType] = Json::Value(kValueGestureTypeScroll);
- ret[kKeyGestureScrollDX] = Json::Value(gesture.details.scroll.dx);
- ret[kKeyGestureScrollDY] = Json::Value(gesture.details.scroll.dy);
- ret[kKeyGestureScrollOrdinalDX] =
+ ret[kKeyGestureDX] = Json::Value(gesture.details.scroll.dx);
+ ret[kKeyGestureDY] = Json::Value(gesture.details.scroll.dy);
+ ret[kKeyGestureOrdinalDX] =
Json::Value(gesture.details.scroll.ordinal_dx);
- ret[kKeyGestureScrollOrdinalDY] =
+ ret[kKeyGestureOrdinalDY] =
Json::Value(gesture.details.scroll.ordinal_dy);
break;
case kGestureTypeMouseWheel:
ret[kKeyGestureType] = Json::Value(kValueGestureTypeMouseWheel);
- ret[kKeyGestureMouseWheelDX] = Json::Value(gesture.details.wheel.dx);
- ret[kKeyGestureMouseWheelDY] = Json::Value(gesture.details.wheel.dy);
+ ret[kKeyGestureDX] = Json::Value(gesture.details.wheel.dx);
+ ret[kKeyGestureDY] = Json::Value(gesture.details.wheel.dy);
ret[kKeyGestureMouseWheelTicksDX] =
Json::Value(gesture.details.wheel.tick_120ths_dx);
ret[kKeyGestureMouseWheelTicksDY] =
@@ -259,11 +345,11 @@ Json::Value ActivityLog::EncodeGesture(const Gesture& gesture) {
break;
case kGestureTypeSwipe:
ret[kKeyGestureType] = Json::Value(kValueGestureTypeSwipe);
- ret[kKeyGestureSwipeDX] = Json::Value(gesture.details.swipe.dx);
- ret[kKeyGestureSwipeDY] = Json::Value(gesture.details.swipe.dy);
- ret[kKeyGestureSwipeOrdinalDX] =
+ ret[kKeyGestureDX] = Json::Value(gesture.details.swipe.dx);
+ ret[kKeyGestureDY] = Json::Value(gesture.details.swipe.dy);
+ ret[kKeyGestureOrdinalDX] =
Json::Value(gesture.details.swipe.ordinal_dx);
- ret[kKeyGestureSwipeOrdinalDY] =
+ ret[kKeyGestureOrdinalDY] =
Json::Value(gesture.details.swipe.ordinal_dy);
break;
case kGestureTypeSwipeLift:
@@ -271,13 +357,13 @@ Json::Value ActivityLog::EncodeGesture(const Gesture& gesture) {
break;
case kGestureTypeFourFingerSwipe:
ret[kKeyGestureType] = Json::Value(kValueGestureTypeFourFingerSwipe);
- ret[kKeyGestureFourFingerSwipeDX] =
+ ret[kKeyGestureDX] =
Json::Value(gesture.details.four_finger_swipe.dx);
- ret[kKeyGestureFourFingerSwipeDY] =
+ ret[kKeyGestureDY] =
Json::Value(gesture.details.four_finger_swipe.dy);
- ret[kKeyGestureFourFingerSwipeOrdinalDX] =
+ ret[kKeyGestureOrdinalDX] =
Json::Value(gesture.details.four_finger_swipe.ordinal_dx);
- ret[kKeyGestureFourFingerSwipeOrdinalDY] =
+ ret[kKeyGestureOrdinalDY] =
Json::Value(gesture.details.four_finger_swipe.ordinal_dy);
break;
case kGestureTypeFourFingerSwipeLift:
@@ -299,6 +385,26 @@ Json::Value ActivityLog::EncodeGesture(const Gesture& gesture) {
return ret;
}
+Json::Value ActivityLog::EncodeGesture(const Gesture& gesture) {
+ auto ret = EncodeGestureCommon(gesture);
+ ret[kKeyType] = Json::Value(kKeyGesture);
+ return ret;
+}
+
+Json::Value ActivityLog::EncodeGesture(const GestureConsume& gesture_consume) {
+ auto ret = EncodeGestureCommon(gesture_consume.gesture);
+ ret[kKeyType] = Json::Value(kKeyGestureConsume);
+ ret[kKeyMethodName] = Json::Value(gesture_consume.name);
+ return ret;
+}
+
+Json::Value ActivityLog::EncodeGesture(const GestureProduce& gesture_produce) {
+ auto ret = EncodeGestureCommon(gesture_produce.gesture);
+ ret[kKeyType] = Json::Value(kKeyGestureProduce);
+ ret[kKeyMethodName] = Json::Value(gesture_produce.name);
+ return ret;
+}
+
Json::Value ActivityLog::EncodePropChange(const PropChangeEntry& prop_change) {
Json::Value ret(Json::objectValue);
ret[kKeyType] = Json::Value(kKeyPropChange);
@@ -334,6 +440,67 @@ Json::Value ActivityLog::EncodePropChange(const PropChangeEntry& prop_change) {
return ret;
}
+Json::Value ActivityLog::EncodeGestureDebug(
+ const AccelGestureDebug& debug_data) {
+ Json::Value ret(Json::objectValue);
+ ret[kKeyType] = Json::Value(kKeyAccelGestureDebug);
+ ret[kKeyAccelDebugDroppedGesture] = Json::Value(debug_data.dropped_gesture);
+ if (debug_data.no_accel_for_gesture_type)
+ ret[kKeyAccelDebugNoAccelGestureType] = Json::Value(true);
+ else if (debug_data.no_accel_for_small_dt)
+ ret[kKeyAccelDebugNoAccelSmallDt] = Json::Value(true);
+ else if (debug_data.no_accel_for_small_speed)
+ ret[kKeyAccelDebugNoAccelSmallSpeed] = Json::Value(true);
+ else if (debug_data.no_accel_for_bad_gain)
+ ret[kKeyAccelDebugNoAccelBadGain] = Json::Value(true);
+ ret[kKeyAccelDebugXYAreVelocity] = Json::Value(debug_data.x_y_are_velocity);
+ ret[kKeyAccelDebugXScale] = Json::Value(debug_data.x_scale);
+ ret[kKeyAccelDebugYScale] = Json::Value(debug_data.y_scale);
+ ret[kKeyAccelDebugDt] = Json::Value(debug_data.dt);
+ ret[kKeyAccelDebugAdjustedDt] = Json::Value(debug_data.adjusted_dt);
+ ret[kKeyAccelDebugSpeed] = Json::Value(debug_data.speed);
+ if (debug_data.speed != debug_data.smoothed_speed)
+ ret[kKeyAccelDebugSmoothSpeed] = Json::Value(debug_data.smoothed_speed);
+ ret[kKeyAccelDebugGainX] = Json::Value(debug_data.gain_x);
+ ret[kKeyAccelDebugGainY] = Json::Value(debug_data.gain_y);
+ return ret;
+}
+
+Json::Value ActivityLog::EncodeGestureDebug(
+ const TimestampGestureDebug& debug_data) {
+ Json::Value ret(Json::objectValue);
+ ret[kKeyType] = Json::Value(kKeyTimestampGestureDebug);
+ ret[kKeyTimestampDebugSkew] = Json::Value(debug_data.skew);
+ return ret;
+}
+
+Json::Value ActivityLog::EncodeHardwareStateDebug(
+ const TimestampHardwareStateDebug& debug_data) {
+ Json::Value ret(Json::objectValue);
+ ret[kKeyType] = Json::Value(kKeyTimestampHardwareStateDebug);
+ ret[kKeyTimestampDebugIsUsingFake] = Json::Value(debug_data.is_using_fake);
+ if (debug_data.is_using_fake) {
+ ret[kKeyTimestampDebugWasFirstOrBackward] =
+ Json::Value(debug_data.was_first_or_backward);
+ ret[kKeyTimestampDebugPrevMscTimestampIn] =
+ Json::Value(debug_data.prev_msc_timestamp_in);
+ ret[kKeyTimestampDebugPrevMscTimestampOut] =
+ Json::Value(debug_data.prev_msc_timestamp_out);
+ } else {
+ ret[kKeyTimestampDebugWasDivergenceReset] =
+ Json::Value(debug_data.was_divergence_reset);
+ ret[kKeyTimestampDebugFakeTimestampIn] =
+ Json::Value(debug_data.fake_timestamp_in);
+ ret[kKeyTimestampDebugFakeTimestampDelta] =
+ Json::Value(debug_data.fake_timestamp_delta);
+ ret[kKeyTimestampDebugFakeTimestampOut] =
+ Json::Value(debug_data.fake_timestamp_out);
+ }
+ ret[kKeyTimestampDebugSkew] = Json::Value(debug_data.skew);
+ ret[kKeyTimestampDebugMaxSkew] = Json::Value(debug_data.max_skew);
+ return ret;
+}
+
Json::Value ActivityLog::EncodePropRegistry() {
Json::Value ret(Json::objectValue);
if (!prop_reg_)
@@ -357,6 +524,12 @@ Json::Value ActivityLog::EncodeCommonInfo() {
[this, &entries](HardwareState hwstate) {
entries.append(EncodeHardwareState(hwstate));
},
+ [this, &entries](HardwareStatePre hwstate) {
+ entries.append(EncodeHardwareState(hwstate));
+ },
+ [this, &entries](HardwareStatePost hwstate) {
+ entries.append(EncodeHardwareState(hwstate));
+ },
[this, &entries](TimerCallbackEntry now) {
entries.append(EncodeTimerCallback(now.timestamp));
},
@@ -366,9 +539,30 @@ Json::Value ActivityLog::EncodeCommonInfo() {
[this, &entries](Gesture gesture) {
entries.append(EncodeGesture(gesture));
},
+ [this, &entries](GestureConsume gesture) {
+ entries.append(EncodeGesture(gesture));
+ },
+ [this, &entries](GestureProduce gesture) {
+ entries.append(EncodeGesture(gesture));
+ },
[this, &entries](PropChangeEntry prop_change) {
entries.append(EncodePropChange(prop_change));
},
+ [this, &entries](HandleTimerPre handle) {
+ entries.append(EncodeHandleTimer(handle));
+ },
+ [this, &entries](HandleTimerPost handle) {
+ entries.append(EncodeHandleTimer(handle));
+ },
+ [this, &entries](AccelGestureDebug debug_data) {
+ entries.append(EncodeGestureDebug(debug_data));
+ },
+ [this, &entries](TimestampGestureDebug debug_data) {
+ entries.append(EncodeGestureDebug(debug_data));
+ },
+ [this, &entries](TimestampHardwareStateDebug debug_data) {
+ entries.append(EncodeHardwareStateDebug(debug_data));
+ },
[](auto arg) {
Err("Unknown entry type");
}
@@ -400,10 +594,19 @@ const char ActivityLog::kKeyInterpreterName[] = "interpreterName";
const char ActivityLog::kKeyNext[] = "nextLayer";
const char ActivityLog::kKeyRoot[] = "entries";
const char ActivityLog::kKeyType[] = "type";
+const char ActivityLog::kKeyMethodName[] = "methodName";
const char ActivityLog::kKeyHardwareState[] = "hardwareState";
+const char ActivityLog::kKeyHardwareStatePre[] = "debugHardwareStatePre";
+const char ActivityLog::kKeyHardwareStatePost[] = "debugHardwareStatePost";
const char ActivityLog::kKeyTimerCallback[] = "timerCallback";
const char ActivityLog::kKeyCallbackRequest[] = "callbackRequest";
const char ActivityLog::kKeyGesture[] = "gesture";
+const char ActivityLog::kKeyGestureConsume[] = "debugGestureConsume";
+const char ActivityLog::kKeyGestureProduce[] = "debugGestureProduce";
+const char ActivityLog::kKeyHandleTimerPre[] = "debugHandleTimerPre";
+const char ActivityLog::kKeyHandleTimerPost[] = "debugHandleTimerPost";
+const char ActivityLog::kKeyTimerNow[] = "now";
+const char ActivityLog::kKeyHandleTimerTimeout[] = "timeout";
const char ActivityLog::kKeyPropChange[] = "propertyChange";
const char ActivityLog::kKeyHardwareStateTimestamp[] = "timestamp";
const char ActivityLog::kKeyHardwareStateButtonsDown[] = "buttonsDown";
@@ -423,7 +626,6 @@ const char ActivityLog::kKeyFingerStatePositionX[] = "positionX";
const char ActivityLog::kKeyFingerStatePositionY[] = "positionY";
const char ActivityLog::kKeyFingerStateTrackingId[] = "trackingId";
const char ActivityLog::kKeyFingerStateFlags[] = "flags";
-const char ActivityLog::kKeyTimerCallbackNow[] = "now";
const char ActivityLog::kKeyCallbackRequestWhen[] = "when";
const char ActivityLog::kKeyGestureType[] = "gestureType";
const char ActivityLog::kValueGestureTypeContactInitiated[] =
@@ -442,16 +644,10 @@ const char ActivityLog::kValueGestureTypeFourFingerSwipeLift[] =
const char ActivityLog::kValueGestureTypeMetrics[] = "metrics";
const char ActivityLog::kKeyGestureStartTime[] = "startTime";
const char ActivityLog::kKeyGestureEndTime[] = "endTime";
-const char ActivityLog::kKeyGestureMoveDX[] = "dx";
-const char ActivityLog::kKeyGestureMoveDY[] = "dy";
-const char ActivityLog::kKeyGestureMoveOrdinalDX[] = "ordinalDx";
-const char ActivityLog::kKeyGestureMoveOrdinalDY[] = "ordinalDy";
-const char ActivityLog::kKeyGestureScrollDX[] = "dx";
-const char ActivityLog::kKeyGestureScrollDY[] = "dy";
-const char ActivityLog::kKeyGestureScrollOrdinalDX[] = "ordinalDx";
-const char ActivityLog::kKeyGestureScrollOrdinalDY[] = "ordinalDy";
-const char ActivityLog::kKeyGestureMouseWheelDX[] = "dx";
-const char ActivityLog::kKeyGestureMouseWheelDY[] = "dy";
+const char ActivityLog::kKeyGestureDX[] = "dx";
+const char ActivityLog::kKeyGestureDY[] = "dy";
+const char ActivityLog::kKeyGestureOrdinalDX[] = "ordinalDx";
+const char ActivityLog::kKeyGestureOrdinalDY[] = "ordinalDy";
const char ActivityLog::kKeyGestureMouseWheelTicksDX[] = "ticksDx";
const char ActivityLog::kKeyGestureMouseWheelTicksDY[] = "ticksDy";
const char ActivityLog::kKeyGesturePinchDZ[] = "dz";
@@ -464,14 +660,6 @@ const char ActivityLog::kKeyGestureFlingVY[] = "vy";
const char ActivityLog::kKeyGestureFlingOrdinalVX[] = "ordinalVx";
const char ActivityLog::kKeyGestureFlingOrdinalVY[] = "ordinalVy";
const char ActivityLog::kKeyGestureFlingState[] = "flingState";
-const char ActivityLog::kKeyGestureSwipeDX[] = "dx";
-const char ActivityLog::kKeyGestureSwipeDY[] = "dy";
-const char ActivityLog::kKeyGestureSwipeOrdinalDX[] = "ordinalDx";
-const char ActivityLog::kKeyGestureSwipeOrdinalDY[] = "ordinalDy";
-const char ActivityLog::kKeyGestureFourFingerSwipeDX[] = "dx";
-const char ActivityLog::kKeyGestureFourFingerSwipeDY[] = "dy";
-const char ActivityLog::kKeyGestureFourFingerSwipeOrdinalDX[] = "ordinalDx";
-const char ActivityLog::kKeyGestureFourFingerSwipeOrdinalDY[] = "ordinalDy";
const char ActivityLog::kKeyGestureMetricsType[] = "metricsType";
const char ActivityLog::kKeyGestureMetricsData1[] = "data1";
const char ActivityLog::kKeyGestureMetricsData2[] = "data2";
@@ -504,5 +692,42 @@ const char ActivityLog::kKeyHardwarePropHasWheel[] = "hasWheel";
const char ActivityLog::kKeyProperties[] = "properties";
+const char ActivityLog::kKeyAccelGestureDebug[] = "debugAccelGesture";
+const char ActivityLog::kKeyAccelDebugNoAccelBadGain[] = "noAccelBadGain";
+const char ActivityLog::kKeyAccelDebugNoAccelGestureType[] = "noAccelBadType";
+const char ActivityLog::kKeyAccelDebugNoAccelSmallDt[] = "noAccelSmallDt";
+const char ActivityLog::kKeyAccelDebugNoAccelSmallSpeed[] =
+ "noAccelSmallSpeed";
+const char ActivityLog::kKeyAccelDebugDroppedGesture[] = "gestureDropped";
+const char ActivityLog::kKeyAccelDebugXYAreVelocity[] = "XYAreVelocity";
+const char ActivityLog::kKeyAccelDebugXScale[] = "XScale";
+const char ActivityLog::kKeyAccelDebugYScale[] = "YScale";
+const char ActivityLog::kKeyAccelDebugDt[] = "dt";
+const char ActivityLog::kKeyAccelDebugAdjustedDt[] = "adjDt";
+const char ActivityLog::kKeyAccelDebugSpeed[] = "speed";
+const char ActivityLog::kKeyAccelDebugSmoothSpeed[] = "smoothSpeed";
+const char ActivityLog::kKeyAccelDebugGainX[] = "gainX";
+const char ActivityLog::kKeyAccelDebugGainY[] = "gainY";
+
+const char ActivityLog::kKeyTimestampGestureDebug[] = "debugTimestampGesture";
+const char ActivityLog::kKeyTimestampHardwareStateDebug[] =
+ "debugTimestampHardwareState";
+const char ActivityLog::kKeyTimestampDebugIsUsingFake[] = "isUsingFake";
+const char ActivityLog::kKeyTimestampDebugWasFirstOrBackward[] =
+ "wasFirstOrBackward";
+const char ActivityLog::kKeyTimestampDebugPrevMscTimestampIn[] =
+ "prevMscTimestampIn";
+const char ActivityLog::kKeyTimestampDebugPrevMscTimestampOut[] =
+ "prevMscTimestampOut";
+const char ActivityLog::kKeyTimestampDebugWasDivergenceReset[] =
+ "wasDivergenceReset";
+const char ActivityLog::kKeyTimestampDebugFakeTimestampIn[] =
+ "fakeTimestampIn";
+const char ActivityLog::kKeyTimestampDebugFakeTimestampDelta[] =
+ "fakeTimestampDelta";
+const char ActivityLog::kKeyTimestampDebugFakeTimestampOut[] =
+ "fakeTimestampOut";
+const char ActivityLog::kKeyTimestampDebugSkew[] = "skew";
+const char ActivityLog::kKeyTimestampDebugMaxSkew[] = "maxSkew";
} // namespace gestures
diff --git a/src/activity_log_unittest.cc b/src/activity_log_unittest.cc
index aadf2f5..36dd6c0 100644
--- a/src/activity_log_unittest.cc
+++ b/src/activity_log_unittest.cc
@@ -33,24 +33,24 @@ TEST(ActivityLogTest, SimpleTest) {
EXPECT_TRUE(strstr(log.Encode().c_str(), "foobarstr"));
HardwareProperties hwprops = {
- 6011, // left edge
- 6012, // top edge
- 6013, // right edge
- 6014, // bottom edge
- 6015, // x pixels/TP width
- 6016, // y pixels/TP height
- 6017, // x screen DPI
- 6018, // y screen DPI
- 6019, // orientation minimum
- 6020, // orientation maximum
- 6021, // max fingers
- 6022, // max touch
- 1, // t5r2
- 0, // semi-mt
- 1, // is button pad,
- 0, // has wheel
- 0, // vertical wheel is high resolution
- 0, // is haptic pad
+ .left = 6011,
+ .top = 6012,
+ .right = 6013,
+ .bottom = 6014,
+ .res_x = 6015,
+ .res_y = 6016,
+ .screen_x_dpi = 6017,
+ .screen_y_dpi = 6018,
+ .orientation_minimum = 6019,
+ .orientation_maximum = 6020,
+ .max_finger_cnt = 6021,
+ .max_touch_cnt = 6022,
+ .supports_t5r2 = 1,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
log.SetHardwareProperties(hwprops);
@@ -131,10 +131,6 @@ TEST(ActivityLogTest, SimpleTest) {
TEST(ActivityLogTest, WrapAroundTest) {
ActivityLog log(nullptr);
-#ifndef __ANDROID__
- // Disabling this test with DISABLED_ prefix is not sufficient as just by compiling this
- // section causes the hwasan crash at runtime in some other tests
- // TODO(b/311110623): re-enable this section once we've tracked down the hwasan crash
// overfill the buffer
const size_t fill_size = (ActivityLog::kBufferSize * 3) / 2;
for (size_t i = 0; i < fill_size; i++)
@@ -144,7 +140,6 @@ TEST(ActivityLogTest, WrapAroundTest) {
log.LogCallbackRequest(static_cast<stime_t>(fill_size));
string second_prefix = log.Encode().substr(0, prefix_length);
EXPECT_NE(first_prefix, second_prefix);
-#endif
}
TEST(ActivityLogTest, VersionTest) {
@@ -227,4 +222,273 @@ TEST(ActivityLogTest, EncodePropChangeShortTest) {
ActivityLog::kValuePropChangeTypeShort);
}
+TEST(ActivityLogTest, HardwareStatePreTest) {
+ PropRegistry prop_reg;
+ ActivityLog log(&prop_reg);
+
+ HardwareProperties hwprops = {
+ .left = 6011,
+ .top = 6012,
+ .right = 6013,
+ .bottom = 6014,
+ .res_x = 6015,
+ .res_y = 6016,
+ .screen_x_dpi = 6017,
+ .screen_y_dpi = 6018,
+ .orientation_minimum = 6019,
+ .orientation_maximum = 6020,
+ .max_finger_cnt = 6021,
+ .max_touch_cnt = 6022,
+ .supports_t5r2 = 1,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
+ };
+ log.SetHardwareProperties(hwprops);
+
+ 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);
+
+ ActivityLog::Entry* entry;
+ Json::Value result;
+
+ EXPECT_EQ(0, log.size());
+
+ // Build and log a HardwareStatePre structure
+ log.LogHardwareStatePre("ActivityLogTest_HwStateTest", hs);
+ ASSERT_EQ(1, log.size());
+ entry = log.GetEntry(0);
+ ASSERT_TRUE(std::holds_alternative<ActivityLog::HardwareStatePre>
+ (entry->details));
+
+ // Encode the HardwareStatePre into Json
+ result = log.EncodeCommonInfo();
+ result = result[ActivityLog::kKeyRoot][0];
+
+ // Verify the Json information
+ EXPECT_EQ(result[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyHardwareStatePre));
+ EXPECT_EQ(result[ActivityLog::kKeyMethodName],
+ Json::Value("ActivityLogTest_HwStateTest"));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateButtonsDown],
+ Json::Value(hs.buttons_down));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateTouchCnt],
+ Json::Value(hs.touch_cnt));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateTimestamp],
+ Json::Value(hs.timestamp));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateRelX], Json::Value(hs.rel_x));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateRelY], Json::Value(hs.rel_y));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateRelWheel],
+ Json::Value(hs.rel_wheel));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateRelHWheel],
+ Json::Value(hs.rel_hwheel));
+ log.Clear();
+}
+
+TEST(ActivityLogTest, HardwareStatePostTest) {
+ PropRegistry prop_reg;
+ ActivityLog log(&prop_reg);
+
+ HardwareProperties hwprops = {
+ .left = 6011,
+ .top = 6012,
+ .right = 6013,
+ .bottom = 6014,
+ .res_x = 6015,
+ .res_y = 6016,
+ .screen_x_dpi = 6017,
+ .screen_y_dpi = 6018,
+ .orientation_minimum = 6019,
+ .orientation_maximum = 6020,
+ .max_finger_cnt = 6021,
+ .max_touch_cnt = 6022,
+ .supports_t5r2 = 1,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
+ };
+ log.SetHardwareProperties(hwprops);
+
+ 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);
+
+ ActivityLog::Entry* entry;
+ Json::Value result;
+
+ EXPECT_EQ(0, log.size());
+
+ // Build and log a HardwareStatePost structure
+ log.LogHardwareStatePost("ActivityLogTest_HwStateTest", hs);
+ ASSERT_EQ(1, log.size());
+ entry = log.GetEntry(0);
+ ASSERT_TRUE(std::holds_alternative<ActivityLog::HardwareStatePost>
+ (entry->details));
+
+ // Encode the HardwareStatePost into Json
+ result = log.EncodeCommonInfo();
+ result = result[ActivityLog::kKeyRoot][0];
+
+ // Verify the Json information
+ EXPECT_EQ(result[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyHardwareStatePost));
+ EXPECT_EQ(result[ActivityLog::kKeyMethodName],
+ Json::Value("ActivityLogTest_HwStateTest"));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateButtonsDown],
+ Json::Value(hs.buttons_down));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateTouchCnt],
+ Json::Value(hs.touch_cnt));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateTimestamp],
+ Json::Value(hs.timestamp));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateRelX], Json::Value(hs.rel_x));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateRelY], Json::Value(hs.rel_y));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateRelWheel],
+ Json::Value(hs.rel_wheel));
+ EXPECT_EQ(result[ActivityLog::kKeyHardwareStateRelHWheel],
+ Json::Value(hs.rel_hwheel));
+ log.Clear();
+}
+
+
+TEST(ActivityLogTest, GestureConsumeTest) {
+ PropRegistry prop_reg;
+ ActivityLog log(&prop_reg);
+ ActivityLog::Entry* entry;
+ Json::Value result;
+
+ EXPECT_EQ(0, log.size());
+
+ // Build and log a GestureConsume structure
+ Gesture move(kGestureMove, 1.0, 2.0, 773, 4.0);
+ log.LogGestureConsume("ActivityLogTest_GestureTest", move);
+ ASSERT_EQ(1, log.size());
+ entry = log.GetEntry(0);
+ ASSERT_TRUE(std::holds_alternative<ActivityLog::GestureConsume>
+ (entry->details));
+
+ // Encode the GestureConsume into Json
+ result = log.EncodeCommonInfo();
+ result = result[ActivityLog::kKeyRoot][0];
+
+ // Verify the Json information
+ EXPECT_EQ(result[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGestureConsume));
+ EXPECT_EQ(result[ActivityLog::kKeyMethodName],
+ Json::Value("ActivityLogTest_GestureTest"));
+ EXPECT_EQ(result[ActivityLog::kKeyGestureType],
+ Json::Value(ActivityLog::kValueGestureTypeMove));
+ EXPECT_EQ(result[ActivityLog::kKeyGestureDX],
+ Json::Value(move.details.move.dx));
+ EXPECT_EQ(result[ActivityLog::kKeyGestureDY],
+ Json::Value(move.details.move.dy));
+ EXPECT_EQ(result[ActivityLog::kKeyGestureOrdinalDX],
+ Json::Value(move.details.move.ordinal_dx));
+ EXPECT_EQ(result[ActivityLog::kKeyGestureOrdinalDY],
+ Json::Value(move.details.move.ordinal_dy));
+ log.Clear();
+}
+
+TEST(ActivityLogTest, GestureProduceTest) {
+ PropRegistry prop_reg;
+ ActivityLog log(&prop_reg);
+ ActivityLog::Entry* entry;
+ Json::Value result;
+
+ EXPECT_EQ(0, log.size());
+
+ // Build and log a GestureProduce structure
+ Gesture scroll(kGestureScroll, 1.0, 2.0, 312, 4.0);
+ log.LogGestureProduce("ActivityLogTest_GestureTest", scroll);
+ ASSERT_EQ(1, log.size());
+ entry = log.GetEntry(0);
+ ASSERT_TRUE(std::holds_alternative<ActivityLog::GestureProduce>
+ (entry->details));
+
+ // Encode the GestureProduce into Json
+ result = log.EncodeCommonInfo();
+ result = result[ActivityLog::kKeyRoot][0];
+
+ // Verify the Json information
+ EXPECT_EQ(result[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGestureProduce));
+ EXPECT_EQ(result[ActivityLog::kKeyMethodName],
+ Json::Value("ActivityLogTest_GestureTest"));
+ EXPECT_EQ(result[ActivityLog::kKeyGestureType],
+ Json::Value(ActivityLog::kValueGestureTypeScroll));
+ EXPECT_EQ(result[ActivityLog::kKeyGestureDX],
+ Json::Value(scroll.details.scroll.dx));
+ EXPECT_EQ(result[ActivityLog::kKeyGestureDY],
+ Json::Value(scroll.details.scroll.dy));
+ EXPECT_EQ(result[ActivityLog::kKeyGestureOrdinalDX],
+ Json::Value(scroll.details.scroll.ordinal_dx));
+ EXPECT_EQ(result[ActivityLog::kKeyGestureOrdinalDY],
+ Json::Value(scroll.details.scroll.ordinal_dy));
+ log.Clear();
+}
+
+TEST(ActivityLogTest, HandleTimerPreTest) {
+ PropRegistry prop_reg;
+ ActivityLog log(&prop_reg);
+ ActivityLog::Entry* entry;
+ Json::Value result;
+ stime_t timeout = 1;
+
+ EXPECT_EQ(0, log.size());
+
+ // Build and log a HandleTimerPre structure
+ log.LogHandleTimerPre("ActivityLogTest_HandleTimerTest", 0, &timeout);
+ EXPECT_EQ(1, log.size());
+ entry = log.GetEntry(0);
+ EXPECT_TRUE(std::holds_alternative<ActivityLog::HandleTimerPre>
+ (entry->details));
+
+ // Encode the HandleTimerPre into Json
+ result = log.EncodeCommonInfo();
+ result = result[ActivityLog::kKeyRoot][0];
+
+ // Verify the Json information
+ EXPECT_EQ(result[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyHandleTimerPre));
+ EXPECT_EQ(result[ActivityLog::kKeyMethodName],
+ Json::Value("ActivityLogTest_HandleTimerTest"));
+ EXPECT_EQ(result[ActivityLog::kKeyTimerNow],
+ Json::Value(static_cast<stime_t>(0)));
+ EXPECT_EQ(result[ActivityLog::kKeyHandleTimerTimeout], Json::Value(timeout));
+ log.Clear();
+}
+
+TEST(ActivityLogTest, HandleTimerPostTest) {
+ PropRegistry prop_reg;
+ ActivityLog log(&prop_reg);
+ ActivityLog::Entry* entry;
+ Json::Value result;
+ stime_t timeout = 1;
+
+ EXPECT_EQ(0, log.size());
+
+ // Build and log a HandleTimerPost structure
+ log.LogHandleTimerPost("ActivityLogTest_HandleTimerTest", 0, &timeout);
+ EXPECT_EQ(1, log.size());
+ entry = log.GetEntry(0);
+ EXPECT_TRUE(std::holds_alternative<ActivityLog::HandleTimerPost>
+ (entry->details));
+
+ // Encode the HandleTimerPost into Json
+ result = log.EncodeCommonInfo();
+ result = result[ActivityLog::kKeyRoot][0];
+
+ // Verify the Json information
+ EXPECT_EQ(result[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyHandleTimerPost));
+ EXPECT_EQ(result[ActivityLog::kKeyMethodName],
+ Json::Value("ActivityLogTest_HandleTimerTest"));
+ EXPECT_EQ(result[ActivityLog::kKeyTimerNow],
+ Json::Value(static_cast<stime_t>(0)));
+ EXPECT_EQ(result[ActivityLog::kKeyHandleTimerTimeout], Json::Value(timeout));
+ log.Clear();
+}
+
} // namespace gestures
diff --git a/src/activity_replay.cc b/src/activity_replay.cc
index 47039cb..e020be9 100644
--- a/src/activity_replay.cc
+++ b/src/activity_replay.cc
@@ -25,7 +25,9 @@ namespace {
// Helper to std::visit with lambdas.
template <typename... V>
-struct Visitor : V... {};
+struct Visitor : V... {
+ using V::operator()...;
+};
// Explicit deduction guide (not needed as of C++20).
template <typename... V>
Visitor(V...) -> Visitor<V...>;
@@ -334,11 +336,11 @@ bool ActivityReplay::ParseFingerState(const Json::Value& entry,
}
bool ActivityReplay::ParseTimerCallback(const Json::Value& entry) {
- if (!entry.isMember(ActivityLog::kKeyTimerCallbackNow)) {
+ if (!entry.isMember(ActivityLog::kKeyTimerNow)) {
Err("can't parse timercallback");
return false;
}
- log_.LogTimerCallback(entry[ActivityLog::kKeyTimerCallbackNow].asDouble());
+ log_.LogTimerCallback(entry[ActivityLog::kKeyTimerNow].asDouble());
return true;
}
@@ -407,86 +409,86 @@ bool ActivityReplay::ParseGesture(const Json::Value& entry) {
bool ActivityReplay::ParseGestureMove(const Json::Value& entry,
Gesture* out_gs) {
out_gs->type = kGestureTypeMove;
- if (!entry.isMember(ActivityLog::kKeyGestureMoveDX)) {
+ if (!entry.isMember(ActivityLog::kKeyGestureDX)) {
Err("can't parse move dx");
return false;
}
- out_gs->details.move.dx = entry[ActivityLog::kKeyGestureMoveDX].asDouble();
- if (!entry.isMember(ActivityLog::kKeyGestureMoveDY)) {
+ out_gs->details.move.dx = entry[ActivityLog::kKeyGestureDX].asDouble();
+ if (!entry.isMember(ActivityLog::kKeyGestureDY)) {
Err("can't parse move dy");
return false;
}
- out_gs->details.move.dy = entry[ActivityLog::kKeyGestureMoveDY].asDouble();
- if (!entry.isMember(ActivityLog::kKeyGestureMoveOrdinalDX)) {
+ out_gs->details.move.dy = entry[ActivityLog::kKeyGestureDY].asDouble();
+ if (!entry.isMember(ActivityLog::kKeyGestureOrdinalDX)) {
Err("can't parse move ordinal_dx");
return false;
}
out_gs->details.move.ordinal_dx =
- entry[ActivityLog::kKeyGestureMoveOrdinalDX].asDouble();
- if (!entry.isMember(ActivityLog::kKeyGestureMoveOrdinalDY)) {
+ entry[ActivityLog::kKeyGestureOrdinalDX].asDouble();
+ if (!entry.isMember(ActivityLog::kKeyGestureOrdinalDY)) {
Err("can't parse move ordinal_dy");
return false;
}
out_gs->details.move.ordinal_dy =
- entry[ActivityLog::kKeyGestureMoveOrdinalDY].asDouble();
+ entry[ActivityLog::kKeyGestureOrdinalDY].asDouble();
return true;
}
bool ActivityReplay::ParseGestureScroll(const Json::Value& entry,
Gesture* out_gs) {
out_gs->type = kGestureTypeScroll;
- if (!entry.isMember(ActivityLog::kKeyGestureScrollDX)) {
+ if (!entry.isMember(ActivityLog::kKeyGestureDX)) {
Err("can't parse scroll dx");
return false;
}
out_gs->details.scroll.dx =
- entry[ActivityLog::kKeyGestureScrollDX].asDouble();
- if (!entry.isMember(ActivityLog::kKeyGestureScrollDY)) {
+ entry[ActivityLog::kKeyGestureDX].asDouble();
+ if (!entry.isMember(ActivityLog::kKeyGestureDY)) {
Err("can't parse scroll dy");
return false;
}
out_gs->details.scroll.dy =
- entry[ActivityLog::kKeyGestureScrollDY].asDouble();
- if (!entry.isMember(ActivityLog::kKeyGestureScrollOrdinalDX)) {
+ entry[ActivityLog::kKeyGestureDY].asDouble();
+ if (!entry.isMember(ActivityLog::kKeyGestureOrdinalDX)) {
Err("can't parse scroll ordinal_dx");
return false;
}
out_gs->details.scroll.ordinal_dx =
- entry[ActivityLog::kKeyGestureScrollOrdinalDX].asDouble();
- if (!entry.isMember(ActivityLog::kKeyGestureScrollOrdinalDY)) {
+ entry[ActivityLog::kKeyGestureOrdinalDX].asDouble();
+ if (!entry.isMember(ActivityLog::kKeyGestureOrdinalDY)) {
Err("can't parse scroll ordinal_dy");
return false;
}
out_gs->details.scroll.ordinal_dy =
- entry[ActivityLog::kKeyGestureScrollOrdinalDY].asDouble();
+ entry[ActivityLog::kKeyGestureOrdinalDY].asDouble();
return true;
}
bool ActivityReplay::ParseGestureSwipe(const Json::Value& entry,
Gesture* out_gs) {
out_gs->type = kGestureTypeSwipe;
- if (!entry.isMember(ActivityLog::kKeyGestureSwipeDX)) {
+ if (!entry.isMember(ActivityLog::kKeyGestureDX)) {
Err("can't parse swipe dx");
return false;
}
- out_gs->details.swipe.dx = entry[ActivityLog::kKeyGestureSwipeDX].asDouble();
- if (!entry.isMember(ActivityLog::kKeyGestureSwipeDY)) {
+ out_gs->details.swipe.dx = entry[ActivityLog::kKeyGestureDX].asDouble();
+ if (!entry.isMember(ActivityLog::kKeyGestureDY)) {
Err("can't parse swipe dy");
return false;
}
- out_gs->details.swipe.dy = entry[ActivityLog::kKeyGestureSwipeDY].asDouble();
- if (!entry.isMember(ActivityLog::kKeyGestureSwipeOrdinalDX)) {
+ out_gs->details.swipe.dy = entry[ActivityLog::kKeyGestureDY].asDouble();
+ if (!entry.isMember(ActivityLog::kKeyGestureOrdinalDX)) {
Err("can't parse swipe ordinal_dx");
return false;
}
out_gs->details.swipe.ordinal_dx =
- entry[ActivityLog::kKeyGestureSwipeOrdinalDX].asDouble();
- if (!entry.isMember(ActivityLog::kKeyGestureSwipeOrdinalDY)) {
+ entry[ActivityLog::kKeyGestureOrdinalDX].asDouble();
+ if (!entry.isMember(ActivityLog::kKeyGestureOrdinalDY)) {
Err("can't parse swipe ordinal_dy");
return false;
}
out_gs->details.swipe.ordinal_dy =
- entry[ActivityLog::kKeyGestureSwipeOrdinalDY].asDouble();
+ entry[ActivityLog::kKeyGestureOrdinalDY].asDouble();
return true;
}
@@ -736,12 +738,12 @@ bool ActivityReplay::ReplayPropChange(
for (::set<Property*>::iterator it = props.begin(), e = props.end(); it != e;
++it) {
prop = *it;
- if (strcmp(prop->name(), entry.name) == 0)
+ if (strcmp(prop->name(), entry.name.c_str()) == 0)
break;
prop = nullptr;
}
if (!prop) {
- Err("Unable to find prop %s to set.", entry.name);
+ Err("Unable to find prop %s to set.", entry.name.c_str());
return false;
}
bool valid_property = true;
diff --git a/src/box_filter_interpreter.cc b/src/box_filter_interpreter.cc
index 3745e7a..b798b0c 100644
--- a/src/box_filter_interpreter.cc
+++ b/src/box_filter_interpreter.cc
@@ -21,7 +21,11 @@ BoxFilterInterpreter::BoxFilterInterpreter(PropRegistry* prop_reg,
void BoxFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "BoxFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
if (box_width_.val_ == 0.0 && box_height_.val_ == 0.0) {
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
return;
}
@@ -63,6 +67,7 @@ void BoxFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
for (size_t i = 0; i < hwstate.finger_cnt; i++)
previous_output_[hwstate.fingers[i].tracking_id] = hwstate.fingers[i];
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
}
diff --git a/src/box_filter_interpreter_unittest.cc b/src/box_filter_interpreter_unittest.cc
index 01b81c7..b2f37d7 100644
--- a/src/box_filter_interpreter_unittest.cc
+++ b/src/box_filter_interpreter_unittest.cc
@@ -19,6 +19,18 @@ using std::make_pair;
using std::pair;
using std::vector;
+static const HardwareProperties hwprops = {
+ .right = 100, .bottom = 100,
+ .res_x = 1, .res_y = 1,
+ .screen_x_dpi = 0, .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 1,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
+};
+
namespace gestures {
class BoxFilterInterpreterTest : public ::testing::Test {};
@@ -51,21 +63,8 @@ TEST(BoxFilterInterpreterTest, SimpleTest) {
BoxFilterInterpreterTestInterpreter* base_interpreter =
new BoxFilterInterpreterTestInterpreter;
BoxFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
-
interpreter.box_width_.val_ = 1.0;
interpreter.box_height_.val_ = 1.0;
-
- HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, 1, // x res (pixels/mm), y res (pixels/mm)
- 1, 1, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 5, 5, // max fingers, max_touch,
- 0, 0, 1, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
- };
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
EXPECT_FALSE(base_interpreter->handle_timer_called_);
@@ -97,4 +96,41 @@ TEST(BoxFilterInterpreterTest, SimpleTest) {
}
}
+TEST(BoxFilterInterpreterTest, ZeroSizeBoxTest) {
+ BoxFilterInterpreterTestInterpreter* base_interpreter =
+ new BoxFilterInterpreterTestInterpreter;
+ BoxFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
+ interpreter.box_width_.val_ = 0.0;
+ interpreter.box_height_.val_ = 0.0;
+ TestInterpreterWrapper wrapper(&interpreter, &hwprops);
+
+ EXPECT_FALSE(base_interpreter->handle_timer_called_);
+ wrapper.HandleTimer(0.0, nullptr);
+ EXPECT_TRUE(base_interpreter->handle_timer_called_);
+
+ FingerState fs = { 0, 0, 0, 0, 1, 0, 3.0, 0.0, 1, 0 };
+ HardwareState hs = make_hwstate(0.0, 0, 1, 1, &fs);
+
+ InputAndExpectedOutput data[] = {
+ { 3.0, 3.0 },
+ { 4.0, 4.0 },
+ { 3.0, 3.0 },
+ { 4.0, 4.0 },
+ { 5.0, 5.0 },
+ { 6.0, 6.0 },
+ { 5.0, 5.0 },
+ { 4.0, 4.0 },
+ };
+
+ stime_t now = 0.0;
+ const stime_t kTimeDelta = 0.01;
+ for (size_t i = 0; i < arraysize(data); i++) {
+ now += kTimeDelta;
+ hs.timestamp = now;
+ fs.position_y = data[i].in;
+ wrapper.SyncInterpret(hs, nullptr);
+ EXPECT_FLOAT_EQ(data[i].out, fs.position_y) << "i=" << i;
+ }
+}
+
} // namespace gestures
diff --git a/src/click_wiggle_filter_interpreter.cc b/src/click_wiggle_filter_interpreter.cc
index 636a27e..e4f9b10 100644
--- a/src/click_wiggle_filter_interpreter.cc
+++ b/src/click_wiggle_filter_interpreter.cc
@@ -31,6 +31,9 @@ ClickWiggleFilterInterpreter::ClickWiggleFilterInterpreter(
void ClickWiggleFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "ClickWiggleFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
UpdateClickWiggle(hwstate);
SetWarpFlags(hwstate);
@@ -42,6 +45,7 @@ void ClickWiggleFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
prev_pressure_[fs.tracking_id] = fs.pressure;
}
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
}
diff --git a/src/click_wiggle_filter_interpreter_unittest.cc b/src/click_wiggle_filter_interpreter_unittest.cc
index b8f7b06..a7168d9 100644
--- a/src/click_wiggle_filter_interpreter_unittest.cc
+++ b/src/click_wiggle_filter_interpreter_unittest.cc
@@ -55,24 +55,22 @@ TEST(ClickWiggleFilterInterpreterTest, WiggleSuppressTest) {
new ClickWiggleFilterInterpreterTestInterpreter;
ClickWiggleFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 92, // right edge
- 61, // bottom edge
- 1, // x pixels/TP width
- 1, // y pixels/TP height
- 26, // x screen DPI
- 26, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 0, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 92,
+ .bottom = 61,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 0,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
@@ -131,24 +129,22 @@ TEST(ClickWiggleFilterInterpreterTest, OneFingerClickSuppressTest) {
new ClickWiggleFilterInterpreterTestInterpreter;
ClickWiggleFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 92, // right edge
- 61, // bottom edge
- 1, // x pixels/TP width
- 1, // y pixels/TP height
- 26, // x screen DPI
- 26, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 0, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 92,
+ .bottom = 61,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 0,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
@@ -202,24 +198,22 @@ TEST(ClickWiggleFilterInterpreter, ThumbClickTest) {
new ClickWiggleFilterInterpreterTestInterpreter;
ClickWiggleFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 92, // right edge
- 61, // bottom edge
- 1, // x pixels/TP width
- 1, // y pixels/TP height
- 26, // x screen DPI
- 26, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 0, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 92,
+ .bottom = 61,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 0,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
@@ -258,24 +252,22 @@ TEST(ClickWiggleFilterInterpreter, TimeBackwardsTest) {
new ClickWiggleFilterInterpreterTestInterpreter;
ClickWiggleFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 92, // right edge
- 61, // bottom edge
- 1, // x pixels/TP width
- 1, // y pixels/TP height
- 26, // x screen DPI
- 26, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 0, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 92,
+ .bottom = 61,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 0,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
@@ -326,24 +318,22 @@ TEST(ClickWiggleFilterInterpreter, ThumbClickWiggleWithPalmTest) {
new ClickWiggleFilterInterpreterTestInterpreter;
ClickWiggleFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
HardwareProperties hwprops = {
- 0.000000, // left edge
- 0.000000, // top edge
- 106.666672, // right edge
- 68.000000, // bottom edge
- 1.000000, // x pixels/TP width
- 1.000000, // y pixels/TP height
- 25.400000, // x screen DPI
- 25.400000, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 15, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 106.666672,
+ .bottom = 68.000000,
+ .res_x = 1.000000,
+ .res_y = 1.000000,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 15,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
diff --git a/src/finger_merge_filter_interpreter.cc b/src/finger_merge_filter_interpreter.cc
index 1597e00..c75ac14 100644
--- a/src/finger_merge_filter_interpreter.cc
+++ b/src/finger_merge_filter_interpreter.cc
@@ -45,8 +45,13 @@ FingerMergeFilterInterpreter::FingerMergeFilterInterpreter(
void FingerMergeFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "FingerMergeFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
if (finger_merge_filter_enable_.val_)
UpdateFingerMergeState(hwstate);
+
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
}
diff --git a/src/finger_merge_filter_interpreter_unittest.cc b/src/finger_merge_filter_interpreter_unittest.cc
index 0c85915..fc804d4 100644
--- a/src/finger_merge_filter_interpreter_unittest.cc
+++ b/src/finger_merge_filter_interpreter_unittest.cc
@@ -52,15 +52,15 @@ TEST(FingerMergeFilterInterpreterTest, SimpleTest) {
interpreter.finger_merge_filter_enable_.val_ = true;
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, 1, // x res (pixels/mm), y res (pixels/mm)
- 1, 1, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 5, 5, // max fingers, max_touch,
- 0, 0, 1, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 1, .res_y = 1,
+ .screen_x_dpi = 0, .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 1,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
diff --git a/src/finger_metrics.cc b/src/finger_metrics.cc
index 4f62942..a79ea10 100644
--- a/src/finger_metrics.cc
+++ b/src/finger_metrics.cc
@@ -34,6 +34,10 @@ FingerMetrics::FingerMetrics()
FingerMetrics::FingerMetrics(short tracking_id)
: tracking_id_(tracking_id) {}
+FingerMetrics::FingerMetrics(short tracking_id, stime_t timestamp)
+ : tracking_id_(tracking_id),
+ origin_time_(timestamp) {}
+
FingerMetrics::FingerMetrics(const FingerState& state,
stime_t timestamp)
: tracking_id_(state.tracking_id),
@@ -132,4 +136,13 @@ void Metrics::Clear() {
fingers_.clear();
}
+void Metrics::SetFingerOriginTimestampForTesting(short tracking_id,
+ stime_t time) {
+ if (auto iter = fingers_.find(FingerMetrics(tracking_id));
+ iter != fingers_.end()) {
+ fingers_.erase(iter);
+ }
+ fingers_.push_back(FingerMetrics(tracking_id, time));
+}
+
} // namespace gestures
diff --git a/src/fling_stop_filter_interpreter.cc b/src/fling_stop_filter_interpreter.cc
index 2ce44f6..5cf3c78 100644
--- a/src/fling_stop_filter_interpreter.cc
+++ b/src/fling_stop_filter_interpreter.cc
@@ -25,6 +25,9 @@ FlingStopFilterInterpreter::FlingStopFilterInterpreter(
void FlingStopFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "FlingStopFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
fingers_of_last_hwstate_.clear();
for (int i = 0; i < hwstate.finger_cnt; i++)
fingers_of_last_hwstate_.insert(hwstate.fingers[i].tracking_id);
@@ -37,15 +40,19 @@ void FlingStopFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
}
if (hwstate.timestamp > fling_stop_deadline_) {
// sub in a fling before processing other interpreters
- ProduceGesture(Gesture(kGestureFling, prev_timestamp_,
- hwstate.timestamp, 0.0, 0.0,
- GESTURES_FLING_TAP_DOWN));
+ auto fling_tap_down = Gesture(kGestureFling, prev_timestamp_,
+ hwstate.timestamp, 0.0, 0.0,
+ GESTURES_FLING_TAP_DOWN);
+ LogGestureProduce(name, fling_tap_down);
+ ProduceGesture(fling_tap_down);
+
fling_stop_already_sent_ = true;
fling_stop_deadline_ = NO_DEADLINE;
}
}
stime_t next_timeout = NO_DEADLINE;
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, &next_timeout);
*timeout = SetNextDeadlineAndReturnTimeoutVal(hwstate.timestamp,
@@ -62,7 +69,6 @@ bool FlingStopFilterInterpreter::NeedsExtraTime(
num_new_fingers++;
}
}
-
return (num_new_fingers >= 2);
}
@@ -80,6 +86,9 @@ bool FlingStopFilterInterpreter::FlingStopNeeded(const Gesture& gesture) const {
}
void FlingStopFilterInterpreter::ConsumeGesture(const Gesture& gesture) {
+ const char name[] = "FlingStopFilterInterpreter::ConsumeGesture";
+ LogGestureConsume(name, gesture);
+
if (gesture.type == kGestureTypeFling) {
fingers_present_for_last_fling_ = fingers_of_last_hwstate_;
already_extended_ = false;
@@ -87,11 +96,15 @@ void FlingStopFilterInterpreter::ConsumeGesture(const Gesture& gesture) {
if (FlingStopNeeded(gesture)) {
// sub in a fling before a new gesture
- ProduceGesture(Gesture(kGestureFling, gesture.start_time,
- gesture.start_time, 0.0, 0.0,
- GESTURES_FLING_TAP_DOWN));
+ auto fling_tap_down = Gesture(kGestureFling, gesture.start_time,
+ gesture.start_time, 0.0, 0.0,
+ GESTURES_FLING_TAP_DOWN);
+ LogGestureProduce(name, fling_tap_down);
+ ProduceGesture(fling_tap_down);
}
+ LogGestureProduce(name, gesture);
ProduceGesture(gesture);
+
fling_stop_deadline_ = NO_DEADLINE;
prev_gesture_type_ = gesture.type;
fling_stop_already_sent_ = false;
@@ -117,6 +130,9 @@ void FlingStopFilterInterpreter::UpdateFlingStopDeadline(
void FlingStopFilterInterpreter::HandleTimerImpl(stime_t now,
stime_t* timeout) {
+ const char name[] = "FlingStopFilterInterpreter::HandleTimerImpl";
+ LogHandleTimerPre(name, now, timeout);
+
stime_t next_timeout;
if (ShouldCallNextTimer(fling_stop_deadline_)) {
if (next_timer_deadline_ > now) {
@@ -133,9 +149,12 @@ void FlingStopFilterInterpreter::HandleTimerImpl(stime_t now,
return;
}
fling_stop_deadline_ = NO_DEADLINE;
- ProduceGesture(Gesture(kGestureFling, prev_timestamp_,
- now, 0.0, 0.0,
- GESTURES_FLING_TAP_DOWN));
+ auto fling_tap_down = Gesture(kGestureFling, prev_timestamp_,
+ now, 0.0, 0.0,
+ GESTURES_FLING_TAP_DOWN);
+ LogGestureProduce(name, fling_tap_down);
+ ProduceGesture(fling_tap_down);
+
fling_stop_already_sent_ = true;
next_timeout = next_timer_deadline_ == NO_DEADLINE ||
next_timer_deadline_ <= now
@@ -144,6 +163,7 @@ void FlingStopFilterInterpreter::HandleTimerImpl(stime_t now,
}
*timeout = SetNextDeadlineAndReturnTimeoutVal(now, fling_stop_deadline_,
next_timeout);
+ LogHandleTimerPost(name, now, timeout);
}
} // namespace gestures
diff --git a/src/fling_stop_filter_interpreter_unittest.cc b/src/fling_stop_filter_interpreter_unittest.cc
index 6410d2f..8637cf9 100644
--- a/src/fling_stop_filter_interpreter_unittest.cc
+++ b/src/fling_stop_filter_interpreter_unittest.cc
@@ -142,4 +142,48 @@ TEST(FlingStopFilterInterpreterTest, SimpleTest) {
}
}
+TEST(FlingStopFilterInterpreterTest, FlingGestureTest) {
+ FlingStopFilterInterpreterTestInterpreter* base_interpreter =
+ new FlingStopFilterInterpreterTestInterpreter;
+ FlingStopFilterInterpreter interpreter(nullptr, base_interpreter, nullptr,
+ GESTURES_DEVCLASS_TOUCHPAD);
+
+ Gesture fling(kGestureFling, 0.0, 1.0, 0.0, 0.0, GESTURES_FLING_TAP_DOWN);
+ Gesture swipelift(kGestureSwipeLift, 1.0, 2.0);
+ Gesture swipe4flift(kGestureFourFingerSwipeLift, 1.0, 2.0);
+ Gesture move(kGestureMove, 1.0, 2.0, 3.0, 4.0);
+
+ interpreter.fling_stop_already_sent_ = true;
+ interpreter.ConsumeGesture(fling);
+ interpreter.ConsumeGesture(fling);
+ EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeFling);
+ interpreter.ConsumeGesture(swipelift);
+ EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeSwipeLift);
+ interpreter.ConsumeGesture(swipe4flift);
+ EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeFourFingerSwipeLift);
+
+ interpreter.fling_stop_already_sent_ = false;
+ interpreter.ConsumeGesture(fling);
+ interpreter.ConsumeGesture(fling);
+ EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeFling);
+ interpreter.ConsumeGesture(swipelift);
+ EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeSwipeLift);
+ interpreter.ConsumeGesture(swipe4flift);
+ EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeFourFingerSwipeLift);
+
+ interpreter.ConsumeGesture(move);
+ EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeMove);
+}
+
+TEST(FlingStopFilterInterpreterTest, FlingStopMultimouseMoveTest) {
+ FlingStopFilterInterpreterTestInterpreter* base_interpreter =
+ new FlingStopFilterInterpreterTestInterpreter;
+ FlingStopFilterInterpreter interpreter(nullptr, base_interpreter, nullptr,
+ GESTURES_DEVCLASS_MULTITOUCH_MOUSE);
+
+ Gesture move(kGestureMove, 1.0, 2.0, 3.0, 4.0);
+ interpreter.ConsumeGesture(move);
+ EXPECT_EQ(interpreter.prev_gesture_type_, kGestureTypeMove);
+}
+
} // namespace gestures
diff --git a/src/gestures.cc b/src/gestures.cc
index f50211c..b4d5271 100644
--- a/src/gestures.cc
+++ b/src/gestures.cc
@@ -203,7 +203,11 @@ void HardwareState::DeepCopy(const HardwareState& that,
buttons_down = that.buttons_down;
touch_cnt = that.touch_cnt;
finger_cnt = min(that.finger_cnt, max_finger_cnt);
- memcpy(fingers, that.fingers, finger_cnt * sizeof(FingerState));
+ if(that.fingers != nullptr) {
+ memcpy(fingers, that.fingers, finger_cnt * sizeof(FingerState));
+ } else if (finger_cnt > 0) {
+ Err("HardwareState with no finger data but %d finger count", finger_cnt);
+ }
rel_x = that.rel_x;
rel_y = that.rel_y;
rel_wheel = that.rel_wheel;
@@ -531,8 +535,9 @@ void GestureInterpreter::set_callback(GestureReadyFunction callback,
void GestureInterpreter::InitializeTouchpad(void) {
if (prop_reg_.get()) {
- IntProperty stack_version(prop_reg_.get(), "Touchpad Stack Version", 2);
- if (stack_version.val_ == 2) {
+ stack_version_ = std::make_unique<IntProperty>(prop_reg_.get(),
+ "Touchpad Stack Version", 2);
+ if (stack_version_->val_ == 2) {
InitializeTouchpad2();
return;
}
diff --git a/src/gestures_unittest.cc b/src/gestures_unittest.cc
index 6a22b2f..6b00902 100644
--- a/src/gestures_unittest.cc
+++ b/src/gestures_unittest.cc
@@ -342,15 +342,12 @@ TEST(GesturesTest, SimpleTest) {
gs_ptr->Initialize(GESTURES_DEVCLASS_POINTING_STICK);
DeleteGestureInterpreter(gs_ptr);
-#ifndef __ANDROID__
- // TODO(b/311110623): re-enable this section once we've tracked down the hwasan crash
gs_ptr = NewGestureInterpreter();
EXPECT_NE(nullptr, gs_ptr);
gs_ptr->Initialize(GESTURES_DEVCLASS_MULTITOUCH_MOUSE);
std::string activity = gs_ptr->EncodeActivityLog();
EXPECT_NE(activity.size(), 0);
DeleteGestureInterpreter(gs_ptr);
-#endif
EXPECT_EQ("1073741824", FingerState::FlagsString(1 << 30));
}
@@ -435,16 +432,17 @@ TEST(GesturesTest, HardwareStateGetFingerStateTest) {
TEST(GesturesTest, HardwarePropertiesToStringTest) {
HardwareProperties hp = {
- 1009.5, 1002.4, 1003.9, 1004.5, // left, top, right, bottom
- 1005.4, 1006.9, // res_x, res_y
- 1007.4, 1008.5, // x, y screen dpi
- -1, // orientation minimum
- 2, // orientation maximum
- 12, // max fingers
- 11, // max touches
- 0, 1, 1, // t5r2, semi-mt, is_button_pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // is_haptic_pad
+ .left = 1009.5, .top = 1002.4, .right = 1003.9, .bottom = 1004.5,
+ .res_x = 1005.4, .res_y = 1006.9,
+ .screen_x_dpi = 1007.4,
+ .screen_y_dpi = 1008.5,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 12,
+ .max_touch_cnt = 11,
+ .supports_t5r2 = 0, .support_semi_mt = 1, .is_button_pad = 1,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
string str = hp.String();
fprintf(stderr, "str: %s\n", str.c_str());
@@ -529,4 +527,48 @@ TEST(GesturesTest, HardwareStateToStringTest) {
return;
}
+TEST(GesturesTest, HardwareStateDeepCopyWithFingersTest) {
+ FingerState fingerStates[] = {
+ { 1.0, 2.0, 3.0, 4.5, 30.0, 11.0, 20.0, 30.0, 14, 0 },
+ { 1.5, 2.5, 3.5, 5.0, 30.5, 11.5, 20.5, 30.5, 15, 0 }
+ };
+ const HardwareState hardwareState = make_hwstate(1.123, 1, 2, 2, fingerStates);
+
+ HardwareState hardwareStateCopy;
+ hardwareStateCopy.fingers = new FingerState[hardwareState.finger_cnt];
+ hardwareStateCopy.DeepCopy(hardwareState, hardwareState.finger_cnt);
+
+ EXPECT_EQ(hardwareStateCopy.String(), hardwareState.String());
+ delete[] hardwareStateCopy.fingers;
+}
+
+TEST(GesturesTest, HardwareStateDeepCopyWithoutFingersTest) {
+ const HardwareState hardwareState = make_hwstate(1.123, 1, 0, 2, nullptr);
+
+ HardwareState hardwareStateCopy;
+ hardwareStateCopy.DeepCopy(hardwareState, hardwareState.finger_cnt);
+
+ EXPECT_EQ(hardwareStateCopy.String(), hardwareState.String());
+}
+
+TEST(GesturesTest, InvalidHardwareStateDeepCopyTest) {
+ // 2 finger_cnt without any fingersState(s) specified
+ const HardwareState invalidHardwareState = make_hwstate(1.123, 1, 2, 2, nullptr);
+
+ HardwareState hardwareStateCopy;
+ hardwareStateCopy.DeepCopy(invalidHardwareState, invalidHardwareState.finger_cnt);
+
+ EXPECT_EQ(invalidHardwareState.timestamp, hardwareStateCopy.timestamp);
+ EXPECT_EQ(invalidHardwareState.buttons_down, hardwareStateCopy.buttons_down);
+ EXPECT_EQ(invalidHardwareState.finger_cnt, hardwareStateCopy.finger_cnt);
+ EXPECT_EQ(invalidHardwareState.touch_cnt, hardwareStateCopy.touch_cnt);
+ EXPECT_EQ(invalidHardwareState.fingers, hardwareStateCopy.fingers);
+ EXPECT_EQ(invalidHardwareState.rel_x, hardwareStateCopy.rel_x);
+ EXPECT_EQ(invalidHardwareState.rel_y, hardwareStateCopy.rel_y);
+ EXPECT_EQ(invalidHardwareState.rel_wheel, hardwareStateCopy.rel_wheel);
+ EXPECT_EQ(invalidHardwareState.rel_wheel_hi_res, hardwareStateCopy.rel_wheel_hi_res);
+ EXPECT_EQ(invalidHardwareState.rel_hwheel, hardwareStateCopy.rel_wheel);
+ EXPECT_EQ(invalidHardwareState.msc_timestamp, hardwareStateCopy.msc_timestamp);
+}
+
} // namespace gestures
diff --git a/src/haptic_button_generator_filter_interpreter.cc b/src/haptic_button_generator_filter_interpreter.cc
index 5cdad9f..93f9aa6 100644
--- a/src/haptic_button_generator_filter_interpreter.cc
+++ b/src/haptic_button_generator_filter_interpreter.cc
@@ -57,8 +57,14 @@ void HapticButtonGeneratorFilterInterpreter::Initialize(
void HapticButtonGeneratorFilterInterpreter::SyncInterpretImpl(
HardwareState& hwstate, stime_t* timeout) {
+ const char name[] =
+ "HapticButtonGeneratorFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
HandleHardwareState(hwstate);
stime_t next_timeout = NO_DEADLINE;
+
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, &next_timeout);
UpdatePalmState(hwstate);
*timeout = SetNextDeadlineAndReturnTimeoutVal(
@@ -162,6 +168,9 @@ void HapticButtonGeneratorFilterInterpreter::UpdatePalmState(
void HapticButtonGeneratorFilterInterpreter::HandleTimerImpl(
stime_t now, stime_t *timeout) {
+ const char name[] = "HapticButtonGeneratorFilterInterpreter::HandleTimerImpl";
+ LogHandleTimerPre(name, now, timeout);
+
stime_t next_timeout;
if (ShouldCallNextTimer(active_gesture_deadline_)) {
next_timeout = NO_DEADLINE;
@@ -185,11 +194,16 @@ void HapticButtonGeneratorFilterInterpreter::HandleTimerImpl(
*timeout = SetNextDeadlineAndReturnTimeoutVal(now,
active_gesture_deadline_,
next_timeout);
+ LogHandleTimerPost(name, now, timeout);
}
void HapticButtonGeneratorFilterInterpreter::ConsumeGesture(
const Gesture& gesture) {
+ const char name[] = "HapticButtonGeneratorFilterInterpreter::ConsumeGesture";
+ LogGestureConsume(name, gesture);
+
if (!enabled_.val_ || !is_haptic_pad_) {
+ LogGestureProduce(name, gesture);
ProduceGesture(gesture);
return;
}
@@ -237,6 +251,7 @@ void HapticButtonGeneratorFilterInterpreter::ConsumeGesture(
release_suppress_factor_ = fmax(release_suppress_factor_, 0.1);
}
+ LogGestureProduce(name, gesture);
ProduceGesture(gesture);
}
diff --git a/src/haptic_button_generator_filter_interpreter_unittest.cc b/src/haptic_button_generator_filter_interpreter_unittest.cc
index 97d3219..8fef528 100644
--- a/src/haptic_button_generator_filter_interpreter_unittest.cc
+++ b/src/haptic_button_generator_filter_interpreter_unittest.cc
@@ -46,16 +46,17 @@ TEST(HapticButtonGeneratorFilterInterpreterTest, SimpleTest) {
HapticButtonGeneratorFilterInterpreter interpreter(
nullptr, base_interpreter, nullptr);
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 10, // x res (pixels/mm)
- 10, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -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
- 1, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 10,
+ .res_y = 10,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 1,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
@@ -134,16 +135,17 @@ TEST(HapticButtonGeneratorFilterInterpreterTest, NotHapticTest) {
HapticButtonGeneratorFilterInterpreter interpreter(
nullptr, base_interpreter, nullptr);
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 10, // x res (pixels/mm)
- 10, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -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
+ .right = 100, .bottom = 100,
+ .res_x = 10,
+ .res_y = 10,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
@@ -183,6 +185,60 @@ TEST(HapticButtonGeneratorFilterInterpreterTest, NotHapticTest) {
}
}
+TEST(HapticButtonGeneratorFilterInterpreterTest, NotHapticConsumeGestureTest) {
+ HapticButtonGeneratorFilterInterpreter interpreter(
+ nullptr, nullptr, nullptr);
+ interpreter.is_haptic_pad_ = false;
+ interpreter.active_gesture_deadline_ = 0.0;
+ interpreter.release_suppress_factor_ = 0.0;
+
+ const Gesture kFling(kGestureFling, 0, 0, 20, 0, GESTURES_FLING_START);
+ const Gesture kMove(kGestureMove, 2, 3, 4.0, 5.0);
+ const Gesture kScroll(kGestureScroll, 0, 0, 20, 0);
+
+ // Verify no state change happens when a Fling is sent to haptics
+ // when this is not a haptics device
+ interpreter.active_gesture_ = false;
+ interpreter.ConsumeGesture(kFling);
+ EXPECT_FALSE(interpreter.active_gesture_);
+ EXPECT_EQ(interpreter.active_gesture_deadline_, 0.0);
+ EXPECT_EQ(interpreter.release_suppress_factor_, 0.0);
+
+ interpreter.active_gesture_ = true;
+ interpreter.ConsumeGesture(kFling);
+ EXPECT_TRUE(interpreter.active_gesture_);
+ EXPECT_EQ(interpreter.active_gesture_deadline_, 0.0);
+ EXPECT_EQ(interpreter.release_suppress_factor_, 0.0);
+
+ // Verify no state change happens when a MOVE is sent to haptics
+ // when this is not a haptics device
+ interpreter.active_gesture_ = false;
+ interpreter.ConsumeGesture(kMove);
+ EXPECT_FALSE(interpreter.active_gesture_);
+ EXPECT_EQ(interpreter.active_gesture_deadline_, 0.0);
+ EXPECT_EQ(interpreter.release_suppress_factor_, 0.0);
+
+ interpreter.active_gesture_ = true;
+ interpreter.ConsumeGesture(kMove);
+ EXPECT_TRUE(interpreter.active_gesture_);
+ EXPECT_EQ(interpreter.active_gesture_deadline_, 0.0);
+ EXPECT_EQ(interpreter.release_suppress_factor_, 0.0);
+
+ // Verify no state change happens when a Scroll is sent to haptics
+ // when this is not a haptics device
+ interpreter.active_gesture_ = false;
+ interpreter.ConsumeGesture(kScroll);
+ EXPECT_FALSE(interpreter.active_gesture_);
+ EXPECT_EQ(interpreter.active_gesture_deadline_, 0.0);
+ EXPECT_EQ(interpreter.release_suppress_factor_, 0.0);
+
+ interpreter.active_gesture_ = true;
+ interpreter.ConsumeGesture(kScroll);
+ EXPECT_TRUE(interpreter.active_gesture_);
+ EXPECT_EQ(interpreter.active_gesture_deadline_, 0.0);
+ EXPECT_EQ(interpreter.release_suppress_factor_, 0.0);
+}
+
TEST(HapticButtonGeneratorFilterInterpreterTest,
GesturePreventsButtonDownTest) {
HapticButtonGeneratorFilterInterpreterTestInterpreter* base_interpreter =
@@ -190,16 +246,17 @@ TEST(HapticButtonGeneratorFilterInterpreterTest,
HapticButtonGeneratorFilterInterpreter interpreter(
nullptr, base_interpreter, nullptr);
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 10, // x res (pixels/mm)
- 10, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -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
- 1, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 10,
+ .res_y = 10,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 1,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
@@ -266,16 +323,17 @@ TEST(HapticButtonGeneratorFilterInterpreterTest, DynamicThresholdTest) {
HapticButtonGeneratorFilterInterpreter interpreter(
nullptr, base_interpreter, nullptr);
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 10, // x res (pixels/mm)
- 10, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -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
- 1, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 10,
+ .res_y = 10,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 1,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
@@ -346,16 +404,17 @@ TEST(HapticButtonGeneratorFilterInterpreterTest, PalmTest) {
HapticButtonGeneratorFilterInterpreter interpreter(
nullptr, base_interpreter, nullptr);
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 10, // x res (pixels/mm)
- 10, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -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
- 1, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 10,
+ .res_y = 10,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 1,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
diff --git a/src/iir_filter_interpreter.cc b/src/iir_filter_interpreter.cc
index 2387650..5ea513d 100644
--- a/src/iir_filter_interpreter.cc
+++ b/src/iir_filter_interpreter.cc
@@ -53,6 +53,9 @@ IirFilterInterpreter::IirFilterInterpreter(PropRegistry* prop_reg,
void IirFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "IirFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
// Delete old entries from map
short dead_ids[histories_.size() + 1];
size_t dead_ids_len = 0;
@@ -152,6 +155,7 @@ void IirFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
fs = *hist->NextOut();
hist->Increment();
}
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
}
diff --git a/src/iir_filter_interpreter_unittest.cc b/src/iir_filter_interpreter_unittest.cc
index c7a3b81..d1c8b8c 100644
--- a/src/iir_filter_interpreter_unittest.cc
+++ b/src/iir_filter_interpreter_unittest.cc
@@ -109,13 +109,15 @@ TEST(IirFilterInterpreterTest, SemiMTIIRTest) {
IirFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
HardwareProperties hwprops = {
- 0, 0, 100, 60, // left, top, right, bottom
- 1.0, 1.0, 25.4, 25.4, // x res, y res, x DPI, y DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, 3, 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
+ .right = 100, .bottom = 60,
+ .res_x = 1.0, .res_y = 1.0,
+ .screen_x_dpi = 0, .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 3,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
diff --git a/src/immediate_interpreter.cc b/src/immediate_interpreter.cc
index 5f134b8..c1aa568 100644
--- a/src/immediate_interpreter.cc
+++ b/src/immediate_interpreter.cc
@@ -342,7 +342,7 @@ void HardwareStateBuffer::Reset(size_t max_finger_cnt) {
void HardwareStateBuffer::PushState(const HardwareState& state) {
newest_index_ = (newest_index_ + size_ - 1) % size_;
- Get(0)->DeepCopy(state, max_finger_cnt_);
+ Get(0).DeepCopy(state, max_finger_cnt_);
}
void HardwareStateBuffer::PopState() {
@@ -385,12 +385,12 @@ bool ScrollManager::StationaryFingerPressureChangingSignificantly(
bool pressure_is_increasing = false;
bool pressure_direction_established = false;
const FingerState* prev = &current;
- stime_t now = state_buffer.Get(0)->timestamp;
+ stime_t now = state_buffer.Get(0).timestamp;
stime_t duration = 0.0;
if (max_pressure_change_duration_.val_ > 0.0) {
for (size_t i = 1; i < state_buffer.Size(); i++) {
- const HardwareState& state = *state_buffer.Get(i);
+ const HardwareState& state = state_buffer.Get(i);
stime_t local_duration = now - state.timestamp;
if (local_duration > max_pressure_change_duration_.val_)
break;
@@ -419,8 +419,8 @@ bool ScrollManager::StationaryFingerPressureChangingSignificantly(
// To disable this feature, max_pressure_change_duration_ can be set to a
// negative number. When this occurs it reverts to just checking the last
// event, not looking through the backlog as well.
- prev = state_buffer.Get(1)->GetFingerState(current.tracking_id);
- duration = now - state_buffer.Get(1)->timestamp;
+ prev = state_buffer.Get(1).GetFingerState(current.tracking_id);
+ duration = now - state_buffer.Get(1).timestamp;
}
if (max_stationary_speed_.val_ != 0.0) {
@@ -459,12 +459,12 @@ bool ScrollManager::FillResultScroll(
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);
+ const FingerState* fs = state_buffer.Get(0).GetFingerState(*it);
+ const FingerState* prev = state_buffer.Get(1).GetFingerState(*it);
if (!prev)
return false;
const stime_t dt =
- state_buffer.Get(0)->timestamp - state_buffer.Get(1)->timestamp;
+ state_buffer.Get(0).timestamp - state_buffer.Get(1).timestamp;
pressure_changing =
pressure_changing ||
StationaryFingerPressureChangingSignificantly(state_buffer, *fs);
@@ -523,8 +523,8 @@ bool ScrollManager::FillResultScroll(
if (max_mag_sq > 0) {
did_generate_scroll_ = true;
*result = Gesture(kGestureScroll,
- state_buffer.Get(1)->timestamp,
- state_buffer.Get(0)->timestamp,
+ state_buffer.Get(1).timestamp,
+ state_buffer.Get(0).timestamp,
dx, dy);
}
if (prev_gesture_type != kGestureTypeScroll || prev_gs_fingers != gs_fingers)
@@ -533,7 +533,7 @@ bool ScrollManager::FillResultScroll(
!FloatEq(dx, 0.0) || !FloatEq(dy, 0.0))
scroll_buffer->Insert(
dx, dy,
- state_buffer.Get(0)->timestamp - state_buffer.Get(1)->timestamp);
+ state_buffer.Get(0).timestamp - state_buffer.Get(1).timestamp);
return true;
}
@@ -703,8 +703,8 @@ done:
float vx = out.dt ? (out.dx / out.dt) : 0.0;
float vy = out.dt ? (out.dy / out.dt) : 0.0;
*result = Gesture(kGestureFling,
- state_buffer.Get(1)->timestamp,
- state_buffer.Get(0)->timestamp,
+ state_buffer.Get(1).timestamp,
+ state_buffer.Get(0).timestamp,
vx,
vy,
GESTURES_FLING_START);
@@ -1000,6 +1000,7 @@ ImmediateInterpreter::ImmediateInterpreter(PropRegistry* prop_reg,
last_movement_timestamp_(-1.0),
swipe_is_vertical_(false),
current_gesture_type_(kGestureTypeNull),
+ prev_gesture_type_(kGestureTypeNull),
state_buffer_(8),
scroll_buffer_(20),
pinch_guess_start_(-1.0),
@@ -1146,7 +1147,10 @@ ImmediateInterpreter::ImmediateInterpreter(PropRegistry* prop_reg,
void ImmediateInterpreter::SyncInterpretImpl(HardwareState& hwstate,
stime_t* timeout) {
- if (!state_buffer_.Get(0)->fingers) {
+ const char name[] = "ImmediateInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
+ if (!state_buffer_.Get(0).fingers) {
Err("Must call SetHardwareProperties() before Push().");
return;
}
@@ -1155,8 +1159,8 @@ void ImmediateInterpreter::SyncInterpretImpl(HardwareState& hwstate,
FillOriginInfo(hwstate);
result_.type = kGestureTypeNull;
- const bool same_fingers = state_buffer_.Get(1)->SameFingersAs(hwstate) &&
- (hwstate.buttons_down == state_buffer_.Get(1)->buttons_down);
+ const bool same_fingers = state_buffer_.Get(1).SameFingersAs(hwstate) &&
+ (hwstate.buttons_down == state_buffer_.Get(1).buttons_down);
if (!same_fingers) {
// Fingers changed, do nothing this time
FingerMap new_gs_fingers;
@@ -1174,13 +1178,13 @@ void ImmediateInterpreter::SyncInterpretImpl(HardwareState& hwstate,
moving_finger_id_ = -1;
}
- if (hwstate.finger_cnt < state_buffer_.Get(1)->finger_cnt &&
+ if (hwstate.finger_cnt < state_buffer_.Get(1).finger_cnt &&
AnyGesturingFingerLeft(hwstate, prev_active_gs_fingers_)) {
finger_leave_time_ = hwstate.timestamp;
}
// Check if clock changed backwards
- if (hwstate.timestamp < state_buffer_.Get(1)->timestamp)
+ if (hwstate.timestamp < state_buffer_.Get(1).timestamp)
ResetTime();
UpdatePointingFingers(hwstate);
@@ -1225,11 +1229,16 @@ void ImmediateInterpreter::SyncInterpretImpl(HardwareState& hwstate,
active_gs_fingers.begin(), active_gs_fingers.end(),
std::inserter(non_gs_fingers_,
non_gs_fingers_.begin()));
+ LogGestureProduce(name, result_);
ProduceGesture(result_);
}
+ LogHardwareStatePost(name, hwstate);
}
void ImmediateInterpreter::HandleTimerImpl(stime_t now, stime_t* timeout) {
+ const char name[] = "ImmediateInterpreter::HandleTimerImpl";
+ LogHandleTimerPre(name, now, timeout);
+
result_.type = kGestureTypeNull;
// Tap-to-click always aborts when real button(s) are being used, so we
// don't need to worry about conflicts with these two types of callback.
@@ -1239,28 +1248,29 @@ void ImmediateInterpreter::HandleTimerImpl(stime_t now, stime_t* timeout) {
false,
now,
timeout);
- if (result_.type != kGestureTypeNull)
+ if (result_.type != kGestureTypeNull) {
+ LogGestureProduce(name, result_);
ProduceGesture(result_);
+ }
+ LogHandleTimerPost(name, now, timeout);
}
void ImmediateInterpreter::FillOriginInfo(
const HardwareState& hwstate) {
- RemoveMissingIdsFromMap(&origin_timestamps_, hwstate);
RemoveMissingIdsFromMap(&distance_walked_, hwstate);
for (size_t i = 0; i < hwstate.finger_cnt; i++) {
const FingerState& fs = hwstate.fingers[i];
- if (MapContainsKey(origin_timestamps_, fs.tracking_id) &&
+ if (distance_walked_.find(fs.tracking_id) != distance_walked_.end() &&
state_buffer_.Size() > 1 &&
- state_buffer_.Get(1)->GetFingerState(fs.tracking_id)) {
+ state_buffer_.Get(1).GetFingerState(fs.tracking_id)) {
float delta_x = hwstate.GetFingerState(fs.tracking_id)->position_x -
- state_buffer_.Get(1)->GetFingerState(fs.tracking_id)->position_x;
+ state_buffer_.Get(1).GetFingerState(fs.tracking_id)->position_x;
float delta_y = hwstate.GetFingerState(fs.tracking_id)->position_y -
- state_buffer_.Get(1)->GetFingerState(fs.tracking_id)->position_y;
+ state_buffer_.Get(1).GetFingerState(fs.tracking_id)->position_y;
distance_walked_[fs.tracking_id] += sqrtf(delta_x * delta_x +
delta_y * delta_y);
continue;
}
- origin_timestamps_[fs.tracking_id] = hwstate.timestamp;
distance_walked_[fs.tracking_id] = 0.0;
}
}
@@ -1338,8 +1348,8 @@ bool ImmediateInterpreter::EarlyZoomPotential(const HardwareState& hwstate)
if (finger1 == nullptr || finger2 == nullptr)
return false;
// Wait for a longer time if fingers arrived together
- stime_t t1 = origin_timestamps_.at(id1);
- stime_t t2 = origin_timestamps_.at(id2);
+ stime_t t1 = metrics_->GetFinger(id1)->origin_time();
+ stime_t t2 = metrics_->GetFinger(id2)->origin_time();
if (fabs(t1 - t2) < evaluation_timeout_.val_ &&
hwstate.timestamp - max(t1, t2) <
thumb_pinch_evaluation_timeout_.val_ * thumb_pinch_delay_factor_.val_)
@@ -1363,10 +1373,10 @@ bool ImmediateInterpreter::EarlyZoomPotential(const HardwareState& hwstate)
bool motionless_cycles = false;
for (int i = 1;
i < min<int>(state_buffer_.Size(), pinch_zoom_min_events_.val_); i++) {
- const FingerState* curr1 = state_buffer_.Get(i - 1)->GetFingerState(id1);
- const FingerState* curr2 = state_buffer_.Get(i - 1)->GetFingerState(id2);
- const FingerState* prev1 = state_buffer_.Get(i)->GetFingerState(id1);
- const FingerState* prev2 = state_buffer_.Get(i)->GetFingerState(id2);
+ const FingerState* curr1 = state_buffer_.Get(i - 1).GetFingerState(id1);
+ const FingerState* curr2 = state_buffer_.Get(i - 1).GetFingerState(id2);
+ const FingerState* prev1 = state_buffer_.Get(i).GetFingerState(id1);
+ const FingerState* prev2 = state_buffer_.Get(i).GetFingerState(id2);
if (!curr1 || !curr2 || !prev1 || !prev2) {
motionless_cycles = true;
break;
@@ -1406,23 +1416,23 @@ bool ImmediateInterpreter::ZoomFingersAreConsistent(
int id2 = *(++fingers_.begin());
const FingerState* curr1 = state_buffer.Get(min<int>(state_buffer.Size() - 1,
- pinch_zoom_min_events_.val_))->GetFingerState(id1);
+ pinch_zoom_min_events_.val_)).GetFingerState(id1);
const FingerState* curr2 = state_buffer.Get(min<int>(state_buffer.Size() - 1,
- pinch_zoom_min_events_.val_))->GetFingerState(id2);
+ pinch_zoom_min_events_.val_)).GetFingerState(id2);
if (!curr1 || !curr2)
return false;
for (int i = 0;
i < min<int>(state_buffer.Size(), pinch_zoom_min_events_.val_); i++) {
- const FingerState* prev1 = state_buffer.Get(i)->GetFingerState(id1);
- const FingerState* prev2 = state_buffer.Get(i)->GetFingerState(id2);
+ const FingerState* prev1 = state_buffer.Get(i).GetFingerState(id1);
+ const FingerState* prev2 = state_buffer.Get(i).GetFingerState(id2);
if (!prev1 || !prev2)
return false;
float dot = FingersAngle(prev1, prev2, curr1, curr2);
if (dot >= 0)
return false;
}
- const FingerState* last1 = state_buffer.Get(0)->GetFingerState(id1);
- const FingerState* last2 = state_buffer.Get(0)->GetFingerState(id2);
+ const FingerState* last1 = state_buffer.Get(0).GetFingerState(id1);
+ const FingerState* last2 = state_buffer.Get(0).GetFingerState(id2);
float angle = FingersAngle(last1, last2, curr1, curr2);
if (angle > pinch_zoom_max_angle_.val_)
return false;
@@ -1438,19 +1448,19 @@ bool ImmediateInterpreter::InwardPinch(
const FingerState* curr =
state_buffer.Get(min<int>(state_buffer.Size(),
- pinch_zoom_min_events_.val_))->GetFingerState(id);
+ pinch_zoom_min_events_.val_)).GetFingerState(id);
if (!curr)
return false;
for (int i = 0;
i < min<int>(state_buffer.Size(), pinch_zoom_min_events_.val_); i++) {
- const FingerState* prev = state_buffer.Get(i)->GetFingerState(id);
+ const FingerState* prev = state_buffer.Get(i).GetFingerState(id);
if (!prev)
return false;
float dot = (curr->position_y - prev->position_y);
if (dot <= 0)
return false;
}
- const FingerState* last = state_buffer.Get(0)->GetFingerState(id);
+ const FingerState* last = state_buffer.Get(0).GetFingerState(id);
float dot_last = (curr->position_y - last->position_y);
float size_last = sqrt((curr->position_x - last->position_x) *
(curr->position_x - last->position_x) +
@@ -1490,15 +1500,15 @@ float ImmediateInterpreter::FingersAngle(const FingerState* prev1,
bool ImmediateInterpreter::ScrollAngle(const FingerState& finger1,
const FingerState& finger2) {
const FingerState* curr1 = state_buffer_.Get(
- min<int>(state_buffer_.Size() - 1, 3))->
- GetFingerState(finger1.tracking_id);
+ min<int>(state_buffer_.Size() - 1, 3))
+ .GetFingerState(finger1.tracking_id);
const FingerState* curr2 = state_buffer_.Get(
- min<int>(state_buffer_.Size() - 1, 3))->
- GetFingerState(finger2.tracking_id);
+ min<int>(state_buffer_.Size() - 1, 3))
+ .GetFingerState(finger2.tracking_id);
const FingerState* last1 =
- state_buffer_.Get(0)->GetFingerState(finger1.tracking_id);
+ state_buffer_.Get(0).GetFingerState(finger1.tracking_id);
const FingerState* last2 =
- state_buffer_.Get(0)->GetFingerState(finger2.tracking_id);
+ state_buffer_.Get(0).GetFingerState(finger2.tracking_id);
if (last1 && last2 && curr1 && curr2) {
if (FingersAngle(last1, last2, curr1, curr2) < scroll_min_angle_.val_)
return false;
@@ -1561,7 +1571,7 @@ void ImmediateInterpreter::UpdateThumbState(const HardwareState& hwstate) {
(min_fs->flags & GESTURES_FINGER_WARP_Y_MOVE));
float min_dist_sq = DistanceTravelledSq(*min_fs, false, true);
float min_dt = hwstate.timestamp -
- origin_timestamps_[min_fs->tracking_id];
+ metrics_->GetFinger(min_fs->tracking_id)->origin_time();
float thumb_dist_sq_thresh = min_dist_sq *
thumb_movement_factor_.val_ * thumb_movement_factor_.val_;
float thumb_speed_sq_thresh = min_dist_sq *
@@ -1572,10 +1582,12 @@ void ImmediateInterpreter::UpdateThumbState(const HardwareState& hwstate) {
if (pinch_enable_.val_ && hwstate.finger_cnt == 2) {
float dt1 = hwstate.timestamp -
- origin_timestamps_[hwstate.fingers[0].tracking_id];
+ metrics_->GetFinger(hwstate.fingers[0].tracking_id)
+ ->origin_time();
float dist_sq1 = DistanceTravelledSq(hwstate.fingers[0], true, true);
float dt2 = hwstate.timestamp -
- origin_timestamps_[hwstate.fingers[1].tracking_id];
+ metrics_->GetFinger(hwstate.fingers[1].tracking_id)
+ ->origin_time();
float dist_sq2 = DistanceTravelledSq(hwstate.fingers[1], true, true);
if (dist_sq1 * dt1 && dist_sq2 * dt2)
similar_movement = max((dist_sq1 * dt1 * dt1) / (dist_sq2 * dt2 * dt2),
@@ -1593,7 +1605,8 @@ void ImmediateInterpreter::UpdateThumbState(const HardwareState& hwstate) {
thumb_dist_sq_thresh *= thumb_pinch_threshold_ratio_.val_;
}
float dist_sq = DistanceTravelledSq(fs, false, true);
- float dt = hwstate.timestamp - origin_timestamps_[fs.tracking_id];
+ float dt = hwstate.timestamp -
+ metrics_->GetFinger(fs.tracking_id)->origin_time();
bool closer_to_origin = dist_sq <= thumb_dist_sq_thresh;
bool slower_moved = (dist_sq * min_dt &&
dist_sq * min_dt * min_dt <
@@ -1635,13 +1648,15 @@ void ImmediateInterpreter::UpdateThumbState(const HardwareState& hwstate) {
dist_sq * min_dt * min_dt / (thumb_speed_sq_thresh * dt * dt) >
thumb_pinch_min_movement_.val_ &&
similar_movement;
- bool might_be_pinch = (slow_pinch_guess &&
- hwstate.timestamp -
- origin_timestamps_[fs.tracking_id] < 2 *
- thumb_pinch_evaluation_timeout_.val_ &&
- ZoomFingersAreConsistent(state_buffer_));
+ stime_t origin_time =
+ metrics_->GetFinger(fs.tracking_id) ->origin_time();
+ bool might_be_pinch =
+ slow_pinch_guess &&
+ hwstate.timestamp - origin_time < 2 *
+ thumb_pinch_evaluation_timeout_.val_ &&
+ ZoomFingersAreConsistent(state_buffer_);
if (relatively_motionless ||
- hwstate.timestamp - origin_timestamps_[fs.tracking_id] >
+ hwstate.timestamp - origin_time >
thumb_pinch_evaluation_timeout_.val_) {
if (!might_be_pinch)
continue;
@@ -1655,11 +1670,11 @@ void ImmediateInterpreter::UpdateThumbState(const HardwareState& hwstate) {
// Decrease the timer as the finger is thumb-like in the previous
// frame.
const FingerState* prev =
- state_buffer_.Get(1)->GetFingerState(fs.tracking_id);
+ state_buffer_.Get(1).GetFingerState(fs.tracking_id);
if (!prev)
continue;
thumb_eval_timer_[fs.tracking_id] -=
- hwstate.timestamp - state_buffer_.Get(1)->timestamp;
+ hwstate.timestamp - state_buffer_.Get(1).timestamp;
} else {
// The finger wasn't thumb-like in the frame. Remove it from the thumb
// list.
@@ -1714,6 +1729,10 @@ FingerMap ImmediateInterpreter::GetGesturingFingers(
if (pointing_.size() <= kMaxGesturingFingers)
return pointing_;
+ if (hwstate.finger_cnt <= 0) {
+ return {};
+ }
+
const FingerState* fs[hwstate.finger_cnt];
for (size_t i = 0; i < hwstate.finger_cnt; ++i)
fs[i] = &hwstate.fingers[i];
@@ -1823,8 +1842,10 @@ void ImmediateInterpreter::UpdateCurrentGestureType(
// ambiguous. Only move if they've been down long enough.
if (new_gs_type == kGestureTypeMove &&
hwstate.timestamp -
- min(origin_timestamps_[fingers[0]->tracking_id],
- origin_timestamps_[fingers[1]->tracking_id]) <
+ min(metrics_->GetFinger(fingers[0]->tracking_id)
+ ->origin_time(),
+ metrics_->GetFinger(fingers[1]->tracking_id)
+ ->origin_time()) <
evaluation_timeout_.val_)
new_gs_type = kGestureTypeNull;
}
@@ -2203,7 +2224,7 @@ bool ImmediateInterpreter::IsTooCloseToThumb(const FingerState& finger) const {
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);
+ const FingerState* thumb = state_buffer_.Get(0).GetFingerState(it->first);
float xdist = fabsf(finger.position_x - thumb->position_x);
float ydist = fabsf(finger.position_y - thumb->position_y);
if (xdist * xdist + ydist * ydist < kMin2fDistThreshSq)
@@ -2554,7 +2575,7 @@ void ImmediateInterpreter::UpdateTapGesture(
}
Log("UpdateTapGesture: Tap Generated");
result_ = Gesture(kGestureButtonsChange,
- state_buffer_.Get(1)->timestamp,
+ state_buffer_.Get(1).timestamp,
now,
down,
up,
@@ -2628,7 +2649,7 @@ void ImmediateInterpreter::UpdateTapState(
// Gesturing finger wasn't in prev state. It's new.
const FingerState* fs = hwstate->GetFingerState(*it);
if (FingerTooCloseToTap(*hwstate, *fs) ||
- FingerTooCloseToTap(*state_buffer_.Get(1), *fs) ||
+ FingerTooCloseToTap(state_buffer_.Get(1), *fs) ||
SetContainsValue(tap_dead_fingers_, fs->tracking_id))
continue;
added_fingers.insert(*it);
@@ -2714,7 +2735,7 @@ void ImmediateInterpreter::UpdateTapState(
hwstate->timestamp - last_movement_timestamp_ >=
motion_tap_prevent_timeout_.val_) {
tap_record_.Update(
- *hwstate, *state_buffer_.Get(1), added_fingers, removed_fingers,
+ *hwstate, state_buffer_.Get(1), added_fingers, removed_fingers,
dead_fingers);
if (tap_record_.TapBegan())
SetTapToClickState(kTtcFirstTapBegan, now);
@@ -2730,7 +2751,7 @@ void ImmediateInterpreter::UpdateTapState(
break;
}
tap_record_.Update(
- *hwstate, *state_buffer_.Get(1), added_fingers,
+ *hwstate, state_buffer_.Get(1), added_fingers,
removed_fingers, dead_fingers);
Log("TTC: Is tap? %d Is moving? %d",
tap_record_.TapComplete(),
@@ -2755,7 +2776,7 @@ void ImmediateInterpreter::UpdateTapState(
tap_record_.Clear();
tap_record_.Update(
- *hwstate, *state_buffer_.Get(1), added_fingers, removed_fingers,
+ *hwstate, state_buffer_.Get(1), added_fingers, removed_fingers,
dead_fingers);
// If more than one finger is touching: Send click
@@ -2780,10 +2801,10 @@ void ImmediateInterpreter::UpdateTapState(
break;
}
if (hwstate)
- tap_record_.Update(*hwstate, *state_buffer_.Get(1), added_fingers,
+ tap_record_.Update(*hwstate, state_buffer_.Get(1), added_fingers,
removed_fingers, dead_fingers);
- if (!tap_record_.Motionless(*hwstate, *state_buffer_.Get(1),
+ if (!tap_record_.Motionless(*hwstate, state_buffer_.Get(1),
tap_max_movement_.val_)) {
tap_drag_last_motion_time_ = now;
}
@@ -2832,7 +2853,7 @@ void ImmediateInterpreter::UpdateTapState(
case kTtcDrag:
if (hwstate)
tap_record_.Update(
- *hwstate, *state_buffer_.Get(1), added_fingers, removed_fingers,
+ *hwstate, state_buffer_.Get(1), added_fingers, removed_fingers,
dead_fingers);
if (tap_record_.TapComplete()) {
tap_record_.Clear();
@@ -2854,7 +2875,7 @@ void ImmediateInterpreter::UpdateTapState(
case kTtcDragRelease:
if (!added_fingers.empty()) {
tap_record_.Update(
- *hwstate, *state_buffer_.Get(1), added_fingers, removed_fingers,
+ *hwstate, state_buffer_.Get(1), added_fingers, removed_fingers,
dead_fingers);
SetTapToClickState(kTtcDragRetouch, now);
} else if (is_timeout) {
@@ -2865,7 +2886,7 @@ void ImmediateInterpreter::UpdateTapState(
case kTtcDragRetouch:
if (hwstate)
tap_record_.Update(
- *hwstate, *state_buffer_.Get(1), added_fingers, removed_fingers,
+ *hwstate, state_buffer_.Get(1), added_fingers, removed_fingers,
dead_fingers);
if (tap_record_.TapComplete()) {
*buttons_up = GESTURES_BUTTON_LEFT;
@@ -3034,7 +3055,7 @@ void ImmediateInterpreter::UpdateStartedMovingTime(
void ImmediateInterpreter::UpdateButtons(const HardwareState& hwstate,
stime_t* timeout) {
// TODO(miletus): To distinguish between left/right buttons down
- bool prev_button_down = state_buffer_.Get(1)->buttons_down;
+ bool prev_button_down = state_buffer_.Get(1).buttons_down;
bool button_down = hwstate.buttons_down;
if (!prev_button_down && !button_down)
return;
@@ -3066,7 +3087,7 @@ void ImmediateInterpreter::UpdateButtons(const HardwareState& hwstate,
button_evaluation_timeout;
button_type_ = EvaluateButtonType(hwstate, button_down_time);
- if (!hwstate.SameFingersAs(*state_buffer_.Get(0))) {
+ if (!hwstate.SameFingersAs(state_buffer_.Get(0))) {
// Fingers have changed since last state, reset timeout
button_down_deadline_ = hwstate.timestamp + button_finger_timeout;
}
@@ -3082,7 +3103,7 @@ void ImmediateInterpreter::UpdateButtons(const HardwareState& hwstate,
if (result_.type == kGestureTypeButtonsChange)
Err("Gesture type already button?!");
result_ = Gesture(kGestureButtonsChange,
- state_buffer_.Get(1)->timestamp,
+ state_buffer_.Get(1).timestamp,
hwstate.timestamp,
button_type_,
0,
@@ -3096,7 +3117,7 @@ void ImmediateInterpreter::UpdateButtons(const HardwareState& hwstate,
// Send button up
if (result_.type != kGestureTypeButtonsChange)
result_ = Gesture(kGestureButtonsChange,
- state_buffer_.Get(1)->timestamp,
+ state_buffer_.Get(1).timestamp,
hwstate.timestamp,
0,
button_type_,
@@ -3123,7 +3144,7 @@ void ImmediateInterpreter::UpdateButtonsTimeout(stime_t now) {
return;
sent_button_down_ = true;
result_ = Gesture(kGestureButtonsChange,
- state_buffer_.Get(1)->timestamp,
+ state_buffer_.Get(1).timestamp,
now,
button_type_,
0,
@@ -3144,13 +3165,13 @@ void ImmediateInterpreter::FillResultGesture(
if (moving_finger_id_ >= 0)
current = hwstate.GetFingerState(moving_finger_id_);
- const HardwareState* prev_hs = state_buffer_.Get(1);
- if (prev_hs && !current) {
+ 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);
- const FingerState* prev_fs = prev_hs->GetFingerState(fs->tracking_id);
+ const FingerState* prev_fs = prev_hs.GetFingerState(fs->tracking_id);
if (!prev_fs)
break;
float dist_sq = DistSq(*fs, *prev_fs);
@@ -3165,14 +3186,14 @@ void ImmediateInterpreter::FillResultGesture(
// Find corresponding finger id in previous state
const FingerState* prev =
- state_buffer_.Get(1)->GetFingerState(current->tracking_id);
- const FingerState* prev2 = !state_buffer_.Get(2) ? nullptr :
- state_buffer_.Get(2)->GetFingerState(current->tracking_id);
+ state_buffer_.Get(1).GetFingerState(current->tracking_id);
+ const FingerState* prev2 =
+ state_buffer_.Get(2).GetFingerState(current->tracking_id);
if (!prev || !current)
return;
if (current->flags & GESTURES_FINGER_MERGE)
return;
- stime_t dt = hwstate.timestamp - state_buffer_.Get(1)->timestamp;
+ stime_t dt = hwstate.timestamp - state_buffer_.Get(1).timestamp;
bool suppress_finger_movement =
scroll_manager_.SuppressStationaryFingerMovement(
*current, *prev, dt) ||
@@ -3180,7 +3201,7 @@ void ImmediateInterpreter::FillResultGesture(
state_buffer_, *current);
if (quick_acceleration_factor_.val_ && prev2) {
stime_t dt2 =
- state_buffer_.Get(1)->timestamp - state_buffer_.Get(2)->timestamp;
+ state_buffer_.Get(1).timestamp - state_buffer_.Get(2).timestamp;
float dist_sq = DistSq(*current, *prev);
float dist_sq2 = DistSq(*prev, *prev2);
if (dist_sq2 * dt && // have prev dist and current time
@@ -3193,7 +3214,7 @@ void ImmediateInterpreter::FillResultGesture(
if (suppress_finger_movement) {
scroll_manager_.prev_result_suppress_finger_movement_ = true;
result_ = Gesture(kGestureMove,
- state_buffer_.Get(1)->timestamp,
+ state_buffer_.Get(1).timestamp,
hwstate.timestamp,
0,
0);
@@ -3225,7 +3246,7 @@ void ImmediateInterpreter::FillResultGesture(
if (dsq_total >= dsq_total_thresh) {
zero_move = dsq == 0.0;
result_ = Gesture(kGestureMove,
- state_buffer_.Get(1)->timestamp,
+ state_buffer_.Get(1).timestamp,
hwstate.timestamp,
dx,
dy);
@@ -3258,7 +3279,7 @@ void ImmediateInterpreter::FillResultGesture(
&FingerState::position_y };
for (FingerMap::const_iterator it =
fingers.begin(), e = fingers.end(); it != e; ++it) {
- if (!state_buffer_.Get(1)->GetFingerState(*it)) {
+ if (!state_buffer_.Get(1).GetFingerState(*it)) {
Err("missing prev state?");
continue;
}
@@ -3270,7 +3291,7 @@ void ImmediateInterpreter::FillResultGesture(
continue;
float FingerState::*field = fields[i];
float delta = hwstate.GetFingerState(*it)->*field -
- state_buffer_.Get(1)->GetFingerState(*it)->*field;
+ state_buffer_.Get(1).GetFingerState(*it)->*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;
@@ -3283,7 +3304,7 @@ void ImmediateInterpreter::FillResultGesture(
}
if (current_gesture_type_ == kGestureTypeSwipe) {
result_ = Gesture(
- kGestureSwipe, state_buffer_.Get(1)->timestamp,
+ kGestureSwipe, state_buffer_.Get(1).timestamp,
hwstate.timestamp,
(!swipe_is_vertical_ && finger_cnt[0]) ?
sum_delta[0] / finger_cnt[0] : 0.0,
@@ -3291,7 +3312,7 @@ void ImmediateInterpreter::FillResultGesture(
sum_delta[1] / finger_cnt[1] : 0.0);
} else if (current_gesture_type_ == kGestureTypeFourFingerSwipe) {
result_ = Gesture(
- kGestureFourFingerSwipe, state_buffer_.Get(1)->timestamp,
+ kGestureFourFingerSwipe, state_buffer_.Get(1).timestamp,
hwstate.timestamp,
(!swipe_is_vertical_ && finger_cnt[0]) ?
sum_delta[0] / finger_cnt[0] : 0.0,
@@ -3302,14 +3323,14 @@ void ImmediateInterpreter::FillResultGesture(
}
case kGestureTypeSwipeLift: {
result_ = Gesture(kGestureSwipeLift,
- state_buffer_.Get(1)->timestamp,
+ state_buffer_.Get(1).timestamp,
hwstate.timestamp);
break;
}
case kGestureTypeFourFingerSwipeLift: {
result_ = Gesture(kGestureFourFingerSwipeLift,
- state_buffer_.Get(1)->timestamp,
+ state_buffer_.Get(1).timestamp,
hwstate.timestamp);
break;
}
diff --git a/src/immediate_interpreter_unittest.cc b/src/immediate_interpreter_unittest.cc
index 04c822e..c7c6db2 100644
--- a/src/immediate_interpreter_unittest.cc
+++ b/src/immediate_interpreter_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <stdio.h>
+#include <string>
#include <vector>
#include <gtest/gtest.h>
@@ -61,24 +62,22 @@ TEST(ImmediateInterpreterTest, MoveDownTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 1000, // right edge
- 1000, // bottom edge
- 500, // pixels/TP width
- 500, // pixels/TP height
- 96, // screen DPI x
- 96, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 1000,
+ .bottom = 1000,
+ .res_x = 500,
+ .res_y = 500,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&ii, &hwprops);
@@ -125,24 +124,22 @@ TEST(ImmediateInterpreterTest, MoveUpWithRestingThumbTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 1000, // right edge
- 1000, // bottom edge
- 50, // pixels/TP width
- 50, // pixels/TP height
- 96, // screen DPI x
- 96, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 1000,
+ .bottom = 1000,
+ .res_x = 50,
+ .res_y = 50,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&ii, &hwprops);
@@ -191,24 +188,22 @@ TEST(ImmediateInterpreterTest, MoveUpWithRestingThumbTest) {
TEST(ImmediateInterpreterTest, SemiMtScrollUpWithRestingThumbTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 1000, // right edge
- 1000, // bottom edge
- 20, // pixels/TP width
- 20, // pixels/TP height
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 3, // max touch
- 0, // tripletap
- 1, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 1000,
+ .bottom = 1000,
+ .res_x = 20,
+ .res_y = 20,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 3,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 1,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&ii, &hwprops);
@@ -252,24 +247,22 @@ TEST(ImmediateInterpreterTest, SemiMtScrollUpWithRestingThumbTest) {
void ScrollUpTest(float pressure_a, float pressure_b) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 1000, // right edge
- 1000, // bottom edge
- 20, // pixels/TP width
- 20, // pixels/TP height
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 1000,
+ .bottom = 1000,
+ .res_x = 20,
+ .res_y = 20,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&ii, &hwprops);
@@ -326,24 +319,22 @@ TEST(ImmediateInterpreterTest, FatFingerScrollUpTest) {
TEST(ImmediateInterpreterTest, ScrollThenFalseTapTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 1000, // right edge
- 1000, // bottom edge
- 20, // pixels/TP width
- 20, // pixels/TP height
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 1000,
+ .bottom = 1000,
+ .res_x = 20,
+ .res_y = 20,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&ii, &hwprops);
@@ -397,24 +388,22 @@ TEST(ImmediateInterpreterTest, ScrollThenFalseTapTest) {
TEST(ImmediateInterpreterTest, FlingTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&ii, &hwprops);
@@ -511,24 +500,22 @@ TEST(ImmediateInterpreterTest, FlingTest) {
TEST(ImmediateInterpreterTest, DelayedStartScrollTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&ii, &hwprops);
@@ -572,24 +559,22 @@ TEST(ImmediateInterpreterTest, DelayedStartScrollTest) {
TEST(ImmediateInterpreterTest, ScrollReevaluateTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
FingerState finger_states[] = {
@@ -647,24 +632,22 @@ TEST(ImmediateInterpreterTest, ScrollReevaluateTest) {
TEST(ImmediateInterpreterTest, OneFingerThenTwoDelayedStartScrollTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
FingerState finger_states[] = {
@@ -729,24 +712,22 @@ struct OneFatFingerScrollTestInputs {
TEST(ImmediateInterpreterTest, OneFatFingerScrollTest) {
std::unique_ptr<ImmediateInterpreter> ii;
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 106.666672, // right edge
- 68.000000, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 25.4, // screen DPI x
- 25.4, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 15, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- true, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- false, // is haptic pad
+ .right = 106.666672,
+ .bottom = 68.000000,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 15,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = true,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = false,
};
TestInterpreterWrapper wrapper(ii.get(), &hwprops);
// 4 runs that were failing, but now pass:
@@ -899,24 +880,22 @@ struct NoLiftoffScrollTestInputs {
TEST(ImmediateInterpreterTest, NoLiftoffScrollTest) {
std::unique_ptr<ImmediateInterpreter> ii;
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 106.666672, // right edge
- 68.000000, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 25.4, // screen DPI x
- 25.4, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 15, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- true, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- false, // is haptic pad
+ .right = 106.666672,
+ .bottom = 68.000000,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 15,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = true,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = false,
};
TestInterpreterWrapper wrapper(ii.get(), &hwprops);
@@ -1037,24 +1016,22 @@ struct HardwareStateAnScrollExpectations {
TEST(ImmediateInterpreterTest, DiagonalSnapTest) {
std::unique_ptr<ImmediateInterpreter> ii;
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(ii.get(), &hwprops);
@@ -1151,24 +1128,22 @@ TEST(ImmediateInterpreterTest, DiagonalSnapTest) {
TEST(ImmediateInterpreterTest, RestingFingerTest) {
std::unique_ptr<ImmediateInterpreter> ii;
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(ii.get(), &hwprops);
@@ -1221,24 +1196,22 @@ TEST(ImmediateInterpreterTest, RestingFingerTest) {
TEST(ImmediateInterpreterTest, ThumbRetainTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 1, // x screen DPI
- 1, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
FingerState finger_states[] = {
@@ -1275,24 +1248,22 @@ TEST(ImmediateInterpreterTest, ThumbRetainTest) {
TEST(ImmediateInterpreterTest, ThumbRetainReevaluateTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 1, // x screen DPI
- 1, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
FingerState finger_states[] = {
@@ -1326,24 +1297,22 @@ TEST(ImmediateInterpreterTest, ThumbRetainReevaluateTest) {
TEST(ImmediateInterpreterTest, SetHardwarePropertiesTwiceTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 1000, // right edge
- 1000, // bottom edge
- 500, // pixels/TP width
- 500, // pixels/TP height
- 96, // screen DPI x
- 96, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 1000,
+ .bottom = 1000,
+ .res_x = 500,
+ .res_y = 500,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
hwprops.max_finger_cnt = 3;
TestInterpreterWrapper wrapper(&ii, &hwprops);
@@ -1368,24 +1337,22 @@ TEST(ImmediateInterpreterTest, SetHardwarePropertiesTwiceTest) {
TEST(ImmediateInterpreterTest, AmbiguousPalmCoScrollTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // x pixels/TP width
- 1, // y pixels/TP height
- 1, // x screen DPI
- 1, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 5, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&ii, &hwprops);
@@ -1453,24 +1420,22 @@ TEST(ImmediateInterpreterTest, AmbiguousPalmCoScrollTest) {
TEST(ImmediateInterpreterTest, PressureChangeMoveTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 1000, // right edge
- 1000, // bottom edge
- 500, // x pixels/TP width
- 500, // y pixels/TP height
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 1000,
+ .bottom = 1000,
+ .res_x = 500,
+ .res_y = 500,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&ii, &hwprops);
@@ -1516,29 +1481,27 @@ TEST(ImmediateInterpreterTest, PressureChangeMoveTest) {
TEST(ImmediateInterpreterTest, GetGesturingFingersTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 1000, // right edge
- 1000, // bottom edge
- 500, // pixels/TP width
- 500, // pixels/TP height
- 96, // screen DPI x
- 96, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 1000,
+ .bottom = 1000,
+ .res_x = 500,
+ .res_y = 500,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&ii, &hwprops);
FingerState finger_states[] = {
- // TM, Tm, WM, Wm, Press, Orientation, X, Y, TrID
+ // TM, Tm, WM, Wm, Press, Orientation, X, Y, TrID, flags
{0, 0, 0, 0, 1, 0, 61, 70, 91, 0},
{0, 0, 0, 0, 1, 0, 62, 65, 92, 0},
{0, 0, 0, 0, 1, 0, 62, 69, 93, 0},
@@ -1599,6 +1562,27 @@ TEST(ImmediateInterpreterTest, GetGesturingFingersTest) {
EXPECT_TRUE(ids.end() != ids.find(92));
}
+TEST(ImmediateInterpreterTest, GetGesturingFingersWithEmptyStateTest) {
+ ImmediateInterpreter ii(nullptr, nullptr);
+ HardwareProperties hwprops = {};
+ TestInterpreterWrapper wrapper(&ii, &hwprops);
+
+ FingerState finger_states[] = {
+ // TM, Tm, WM, Wm, Press, Orientation, X, Y, TrID, flags
+ {0, 0, 0, 0, 1, 0, 61, 70, 91, 0},
+ {0, 0, 0, 0, 1, 0, 62, 65, 92, 0},
+ {0, 0, 0, 0, 1, 0, 62, 69, 93, 0},
+ {0, 0, 0, 0, 1, 0, 62, 61, 94, 0},
+ {0, 0, 0, 0, 1, 0, 63, 80, 95, 0},
+ };
+ HardwareState five_finger_hwstate =
+ make_hwstate(200000, 0, 5, 5, &finger_states[0]);
+ HardwareState no_finger_hwstate = make_hwstate(200001, 0, 0, 0, nullptr);
+ ii.ResetSameFingersState(five_finger_hwstate);
+ ii.UpdatePointingFingers(five_finger_hwstate);
+ EXPECT_TRUE(ii.GetGesturingFingers(no_finger_hwstate).empty());
+}
+
namespace {
std::set<short> MkSet() {
return std::set<short>();
@@ -1625,6 +1609,8 @@ std::set<short> MkSet(short id1, short id2, short id3) {
TEST(ImmediateInterpreterTest, TapRecordTest) {
ImmediateInterpreter ii(nullptr, nullptr);
+ HardwareProperties hwprops = {};
+ TestInterpreterWrapper wrapper(&ii, &hwprops);
TapRecord tr(&ii);
EXPECT_FALSE(tr.TapComplete());
// two finger IDs:
@@ -1650,15 +1636,13 @@ TEST(ImmediateInterpreterTest, TapRecordTest) {
make_hwstate(0.5, 0, 1, 1, &fs[2]),
};
- /* Hack: Tap recorder points to immediate interpreter and assummes it contains
- * valid values, so we need to insert some origin timestamps */
- const_cast<ImmediateInterpreter*>(tr.immediate_interpreter_)->
- origin_timestamps_[kF1] = 0;
- const_cast<ImmediateInterpreter*>(tr.immediate_interpreter_)->
- origin_timestamps_[kF2] = 0;
+ // Hack: TapRecord uses ImmediateInterpreter's FingerMetrics for origin
+ // timestamps, so we need to populate those.
+ ii.metrics_->Update(hw[0]);
tr.Update(hw[0], nullstate, MkSet(kF1), MkSet(), MkSet());
EXPECT_FALSE(tr.Moving(hw[0], kTapMoveDist));
EXPECT_FALSE(tr.TapComplete());
+ ii.metrics_->Update(hw[1]);
tr.Update(hw[1], hw[0], MkSet(), MkSet(), MkSet());
EXPECT_FALSE(tr.Moving(hw[1], kTapMoveDist));
EXPECT_FALSE(tr.TapComplete());
@@ -1763,13 +1747,18 @@ protected:
}
if (!hwstate || hwstate->timestamp != 0.0) {
- same_fingers = ii_->state_buffer_.Get(1)->SameFingersAs(states[i].hws);
+ same_fingers = ii_->state_buffer_.Get(1).SameFingersAs(states[i].hws);
}
if (hwstate)
ii_->state_buffer_.PushState(*hwstate);
- for (auto finger: states[i].gesturing_fingers)
- ii_->origin_timestamps_.emplace(finger, 0);
+ // TODO(b/307933752): this is unrealistic compared to the actual code that
+ // tracks origin timestamps, but making it more realistic (by calling
+ // ii_->metrics_->Update(*hwstate)) causes
+ // OneFingerTapThenMoveAfterDelayDoesNotDrag to fail.
+ for (auto finger: states[i].gesturing_fingers) {
+ ii_->metrics_->SetFingerOriginTimestampForTesting(finger, 0);
+ }
ii_->UpdateTapState(
hwstate, states[i].gesturing_fingers, same_fingers, now,
&buttons_down, &buttons_up, &timeout);
@@ -1853,12 +1842,12 @@ protected:
double tap_timeout_ = 0.05;
private:
const HardwareProperties hwprops_ = {
- .left = 0,
- .top = 0,
.right = 200,
.bottom = 200,
.res_x = 1.0, // pixels/TP width
.res_y = 1.0, // pixels/TP height
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
.orientation_minimum = -1,
.orientation_maximum = 2,
.max_finger_cnt = 5,
@@ -1984,6 +1973,11 @@ TEST_F(TapToClickStateMachineTest, OneFingerTapAndDrag) {
}
TEST_F(TapToClickStateMachineTest, OneFingerTapThenMoveAfterDelayDoesNotDrag) {
+ // TODO(b/307933752): this test fails if more realistic origin timestamps are
+ // set in TapToClickStateMachineTest::check_hwstates (i.e. calling
+ // ii_->metrics_->Update instead of setting the origin timestamps of
+ // gesturing_fingers to 0). Check whether that's a problem with the test or
+ // the code it's testing.
FingerState tap_fs = {0, 0, 0, 0, 50, 0, 4, 4, 91, 0};
FingerState move_fs[] = {
{0, 0, 0, 0, 50, 0, 4, 4, 95, 0},
@@ -2691,24 +2685,22 @@ struct TapToClickLowPressureBeginOrEndInputs {
TEST(ImmediateInterpreterTest, TapToClickLowPressureBeginOrEndTest) {
std::unique_ptr<ImmediateInterpreter> ii;
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 106.666672, // right edge
- 68.000000, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 25.4, // screen DPI x
- 25.4, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 15, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- true, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- false, // is haptic pad
+ .right = 106.666672,
+ .bottom = 68.000000,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 15,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = true,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = false,
};
TestInterpreterWrapper wrapper(ii.get(), &hwprops);
@@ -2781,24 +2773,22 @@ TEST(ImmediateInterpreterTest, TapToClickKeyboardTest) {
std::unique_ptr<ImmediateInterpreter> ii;
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 200, // right edge
- 200, // bottom edge
- 1.0, // pixels/TP width
- 1.0, // pixels/TP height
- 1.0, // screen DPI x
- 1.0, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 5, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 200,
+ .bottom = 200,
+ .res_x = 1.0,
+ .res_y = 1.0,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(ii.get(), &hwprops);
@@ -2836,8 +2826,7 @@ TEST(ImmediateInterpreterTest, TapToClickKeyboardTest) {
stime_t timeout = NO_DEADLINE;
std::set<short> gs =
hwstates[i].finger_cnt == 1 ? MkSet(91) : MkSet();
- for (auto finger: gs)
- ii->origin_timestamps_.emplace(finger, 0);
+ ii->metrics_->Update(hwstates[i]);
ii->UpdateTapState(
&hwstates[i],
gs,
@@ -2855,30 +2844,49 @@ TEST(ImmediateInterpreterTest, TapToClickKeyboardTest) {
}
}
-TEST(ImmediateInterpreterTest, TapToClickEnableTest) {
- std::unique_ptr<ImmediateInterpreter> ii;
+enum class TtcEnableTestMode {
+ TapEnabled = 0,
+ TapDisabledDuringGesture,
+ TapDisabledBeforeGestureWhileIdle,
+ TapPausedDuringGesture,
+ TapPausedBeforeGestureWhileIdle,
+};
+
+class ImmediateInterpreterTtcEnableTest :
+ public testing::TestWithParam<TtcEnableTestMode> {};
+
+TEST_P(ImmediateInterpreterTtcEnableTest, TapToClickEnableTest) {
+ ImmediateInterpreter ii(nullptr, nullptr);
+ ii.drag_lock_enable_.val_ = 1;
+ ii.motion_tap_prevent_timeout_.val_ = 0;
+ ii.tap_drag_timeout_.val_ = 0.05;
+ ii.tap_enable_.val_ = 1;
+ ii.tap_drag_enable_.val_ = 1;
+ ii.tap_paused_.val_ = 0;
+ ii.tap_move_dist_.val_ = 1.0;
+ ii.tap_timeout_.val_ = 0.05;
+ EXPECT_EQ(kIdl, ii.tap_to_click_state_);
+ EXPECT_TRUE(ii.tap_enable_.val_);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 200, // right edge
- 200, // bottom edge
- 1.0, // pixels/TP width
- 1.0, // pixels/TP height
- 1.0, // screen DPI x
- 1.0, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 5, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 200,
+ .bottom = 200,
+ .res_x = 1.0,
+ .res_y = 1.0,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
- TestInterpreterWrapper wrapper(ii.get(), &hwprops);
+ TestInterpreterWrapper wrapper(&ii, &hwprops);
FingerState fs[] = {
// TM, Tm, WM, Wm, Press, Orientation, X, Y, TrID
@@ -2906,110 +2914,104 @@ TEST(ImmediateInterpreterTest, TapToClickEnableTest) {
{make_hwstate(0.99,0,0,0,nullptr),.99,MkSet(),0,kBL,kIdl,false}
};
- for (int iter = 0; iter < 5; ++iter) {
- for (size_t i = 0; i < arraysize(hwsgs_list); ++i) {
- string desc;
- stime_t disable_time = 0.0;
- stime_t pause_time = 0.0;
- switch (iter) {
- case 0: // test with tap enabled
- desc = StringPrintf("State %zu (tap enabled)", i);
- disable_time = -1; // unreachable time
- pause_time = -1;
- break;
- case 1: // test with tap disabled during gesture
- desc = StringPrintf("State %zu (tap disabled during gesture)", i);
- disable_time = 0.02;
- pause_time = -1;
- break;
- case 2: // test with tap disabled before gesture (while Idle)
- desc = StringPrintf("State %zu (tap disabled while Idle)", i);
- disable_time = 0.00;
- pause_time = -1;
- break;
- case 3: // test with tap paused during gesture
- desc = StringPrintf("State %zu (tap paused during gesture)", i);
- disable_time = -1;
- pause_time = 0.02;
- break;
- case 4: // test with tap paused before gesture (while Idle)
- desc = StringPrintf("State %zu (tap paused while Idle)", i);
- disable_time = 0.00;
- pause_time = -1;
- break;
- }
+ for (size_t i = 0; i < arraysize(hwsgs_list); ++i) {
+ string desc;
+ stime_t disable_time = 0.0;
+ stime_t pause_time = 0.0;
+ switch (GetParam()) {
+ case TtcEnableTestMode::TapEnabled:
+ desc = "tap enabled";
+ disable_time = -1; // unreachable time
+ pause_time = -1;
+ break;
+ case TtcEnableTestMode::TapDisabledDuringGesture:
+ desc = "tap disabled during gesture";
+ disable_time = 0.02;
+ pause_time = -1;
+ break;
+ case TtcEnableTestMode::TapDisabledBeforeGestureWhileIdle:
+ desc = "tap disabled while Idle";
+ disable_time = 0.00;
+ pause_time = -1;
+ break;
+ case TtcEnableTestMode::TapPausedDuringGesture:
+ desc = "tap paused during gesture";
+ disable_time = -1;
+ pause_time = 0.02;
+ break;
+ case TtcEnableTestMode::TapPausedBeforeGestureWhileIdle:
+ desc = "tap paused while Idle";
+ disable_time = 0.00;
+ pause_time = -1;
+ break;
+ }
+ SCOPED_TRACE(StringPrintf("State %zu (%s)", i, desc.c_str()));
- HWStateGs &hwsgs = hwsgs_list[i];
- HardwareState* hwstate = &hwsgs.hws;
- stime_t now = hwsgs.callback_now;
- if (hwsgs.callback_now >= 0.0)
- hwstate = nullptr;
- else
- now = hwsgs.hws.timestamp;
+ HWStateGs &hwsgs = hwsgs_list[i];
+ HardwareState* hwstate = &hwsgs.hws;
+ stime_t now = hwsgs.callback_now;
+ if (hwsgs.callback_now >= 0.0)
+ hwstate = nullptr;
+ else
+ now = hwsgs.hws.timestamp;
- bool same_fingers = false;
- if (hwstate && hwstate->timestamp == 0.0) {
- // Reset imm interpreter
- fprintf(stderr, "Resetting imm interpreter, i = %zd\n", i);
- ii.reset(new ImmediateInterpreter(nullptr, nullptr));
- wrapper.Reset(ii.get());
- ii->drag_lock_enable_.val_ = 1;
- ii->motion_tap_prevent_timeout_.val_ = 0;
- ii->tap_drag_timeout_.val_ = 0.05;
- ii->tap_enable_.val_ = 1;
- ii->tap_drag_enable_.val_ = 1;
- ii->tap_paused_.val_ = 0;
- ii->tap_move_dist_.val_ = 1.0;
- ii->tap_timeout_.val_ = 0.05;
- EXPECT_EQ(kIdl, ii->tap_to_click_state_);
- EXPECT_TRUE(ii->tap_enable_.val_);
- } else {
- same_fingers = ii->state_buffer_.Get(1)->SameFingersAs(hwsgs.hws);
- }
+ bool same_fingers = false;
+ if (!hwstate || hwstate->timestamp != 0.0) {
+ same_fingers = ii.state_buffer_.Get(1).SameFingersAs(hwsgs.hws);
+ }
- // Disable tap in the middle of the gesture
- if (hwstate && hwstate->timestamp == disable_time)
- ii->tap_enable_.val_ = 0;
+ // Disable tap in the middle of the gesture
+ if (hwstate && hwstate->timestamp == disable_time)
+ ii.tap_enable_.val_ = 0;
- if (hwstate && hwstate->timestamp == pause_time)
- ii->tap_paused_.val_ = true;
+ if (hwstate && hwstate->timestamp == pause_time)
+ ii.tap_paused_.val_ = true;
- if (hwstate)
- ii->state_buffer_.PushState(*hwstate);
- unsigned bdown = 0;
- unsigned bup = 0;
- stime_t tm = NO_DEADLINE;
- for (auto finger: hwsgs.gesturing_fingers)
- ii->origin_timestamps_.emplace(finger, 0);
- ii->UpdateTapState(
- hwstate, hwsgs.gesturing_fingers, same_fingers, now, &bdown, &bup,
- &tm);
- ii->prev_gs_fingers_ = hwsgs.gesturing_fingers;
-
- switch (iter) {
- case 0: // tap should be enabled
- case 1:
- case 3:
- EXPECT_EQ(hwsgs.expected_down, bdown) << desc;
- EXPECT_EQ(hwsgs.expected_up, bup) << desc;
- if (hwsgs.timeout)
- EXPECT_GT(tm, 0.0) << desc;
- else
- EXPECT_DOUBLE_EQ(NO_DEADLINE, tm) << desc;
- EXPECT_EQ(hwsgs.expected_state, ii->tap_to_click_state_) << desc;
- break;
- case 2: // tap should be disabled
- case 4:
- EXPECT_EQ(0, bdown) << desc;
- EXPECT_EQ(0, bup) << desc;
- EXPECT_DOUBLE_EQ(NO_DEADLINE, tm) << desc;
- EXPECT_EQ(kIdl, ii->tap_to_click_state_) << desc;
- break;
- }
+ if (hwstate) {
+ ii.metrics_->Update(*hwstate);
+ ii.state_buffer_.PushState(*hwstate);
+ }
+ unsigned buttons_down = 0;
+ unsigned buttons_up = 0;
+ stime_t timeout = NO_DEADLINE;
+ ii.UpdateTapState(
+ hwstate, hwsgs.gesturing_fingers, same_fingers, now, &buttons_down,
+ &buttons_up, &timeout);
+ ii.prev_gs_fingers_ = hwsgs.gesturing_fingers;
+
+ switch (GetParam()) {
+ case TtcEnableTestMode::TapEnabled:
+ case TtcEnableTestMode::TapDisabledDuringGesture:
+ case TtcEnableTestMode::TapPausedDuringGesture:
+ // tap should be enabled
+ EXPECT_EQ(hwsgs.expected_down, buttons_down);
+ EXPECT_EQ(hwsgs.expected_up, buttons_up);
+ if (hwsgs.timeout)
+ EXPECT_GT(timeout, 0.0);
+ else
+ EXPECT_DOUBLE_EQ(NO_DEADLINE, timeout);
+ EXPECT_EQ(hwsgs.expected_state, ii.tap_to_click_state_);
+ break;
+ case TtcEnableTestMode::TapDisabledBeforeGestureWhileIdle:
+ case TtcEnableTestMode::TapPausedBeforeGestureWhileIdle:
+ // tap should be disabled
+ EXPECT_EQ(0, buttons_down);
+ EXPECT_EQ(0, buttons_up);
+ EXPECT_DOUBLE_EQ(NO_DEADLINE, timeout);
+ EXPECT_EQ(kIdl, ii.tap_to_click_state_);
+ break;
}
}
}
+INSTANTIATE_TEST_SUITE_P(
+ ImmediateInterpreterTtc, ImmediateInterpreterTtcEnableTest,
+ testing::Values(TtcEnableTestMode::TapEnabled,
+ TtcEnableTestMode::TapDisabledDuringGesture,
+ TtcEnableTestMode::TapDisabledBeforeGestureWhileIdle,
+ TtcEnableTestMode::TapPausedDuringGesture,
+ TtcEnableTestMode::TapPausedBeforeGestureWhileIdle));
+
struct ClickTestHardwareStateAndExpectations {
HardwareState hs;
stime_t timeout;
@@ -3020,24 +3022,22 @@ struct ClickTestHardwareStateAndExpectations {
TEST(ImmediateInterpreterTest, ClickTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // x pixels/mm
- 1, // y pixels/mm
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&ii, &hwprops);
EXPECT_FLOAT_EQ(10.0, ii.tapping_finger_min_separation_.val_);
@@ -3114,24 +3114,22 @@ struct BigHandsRightClickInputAndExpectations {
// right click.
TEST(ImmediateInterpreterTest, BigHandsRightClickTest) {
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 106.666672, // right edge
- 68.000000, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 25.4, // screen DPI x
- 25.4, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 15, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- true, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- false, // is haptic pad
+ .right = 106.666672,
+ .bottom = 68.000000,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 15,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = true,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = false,
};
BigHandsRightClickInputAndExpectations records[] = {
{ make_hwstate(1329527921.327647, 0, 2, 2, nullptr), 0, 0,
@@ -3269,24 +3267,22 @@ TEST(ImmediateInterpreterTest, BigHandsRightClickTest) {
TEST(ImmediateInterpreterTest, ChangeTimeoutTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 1000, // right edge
- 1000, // bottom edge
- 500, // pixels/TP width
- 500, // pixels/TP height
- 96, // screen DPI x
- 96, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 1000,
+ .bottom = 1000,
+ .res_x = 500,
+ .res_y = 500,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
FingerState finger_states[] = {
@@ -3376,24 +3372,22 @@ TEST(ImmediateInterpreterTest, PinchTests) {
ImmediateInterpreter ii(nullptr, nullptr);
ii.pinch_enable_.val_ = 1;
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
FingerState finger_states[] = {
@@ -3523,24 +3517,22 @@ struct AvoidAccidentalPinchTestInput {
TEST(ImmediateInterpreterTest, AvoidAccidentalPinchTest) {
std::unique_ptr<ImmediateInterpreter> ii;
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 106.666672, // right edge
- 68.000000, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 25.4, // screen DPI x
- 25.4, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 15, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- true, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- false, // is haptic pad
+ .right = 106.666672,
+ .bottom = 68.000000,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 15,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = true,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = false,
};
TestInterpreterWrapper wrapper(ii.get(), &hwprops);
@@ -3681,24 +3673,22 @@ TEST(ImmediateInterpreterTest, SemiMtActiveAreaTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties old_hwprops = {
- 0, // left edge
- 0, // top edge
- 90.404251, // right edge
- 48.953846, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 133, // screen DPI x
- 133, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 3, // max touch
- 0, // t5r2
- 1, // semi-mt
- true, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- false, // is haptic pad
+ .right = 90.404251,
+ .bottom = 48.953846,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 3,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 1,
+ .is_button_pad = true,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = false,
};
const unsigned kNonPalmFlags = GESTURES_FINGER_WARP_X |
@@ -3731,24 +3721,22 @@ TEST(ImmediateInterpreterTest, SemiMtActiveAreaTest) {
}
HardwareProperties new_hwprops = {
- 0, // left edge
- 0, // top edge
- 96.085106, // right edge
- 57.492310, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 133, // screen DPI x
- 133, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 3, // max touch
- 0, // t5r2
- 1, // semi-mt
- true, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- false, // is haptic pad
+ .right = 96.085106,
+ .bottom = 57.492310,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 3,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 1,
+ .is_button_pad = true,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = false,
};
FingerState new_finger_states[] = {
@@ -3783,24 +3771,22 @@ TEST(ImmediateInterpreterTest, SemiMtNoPinchTest) {
ii.pinch_enable_.val_ = 1;
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 90.404251, // right edge
- 48.953846, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 133, // screen DPI x
- 133, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 3, // max touch
- 0, // t5r2
- 0, // semi-mt
- true, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- false, // is haptic pad
+ .right = 90.404251,
+ .bottom = 48.953846,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 3,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = true,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = false,
};
FingerState finger_state[] = {
@@ -3861,24 +3847,22 @@ TEST(ImmediateInterpreterTest, WarpedFingersTappingTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 90.404251, // right edge
- 48.953846, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 133, // screen DPI x
- 133, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 3, // max touch
- 0, // t5r2
- 1, // semi-mt
- true, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- false, // is haptic pad
+ .right = 90.404251,
+ .bottom = 48.953846,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 3,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 1,
+ .is_button_pad = true,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = false,
};
unsigned flags = GESTURES_FINGER_WARP_X_NON_MOVE |
@@ -3923,24 +3907,22 @@ TEST(ImmediateInterpreterTest, WarpedFingersTappingTest) {
TEST(ImmediateInterpreterTest, FlingDepthTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 1, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 1,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
FingerState finger_states[] = {
@@ -4022,24 +4004,22 @@ TEST(ImmediateInterpreterTest, ScrollResetTapTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 96.085106, // right edge
- 57.492310, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 25.4, // screen DPI x
- 25.4, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 3, // max touch
- 0, // t5r2
- 1, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 96.085106,
+ .bottom = 57.492310,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 3,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 1,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
FingerState finger_state[] = {
@@ -4093,24 +4073,22 @@ TEST(ImmediateInterpreterTest, ZeroClickInitializationTest) {
ImmediateInterpreter ii(nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 1000, // right edge
- 1000, // bottom edge
- 500, // pixels/TP width
- 500, // pixels/TP height
- 96, // screen DPI x
- 96, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // tripletap
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 1000,
+ .bottom = 1000,
+ .res_x = 500,
+ .res_y = 500,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&ii, &hwprops);
diff --git a/src/integral_gesture_filter_interpreter.cc b/src/integral_gesture_filter_interpreter.cc
index 20e1d3a..12df856 100644
--- a/src/integral_gesture_filter_interpreter.cc
+++ b/src/integral_gesture_filter_interpreter.cc
@@ -27,8 +27,13 @@ IntegralGestureFilterInterpreter::IntegralGestureFilterInterpreter(
void IntegralGestureFilterInterpreter::SyncInterpretImpl(
HardwareState& hwstate, stime_t* timeout) {
+ const char name[] = "IntegralGestureFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
can_clear_remainders_ = hwstate.finger_cnt == 0 && hwstate.touch_cnt == 0;
stime_t next_timeout = NO_DEADLINE;
+
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, &next_timeout);
*timeout = SetNextDeadlineAndReturnTimeoutVal(
hwstate.timestamp, remainder_reset_deadline_, next_timeout);
@@ -36,6 +41,9 @@ void IntegralGestureFilterInterpreter::SyncInterpretImpl(
void IntegralGestureFilterInterpreter::HandleTimerImpl(
stime_t now, stime_t *timeout) {
+ const char name[] = "IntegralGestureFilterInterpreter::HandleTimerImpl";
+ LogHandleTimerPre(name, now, timeout);
+
stime_t next_timeout;
if (ShouldCallNextTimer(remainder_reset_deadline_)) {
if (next_timer_deadline_ > now) {
@@ -64,6 +72,7 @@ void IntegralGestureFilterInterpreter::HandleTimerImpl(
*timeout = SetNextDeadlineAndReturnTimeoutVal(now,
remainder_reset_deadline_,
next_timeout);
+ LogHandleTimerPost(name, now, timeout);
}
namespace {
@@ -79,13 +88,18 @@ float Truncate(float input, float* overflow) {
// absolute value of an input is < 1, we will change it to 0, unless
// there has been enough fractional accumulation to bring it above 1.
void IntegralGestureFilterInterpreter::ConsumeGesture(const Gesture& gesture) {
+ const char name[] = "IntegralGestureFilterInterpreter::ConsumeGesture";
+ LogGestureConsume(name, gesture);
+
Gesture copy = gesture;
switch (gesture.type) {
case kGestureTypeMove:
if (gesture.details.move.dx != 0.0 || gesture.details.move.dy != 0.0 ||
gesture.details.move.ordinal_dx != 0.0 ||
- gesture.details.move.ordinal_dy != 0.0)
+ gesture.details.move.ordinal_dy != 0.0) {
+ LogGestureProduce(name, gesture);
ProduceGesture(gesture);
+ }
break;
case kGestureTypeScroll:
copy.details.scroll.dx = Truncate(copy.details.scroll.dx,
@@ -99,10 +113,14 @@ void IntegralGestureFilterInterpreter::ConsumeGesture(const Gesture& gesture) {
if (copy.details.scroll.dx != 0.0 || copy.details.scroll.dy != 0.0 ||
copy.details.scroll.ordinal_dx != 0.0 ||
copy.details.scroll.ordinal_dy != 0.0) {
+ LogGestureProduce(name, copy);
ProduceGesture(copy);
} else if (copy.details.scroll.stop_fling) {
- ProduceGesture(Gesture(kGestureFling, copy.start_time, copy.end_time,
- 0, 0, GESTURES_FLING_TAP_DOWN));
+ auto fling_tap_down = Gesture(kGestureFling,
+ copy.start_time, copy.end_time,
+ 0, 0, GESTURES_FLING_TAP_DOWN);
+ LogGestureProduce(name, fling_tap_down);
+ ProduceGesture(fling_tap_down);
}
remainder_reset_deadline_ = copy.end_time + 1.0;
break;
@@ -114,11 +132,13 @@ void IntegralGestureFilterInterpreter::ConsumeGesture(const Gesture& gesture) {
if (copy.details.wheel.dx != 0.0 || copy.details.wheel.dy != 0.0 ||
copy.details.wheel.tick_120ths_dx != 0.0 ||
copy.details.wheel.tick_120ths_dy != 0.0) {
+ LogGestureProduce(name, copy);
ProduceGesture(copy);
}
remainder_reset_deadline_ = copy.end_time + 1.0;
break;
default:
+ LogGestureProduce(name, gesture);
ProduceGesture(gesture);
break;
}
diff --git a/src/integral_gesture_filter_interpreter_unittest.cc b/src/integral_gesture_filter_interpreter_unittest.cc
index a17056d..bebd37a 100644
--- a/src/integral_gesture_filter_interpreter_unittest.cc
+++ b/src/integral_gesture_filter_interpreter_unittest.cc
@@ -220,4 +220,28 @@ TEST(IntegralGestureFilterInterpreterTest, SlowScrollTest) {
EXPECT_FLOAT_EQ(1.0, out->details.scroll.dy);
}
+TEST(IntegralGestureFilterInterpreterTestInterpreter, ConsumeGesture) {
+ PropRegistry prop_reg;
+ IntegralGestureFilterInterpreterTestInterpreter* base_interpreter =
+ new IntegralGestureFilterInterpreterTestInterpreter;
+ IntegralGestureFilterInterpreter interpreter(base_interpreter, nullptr);
+
+ using EventDebug = ActivityLog::EventDebug;
+ interpreter.SetEventLoggingEnabled(true);
+ interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
+ interpreter.log_.reset(new ActivityLog(&prop_reg));
+
+ Gesture move(kGestureMove, 0, 0.1, 5, 6);
+ Gesture mouse_wheel(kGestureMouseWheel, 0.2, 0.3, 0.0010, 0, 0, 1);
+ Gesture button_change(kGestureButtonsChange, 0.4, 0.5, 0, 0, false);
+
+ EXPECT_EQ(interpreter.log_->size(), 0);
+ interpreter.ConsumeGesture(move);
+ EXPECT_EQ(interpreter.log_->size(), 2);
+ interpreter.ConsumeGesture(mouse_wheel);
+ EXPECT_EQ(interpreter.log_->size(), 4);
+ interpreter.ConsumeGesture(button_change);
+ EXPECT_EQ(interpreter.log_->size(), 6);
+}
+
} // namespace gestures
diff --git a/src/interpreter.cc b/src/interpreter.cc
index e3a7356..cee8dd3 100644
--- a/src/interpreter.cc
+++ b/src/interpreter.cc
@@ -20,6 +20,8 @@ using std::string;
namespace gestures {
+using EventDebug = ActivityLog::EventDebug;
+
Interpreter::Interpreter(PropRegistry* prop_reg,
Tracer* tracer,
bool force_log_creation)
@@ -49,7 +51,7 @@ void Interpreter::Trace(const char* message, const char* name) {
void Interpreter::SyncInterpret(HardwareState& hwstate,
stime_t* timeout) {
AssertWithReturn(initialized_);
- if (enable_event_logging_ && log_.get()) {
+ if (EventLoggingIsEnabled()) {
Trace("log: start: ", "LogHardwareState");
log_->LogHardwareState(hwstate);
Trace("log: end: ", "LogHardwareState");
@@ -65,7 +67,7 @@ void Interpreter::SyncInterpret(HardwareState& hwstate,
void Interpreter::HandleTimer(stime_t now, stime_t* timeout) {
AssertWithReturn(initialized_);
- if (enable_event_logging_ && log_.get()) {
+ if (EventLoggingIsEnabled()) {
Trace("log: start: ", "LogTimerCallback");
log_->LogTimerCallback(now);
Trace("log: end: ", "LogTimerCallback");
@@ -144,15 +146,40 @@ void Interpreter::InitName() {
}
}
+bool Interpreter::EventLoggingIsEnabled() {
+ return enable_event_logging_ && log_.get();
+}
+
void Interpreter::SetEventLoggingEnabled(bool enabled) {
// TODO(b/185844310): log an event when touch logging is enabled or disabled.
enable_event_logging_ = enabled;
}
+bool Interpreter::EventDebugLoggingIsEnabled(ActivityLog::EventDebug event) {
+ return EventLoggingIsEnabled() &&
+ (enable_event_debug_logging_ & (1 << static_cast<int>(event)));
+}
+
+uint32_t Interpreter::GetEventDebugLoggingEnabled() {
+ return enable_event_debug_logging_;
+}
+
+void Interpreter::SetEventDebugLoggingEnabled(uint32_t enabled) {
+ enable_event_debug_logging_ = enabled;
+}
+
+void Interpreter::EventDebugLoggingDisable(ActivityLog::EventDebug event) {
+ enable_event_debug_logging_ &= ~(1 << static_cast<int>(event));
+}
+
+void Interpreter::EventDebugLoggingEnable(ActivityLog::EventDebug event) {
+ enable_event_debug_logging_ |= (1 << static_cast<int>(event));
+}
+
void Interpreter::LogOutputs(const Gesture* result,
stime_t* timeout,
const char* action) {
- if (!enable_event_logging_ || !log_.get())
+ if (!EventLoggingIsEnabled())
return;
Trace("log: start: ", action);
if (result)
@@ -161,4 +188,41 @@ void Interpreter::LogOutputs(const Gesture* result,
log_->LogCallbackRequest(*timeout);
Trace("log: end: ", action);
}
+
+void Interpreter::LogGestureConsume(
+ const std::string& name, const Gesture& gesture) {
+ if (EventDebugLoggingIsEnabled(EventDebug::Gesture))
+ log_->LogGestureConsume(name, gesture);
+}
+
+void Interpreter::LogGestureProduce(
+ const std::string& name, const Gesture& gesture) {
+ if (EventDebugLoggingIsEnabled(EventDebug::Gesture))
+ log_->LogGestureProduce(name, gesture);
+}
+
+void Interpreter::LogHardwareStatePre(
+ const std::string& name, const HardwareState& hwstate) {
+ if (EventDebugLoggingIsEnabled(EventDebug::HardwareState))
+ log_->LogHardwareStatePre(name, hwstate);
+}
+
+void Interpreter::LogHardwareStatePost(
+ const std::string& name, const HardwareState& hwstate) {
+ if (EventDebugLoggingIsEnabled(EventDebug::HardwareState))
+ log_->LogHardwareStatePost(name, hwstate);
+}
+
+void Interpreter::LogHandleTimerPre(
+ const std::string& name, stime_t now, const stime_t* timeout) {
+ if (EventDebugLoggingIsEnabled(EventDebug::HandleTimer))
+ log_->LogHandleTimerPre(name, now, timeout);
+}
+
+void Interpreter::LogHandleTimerPost(
+ const std::string& name, stime_t now, const stime_t* timeout) {
+ if (EventDebugLoggingIsEnabled(EventDebug::HandleTimer))
+ log_->LogHandleTimerPost(name, now, timeout);
+}
+
} // namespace gestures
diff --git a/src/interpreter_unittest.cc b/src/interpreter_unittest.cc
index a64fa01..e0d1cff 100644
--- a/src/interpreter_unittest.cc
+++ b/src/interpreter_unittest.cc
@@ -67,6 +67,7 @@ class InterpreterTestInterpreter : public Interpreter {
virtual void HandleTimerImpl(stime_t now, stime_t* timeout) {
handle_timer_call_count_++;
+ Interpreter::HandleTimerImpl(now, timeout);
ProduceGesture(return_value_);
}
};
@@ -80,16 +81,17 @@ TEST(InterpreterTest, SimpleTest) {
MetricsProperties mprops(&prop_reg);
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 10, // x res (pixels/mm)
- 10, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- 1, // orientation minimum
- 2, // orientation maximum
- 2, 5, // max fingers, max_touch
- 1, 0, 0, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 10,
+ .res_y = 10,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = 1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 1, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(base_interpreter, &hwprops);
@@ -209,4 +211,97 @@ TEST(InterpreterTest, LoggingDisabledByDefault) {
wrapper.SyncInterpret(hardware_state, &timeout);
EXPECT_EQ(base_interpreter->log_->size(), 0);
}
+
+TEST(InterpreterTest, EventDebugLoggingEnableTest) {
+ InterpreterResetLogTestInterpreter* base_interpreter =
+ new InterpreterResetLogTestInterpreter();
+
+ base_interpreter->SetEventDebugLoggingEnabled(0);
+ EXPECT_EQ(base_interpreter->GetEventDebugLoggingEnabled(), 0);
+
+ using EventDebug = ActivityLog::EventDebug;
+ 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);
+}
+
+TEST(InterpreterTest, LogHardwareStateTest) {
+ PropRegistry prop_reg;
+ InterpreterResetLogTestInterpreter* base_interpreter =
+ new InterpreterResetLogTestInterpreter();
+
+ 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->LogHardwareStatePre(
+ "InterpreterTest_LogHardwareStateTest", hs);
+ EXPECT_EQ(base_interpreter->log_->size(), 0);
+
+ base_interpreter->LogHardwareStatePost(
+ "InterpreterTest_LogHardwareStateTest", hs);
+ EXPECT_EQ(base_interpreter->log_->size(), 0);
+
+ using EventDebug = ActivityLog::EventDebug;
+ base_interpreter->SetEventLoggingEnabled(true);
+ base_interpreter->EventDebugLoggingEnable(EventDebug::HardwareState);
+
+ base_interpreter->LogHardwareStatePre(
+ "InterpreterTest_LogHardwareStateTest", hs);
+ EXPECT_EQ(base_interpreter->log_->size(), 1);
+
+ base_interpreter->LogHardwareStatePost(
+ "InterpreterTest_LogHardwareStateTest", hs);
+ EXPECT_EQ(base_interpreter->log_->size(), 2);
+}
+
+TEST(InterpreterTest, LogGestureTest) {
+ PropRegistry prop_reg;
+ InterpreterResetLogTestInterpreter* base_interpreter =
+ new InterpreterResetLogTestInterpreter();
+
+ 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);
+
+
+ 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);
+}
+
+TEST(InterpreterTest, LogHandleTimerTest) {
+ PropRegistry prop_reg;
+ InterpreterResetLogTestInterpreter* base_interpreter =
+ new InterpreterResetLogTestInterpreter();
+
+ using EventDebug = ActivityLog::EventDebug;
+ base_interpreter->SetEventLoggingEnabled(true);
+ base_interpreter->EventDebugLoggingEnable(EventDebug::HandleTimer);
+
+ stime_t timeout = 10;
+
+ base_interpreter->LogHandleTimerPre("InterpreterTest_LogHandleTimerTest",
+ 0, &timeout);
+ EXPECT_EQ(base_interpreter->log_->size(), 1);
+
+ base_interpreter->LogHandleTimerPost("InterpreterTest_LogHandleTimerTest",
+ 0, &timeout);
+ EXPECT_EQ(base_interpreter->log_->size(), 2);
+}
+
} // namespace gestures
diff --git a/src/logging_filter_interpreter.cc b/src/logging_filter_interpreter.cc
index 2c43238..3d65ad6 100644
--- a/src/logging_filter_interpreter.cc
+++ b/src/logging_filter_interpreter.cc
@@ -17,6 +17,8 @@ LoggingFilterInterpreter::LoggingFilterInterpreter(PropRegistry* prop_reg,
Interpreter* next,
Tracer* tracer)
: FilterInterpreter(prop_reg, next, tracer, true),
+ event_debug_logging_enable_(prop_reg,
+ "Event Debug Logging Components Enable", 0),
event_logging_enable_(prop_reg, "Event Logging Enable", false),
logging_notify_(prop_reg, "Logging Notify", 0),
logging_reset_(prop_reg, "Logging Reset", 0),
@@ -26,6 +28,8 @@ LoggingFilterInterpreter::LoggingFilterInterpreter(PropRegistry* prop_reg,
InitName();
if (prop_reg && log_.get())
prop_reg->set_activity_log(log_.get());
+ event_debug_logging_enable_.SetDelegate(this);
+ IntWasWritten(&event_debug_logging_enable_);
event_logging_enable_.SetDelegate(this);
BoolWasWritten(&event_logging_enable_);
logging_notify_.SetDelegate(this);
@@ -35,8 +39,12 @@ LoggingFilterInterpreter::LoggingFilterInterpreter(PropRegistry* prop_reg,
void LoggingFilterInterpreter::IntWasWritten(IntProperty* prop) {
if (prop == &logging_notify_)
Dump(log_location_.val_);
- if (prop == &logging_reset_)
+ else if (prop == &logging_reset_)
Clear();
+ else if (prop == &event_debug_logging_enable_) {
+ Log("Event Debug Enabled 0x%X", event_debug_logging_enable_.val_);
+ SetEventDebugLoggingEnabled(event_debug_logging_enable_.val_);
+ }
};
void LoggingFilterInterpreter::BoolWasWritten(BoolProperty* prop) {
diff --git a/src/logging_filter_interpreter_unittest.cc b/src/logging_filter_interpreter_unittest.cc
index 001a4ee..fb4ebaa 100644
--- a/src/logging_filter_interpreter_unittest.cc
+++ b/src/logging_filter_interpreter_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <cstdio>
#include <string>
#include <gtest/gtest.h>
@@ -40,17 +41,28 @@ TEST(LoggingFilterInterpreterTest, LogResetHandlerTest) {
interpreter.event_logging_enable_.SetValue(Json::Value(true));
interpreter.BoolWasWritten(&interpreter.event_logging_enable_);
+ using EventDebug = ActivityLog::EventDebug;
+ EXPECT_EQ(interpreter.enable_event_debug_logging_, 0);
+ interpreter.event_debug_logging_enable_.SetValue(
+ Json::Value((1 << static_cast<int>(EventDebug::Gesture)) |
+ (1 << static_cast<int>(EventDebug::HardwareState))));
+ interpreter.IntWasWritten(&interpreter.event_debug_logging_enable_);
+ EXPECT_EQ(interpreter.enable_event_debug_logging_,
+ (1 << static_cast<int>(EventDebug::Gesture)) |
+ (1 << static_cast<int>(EventDebug::HardwareState)));
+
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 10, // x res (pixels/mm)
- 10, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, 5, // max fingers, max_touch,
- 1, 0, 0, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 10,
+ .res_y = 10,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 1, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
@@ -76,8 +88,17 @@ TEST(LoggingFilterInterpreterTest, LogResetHandlerTest) {
std::string str = interpreter.EncodeActivityLog();
EXPECT_NE(0, str.size());
- const char* filename = "testlog.dump";
- interpreter.Dump(filename);
+ // std::tmpnam is considered unsafe because another process could create the
+ // temporary file after time std::tmpnam returns the name but before the code
+ // actually opens it. Because this is just test code, we don't need to be
+ // concerned about such security holes here.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ const char* filename = std::tmpnam(nullptr);
+#pragma GCC diagnostic pop
+ ASSERT_NE(nullptr, filename) << "Couldn't generate a temporary file name";
+ interpreter.log_location_.SetValue(Json::Value(filename));
+ interpreter.IntWasWritten(&interpreter.logging_notify_);
std::string read_str = "";
bool couldRead = ReadFileToString(filename, &read_str);
diff --git a/src/lookahead_filter_interpreter.cc b/src/lookahead_filter_interpreter.cc
index d42643c..7a5c8fd 100644
--- a/src/lookahead_filter_interpreter.cc
+++ b/src/lookahead_filter_interpreter.cc
@@ -45,6 +45,9 @@ LookaheadFilterInterpreter::LookaheadFilterInterpreter(
void LookaheadFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "LookaheadFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, 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;
@@ -91,6 +94,8 @@ void LookaheadFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
hwstate.fingers[i].flags = q_node.state_.fingers[i].flags;
}
}
+
+ LogHardwareStatePost(name, hwstate);
}
// Interpolates the two hardware states into out.
@@ -353,6 +358,9 @@ void LookaheadFilterInterpreter::TapDownOccurringGesture(stime_t now) {
return;
if (queue_.size() < 2)
return; // Not enough data to know
+
+ const char name[] = "LookaheadFilterInterpreter::TapDownOccurringGesture";
+
HardwareState& hs = queue_.back().state_;
if (queue_.back().state_.timestamp != now)
return; // We didn't push a new hardware state now
@@ -361,15 +369,21 @@ void LookaheadFilterInterpreter::TapDownOccurringGesture(stime_t now) {
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,
- 0, 0, GESTURES_FLING_TAP_DOWN));
+ auto fling_tap_down = Gesture(kGestureFling,
+ prev_hs.timestamp, hs.timestamp,
+ 0, 0, GESTURES_FLING_TAP_DOWN);
+ LogGestureProduce(name, fling_tap_down);
+ ProduceGesture(fling_tap_down);
return;
}
// Go finger by finger for a final check
for (size_t i = 0; i < hs.finger_cnt; i++)
if (!prev_hs.GetFingerState(hs.fingers[i].tracking_id)) {
- ProduceGesture(Gesture(kGestureFling, prev_hs.timestamp, hs.timestamp,
- 0, 0, GESTURES_FLING_TAP_DOWN));
+ auto fling_tap_down = Gesture(kGestureFling,
+ prev_hs.timestamp, hs.timestamp,
+ 0, 0, GESTURES_FLING_TAP_DOWN);
+ LogGestureProduce(name, fling_tap_down);
+ ProduceGesture(fling_tap_down);
return;
}
}
@@ -416,6 +430,9 @@ void LookaheadFilterInterpreter::AttemptInterpolation() {
void LookaheadFilterInterpreter::HandleTimerImpl(stime_t now,
stime_t* timeout) {
+ const char name[] = "LookaheadFilterInterpreter::HandleTimerImpl";
+ LogHandleTimerPre(name, now, timeout);
+
stime_t next_timeout = NO_DEADLINE;
// Determine if a FlingTapDown gesture needs to be produced
@@ -492,9 +509,13 @@ void LookaheadFilterInterpreter::HandleTimerImpl(stime_t now,
UpdateInterpreterDue(next_timeout, now, timeout);
}
UpdateInterpreterDue(next_timeout, now, timeout);
+ LogHandleTimerPost(name, now, timeout);
}
void LookaheadFilterInterpreter::ConsumeGesture(const Gesture& gesture) {
+ const char name[] = "LookaheadFilterInterpreter::ConsumeGesture";
+ LogGestureConsume(name, gesture);
+
QState& node = queue_.front();
float distance_sq = 0.0;
@@ -510,6 +531,7 @@ void LookaheadFilterInterpreter::ConsumeGesture(const Gesture& gesture) {
break;
default:
// Non-movement: just allow it.
+ LogGestureProduce(name, gesture);
ProduceGesture(gesture);
return;
}
@@ -518,6 +540,7 @@ void LookaheadFilterInterpreter::ConsumeGesture(const Gesture& gesture) {
min_nonsuppress_speed_.val_ * min_nonsuppress_speed_.val_ *
time_delta * time_delta;
if (distance_sq >= min_nonsuppress_dist_sq) {
+ LogGestureProduce(name, gesture);
ProduceGesture(gesture);
return;
}
@@ -528,6 +551,7 @@ void LookaheadFilterInterpreter::ConsumeGesture(const Gesture& gesture) {
return; // suppress
}
+ LogGestureProduce(name, gesture);
ProduceGesture(gesture);
}
diff --git a/src/lookahead_filter_interpreter_unittest.cc b/src/lookahead_filter_interpreter_unittest.cc
index dca378e..5aed753 100644
--- a/src/lookahead_filter_interpreter_unittest.cc
+++ b/src/lookahead_filter_interpreter_unittest.cc
@@ -13,6 +13,7 @@
#include "include/gestures.h"
#include "include/lookahead_filter_interpreter.h"
+#include "include/string_util.h"
#include "include/unittest_util.h"
#include "include/util.h"
@@ -22,6 +23,9 @@ using std::pair;
namespace gestures {
class LookaheadFilterInterpreterTest : public ::testing::Test {};
+class LookaheadFilterInterpreterParmTest :
+ public LookaheadFilterInterpreterTest,
+ public testing::WithParamInterface<int> {};
class LookaheadFilterInterpreterTestInterpreter : public Interpreter {
public:
@@ -88,21 +92,22 @@ class LookaheadFilterInterpreterTestInterpreter : public Interpreter {
std::set<short> all_ids_;
};
-TEST(LookaheadFilterInterpreterTest, SimpleTest) {
+TEST_P(LookaheadFilterInterpreterParmTest, SimpleTest) {
LookaheadFilterInterpreterTestInterpreter* base_interpreter = nullptr;
std::unique_ptr<LookaheadFilterInterpreter> interpreter;
HardwareProperties initial_hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 10, // x res (pixels/mm)
- 10, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, 5, // max fingers, max_touch
- 1, 0, 0, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 10,
+ .res_y = 10,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 1, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(interpreter.get(), &initial_hwprops);
@@ -137,6 +142,8 @@ TEST(LookaheadFilterInterpreterTest, SimpleTest) {
stime_t expected_timeout = 0.0;
Gesture expected_movement;
+ int suppress = GetParam();
+
for (size_t i = 3; i < arraysize(hs); ++i) {
if (i % 3 == 0) {
base_interpreter = new LookaheadFilterInterpreterTestInterpreter;
@@ -159,6 +166,7 @@ TEST(LookaheadFilterInterpreterTest, SimpleTest) {
wrapper.Reset(interpreter.get());
interpreter->min_delay_.val_ = 0.05;
expected_timeout = interpreter->min_delay_.val_;
+ interpreter->suppress_immediate_tapdown_.val_ = suppress;
}
stime_t timeout = NO_DEADLINE;
Gesture* out = wrapper.SyncInterpret(hs[i], &timeout);
@@ -204,6 +212,9 @@ TEST(LookaheadFilterInterpreterTest, SimpleTest) {
}
}
}
+INSTANTIATE_TEST_SUITE_P(LookaheadFilterInterpreter,
+ LookaheadFilterInterpreterParmTest,
+ testing::Values(0, 1));
class LookaheadFilterInterpreterVariableDelayTestInterpreter
: public Interpreter {
@@ -233,16 +244,17 @@ TEST(LookaheadFilterInterpreterTest, VariableDelayTest) {
LookaheadFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
HardwareProperties initial_hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, // x res (pixels/mm)
- 1, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 5, 5, // max fingers, max_touch,
- 0, 0, 0, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &initial_hwprops);
@@ -309,16 +321,17 @@ TEST(LookaheadFilterInterpreterTest, NoTapSetTest) {
interpreter.min_delay_.val_ = 0.0;
HardwareProperties initial_hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, // x res (pixels/mm)
- 1, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 5, 5, // max fingers, max_touch
- 0, 0, 0, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
FingerState fs[] = {
@@ -364,16 +377,17 @@ TEST(LookaheadFilterInterpreterTest, SpuriousCallbackTest) {
std::unique_ptr<LookaheadFilterInterpreter> interpreter;
HardwareProperties initial_hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 10, // x res (pixels/mm)
- 10, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, 5, // max fingers, max_touch
- 1, 0, 0, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 10,
+ .res_y = 10,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 1, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(interpreter.get(), &initial_hwprops);
@@ -417,16 +431,17 @@ TEST(LookaheadFilterInterpreterTest, TimeGoesBackwardsTest) {
LookaheadFilterInterpreter interpreter(nullptr, base_interpreter, nullptr);
HardwareProperties initial_hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, // x res (pixels/mm)
- 1, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, 5, // max fingers, max_touch
- 1, 0, 0, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 1, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &initial_hwprops);
@@ -512,16 +527,17 @@ TEST(LookaheadFilterInterpreterTest, InterpolateTest) {
std::unique_ptr<LookaheadFilterInterpreter> interpreter;
HardwareProperties initial_hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 10, // x res (pixels/mm)
- 10, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, 5, // max fingers, max_touch
- 1, 0, 0, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 10,
+ .res_y = 10,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 1, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(interpreter.get(), &initial_hwprops);
@@ -593,16 +609,17 @@ TEST(LookaheadFilterInterpreterTest, InterpolationOverdueTest) {
std::unique_ptr<LookaheadFilterInterpreter> interpreter;
HardwareProperties initial_hwprops = {
- 0, 0, 10, 10, // left, top, right, bottom
- 1, // x res (pixels/mm)
- 1, // y res (pixels/mm)
- 25, 25, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, 5, // max fingers, max_touch
- 1, 0, 0, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 10, .bottom = 10,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 1, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(interpreter.get(), &initial_hwprops);
@@ -668,16 +685,17 @@ TEST(LookaheadFilterInterpreterTest, DrumrollTest) {
std::unique_ptr<LookaheadFilterInterpreter> interpreter;
HardwareProperties initial_hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, // x res (pixels/mm)
- 1, // y res (pixels/mm)
- 25, 25, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, 5, // max fingers, max_touch
- 1, 0, 0, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 1, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(interpreter.get(), &initial_hwprops);
@@ -744,16 +762,17 @@ TEST(LookaheadFilterInterpreterTest, QuickMoveTest) {
std::unique_ptr<LookaheadFilterInterpreter> interpreter;
HardwareProperties initial_hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, // x res (pixels/mm)
- 1, // y res (pixels/mm)
- 25, 25, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, 5, // max fingers, max_touch
- 1, 0, 0, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 1, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(interpreter.get(), &initial_hwprops);
@@ -840,24 +859,22 @@ TEST(LookaheadFilterInterpreterTest, QuickSwipeTest) {
std::unique_ptr<LookaheadFilterInterpreter> interpreter;
HardwareProperties initial_hwprops = {
- 0.000000, // left edge
- 0.000000, // top edge
- 95.934784, // right edge
- 65.259262, // bottom edge
- 1.000000, // x pixels/TP width
- 1.000000, // y pixels/TP height
- 25.400000, // x screen DPI
- 25.400000, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 1, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 95.934784,
+ .bottom = 65.259262,
+ .res_x = 1.000000,
+ .res_y = 1.000000,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 1,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(interpreter.get(), &initial_hwprops);
@@ -937,24 +954,22 @@ TEST(LookaheadFilterInterpreterTest, CyapaDrumrollTest) {
std::unique_ptr<LookaheadFilterInterpreter> interpreter;
HardwareProperties initial_hwprops = {
- 0.000000, // left edge
- 0.000000, // top edge
- 106.666672, // right edge
- 68.000000, // bottom edge
- 1.000000, // x pixels/TP width
- 1.000000, // y pixels/TP height
- 25.400000, // x screen DPI
- 25.400000, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 15, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 0, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 106.666672,
+ .bottom = 68.000000,
+ .res_x = 1.000000,
+ .res_y = 1.000000,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 15,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 0,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(interpreter.get(), &initial_hwprops);
@@ -1147,24 +1162,22 @@ TEST(LookaheadFilterInterpreterTest, CyapaQuickTwoFingerMoveTest) {
interpreter.min_delay_.val_ = 0.0;
HardwareProperties initial_hwprops = {
- 0.000000, // left edge
- 0.000000, // top edge
- 106.666672, // right edge
- 68.000000, // bottom edge
- 1.000000, // x pixels/TP width
- 1.000000, // y pixels/TP height
- 25.400000, // x screen DPI
- 25.400000, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 15, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 0, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 106.666672,
+ .bottom = 68.000000,
+ .res_x = 1.000000,
+ .res_y = 1.000000,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 15,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 0,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &initial_hwprops);
@@ -1212,16 +1225,17 @@ TEST(LookaheadFilterInterpreterTest, SemiMtNoTrackingIdAssignmentTest) {
std::unique_ptr<LookaheadFilterInterpreter> interpreter;
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, // x res (pixels/mm)
- 1, // y res (pixels/mm)
- 25, 25, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 2, 5, // max fingers, max_touch
- 1, 1, 0, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 1, .support_semi_mt = 1, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(interpreter.get(), &hwprops);
@@ -1275,4 +1289,122 @@ TEST(LookaheadFilterInterpreterTest, SemiMtNoTrackingIdAssignmentTest) {
}
}
+TEST(LookaheadFilterInterpreterTest, AddFingerFlingTest) {
+ LookaheadFilterInterpreterTestInterpreter* base_interpreter = nullptr;
+ std::unique_ptr<LookaheadFilterInterpreter> interpreter;
+
+ HardwareProperties hwprops = {
+ .right = 100, .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 1, .support_semi_mt = 1, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
+ };
+ TestInterpreterWrapper wrapper(interpreter.get(), &hwprops);
+
+ base_interpreter = new LookaheadFilterInterpreterTestInterpreter;
+ interpreter.reset(new LookaheadFilterInterpreter(
+ nullptr, base_interpreter, nullptr));
+ wrapper.Reset(interpreter.get());
+
+ // Gesture Consumer that verifies and counts each Fling type gesture
+ class FlingConsumer : public GestureConsumer {
+ public:
+ void ConsumeGesture(const Gesture& gesture) {
+ EXPECT_EQ(gesture.type, kGestureTypeFling);
+ ++gestures_consumed_;
+ }
+ int gestures_consumed_ = 0;
+ } fling_consumer{};
+ interpreter->consumer_ = &fling_consumer;
+
+ FingerState fs[] = {
+ // TM, Tm, WM, Wm, pr, orient, x, y, id
+ { 0, 0, 0, 0, 5, 0, 76, 45, 20, 0}, // 0 - One Finger
+
+ { 0, 0, 0, 0, 62, 0, 56, 43, 20, 0}, // 1 - Two Fingers
+ { 0, 0, 0, 0, 62, 0, 76, 41, 21, 0},
+ };
+ HardwareState hs[] = {
+ make_hwstate(328.989039, 0, 1, 1, &fs[0]),
+ make_hwstate(329.013853, 0, 2, 2, &fs[1]),
+ };
+
+ // Disable Suppress Immediate Tapdown
+ interpreter->suppress_immediate_tapdown_.val_ = 0;
+
+ // Run through the two hardware states and verify a fling is detected
+ stime_t timeout = NO_DEADLINE;
+ EXPECT_EQ(fling_consumer.gestures_consumed_, 0);
+ wrapper.SyncInterpret(hs[0], &timeout);
+ EXPECT_EQ(fling_consumer.gestures_consumed_, 0);
+ wrapper.SyncInterpret(hs[1], &timeout);
+ EXPECT_EQ(fling_consumer.gestures_consumed_, 1);
+}
+
+TEST(LookaheadFilterInterpreterTest, ConsumeGestureTest) {
+ LookaheadFilterInterpreterTestInterpreter* base_interpreter = nullptr;
+ std::unique_ptr<LookaheadFilterInterpreter> interpreter;
+
+ HardwareProperties hwprops = {
+ .right = 100, .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 1, .support_semi_mt = 1, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
+ };
+ TestInterpreterWrapper wrapper(interpreter.get(), &hwprops);
+
+ base_interpreter = new LookaheadFilterInterpreterTestInterpreter;
+ interpreter.reset(new LookaheadFilterInterpreter(
+ nullptr, base_interpreter, nullptr));
+ wrapper.Reset(interpreter.get());
+
+ // Gesture Consumer that counts each Metrics and Scroll type gesture
+ class TestGestureConsumer : public GestureConsumer {
+ public:
+ void ConsumeGesture(const Gesture& gesture) {
+ if (gesture.type == kGestureTypeMetrics)
+ ++metric_gestures_consumed_;
+ else if (gesture.type == kGestureTypeScroll)
+ ++scroll_gestures_consumed_;
+ }
+ int metric_gestures_consumed_ = 0;
+ int scroll_gestures_consumed_ = 0;
+ } test_consumer{};
+ interpreter->consumer_ = &test_consumer;
+
+ // Both gestures counters should start with zero
+ EXPECT_EQ(test_consumer.metric_gestures_consumed_, 0);
+ EXPECT_EQ(test_consumer.scroll_gestures_consumed_, 0);
+
+ // Push a Metrics gesture into the interpreter
+ interpreter->ConsumeGesture(Gesture(kGestureMetrics, 0, 0,
+ kGestureMetricsTypeMouseMovement,
+ 0, 0));
+
+ // Verify it was detected
+ EXPECT_EQ(test_consumer.metric_gestures_consumed_, 1);
+ EXPECT_EQ(test_consumer.scroll_gestures_consumed_, 0);
+
+ // Push a Scroll gesture into the interpreter
+ interpreter->ConsumeGesture(Gesture(kGestureScroll, 0, 0, 0, 0));
+
+ // Verify it was detected
+ EXPECT_EQ(test_consumer.metric_gestures_consumed_, 1);
+ EXPECT_EQ(test_consumer.scroll_gestures_consumed_, 1);
+}
+
} // namespace gestures
diff --git a/src/metrics_filter_interpreter.cc b/src/metrics_filter_interpreter.cc
index 02b536e..d5adf9c 100644
--- a/src/metrics_filter_interpreter.cc
+++ b/src/metrics_filter_interpreter.cc
@@ -43,6 +43,9 @@ MetricsFilterInterpreter::MetricsFilterInterpreter(
void MetricsFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "MetricsFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
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
@@ -61,6 +64,8 @@ void MetricsFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
devclass_ == GESTURES_DEVCLASS_POINTING_STICK) {
UpdateMouseMovementState(hwstate);
}
+
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
}
diff --git a/src/metrics_filter_interpreter_unittest.cc b/src/metrics_filter_interpreter_unittest.cc
index a7ede0a..f078aa3 100644
--- a/src/metrics_filter_interpreter_unittest.cc
+++ b/src/metrics_filter_interpreter_unittest.cc
@@ -9,6 +9,22 @@
namespace gestures {
+namespace {
+
+const HardwareProperties hwprops = {
+ .right = 100, .bottom = 100,
+ .res_x = 1, .res_y = 1,
+ .screen_x_dpi = 0, .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 1,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
+};
+
+} // namespace
+
class MetricsFilterInterpreterTest : public ::testing::Test {};
class MetricsFilterInterpreterTestInterpreter : public Interpreter {
@@ -37,17 +53,6 @@ TEST(MetricsFilterInterpreterTest, SimpleTestTouchpad) {
MetricsFilterInterpreter interpreter(nullptr, base_interpreter, nullptr,
GESTURES_DEVCLASS_TOUCHPAD);
- HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, 1, // x res (pixels/mm), y res (pixels/mm)
- 1, 1, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 5, 5, // max fingers, max_touch,
- 0, 0, 1, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
- };
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
EXPECT_FALSE(base_interpreter->handle_timer_called_);
@@ -117,17 +122,6 @@ TEST(MetricsFilterInterpreterTest, SimpleTestMultitouchMouse) {
MetricsFilterInterpreter interpreter(nullptr, base_interpreter, nullptr,
GESTURES_DEVCLASS_MULTITOUCH_MOUSE);
- HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, 1, // x res (pixels/mm), y res (pixels/mm)
- 1, 1, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 5, 5, // max fingers, max_touch,
- 0, 0, 1, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
- };
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
EXPECT_FALSE(base_interpreter->handle_timer_called_);
@@ -197,17 +191,6 @@ TEST(MetricsFilterInterpreterTest, SimpleTestPointingStick) {
MetricsFilterInterpreter interpreter(nullptr, base_interpreter, nullptr,
GESTURES_DEVCLASS_POINTING_STICK);
- HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, 1, // x res (pixels/mm), y res (pixels/mm)
- 1, 1, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 5, 5, // max fingers, max_touch,
- 0, 0, 1, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
- };
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
EXPECT_FALSE(base_interpreter->handle_timer_called_);
diff --git a/src/mouse_interpreter.cc b/src/mouse_interpreter.cc
index 3518b98..6ed44e7 100644
--- a/src/mouse_interpreter.cc
+++ b/src/mouse_interpreter.cc
@@ -63,6 +63,9 @@ MouseInterpreter::MouseInterpreter(PropRegistry* prop_reg, Tracer* tracer)
void MouseInterpreter::SyncInterpretImpl(HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "MouseInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
if(!EmulateScrollWheel(hwstate)) {
// Interpret mouse events in the order of pointer moves, scroll wheels and
// button clicks.
@@ -78,6 +81,8 @@ void MouseInterpreter::SyncInterpretImpl(HardwareState& hwstate,
// Pass max_finger_cnt = 0 to DeepCopy() since we don't care fingers and
// did not allocate any space for fingers.
prev_state_.DeepCopy(hwstate, 0);
+
+ LogHardwareStatePost(name, hwstate);
}
double MouseInterpreter::ComputeScrollAccelFactor(double input_speed) {
@@ -96,9 +101,10 @@ double MouseInterpreter::ComputeScrollAccelFactor(double input_speed) {
}
bool MouseInterpreter::EmulateScrollWheel(const HardwareState& hwstate) {
+ const char name[] = "MouseInterpreter::EmulateScrollWheel";
+
if (!force_scroll_wheel_emulation_.val_ && hwprops_->has_wheel)
return false;
-
bool down = hwstate.buttons_down & GESTURES_BUTTON_MIDDLE ||
(hwstate.buttons_down & GESTURES_BUTTON_LEFT &&
hwstate.buttons_down & GESTURES_BUTTON_RIGHT);
@@ -117,12 +123,14 @@ bool MouseInterpreter::EmulateScrollWheel(const HardwareState& hwstate) {
// Send button event if button has been released without scrolling.
if (falling && !wheel_emulation_active_) {
- ProduceGesture(Gesture(kGestureButtonsChange,
+ auto button_change = Gesture(kGestureButtonsChange,
prev_state_.timestamp,
hwstate.timestamp,
prev_state_.buttons_down,
prev_state_.buttons_down,
- false)); // is_tap
+ false); // is_tap
+ LogGestureProduce(name, button_change);
+ ProduceGesture(button_change);
}
if (down) {
@@ -144,8 +152,11 @@ bool MouseInterpreter::EmulateScrollWheel(const HardwareState& hwstate) {
if (wheel_emulation_active_) {
double scroll_x = hwstate.rel_x * scroll_wheel_emulation_speed_.val_;
double scroll_y = hwstate.rel_y * scroll_wheel_emulation_speed_.val_;
- ProduceGesture(Gesture(kGestureScroll, hwstate.timestamp,
- hwstate.timestamp, scroll_x, scroll_y));
+
+ auto scroll = Gesture(kGestureScroll, hwstate.timestamp,
+ hwstate.timestamp, scroll_x, scroll_y);
+ LogGestureProduce(name, scroll);
+ ProduceGesture(scroll);
}
return true;
}
@@ -155,6 +166,8 @@ bool MouseInterpreter::EmulateScrollWheel(const HardwareState& hwstate) {
void MouseInterpreter::InterpretScrollWheelEvent(const HardwareState& hwstate,
bool is_vertical) {
+ const char name[] = "MouseInterpreter::InterpretScrollWheelEvent";
+
const float scroll_wheel_event_time_delta_min = 0.008;
bool use_high_resolution =
is_vertical && hwprops_->wheel_is_hi_res
@@ -200,9 +213,7 @@ void MouseInterpreter::InterpretScrollWheelEvent(const HardwareState& hwstate,
// When scroll acceleration is off, the scroll factor does not relate to
// scroll velocity. It's simply a constant multiplier to the wheel value.
- // TODO(zhangwenyu): This is gated behind a flag in settings and final
- // values will be updated after some experimentations.
- const double unaccel_scroll_factors[] = { 8.0, 20.0, 36.0, 64.0, 108.0 };
+ 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 * (
@@ -218,11 +229,15 @@ void MouseInterpreter::InterpretScrollWheelEvent(const HardwareState& hwstate,
offset = -offset;
ticks = -ticks;
}
- ProduceGesture(
- CreateWheelGesture(start_time, end_time, 0, offset, 0, ticks));
+ auto scroll_wheel = CreateWheelGesture(start_time, end_time,
+ 0, offset, 0, ticks);
+ LogGestureProduce(name, scroll_wheel);
+ ProduceGesture(scroll_wheel);
} else {
- ProduceGesture(
- CreateWheelGesture(start_time, end_time, offset, 0, ticks, 0));
+ auto scroll_wheel = CreateWheelGesture(start_time, end_time,
+ offset, 0, ticks, 0);
+ LogGestureProduce(name, scroll_wheel);
+ ProduceGesture(scroll_wheel);
}
}
}
@@ -240,12 +255,16 @@ Gesture MouseInterpreter::CreateWheelGesture(
void MouseInterpreter::InterpretMouseButtonEvent(
const HardwareState& prev_state, const HardwareState& hwstate) {
+ const char name[] = "MouseInterpreter::InterpretMouseButtonEvent";
+
const unsigned buttons[] = {
GESTURES_BUTTON_LEFT,
GESTURES_BUTTON_MIDDLE,
GESTURES_BUTTON_RIGHT,
GESTURES_BUTTON_BACK,
- GESTURES_BUTTON_FORWARD
+ GESTURES_BUTTON_FORWARD,
+ GESTURES_BUTTON_SIDE,
+ GESTURES_BUTTON_EXTRA,
};
unsigned down = 0, up = 0;
@@ -259,24 +278,30 @@ void MouseInterpreter::InterpretMouseButtonEvent(
}
if (down || up) {
- ProduceGesture(Gesture(kGestureButtonsChange,
- prev_state.timestamp,
- hwstate.timestamp,
- down,
- up,
- false)); // is_tap
+ auto button_change = Gesture(kGestureButtonsChange,
+ prev_state.timestamp,
+ hwstate.timestamp,
+ down,
+ up,
+ false); // is_tap
+ LogGestureProduce(name, button_change);
+ ProduceGesture(button_change);
}
}
void MouseInterpreter::InterpretMouseMotionEvent(
const HardwareState& prev_state,
const HardwareState& hwstate) {
+ const char name[] = "MouseInterpreter::InterpretMouseMotionEvent";
+
if (hwstate.rel_x || hwstate.rel_y) {
- ProduceGesture(Gesture(kGestureMove,
- prev_state.timestamp,
- hwstate.timestamp,
- hwstate.rel_x,
- hwstate.rel_y));
+ auto move = Gesture(kGestureMove,
+ prev_state.timestamp,
+ hwstate.timestamp,
+ hwstate.rel_x,
+ hwstate.rel_y);
+ LogGestureProduce(name, move);
+ ProduceGesture(move);
}
}
diff --git a/src/mouse_interpreter_unittest.cc b/src/mouse_interpreter_unittest.cc
index b2d644c..57267d8 100644
--- a/src/mouse_interpreter_unittest.cc
+++ b/src/mouse_interpreter_unittest.cc
@@ -14,10 +14,22 @@ namespace gestures {
HardwareProperties make_hwprops_for_mouse(
unsigned has_wheel, unsigned wheel_is_hi_res) {
return {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // touch-specific properties
- has_wheel,
- wheel_is_hi_res,
- 0, // is_haptic_pad
+ .right = 0,
+ .bottom = 0,
+ .res_x = 0,
+ .res_y = 0,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = 0,
+ .orientation_maximum = 0,
+ .max_finger_cnt = 0,
+ .max_touch_cnt = 0,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 0,
+ .has_wheel = has_wheel,
+ .wheel_is_hi_res = wheel_is_hi_res,
+ .is_haptic_pad = 0,
};
}
@@ -277,4 +289,94 @@ TEST(MouseInterpreterTest, WheelTickReportingLowResTest) {
EXPECT_EQ( 0, gs->details.wheel.tick_120ths_dy);
}
+TEST(MouseInterpreterTest, EmulateScrollWheelTest) {
+ HardwareProperties hwprops = make_hwprops_for_mouse(0, 0);
+ MouseInterpreter mi(nullptr, nullptr);
+ TestInterpreterWrapper wrapper(&mi, &hwprops);
+ Gesture* gs;
+
+ HardwareState hwstates[] = {
+ { 200000, GESTURES_BUTTON_NONE, 0, 0, nullptr, 0, 0, 0, 0, 0, 0.0 },
+ { 210000, GESTURES_BUTTON_NONE, 0, 0, nullptr, 9, -7, 0, 0, 0, 0.0 },
+ { 220000, GESTURES_BUTTON_LEFT, 0, 0, nullptr, 0, 0, 0, 0, 0, 0.0 },
+ { 230000, GESTURES_BUTTON_LEFT + GESTURES_BUTTON_RIGHT, 0, 0, nullptr,
+ 0, 0, 0, 0, 0, 0.0 },
+ { 240000, GESTURES_BUTTON_LEFT + GESTURES_BUTTON_RIGHT, 0, 0, nullptr,
+ 2, 2, 0, 0, 0, 0.0 },
+ { 250000, GESTURES_BUTTON_NONE, 0, 0, nullptr, 0, 0, 0, 0, 0, 0.0 },
+ { 260000, GESTURES_BUTTON_NONE, 0, 0, nullptr, 9, -7, 0, 0, 0, 0.0 },
+ { 270000, GESTURES_BUTTON_MIDDLE, 0, 0, nullptr, 0, 0, 0, 0, 0, 0.0 },
+ { 280000, GESTURES_BUTTON_MIDDLE, 0, 0, nullptr, 0, 0, 0, 0, 0, 0.0 },
+ { 290000, GESTURES_BUTTON_NONE, 0, 0, nullptr, 0, 0, -3, -360, 4, 0.0 },
+ };
+
+ mi.output_mouse_wheel_gestures_.val_ = true;
+
+ gs = wrapper.SyncInterpret(hwstates[0], nullptr);
+ EXPECT_EQ(nullptr, gs);
+
+ gs = wrapper.SyncInterpret(hwstates[1], nullptr);
+ ASSERT_NE(nullptr, gs);
+ EXPECT_EQ(kGestureTypeMove, gs->type);
+ EXPECT_EQ(9, gs->details.move.dx);
+ EXPECT_EQ(-7, gs->details.move.dy);
+ EXPECT_EQ(200000, gs->start_time);
+ EXPECT_EQ(210000, gs->end_time);
+
+ gs = wrapper.SyncInterpret(hwstates[2], nullptr);
+ ASSERT_NE(nullptr, gs);
+ EXPECT_EQ(kGestureTypeButtonsChange, gs->type);
+ EXPECT_EQ(1, gs->details.buttons.down);
+ EXPECT_EQ(0, gs->details.buttons.up);
+ EXPECT_EQ(210000, gs->start_time);
+ EXPECT_EQ(220000, gs->end_time);
+
+ gs = wrapper.SyncInterpret(hwstates[3], nullptr);
+ ASSERT_EQ(nullptr, gs);
+
+ // Temporarily adjust the threshold to force wheel_emulation_active_
+ auto thresh = mi.scroll_wheel_emulation_thresh_.val_;
+ mi.scroll_wheel_emulation_thresh_.val_ = 0.1;
+ EXPECT_FALSE(mi.wheel_emulation_active_);
+ gs = wrapper.SyncInterpret(hwstates[4], nullptr);
+ EXPECT_TRUE(mi.wheel_emulation_active_);
+ ASSERT_NE(nullptr, gs);
+ EXPECT_EQ(kGestureTypeScroll, gs->type);
+ EXPECT_EQ(200, gs->details.scroll.dx);
+ EXPECT_EQ(200, gs->details.scroll.dy);
+ EXPECT_EQ(240000, gs->start_time);
+ EXPECT_EQ(240000, gs->end_time);
+ mi.scroll_wheel_emulation_thresh_.val_ = thresh;
+
+ gs = wrapper.SyncInterpret(hwstates[5], nullptr);
+ ASSERT_NE(nullptr, gs);
+ EXPECT_EQ(kGestureTypeButtonsChange, gs->type);
+ EXPECT_EQ(0, gs->details.buttons.down);
+ EXPECT_EQ(5, gs->details.buttons.up);
+ EXPECT_EQ(240000, gs->start_time);
+ EXPECT_EQ(250000, gs->end_time);
+
+ gs = wrapper.SyncInterpret(hwstates[6], nullptr);
+ ASSERT_NE(nullptr, gs);
+ EXPECT_EQ(kGestureTypeMove, gs->type);
+ EXPECT_EQ(9, gs->details.move.dx);
+ EXPECT_EQ(-7, gs->details.move.dy);
+ EXPECT_EQ(250000, gs->start_time);
+ EXPECT_EQ(260000, gs->end_time);
+
+ gs = wrapper.SyncInterpret(hwstates[7], nullptr);
+ ASSERT_EQ(nullptr, gs);
+
+ gs = wrapper.SyncInterpret(hwstates[8], nullptr);
+ ASSERT_EQ(nullptr, gs);
+
+ gs = wrapper.SyncInterpret(hwstates[9], nullptr);
+ ASSERT_NE(nullptr, gs);
+ EXPECT_EQ(kGestureTypeButtonsChange, gs->type);
+ EXPECT_EQ(0, gs->details.buttons.down);
+ EXPECT_EQ(2, gs->details.buttons.up);
+ EXPECT_EQ(280000, gs->start_time);
+ EXPECT_EQ(290000, gs->end_time);
+}
+
} // namespace gestures
diff --git a/src/multitouch_mouse_interpreter.cc b/src/multitouch_mouse_interpreter.cc
index e4163f2..18974ea 100644
--- a/src/multitouch_mouse_interpreter.cc
+++ b/src/multitouch_mouse_interpreter.cc
@@ -62,7 +62,10 @@ void MultitouchMouseInterpreter::ProduceGesture(const Gesture& gesture) {
void MultitouchMouseInterpreter::SyncInterpretImpl(HardwareState& hwstate,
stime_t* timeout) {
- if (!state_buffer_.Get(0)->fingers) {
+ const char name[] = "MultitouchMouseInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
+ if (!state_buffer_.Get(0).fingers) {
Err("Must call SetHardwareProperties() before interpreting anything.");
return;
}
@@ -107,15 +110,15 @@ void MultitouchMouseInterpreter::SyncInterpretImpl(HardwareState& hwstate,
// TODO(clchiou): Remove palm and thumb.
gs_fingers_.clear();
size_t num_fingers = std::min(kMaxGesturingFingers,
- (size_t)state_buffer_.Get(0)->finger_cnt);
- const FingerState* fs = state_buffer_.Get(0)->fingers;
+ (size_t)state_buffer_.Get(0).finger_cnt);
+ const FingerState* fs = state_buffer_.Get(0).fingers;
for (size_t i = 0; i < num_fingers; i++)
gs_fingers_.insert(fs[i].tracking_id);
InterpretScrollWheelEvent(hwstate, true);
InterpretScrollWheelEvent(hwstate, false);
- InterpretMouseButtonEvent(prev_state_, *state_buffer_.Get(0));
- InterpretMouseMotionEvent(prev_state_, *state_buffer_.Get(0));
+ InterpretMouseButtonEvent(prev_state_, state_buffer_.Get(0));
+ InterpretMouseMotionEvent(prev_state_, state_buffer_.Get(0));
bool should_interpret_multitouch = true;
@@ -124,26 +127,24 @@ void MultitouchMouseInterpreter::SyncInterpretImpl(HardwareState& hwstate,
// was rel data, and the previous finger data exactly matches this finger
// data, we remove the last hardware state from our buffer. This is okay
// because we already processed the rel data.
- if (state_buffer_.Get(0) && state_buffer_.Get(1)) {
- HardwareState* prev_hs = state_buffer_.Get(1);
- HardwareState* cur_hs = state_buffer_.Get(0);
- bool cur_has_rel = cur_hs->rel_x || cur_hs->rel_y ||
- cur_hs->rel_wheel || cur_hs->rel_hwheel;
- bool different_fingers = prev_hs->touch_cnt != cur_hs->touch_cnt ||
- prev_hs->finger_cnt != cur_hs->finger_cnt;
- if (!different_fingers && cur_has_rel) {
- // Compare actual fingers themselves
- for (size_t i = 0; i < cur_hs->finger_cnt; i++) {
- if (!cur_hs->fingers[i].NonFlagsEquals(prev_hs->fingers[i])) {
- different_fingers = true;
- break;
- }
- }
- if (!different_fingers) {
- state_buffer_.PopState();
- should_interpret_multitouch = false;
+ const HardwareState& prev_hs = state_buffer_.Get(1);
+ const HardwareState& cur_hs = state_buffer_.Get(0);
+ bool cur_has_rel = cur_hs.rel_x || cur_hs.rel_y ||
+ cur_hs.rel_wheel || cur_hs.rel_hwheel;
+ bool different_fingers = prev_hs.touch_cnt != cur_hs.touch_cnt ||
+ prev_hs.finger_cnt != cur_hs.finger_cnt;
+ if (!different_fingers && cur_has_rel) {
+ // Compare actual fingers themselves
+ for (size_t i = 0; i < cur_hs.finger_cnt; i++) {
+ if (!cur_hs.fingers[i].NonFlagsEquals(prev_hs.fingers[i])) {
+ different_fingers = true;
+ break;
}
}
+ if (!different_fingers) {
+ state_buffer_.PopState();
+ should_interpret_multitouch = false;
+ }
}
if (should_interpret_multitouch)
@@ -156,6 +157,8 @@ void MultitouchMouseInterpreter::SyncInterpretImpl(HardwareState& hwstate,
prev_gs_fingers_ = gs_fingers_;
prev_gesture_type_ = current_gesture_type_;
+
+ LogHardwareStatePost(name, hwstate);
}
void MultitouchMouseInterpreter::Initialize(
@@ -168,10 +171,12 @@ void MultitouchMouseInterpreter::Initialize(
}
void MultitouchMouseInterpreter::InterpretMultitouchEvent() {
+ const char name[] = "MultitouchMouseInterpreter::InterpretMultitouchEvent";
+
Gesture result;
// If a gesturing finger just left, do fling/lift
- if (should_fling_ && AnyGesturingFingerLeft(*state_buffer_.Get(0),
+ if (should_fling_ && AnyGesturingFingerLeft(state_buffer_.Get(0),
prev_gs_fingers_)) {
current_gesture_type_ = kGestureTypeFling;
scroll_manager_.FillResultFling(state_buffer_, scroll_buffer_, &result);
@@ -207,7 +212,7 @@ void MultitouchMouseInterpreter::InterpretMultitouchEvent() {
should_fling_ = true;
bool hold_off_scroll = false;
- const HardwareState& state = *state_buffer_.Get(0);
+ const HardwareState& state = state_buffer_.Get(0);
// Check small finger movements when button is down
if (state.buttons_down) {
float dist_sq, dt;
@@ -236,8 +241,10 @@ void MultitouchMouseInterpreter::InterpretMultitouchEvent() {
}
scroll_manager_.UpdateScrollEventBuffer(current_gesture_type_,
&scroll_buffer_);
- if (result.type != kGestureTypeNull)
+ if (result.type != kGestureTypeNull) {
+ LogGestureProduce(name, result);
ProduceGesture(result);
+ }
prev_result_ = result;
}
diff --git a/src/multitouch_mouse_interpreter_unittest.cc b/src/multitouch_mouse_interpreter_unittest.cc
index 48bba29..ba23e40 100644
--- a/src/multitouch_mouse_interpreter_unittest.cc
+++ b/src/multitouch_mouse_interpreter_unittest.cc
@@ -18,16 +18,17 @@ TEST(MultitouchMouseInterpreterTest, SimpleTest) {
Gesture* gs;
HardwareProperties hwprops = {
- 133, 728, 10279, 5822, // left, top, right, bottom
- (10279.0 - 133.0) / 100.0, // x res (pixels/mm)
- (5822.0 - 728.0) / 60, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -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
+ .left = 133, .top = 728, .right = 10279, .bottom = 5822,
+ .res_x = (10279.0 - 133.0) / 100.0,
+ .res_y = (5822.0 - 728.0) / 60,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&mi, &hwprops);
diff --git a/src/non_linearity_filter_interpreter.cc b/src/non_linearity_filter_interpreter.cc
index 658ba61..df0e765 100644
--- a/src/non_linearity_filter_interpreter.cc
+++ b/src/non_linearity_filter_interpreter.cc
@@ -112,6 +112,9 @@ abort_load:
void NonLinearityFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "NonLinearityFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
if (enabled_.val_ && err_.get() && hwstate.finger_cnt == 1) {
FingerState* finger = &(hwstate.fingers[0]);
if (finger) {
@@ -121,6 +124,7 @@ void NonLinearityFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
finger->position_y -= error.y_error;
}
}
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
}
diff --git a/src/palm_classifying_filter_interpreter.cc b/src/palm_classifying_filter_interpreter.cc
index 808aca0..1551f94 100644
--- a/src/palm_classifying_filter_interpreter.cc
+++ b/src/palm_classifying_filter_interpreter.cc
@@ -45,12 +45,17 @@ PalmClassifyingFilterInterpreter::PalmClassifyingFilterInterpreter(
void PalmClassifyingFilterInterpreter::SyncInterpretImpl(
HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "PalmClassifyingFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
FillOriginInfo(hwstate);
FillMaxPressureWidthInfo(hwstate);
UpdateDistanceInfo(hwstate);
UpdatePalmState(hwstate);
UpdatePalmFlags(hwstate);
FillPrevInfo(hwstate);
+
+ LogHardwareStatePost(name, hwstate);
if (next_.get())
next_->SyncInterpret(hwstate, timeout);
}
@@ -186,6 +191,11 @@ void PalmClassifyingFilterInterpreter::UpdatePalmState(
pointing_.erase(fs.tracking_id);
continue;
}
+ // Mark externally reported palms
+ if(fs.tool_type == FingerState::ToolType::kPalm){
+ palm_.insert(fs.tracking_id);
+ pointing_.erase(fs.tracking_id);
+ }
}
if (hwstate.finger_cnt == 1 &&
diff --git a/src/palm_classifying_filter_interpreter_unittest.cc b/src/palm_classifying_filter_interpreter_unittest.cc
index 4d814ff..61c1c88 100644
--- a/src/palm_classifying_filter_interpreter_unittest.cc
+++ b/src/palm_classifying_filter_interpreter_unittest.cc
@@ -12,6 +12,7 @@
#include "include/gestures.h"
#include "include/palm_classifying_filter_interpreter.h"
+#include "include/string_util.h"
#include "include/unittest_util.h"
#include "include/util.h"
@@ -46,24 +47,22 @@ class PalmClassifyingFilterInterpreterTestInterpreter : public Interpreter {
TEST(PalmClassifyingFilterInterpreterTest, PalmTest) {
PalmClassifyingFilterInterpreter pci(nullptr, nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 1000, // right edge
- 1000, // bottom edge
- 500, // x pixels/TP width
- 500, // y pixels/TP height
- 96, // x screen DPI
- 96, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 2, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 1000,
+ .bottom = 1000,
+ .res_x = 500,
+ .res_y = 500,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&pci, &hwprops);
@@ -123,27 +122,89 @@ TEST(PalmClassifyingFilterInterpreterTest, PalmTest) {
}
}
+TEST(PalmClassifyingFilterInterpreterTest, ExternallyMarkedPalmTest) {
+ PalmClassifyingFilterInterpreterTestInterpreter* base_interpreter =
+ new PalmClassifyingFilterInterpreterTestInterpreter;
+ PalmClassifyingFilterInterpreter pci(nullptr, base_interpreter, nullptr);
+ HardwareProperties hwprops = {
+ .right = 1000,
+ .bottom = 1000,
+ .res_x = 500,
+ .res_y = 500,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
+ };
+
+ TestInterpreterWrapper wrapper(&pci, &hwprops);
+
+ const float kPr = pci.palm_pressure_.val_ / 2;
+
+ FingerState finger_states[] = {
+ // TM, Tm, WM, Wm, Press, Orientation, X, Y, TrID, flags, ToolType
+ {0, 0, 0, 0, kPr, 0, 600, 500, 1, 0},
+ {0, 0, 0, 0, kPr, 0, 600, 500, 1, 0},
+ // mark the touch as palm
+ {0, 0, 0, 0, kPr, 0, 600, 500, 1, 0, FingerState::ToolType::kPalm},
+ {0, 0, 0, 0, kPr, 0, 600, 500, 1, 0, FingerState::ToolType::kPalm},
+ };
+ HardwareState hardware_state[] = {
+ // time, buttons, finger count, touch count, finger states pointer
+ make_hwstate(0.00, 0, 1, 1, &finger_states[0]),
+ make_hwstate(4.00, 0, 1, 1, &finger_states[1]),
+ make_hwstate(5.00, 0, 1, 1, &finger_states[2]),
+ make_hwstate(5.01, 0, 1, 1, &finger_states[3]),
+ };
+
+ for (size_t i = 0; i < arraysize(hardware_state); ++i) {
+ SCOPED_TRACE(StringPrintf("i = %zu", i));
+ if(i > 1) {
+ base_interpreter->expected_flags_ = GESTURES_FINGER_PALM;
+ }
+ else {
+ base_interpreter->expected_flags_ = 0;
+ }
+ wrapper.SyncInterpret(hardware_state[i], nullptr);
+ if (i > 1) {
+ // After the second frame finger is marked as palm
+ EXPECT_FALSE(SetContainsValue(pci.pointing_, 1));
+ EXPECT_TRUE(SetContainsValue(pci.palm_, 1));
+ }
+ else {
+ EXPECT_TRUE(SetContainsValue(pci.pointing_, 1));
+ EXPECT_FALSE(SetContainsValue(pci.palm_, 1));
+ }
+ }
+}
+
TEST(PalmClassifyingFilterInterpreterTest, StationaryPalmTest) {
PalmClassifyingFilterInterpreter pci(nullptr, nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // x pixels/TP width
- 1, // y pixels/TP height
- 1, // x screen DPI
- 1, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 5, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&pci, &hwprops);
@@ -187,24 +248,22 @@ TEST(PalmClassifyingFilterInterpreterTest, PalmAtEdgeTest) {
std::unique_ptr<PalmClassifyingFilterInterpreter> pci(
new PalmClassifyingFilterInterpreter(nullptr, nullptr, nullptr));
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // x pixels/mm
- 1, // y pixels/mm
- 1, // x screen px/mm
- 1, // y screen px/mm
- -1, // orientation minimum
- 2, // orientation maximum
- 5, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(pci.get(), &hwprops);
@@ -316,24 +375,22 @@ struct PalmReevaluateTestInputs {
TEST(PalmClassifyingFilterInterpreterTest, PalmReevaluateTest) {
PalmClassifyingFilterInterpreter pci(nullptr, nullptr, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 106.666672, // right edge
- 68.000000, // bottom edge
- 1, // pixels/TP width
- 1, // pixels/TP height
- 25.4, // screen DPI x
- 25.4, // screen DPI y
- -1, // orientation minimum
- 2, // orientation maximum
- 15, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- true, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- false, // is haptic pad
+ .right = 106.666672,
+ .bottom = 68.000000,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 15,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = true,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = false,
};
TestInterpreterWrapper wrapper(&pci, &hwprops);
@@ -407,24 +464,22 @@ TEST(PalmClassifyingFilterInterpreterTest, LargeTouchMajorTest) {
new PalmClassifyingFilterInterpreterTestInterpreter;
PalmClassifyingFilterInterpreter pci(nullptr, base_interpreter, nullptr);
HardwareProperties hwprops = {
- 0, // left edge
- 0, // top edge
- 100, // right edge
- 100, // bottom edge
- 1, // x pixels/mm
- 1, // y pixels/mm
- 1, // x screen px/mm
- 1, // y screen px/mm
- -1, // orientation minimum
- 2, // orientation maximum
- 5, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 100,
+ .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&pci, &hwprops);
diff --git a/src/scaling_filter_interpreter.cc b/src/scaling_filter_interpreter.cc
index aa04b20..6045801 100644
--- a/src/scaling_filter_interpreter.cc
+++ b/src/scaling_filter_interpreter.cc
@@ -55,7 +55,12 @@ ScalingFilterInterpreter::ScalingFilterInterpreter(
void ScalingFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "ScalingFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
ScaleHardwareState(hwstate);
+
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
}
@@ -214,6 +219,9 @@ void ScalingFilterInterpreter::ScaleTouchpadHardwareState(
}
void ScalingFilterInterpreter::ConsumeGesture(const Gesture& gs) {
+ const char name[] = "ScalingFilterInterpreter::ConsumeGesture";
+ LogGestureConsume(name, gs);
+
Gesture copy = gs;
switch (copy.type) {
case kGestureTypeMove: {
@@ -310,6 +318,8 @@ void ScalingFilterInterpreter::ConsumeGesture(const Gesture& gs) {
default:
break;
}
+
+ LogGestureProduce(name, copy);
ProduceGesture(copy);
}
diff --git a/src/scaling_filter_interpreter_unittest.cc b/src/scaling_filter_interpreter_unittest.cc
index a42eb1b..6d1c529 100644
--- a/src/scaling_filter_interpreter_unittest.cc
+++ b/src/scaling_filter_interpreter_unittest.cc
@@ -98,8 +98,6 @@ class ScalingFilterInterpreterTestInterpreter : public Interpreter {
EXPECT_FLOAT_EQ(expected_hwprops_.bottom, hw_props->bottom);
EXPECT_FLOAT_EQ(expected_hwprops_.res_x, hw_props->res_x);
EXPECT_FLOAT_EQ(expected_hwprops_.res_y, hw_props->res_y);
- EXPECT_FLOAT_EQ(expected_hwprops_.screen_x_dpi, hw_props->screen_x_dpi);
- EXPECT_FLOAT_EQ(expected_hwprops_.screen_y_dpi, hw_props->screen_y_dpi);
EXPECT_FLOAT_EQ(expected_hwprops_.orientation_minimum,
hw_props->orientation_minimum);
EXPECT_FLOAT_EQ(expected_hwprops_.orientation_maximum,
@@ -132,25 +130,30 @@ TEST(ScalingFilterInterpreterTest, SimpleTest) {
ScalingFilterInterpreter interpreter(nullptr, base_interpreter, nullptr,
GESTURES_DEVCLASS_TOUCHPAD);
HardwareProperties initial_hwprops = {
- 133, 728, 10279, 5822, // left, top, right, bottom
- (10279.0 - 133.0) / 100.0, // x res (pixels/mm)
- (5822.0 - 728.0) / 60, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -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
+ .left = 133, .top = 728, .right = 10279, .bottom = 5822,
+ .res_x = (10279.0 - 133.0) / 100.0,
+ .res_y = (5822.0 - 728.0) / 60,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
HardwareProperties expected_hwprops = {
- 0, 0, 100, 60, // left, top, right, bottom
- 1.0, 1.0, 25.4, 25.4, // x res, y res, 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
+ .right = 100, .bottom = 60,
+ .res_x = 1.0,
+ .res_y = 1.0,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -M_PI_4, // (1 tick above X-axis)
+ .orientation_maximum = M_PI_2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
base_interpreter->expected_hwprops_ = expected_hwprops;
@@ -278,25 +281,26 @@ TEST(ScalingFilterInterpreterTest, ResolutionFallback) {
ScalingFilterInterpreter interpreter(nullptr, base_interpreter, nullptr,
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
+ .right = 2000, .bottom = 1000,
+ .res_x = 0, .res_y = 0,
+ .screen_x_dpi = 0, .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
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
+ .right = 2000 / 32.0, .bottom = 1000 / 32.0,
+ .res_x = 1, .res_y = 1,
+ .screen_x_dpi = 0, .screen_y_dpi = 0,
+ .orientation_minimum = -M_PI_4, // (1 tick above X-axis)
+ .orientation_maximum = M_PI_2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
base_interpreter->expected_hwprops_ = expected_hwprops;
@@ -429,25 +433,28 @@ TEST(ScalingFilterInterpreterTest, TouchMajorAndMinorTest) {
interpreter.tp_y_bias_.val_ = e_y;
HardwareProperties hwprops = {
- 0, 0, 500, 1000, // left, top, right, bottom
- 5, // x res (pixels/mm)
- 10, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -31, // orientation minimum
- 32, // orientation maximum
- 2, 5, // max fingers, max_touch
- 0, 0, 0, // t5r2, semi, button pad
- 1, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 500, .bottom = 1000,
+ .res_x = 5,
+ .res_y = 10,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -31,
+ .orientation_maximum = 32,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 1, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
HardwareProperties expected_hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1.0, 1.0, 25.4, 25.4, // x res, y res, x DPI, y DPI
- -M_PI * 31 / 64, // orientation minimum (1 tick above X-axis)
- M_PI_2, // orientation maximum
- 2, 5, 0, 0, 0, // max_fingers, max_touch, t5r2, semi_mt, button pad
- 1, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 1.0, .res_y = 1.0,
+ .screen_x_dpi = 0, .screen_y_dpi = 0,
+ .orientation_minimum = -M_PI * 31 / 64, // (1 tick above X-axis)
+ .orientation_maximum = M_PI_2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 1, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
// Test 1: Touch major and touch minor scaling with orientation
diff --git a/src/sensor_jump_filter_interpreter.cc b/src/sensor_jump_filter_interpreter.cc
index 4f327d8..2044541 100644
--- a/src/sensor_jump_filter_interpreter.cc
+++ b/src/sensor_jump_filter_interpreter.cc
@@ -32,6 +32,9 @@ SensorJumpFilterInterpreter::SensorJumpFilterInterpreter(PropRegistry* prop_reg,
void SensorJumpFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "SensorJumpFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
if (!enabled_.val_) {
next_->SyncInterpret(hwstate, timeout);
return;
@@ -130,6 +133,7 @@ void SensorJumpFilterInterpreter::SyncInterpretImpl(HardwareState& hwstate,
previous_input_[1] = previous_input_[0];
previous_input_[0] = current_input;
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
}
diff --git a/src/sensor_jump_filter_interpreter_unittest.cc b/src/sensor_jump_filter_interpreter_unittest.cc
index 3caf3c4..64a13e5 100644
--- a/src/sensor_jump_filter_interpreter_unittest.cc
+++ b/src/sensor_jump_filter_interpreter_unittest.cc
@@ -59,15 +59,15 @@ TEST(SensorJumpFilterInterpreterTest, SimpleTest) {
interpreter.enabled_.val_ = 1;
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, 1, // x res (pixels/mm), y res (pixels/mm)
- 1, 1, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 5, 5, // max fingers, max_touch
- 0, 0, 1, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 1, .res_y = 1,
+ .screen_x_dpi = 0, .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 1,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
@@ -122,15 +122,15 @@ TEST(SensorJumpFilterInterpreterTest, ActualLogTest) {
interpreter.enabled_.val_ = 1;
HardwareProperties hwprops = {
- 0, 0, 106.666672, 68, // left, top, right, bottom
- 1, 1, // x res (pixels/mm), y res (pixels/mm)
- 25.4, 25.4, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 15, 5, // max fingers, max_touch,
- 0, 0, 1, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 106.666672, .bottom = 68,
+ .res_x = 1, .res_y = 1,
+ .screen_x_dpi = 0, .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 15, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 1,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
diff --git a/src/split_correcting_filter_interpreter.cc b/src/split_correcting_filter_interpreter.cc
index e1dcc30..2895d48 100644
--- a/src/split_correcting_filter_interpreter.cc
+++ b/src/split_correcting_filter_interpreter.cc
@@ -25,6 +25,9 @@ SplitCorrectingFilterInterpreter::SplitCorrectingFilterInterpreter(
void SplitCorrectingFilterInterpreter::SyncInterpretImpl(
HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "SplitCorrectingFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
// Update internal state
if (enabled_.val_) {
RemoveMissingUnmergedContacts(hwstate);
@@ -36,6 +39,7 @@ void SplitCorrectingFilterInterpreter::SyncInterpretImpl(
// Use internal state to update hwstate
UpdateHwState(hwstate);
}
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
}
diff --git a/src/split_correcting_filter_interpreter_unittest.cc b/src/split_correcting_filter_interpreter_unittest.cc
index 3445bd9..a0c6ea8 100644
--- a/src/split_correcting_filter_interpreter_unittest.cc
+++ b/src/split_correcting_filter_interpreter_unittest.cc
@@ -70,21 +70,21 @@ void DoTest(InputEventWithExpectations* events, size_t events_len, bool t5r2) {
interpreter.Enable();
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, // res_x
- 1, // res_y
- 133, // screen_x_dpi
- 133, // screen_y_dpi
- -1, // orientation minimum
- 2, // orientation maximum
- 5, // max finger cnt
- static_cast<unsigned short>(t5r2 ? 2 : 5), // max touch cnt
- t5r2 ? 1u : 0u, // supports_t5r2
- 0, // support_semi_mt
- 1, // is_button_pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is_haptic_pad
+ .right = 100, .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5,
+ .max_touch_cnt = static_cast<unsigned short>(t5r2 ? 2 : 5),
+ .supports_t5r2 = t5r2 ? 1u : 0u,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
@@ -167,21 +167,21 @@ TEST(SplitCorrectingFilterInterpreterTest, FalseMergeTest) {
interpreter.Enable();
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, // res_x
- 1, // res_y
- 133, // screen_x_dpi
- 133, // screen_y_dpi
- -1, // orientation minimum
- 2, // orientation maximum
- 5, // max finger cnt
- 5, // max touch cnt
- 0, // supports_t5r2
- 0, // support_semi_mt
- 1, // is_button_pad
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is_haptic_pad
+ .right = 100, .bottom = 100,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
@@ -323,24 +323,22 @@ TEST(SplitCorrectingFilterInterpreterTest, LumpyThumbSplitTest) {
base_interpreter->expect_finger_ids_ = true;
HardwareProperties hwprops = {
- 0.0, // left edge
- 0.0, // top edge
- 106.666672, // right edge
- 68.0, // bottom edge
- 1.0, // x pixels/TP width
- 1.0, // y pixels/TP height
- 25.4, // x screen DPI
- 25.4, // y screen DPI
- -1, // orientation minimum
- 2, // orientation maximum
- 15, // max fingers
- 5, // max touch
- 0, // t5r2
- 0, // semi-mt
- 1, // is button pad,
- 0, // has_wheel
- 0, // wheel_is_hi_res
- 0, // is haptic pad
+ .right = 106.666672,
+ .bottom = 68.0,
+ .res_x = 1.0,
+ .res_y = 1.0,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 15,
+ .max_touch_cnt = 5,
+ .supports_t5r2 = 0,
+ .support_semi_mt = 0,
+ .is_button_pad = 1,
+ .has_wheel = 0,
+ .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
diff --git a/src/stationary_wiggle_filter_interpreter.cc b/src/stationary_wiggle_filter_interpreter.cc
index bcde6e9..3ec85b1 100644
--- a/src/stationary_wiggle_filter_interpreter.cc
+++ b/src/stationary_wiggle_filter_interpreter.cc
@@ -110,8 +110,13 @@ StationaryWiggleFilterInterpreter::StationaryWiggleFilterInterpreter(
void StationaryWiggleFilterInterpreter::SyncInterpretImpl(
HardwareState& hwstate, stime_t* timeout) {
+ const char name[] = "StationaryWiggleFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
if (enabled_.val_)
UpdateStationaryFlags(hwstate);
+
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
}
diff --git a/src/stationary_wiggle_filter_interpreter_unittest.cc b/src/stationary_wiggle_filter_interpreter_unittest.cc
index 2367e7e..1ac5e9b 100644
--- a/src/stationary_wiggle_filter_interpreter_unittest.cc
+++ b/src/stationary_wiggle_filter_interpreter_unittest.cc
@@ -59,15 +59,15 @@ TEST(StationaryWiggleFilterInterpreterTest, SimpleTest) {
interpreter.enabled_.val_ = true;
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, 1, // x res (pixels/mm), y res (pixels/mm)
- 1, 1, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 5, 5, // max fingers, max_touch,
- 0, 0, 1, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 1, .res_y = 1,
+ .screen_x_dpi = 0, .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 1,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
diff --git a/src/stuck_button_inhibitor_filter_interpreter.cc b/src/stuck_button_inhibitor_filter_interpreter.cc
index 4566ab2..d5b0999 100644
--- a/src/stuck_button_inhibitor_filter_interpreter.cc
+++ b/src/stuck_button_inhibitor_filter_interpreter.cc
@@ -20,14 +20,23 @@ StuckButtonInhibitorFilterInterpreter::StuckButtonInhibitorFilterInterpreter(
void StuckButtonInhibitorFilterInterpreter::SyncInterpretImpl(
HardwareState& hwstate, stime_t* timeout) {
+ const char name[] =
+ "StuckButtonInhibitorFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
HandleHardwareState(hwstate);
+
stime_t next_timeout = NO_DEADLINE;
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, &next_timeout);
HandleTimeouts(next_timeout, timeout);
}
void StuckButtonInhibitorFilterInterpreter::HandleTimerImpl(
stime_t now, stime_t* timeout) {
+ const char name[] = "StuckButtonInhibitorFilterInterpreter::HandleTimerImpl";
+ LogHandleTimerPre(name, now, timeout);
+
stime_t next_timeout = NO_DEADLINE;
if (next_expects_timer_) {
next_->HandleTimer(now, &next_timeout);
@@ -37,13 +46,16 @@ void StuckButtonInhibitorFilterInterpreter::HandleTimerImpl(
return;
} else {
Err("Mouse button seems stuck down. Sending button-up.");
- ProduceGesture(Gesture(kGestureButtonsChange,
- now, now, 0, sent_buttons_down_,
- false)); // is_tap
+ auto button_change = Gesture(kGestureButtonsChange,
+ now, now, 0, sent_buttons_down_,
+ false); // is_tap
+ LogGestureProduce(name, button_change);
+ ProduceGesture(button_change);
sent_buttons_down_ = 0;
}
}
HandleTimeouts(next_timeout, timeout);
+ LogHandleTimerPost(name, now, timeout);
}
void StuckButtonInhibitorFilterInterpreter::HandleHardwareState(
@@ -54,6 +66,9 @@ void StuckButtonInhibitorFilterInterpreter::HandleHardwareState(
void StuckButtonInhibitorFilterInterpreter::ConsumeGesture(
const Gesture& gesture) {
+ const char name[] = "StuckButtonInhibitorFilterInterpreter::ConsumeGesture";
+ LogGestureConsume(name, gesture);
+
if (gesture.type == kGestureTypeButtonsChange) {
Gesture result = gesture;
// process buttons going down
@@ -73,8 +88,10 @@ void StuckButtonInhibitorFilterInterpreter::ConsumeGesture(
sent_buttons_down_ &= ~result.details.buttons.up;
if (!result.details.buttons.up && !result.details.buttons.down)
return; // skip gesture
+ LogGestureProduce(name, result);
ProduceGesture(result);
} else {
+ LogGestureProduce(name, gesture);
ProduceGesture(gesture);
}
}
diff --git a/src/stuck_button_inhibitor_filter_interpreter_unittest.cc b/src/stuck_button_inhibitor_filter_interpreter_unittest.cc
index e4fd50b..f983f28 100644
--- a/src/stuck_button_inhibitor_filter_interpreter_unittest.cc
+++ b/src/stuck_button_inhibitor_filter_interpreter_unittest.cc
@@ -79,16 +79,17 @@ TEST(StuckButtonInhibitorFilterInterpreterTest, SimpleTest) {
StuckButtonInhibitorFilterInterpreter interpreter(base_interpreter, nullptr);
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 10, // x res (pixels/mm)
- 10, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -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
+ .right = 100, .bottom = 100,
+ .res_x = 10,
+ .res_y = 10,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);
diff --git a/src/t5r2_correcting_filter_interpreter.cc b/src/t5r2_correcting_filter_interpreter.cc
index 8fe8c60..30ebbd7 100644
--- a/src/t5r2_correcting_filter_interpreter.cc
+++ b/src/t5r2_correcting_filter_interpreter.cc
@@ -20,6 +20,9 @@ T5R2CorrectingFilterInterpreter::T5R2CorrectingFilterInterpreter(
void T5R2CorrectingFilterInterpreter::SyncInterpretImpl(
HardwareState& hwstate,
stime_t* timeout) {
+ const char name[] = "T5R2CorrectingFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
if (touch_cnt_correct_enabled_.val_ &&
hwstate.finger_cnt == 0 && last_finger_cnt_ == 0 &&
hwstate.touch_cnt != 0 && hwstate.touch_cnt == last_touch_cnt_) {
@@ -27,6 +30,8 @@ void T5R2CorrectingFilterInterpreter::SyncInterpretImpl(
}
last_touch_cnt_ = hwstate.touch_cnt;
last_finger_cnt_ = hwstate.finger_cnt;
+
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
}
diff --git a/src/t5r2_correcting_filter_interpreter_unittest.cc b/src/t5r2_correcting_filter_interpreter_unittest.cc
index e6d6261..c297457 100644
--- a/src/t5r2_correcting_filter_interpreter_unittest.cc
+++ b/src/t5r2_correcting_filter_interpreter_unittest.cc
@@ -68,16 +68,17 @@ TEST(T5R2CorrectingFilterInterpreterTest, SimpleTest) {
std::unique_ptr<T5R2CorrectingFilterInterpreter> interpreter;
HardwareProperties hwprops = {
- 0, 0, 10, 10, // left, top, right, bottom
- 1, // x res (pixels/mm)
- 1, // y res (pixels/mm)
- 133, 133, // scrn DPI X, Y
- -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
+ .right = 10, .bottom = 10,
+ .res_x = 1,
+ .res_y = 1,
+ .screen_x_dpi = 0,
+ .screen_y_dpi = 0,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 2, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 0,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(interpreter.get(), &hwprops);
diff --git a/src/timestamp_filter_interpreter.cc b/src/timestamp_filter_interpreter.cc
index ed5104d..b3d7bd6 100644
--- a/src/timestamp_filter_interpreter.cc
+++ b/src/timestamp_filter_interpreter.cc
@@ -26,23 +26,34 @@ TimestampFilterInterpreter::TimestampFilterInterpreter(
void TimestampFilterInterpreter::SyncInterpretImpl(
HardwareState& hwstate, stime_t* timeout) {
+ const char name[] = "TimestampFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+ auto debug_data = ActivityLog::TimestampHardwareStateDebug{};
+
if (fake_timestamp_delta_.val_ == 0.0)
- ChangeTimestampDefault(hwstate);
+ ChangeTimestampDefault(hwstate, debug_data);
else
- ChangeTimestampUsingFake(hwstate);
+ ChangeTimestampUsingFake(hwstate, debug_data);
+
+ LogDebugData(debug_data);
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
}
void TimestampFilterInterpreter::ChangeTimestampDefault(
- HardwareState& hwstate) {
+ HardwareState& hwstate,
+ ActivityLog::TimestampHardwareStateDebug& debug_data) {
// Check if this is the first event or there has been a jump backwards.
+ debug_data.prev_msc_timestamp_in = prev_msc_timestamp_;
if (prev_msc_timestamp_ < 0.0 ||
hwstate.msc_timestamp == 0.0 ||
hwstate.msc_timestamp < prev_msc_timestamp_) {
msc_timestamp_offset_ = hwstate.timestamp - hwstate.msc_timestamp;
max_skew_ = 0.0;
+ debug_data.was_first_or_backward = true;
}
prev_msc_timestamp_ = hwstate.msc_timestamp;
+ debug_data.prev_msc_timestamp_out = prev_msc_timestamp_;
stime_t new_timestamp = hwstate.msc_timestamp + msc_timestamp_offset_;
skew_ = new_timestamp - hwstate.timestamp;
@@ -50,34 +61,57 @@ void TimestampFilterInterpreter::ChangeTimestampDefault(
hwstate.timestamp = new_timestamp;
hwstate.msc_timestamp = 0.0;
+ debug_data.skew = skew_;
+ debug_data.max_skew = max_skew_;
}
void TimestampFilterInterpreter::ChangeTimestampUsingFake(
- HardwareState& hwstate) {
+ HardwareState& hwstate,
+ ActivityLog::TimestampHardwareStateDebug& debug_data) {
+ debug_data.is_using_fake = true;
+ debug_data.fake_timestamp_in = fake_timestamp_;
+ debug_data.fake_timestamp_delta = fake_timestamp_delta_.val_;
fake_timestamp_ += fake_timestamp_delta_.val_;
if (fabs(fake_timestamp_ - hwstate.timestamp) >
fake_timestamp_max_divergence_) {
fake_timestamp_ = hwstate.timestamp;
max_skew_ = 0.0;
+ debug_data.was_divergence_reset = true;
}
+ debug_data.fake_timestamp_out = fake_timestamp_;
skew_ = fake_timestamp_ - hwstate.timestamp;
max_skew_ = std::max(max_skew_, skew_);
hwstate.timestamp = fake_timestamp_;
+ debug_data.skew = skew_;
+ debug_data.max_skew = max_skew_;
}
void TimestampFilterInterpreter::HandleTimerImpl(stime_t now,
stime_t* timeout) {
+ const char name[] = "TimestampFilterInterpreter::HandleTimerImpl";
+ LogHandleTimerPre(name, now, timeout);
+
// Adjust the timestamp by the largest skew_ since reset. This ensures that
// the callback isn't ignored because it looks like it's coming too early.
- next_->HandleTimer(now + max_skew_, timeout);
+ now += max_skew_;
+ next_->HandleTimer(now, timeout);
+
+ LogHandleTimerPost(name, now, timeout);
}
void TimestampFilterInterpreter::ConsumeGesture(const Gesture& gs) {
+ const char name[] = "TimestampFilterInterpreter::ConsumeGesture";
+ LogGestureConsume(name, gs);
+ auto debug_data = ActivityLog::TimestampGestureDebug{ skew_ };
+
// Adjust gesture timestamp by latest skew to match browser clock
Gesture copy = gs;
copy.start_time -= skew_;
copy.end_time -= skew_;
+
+ LogDebugData(debug_data);
+ LogGestureProduce(name, copy);
ProduceGesture(copy);
}
diff --git a/src/timestamp_filter_interpreter_unittest.cc b/src/timestamp_filter_interpreter_unittest.cc
index 425d97e..482148f 100644
--- a/src/timestamp_filter_interpreter_unittest.cc
+++ b/src/timestamp_filter_interpreter_unittest.cc
@@ -5,13 +5,19 @@
#include <gtest/gtest.h>
#include "include/gestures.h"
+#include "include/string_util.h"
#include "include/timestamp_filter_interpreter.h"
#include "include/unittest_util.h"
#include "include/util.h"
namespace gestures {
+using EventDebug = ActivityLog::EventDebug;
+
class TimestampFilterInterpreterTest : public ::testing::Test {};
+class TimestampFilterInterpreterParmTest :
+ public TimestampFilterInterpreterTest,
+ public testing::WithParamInterface<stime_t> {};
class TimestampFilterInterpreterTestInterpreter : public Interpreter {
public:
@@ -219,4 +225,95 @@ TEST(TimestampFilterInterpreterTest, FakeTimestampFallBackwardTest) {
// the last reset.
EXPECT_FLOAT_EQ(adjusted_timestamp, 2.025);
}
+
+TEST(TimestampFilterInterpreterTest, GestureDebugTest) {
+ PropRegistry prop_reg;
+ TimestampFilterInterpreter interpreter(&prop_reg, nullptr, nullptr);
+
+ using EventDebug = ActivityLog::EventDebug;
+ interpreter.SetEventLoggingEnabled(true);
+ interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
+ interpreter.EventDebugLoggingEnable(EventDebug::HardwareState);
+ interpreter.EventDebugLoggingEnable(EventDebug::HandleTimer);
+ interpreter.EventDebugLoggingEnable(EventDebug::Timestamp);
+ interpreter.log_.reset(new ActivityLog(&prop_reg));
+
+ EXPECT_EQ(interpreter.log_->size(), 0);
+ interpreter.ConsumeGesture(Gesture(kGestureButtonsChange,
+ 1, // start time
+ 2, // end time
+ 0, // down
+ 0, // up
+ false)); // is_tap
+
+ // Encode the log into Json
+ Json::Value node;
+ Json::Value tree = interpreter.log_->EncodeCommonInfo();
+
+ // Verify the Json information
+ EXPECT_EQ(interpreter.log_->size(), 3);
+ node = tree[ActivityLog::kKeyRoot][0];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGestureConsume));
+ node = tree[ActivityLog::kKeyRoot][1];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyTimestampGestureDebug));
+ EXPECT_EQ(node[ActivityLog::kKeyTimestampDebugSkew],
+ Json::Value(interpreter.skew_));
+ node = tree[ActivityLog::kKeyRoot][2];
+ EXPECT_EQ(node[ActivityLog::kKeyType],
+ Json::Value(ActivityLog::kKeyGestureProduce));
+ interpreter.log_->Clear();
+}
+
+TEST_P(TimestampFilterInterpreterParmTest, TimestampDebugLoggingTest) {
+ PropRegistry prop_reg;
+ TimestampFilterInterpreterTestInterpreter* base_interpreter =
+ new TimestampFilterInterpreterTestInterpreter;
+ TimestampFilterInterpreter interpreter(&prop_reg, base_interpreter, nullptr);
+ TestInterpreterWrapper wrapper(&interpreter);
+
+ interpreter.SetEventLoggingEnabled(true);
+ interpreter.EventDebugLoggingEnable(EventDebug::Gesture);
+ interpreter.EventDebugLoggingEnable(EventDebug::HardwareState);
+ interpreter.EventDebugLoggingEnable(EventDebug::HandleTimer);
+ interpreter.EventDebugLoggingEnable(EventDebug::Timestamp);
+ interpreter.log_.reset(new ActivityLog(&prop_reg));
+ interpreter.fake_timestamp_delta_.val_ = GetParam();
+
+ HardwareState hs = make_hwstate_times(1.000, 0.000);
+ wrapper.SyncInterpret(hs, nullptr);
+
+ // Encode the log into Json
+ Json::Value node;
+ Json::Value tree = interpreter.log_->EncodeCommonInfo();
+
+ // Verify the Json information
+ EXPECT_EQ(interpreter.log_->size(), 4);
+ node = tree[ActivityLog::kKeyRoot][0];
+ EXPECT_EQ(node[ActivityLog::kKeyType].asString(),
+ ActivityLog::kKeyHardwareState);
+ node = tree[ActivityLog::kKeyRoot][1];
+ EXPECT_EQ(node[ActivityLog::kKeyType].asString(),
+ ActivityLog::kKeyHardwareStatePre);
+
+ node = tree[ActivityLog::kKeyRoot][2];
+ EXPECT_EQ(node[ActivityLog::kKeyType].asString(),
+ ActivityLog::kKeyTimestampHardwareStateDebug);
+ if (interpreter.fake_timestamp_delta_.val_ == 0.0) {
+ EXPECT_FALSE(node[ActivityLog::kKeyTimestampDebugIsUsingFake].asBool());
+ } else {
+ EXPECT_TRUE(node[ActivityLog::kKeyTimestampDebugIsUsingFake].asBool());
+ }
+
+ node = tree[ActivityLog::kKeyRoot][3];
+ EXPECT_EQ(node[ActivityLog::kKeyType].asString(),
+ ActivityLog::kKeyHardwareStatePost);
+ interpreter.log_->Clear();
+}
+
+INSTANTIATE_TEST_SUITE_P(TimestampFilterInterpreter,
+ TimestampFilterInterpreterParmTest,
+ testing::Values(0.000, 0.010));
+
} // namespace gestures
diff --git a/src/trend_classifying_filter_interpreter.cc b/src/trend_classifying_filter_interpreter.cc
index 50597cf..d039daf 100644
--- a/src/trend_classifying_filter_interpreter.cc
+++ b/src/trend_classifying_filter_interpreter.cc
@@ -45,8 +45,13 @@ TrendClassifyingFilterInterpreter::TrendClassifyingFilterInterpreter(
void TrendClassifyingFilterInterpreter::SyncInterpretImpl(
HardwareState& hwstate, stime_t* timeout) {
+ const char name[] = "TrendClassifyingFilterInterpreter::SyncInterpretImpl";
+ LogHardwareStatePre(name, hwstate);
+
if (trend_classifying_filter_enable_.val_)
UpdateFingerState(hwstate);
+
+ LogHardwareStatePost(name, hwstate);
next_->SyncInterpret(hwstate, timeout);
}
diff --git a/src/trend_classifying_filter_interpreter_unittest.cc b/src/trend_classifying_filter_interpreter_unittest.cc
index ce4da42..80e069e 100644
--- a/src/trend_classifying_filter_interpreter_unittest.cc
+++ b/src/trend_classifying_filter_interpreter_unittest.cc
@@ -44,15 +44,15 @@ TEST(TrendClassifyingFilterInterpreterTest, SimpleTest) {
EXPECT_TRUE(interpreter.second_order_enable_.val_);
HardwareProperties hwprops = {
- 0, 0, 100, 100, // left, top, right, bottom
- 1, 1, // x res (pixels/mm), y res (pixels/mm)
- 1, 1, // scrn DPI X, Y
- -1, // orientation minimum
- 2, // orientation maximum
- 5, 5, // max fingers, max_touch,
- 0, 0, 1, // t5r2, semi, button pad
- 0, 0, // has wheel, vertical wheel is high resolution
- 0, // haptic pad
+ .right = 100, .bottom = 100,
+ .res_x = 1, .res_y = 1,
+ .screen_x_dpi = 1, .screen_y_dpi = 1,
+ .orientation_minimum = -1,
+ .orientation_maximum = 2,
+ .max_finger_cnt = 5, .max_touch_cnt = 5,
+ .supports_t5r2 = 0, .support_semi_mt = 0, .is_button_pad = 1,
+ .has_wheel = 0, .wheel_is_hi_res = 0,
+ .is_haptic_pad = 0,
};
TestInterpreterWrapper wrapper(&interpreter, &hwprops);