Home | History | Annotate | Download | only in power
      1 // Copyright 2014 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_POWER_PROCESS_POWER_COLLECTOR_H_
      6 #define CHROME_BROWSER_POWER_PROCESS_POWER_COLLECTOR_H_
      7 
      8 #include <map>
      9 
     10 #include "base/memory/linked_ptr.h"
     11 #include "base/process/process_handle.h"
     12 #include "base/process/process_metrics.h"
     13 #include "base/timer/timer.h"
     14 #include "components/power/origin_power_map_factory.h"
     15 #include "url/gurl.h"
     16 
     17 #if defined(OS_CHROMEOS)
     18 #include "chromeos/dbus/power_manager_client.h"
     19 #endif
     20 
     21 class Profile;
     22 
     23 namespace content {
     24 class RenderProcessHost;
     25 }
     26 
     27 #if defined(OS_CHROMEOS)
     28 namespace power_manager {
     29 class PowerSupplyProperties;
     30 }
     31 #endif
     32 
     33 // Manages regular updates of the profile power consumption.
     34 class ProcessPowerCollector
     35 #if defined(OS_CHROMEOS)
     36     : public chromeos::PowerManagerClient::Observer
     37 #endif
     38       {
     39  public:
     40   class PerProcessData {
     41    public:
     42     PerProcessData(scoped_ptr<base::ProcessMetrics> metrics,
     43                    const GURL& origin,
     44                    Profile* profile);
     45     PerProcessData();
     46     ~PerProcessData();
     47 
     48     base::ProcessMetrics* metrics() const { return metrics_.get(); }
     49     Profile* profile() const { return profile_; }
     50     GURL last_origin() const { return last_origin_; }
     51     int last_cpu_percent() const { return last_cpu_percent_; }
     52     bool seen_this_cycle() const { return seen_this_cycle_; }
     53     void set_last_cpu_percent(double new_cpu) { last_cpu_percent_ = new_cpu; }
     54     void set_seen_this_cycle(bool seen) { seen_this_cycle_ = seen; }
     55 
     56    private:
     57     // |metrics_| holds the ProcessMetrics information for the given process.
     58     scoped_ptr<base::ProcessMetrics> metrics_;
     59 
     60     // |profile| is the profile that is visiting the |last_origin_|.
     61     // It is not owned by PerProcessData.
     62     Profile* profile_;
     63 
     64     // |last_origin_| is the last origin visited by the process.
     65     GURL last_origin_;
     66 
     67     // |last_cpu_percent_| is the proportion of the CPU used since the last
     68     // query.
     69     double last_cpu_percent_;
     70 
     71     // |seen_this_cycle| represents if the process still exists in this cycle.
     72     // If it doesn't, we erase the PerProcessData.
     73     bool seen_this_cycle_;
     74 
     75     DISALLOW_COPY_AND_ASSIGN(PerProcessData);
     76   };
     77 
     78   // A map from all process handles to a metric.
     79   typedef std::map<base::ProcessHandle, linked_ptr<PerProcessData> >
     80       ProcessMetricsMap;
     81   // A callback used to define mock CPU usage for testing.
     82   typedef base::Callback<double(base::ProcessHandle)> CpuUsageCallback;
     83 
     84   // On Chrome OS, can only be initialized after the DBusThreadManager has been
     85   // initialized.
     86   ProcessPowerCollector();
     87   // On Chrome OS, can only be destroyed before DBusThreadManager is.
     88   virtual ~ProcessPowerCollector();
     89 
     90   void set_cpu_usage_callback_for_testing(const CpuUsageCallback& callback) {
     91     cpu_usage_callback_ = callback;
     92   }
     93 
     94   ProcessMetricsMap* metrics_map_for_testing() { return &metrics_map_; }
     95 
     96 #if defined(OS_CHROMEOS)
     97   // PowerManagerClient::Observer implementation:
     98   virtual void PowerChanged(
     99       const power_manager::PowerSupplyProperties& prop) OVERRIDE;
    100 #endif
    101 
    102   // Begin periodically updating the power consumption numbers by profile.
    103   void Initialize();
    104 
    105   // Calls UpdatePowerConsumption() and returns the total CPU percent.
    106   double UpdatePowerConsumptionForTesting();
    107 
    108  private:
    109   // Starts the timer for updating the power consumption.
    110   void StartTimer();
    111 
    112   // Calls SynchronizerProcesses() and RecordCpuUsageByOrigin() to update the
    113   // |metrics_map_| and attribute power consumption. Invoked by |timer_| and as
    114   // a helper method for UpdatePowerConsumptionForTesting().
    115   double UpdatePowerConsumption();
    116 
    117   // Calls UpdatePowerConsumption(). Invoked by |timer_|.
    118   void HandleUpdateTimeout();
    119 
    120   // Synchronizes the currently active processes to the |metrics_map_| and
    121   // returns the total amount of cpu usage in the cycle.
    122   double SynchronizeProcesses();
    123 
    124   // Attributes the power usage to the profiles and origins using the
    125   // information from SynchronizeProcesses() given a total amount
    126   // of CPU used in this cycle, |total_cpu_percent|.
    127   void RecordCpuUsageByOrigin(double total_cpu_percent);
    128 
    129   // Adds the information from a given RenderProcessHost to the |metrics_map_|
    130   // for a given origin. Called by SynchronizeProcesses().
    131   void UpdateProcessInMap(const content::RenderProcessHost* render_process,
    132                           const GURL& origin);
    133 
    134   ProcessMetricsMap metrics_map_;
    135   base::RepeatingTimer<ProcessPowerCollector> timer_;
    136 
    137   // Callback to use to get CPU usage if set.
    138   CpuUsageCallback cpu_usage_callback_;
    139 
    140   // The factor to scale the CPU usage by.
    141   double scale_factor_;
    142 
    143   DISALLOW_COPY_AND_ASSIGN(ProcessPowerCollector);
    144 };
    145 
    146 #endif  // CHROME_BROWSER_POWER_PROCESS_POWER_COLLECTOR_H_
    147