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