15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/atomic_sequence_num.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_forward.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/task/cancelable_task_tracker.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/time/time.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromeos/login_event_recorder.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/render_widget_host.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PrefService; 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BootTimesLoader loads the bootimes of Chrome OS from the file system. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Loading is done asynchronously on the file thread. Once loaded, 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// BootTimesLoader calls back to a method of your choice with the boot times. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// To use BootTimesLoader, do the following: 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// . In your class define a member field of type chromeos::BootTimesLoader and 317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// base::CancelableTaskTracker. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// . Define the callback method, something like: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void OnBootTimesLoaded(const BootTimesLoader::BootTimes& boot_times); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// . When you want the version invoke: loader.GetBootTimes(callback, &tracker_); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BootTimesLoader : public content::NotificationObserver, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public LoginEventRecorder::Delegate { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BootTimesLoader(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~BootTimesLoader(); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static BootTimesLoader* Get(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LoginEventRecorder::Delegate override. 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void AddLoginTimeMarker(const std::string& marker_name, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool send_to_uma) OVERRIDE; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RecordAuthenticationSuccess() OVERRIDE; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RecordAuthenticationFailure() OVERRIDE; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a time marker for logout. A timeline will be dumped to 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // /tmp/logout-times-sent after logout is done. If |send_to_uma| is true 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the time between this marker and the last will be sent to UMA with 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the identifier ShutdownTime.|marker_name|. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddLogoutTimeMarker(const std::string& marker_name, bool send_to_uma); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Records current uptime and disk usage for metrics use. 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Posts task to file thread. 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // name will be used as part of file names in /tmp. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Existing stats files will not be overwritten. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RecordCurrentStats(const std::string& name); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Saves away the stats at main, so the can be recorded later. At main() time 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the necessary threads don't exist yet for recording the data. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SaveChromeMainStats(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Records the data previously saved by SaveChromeMainStats(), using the 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // file thread. Existing stats files will not be overwritten. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RecordChromeMainStats(); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Records the time that a login was attempted. This will overwrite any 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // previous login attempt times. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RecordLoginAttempted(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // content::NotificationObserver implementation. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Observe(int type, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) OVERRIDE; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Records "LoginDone" event. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void LoginDone(bool is_user_new); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Writes the logout times to a /tmp/logout-times-sent. Unlike login 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // times, we manually call this function for logout times, as we cannot 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // rely on notification service to tell when the logout is done. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteLogoutTimes(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 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