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