// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_ #define CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_ #include #include #include "base/atomic_sequence_num.h" #include "base/callback_forward.h" #include "base/compiler_specific.h" #include "base/task/cancelable_task_tracker.h" #include "base/time/time.h" #include "chromeos/login_event_recorder.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/render_widget_host.h" class PrefService; namespace chromeos { // BootTimesLoader loads the bootimes of Chrome OS from the file system. // Loading is done asynchronously on the file thread. Once loaded, // BootTimesLoader calls back to a method of your choice with the boot times. // To use BootTimesLoader, do the following: // // . In your class define a member field of type chromeos::BootTimesLoader and // base::CancelableTaskTracker. // . Define the callback method, something like: // void OnBootTimesLoaded(const BootTimesLoader::BootTimes& boot_times); // . When you want the version invoke: loader.GetBootTimes(callback, &tracker_); class BootTimesLoader : public content::NotificationObserver, public LoginEventRecorder::Delegate { public: BootTimesLoader(); virtual ~BootTimesLoader(); static BootTimesLoader* Get(); // LoginEventRecorder::Delegate override. virtual void AddLoginTimeMarker(const std::string& marker_name, bool send_to_uma) OVERRIDE; virtual void RecordAuthenticationSuccess() OVERRIDE; virtual void RecordAuthenticationFailure() OVERRIDE; // Add a time marker for logout. A timeline will be dumped to // /tmp/logout-times-sent after logout is done. If |send_to_uma| is true // the time between this marker and the last will be sent to UMA with // the identifier ShutdownTime.|marker_name|. void AddLogoutTimeMarker(const std::string& marker_name, bool send_to_uma); // Records current uptime and disk usage for metrics use. // Posts task to file thread. // name will be used as part of file names in /tmp. // Existing stats files will not be overwritten. void RecordCurrentStats(const std::string& name); // Saves away the stats at main, so the can be recorded later. At main() time // the necessary threads don't exist yet for recording the data. void SaveChromeMainStats(); // Records the data previously saved by SaveChromeMainStats(), using the // file thread. Existing stats files will not be overwritten. void RecordChromeMainStats(); // Records the time that a login was attempted. This will overwrite any // previous login attempt times. void RecordLoginAttempted(); // content::NotificationObserver implementation. virtual void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE; // Records "LoginDone" event. void LoginDone(bool is_user_new); // Writes the logout times to a /tmp/logout-times-sent. Unlike login // times, we manually call this function for logout times, as we cannot // rely on notification service to tell when the logout is done. void WriteLogoutTimes(); // Mark that WriteLogoutTimes should handle restart. void set_restart_requested() { restart_requested_ = true; } // This is called on Chrome process startup to write saved logout stats. void OnChromeProcessStart(); // This saves logout-started metric to Local State. void OnLogoutStarted(PrefService* state); private: // BootTimesLoader calls into the Backend on the file thread to load // the boot times. class Backend : public base::RefCountedThreadSafe { public: Backend() {} private: friend class base::RefCountedThreadSafe; ~Backend() {} DISALLOW_COPY_AND_ASSIGN(Backend); }; class TimeMarker { public: TimeMarker(const std::string& name, bool send_to_uma) : name_(name), time_(base::Time::NowFromSystemTime()), send_to_uma_(send_to_uma) {} std::string name() const { return name_; } base::Time time() const { return time_; } bool send_to_uma() const { return send_to_uma_; } // comparitor for sorting bool operator<(const TimeMarker& other) const { return time_ < other.time_; } private: friend class std::vector; std::string name_; base::Time time_; bool send_to_uma_; }; class Stats { public: // Initializes stats with current /proc values. static Stats GetCurrentStats(); // Returns JSON representation. std::string SerializeToString() const; // Creates new object from JSON representation. static Stats DeserializeFromString(const std::string& value); const std::string& uptime() const { return uptime_; } const std::string& disk() const { return disk_; } // Writes "uptime in seconds" to result. (This is first field in uptime_.) // Returns true on successful conversion. bool UptimeDouble(double* result) const; void RecordStats(const std::string& name) const; void RecordStatsWithCallback(const std::string& name, const base::Closure& callback) const; private: // Runs on BlockingPool void RecordStatsImpl(const std::string& name) const; std::string uptime_; std::string disk_; }; static void WriteTimes(const std::string base_name, const std::string uma_name, const std::string uma_prefix, std::vector login_times); static void AddMarker(std::vector* vector, TimeMarker marker); // Clear saved logout-started metric in Local State. // This method is called when logout-state was writen to file. static void ClearLogoutStartedLastPreference(); // Used to hold the stats at main(). Stats chrome_main_stats_; scoped_refptr backend_; // Used to track notifications for login. content::NotificationRegistrar registrar_; base::AtomicSequenceNumber num_tabs_; bool have_registered_; std::vector login_time_markers_; std::vector logout_time_markers_; std::set render_widget_hosts_loading_; bool login_done_; bool restart_requested_; DISALLOW_COPY_AND_ASSIGN(BootTimesLoader); }; } // namespace chromeos #endif // CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_