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 "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