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