boot_times_loader.h revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright (c) 2012 The Chromium 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 CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_
6#define CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_
7
8#include <set>
9#include <string>
10
11#include "base/atomic_sequence_num.h"
12#include "base/callback_forward.h"
13#include "base/compiler_specific.h"
14#include "base/task/cancelable_task_tracker.h"
15#include "base/time/time.h"
16#include "content/public/browser/notification_observer.h"
17#include "content/public/browser/notification_registrar.h"
18#include "content/public/browser/render_widget_host.h"
19
20namespace chromeos {
21
22// BootTimesLoader loads the bootimes of Chrome OS from the file system.
23// Loading is done asynchronously on the file thread. Once loaded,
24// BootTimesLoader calls back to a method of your choice with the boot times.
25// To use BootTimesLoader, do the following:
26//
27// . In your class define a member field of type chromeos::BootTimesLoader and
28//   base::CancelableTaskTracker.
29// . Define the callback method, something like:
30//   void OnBootTimesLoaded(const BootTimesLoader::BootTimes& boot_times);
31// . When you want the version invoke: loader.GetBootTimes(callback, &tracker_);
32class BootTimesLoader : public content::NotificationObserver {
33 public:
34  BootTimesLoader();
35  virtual ~BootTimesLoader();
36
37  static BootTimesLoader* Get();
38
39  // Add a time marker for login. A timeline will be dumped to
40  // /tmp/login-times-sent after login is done. If |send_to_uma| is true
41  // the time between this marker and the last will be sent to UMA with
42  // the identifier BootTime.|marker_name|.
43  void AddLoginTimeMarker(const std::string& marker_name, bool send_to_uma);
44
45  // Add a time marker for logout. A timeline will be dumped to
46  // /tmp/logout-times-sent after logout is done. If |send_to_uma| is true
47  // the time between this marker and the last will be sent to UMA with
48  // the identifier ShutdownTime.|marker_name|.
49  void AddLogoutTimeMarker(const std::string& marker_name, bool send_to_uma);
50
51  // Records current uptime and disk usage for metrics use.
52  // Posts task to file thread.
53  // name will be used as part of file names in /tmp.
54  // Existing stats files will not be overwritten.
55  void RecordCurrentStats(const std::string& name);
56
57  // Saves away the stats at main, so the can be recorded later. At main() time
58  // the necessary threads don't exist yet for recording the data.
59  void SaveChromeMainStats();
60
61  // Records the data previously saved by SaveChromeMainStats(), using the
62  // file thread. Existing stats files will not be overwritten.
63  void RecordChromeMainStats();
64
65  // Records the time that a login was attempted. This will overwrite any
66  // previous login attempt times.
67  void RecordLoginAttempted();
68
69  // content::NotificationObserver implementation.
70  virtual void Observe(int type,
71                       const content::NotificationSource& source,
72                       const content::NotificationDetails& details) OVERRIDE;
73
74  // Records "LoginDone" event.
75  void LoginDone(bool is_user_new);
76
77  // Writes the logout times to a /tmp/logout-times-sent. Unlike login
78  // times, we manually call this function for logout times, as we cannot
79  // rely on notification service to tell when the logout is done.
80  void WriteLogoutTimes();
81
82  // Mark that WriteLogoutTimes should handle restart.
83  void set_restart_requested() { restart_requested_ = true; }
84
85 private:
86  // BootTimesLoader calls into the Backend on the file thread to load
87  // the boot times.
88  class Backend : public base::RefCountedThreadSafe<Backend> {
89   public:
90    Backend() {}
91
92   private:
93    friend class base::RefCountedThreadSafe<Backend>;
94
95    ~Backend() {}
96
97    DISALLOW_COPY_AND_ASSIGN(Backend);
98  };
99
100  class TimeMarker {
101   public:
102    TimeMarker(const std::string& name, bool send_to_uma)
103        : name_(name),
104          time_(base::Time::NowFromSystemTime()),
105          send_to_uma_(send_to_uma) {}
106    std::string name() const { return name_; }
107    base::Time time() const { return time_; }
108    bool send_to_uma() const { return send_to_uma_; }
109
110    // comparitor for sorting
111    bool operator<(const TimeMarker& other) const {
112      return time_ < other.time_;
113    }
114
115   private:
116    friend class std::vector<TimeMarker>;
117    std::string name_;
118    base::Time time_;
119    bool send_to_uma_;
120  };
121
122  struct Stats {
123   public:
124    std::string uptime;
125    std::string disk;
126  };
127
128  static void RecordStats(
129      const std::string& name, const Stats& stats);
130  static Stats GetCurrentStats();
131  static void WriteTimes(const std::string base_name,
132                         const std::string uma_name,
133                         const std::string uma_prefix,
134                         std::vector<TimeMarker> login_times);
135  static void AddMarker(std::vector<TimeMarker>* vector, TimeMarker marker);
136
137  // Used to hold the stats at main().
138  Stats chrome_main_stats_;
139  scoped_refptr<Backend> backend_;
140
141  // Used to track notifications for login.
142  content::NotificationRegistrar registrar_;
143  base::AtomicSequenceNumber num_tabs_;
144  bool have_registered_;
145
146  std::vector<TimeMarker> login_time_markers_;
147  std::vector<TimeMarker> logout_time_markers_;
148  std::set<content::RenderWidgetHost*> render_widget_hosts_loading_;
149
150  bool login_done_;
151
152  bool restart_requested_;
153
154  DISALLOW_COPY_AND_ASSIGN(BootTimesLoader);
155};
156
157}  // namespace chromeos
158
159#endif  // CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_
160