Home | History | Annotate | Download | only in chromeos
      1 // Copyright (c) 2011 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 #pragma once
      8 
      9 #include <string>
     10 
     11 #include "base/atomic_sequence_num.h"
     12 #include "base/callback.h"
     13 #include "base/time.h"
     14 #include "content/browser/cancelable_request.h"
     15 #include "content/common/notification_observer.h"
     16 #include "content/common/notification_registrar.h"
     17 
     18 namespace chromeos {
     19 
     20 // BootTimesLoader loads the bootimes of Chrome OS from the file system.
     21 // Loading is done asynchronously on the file thread. Once loaded,
     22 // BootTimesLoader calls back to a method of your choice with the boot times.
     23 // To use BootTimesLoader do the following:
     24 //
     25 // . In your class define a member field of type chromeos::BootTimesLoader and
     26 //   CancelableRequestConsumerBase.
     27 // . Define the callback method, something like:
     28 //   void OnBootTimesLoader(chromeos::BootTimesLoader::Handle,
     29 //                             BootTimesLoader::BootTimes boot_times);
     30 // . When you want the version invoke: loader.GetBootTimes(&consumer, callback);
     31 class BootTimesLoader
     32     : public CancelableRequestProvider,
     33       public NotificationObserver {
     34  public:
     35   BootTimesLoader();
     36 
     37   // All fields are 0.0 if they couldn't be found.
     38   typedef struct BootTimes {
     39     double firmware;           // Time from power button to kernel being loaded.
     40     double pre_startup;        // Time from kernel to system code being called.
     41     double x_started;          // Time X server is ready to be connected to.
     42     double chrome_exec;        // Time session manager executed Chrome.
     43     double chrome_main;        // Time chrome's main() was called.
     44     double login_prompt_ready; // Time login (or OOB) panel is displayed.
     45     double system;             // Time system took to start chrome.
     46     double chrome;             // Time chrome took to display login panel.
     47     double total;              // Time from power button to login panel.
     48 
     49     BootTimes() : firmware(0),
     50                   pre_startup(0),
     51                   x_started(0),
     52                   chrome_exec(0),
     53                   chrome_main(0),
     54                   login_prompt_ready(0),
     55                   system(0),
     56                   chrome(0),
     57                   total(0) {}
     58   } BootTimes;
     59 
     60   // Signature
     61   typedef Callback2<Handle, BootTimes>::Type GetBootTimesCallback;
     62 
     63   typedef CancelableRequest<GetBootTimesCallback> GetBootTimesRequest;
     64 
     65   static BootTimesLoader* Get();
     66 
     67   // Asynchronously requests the info.
     68   Handle GetBootTimes(
     69       CancelableRequestConsumerBase* consumer,
     70       GetBootTimesCallback* callback);
     71 
     72   // Add a time marker for login. A timeline will be dumped to
     73   // /tmp/login-times-sent after login is done. If |send_to_uma| is true
     74   // the time between this marker and the last will be sent to UMA with
     75   // the identifier BootTime.|marker_name|.
     76   void AddLoginTimeMarker(const std::string& marker_name, bool send_to_uma);
     77 
     78   // Add a time marker for logout. A timeline will be dumped to
     79   // /tmp/logout-times-sent after logout is done. If |send_to_uma| is true
     80   // the time between this marker and the last will be sent to UMA with
     81   // the identifier ShutdownTime.|marker_name|.
     82   void AddLogoutTimeMarker(const std::string& marker_name, bool send_to_uma);
     83 
     84   // Records current uptime and disk usage for metrics use.
     85   // Posts task to file thread.
     86   // name will be used as part of file names in /tmp.
     87   // Existing stats files will not be overwritten.
     88   void RecordCurrentStats(const std::string& name);
     89 
     90   // Saves away the stats at main, so the can be recorded later. At main() time
     91   // the necessary threads don't exist yet for recording the data.
     92   void SaveChromeMainStats();
     93 
     94   // Records the data previously saved by SaveChromeMainStats(), using the
     95   // file thread. Existing stats files will not be overwritten.
     96   void RecordChromeMainStats();
     97 
     98   // Records the time that a login was attempted. This will overwrite any
     99   // previous login attempt times.
    100   void RecordLoginAttempted();
    101 
    102   // NotificationObserver implementation.
    103   virtual void Observe(NotificationType type,
    104                        const NotificationSource& source,
    105                        const NotificationDetails& details);
    106 
    107   // Writes the logout times to a /tmp/logout-times-sent. Unlike login
    108   // times, we manually call this function for logout times, as we cannot
    109   // rely on notification service to tell when the logout is done.
    110   void WriteLogoutTimes();
    111 
    112  private:
    113   // BootTimesLoader calls into the Backend on the file thread to load
    114   // the boot times.
    115   class Backend : public base::RefCountedThreadSafe<Backend> {
    116    public:
    117     Backend() {}
    118 
    119     void GetBootTimes(scoped_refptr<GetBootTimesRequest> request);
    120 
    121    private:
    122     friend class base::RefCountedThreadSafe<Backend>;
    123 
    124     ~Backend() {}
    125 
    126     DISALLOW_COPY_AND_ASSIGN(Backend);
    127   };
    128 
    129   class TimeMarker {
    130    public:
    131     TimeMarker(const std::string& name, bool send_to_uma)
    132         : name_(name),
    133           time_(base::Time::NowFromSystemTime()),
    134           send_to_uma_(send_to_uma) {}
    135     std::string name() const { return name_; }
    136     base::Time time() const { return time_; }
    137     bool send_to_uma() const { return send_to_uma_; }
    138 
    139    private:
    140     friend class std::vector<TimeMarker>;
    141     std::string name_;
    142     base::Time time_;
    143     bool send_to_uma_;
    144   };
    145 
    146   struct Stats {
    147    public:
    148     std::string uptime;
    149     std::string disk;
    150   };
    151 
    152   static void RecordStats(
    153       const std::string& name, const Stats& stats);
    154   static Stats GetCurrentStats();
    155   static void WriteTimes(const std::string base_name,
    156                          const std::string uma_name,
    157                          const std::string uma_prefix,
    158                          const std::vector<TimeMarker> login_times);
    159 
    160   // Used to hold the stats at main().
    161   Stats chrome_main_stats_;
    162   scoped_refptr<Backend> backend_;
    163 
    164   // Used to track notifications for login.
    165   NotificationRegistrar registrar_;
    166   base::AtomicSequenceNumber num_tabs_;
    167   bool have_registered_;
    168 
    169   std::vector<TimeMarker> login_time_markers_;
    170   std::vector<TimeMarker> logout_time_markers_;
    171 
    172   DISALLOW_COPY_AND_ASSIGN(BootTimesLoader);
    173 };
    174 
    175 }  // namespace chromeos
    176 
    177 #endif  // CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_
    178