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