• 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 #include "base/power_monitor/power_monitor.h"
6 
7 #include <utility>
8 
9 #include "base/logging.h"
10 #include "base/no_destructor.h"
11 #include "base/power_monitor/power_monitor_source.h"
12 #include "base/trace_event/base_tracing.h"
13 #include "build/build_config.h"
14 #include "power_observer.h"
15 
16 namespace base {
17 
Initialize(std::unique_ptr<PowerMonitorSource> source)18 void PowerMonitor::Initialize(std::unique_ptr<PowerMonitorSource> source) {
19   DCHECK(!IsInitialized());
20   source_ = std::move(source);
21 
22   // When a power source is associated with the power monitor, ensure the
23   // initial state is propagated to observers, if needed.
24   NotifyPowerStateChange(Source()->GetBatteryPowerStatus());
25 
26   NotifyThermalStateChange(Source()->GetCurrentThermalState());
27 
28   NotifySpeedLimitChange(Source()->GetInitialSpeedLimit());
29 }
30 
IsInitialized() const31 bool PowerMonitor::IsInitialized() const {
32   return source_ != nullptr;
33 }
34 
AddPowerSuspendObserver(PowerSuspendObserver * obs)35 void PowerMonitor::AddPowerSuspendObserver(PowerSuspendObserver* obs) {
36   power_suspend_observers_->AddObserver(obs);
37 }
38 
RemovePowerSuspendObserver(PowerSuspendObserver * obs)39 void PowerMonitor::RemovePowerSuspendObserver(PowerSuspendObserver* obs) {
40   power_suspend_observers_->RemoveObserver(obs);
41 }
42 
AddPowerStateObserver(PowerStateObserver * obs)43 void PowerMonitor::AddPowerStateObserver(PowerStateObserver* obs) {
44   power_state_observers_->AddObserver(obs);
45 }
46 
RemovePowerStateObserver(PowerStateObserver * obs)47 void PowerMonitor::RemovePowerStateObserver(PowerStateObserver* obs) {
48   power_state_observers_->RemoveObserver(obs);
49 }
50 
AddPowerThermalObserver(PowerThermalObserver * obs)51 void PowerMonitor::AddPowerThermalObserver(PowerThermalObserver* obs) {
52   thermal_state_observers_->AddObserver(obs);
53 }
54 
RemovePowerThermalObserver(PowerThermalObserver * obs)55 void PowerMonitor::RemovePowerThermalObserver(PowerThermalObserver* obs) {
56   thermal_state_observers_->RemoveObserver(obs);
57 }
58 
AddPowerSuspendObserverAndReturnSuspendedState(PowerSuspendObserver * obs)59 bool PowerMonitor::AddPowerSuspendObserverAndReturnSuspendedState(
60     PowerSuspendObserver* obs) {
61   AutoLock auto_lock(is_system_suspended_lock_);
62   power_suspend_observers_->AddObserver(obs);
63   return is_system_suspended_;
64 }
65 
66 // static
AddPowerStateObserverAndReturnOnBatteryState(PowerStateObserver * obs)67 bool PowerMonitor::AddPowerStateObserverAndReturnOnBatteryState(
68     PowerStateObserver* obs) {
69   return AddPowerStateObserverAndReturnBatteryPowerStatus(obs) ==
70          PowerStateObserver::BatteryPowerStatus::kBatteryPower;
71 }
72 
73 PowerStateObserver::BatteryPowerStatus
AddPowerStateObserverAndReturnBatteryPowerStatus(PowerStateObserver * obs)74 PowerMonitor::AddPowerStateObserverAndReturnBatteryPowerStatus(
75     PowerStateObserver* obs) {
76   AutoLock auto_lock(battery_power_status_lock_);
77   power_state_observers_->AddObserver(obs);
78   return battery_power_status_;
79 }
80 
81 // static
82 PowerThermalObserver::DeviceThermalState
AddPowerStateObserverAndReturnPowerThermalState(PowerThermalObserver * obs)83 PowerMonitor::AddPowerStateObserverAndReturnPowerThermalState(
84     PowerThermalObserver* obs) {
85   AutoLock auto_lock(power_thermal_state_lock_);
86   thermal_state_observers_->AddObserver(obs);
87   return power_thermal_state_;
88 }
89 
Source() const90 const PowerMonitorSource* PowerMonitor::Source() const {
91   return source_.get();
92 }
93 
IsOnBatteryPower() const94 bool PowerMonitor::IsOnBatteryPower() const {
95   DCHECK(IsInitialized());
96   return GetBatteryPowerStatus() ==
97          PowerStateObserver::BatteryPowerStatus::kBatteryPower;
98 }
99 
GetBatteryPowerStatus() const100 PowerStateObserver::BatteryPowerStatus PowerMonitor::GetBatteryPowerStatus()
101     const {
102   DCHECK(IsInitialized());
103   AutoLock auto_lock(battery_power_status_lock_);
104   return battery_power_status_;
105 }
106 
GetLastSystemResumeTime() const107 TimeTicks PowerMonitor::GetLastSystemResumeTime() const {
108   AutoLock auto_lock(is_system_suspended_lock_);
109   return last_system_resume_time_;
110 }
111 
ShutdownForTesting()112 void PowerMonitor::ShutdownForTesting() {
113   source_ = nullptr;
114 
115   {
116     AutoLock auto_lock(is_system_suspended_lock_);
117     is_system_suspended_ = false;
118     last_system_resume_time_ = TimeTicks();
119   }
120   {
121     AutoLock auto_lock(battery_power_status_lock_);
122     battery_power_status_ = PowerStateObserver::BatteryPowerStatus::kUnknown;
123   }
124   {
125     AutoLock auto_lock(power_thermal_state_lock_);
126     power_thermal_state_ = PowerThermalObserver::DeviceThermalState::kUnknown;
127   }
128 }
129 
130 // static
GetCurrentThermalState() const131 PowerThermalObserver::DeviceThermalState PowerMonitor::GetCurrentThermalState()
132     const {
133   DCHECK(IsInitialized());
134   return source_->GetCurrentThermalState();
135 }
136 
137 // static
SetCurrentThermalState(PowerThermalObserver::DeviceThermalState state)138 void PowerMonitor::SetCurrentThermalState(
139     PowerThermalObserver::DeviceThermalState state) {
140   DCHECK(IsInitialized());
141   source_->SetCurrentThermalState(state);
142 }
143 
144 #if BUILDFLAG(IS_ANDROID)
GetRemainingBatteryCapacity() const145 int PowerMonitor::GetRemainingBatteryCapacity() const {
146   DCHECK(IsInitialized());
147   return Source()->GetRemainingBatteryCapacity();
148 }
149 #endif  // BUILDFLAG(IS_ANDROID)
150 
NotifyPowerStateChange(bool on_battery_power)151 void PowerMonitor::NotifyPowerStateChange(bool on_battery_power) {
152   DCHECK(IsInitialized());
153   NotifyPowerStateChange(
154       on_battery_power
155           ? PowerStateObserver::BatteryPowerStatus::kBatteryPower
156           : PowerStateObserver::BatteryPowerStatus::kExternalPower);
157 }
158 
NotifyPowerStateChange(PowerStateObserver::BatteryPowerStatus battery_power_status)159 void PowerMonitor::NotifyPowerStateChange(
160     PowerStateObserver::BatteryPowerStatus battery_power_status) {
161   DCHECK(IsInitialized());
162 
163   if (battery_power_status ==
164       PowerStateObserver::BatteryPowerStatus::kUnknown) {
165     DVLOG(1) << "PowerStateChange: with unknown value";
166   } else {
167     DVLOG(1) << "PowerStateChange: "
168              << (battery_power_status ==
169                          PowerStateObserver::BatteryPowerStatus::kBatteryPower
170                      ? "On"
171                      : "Off")
172              << " battery";
173     TRACE_EVENT_INSTANT(
174         "power",
175         battery_power_status ==
176                 PowerStateObserver::BatteryPowerStatus::kBatteryPower
177             ? perfetto::StaticString("PowerMonitor::BatteryPower")
178             : perfetto::StaticString("PowerMonitor::ExternalPower"),
179         process_track_);
180   }
181 
182   AutoLock auto_lock(battery_power_status_lock_);
183   if (battery_power_status_ != battery_power_status) {
184     battery_power_status_ = battery_power_status;
185     power_state_observers_->Notify(
186         FROM_HERE, &PowerStateObserver::OnBatteryPowerStatusChange,
187         battery_power_status);
188   }
189 }
190 
NotifySuspend()191 void PowerMonitor::NotifySuspend() {
192   DCHECK(IsInitialized());
193   TRACE_EVENT_INSTANT("power", "PowerMonitor::NotifySuspend", process_track_);
194   DVLOG(1) << "Power Suspending";
195 
196   AutoLock auto_lock(is_system_suspended_lock_);
197   if (!is_system_suspended_) {
198     is_system_suspended_ = true;
199     last_system_resume_time_ = TimeTicks::Max();
200     power_suspend_observers_->Notify(FROM_HERE,
201                                      &PowerSuspendObserver::OnSuspend);
202   }
203 }
204 
NotifyResume()205 void PowerMonitor::NotifyResume() {
206   DCHECK(IsInitialized());
207   TRACE_EVENT_INSTANT("power", "PowerMonitor::NotifyResume", process_track_);
208   DVLOG(1) << "Power Resuming";
209 
210   TimeTicks resume_time = TimeTicks::Now();
211 
212   AutoLock auto_lock(is_system_suspended_lock_);
213   if (is_system_suspended_) {
214     is_system_suspended_ = false;
215     last_system_resume_time_ = resume_time;
216     power_suspend_observers_->Notify(FROM_HERE,
217                                      &PowerSuspendObserver::OnResume);
218   }
219 }
220 
NotifyThermalStateChange(PowerThermalObserver::DeviceThermalState new_state)221 void PowerMonitor::NotifyThermalStateChange(
222     PowerThermalObserver::DeviceThermalState new_state) {
223   DCHECK(IsInitialized());
224   DVLOG(1) << "ThermalStateChange: "
225            << PowerMonitorSource::DeviceThermalStateToString(new_state);
226 
227   AutoLock auto_lock(power_thermal_state_lock_);
228   if (power_thermal_state_ != new_state) {
229     power_thermal_state_ = new_state;
230     thermal_state_observers_->Notify(
231         FROM_HERE, &PowerThermalObserver::OnThermalStateChange, new_state);
232   }
233 }
234 
NotifySpeedLimitChange(int speed_limit)235 void PowerMonitor::NotifySpeedLimitChange(int speed_limit) {
236   DCHECK(IsInitialized());
237   DVLOG(1) << "SpeedLimitChange: " << speed_limit;
238 
239   AutoLock auto_lock(power_thermal_state_lock_);
240   if (speed_limit_ != speed_limit) {
241     speed_limit_ = speed_limit;
242     thermal_state_observers_->Notify(
243         FROM_HERE, &PowerThermalObserver::OnSpeedLimitChange, speed_limit);
244   }
245 }
246 
GetInstance()247 PowerMonitor* PowerMonitor::GetInstance() {
248   static base::NoDestructor<PowerMonitor> power_monitor;
249   return power_monitor.get();
250 }
251 
PowerMonitor()252 PowerMonitor::PowerMonitor()
253     : process_track_("PowerMonitor"),
254       power_state_observers_(
255           base::MakeRefCounted<ObserverListThreadSafe<PowerStateObserver>>()),
256       power_suspend_observers_(
257           base::MakeRefCounted<ObserverListThreadSafe<PowerSuspendObserver>>()),
258       thermal_state_observers_(
259           base::MakeRefCounted<
260               ObserverListThreadSafe<PowerThermalObserver>>()) {}
261 
262 PowerMonitor::~PowerMonitor() = default;
263 
264 }  // namespace base
265