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