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 49 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: 117 Backend() {} 118 119 void GetBootTimes(scoped_refptr<GetBootTimesRequest> request); 120 121 private: 122 friend class base::RefCountedThreadSafe<Backend>; 123 124 ~Backend() {} 125 126 DISALLOW_COPY_AND_ASSIGN(Backend); 127 }; 128 129 class TimeMarker { 130 public: 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) {} 135 std::string name() const { return name_; } 136 base::Time time() const { return time_; } 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