• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "include/activity_log.h"
6 
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <set>
10 #include <string>
11 #include <sys/stat.h>
12 #include <sys/types.h>
13 
14 #include <json/value.h>
15 #include <json/writer.h>
16 
17 #include "include/file_util.h"
18 #include "include/logging.h"
19 #include "include/prop_registry.h"
20 #include "include/string_util.h"
21 
22 #define QUINTTAP_COUNT 5  /* BTN_TOOL_QUINTTAP - Five fingers on trackpad */
23 
24 using std::set;
25 using std::string;
26 
27 namespace {
28 
29 // Helper to std::visit with lambdas.
30 template <typename... V>
31 struct Visitor : V... {
32   using V::operator()...;
33 };
34 // Explicit deduction guide (not needed as of C++20).
35 template <typename... V>
36 Visitor(V...) -> Visitor<V...>;
37 
38 } // namespace
39 
40 namespace gestures {
41 
ActivityLog(PropRegistry * prop_reg)42 ActivityLog::ActivityLog(PropRegistry* prop_reg)
43     : head_idx_(0), size_(0), max_fingers_(0), hwprops_(),
44       prop_reg_(prop_reg) {}
45 
SetHardwareProperties(const HardwareProperties & hwprops)46 void ActivityLog::SetHardwareProperties(const HardwareProperties& hwprops) {
47   hwprops_ = hwprops;
48 
49   // For old devices(such as mario, alex, zgb..), the reporting touch count
50   // or 'max_touch_cnt' will be less than number of slots or 'max_finger_cnt'
51   // they support. As kernel evdev drivers do not have a bitset to report
52   // touch count greater than five (bitset for five-fingers gesture is
53   // BTN_TOOL_QUINTAP), we respect 'max_finger_cnt' than 'max_touch_cnt'
54   // reported from kernel driver as the 'max_fingers_' instead.
55   if (hwprops.max_touch_cnt < QUINTTAP_COUNT) {
56     max_fingers_ = std::min<size_t>(hwprops.max_finger_cnt,
57                                     hwprops.max_touch_cnt);
58   } else {
59     max_fingers_ = std::max<size_t>(hwprops.max_finger_cnt,
60                                     hwprops.max_touch_cnt);
61   }
62 
63   finger_states_.reset(new FingerState[kBufferSize * max_fingers_]);
64 }
65 
LogHardwareState(const HardwareState & hwstate)66 void ActivityLog::LogHardwareState(const HardwareState& hwstate) {
67   Entry* entry = PushBack();
68   entry->details = hwstate;
69   HardwareState& entry_hwstate = std::get<HardwareState>(entry->details);
70   if (hwstate.finger_cnt > max_fingers_) {
71     Err("Too many fingers! Max is %zu, but I got %d",
72         max_fingers_, hwstate.finger_cnt);
73     entry_hwstate.fingers = nullptr;
74     entry_hwstate.finger_cnt = 0;
75     return;
76   }
77   if (!finger_states_.get())
78     return;
79   entry_hwstate.fingers = &finger_states_[TailIdx() * max_fingers_];
80   std::copy(&hwstate.fingers[0], &hwstate.fingers[hwstate.finger_cnt],
81             entry_hwstate.fingers);
82 }
83 
LogTimerCallback(stime_t now)84 void ActivityLog::LogTimerCallback(stime_t now) {
85   Entry* entry = PushBack();
86   entry->details = TimerCallbackEntry{now};
87 }
88 
LogCallbackRequest(stime_t when)89 void ActivityLog::LogCallbackRequest(stime_t when) {
90   Entry* entry = PushBack();
91   entry->details = CallbackRequestEntry{when};
92 }
93 
LogGesture(const Gesture & gesture)94 void ActivityLog::LogGesture(const Gesture& gesture) {
95   Entry* entry = PushBack();
96   entry->details = gesture;
97 }
98 
LogPropChange(const PropChangeEntry & prop_change)99 void ActivityLog::LogPropChange(const PropChangeEntry& prop_change) {
100   Entry* entry = PushBack();
101   entry->details = prop_change;
102 }
103 
LogGestureConsume(const std::string & name,const Gesture & gesture)104 void ActivityLog::LogGestureConsume(
105     const std::string& name, const Gesture& gesture) {
106   GestureConsume gesture_consume { name, gesture };
107   Entry* entry = PushBack();
108   entry->details = gesture_consume;
109 }
110 
LogGestureProduce(const std::string & name,const Gesture & gesture)111 void ActivityLog::LogGestureProduce(
112     const std::string& name, const Gesture& gesture) {
113   GestureProduce gesture_produce { name, gesture };
114   Entry* entry = PushBack();
115   entry->details = gesture_produce;
116 }
117 
LogHardwareStatePre(const std::string & name,const HardwareState & hwstate)118 void ActivityLog::LogHardwareStatePre(const std::string& name,
119                                       const HardwareState& hwstate) {
120   HardwareStatePre hwstate_pre { name, hwstate };
121   Entry* entry = PushBack();
122   entry->details = hwstate_pre;
123 }
124 
LogHardwareStatePost(const std::string & name,const HardwareState & hwstate)125 void ActivityLog::LogHardwareStatePost(const std::string& name,
126                                        const HardwareState& hwstate) {
127   HardwareStatePost hwstate_post { name, hwstate };
128   Entry* entry = PushBack();
129   entry->details = hwstate_post;
130 }
131 
LogHandleTimerPre(const std::string & name,stime_t now,const stime_t * timeout)132 void ActivityLog::LogHandleTimerPre(const std::string& name,
133                                     stime_t now, const stime_t* timeout) {
134   HandleTimerPre handle;
135   handle.name = name;
136   handle.now = now;
137   handle.timeout_is_present = (timeout != nullptr);
138   handle.timeout = (timeout == nullptr) ? 0 : *timeout;
139   Entry* entry = PushBack();
140   entry->details = handle;
141 }
142 
LogHandleTimerPost(const std::string & name,stime_t now,const stime_t * timeout)143 void ActivityLog::LogHandleTimerPost(const std::string& name,
144                                      stime_t now, const stime_t* timeout) {
145   HandleTimerPost handle;
146   handle.name = name;
147   handle.now = now;
148   handle.timeout_is_present = (timeout != nullptr);
149   handle.timeout = (timeout == nullptr) ? 0 : *timeout;
150   Entry* entry = PushBack();
151   entry->details = handle;
152 }
153 
Dump(const char * filename)154 void ActivityLog::Dump(const char* filename) {
155   string data = Encode();
156   WriteFile(filename, data.c_str(), data.size());
157 }
158 
PushBack()159 ActivityLog::Entry* ActivityLog::PushBack() {
160   if (size_ == kBufferSize) {
161     Entry* ret = &buffer_[head_idx_];
162     head_idx_ = (head_idx_ + 1) % kBufferSize;
163     return ret;
164   }
165   ++size_;
166   return &buffer_[TailIdx()];
167 }
168 
EncodeHardwareProperties() const169 Json::Value ActivityLog::EncodeHardwareProperties() const {
170   Json::Value ret(Json::objectValue);
171   ret[kKeyHardwarePropLeft] = Json::Value(hwprops_.left);
172   ret[kKeyHardwarePropTop] = Json::Value(hwprops_.top);
173   ret[kKeyHardwarePropRight] = Json::Value(hwprops_.right);
174   ret[kKeyHardwarePropBottom] = Json::Value(hwprops_.bottom);
175   ret[kKeyHardwarePropXResolution] = Json::Value(hwprops_.res_x);
176   ret[kKeyHardwarePropYResolution] = Json::Value(hwprops_.res_y);
177   ret[kKeyHardwarePropXDpi] = Json::Value(hwprops_.screen_x_dpi);
178   ret[kKeyHardwarePropYDpi] = Json::Value(hwprops_.screen_y_dpi);
179   ret[kKeyHardwarePropOrientationMinimum] =
180       Json::Value(hwprops_.orientation_minimum);
181   ret[kKeyHardwarePropOrientationMaximum] =
182       Json::Value(hwprops_.orientation_maximum);
183   ret[kKeyHardwarePropMaxFingerCount] = Json::Value(hwprops_.max_finger_cnt);
184   ret[kKeyHardwarePropMaxTouchCount] = Json::Value(hwprops_.max_touch_cnt);
185 
186   ret[kKeyHardwarePropSupportsT5R2] = Json::Value(hwprops_.supports_t5r2 != 0);
187   ret[kKeyHardwarePropSemiMt] = Json::Value(hwprops_.support_semi_mt != 0);
188   ret[kKeyHardwarePropIsButtonPad] = Json::Value(hwprops_.is_button_pad != 0);
189   ret[kKeyHardwarePropHasWheel] = Json::Value(hwprops_.has_wheel != 0);
190   return ret;
191 }
192 
EncodeHardwareStateCommon(const HardwareState & hwstate)193 Json::Value ActivityLog::EncodeHardwareStateCommon(
194     const HardwareState& hwstate) {
195   Json::Value ret(Json::objectValue);
196   ret[kKeyHardwareStateButtonsDown] = Json::Value(hwstate.buttons_down);
197   ret[kKeyHardwareStateTouchCnt] = Json::Value(hwstate.touch_cnt);
198   ret[kKeyHardwareStateTimestamp] = Json::Value(hwstate.timestamp);
199   Json::Value fingers(Json::arrayValue);
200   for (size_t i = 0; i < hwstate.finger_cnt; ++i) {
201     if (hwstate.fingers == nullptr) {
202       Err("Have finger_cnt %d but fingers is null!", hwstate.finger_cnt);
203       break;
204     }
205     const FingerState& fs = hwstate.fingers[i];
206     Json::Value finger(Json::objectValue);
207     finger[kKeyFingerStateTouchMajor] = Json::Value(fs.touch_major);
208     finger[kKeyFingerStateTouchMinor] = Json::Value(fs.touch_minor);
209     finger[kKeyFingerStateWidthMajor] = Json::Value(fs.width_major);
210     finger[kKeyFingerStateWidthMinor] = Json::Value(fs.width_minor);
211     finger[kKeyFingerStatePressure] = Json::Value(fs.pressure);
212     finger[kKeyFingerStateOrientation] = Json::Value(fs.orientation);
213     finger[kKeyFingerStatePositionX] = Json::Value(fs.position_x);
214     finger[kKeyFingerStatePositionY] = Json::Value(fs.position_y);
215     finger[kKeyFingerStateTrackingId] = Json::Value(fs.tracking_id);
216     finger[kKeyFingerStateFlags] = Json::Value(static_cast<int>(fs.flags));
217     fingers.append(finger);
218   }
219   ret[kKeyHardwareStateFingers] = fingers;
220   ret[kKeyHardwareStateRelX] = Json::Value(hwstate.rel_x);
221   ret[kKeyHardwareStateRelY] = Json::Value(hwstate.rel_y);
222   ret[kKeyHardwareStateRelWheel] = Json::Value(hwstate.rel_wheel);
223   ret[kKeyHardwareStateRelHWheel] = Json::Value(hwstate.rel_hwheel);
224   return ret;
225 }
226 
EncodeHardwareState(const HardwareState & hwstate)227 Json::Value ActivityLog::EncodeHardwareState(const HardwareState& hwstate) {
228   auto ret = EncodeHardwareStateCommon(hwstate);
229   ret[kKeyType] = Json::Value(kKeyHardwareState);
230   return ret;
231 }
232 
EncodeHardwareState(const HardwareStatePre & pre_hwstate)233 Json::Value ActivityLog::EncodeHardwareState(
234     const HardwareStatePre& pre_hwstate) {
235   auto ret = EncodeHardwareStateCommon(pre_hwstate.hwstate);
236   ret[kKeyType] = Json::Value(kKeyHardwareStatePre);
237   ret[kKeyMethodName] = Json::Value(pre_hwstate.name);
238   return ret;
239 }
240 
EncodeHardwareState(const HardwareStatePost & post_hwstate)241 Json::Value ActivityLog::EncodeHardwareState(
242     const HardwareStatePost& post_hwstate) {
243   auto ret = EncodeHardwareStateCommon(post_hwstate.hwstate);
244   ret[kKeyType] = Json::Value(kKeyHardwareStatePost);
245   ret[kKeyMethodName] = Json::Value(post_hwstate.name);
246   return ret;
247 }
248 
EncodeHandleTimer(const HandleTimerPre & handle)249 Json::Value ActivityLog::EncodeHandleTimer(const HandleTimerPre& handle) {
250   Json::Value ret(Json::objectValue);
251   ret[kKeyType] = Json::Value(kKeyHandleTimerPre);
252   ret[kKeyMethodName] = Json::Value(handle.name);
253   ret[kKeyTimerNow] = Json::Value(handle.now);
254   if (handle.timeout_is_present)
255     ret[kKeyHandleTimerTimeout] = Json::Value(handle.timeout);
256   return ret;
257 }
258 
EncodeHandleTimer(const HandleTimerPost & handle)259 Json::Value ActivityLog::EncodeHandleTimer(const HandleTimerPost& handle) {
260   Json::Value ret(Json::objectValue);
261   ret[kKeyType] = Json::Value(kKeyHandleTimerPost);
262   ret[kKeyMethodName] = Json::Value(handle.name);
263   ret[kKeyTimerNow] = Json::Value(handle.now);
264   if (handle.timeout_is_present)
265     ret[kKeyHandleTimerTimeout] = Json::Value(handle.timeout);
266   return ret;
267 }
268 
EncodeTimerCallback(stime_t timestamp)269 Json::Value ActivityLog::EncodeTimerCallback(stime_t timestamp) {
270   Json::Value ret(Json::objectValue);
271   ret[kKeyType] = Json::Value(kKeyTimerCallback);
272   ret[kKeyTimerNow] = Json::Value(timestamp);
273   return ret;
274 }
275 
EncodeCallbackRequest(stime_t timestamp)276 Json::Value ActivityLog::EncodeCallbackRequest(stime_t timestamp) {
277   Json::Value ret(Json::objectValue);
278   ret[kKeyType] = Json::Value(kKeyCallbackRequest);
279   ret[kKeyCallbackRequestWhen] = Json::Value(timestamp);
280   return ret;
281 }
282 
EncodeGestureCommon(const Gesture & gesture)283 Json::Value ActivityLog::EncodeGestureCommon(const Gesture& gesture) {
284   Json::Value ret(Json::objectValue);
285   ret[kKeyGestureStartTime] = Json::Value(gesture.start_time);
286   ret[kKeyGestureEndTime] = Json::Value(gesture.end_time);
287 
288   switch (gesture.type) {
289     case kGestureTypeNull:
290       ret[kKeyGestureType] = Json::Value("null");
291       break;
292     case kGestureTypeContactInitiated:
293       ret[kKeyGestureType] = Json::Value(kValueGestureTypeContactInitiated);
294       break;
295     case kGestureTypeMove:
296       ret[kKeyGestureType] = Json::Value(kValueGestureTypeMove);
297       ret[kKeyGestureDX] = Json::Value(gesture.details.move.dx);
298       ret[kKeyGestureDY] = Json::Value(gesture.details.move.dy);
299       ret[kKeyGestureOrdinalDX] = Json::Value(gesture.details.move.ordinal_dx);
300       ret[kKeyGestureOrdinalDY] = Json::Value(gesture.details.move.ordinal_dy);
301       break;
302     case kGestureTypeScroll:
303       ret[kKeyGestureType] = Json::Value(kValueGestureTypeScroll);
304       ret[kKeyGestureDX] = Json::Value(gesture.details.scroll.dx);
305       ret[kKeyGestureDY] = Json::Value(gesture.details.scroll.dy);
306       ret[kKeyGestureOrdinalDX] =
307           Json::Value(gesture.details.scroll.ordinal_dx);
308       ret[kKeyGestureOrdinalDY] =
309           Json::Value(gesture.details.scroll.ordinal_dy);
310       break;
311     case kGestureTypeMouseWheel:
312       ret[kKeyGestureType] = Json::Value(kValueGestureTypeMouseWheel);
313       ret[kKeyGestureDX] = Json::Value(gesture.details.wheel.dx);
314       ret[kKeyGestureDY] = Json::Value(gesture.details.wheel.dy);
315       ret[kKeyGestureMouseWheelTicksDX] =
316           Json::Value(gesture.details.wheel.tick_120ths_dx);
317       ret[kKeyGestureMouseWheelTicksDY] =
318           Json::Value(gesture.details.wheel.tick_120ths_dy);
319       break;
320     case kGestureTypePinch:
321       ret[kKeyGestureType] = Json::Value(kValueGestureTypePinch);
322       ret[kKeyGesturePinchDZ] = Json::Value(gesture.details.pinch.dz);
323       ret[kKeyGesturePinchOrdinalDZ] =
324           Json::Value(gesture.details.pinch.ordinal_dz);
325       ret[kKeyGesturePinchZoomState] =
326           Json::Value(gesture.details.pinch.zoom_state);
327       break;
328     case kGestureTypeButtonsChange:
329       ret[kKeyGestureType] = Json::Value(kValueGestureTypeButtonsChange);
330       ret[kKeyGestureButtonsChangeDown] =
331           Json::Value(static_cast<int>(gesture.details.buttons.down));
332       ret[kKeyGestureButtonsChangeUp] =
333           Json::Value(static_cast<int>(gesture.details.buttons.up));
334       break;
335     case kGestureTypeFling:
336       ret[kKeyGestureType] = Json::Value(kValueGestureTypeFling);
337       ret[kKeyGestureFlingVX] = Json::Value(gesture.details.fling.vx);
338       ret[kKeyGestureFlingVY] = Json::Value(gesture.details.fling.vy);
339       ret[kKeyGestureFlingOrdinalVX] =
340           Json::Value(gesture.details.fling.ordinal_vx);
341       ret[kKeyGestureFlingOrdinalVY] =
342           Json::Value(gesture.details.fling.ordinal_vy);
343       ret[kKeyGestureFlingState] =
344           Json::Value(static_cast<int>(gesture.details.fling.fling_state));
345       break;
346     case kGestureTypeSwipe:
347       ret[kKeyGestureType] = Json::Value(kValueGestureTypeSwipe);
348       ret[kKeyGestureDX] = Json::Value(gesture.details.swipe.dx);
349       ret[kKeyGestureDY] = Json::Value(gesture.details.swipe.dy);
350       ret[kKeyGestureOrdinalDX] =
351           Json::Value(gesture.details.swipe.ordinal_dx);
352       ret[kKeyGestureOrdinalDY] =
353           Json::Value(gesture.details.swipe.ordinal_dy);
354       break;
355     case kGestureTypeSwipeLift:
356       ret[kKeyGestureType] = Json::Value(kValueGestureTypeSwipeLift);
357       break;
358     case kGestureTypeFourFingerSwipe:
359       ret[kKeyGestureType] = Json::Value(kValueGestureTypeFourFingerSwipe);
360       ret[kKeyGestureDX] =
361           Json::Value(gesture.details.four_finger_swipe.dx);
362       ret[kKeyGestureDY] =
363           Json::Value(gesture.details.four_finger_swipe.dy);
364       ret[kKeyGestureOrdinalDX] =
365           Json::Value(gesture.details.four_finger_swipe.ordinal_dx);
366       ret[kKeyGestureOrdinalDY] =
367           Json::Value(gesture.details.four_finger_swipe.ordinal_dy);
368       break;
369     case kGestureTypeFourFingerSwipeLift:
370       ret[kKeyGestureType] = Json::Value(kValueGestureTypeFourFingerSwipeLift);
371       break;
372     case kGestureTypeMetrics:
373       ret[kKeyGestureType] = Json::Value(kValueGestureTypeMetrics);
374       ret[kKeyGestureMetricsType] =
375           Json::Value(static_cast<int>(gesture.details.metrics.type));
376       ret[kKeyGestureMetricsData1] =
377           Json::Value(gesture.details.metrics.data[0]);
378       ret[kKeyGestureMetricsData2] =
379           Json::Value(gesture.details.metrics.data[1]);
380       break;
381     default:
382       ret[kKeyGestureType] =
383           Json::Value(StringPrintf("Unhandled %d", gesture.type));
384   }
385   return ret;
386 }
387 
EncodeGesture(const Gesture & gesture)388 Json::Value ActivityLog::EncodeGesture(const Gesture& gesture) {
389   auto ret = EncodeGestureCommon(gesture);
390   ret[kKeyType] = Json::Value(kKeyGesture);
391   return ret;
392 }
393 
EncodeGesture(const GestureConsume & gesture_consume)394 Json::Value ActivityLog::EncodeGesture(const GestureConsume& gesture_consume) {
395   auto ret = EncodeGestureCommon(gesture_consume.gesture);
396   ret[kKeyType] = Json::Value(kKeyGestureConsume);
397   ret[kKeyMethodName] = Json::Value(gesture_consume.name);
398   return ret;
399 }
400 
EncodeGesture(const GestureProduce & gesture_produce)401 Json::Value ActivityLog::EncodeGesture(const GestureProduce& gesture_produce) {
402   auto ret = EncodeGestureCommon(gesture_produce.gesture);
403   ret[kKeyType] = Json::Value(kKeyGestureProduce);
404   ret[kKeyMethodName] = Json::Value(gesture_produce.name);
405   return ret;
406 }
407 
EncodePropChange(const PropChangeEntry & prop_change)408 Json::Value ActivityLog::EncodePropChange(const PropChangeEntry& prop_change) {
409   Json::Value ret(Json::objectValue);
410   ret[kKeyType] = Json::Value(kKeyPropChange);
411   ret[kKeyPropChangeName] = Json::Value(prop_change.name);
412   Json::Value val;
413   Json::Value type;
414   std::visit(
415     Visitor {
416       [&val, &type](GesturesPropBool value) {
417         val = Json::Value(value);
418         type = Json::Value(kValuePropChangeTypeBool);
419       },
420       [&val, &type](double value) {
421         val = Json::Value(value);
422         type = Json::Value(kValuePropChangeTypeDouble);
423       },
424       [&val, &type](int value) {
425         val = Json::Value(value);
426         type = Json::Value(kValuePropChangeTypeInt);
427       },
428       [&val, &type](short value) {
429         val = Json::Value(value);
430         type = Json::Value(kValuePropChangeTypeShort);
431       },
432       [](auto arg) {
433         Err("Invalid value type");
434       }
435     }, prop_change.value);
436   if (!val.isNull())
437     ret[kKeyPropChangeValue] = val;
438   if (!type.isNull())
439     ret[kKeyPropChangeType] = type;
440   return ret;
441 }
442 
EncodeGestureDebug(const AccelGestureDebug & debug_data)443 Json::Value ActivityLog::EncodeGestureDebug(
444     const AccelGestureDebug& debug_data) {
445   Json::Value ret(Json::objectValue);
446   ret[kKeyType] = Json::Value(kKeyAccelGestureDebug);
447   ret[kKeyAccelDebugDroppedGesture] = Json::Value(debug_data.dropped_gesture);
448   if (debug_data.no_accel_for_gesture_type)
449     ret[kKeyAccelDebugNoAccelGestureType] = Json::Value(true);
450   else if (debug_data.no_accel_for_small_dt)
451     ret[kKeyAccelDebugNoAccelSmallDt] = Json::Value(true);
452   else if (debug_data.no_accel_for_small_speed)
453     ret[kKeyAccelDebugNoAccelSmallSpeed] = Json::Value(true);
454   else if (debug_data.no_accel_for_bad_gain)
455     ret[kKeyAccelDebugNoAccelBadGain] = Json::Value(true);
456   ret[kKeyAccelDebugXYAreVelocity] = Json::Value(debug_data.x_y_are_velocity);
457   ret[kKeyAccelDebugXScale] = Json::Value(debug_data.x_scale);
458   ret[kKeyAccelDebugYScale] = Json::Value(debug_data.y_scale);
459   ret[kKeyAccelDebugDt] = Json::Value(debug_data.dt);
460   ret[kKeyAccelDebugAdjustedDt] = Json::Value(debug_data.adjusted_dt);
461   ret[kKeyAccelDebugSpeed] = Json::Value(debug_data.speed);
462   if (debug_data.speed != debug_data.smoothed_speed)
463     ret[kKeyAccelDebugSmoothSpeed] = Json::Value(debug_data.smoothed_speed);
464   ret[kKeyAccelDebugGainX] = Json::Value(debug_data.gain_x);
465   ret[kKeyAccelDebugGainY] = Json::Value(debug_data.gain_y);
466   return ret;
467 }
468 
EncodeGestureDebug(const TimestampGestureDebug & debug_data)469 Json::Value ActivityLog::EncodeGestureDebug(
470     const TimestampGestureDebug& debug_data) {
471   Json::Value ret(Json::objectValue);
472   ret[kKeyType] = Json::Value(kKeyTimestampGestureDebug);
473   ret[kKeyTimestampDebugSkew] = Json::Value(debug_data.skew);
474   return ret;
475 }
476 
EncodeHardwareStateDebug(const TimestampHardwareStateDebug & debug_data)477 Json::Value ActivityLog::EncodeHardwareStateDebug(
478     const TimestampHardwareStateDebug& debug_data) {
479   Json::Value ret(Json::objectValue);
480   ret[kKeyType] = Json::Value(kKeyTimestampHardwareStateDebug);
481   ret[kKeyTimestampDebugIsUsingFake] = Json::Value(debug_data.is_using_fake);
482   if (debug_data.is_using_fake) {
483     ret[kKeyTimestampDebugWasFirstOrBackward] =
484         Json::Value(debug_data.was_first_or_backward);
485     ret[kKeyTimestampDebugPrevMscTimestampIn] =
486         Json::Value(debug_data.prev_msc_timestamp_in);
487     ret[kKeyTimestampDebugPrevMscTimestampOut] =
488         Json::Value(debug_data.prev_msc_timestamp_out);
489   } else {
490     ret[kKeyTimestampDebugWasDivergenceReset] =
491         Json::Value(debug_data.was_divergence_reset);
492     ret[kKeyTimestampDebugFakeTimestampIn] =
493         Json::Value(debug_data.fake_timestamp_in);
494     ret[kKeyTimestampDebugFakeTimestampDelta] =
495         Json::Value(debug_data.fake_timestamp_delta);
496     ret[kKeyTimestampDebugFakeTimestampOut] =
497         Json::Value(debug_data.fake_timestamp_out);
498   }
499   ret[kKeyTimestampDebugSkew] = Json::Value(debug_data.skew);
500   ret[kKeyTimestampDebugMaxSkew] = Json::Value(debug_data.max_skew);
501   return ret;
502 }
503 
EncodePropRegistry()504 Json::Value ActivityLog::EncodePropRegistry() {
505   Json::Value ret(Json::objectValue);
506   if (!prop_reg_)
507     return ret;
508 
509   const set<Property*>& props = prop_reg_->props();
510   for (set<Property*>::const_iterator it = props.begin(), e = props.end();
511        it != e; ++it) {
512     ret[(*it)->name()] = (*it)->NewValue();
513   }
514   return ret;
515 }
516 
EncodeCommonInfo()517 Json::Value ActivityLog::EncodeCommonInfo() {
518   Json::Value root(Json::objectValue);
519   Json::Value entries(Json::arrayValue);
520   for (size_t i = 0; i < size_; ++i) {
521     const Entry& entry = buffer_[(i + head_idx_) % kBufferSize];
522     std::visit(
523       Visitor {
524         [this, &entries](HardwareState hwstate) {
525           entries.append(EncodeHardwareState(hwstate));
526         },
527         [this, &entries](HardwareStatePre hwstate) {
528           entries.append(EncodeHardwareState(hwstate));
529         },
530         [this, &entries](HardwareStatePost hwstate) {
531           entries.append(EncodeHardwareState(hwstate));
532         },
533         [this, &entries](TimerCallbackEntry now) {
534           entries.append(EncodeTimerCallback(now.timestamp));
535         },
536         [this, &entries](CallbackRequestEntry when) {
537           entries.append(EncodeCallbackRequest(when.timestamp));
538         },
539         [this, &entries](Gesture gesture) {
540           entries.append(EncodeGesture(gesture));
541         },
542         [this, &entries](GestureConsume gesture) {
543           entries.append(EncodeGesture(gesture));
544         },
545         [this, &entries](GestureProduce gesture) {
546           entries.append(EncodeGesture(gesture));
547         },
548         [this, &entries](PropChangeEntry prop_change) {
549           entries.append(EncodePropChange(prop_change));
550         },
551         [this, &entries](HandleTimerPre handle) {
552           entries.append(EncodeHandleTimer(handle));
553         },
554         [this, &entries](HandleTimerPost handle) {
555           entries.append(EncodeHandleTimer(handle));
556         },
557         [this, &entries](AccelGestureDebug debug_data) {
558           entries.append(EncodeGestureDebug(debug_data));
559         },
560         [this, &entries](TimestampGestureDebug debug_data) {
561           entries.append(EncodeGestureDebug(debug_data));
562         },
563         [this, &entries](TimestampHardwareStateDebug debug_data) {
564           entries.append(EncodeHardwareStateDebug(debug_data));
565         },
566         [](auto arg) {
567           Err("Unknown entry type");
568         }
569       }, entry.details);
570   }
571   root[kKeyRoot] = entries;
572   root[kKeyHardwarePropRoot] = EncodeHardwareProperties();
573 
574   return root;
575 }
576 
AddEncodeInfo(Json::Value * root)577 void ActivityLog::AddEncodeInfo(Json::Value* root) {
578   (*root)["version"] = Json::Value(1);
579   string gestures_version = VCSID;
580 
581   // Strip tailing whitespace.
582   gestures_version = TrimWhitespaceASCII(gestures_version);
583   (*root)["gesturesVersion"] = Json::Value(gestures_version);
584   (*root)[kKeyProperties] = EncodePropRegistry();
585 }
586 
Encode()587 string ActivityLog::Encode() {
588   Json::Value root = EncodeCommonInfo();
589   AddEncodeInfo(&root);
590   return root.toStyledString();
591 }
592 
593 const char ActivityLog::kKeyInterpreterName[] = "interpreterName";
594 const char ActivityLog::kKeyNext[] = "nextLayer";
595 const char ActivityLog::kKeyRoot[] = "entries";
596 const char ActivityLog::kKeyType[] = "type";
597 const char ActivityLog::kKeyMethodName[] = "methodName";
598 const char ActivityLog::kKeyHardwareState[] = "hardwareState";
599 const char ActivityLog::kKeyHardwareStatePre[] = "debugHardwareStatePre";
600 const char ActivityLog::kKeyHardwareStatePost[] = "debugHardwareStatePost";
601 const char ActivityLog::kKeyTimerCallback[] = "timerCallback";
602 const char ActivityLog::kKeyCallbackRequest[] = "callbackRequest";
603 const char ActivityLog::kKeyGesture[] = "gesture";
604 const char ActivityLog::kKeyGestureConsume[] = "debugGestureConsume";
605 const char ActivityLog::kKeyGestureProduce[] = "debugGestureProduce";
606 const char ActivityLog::kKeyHandleTimerPre[] = "debugHandleTimerPre";
607 const char ActivityLog::kKeyHandleTimerPost[] = "debugHandleTimerPost";
608 const char ActivityLog::kKeyTimerNow[] = "now";
609 const char ActivityLog::kKeyHandleTimerTimeout[] = "timeout";
610 const char ActivityLog::kKeyPropChange[] = "propertyChange";
611 const char ActivityLog::kKeyHardwareStateTimestamp[] = "timestamp";
612 const char ActivityLog::kKeyHardwareStateButtonsDown[] = "buttonsDown";
613 const char ActivityLog::kKeyHardwareStateTouchCnt[] = "touchCount";
614 const char ActivityLog::kKeyHardwareStateFingers[] = "fingers";
615 const char ActivityLog::kKeyHardwareStateRelX[] = "relX";
616 const char ActivityLog::kKeyHardwareStateRelY[] = "relY";
617 const char ActivityLog::kKeyHardwareStateRelWheel[] = "relWheel";
618 const char ActivityLog::kKeyHardwareStateRelHWheel[] = "relHWheel";
619 const char ActivityLog::kKeyFingerStateTouchMajor[] = "touchMajor";
620 const char ActivityLog::kKeyFingerStateTouchMinor[] = "touchMinor";
621 const char ActivityLog::kKeyFingerStateWidthMajor[] = "widthMajor";
622 const char ActivityLog::kKeyFingerStateWidthMinor[] = "widthMinor";
623 const char ActivityLog::kKeyFingerStatePressure[] = "pressure";
624 const char ActivityLog::kKeyFingerStateOrientation[] = "orientation";
625 const char ActivityLog::kKeyFingerStatePositionX[] = "positionX";
626 const char ActivityLog::kKeyFingerStatePositionY[] = "positionY";
627 const char ActivityLog::kKeyFingerStateTrackingId[] = "trackingId";
628 const char ActivityLog::kKeyFingerStateFlags[] = "flags";
629 const char ActivityLog::kKeyCallbackRequestWhen[] = "when";
630 const char ActivityLog::kKeyGestureType[] = "gestureType";
631 const char ActivityLog::kValueGestureTypeContactInitiated[] =
632     "contactInitiated";
633 const char ActivityLog::kValueGestureTypeMove[] = "move";
634 const char ActivityLog::kValueGestureTypeScroll[] = "scroll";
635 const char ActivityLog::kValueGestureTypeMouseWheel[] = "mouseWheel";
636 const char ActivityLog::kValueGestureTypePinch[] = "pinch";
637 const char ActivityLog::kValueGestureTypeButtonsChange[] = "buttonsChange";
638 const char ActivityLog::kValueGestureTypeFling[] = "fling";
639 const char ActivityLog::kValueGestureTypeSwipe[] = "swipe";
640 const char ActivityLog::kValueGestureTypeSwipeLift[] = "swipeLift";
641 const char ActivityLog::kValueGestureTypeFourFingerSwipe[] = "fourFingerSwipe";
642 const char ActivityLog::kValueGestureTypeFourFingerSwipeLift[] =
643     "fourFingerSwipeLift";
644 const char ActivityLog::kValueGestureTypeMetrics[] = "metrics";
645 const char ActivityLog::kKeyGestureStartTime[] = "startTime";
646 const char ActivityLog::kKeyGestureEndTime[] = "endTime";
647 const char ActivityLog::kKeyGestureDX[] = "dx";
648 const char ActivityLog::kKeyGestureDY[] = "dy";
649 const char ActivityLog::kKeyGestureOrdinalDX[] = "ordinalDx";
650 const char ActivityLog::kKeyGestureOrdinalDY[] = "ordinalDy";
651 const char ActivityLog::kKeyGestureMouseWheelTicksDX[] = "ticksDx";
652 const char ActivityLog::kKeyGestureMouseWheelTicksDY[] = "ticksDy";
653 const char ActivityLog::kKeyGesturePinchDZ[] = "dz";
654 const char ActivityLog::kKeyGesturePinchOrdinalDZ[] = "ordinalDz";
655 const char ActivityLog::kKeyGesturePinchZoomState[] = "zoomState";
656 const char ActivityLog::kKeyGestureButtonsChangeDown[] = "down";
657 const char ActivityLog::kKeyGestureButtonsChangeUp[] = "up";
658 const char ActivityLog::kKeyGestureFlingVX[] = "vx";
659 const char ActivityLog::kKeyGestureFlingVY[] = "vy";
660 const char ActivityLog::kKeyGestureFlingOrdinalVX[] = "ordinalVx";
661 const char ActivityLog::kKeyGestureFlingOrdinalVY[] = "ordinalVy";
662 const char ActivityLog::kKeyGestureFlingState[] = "flingState";
663 const char ActivityLog::kKeyGestureMetricsType[] = "metricsType";
664 const char ActivityLog::kKeyGestureMetricsData1[] = "data1";
665 const char ActivityLog::kKeyGestureMetricsData2[] = "data2";
666 const char ActivityLog::kKeyPropChangeType[] = "propChangeType";
667 const char ActivityLog::kKeyPropChangeName[] = "name";
668 const char ActivityLog::kKeyPropChangeValue[] = "value";
669 const char ActivityLog::kValuePropChangeTypeBool[] = "bool";
670 const char ActivityLog::kValuePropChangeTypeDouble[] = "double";
671 const char ActivityLog::kValuePropChangeTypeInt[] = "int";
672 const char ActivityLog::kValuePropChangeTypeShort[] = "short";
673 const char ActivityLog::kKeyHardwarePropRoot[] = "hardwareProperties";
674 const char ActivityLog::kKeyHardwarePropLeft[] = "left";
675 const char ActivityLog::kKeyHardwarePropTop[] = "top";
676 const char ActivityLog::kKeyHardwarePropRight[] = "right";
677 const char ActivityLog::kKeyHardwarePropBottom[] = "bottom";
678 const char ActivityLog::kKeyHardwarePropXResolution[] = "xResolution";
679 const char ActivityLog::kKeyHardwarePropYResolution[] = "yResolution";
680 const char ActivityLog::kKeyHardwarePropXDpi[] = "xDpi";
681 const char ActivityLog::kKeyHardwarePropYDpi[] = "yDpi";
682 const char ActivityLog::kKeyHardwarePropOrientationMinimum[] =
683     "orientationMinimum";
684 const char ActivityLog::kKeyHardwarePropOrientationMaximum[] =
685     "orientationMaximum";
686 const char ActivityLog::kKeyHardwarePropMaxFingerCount[] = "maxFingerCount";
687 const char ActivityLog::kKeyHardwarePropMaxTouchCount[] = "maxTouchCount";
688 const char ActivityLog::kKeyHardwarePropSupportsT5R2[] = "supportsT5R2";
689 const char ActivityLog::kKeyHardwarePropSemiMt[] = "semiMt";
690 const char ActivityLog::kKeyHardwarePropIsButtonPad[] = "isButtonPad";
691 const char ActivityLog::kKeyHardwarePropHasWheel[] = "hasWheel";
692 
693 const char ActivityLog::kKeyProperties[] = "properties";
694 
695 const char ActivityLog::kKeyAccelGestureDebug[] = "debugAccelGesture";
696 const char ActivityLog::kKeyAccelDebugNoAccelBadGain[] = "noAccelBadGain";
697 const char ActivityLog::kKeyAccelDebugNoAccelGestureType[] = "noAccelBadType";
698 const char ActivityLog::kKeyAccelDebugNoAccelSmallDt[] = "noAccelSmallDt";
699 const char ActivityLog::kKeyAccelDebugNoAccelSmallSpeed[] =
700     "noAccelSmallSpeed";
701 const char ActivityLog::kKeyAccelDebugDroppedGesture[] = "gestureDropped";
702 const char ActivityLog::kKeyAccelDebugXYAreVelocity[] = "XYAreVelocity";
703 const char ActivityLog::kKeyAccelDebugXScale[] = "XScale";
704 const char ActivityLog::kKeyAccelDebugYScale[] = "YScale";
705 const char ActivityLog::kKeyAccelDebugDt[] = "dt";
706 const char ActivityLog::kKeyAccelDebugAdjustedDt[] = "adjDt";
707 const char ActivityLog::kKeyAccelDebugSpeed[] = "speed";
708 const char ActivityLog::kKeyAccelDebugSmoothSpeed[] = "smoothSpeed";
709 const char ActivityLog::kKeyAccelDebugGainX[] = "gainX";
710 const char ActivityLog::kKeyAccelDebugGainY[] = "gainY";
711 
712 const char ActivityLog::kKeyTimestampGestureDebug[] = "debugTimestampGesture";
713 const char ActivityLog::kKeyTimestampHardwareStateDebug[] =
714     "debugTimestampHardwareState";
715 const char ActivityLog::kKeyTimestampDebugIsUsingFake[] = "isUsingFake";
716 const char ActivityLog::kKeyTimestampDebugWasFirstOrBackward[] =
717     "wasFirstOrBackward";
718 const char ActivityLog::kKeyTimestampDebugPrevMscTimestampIn[] =
719     "prevMscTimestampIn";
720 const char ActivityLog::kKeyTimestampDebugPrevMscTimestampOut[] =
721     "prevMscTimestampOut";
722 const char ActivityLog::kKeyTimestampDebugWasDivergenceReset[] =
723     "wasDivergenceReset";
724 const char ActivityLog::kKeyTimestampDebugFakeTimestampIn[] =
725     "fakeTimestampIn";
726 const char ActivityLog::kKeyTimestampDebugFakeTimestampDelta[] =
727     "fakeTimestampDelta";
728 const char ActivityLog::kKeyTimestampDebugFakeTimestampOut[] =
729     "fakeTimestampOut";
730 const char ActivityLog::kKeyTimestampDebugSkew[] = "skew";
731 const char ActivityLog::kKeyTimestampDebugMaxSkew[] = "maxSkew";
732 
733 }  // namespace gestures
734