// Copyright 2012 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef GESTURES_ACTIVITY_LOG_H_ #define GESTURES_ACTIVITY_LOG_H_ #include "include/gestures.h" #include #include #include // For FRIEND_TEST #include // 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. namespace gestures { class PropRegistry; class ActivityLog { FRIEND_TEST(ActivityLogTest, SimpleTest); FRIEND_TEST(ActivityLogTest, WrapAroundTest); FRIEND_TEST(ActivityLogTest, VersionTest); FRIEND_TEST(ActivityLogTest, EncodePropChangeBoolTest); 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: struct TimerCallbackEntry { stime_t timestamp; }; struct CallbackRequestEntry { stime_t timestamp; }; struct PropChangeEntry { std::string name; // No string variant because string values can't change std::variant 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 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); void SetHardwareProperties(const HardwareProperties& hwprops); // Log*() functions record an argument into the buffer void LogHardwareState(const HardwareState& hwstate); void LogTimerCallback(stime_t now); void LogCallbackRequest(stime_t when); 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 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; } // Returns a JSON string representing all the state in the buffer std::string Encode(); void AddEncodeInfo(Json::Value* root); Json::Value EncodeCommonInfo(); size_t size() const { return size_; } size_t MaxSize() const { return kBufferSize; } Entry* GetEntry(size_t idx) { return &buffer_[(head_idx_ + idx) % kBufferSize]; } static const char kKeyInterpreterName[]; 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[]; static const char kKeyHardwareStateTouchCnt[]; static const char kKeyHardwareStateFingers[]; static const char kKeyHardwareStateRelX[]; static const char kKeyHardwareStateRelY[]; static const char kKeyHardwareStateRelWheel[]; static const char kKeyHardwareStateRelHWheel[]; // FingerState keys (part of HardwareState): static const char kKeyFingerStateTouchMajor[]; static const char kKeyFingerStateTouchMinor[]; static const char kKeyFingerStateWidthMajor[]; static const char kKeyFingerStateWidthMinor[]; static const char kKeyFingerStatePressure[]; static const char kKeyFingerStateOrientation[]; static const char kKeyFingerStatePositionX[]; static const char kKeyFingerStatePositionY[]; static const char kKeyFingerStateTrackingId[]; static const char kKeyFingerStateFlags[]; // Timer/Callback keys: static const char kKeyTimerNow[]; static const char kKeyHandleTimerTimeout[]; static const char kKeyCallbackRequestWhen[]; // Gesture keys: static const char kKeyGestureType[]; static const char kValueGestureTypeContactInitiated[]; static const char kValueGestureTypeMove[]; static const char kValueGestureTypeScroll[]; static const char kValueGestureTypeMouseWheel[]; static const char kValueGestureTypePinch[]; static const char kValueGestureTypeButtonsChange[]; static const char kValueGestureTypeFling[]; static const char kValueGestureTypeSwipe[]; static const char kValueGestureTypeSwipeLift[]; static const char kValueGestureTypeFourFingerSwipe[]; static const char kValueGestureTypeFourFingerSwipeLift[]; static const char kValueGestureTypeMetrics[]; static const char kKeyGestureStartTime[]; static const char kKeyGestureEndTime[]; 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[]; static const char kKeyGesturePinchOrdinalDZ[]; static const char kKeyGesturePinchZoomState[]; static const char kKeyGestureButtonsChangeDown[]; static const char kKeyGestureButtonsChangeUp[]; static const char kKeyGestureFlingVX[]; static const char kKeyGestureFlingVY[]; static const char kKeyGestureFlingOrdinalVX[]; static const char kKeyGestureFlingOrdinalVY[]; static const char kKeyGestureFlingState[]; static const char kKeyGestureMetricsType[]; static const char kKeyGestureMetricsData1[]; static const char kKeyGestureMetricsData2[]; // PropChange keys: static const char kKeyPropChangeType[]; static const char kKeyPropChangeName[]; static const char kKeyPropChangeValue[]; static const char kValuePropChangeTypeBool[]; static const char kValuePropChangeTypeDouble[]; static const char kValuePropChangeTypeInt[]; static const char kValuePropChangeTypeShort[]; // Hardware Properties keys: static const char kKeyHardwarePropRoot[]; static const char kKeyHardwarePropLeft[]; static const char kKeyHardwarePropTop[]; static const char kKeyHardwarePropRight[]; static const char kKeyHardwarePropBottom[]; static const char kKeyHardwarePropXResolution[]; static const char kKeyHardwarePropYResolution[]; static const char kKeyHardwarePropXDpi[]; static const char kKeyHardwarePropYDpi[]; static const char kKeyHardwarePropOrientationMinimum[]; static const char kKeyHardwarePropOrientationMaximum[]; static const char kKeyHardwarePropMaxFingerCount[]; static const char kKeyHardwarePropMaxTouchCount[]; static const char kKeyHardwarePropSupportsT5R2[]; static const char kKeyHardwarePropSemiMt[]; static const char kKeyHardwarePropIsButtonPad[]; static const char kKeyHardwarePropHasWheel[]; 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. Entry* PushBack(); size_t TailIdx() const { return (head_idx_ + size_ - 1) % kBufferSize; } // 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 Json::Value EncodePropRegistry(); #ifdef GESTURES_LARGE_LOGGING_BUFFER static const size_t kBufferSize = 65536; #else static const size_t kBufferSize = 8192; #endif Entry buffer_[kBufferSize]; size_t head_idx_; size_t size_; // We allocate this to be number of entries * max fingers/entry, and // if buffer_[i] is a kHardwareState type, then the fingers for it are // at finger_states_[i * (max fingers/entry)]. std::unique_ptr finger_states_; size_t max_fingers_; HardwareProperties hwprops_; PropRegistry* prop_reg_; }; } // namespace gestures #endif // GESTURES_ACTIVITY_LOG_H_