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. 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: 100 Backend() {} 101 102 private: 103 friend class base::RefCountedThreadSafe<Backend>; 104 105 ~Backend() {} 106 107 DISALLOW_COPY_AND_ASSIGN(Backend); 108 }; 109 110 class TimeMarker { 111 public: 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) {} 116 std::string name() const { return name_; } 117 base::Time time() const { return time_; } 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 143 const std::string& uptime() const { return uptime_; } 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