• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
20 class PrefService;
21 
22 namespace chromeos {
23 
24 // BootTimesLoader loads the bootimes of Chrome OS from the file system.
25 // Loading is done asynchronously on the file thread. Once loaded,
26 // BootTimesLoader calls back to a method of your choice with the boot times.
27 // To use BootTimesLoader, do the following:
28 //
29 // . In your class define a member field of type chromeos::BootTimesLoader and
30 //   base::CancelableTaskTracker.
31 // . Define the callback method, something like:
32 //   void OnBootTimesLoaded(const BootTimesLoader::BootTimes& boot_times);
33 // . When you want the version invoke: loader.GetBootTimes(callback, &tracker_);
34 class BootTimesLoader : public content::NotificationObserver {
35  public:
36   BootTimesLoader();
37   virtual ~BootTimesLoader();
38 
39   static BootTimesLoader* Get();
40 
41   // Add a time marker for login. A timeline will be dumped to
42   // /tmp/login-times-sent after login is done. If |send_to_uma| is true
43   // the time between this marker and the last will be sent to UMA with
44   // the identifier BootTime.|marker_name|.
45   void AddLoginTimeMarker(const std::string& marker_name, bool send_to_uma);
46 
47   // Add a time marker for logout. A timeline will be dumped to
48   // /tmp/logout-times-sent after logout is done. If |send_to_uma| is true
49   // the time between this marker and the last will be sent to UMA with
50   // the identifier ShutdownTime.|marker_name|.
51   void AddLogoutTimeMarker(const std::string& marker_name, bool send_to_uma);
52 
53   // Records current uptime and disk usage for metrics use.
54   // Posts task to file thread.
55   // name will be used as part of file names in /tmp.
56   // Existing stats files will not be overwritten.
57   void RecordCurrentStats(const std::string& name);
58 
59   // Saves away the stats at main, so the can be recorded later. At main() time
60   // the necessary threads don't exist yet for recording the data.
61   void SaveChromeMainStats();
62 
63   // Records the data previously saved by SaveChromeMainStats(), using the
64   // file thread. Existing stats files will not be overwritten.
65   void RecordChromeMainStats();
66 
67   // Records the time that a login was attempted. This will overwrite any
68   // previous login attempt times.
69   void RecordLoginAttempted();
70 
71   // content::NotificationObserver implementation.
72   virtual void Observe(int type,
73                        const content::NotificationSource& source,
74                        const content::NotificationDetails& details) OVERRIDE;
75 
76   // Records "LoginDone" event.
77   void LoginDone(bool is_user_new);
78 
79   // Writes the logout times to a /tmp/logout-times-sent. Unlike login
80   // times, we manually call this function for logout times, as we cannot
81   // rely on notification service to tell when the logout is done.
82   void WriteLogoutTimes();
83 
84   // Mark that WriteLogoutTimes should handle restart.
set_restart_requested()85   void set_restart_requested() { restart_requested_ = true; }
86 
87   // This is called on Chrome process startup to write saved logout stats.
88   void OnChromeProcessStart();
89 
90   // This saves logout-started metric to Local State.
91   void OnLogoutStarted(PrefService* state);
92 
93  private:
94   // BootTimesLoader calls into the Backend on the file thread to load
95   // the boot times.
96   class Backend : public base::RefCountedThreadSafe<Backend> {
97    public:
Backend()98     Backend() {}
99 
100    private:
101     friend class base::RefCountedThreadSafe<Backend>;
102 
~Backend()103     ~Backend() {}
104 
105     DISALLOW_COPY_AND_ASSIGN(Backend);
106   };
107 
108   class TimeMarker {
109    public:
TimeMarker(const std::string & name,bool send_to_uma)110     TimeMarker(const std::string& name, bool send_to_uma)
111         : name_(name),
112           time_(base::Time::NowFromSystemTime()),
113           send_to_uma_(send_to_uma) {}
name()114     std::string name() const { return name_; }
time()115     base::Time time() const { return time_; }
send_to_uma()116     bool send_to_uma() const { return send_to_uma_; }
117 
118     // comparitor for sorting
119     bool operator<(const TimeMarker& other) const {
120       return time_ < other.time_;
121     }
122 
123    private:
124     friend class std::vector<TimeMarker>;
125     std::string name_;
126     base::Time time_;
127     bool send_to_uma_;
128   };
129 
130   class Stats {
131    public:
132     // Initializes stats with current /proc values.
133     static Stats GetCurrentStats();
134 
135     // Returns JSON representation.
136     std::string SerializeToString() const;
137 
138     // Creates new object from JSON representation.
139     static Stats DeserializeFromString(const std::string& value);
140 
uptime()141     const std::string& uptime() const { return uptime_; }
disk()142     const std::string& disk() const { return disk_; }
143 
144     // Writes "uptime in seconds" to result. (This is first field in uptime_.)
145     // Returns true on successful conversion.
146     bool UptimeDouble(double* result) const;
147 
148     void RecordStats(const std::string& name) const;
149     void RecordStatsWithCallback(const std::string& name,
150                                  const base::Closure& callback) const;
151 
152    private:
153     // Runs on BlockingPool
154     void RecordStatsImpl(const std::string& name) const;
155 
156     std::string uptime_;
157     std::string disk_;
158   };
159 
160   static void WriteTimes(const std::string base_name,
161                          const std::string uma_name,
162                          const std::string uma_prefix,
163                          std::vector<TimeMarker> login_times);
164   static void AddMarker(std::vector<TimeMarker>* vector, TimeMarker marker);
165 
166   // Clear saved logout-started metric in Local State.
167   // This method is called when logout-state was writen to file.
168   static void ClearLogoutStartedLastPreference();
169 
170   // Used to hold the stats at main().
171   Stats chrome_main_stats_;
172   scoped_refptr<Backend> backend_;
173 
174   // Used to track notifications for login.
175   content::NotificationRegistrar registrar_;
176   base::AtomicSequenceNumber num_tabs_;
177   bool have_registered_;
178 
179   std::vector<TimeMarker> login_time_markers_;
180   std::vector<TimeMarker> logout_time_markers_;
181   std::set<content::RenderWidgetHost*> render_widget_hosts_loading_;
182 
183   bool login_done_;
184 
185   bool restart_requested_;
186 
187   DISALLOW_COPY_AND_ASSIGN(BootTimesLoader);
188 };
189 
190 }  // namespace chromeos
191 
192 #endif  // CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_
193