| // Copyright 2016 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef POWER_MANAGER_COMMON_ACTIVITY_LOGGER_H_ |
| #define POWER_MANAGER_COMMON_ACTIVITY_LOGGER_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include <base/callback.h> |
| #include <base/time/time.h> |
| #include <base/timer/timer.h> |
| |
| namespace power_manager { |
| |
| class Clock; |
| |
| // Non-instantiatable base class for logging activity. This contains members and |
| // testing code shared by all implementations. |
| class BaseActivityLogger { |
| public: |
| // Logging callback that can be replaced for testing. |
| using LogCallback = base::RepeatingCallback<void(const std::string&)>; |
| |
| Clock* clock_for_test() { return clock_.get(); } |
| |
| // Sets an alternate callback to be run to log messages. |
| void SetLogCallbackForTest(const LogCallback& callback); |
| |
| // Returns the current delays of timers or empty deltas if they're stopped. |
| base::TimeDelta GetStoppedTimerDelayForTest() const; |
| base::TimeDelta GetOngoingTimerDelayForTest() const; |
| |
| // Triggers timers and returns true if they're running. Returns false if they |
| // aren't. |
| [[nodiscard]] bool TriggerStoppedTimerForTest(); |
| [[nodiscard]] bool TriggerOngoingTimerForTest(); |
| |
| protected: |
| BaseActivityLogger(const std::string& activity_name, |
| base::TimeDelta stopped_delay, |
| base::TimeDelta ongoing_interval); |
| BaseActivityLogger(const BaseActivityLogger&) = delete; |
| BaseActivityLogger& operator=(const BaseActivityLogger&) = delete; |
| |
| virtual ~BaseActivityLogger(); |
| |
| // Returns a string of the format "0.5 sec ago" describing how long ago |
| // |timestamp| occurred (compared to |clock_|'s idea of "now"). |
| std::string GetDelaySuffix(base::TimeTicks timestamp) const; |
| |
| // Callback used to log messages. |
| LogCallback log_callback_; |
| |
| const std::unique_ptr<Clock> clock_; |
| |
| // String describing the type of activity being tracked. |
| const std::string activity_name_; |
| |
| // Delay after the cessation of activity before logging that it's stopped. |
| const base::TimeDelta stopped_delay_; |
| |
| // Interval for logging activity periodically. |
| base::TimeDelta ongoing_interval_; |
| |
| // Used to log the cessation of activity and ongoing activity, respectively. |
| base::OneShotTimer stopped_timer_; |
| base::RepeatingTimer ongoing_timer_; |
| }; |
| |
| // PeriodicActivityLogger should be used for activity that is reported to powerd |
| // periodically, e.g. user or video activity (each reported every five seconds |
| // by Chrome while ongoing). |
| // |
| // It allows setting a "stopped delay" describing how long after the last report |
| // activity should be considered active (typically slightly longer than the |
| // interval with which reports are received) and an "ongoing interval" to log |
| // periodic messages while activity remains active. |
| // |
| // For example, with 5-second reporting interval, a stopped delay of 7 seconds, |
| // and an ongoing interval of 22 seconds: |
| // |
| // :00 reported -> "activity reported" |
| // :05 reported |
| // :10 reported |
| // :15 reported |
| // :20 reported |
| // :22 -> "activity ongoing; last reported 2 sec ago" |
| // :25 reported |
| // :32 -> "activity stopped; last reported 7 sec ago" |
| // :40 reported -> "activity reported" |
| class PeriodicActivityLogger : public BaseActivityLogger { |
| public: |
| // |activity_name| appears at the beginning of messages and describes the |
| // activity, e.g. "User activity" or "Hovering". |
| // |
| // |stopped_delay| contains the duration after a report for which activity |
| // will be considered ongoing. It should be longer than the interval between |
| // reports. |
| // |
| // If |ongoing_interval| is nonzero, a message will be logged periodically |
| // while activity is considered to be ongoing. If provided, it must be greater |
| // than |stopped_delay|. |
| PeriodicActivityLogger(const std::string& activity_name, |
| base::TimeDelta stopped_delay, |
| base::TimeDelta ongoing_interval); |
| PeriodicActivityLogger(const PeriodicActivityLogger&) = delete; |
| PeriodicActivityLogger& operator=(const PeriodicActivityLogger&) = delete; |
| |
| ~PeriodicActivityLogger() override; |
| |
| // Should be called when a periodic report of activity is received. |
| void OnActivityReported(); |
| |
| private: |
| void LogStopped(); |
| void LogOngoing(); |
| |
| // The time at which activity was last reported. Zero if activity hasn't yet |
| // been reported. |
| base::TimeTicks last_report_time_; |
| }; |
| |
| // StartStopActivityLogger should be used for activity that is reported to |
| // powerd via separate "start" and "stop" events, e.g. audio activity (reported |
| // by CRAS as changes to the number of active audio streams). |
| // |
| // It allows setting a "stopped delay" to suppress excess logging for activity |
| // that frequently starts and stops and an "ongoing interval" to log periodic |
| // messages while activity remains active. |
| // |
| // For example, with a stopped delay of 5 seconds and an ongoing interval of 10 |
| // seconds: |
| // |
| // :00 started -> "activity started" |
| // :07 stopped |
| // :10 started |
| // :20 -> "activity ongoing" |
| // :30 -> "activity ongoing" |
| // :35 stopped |
| // :40 -> "activity stopped 5 sec ago" |
| // :42 started -> "activity started" |
| class StartStopActivityLogger : public BaseActivityLogger { |
| public: |
| // |activity_name| appears at the beginning of messages and describes the |
| // activity, e.g. "User activity" or "Hovering". |
| // |
| // If |stopped_delay| is nonzero, it contains a duration after activity stops |
| // during which future state changes will not be logged. If zero, all state |
| // changes will be logged. |
| // |
| // If |ongoing_interval| is nonzero, a message will be logged periodically |
| // while activity is considered to be ongoing. |
| StartStopActivityLogger(const std::string& activity_name, |
| base::TimeDelta stopped_delay, |
| base::TimeDelta ongoing_interval); |
| StartStopActivityLogger(const StartStopActivityLogger&) = delete; |
| StartStopActivityLogger& operator=(const StartStopActivityLogger&) = delete; |
| |
| ~StartStopActivityLogger() override; |
| |
| // Should be called when activity starts or stops. |
| void OnActivityStarted(); |
| void OnActivityStopped(); |
| |
| private: |
| void LogStopped(); |
| void LogOngoing(); |
| |
| // The time at which activity last stopped. Zero if activity is currently |
| // active or never started. |
| base::TimeTicks stopped_time_; |
| }; |
| |
| // OngoingStateActivityLogger periodically logs a caller-provided state. |
| // The state is logged verbatim and can be changed. |
| // |
| // For example, with an ongoing interval of 10 seconds: |
| // |
| // :00 state "a" |
| // :10 -> "a" |
| // :20 -> "a" |
| // :26 state "b" |
| // :30 -> "b" |
| // :33 state "" |
| // :45 state "c" |
| // :55 -> "c" |
| class OngoingStateActivityLogger : public BaseActivityLogger { |
| public: |
| // |ongoing_interval| contains the interval between log messages while |
| // |state_| is non-empty. |
| explicit OngoingStateActivityLogger(base::TimeDelta ongoing_interval); |
| OngoingStateActivityLogger(const OngoingStateActivityLogger&) = delete; |
| OngoingStateActivityLogger& operator=(const OngoingStateActivityLogger&) = |
| delete; |
| |
| ~OngoingStateActivityLogger() override; |
| |
| // Should be called when the state to log has changed. |
| // When |state| transitions from empty to non-empty, a message will be logged |
| // after |ongoing_interval| and then every |ongoing_interval|. |
| // An empty string stops logging. |
| void OnStateChanged(const std::string& state); |
| |
| private: |
| void LogOngoing(); |
| |
| // Current state message to log. |
| std::string state_; |
| }; |
| |
| } // namespace power_manager |
| |
| #endif // POWER_MANAGER_COMMON_ACTIVITY_LOGGER_H_ |