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/time.h" 15 #include "chrome/common/cancelable_task_tracker.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 20 namespace 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 // CancelableTaskTracker. 29 // . Define the callback method, something like: 30 // void OnBootTimesLoaded(const BootTimesLoader::BootTimes& boot_times); 31 // . When you want the version invoke: loader.GetBootTimes(callback, &tracker_); 32 class BootTimesLoader : public content::NotificationObserver { 33 public: 34 BootTimesLoader(); 35 virtual ~BootTimesLoader(); 36 37 static BootTimesLoader* Get(); 38 39 // Add a time marker for login. A timeline will be dumped to 40 // /tmp/login-times-sent after login is done. If |send_to_uma| is true 41 // the time between this marker and the last will be sent to UMA with 42 // the identifier BootTime.|marker_name|. 43 void AddLoginTimeMarker(const std::string& marker_name, bool send_to_uma); 44 45 // Add a time marker for logout. A timeline will be dumped to 46 // /tmp/logout-times-sent after logout is done. If |send_to_uma| is true 47 // the time between this marker and the last will be sent to UMA with 48 // the identifier ShutdownTime.|marker_name|. 49 void AddLogoutTimeMarker(const std::string& marker_name, bool send_to_uma); 50 51 // Records current uptime and disk usage for metrics use. 52 // Posts task to file thread. 53 // name will be used as part of file names in /tmp. 54 // Existing stats files will not be overwritten. 55 void RecordCurrentStats(const std::string& name); 56 57 // Saves away the stats at main, so the can be recorded later. At main() time 58 // the necessary threads don't exist yet for recording the data. 59 void SaveChromeMainStats(); 60 61 // Records the data previously saved by SaveChromeMainStats(), using the 62 // file thread. Existing stats files will not be overwritten. 63 void RecordChromeMainStats(); 64 65 // Records the time that a login was attempted. This will overwrite any 66 // previous login attempt times. 67 void RecordLoginAttempted(); 68 69 // content::NotificationObserver implementation. 70 virtual void Observe(int type, 71 const content::NotificationSource& source, 72 const content::NotificationDetails& details) OVERRIDE; 73 74 // Writes the logout times to a /tmp/logout-times-sent. Unlike login 75 // times, we manually call this function for logout times, as we cannot 76 // rely on notification service to tell when the logout is done. 77 void WriteLogoutTimes(); 78 79 private: 80 // BootTimesLoader calls into the Backend on the file thread to load 81 // the boot times. 82 class Backend : public base::RefCountedThreadSafe<Backend> { 83 public: 84 Backend() {} 85 86 private: 87 friend class base::RefCountedThreadSafe<Backend>; 88 89 ~Backend() {} 90 91 DISALLOW_COPY_AND_ASSIGN(Backend); 92 }; 93 94 class TimeMarker { 95 public: 96 TimeMarker(const std::string& name, bool send_to_uma) 97 : name_(name), 98 time_(base::Time::NowFromSystemTime()), 99 send_to_uma_(send_to_uma) {} 100 std::string name() const { return name_; } 101 base::Time time() const { return time_; } 102 bool send_to_uma() const { return send_to_uma_; } 103 104 // comparitor for sorting 105 bool operator<(const TimeMarker& other) const { 106 return time_ < other.time_; 107 } 108 109 private: 110 friend class std::vector<TimeMarker>; 111 std::string name_; 112 base::Time time_; 113 bool send_to_uma_; 114 }; 115 116 struct Stats { 117 public: 118 std::string uptime; 119 std::string disk; 120 }; 121 122 static void RecordStats( 123 const std::string& name, const Stats& stats); 124 static Stats GetCurrentStats(); 125 static void WriteTimes(const std::string base_name, 126 const std::string uma_name, 127 const std::string uma_prefix, 128 std::vector<TimeMarker> login_times); 129 static void AddMarker(std::vector<TimeMarker>* vector, TimeMarker marker); 130 131 void LoginDone(); 132 133 // Used to hold the stats at main(). 134 Stats chrome_main_stats_; 135 scoped_refptr<Backend> backend_; 136 137 // Used to track notifications for login. 138 content::NotificationRegistrar registrar_; 139 base::AtomicSequenceNumber num_tabs_; 140 bool have_registered_; 141 142 std::vector<TimeMarker> login_time_markers_; 143 std::vector<TimeMarker> logout_time_markers_; 144 std::set<content::RenderWidgetHost*> render_widget_hosts_loading_; 145 146 DISALLOW_COPY_AND_ASSIGN(BootTimesLoader); 147 }; 148 149 } // namespace chromeos 150 151 #endif // CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_ 152