blob: f98c34c4f77b7673c3dbd836c8bedaeac56b7ab8 [file] [log] [blame]
Darin Petkov65b01462010-04-14 13:32:20 -07001// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
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 METRICS_DAEMON_H_
6#define METRICS_DAEMON_H_
7
Darin Petkov703ec972010-04-27 11:02:18 -07008#include <dbus/dbus.h>
Darin Petkov41e06232010-05-03 16:45:37 -07009#include <glib.h>
Darin Petkov65b01462010-04-14 13:32:20 -070010
Darin Petkovf1e85e42010-06-10 15:59:53 -070011#include <base/scoped_ptr.h>
12#include <base/time.h>
13#include <gtest/gtest_prod.h> // for FRIEND_TEST
14
Darin Petkovfc91b422010-05-12 13:05:45 -070015#include "metrics_library.h"
16
Ken Mixterccd84c02010-08-16 19:57:13 -070017namespace chromeos_metrics {
18class FrequencyCounter;
19class TaggedCounterInterface;
20}
Darin Petkov2ccef012010-05-05 16:06:37 -070021
Darin Petkov65b01462010-04-14 13:32:20 -070022class MetricsDaemon {
23
24 public:
Darin Petkovf1e85e42010-06-10 15:59:53 -070025 MetricsDaemon();
26 ~MetricsDaemon();
Darin Petkov65b01462010-04-14 13:32:20 -070027
Darin Petkov11b8eb32010-05-18 11:00:59 -070028 // Initializes.
29 void Init(bool testing, MetricsLibraryInterface* metrics_lib);
30
Darin Petkov703ec972010-04-27 11:02:18 -070031 // Does all the work. If |run_as_daemon| is true, daemonizes by
Darin Petkov2ccef012010-05-05 16:06:37 -070032 // forking.
33 void Run(bool run_as_daemon);
Darin Petkov65b01462010-04-14 13:32:20 -070034
35 private:
Darin Petkov2ccef012010-05-05 16:06:37 -070036 friend class MetricsDaemonTest;
Ken Mixterccd84c02010-08-16 19:57:13 -070037 FRIEND_TEST(MetricsDaemonTest, CheckSystemCrash);
Darin Petkov2ccef012010-05-05 16:06:37 -070038 FRIEND_TEST(MetricsDaemonTest, LookupNetworkState);
39 FRIEND_TEST(MetricsDaemonTest, LookupPowerState);
40 FRIEND_TEST(MetricsDaemonTest, LookupScreenSaverState);
41 FRIEND_TEST(MetricsDaemonTest, LookupSessionState);
Darin Petkove579d662010-05-05 16:19:39 -070042 FRIEND_TEST(MetricsDaemonTest, MessageFilter);
Darin Petkovfc91b422010-05-12 13:05:45 -070043 FRIEND_TEST(MetricsDaemonTest, NetStateChangedSimpleDrop);
44 FRIEND_TEST(MetricsDaemonTest, NetStateChangedSuspend);
Darin Petkov2ccef012010-05-05 16:06:37 -070045 FRIEND_TEST(MetricsDaemonTest, PowerStateChanged);
Darin Petkov38d5cb02010-06-24 12:10:26 -070046 FRIEND_TEST(MetricsDaemonTest, ProcessKernelCrash);
Ken Mixterccd84c02010-08-16 19:57:13 -070047 FRIEND_TEST(MetricsDaemonTest, ProcessUncleanShutdown);
Darin Petkov1bb904e2010-06-16 15:58:06 -070048 FRIEND_TEST(MetricsDaemonTest, ProcessUserCrash);
Ken Mixterccd84c02010-08-16 19:57:13 -070049 FRIEND_TEST(MetricsDaemonTest, ReportCrashesDailyFrequency);
50 FRIEND_TEST(MetricsDaemonTest, ReportDailyUse);
51 FRIEND_TEST(MetricsDaemonTest, ReportKernelCrashInterval);
52 FRIEND_TEST(MetricsDaemonTest, ReportUncleanShutdownInterval);
53 FRIEND_TEST(MetricsDaemonTest, ReportUserCrashInterval);
Darin Petkov2ccef012010-05-05 16:06:37 -070054 FRIEND_TEST(MetricsDaemonTest, ScreenSaverStateChanged);
Darin Petkov11b8eb32010-05-18 11:00:59 -070055 FRIEND_TEST(MetricsDaemonTest, SendMetric);
Darin Petkov2ccef012010-05-05 16:06:37 -070056 FRIEND_TEST(MetricsDaemonTest, SessionStateChanged);
Darin Petkovf1e85e42010-06-10 15:59:53 -070057 FRIEND_TEST(MetricsDaemonTest, SetUserActiveState);
Darin Petkovf27f0362010-06-04 13:14:19 -070058 FRIEND_TEST(MetricsDaemonTest, SetUserActiveStateTimeJump);
Darin Petkov2ccef012010-05-05 16:06:37 -070059
Darin Petkov703ec972010-04-27 11:02:18 -070060 // The network states (see network_states.h).
61 enum NetworkState {
62 kUnknownNetworkState = -1, // Initial/unknown network state.
Darin Petkov65b01462010-04-14 13:32:20 -070063#define STATE(name, capname) kNetworkState ## capname,
64#include "network_states.h"
65 kNumberNetworkStates
Darin Petkov703ec972010-04-27 11:02:18 -070066 };
Darin Petkov65b01462010-04-14 13:32:20 -070067
Darin Petkov703ec972010-04-27 11:02:18 -070068 // The power states (see power_states.h).
69 enum PowerState {
70 kUnknownPowerState = -1, // Initial/unknown power state.
71#define STATE(name, capname) kPowerState ## capname,
72#include "power_states.h"
73 kNumberPowerStates
74 };
Darin Petkov65b01462010-04-14 13:32:20 -070075
Darin Petkov41e06232010-05-03 16:45:37 -070076 // The user session states (see session_states.h).
77 enum SessionState {
78 kUnknownSessionState = -1, // Initial/unknown user session state.
79#define STATE(name, capname) kSessionState ## capname,
80#include "session_states.h"
81 kNumberSessionStates
82 };
83
84 // Data record for aggregating daily usage.
85 class UseRecord {
86 public:
87 UseRecord() : day_(0), seconds_(0) {}
88 int day_;
89 int seconds_;
90 };
91
Darin Petkov2ccef012010-05-05 16:06:37 -070092 // Metric parameters.
Ken Mixterccd84c02010-08-16 19:57:13 -070093 static const char kMetricAnyCrashesDailyName[];
94 static const char kMetricCrashesDailyBuckets;
95 static const char kMetricCrashesDailyMax;
96 static const char kMetricCrashesDailyMin;
97 static const int kMetricCrashIntervalBuckets;
98 static const int kMetricCrashIntervalMax;
99 static const int kMetricCrashIntervalMin;
100 static const int kMetricDailyUseTimeBuckets;
101 static const int kMetricDailyUseTimeMax;
102 static const int kMetricDailyUseTimeMin;
Darin Petkov2ccef012010-05-05 16:06:37 -0700103 static const char kMetricDailyUseTimeName[];
Ken Mixterccd84c02010-08-16 19:57:13 -0700104 static const char kMetricKernelCrashesDailyName[];
Darin Petkov38d5cb02010-06-24 12:10:26 -0700105 static const char kMetricKernelCrashIntervalName[];
Ken Mixterccd84c02010-08-16 19:57:13 -0700106 static const int kMetricTimeToNetworkDropBuckets;
107 static const int kMetricTimeToNetworkDropMax;
108 static const int kMetricTimeToNetworkDropMin;
Darin Petkov2ccef012010-05-05 16:06:37 -0700109 static const char kMetricTimeToNetworkDropName[];
Ken Mixterccd84c02010-08-16 19:57:13 -0700110 static const char kMetricUncleanShutdownIntervalName[];
111 static const char kMetricUncleanShutdownsDailyName[];
112 static const char kMetricUserCrashesDailyName[];
Darin Petkov1bb904e2010-06-16 15:58:06 -0700113 static const char kMetricUserCrashIntervalName[];
Darin Petkov2ccef012010-05-05 16:06:37 -0700114
Darin Petkov41e06232010-05-03 16:45:37 -0700115 // D-Bus message match strings.
116 static const char* kDBusMatches_[];
117
118 // Array of network states.
119 static const char* kNetworkStates_[kNumberNetworkStates];
120
121 // Array of power states.
122 static const char* kPowerStates_[kNumberPowerStates];
123
Darin Petkov41e06232010-05-03 16:45:37 -0700124 // Array of user session states.
125 static const char* kSessionStates_[kNumberSessionStates];
126
Darin Petkov65b01462010-04-14 13:32:20 -0700127 // Creates the event loop and enters it.
128 void Loop();
129
Darin Petkov703ec972010-04-27 11:02:18 -0700130 // D-Bus filter callback.
131 static DBusHandlerResult MessageFilter(DBusConnection* connection,
132 DBusMessage* message,
133 void* user_data);
Darin Petkov65b01462010-04-14 13:32:20 -0700134
Darin Petkov703ec972010-04-27 11:02:18 -0700135 // Processes network state change.
Darin Petkovf27f0362010-06-04 13:14:19 -0700136 void NetStateChanged(const char* state_name, base::TimeTicks ticks);
Darin Petkov65b01462010-04-14 13:32:20 -0700137
Darin Petkov703ec972010-04-27 11:02:18 -0700138 // Given the state name, returns the state id.
139 NetworkState LookupNetworkState(const char* state_name);
Darin Petkov65b01462010-04-14 13:32:20 -0700140
Darin Petkov703ec972010-04-27 11:02:18 -0700141 // Processes power state change.
Darin Petkovf27f0362010-06-04 13:14:19 -0700142 void PowerStateChanged(const char* state_name, base::Time now);
Darin Petkov703ec972010-04-27 11:02:18 -0700143
144 // Given the state name, returns the state id.
145 PowerState LookupPowerState(const char* state_name);
Darin Petkov65b01462010-04-14 13:32:20 -0700146
Darin Petkov41e06232010-05-03 16:45:37 -0700147 // Processes user session state change.
Darin Petkovf27f0362010-06-04 13:14:19 -0700148 void SessionStateChanged(const char* state_name, base::Time now);
Darin Petkov41e06232010-05-03 16:45:37 -0700149
150 // Given the state name, returns the state id.
151 SessionState LookupSessionState(const char* state_name);
152
153 // Updates the user-active state to |active| and logs the usage data
154 // since the last update. If the user has just become active,
155 // reschedule the daily use monitor for more frequent updates --
156 // this is followed by an exponential back-off (see UseMonitor).
Darin Petkovf27f0362010-06-04 13:14:19 -0700157 // While in active use, this method should be called at intervals no
158 // longer than kUseMonitorIntervalMax otherwise new use time will be
159 // discarded.
160 void SetUserActiveState(bool active, base::Time now);
Darin Petkov41e06232010-05-03 16:45:37 -0700161
162 // Updates the daily usage file, if necessary, by adding |seconds|
163 // of active use to the |day| since Epoch. If there's usage data for
164 // day in the past in the usage file, that data is sent to UMA and
165 // removed from the file. If there's already usage data for |day| in
166 // the usage file, the |seconds| are accumulated.
167 void LogDailyUseRecord(int day, int seconds);
168
Darin Petkov1bb904e2010-06-16 15:58:06 -0700169 // Updates the active use time and logs time between user-space
170 // process crashes.
171 void ProcessUserCrash();
172
Darin Petkov38d5cb02010-06-24 12:10:26 -0700173 // Updates the active use time and logs time between kernel crashes.
174 void ProcessKernelCrash();
175
Ken Mixterccd84c02010-08-16 19:57:13 -0700176 // Updates the active use time and logs time between unclean shutdowns.
177 void ProcessUncleanShutdown();
178
179 // Checks if a kernel crash has been detected and returns true if
180 // so. The method assumes that a kernel crash has happened if
181 // |crash_file| exists. It removes the file immediately if it
182 // exists, so it must not be called more than once.
183 bool CheckSystemCrash(const std::string& crash_file);
Darin Petkov38d5cb02010-06-24 12:10:26 -0700184
Darin Petkov41e06232010-05-03 16:45:37 -0700185 // Callbacks for the daily use monitor. The daily use monitor uses
186 // LogDailyUseRecord to aggregate current usage data and send it to
187 // UMA, if necessary. It also reschedules itself using an
188 // exponentially bigger interval (up to a certain maximum) -- so
189 // usage is monitored less frequently with longer active use.
190 static gboolean UseMonitorStatic(gpointer data);
191 bool UseMonitor();
192
193 // Schedules or reschedules a daily use monitor for |interval|
194 // seconds from now. |backoff| mode is used by the use monitor to
195 // reschedule itself. If there's a monitor scheduled already and
196 // |backoff| is false, unschedules it first. Doesn't schedule a
197 // monitor for more than kUseMonitorIntervalMax seconds in the
198 // future (see metrics_daemon.cc). Returns true if a new use monitor
199 // was scheduled, false otherwise (note that if |backoff| is false a
200 // new use monitor will always be scheduled).
201 bool ScheduleUseMonitor(int interval, bool backoff);
202
203 // Unschedules a scheduled use monitor, if any.
204 void UnscheduleUseMonitor();
205
Darin Petkov11b8eb32010-05-18 11:00:59 -0700206 // Sends a regular (exponential) histogram sample to Chrome for
207 // transport to UMA. See MetricsLibrary::SendToUMA in
208 // metrics_library.h for a description of the arguments.
209 void SendMetric(const std::string& name, int sample,
210 int min, int max, int nbuckets);
Darin Petkov65b01462010-04-14 13:32:20 -0700211
Darin Petkov1bb904e2010-06-16 15:58:06 -0700212 // TaggedCounter callback to process aggregated daily usage data and
213 // send to UMA.
Ken Mixterccd84c02010-08-16 19:57:13 -0700214 static void ReportDailyUse(void* data, int tag, int count);
215
216 // Helper to report a crash interval to UMA.
217 static void ReportCrashInterval(const char* histogram_name,
218 void* handle, int count);
Darin Petkovf1e85e42010-06-10 15:59:53 -0700219
Darin Petkov1bb904e2010-06-16 15:58:06 -0700220 // TaggedCounter callback to process time between user-space process
221 // crashes and send to UMA.
Ken Mixterccd84c02010-08-16 19:57:13 -0700222 static void ReportUserCrashInterval(void* data, int tag, int count);
Darin Petkov1bb904e2010-06-16 15:58:06 -0700223
Darin Petkov38d5cb02010-06-24 12:10:26 -0700224 // TaggedCounter callback to process time between kernel crashes and
225 // send to UMA.
Ken Mixterccd84c02010-08-16 19:57:13 -0700226 static void ReportKernelCrashInterval(void* data, int tag, int count);
227
228 // TaggedCounter callback to process time between unclean shutdowns and
229 // send to UMA.
230 static void ReportUncleanShutdownInterval(void* data, int tag, int count);
231
232 // Helper to report a daily crash frequency to UMA.
233 static void ReportCrashesDailyFrequency(const char* histogram_name,
234 void* handle, int count);
235
236 // TaggedCounter callback to report daily crash frequency to UMA.
237 static void ReportUserCrashesDaily(void* handle, int tag, int count);
238
239 // TaggedCounter callback to report kernel crash frequency to UMA.
240 static void ReportKernelCrashesDaily(void* handle, int tag, int count);
241
242 // TaggedCounter callback to report unclean shutdown frequency to UMA.
243 static void ReportUncleanShutdownsDaily(void* handle, int tag, int count);
244
245 // TaggedCounter callback to report frequency of any crashes to UMA.
246 static void ReportAnyCrashesDaily(void* handle, int tag, int count);
Darin Petkov38d5cb02010-06-24 12:10:26 -0700247
Darin Petkov2ccef012010-05-05 16:06:37 -0700248 // Test mode.
Darin Petkov41e06232010-05-03 16:45:37 -0700249 bool testing_;
Darin Petkov65b01462010-04-14 13:32:20 -0700250
Darin Petkovfc91b422010-05-12 13:05:45 -0700251 // The metrics library handle.
252 MetricsLibraryInterface* metrics_lib_;
253
Darin Petkov41e06232010-05-03 16:45:37 -0700254 // Current network state.
255 NetworkState network_state_;
Darin Petkov65b01462010-04-14 13:32:20 -0700256
Darin Petkovf27f0362010-06-04 13:14:19 -0700257 // Timestamps last network state update. This timestamp is used to
258 // sample the time from the network going online to going offline so
259 // TimeTicks ensures a monotonically increasing TimeDelta.
260 base::TimeTicks network_state_last_;
Darin Petkov65b01462010-04-14 13:32:20 -0700261
Darin Petkov41e06232010-05-03 16:45:37 -0700262 // Current power state.
263 PowerState power_state_;
264
Darin Petkov41e06232010-05-03 16:45:37 -0700265 // Current user session state.
266 SessionState session_state_;
267
268 // Is the user currently active: power is on, user session has
269 // started, screen is not locked.
270 bool user_active_;
271
Darin Petkov1bb904e2010-06-16 15:58:06 -0700272 // Timestamps last user active update. Active use time is aggregated
273 // each day before sending to UMA so using time since the epoch as
274 // the timestamp.
Darin Petkovf27f0362010-06-04 13:14:19 -0700275 base::Time user_active_last_;
Darin Petkov41e06232010-05-03 16:45:37 -0700276
Darin Petkov1bb904e2010-06-16 15:58:06 -0700277 // Daily active use time in seconds.
Darin Petkovf1e85e42010-06-10 15:59:53 -0700278 scoped_ptr<chromeos_metrics::TaggedCounterInterface> daily_use_;
Darin Petkov41e06232010-05-03 16:45:37 -0700279
Darin Petkov1bb904e2010-06-16 15:58:06 -0700280 // Active use time between user-space process crashes.
281 scoped_ptr<chromeos_metrics::TaggedCounterInterface> user_crash_interval_;
282
Darin Petkov38d5cb02010-06-24 12:10:26 -0700283 // Active use time between kernel crashes.
284 scoped_ptr<chromeos_metrics::TaggedCounterInterface> kernel_crash_interval_;
285
Ken Mixterccd84c02010-08-16 19:57:13 -0700286 // Active use time between unclean shutdowns crashes.
287 scoped_ptr<chromeos_metrics::TaggedCounterInterface>
288 unclean_shutdown_interval_;
289
290 // Daily count of user-space process crashes.
291 scoped_ptr<chromeos_metrics::FrequencyCounter> user_crashes_daily_;
292
293 // Daily count of kernel crashes.
294 scoped_ptr<chromeos_metrics::FrequencyCounter> kernel_crashes_daily_;
295
296 // Daily count of unclean shutdowns.
297 scoped_ptr<chromeos_metrics::FrequencyCounter> unclean_shutdowns_daily_;
298
299 // Daily count of any crashes (user-space processes, kernel, or
300 // unclean shutdowns).
301 scoped_ptr<chromeos_metrics::FrequencyCounter> any_crashes_daily_;
302
Darin Petkov41e06232010-05-03 16:45:37 -0700303 // Sleep period until the next daily usage aggregation performed by
304 // the daily use monitor (see ScheduleUseMonitor).
305 int usemon_interval_;
306
307 // Scheduled daily use monitor source (see ScheduleUseMonitor).
308 GSource* usemon_source_;
Darin Petkov65b01462010-04-14 13:32:20 -0700309};
310
311#endif // METRICS_DAEMON_H_