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
15 namespace base {
16
Initialize(std::unique_ptr<PowerMonitorSource> source)17 void PowerMonitor::Initialize(std::unique_ptr<PowerMonitorSource> source) {
18 DCHECK(!IsInitialized());
19 PowerMonitor* power_monitor = GetInstance();
20 power_monitor->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 PowerMonitor::NotifyPowerStateChange(
25 PowerMonitor::Source()->IsOnBatteryPower());
26
27 PowerMonitor::PowerMonitor::NotifyThermalStateChange(
28 PowerMonitor::Source()->GetCurrentThermalState());
29
30 PowerMonitor::PowerMonitor::NotifySpeedLimitChange(
31 PowerMonitor::Source()->GetInitialSpeedLimit());
32 }
33
IsInitialized()34 bool PowerMonitor::IsInitialized() {
35 return GetInstance()->source_.get() != nullptr;
36 }
37
38 // static
AddPowerSuspendObserver(PowerSuspendObserver * obs)39 void PowerMonitor::AddPowerSuspendObserver(PowerSuspendObserver* obs) {
40 GetInstance()->power_suspend_observers_->AddObserver(obs);
41 }
42
43 // static
RemovePowerSuspendObserver(PowerSuspendObserver * obs)44 void PowerMonitor::RemovePowerSuspendObserver(PowerSuspendObserver* obs) {
45 GetInstance()->power_suspend_observers_->RemoveObserver(obs);
46 }
47
48 // static
AddPowerStateObserver(PowerStateObserver * obs)49 void PowerMonitor::AddPowerStateObserver(PowerStateObserver* obs) {
50 GetInstance()->power_state_observers_->AddObserver(obs);
51 }
52
53 // static
RemovePowerStateObserver(PowerStateObserver * obs)54 void PowerMonitor::RemovePowerStateObserver(PowerStateObserver* obs) {
55 GetInstance()->power_state_observers_->RemoveObserver(obs);
56 }
57
58 // static
AddPowerThermalObserver(PowerThermalObserver * obs)59 void PowerMonitor::AddPowerThermalObserver(PowerThermalObserver* obs) {
60 GetInstance()->thermal_state_observers_->AddObserver(obs);
61 }
62
63 // static
RemovePowerThermalObserver(PowerThermalObserver * obs)64 void PowerMonitor::RemovePowerThermalObserver(PowerThermalObserver* obs) {
65 GetInstance()->thermal_state_observers_->RemoveObserver(obs);
66 }
67
68 // static
AddPowerSuspendObserverAndReturnSuspendedState(PowerSuspendObserver * obs)69 bool PowerMonitor::AddPowerSuspendObserverAndReturnSuspendedState(
70 PowerSuspendObserver* obs) {
71 PowerMonitor* power_monitor = GetInstance();
72 AutoLock auto_lock(power_monitor->is_system_suspended_lock_);
73 power_monitor->power_suspend_observers_->AddObserver(obs);
74 return power_monitor->is_system_suspended_;
75 }
76
77 // static
AddPowerStateObserverAndReturnOnBatteryState(PowerStateObserver * obs)78 bool PowerMonitor::AddPowerStateObserverAndReturnOnBatteryState(
79 PowerStateObserver* obs) {
80 PowerMonitor* power_monitor = GetInstance();
81 AutoLock auto_lock(power_monitor->on_battery_power_lock_);
82 power_monitor->power_state_observers_->AddObserver(obs);
83 return power_monitor->on_battery_power_;
84 }
85
86 // static
87 PowerThermalObserver::DeviceThermalState
AddPowerStateObserverAndReturnPowerThermalState(PowerThermalObserver * obs)88 PowerMonitor::AddPowerStateObserverAndReturnPowerThermalState(
89 PowerThermalObserver* obs) {
90 PowerMonitor* power_monitor = GetInstance();
91 AutoLock auto_lock(power_monitor->power_thermal_state_lock_);
92 power_monitor->thermal_state_observers_->AddObserver(obs);
93 return power_monitor->power_thermal_state_;
94 }
95
Source()96 PowerMonitorSource* PowerMonitor::Source() {
97 return GetInstance()->source_.get();
98 }
99
IsOnBatteryPower()100 bool PowerMonitor::IsOnBatteryPower() {
101 DCHECK(IsInitialized());
102 PowerMonitor* power_monitor = GetInstance();
103 AutoLock auto_lock(power_monitor->on_battery_power_lock_);
104 return power_monitor->on_battery_power_;
105 }
106
GetLastSystemResumeTime()107 TimeTicks PowerMonitor::GetLastSystemResumeTime() {
108 PowerMonitor* power_monitor = GetInstance();
109 AutoLock auto_lock(power_monitor->is_system_suspended_lock_);
110 return power_monitor->last_system_resume_time_;
111 }
112
ShutdownForTesting()113 void PowerMonitor::ShutdownForTesting() {
114 GetInstance()->source_ = nullptr;
115
116 PowerMonitor* power_monitor = GetInstance();
117 {
118 AutoLock auto_lock(power_monitor->is_system_suspended_lock_);
119 power_monitor->is_system_suspended_ = false;
120 power_monitor->last_system_resume_time_ = TimeTicks();
121 }
122 {
123 AutoLock auto_lock(power_monitor->on_battery_power_lock_);
124 power_monitor->on_battery_power_ = false;
125 }
126 {
127 AutoLock auto_lock(power_monitor->power_thermal_state_lock_);
128 power_monitor->power_thermal_state_ =
129 PowerThermalObserver::DeviceThermalState::kUnknown;
130 }
131 }
132
133 // static
134 PowerThermalObserver::DeviceThermalState
GetCurrentThermalState()135 PowerMonitor::GetCurrentThermalState() {
136 DCHECK(IsInitialized());
137 return GetInstance()->source_->GetCurrentThermalState();
138 }
139
140 // static
SetCurrentThermalState(PowerThermalObserver::DeviceThermalState state)141 void PowerMonitor::SetCurrentThermalState(
142 PowerThermalObserver::DeviceThermalState state) {
143 DCHECK(IsInitialized());
144 GetInstance()->source_->SetCurrentThermalState(state);
145 }
146
147 #if BUILDFLAG(IS_ANDROID)
GetRemainingBatteryCapacity()148 int PowerMonitor::GetRemainingBatteryCapacity() {
149 DCHECK(IsInitialized());
150 return PowerMonitor::Source()->GetRemainingBatteryCapacity();
151 }
152 #endif // BUILDFLAG(IS_ANDROID)
153
NotifyPowerStateChange(bool on_battery_power)154 void PowerMonitor::NotifyPowerStateChange(bool on_battery_power) {
155 DCHECK(IsInitialized());
156 DVLOG(1) << "PowerStateChange: " << (on_battery_power ? "On" : "Off")
157 << " battery";
158
159 PowerMonitor* power_monitor = GetInstance();
160 AutoLock auto_lock(power_monitor->on_battery_power_lock_);
161 if (power_monitor->on_battery_power_ != on_battery_power) {
162 power_monitor->on_battery_power_ = on_battery_power;
163 GetInstance()->power_state_observers_->Notify(
164 FROM_HERE, &PowerStateObserver::OnPowerStateChange, on_battery_power);
165 }
166 }
167
NotifySuspend()168 void PowerMonitor::NotifySuspend() {
169 DCHECK(IsInitialized());
170 TRACE_EVENT_INSTANT0("base", "PowerMonitor::NotifySuspend",
171 TRACE_EVENT_SCOPE_PROCESS);
172 DVLOG(1) << "Power Suspending";
173
174 PowerMonitor* power_monitor = GetInstance();
175 AutoLock auto_lock(power_monitor->is_system_suspended_lock_);
176 if (!power_monitor->is_system_suspended_) {
177 power_monitor->is_system_suspended_ = true;
178 power_monitor->last_system_resume_time_ = TimeTicks::Max();
179 GetInstance()->power_suspend_observers_->Notify(
180 FROM_HERE, &PowerSuspendObserver::OnSuspend);
181 }
182 }
183
NotifyResume()184 void PowerMonitor::NotifyResume() {
185 DCHECK(IsInitialized());
186 TRACE_EVENT_INSTANT0("base", "PowerMonitor::NotifyResume",
187 TRACE_EVENT_SCOPE_PROCESS);
188 DVLOG(1) << "Power Resuming";
189
190 TimeTicks resume_time = TimeTicks::Now();
191
192 PowerMonitor* power_monitor = GetInstance();
193 AutoLock auto_lock(power_monitor->is_system_suspended_lock_);
194 if (power_monitor->is_system_suspended_) {
195 power_monitor->is_system_suspended_ = false;
196 power_monitor->last_system_resume_time_ = resume_time;
197 GetInstance()->power_suspend_observers_->Notify(
198 FROM_HERE, &PowerSuspendObserver::OnResume);
199 }
200 }
201
NotifyThermalStateChange(PowerThermalObserver::DeviceThermalState new_state)202 void PowerMonitor::NotifyThermalStateChange(
203 PowerThermalObserver::DeviceThermalState new_state) {
204 DCHECK(IsInitialized());
205 DVLOG(1) << "ThermalStateChange: "
206 << PowerMonitorSource::DeviceThermalStateToString(new_state);
207
208 PowerMonitor* power_monitor = GetInstance();
209 AutoLock auto_lock(power_monitor->power_thermal_state_lock_);
210 if (power_monitor->power_thermal_state_ != new_state) {
211 power_monitor->power_thermal_state_ = new_state;
212 GetInstance()->thermal_state_observers_->Notify(
213 FROM_HERE, &PowerThermalObserver::OnThermalStateChange, new_state);
214 }
215 }
216
NotifySpeedLimitChange(int speed_limit)217 void PowerMonitor::NotifySpeedLimitChange(int speed_limit) {
218 DCHECK(IsInitialized());
219 DVLOG(1) << "SpeedLimitChange: " << speed_limit;
220
221 PowerMonitor* power_monitor = GetInstance();
222 AutoLock auto_lock(power_monitor->power_thermal_state_lock_);
223 if (power_monitor->speed_limit_ != speed_limit) {
224 power_monitor->speed_limit_ = speed_limit;
225 GetInstance()->thermal_state_observers_->Notify(
226 FROM_HERE, &PowerThermalObserver::OnSpeedLimitChange, speed_limit);
227 }
228 }
229
GetInstance()230 PowerMonitor* PowerMonitor::GetInstance() {
231 static base::NoDestructor<PowerMonitor> power_monitor;
232 return power_monitor.get();
233 }
234
PowerMonitor()235 PowerMonitor::PowerMonitor()
236 : power_state_observers_(
237 base::MakeRefCounted<ObserverListThreadSafe<PowerStateObserver>>()),
238 power_suspend_observers_(
239 base::MakeRefCounted<ObserverListThreadSafe<PowerSuspendObserver>>()),
240 thermal_state_observers_(
241 base::MakeRefCounted<
242 ObserverListThreadSafe<PowerThermalObserver>>()) {}
243
244 PowerMonitor::~PowerMonitor() = default;
245
246 } // namespace base
247