• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors
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 BASE_POWER_MONITOR_POWER_MONITOR_H_
6 #define BASE_POWER_MONITOR_POWER_MONITOR_H_
7 
8 #include <memory>
9 
10 #include "base/base_export.h"
11 #include "base/no_destructor.h"
12 #include "base/observer_list_threadsafe.h"
13 #include "base/power_monitor/power_observer.h"
14 #include "base/time/time.h"
15 #include "base/trace_event/base_tracing.h"
16 #include "build/build_config.h"
17 
18 namespace base {
19 
20 class PowerMonitorSource;
21 
22 // A class used to monitor the power state change and notify the observers about
23 // the change event. The threading model of this class is as follows:
24 // Once initialized, it is threadsafe. However, the client must ensure that
25 // initialization happens before any other methods are invoked, including
26 // IsInitialized(). IsInitialized() exists only as a convenience for detection
27 // of test contexts where the PowerMonitor global is never created.
28 class BASE_EXPORT PowerMonitor {
29  public:
30   static PowerMonitor* GetInstance();
31 
32   // Initializes global PowerMonitor state. Takes ownership of |source|, which
33   // will be leaked on process teardown. May only be called once. Not threadsafe
34   // - no other PowerMonitor methods may be called on any thread while calling
35   // Initialize(). |source| must not be nullptr.
36   void Initialize(std::unique_ptr<PowerMonitorSource> source);
37 
38   PowerMonitor(const PowerMonitor&) = delete;
39   PowerMonitor& operator=(const PowerMonitor&) = delete;
40 
41   // Returns true if Initialize() has been called. Safe to call on any thread,
42   // but must not be called while Initialize() or ShutdownForTesting() is being
43   // invoked.
44   bool IsInitialized() const;
45 
46   // Add and remove an observer.
47   // Can be called from any thread. |observer| is notified on the sequence
48   // from which it was registered.
49   // Must not be called from within a notification callback.
50   //
51   // It is safe to add observers before the PowerMonitor is initialized. It is
52   // safe to remove an observer even if it was not added as an observer.
53   void AddPowerSuspendObserver(PowerSuspendObserver* observer);
54   void RemovePowerSuspendObserver(PowerSuspendObserver* observer);
55   void AddPowerStateObserver(PowerStateObserver* observer);
56   void RemovePowerStateObserver(PowerStateObserver* observer);
57   void AddPowerThermalObserver(PowerThermalObserver* observer);
58   void RemovePowerThermalObserver(PowerThermalObserver* observer);
59 
60   // Atomically add a PowerSuspendObserver and read the current power suspended
61   // state. This variant must be used to avoid race between adding an observer
62   // and reading the power state. The following code would be racy:
63   //    AddOPowerSuspendbserver(...);
64   //    if (PowerMonitor::IsSystemSuspended()) { ... }
65   //
66   // Returns true if the system is currently suspended.
67   bool AddPowerSuspendObserverAndReturnSuspendedState(
68       PowerSuspendObserver* observer);
69   // Returns true if the system is on-battery.
70   bool AddPowerStateObserverAndReturnOnBatteryState(
71       PowerStateObserver* observer);
72   PowerStateObserver::BatteryPowerStatus
73   AddPowerStateObserverAndReturnBatteryPowerStatus(
74       PowerStateObserver* observer);
75   // Returns the power thermal state.
76   PowerThermalObserver::DeviceThermalState
77   AddPowerStateObserverAndReturnPowerThermalState(
78       PowerThermalObserver* observer);
79 
80   // Is the computer currently on battery power. May only be called if the
81   // PowerMonitor has been initialized.
82   bool IsOnBatteryPower() const;
83 
84   // Returns the current state of the battery power, that can be unknown if the
85   // value isn't initialized yet. May only be called if the PowerMonitor has
86   // been initialized.
87   PowerStateObserver::BatteryPowerStatus GetBatteryPowerStatus() const;
88 
89   // Returns the time of the last system resume. If no system suspend/resume was
90   // observed, returns an empty time. If the system is currently suspended,
91   // returns TimeTicks::Max().
92   TimeTicks GetLastSystemResumeTime() const;
93 
94   // Read the current DeviceThermalState if known. Can be called on any thread.
95   // May only be called if the PowerMonitor has been initialized.
96   PowerThermalObserver::DeviceThermalState GetCurrentThermalState() const;
97 
98   // Update the result of thermal state.
99   void SetCurrentThermalState(PowerThermalObserver::DeviceThermalState state);
100 
101 #if BUILDFLAG(IS_ANDROID)
102   // Read and return the current remaining battery capacity (microampere-hours).
103   // Only supported with a device power source (i.e. not in child processes in
104   // Chrome) and on devices with Android >= Lollipop as well as a power supply
105   // that supports this counter. Returns 0 if unsupported.
106   int GetRemainingBatteryCapacity() const;
107 #endif  // BUILDFLAG(IS_ANDROID)
108 
109   // Uninitializes the PowerMonitor. Should be called at the end of any unit
110   // test that mocks out the PowerMonitor, to avoid affecting subsequent tests.
111   // There must be no live observers when invoked. Safe to call even if the
112   // PowerMonitor hasn't been initialized.
113   void ShutdownForTesting();
114 
115  private:
116   friend class PowerMonitorSource;
117   friend class base::NoDestructor<PowerMonitor>;
118 
119   PowerMonitor();
120   ~PowerMonitor();
121 
122   const PowerMonitorSource* Source() const;
123 
124   void NotifyPowerStateChange(bool on_battery_power);
125   void NotifyPowerStateChange(
126       PowerStateObserver::BatteryPowerStatus battery_power_status);
127   void NotifySuspend();
128   void NotifyResume();
129   void NotifyThermalStateChange(
130       PowerThermalObserver::DeviceThermalState new_state);
131   void NotifySpeedLimitChange(int speed_limit);
132 
133   bool is_system_suspended_ GUARDED_BY(is_system_suspended_lock_) = false;
134   mutable Lock is_system_suspended_lock_;
135   TimeTicks last_system_resume_time_ GUARDED_BY(is_system_suspended_lock_);
136 
137   PowerStateObserver::BatteryPowerStatus battery_power_status_
138       GUARDED_BY(battery_power_status_lock_) =
139           PowerStateObserver::BatteryPowerStatus::kUnknown;
140 
141   mutable Lock battery_power_status_lock_;
142 
143   perfetto::NamedTrack process_track_;
144   PowerThermalObserver::DeviceThermalState power_thermal_state_
145       GUARDED_BY(power_thermal_state_lock_) =
146           PowerThermalObserver::DeviceThermalState::kUnknown;
147   int speed_limit_ GUARDED_BY(power_thermal_state_lock_) =
148       PowerThermalObserver::kSpeedLimitMax;
149   Lock power_thermal_state_lock_;
150 
151   scoped_refptr<ObserverListThreadSafe<PowerStateObserver>>
152       power_state_observers_;
153   scoped_refptr<ObserverListThreadSafe<PowerSuspendObserver>>
154       power_suspend_observers_;
155   scoped_refptr<ObserverListThreadSafe<PowerThermalObserver>>
156       thermal_state_observers_;
157   std::unique_ptr<PowerMonitorSource> source_;
158 };
159 
160 }  // namespace base
161 
162 #endif  // BASE_POWER_MONITOR_POWER_MONITOR_H_
163