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