• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 #pragma once
8 
9 #include <string>
10 
11 #include "base/atomic_sequence_num.h"
12 #include "base/callback.h"
13 #include "base/time.h"
14 #include "content/browser/cancelable_request.h"
15 #include "content/common/notification_observer.h"
16 #include "content/common/notification_registrar.h"
17 
18 namespace chromeos {
19 
20 // BootTimesLoader loads the bootimes of Chrome OS from the file system.
21 // Loading is done asynchronously on the file thread. Once loaded,
22 // BootTimesLoader calls back to a method of your choice with the boot times.
23 // To use BootTimesLoader do the following:
24 //
25 // . In your class define a member field of type chromeos::BootTimesLoader and
26 //   CancelableRequestConsumerBase.
27 // . Define the callback method, something like:
28 //   void OnBootTimesLoader(chromeos::BootTimesLoader::Handle,
29 //                             BootTimesLoader::BootTimes boot_times);
30 // . When you want the version invoke: loader.GetBootTimes(&consumer, callback);
31 class BootTimesLoader
32     : public CancelableRequestProvider,
33       public NotificationObserver {
34  public:
35   BootTimesLoader();
36 
37   // All fields are 0.0 if they couldn't be found.
38   typedef struct BootTimes {
39     double firmware;           // Time from power button to kernel being loaded.
40     double pre_startup;        // Time from kernel to system code being called.
41     double x_started;          // Time X server is ready to be connected to.
42     double chrome_exec;        // Time session manager executed Chrome.
43     double chrome_main;        // Time chrome's main() was called.
44     double login_prompt_ready; // Time login (or OOB) panel is displayed.
45     double system;             // Time system took to start chrome.
46     double chrome;             // Time chrome took to display login panel.
47     double total;              // Time from power button to login panel.
48 
BootTimesBootTimes49     BootTimes() : firmware(0),
50                   pre_startup(0),
51                   x_started(0),
52                   chrome_exec(0),
53                   chrome_main(0),
54                   login_prompt_ready(0),
55                   system(0),
56                   chrome(0),
57                   total(0) {}
58   } BootTimes;
59 
60   // Signature
61   typedef Callback2<Handle, BootTimes>::Type GetBootTimesCallback;
62 
63   typedef CancelableRequest<GetBootTimesCallback> GetBootTimesRequest;
64 
65   static BootTimesLoader* Get();
66 
67   // Asynchronously requests the info.
68   Handle GetBootTimes(
69       CancelableRequestConsumerBase* consumer,
70       GetBootTimesCallback* callback);
71 
72   // Add a time marker for login. A timeline will be dumped to
73   // /tmp/login-times-sent after login is done. If |send_to_uma| is true
74   // the time between this marker and the last will be sent to UMA with
75   // the identifier BootTime.|marker_name|.
76   void AddLoginTimeMarker(const std::string& marker_name, bool send_to_uma);
77 
78   // Add a time marker for logout. A timeline will be dumped to
79   // /tmp/logout-times-sent after logout is done. If |send_to_uma| is true
80   // the time between this marker and the last will be sent to UMA with
81   // the identifier ShutdownTime.|marker_name|.
82   void AddLogoutTimeMarker(const std::string& marker_name, bool send_to_uma);
83 
84   // Records current uptime and disk usage for metrics use.
85   // Posts task to file thread.
86   // name will be used as part of file names in /tmp.
87   // Existing stats files will not be overwritten.
88   void RecordCurrentStats(const std::string& name);
89 
90   // Saves away the stats at main, so the can be recorded later. At main() time
91   // the necessary threads don't exist yet for recording the data.
92   void SaveChromeMainStats();
93 
94   // Records the data previously saved by SaveChromeMainStats(), using the
95   // file thread. Existing stats files will not be overwritten.
96   void RecordChromeMainStats();
97 
98   // Records the time that a login was attempted. This will overwrite any
99   // previous login attempt times.
100   void RecordLoginAttempted();
101 
102   // NotificationObserver implementation.
103   virtual void Observe(NotificationType type,
104                        const NotificationSource& source,
105                        const NotificationDetails& details);
106 
107   // Writes the logout times to a /tmp/logout-times-sent. Unlike login
108   // times, we manually call this function for logout times, as we cannot
109   // rely on notification service to tell when the logout is done.
110   void WriteLogoutTimes();
111 
112  private:
113   // BootTimesLoader calls into the Backend on the file thread to load
114   // the boot times.
115   class Backend : public base::RefCountedThreadSafe<Backend> {
116    public:
Backend()117     Backend() {}
118 
119     void GetBootTimes(scoped_refptr<GetBootTimesRequest> request);
120 
121    private:
122     friend class base::RefCountedThreadSafe<Backend>;
123 
~Backend()124     ~Backend() {}
125 
126     DISALLOW_COPY_AND_ASSIGN(Backend);
127   };
128 
129   class TimeMarker {
130    public:
TimeMarker(const std::string & name,bool send_to_uma)131     TimeMarker(const std::string& name, bool send_to_uma)
132         : name_(name),
133           time_(base::Time::NowFromSystemTime()),
134           send_to_uma_(send_to_uma) {}
name()135     std::string name() const { return name_; }
time()136     base::Time time() const { return time_; }
send_to_uma()137     bool send_to_uma() const { return send_to_uma_; }
138 
139    private:
140     friend class std::vector<TimeMarker>;
141     std::string name_;
142     base::Time time_;
143     bool send_to_uma_;
144   };
145 
146   struct Stats {
147    public:
148     std::string uptime;
149     std::string disk;
150   };
151 
152   static void RecordStats(
153       const std::string& name, const Stats& stats);
154   static Stats GetCurrentStats();
155   static void WriteTimes(const std::string base_name,
156                          const std::string uma_name,
157                          const std::string uma_prefix,
158                          const std::vector<TimeMarker> login_times);
159 
160   // Used to hold the stats at main().
161   Stats chrome_main_stats_;
162   scoped_refptr<Backend> backend_;
163 
164   // Used to track notifications for login.
165   NotificationRegistrar registrar_;
166   base::AtomicSequenceNumber num_tabs_;
167   bool have_registered_;
168 
169   std::vector<TimeMarker> login_time_markers_;
170   std::vector<TimeMarker> logout_time_markers_;
171 
172   DISALLOW_COPY_AND_ASSIGN(BootTimesLoader);
173 };
174 
175 }  // namespace chromeos
176 
177 #endif  // CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_
178