Home | History | Annotate | Download | only in chromeos
      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 "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 class PrefService;
     21 
     22 namespace chromeos {
     23 
     24 // BootTimesLoader loads the bootimes of Chrome OS from the file system.
     25 // Loading is done asynchronously on the file thread. Once loaded,
     26 // BootTimesLoader calls back to a method of your choice with the boot times.
     27 // To use BootTimesLoader, do the following:
     28 //
     29 // . In your class define a member field of type chromeos::BootTimesLoader and
     30 //   base::CancelableTaskTracker.
     31 // . Define the callback method, something like:
     32 //   void OnBootTimesLoaded(const BootTimesLoader::BootTimes& boot_times);
     33 // . When you want the version invoke: loader.GetBootTimes(callback, &tracker_);
     34 class BootTimesLoader : public content::NotificationObserver {
     35  public:
     36   BootTimesLoader();
     37   virtual ~BootTimesLoader();
     38 
     39   static BootTimesLoader* Get();
     40 
     41   // Add a time marker for login. A timeline will be dumped to
     42   // /tmp/login-times-sent after login is done. If |send_to_uma| is true
     43   // the time between this marker and the last will be sent to UMA with
     44   // the identifier BootTime.|marker_name|.
     45   void AddLoginTimeMarker(const std::string& marker_name, bool send_to_uma);
     46 
     47   // Add a time marker for logout. A timeline will be dumped to
     48   // /tmp/logout-times-sent after logout is done. If |send_to_uma| is true
     49   // the time between this marker and the last will be sent to UMA with
     50   // the identifier ShutdownTime.|marker_name|.
     51   void AddLogoutTimeMarker(const std::string& marker_name, bool send_to_uma);
     52 
     53   // Records current uptime and disk usage for metrics use.
     54   // Posts task to file thread.
     55   // name will be used as part of file names in /tmp.
     56   // Existing stats files will not be overwritten.
     57   void RecordCurrentStats(const std::string& name);
     58 
     59   // Saves away the stats at main, so the can be recorded later. At main() time
     60   // the necessary threads don't exist yet for recording the data.
     61   void SaveChromeMainStats();
     62 
     63   // Records the data previously saved by SaveChromeMainStats(), using the
     64   // file thread. Existing stats files will not be overwritten.
     65   void RecordChromeMainStats();
     66 
     67   // Records the time that a login was attempted. This will overwrite any
     68   // previous login attempt times.
     69   void RecordLoginAttempted();
     70 
     71   // content::NotificationObserver implementation.
     72   virtual void Observe(int type,
     73                        const content::NotificationSource& source,
     74                        const content::NotificationDetails& details) OVERRIDE;
     75 
     76   // Records "LoginDone" event.
     77   void LoginDone(bool is_user_new);
     78 
     79   // Writes the logout times to a /tmp/logout-times-sent. Unlike login
     80   // times, we manually call this function for logout times, as we cannot
     81   // rely on notification service to tell when the logout is done.
     82   void WriteLogoutTimes();
     83 
     84   // Mark that WriteLogoutTimes should handle restart.
     85   void set_restart_requested() { restart_requested_ = true; }
     86 
     87   // This is called on Chrome process startup to write saved logout stats.
     88   void OnChromeProcessStart();
     89 
     90   // This saves logout-started metric to Local State.
     91   void OnLogoutStarted(PrefService* state);
     92 
     93  private:
     94   // BootTimesLoader calls into the Backend on the file thread to load
     95   // the boot times.
     96   class Backend : public base::RefCountedThreadSafe<Backend> {
     97    public:
     98     Backend() {}
     99 
    100    private:
    101     friend class base::RefCountedThreadSafe<Backend>;
    102 
    103     ~Backend() {}
    104 
    105     DISALLOW_COPY_AND_ASSIGN(Backend);
    106   };
    107 
    108   class TimeMarker {
    109    public:
    110     TimeMarker(const std::string& name, bool send_to_uma)
    111         : name_(name),
    112           time_(base::Time::NowFromSystemTime()),
    113           send_to_uma_(send_to_uma) {}
    114     std::string name() const { return name_; }
    115     base::Time time() const { return time_; }
    116     bool send_to_uma() const { return send_to_uma_; }
    117 
    118     // comparitor for sorting
    119     bool operator<(const TimeMarker& other) const {
    120       return time_ < other.time_;
    121     }
    122 
    123    private:
    124     friend class std::vector<TimeMarker>;
    125     std::string name_;
    126     base::Time time_;
    127     bool send_to_uma_;
    128   };
    129 
    130   class Stats {
    131    public:
    132     // Initializes stats with current /proc values.
    133     static Stats GetCurrentStats();
    134 
    135     // Returns JSON representation.
    136     std::string SerializeToString() const;
    137 
    138     // Creates new object from JSON representation.
    139     static Stats DeserializeFromString(const std::string& value);
    140 
    141     const std::string& uptime() const { return uptime_; }
    142     const std::string& disk() const { return disk_; }
    143 
    144     // Writes "uptime in seconds" to result. (This is first field in uptime_.)
    145     // Returns true on successful conversion.
    146     bool UptimeDouble(double* result) const;
    147 
    148     void RecordStats(const std::string& name) const;
    149     void RecordStatsWithCallback(const std::string& name,
    150                                  const base::Closure& callback) const;
    151 
    152    private:
    153     // Runs on BlockingPool
    154     void RecordStatsImpl(const std::string& name) const;
    155 
    156     std::string uptime_;
    157     std::string disk_;
    158   };
    159 
    160   static void WriteTimes(const std::string base_name,
    161                          const std::string uma_name,
    162                          const std::string uma_prefix,
    163                          std::vector<TimeMarker> login_times);
    164   static void AddMarker(std::vector<TimeMarker>* vector, TimeMarker marker);
    165 
    166   // Clear saved logout-started metric in Local State.
    167   // This method is called when logout-state was writen to file.
    168   static void ClearLogoutStartedLastPreference();
    169 
    170   // Used to hold the stats at main().
    171   Stats chrome_main_stats_;
    172   scoped_refptr<Backend> backend_;
    173 
    174   // Used to track notifications for login.
    175   content::NotificationRegistrar registrar_;
    176   base::AtomicSequenceNumber num_tabs_;
    177   bool have_registered_;
    178 
    179   std::vector<TimeMarker> login_time_markers_;
    180   std::vector<TimeMarker> logout_time_markers_;
    181   std::set<content::RenderWidgetHost*> render_widget_hosts_loading_;
    182 
    183   bool login_done_;
    184 
    185   bool restart_requested_;
    186 
    187   DISALLOW_COPY_AND_ASSIGN(BootTimesLoader);
    188 };
    189 
    190 }  // namespace chromeos
    191 
    192 #endif  // CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_
    193