blob: 68a00043579f7954a8a9e3c17095d77fc7eff684 [file] [log] [blame]
// 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/macros.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::Callback<void(const std::string&)>;
Clock* clock_for_test() { return clock_.get(); }
// Sets an alternate callback to be run to log messages.
void SetLogCallbackForTest(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.
bool TriggerStoppedTimerForTest() WARN_UNUSED_RESULT;
bool TriggerOngoingTimerForTest() WARN_UNUSED_RESULT;
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_