xref: /aosp_15_r20/external/libchrome-gestures/include/activity_log.h (revision aed3e5085e770be5b69ce25295ecf6ddf906af95)
1 // Copyright 2012 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef GESTURES_ACTIVITY_LOG_H_
6 #define GESTURES_ACTIVITY_LOG_H_
7 
8 #include "include/gestures.h"
9 
10 #include <string>
11 #include <variant>
12 
13 #include <gtest/gtest.h>  // For FRIEND_TEST
14 #include <json/value.h>
15 
16 // This should be set by build system:
17 #ifndef VCSID
18 #define VCSID "Unknown"
19 #endif  // VCSID
20 
21 // This is a class that circularly buffers all incoming and outgoing activity
22 // so that end users can report issues and engineers can reproduce them.
23 
24 namespace gestures {
25 
26 class PropRegistry;
27 
28 class ActivityLog {
29   FRIEND_TEST(ActivityLogTest, SimpleTest);
30   FRIEND_TEST(ActivityLogTest, WrapAroundTest);
31   FRIEND_TEST(ActivityLogTest, VersionTest);
32   FRIEND_TEST(ActivityLogTest, EncodePropChangeBoolTest);
33   FRIEND_TEST(ActivityLogTest, EncodePropChangeDoubleTest);
34   FRIEND_TEST(ActivityLogTest, EncodePropChangeIntTest);
35   FRIEND_TEST(ActivityLogTest, EncodePropChangeShortTest);
36   FRIEND_TEST(ActivityLogTest, GestureConsumeTest);
37   FRIEND_TEST(ActivityLogTest, GestureProduceTest);
38   FRIEND_TEST(ActivityLogTest, HardwareStatePreTest);
39   FRIEND_TEST(ActivityLogTest, HardwareStatePostTest);
40   FRIEND_TEST(LoggingFilterInterpreterTest, SimpleTest);
41   FRIEND_TEST(PropRegistryTest, PropChangeTest);
42  public:
43   struct TimerCallbackEntry {
44     stime_t timestamp;
45   };
46   struct CallbackRequestEntry {
47     stime_t timestamp;
48   };
49   struct PropChangeEntry {
50     std::string name;
51     // No string variant because string values can't change
52     std::variant<GesturesPropBool,
53                  double,
54                  int,
55                  short> value;
56   };
57 
58   struct HardwareStatePre {
59     std::string name;
60     HardwareState hwstate;
61   };
62   struct HardwareStatePost {
63     std::string name;
64     HardwareState hwstate;
65   };
66   struct GestureConsume {
67     std::string name;
68     Gesture gesture;
69   };
70   struct GestureProduce {
71     std::string name;
72     Gesture gesture;
73   };
74   struct HandleTimerPre {
75     std::string name;
76     bool timeout_is_present;
77     stime_t now;
78     stime_t timeout;
79   };
80   struct HandleTimerPost {
81     std::string name;
82     bool timeout_is_present;
83     stime_t now;
84     stime_t timeout;
85   };
86   struct AccelGestureDebug {
87     bool no_accel_for_gesture_type;
88     bool no_accel_for_small_dt;
89     bool no_accel_for_small_speed;
90     bool no_accel_for_bad_gain;
91     bool dropped_gesture;
92     bool x_y_are_velocity;
93     float x_scale, y_scale;
94     float dt;
95     float adjusted_dt;
96     float speed;
97     float smoothed_speed;
98     float gain_x, gain_y;
99   };
100   struct TimestampGestureDebug {
101     stime_t skew;
102   };
103   struct TimestampHardwareStateDebug {
104     bool is_using_fake;
105     union {
106       struct {
107         bool was_first_or_backward;
108         stime_t prev_msc_timestamp_in;
109         stime_t prev_msc_timestamp_out;
110       };
111       struct {
112         bool was_divergence_reset;
113         stime_t fake_timestamp_in;
114         stime_t fake_timestamp_delta;
115         stime_t fake_timestamp_out;
116       };
117     };
118     stime_t skew;
119     stime_t max_skew;
120   };
121 
122   struct Entry {
123     std::variant<HardwareState,
124                  TimerCallbackEntry,
125                  CallbackRequestEntry,
126                  Gesture,
127                  PropChangeEntry,
128                  HardwareStatePre,
129                  HardwareStatePost,
130                  GestureConsume,
131                  GestureProduce,
132                  HandleTimerPre,
133                  HandleTimerPost,
134                  AccelGestureDebug,
135                  TimestampGestureDebug,
136                  TimestampHardwareStateDebug> details;
137   };
138 
139   enum class EventDebug {
140     // Base Event Types
141     Gesture = 0,
142     HardwareState,
143     HandleTimer,
144     // FilterInterpreter Debug Detail Event Types
145     Accel,
146     Box,
147     ClickWiggle,
148     FingerMerge,
149     FlingStop,
150     HapticButtonGenerator,
151     Iir,
152     IntegratGesture,
153     Logging,
154     Lookahead,
155     Metrics,
156     NonLinearity,
157     PalmClassifying,
158     Scaling,
159     SensorJump,
160     SplitCorrecting,
161     StationaryWiggle,
162     StuckButtonInhibitor,
163     T5R2Correcting,
164     Timestamp,
165     TrendClassifying,
166     // Interpreter Debug Detail Event Types
167     ImmediateInterpreter,
168     MouseInterpreter,
169     MultitouchMouseInterpreter,
170   };
171 
172   explicit ActivityLog(PropRegistry* prop_reg);
173   void SetHardwareProperties(const HardwareProperties& hwprops);
174 
175   // Log*() functions record an argument into the buffer
176   void LogHardwareState(const HardwareState& hwstate);
177   void LogTimerCallback(stime_t now);
178   void LogCallbackRequest(stime_t when);
179   void LogGesture(const Gesture& gesture);
180   void LogPropChange(const PropChangeEntry& prop_change);
181 
182   // Debug extensions for Log*()
183   void LogGestureConsume(const std::string& name, const Gesture& gesture);
184   void LogGestureProduce(const std::string& name, const Gesture& gesture);
185   void LogHardwareStatePre(const std::string& name,
186                            const HardwareState& hwstate);
187   void LogHardwareStatePost(const std::string& name,
188                             const HardwareState& hwstate);
189   void LogHandleTimerPre(const std::string& name,
190                          stime_t now, const stime_t* timeout);
191   void LogHandleTimerPost(const std::string& name,
192                           stime_t now, const stime_t* timeout);
193 
194   template<typename T>
LogDebugData(const T & debug_data)195   void LogDebugData(const T& debug_data) {
196     Entry* entry = PushBack();
197     entry->details = debug_data;
198   }
199 
200   // Dump allocates, and thus must not be called on a signal handler.
201   void Dump(const char* filename);
Clear()202   void Clear() { head_idx_ = size_ = 0; }
203 
204   // Returns a JSON string representing all the state in the buffer
205   std::string Encode();
206   void AddEncodeInfo(Json::Value* root);
207   Json::Value EncodeCommonInfo();
size()208   size_t size() const { return size_; }
MaxSize()209   size_t MaxSize() const { return kBufferSize; }
GetEntry(size_t idx)210   Entry* GetEntry(size_t idx) {
211     return &buffer_[(head_idx_ + idx) % kBufferSize];
212   }
213 
214   static const char kKeyInterpreterName[];
215   static const char kKeyNext[];
216   static const char kKeyRoot[];
217   static const char kKeyType[];
218   static const char kKeyMethodName[];
219   static const char kKeyHardwareState[];
220   static const char kKeyHardwareStatePre[];
221   static const char kKeyHardwareStatePost[];
222   static const char kKeyTimerCallback[];
223   static const char kKeyCallbackRequest[];
224   static const char kKeyGesture[];
225   static const char kKeyGestureConsume[];
226   static const char kKeyGestureProduce[];
227   static const char kKeyPropChange[];
228   static const char kKeyHandleTimerPre[];
229   static const char kKeyHandleTimerPost[];
230   // HardwareState keys:
231   static const char kKeyHardwareStateTimestamp[];
232   static const char kKeyHardwareStateButtonsDown[];
233   static const char kKeyHardwareStateTouchCnt[];
234   static const char kKeyHardwareStateFingers[];
235   static const char kKeyHardwareStateRelX[];
236   static const char kKeyHardwareStateRelY[];
237   static const char kKeyHardwareStateRelWheel[];
238   static const char kKeyHardwareStateRelHWheel[];
239   // FingerState keys (part of HardwareState):
240   static const char kKeyFingerStateTouchMajor[];
241   static const char kKeyFingerStateTouchMinor[];
242   static const char kKeyFingerStateWidthMajor[];
243   static const char kKeyFingerStateWidthMinor[];
244   static const char kKeyFingerStatePressure[];
245   static const char kKeyFingerStateOrientation[];
246   static const char kKeyFingerStatePositionX[];
247   static const char kKeyFingerStatePositionY[];
248   static const char kKeyFingerStateTrackingId[];
249   static const char kKeyFingerStateFlags[];
250   // Timer/Callback keys:
251   static const char kKeyTimerNow[];
252   static const char kKeyHandleTimerTimeout[];
253   static const char kKeyCallbackRequestWhen[];
254   // Gesture keys:
255   static const char kKeyGestureType[];
256   static const char kValueGestureTypeContactInitiated[];
257   static const char kValueGestureTypeMove[];
258   static const char kValueGestureTypeScroll[];
259   static const char kValueGestureTypeMouseWheel[];
260   static const char kValueGestureTypePinch[];
261   static const char kValueGestureTypeButtonsChange[];
262   static const char kValueGestureTypeFling[];
263   static const char kValueGestureTypeSwipe[];
264   static const char kValueGestureTypeSwipeLift[];
265   static const char kValueGestureTypeFourFingerSwipe[];
266   static const char kValueGestureTypeFourFingerSwipeLift[];
267   static const char kValueGestureTypeMetrics[];
268   static const char kKeyGestureStartTime[];
269   static const char kKeyGestureEndTime[];
270   static const char kKeyGestureDX[];
271   static const char kKeyGestureDY[];
272   static const char kKeyGestureOrdinalDX[];
273   static const char kKeyGestureOrdinalDY[];
274   static const char kKeyGestureMouseWheelTicksDX[];
275   static const char kKeyGestureMouseWheelTicksDY[];
276   static const char kKeyGesturePinchDZ[];
277   static const char kKeyGesturePinchOrdinalDZ[];
278   static const char kKeyGesturePinchZoomState[];
279   static const char kKeyGestureButtonsChangeDown[];
280   static const char kKeyGestureButtonsChangeUp[];
281   static const char kKeyGestureFlingVX[];
282   static const char kKeyGestureFlingVY[];
283   static const char kKeyGestureFlingOrdinalVX[];
284   static const char kKeyGestureFlingOrdinalVY[];
285   static const char kKeyGestureFlingState[];
286   static const char kKeyGestureMetricsType[];
287   static const char kKeyGestureMetricsData1[];
288   static const char kKeyGestureMetricsData2[];
289   // PropChange keys:
290   static const char kKeyPropChangeType[];
291   static const char kKeyPropChangeName[];
292   static const char kKeyPropChangeValue[];
293   static const char kValuePropChangeTypeBool[];
294   static const char kValuePropChangeTypeDouble[];
295   static const char kValuePropChangeTypeInt[];
296   static const char kValuePropChangeTypeShort[];
297 
298   // Hardware Properties keys:
299   static const char kKeyHardwarePropRoot[];
300   static const char kKeyHardwarePropLeft[];
301   static const char kKeyHardwarePropTop[];
302   static const char kKeyHardwarePropRight[];
303   static const char kKeyHardwarePropBottom[];
304   static const char kKeyHardwarePropXResolution[];
305   static const char kKeyHardwarePropYResolution[];
306   static const char kKeyHardwarePropXDpi[];
307   static const char kKeyHardwarePropYDpi[];
308   static const char kKeyHardwarePropOrientationMinimum[];
309   static const char kKeyHardwarePropOrientationMaximum[];
310   static const char kKeyHardwarePropMaxFingerCount[];
311   static const char kKeyHardwarePropMaxTouchCount[];
312   static const char kKeyHardwarePropSupportsT5R2[];
313   static const char kKeyHardwarePropSemiMt[];
314   static const char kKeyHardwarePropIsButtonPad[];
315   static const char kKeyHardwarePropHasWheel[];
316 
317   static const char kKeyProperties[];
318 
319   // AccelFilterInterpreter Debug Data keys:
320   static const char kKeyAccelGestureDebug[];
321   static const char kKeyAccelDebugNoAccelBadGain[];
322   static const char kKeyAccelDebugNoAccelGestureType[];
323   static const char kKeyAccelDebugNoAccelSmallDt[];
324   static const char kKeyAccelDebugNoAccelSmallSpeed[];
325   static const char kKeyAccelDebugDroppedGesture[];
326   static const char kKeyAccelDebugXYAreVelocity[];
327   static const char kKeyAccelDebugXScale[];
328   static const char kKeyAccelDebugYScale[];
329   static const char kKeyAccelDebugDt[];
330   static const char kKeyAccelDebugAdjustedDt[];
331   static const char kKeyAccelDebugSpeed[];
332   static const char kKeyAccelDebugSmoothSpeed[];
333   static const char kKeyAccelDebugGainX[];
334   static const char kKeyAccelDebugGainY[];
335 
336   // Timestamp Debug Data keys:
337   static const char kKeyTimestampGestureDebug[];
338   static const char kKeyTimestampHardwareStateDebug[];
339   static const char kKeyTimestampDebugIsUsingFake[];
340   static const char kKeyTimestampDebugWasFirstOrBackward[];
341   static const char kKeyTimestampDebugPrevMscTimestampIn[];
342   static const char kKeyTimestampDebugPrevMscTimestampOut[];
343   static const char kKeyTimestampDebugWasDivergenceReset[];
344   static const char kKeyTimestampDebugFakeTimestampIn[];
345   static const char kKeyTimestampDebugFakeTimestampDelta[];
346   static const char kKeyTimestampDebugFakeTimestampOut[];
347   static const char kKeyTimestampDebugSkew[];
348   static const char kKeyTimestampDebugMaxSkew[];
349 
350  private:
351   // Extends the tail of the buffer by one element and returns that new element.
352   // This may cause an older element to be overwritten if the buffer is full.
353   Entry* PushBack();
354 
TailIdx()355   size_t TailIdx() const { return (head_idx_ + size_ - 1) % kBufferSize; }
356 
357   // JSON-encoders for various types
358   Json::Value EncodeHardwareProperties() const;
359 
360   Json::Value EncodeHardwareStateCommon(const HardwareState& hwstate);
361   Json::Value EncodeHardwareState(const HardwareState& hwstate);
362   Json::Value EncodeHardwareState(const HardwareStatePre& hwstate);
363   Json::Value EncodeHardwareState(const HardwareStatePost& hwstate);
364   Json::Value EncodeHardwareStateDebug(
365       const TimestampHardwareStateDebug& debug_data);
366 
367   Json::Value EncodeTimerCallback(stime_t timestamp);
368   Json::Value EncodeHandleTimer(const HandleTimerPre& handle);
369   Json::Value EncodeHandleTimer(const HandleTimerPost& handle);
370   Json::Value EncodeCallbackRequest(stime_t timestamp);
371 
372   Json::Value EncodeGestureCommon(const Gesture& gesture);
373   Json::Value EncodeGesture(const Gesture& gesture);
374   Json::Value EncodeGesture(const GestureConsume& gesture);
375   Json::Value EncodeGesture(const GestureProduce& gesture);
376   Json::Value EncodeGestureDebug(const AccelGestureDebug& debug_data);
377   Json::Value EncodeGestureDebug(const TimestampGestureDebug& debug_data);
378 
379   Json::Value EncodePropChange(const PropChangeEntry& prop_change);
380 
381   // Encode user-configurable properties
382   Json::Value EncodePropRegistry();
383 
384 #ifdef GESTURES_LARGE_LOGGING_BUFFER
385   static const size_t kBufferSize = 65536;
386 #else
387   static const size_t kBufferSize = 8192;
388 #endif
389 
390   Entry buffer_[kBufferSize];
391   size_t head_idx_;
392   size_t size_;
393 
394   // We allocate this to be number of entries * max fingers/entry, and
395   // if buffer_[i] is a kHardwareState type, then the fingers for it are
396   // at finger_states_[i * (max fingers/entry)].
397   std::unique_ptr<FingerState[]> finger_states_;
398   size_t max_fingers_;
399 
400   HardwareProperties hwprops_;
401   PropRegistry* prop_reg_;
402 };
403 
404 }  // namespace gestures
405 
406 #endif  // GESTURES_ACTIVITY_LOG_H_
407