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 "base/test/power_monitor_test.h"
8 #include "base/test/task_environment.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/abseil-cpp/absl/types/optional.h"
11
12 namespace base {
13 namespace test {
14
15 class PowerMonitorTest : public testing::Test {
16 public:
17 PowerMonitorTest(const PowerMonitorTest&) = delete;
18 PowerMonitorTest& operator=(const PowerMonitorTest&) = delete;
19
20 protected:
21 PowerMonitorTest() = default;
22
PowerMonitorInitialize()23 void PowerMonitorInitialize() { power_monitor_source_.emplace(); }
24
source()25 ScopedPowerMonitorTestSource& source() {
26 return power_monitor_source_.value();
27 }
28
29 private:
30 TaskEnvironment task_environment_;
31 absl::optional<ScopedPowerMonitorTestSource> power_monitor_source_;
32 };
33
34 // PowerMonitorSource is tightly coupled with the PowerMonitor, so this test
35 // covers both classes.
TEST_F(PowerMonitorTest,PowerNotifications)36 TEST_F(PowerMonitorTest, PowerNotifications) {
37 const int kObservers = 5;
38
39 PowerMonitorInitialize();
40
41 PowerMonitorTestObserver observers[kObservers];
42 for (auto& index : observers) {
43 PowerMonitor::AddPowerSuspendObserver(&index);
44 PowerMonitor::AddPowerStateObserver(&index);
45 PowerMonitor::AddPowerThermalObserver(&index);
46 }
47
48 // Sending resume when not suspended should have no effect.
49 source().GenerateResumeEvent();
50 EXPECT_EQ(observers[0].resumes(), 0);
51
52 // Pretend we suspended.
53 source().GenerateSuspendEvent();
54 // Ensure all observers were notified of the event
55 for (const auto& index : observers)
56 EXPECT_EQ(index.suspends(), 1);
57
58 // Send a second suspend notification. This should be suppressed.
59 source().GenerateSuspendEvent();
60 EXPECT_EQ(observers[0].suspends(), 1);
61
62 // Pretend we were awakened.
63 source().GenerateResumeEvent();
64 EXPECT_EQ(observers[0].resumes(), 1);
65
66 // Send a duplicate resume notification. This should be suppressed.
67 source().GenerateResumeEvent();
68 EXPECT_EQ(observers[0].resumes(), 1);
69
70 // Pretend the device has gone on battery power
71 source().GeneratePowerStateEvent(true);
72 EXPECT_EQ(observers[0].power_state_changes(), 1);
73 EXPECT_EQ(observers[0].last_power_state(), true);
74
75 // Repeated indications the device is on battery power should be suppressed.
76 source().GeneratePowerStateEvent(true);
77 EXPECT_EQ(observers[0].power_state_changes(), 1);
78
79 // Pretend the device has gone off battery power
80 source().GeneratePowerStateEvent(false);
81 EXPECT_EQ(observers[0].power_state_changes(), 2);
82 EXPECT_EQ(observers[0].last_power_state(), false);
83
84 // Repeated indications the device is off battery power should be suppressed.
85 source().GeneratePowerStateEvent(false);
86 EXPECT_EQ(observers[0].power_state_changes(), 2);
87
88 // Send speed limit change notifications.
89 source().GenerateSpeedLimitEvent(666);
90 EXPECT_EQ(observers[0].speed_limit_changes(), 1);
91 EXPECT_EQ(observers[0].last_speed_limit(), 666);
92 source().GenerateSpeedLimitEvent(777);
93 EXPECT_EQ(observers[0].speed_limit_changes(), 2);
94 EXPECT_EQ(observers[0].last_speed_limit(), 777);
95
96 EXPECT_EQ(observers[0].thermal_state_changes(), 0);
97
98 // Send a power thermal change notification.
99 source().GenerateThermalThrottlingEvent(
100 PowerThermalObserver::DeviceThermalState::kNominal);
101 EXPECT_EQ(observers[0].thermal_state_changes(), 1);
102 EXPECT_EQ(observers[0].last_thermal_state(),
103 PowerThermalObserver::DeviceThermalState::kNominal);
104
105 // Send a duplicate power thermal notification. This should be suppressed.
106 source().GenerateThermalThrottlingEvent(
107 PowerThermalObserver::DeviceThermalState::kNominal);
108 EXPECT_EQ(observers[0].thermal_state_changes(), 1);
109
110 // Send a different power thermal change notification.
111 source().GenerateThermalThrottlingEvent(
112 PowerThermalObserver::DeviceThermalState::kFair);
113 EXPECT_EQ(observers[0].thermal_state_changes(), 2);
114 EXPECT_EQ(observers[0].last_thermal_state(),
115 PowerThermalObserver::DeviceThermalState::kFair);
116
117 for (auto& index : observers) {
118 PowerMonitor::RemovePowerSuspendObserver(&index);
119 PowerMonitor::RemovePowerStateObserver(&index);
120 PowerMonitor::RemovePowerThermalObserver(&index);
121 }
122 }
123
TEST_F(PowerMonitorTest,ThermalThrottling)124 TEST_F(PowerMonitorTest, ThermalThrottling) {
125 PowerMonitorTestObserver observer;
126 PowerMonitor::AddPowerThermalObserver(&observer);
127
128 PowerMonitorInitialize();
129
130 constexpr PowerThermalObserver::DeviceThermalState kThermalStates[] = {
131 PowerThermalObserver::DeviceThermalState::kUnknown,
132 PowerThermalObserver::DeviceThermalState::kNominal,
133 PowerThermalObserver::DeviceThermalState::kFair,
134 PowerThermalObserver::DeviceThermalState::kSerious,
135 PowerThermalObserver::DeviceThermalState::kCritical};
136
137 for (const auto state : kThermalStates) {
138 source().GenerateThermalThrottlingEvent(state);
139 EXPECT_EQ(state, source().GetCurrentThermalState());
140 EXPECT_EQ(observer.last_thermal_state(), state);
141 }
142
143 PowerMonitor::RemovePowerThermalObserver(&observer);
144 }
145
TEST_F(PowerMonitorTest,AddPowerSuspendObserverBeforeAndAfterInitialization)146 TEST_F(PowerMonitorTest, AddPowerSuspendObserverBeforeAndAfterInitialization) {
147 PowerMonitorTestObserver observer1;
148 PowerMonitorTestObserver observer2;
149
150 // An observer is added before the PowerMonitor initialization.
151 PowerMonitor::AddPowerSuspendObserver(&observer1);
152
153 PowerMonitorInitialize();
154
155 // An observer is added after the PowerMonitor initialization.
156 PowerMonitor::AddPowerSuspendObserver(&observer2);
157
158 // Simulate suspend/resume notifications.
159 source().GenerateSuspendEvent();
160 EXPECT_EQ(observer1.suspends(), 1);
161 EXPECT_EQ(observer2.suspends(), 1);
162 EXPECT_EQ(observer1.resumes(), 0);
163 EXPECT_EQ(observer2.resumes(), 0);
164
165 source().GenerateResumeEvent();
166 EXPECT_EQ(observer1.resumes(), 1);
167 EXPECT_EQ(observer2.resumes(), 1);
168
169 PowerMonitor::RemovePowerSuspendObserver(&observer1);
170 PowerMonitor::RemovePowerSuspendObserver(&observer2);
171 }
172
TEST_F(PowerMonitorTest,AddPowerStateObserverBeforeAndAfterInitialization)173 TEST_F(PowerMonitorTest, AddPowerStateObserverBeforeAndAfterInitialization) {
174 PowerMonitorTestObserver observer1;
175 PowerMonitorTestObserver observer2;
176
177 // An observer is added before the PowerMonitor initialization.
178 PowerMonitor::AddPowerStateObserver(&observer1);
179
180 PowerMonitorInitialize();
181
182 // An observer is added after the PowerMonitor initialization.
183 PowerMonitor::AddPowerStateObserver(&observer2);
184
185 // Simulate power state transitions (e.g. battery on/off).
186 EXPECT_EQ(observer1.power_state_changes(), 0);
187 EXPECT_EQ(observer2.power_state_changes(), 0);
188 source().GeneratePowerStateEvent(true);
189 EXPECT_EQ(observer1.power_state_changes(), 1);
190 EXPECT_EQ(observer2.power_state_changes(), 1);
191 source().GeneratePowerStateEvent(false);
192 EXPECT_EQ(observer1.power_state_changes(), 2);
193 EXPECT_EQ(observer2.power_state_changes(), 2);
194
195 PowerMonitor::RemovePowerStateObserver(&observer1);
196 PowerMonitor::RemovePowerStateObserver(&observer2);
197 }
198
TEST_F(PowerMonitorTest,SuspendStateReturnedFromAddObserver)199 TEST_F(PowerMonitorTest, SuspendStateReturnedFromAddObserver) {
200 PowerMonitorTestObserver observer1;
201 PowerMonitorTestObserver observer2;
202
203 PowerMonitorInitialize();
204
205 EXPECT_FALSE(
206 PowerMonitor::AddPowerSuspendObserverAndReturnSuspendedState(&observer1));
207
208 source().GenerateSuspendEvent();
209
210 EXPECT_TRUE(
211 PowerMonitor::AddPowerSuspendObserverAndReturnSuspendedState(&observer2));
212
213 EXPECT_EQ(observer1.suspends(), 1);
214 EXPECT_EQ(observer2.suspends(), 0);
215 EXPECT_EQ(observer1.resumes(), 0);
216 EXPECT_EQ(observer2.resumes(), 0);
217
218 PowerMonitor::RemovePowerSuspendObserver(&observer1);
219 PowerMonitor::RemovePowerSuspendObserver(&observer2);
220 }
221
TEST_F(PowerMonitorTest,PowerStateReturnedFromAddObserver)222 TEST_F(PowerMonitorTest, PowerStateReturnedFromAddObserver) {
223 PowerMonitorTestObserver observer1;
224 PowerMonitorTestObserver observer2;
225
226 PowerMonitorInitialize();
227
228 // An observer is added before the on-battery notification.
229 EXPECT_FALSE(
230 PowerMonitor::AddPowerStateObserverAndReturnOnBatteryState(&observer1));
231
232 source().GeneratePowerStateEvent(true);
233
234 // An observer is added after the on-battery notification.
235 EXPECT_TRUE(
236 PowerMonitor::AddPowerStateObserverAndReturnOnBatteryState(&observer2));
237
238 EXPECT_EQ(observer1.power_state_changes(), 1);
239 EXPECT_EQ(observer2.power_state_changes(), 0);
240
241 PowerMonitor::RemovePowerStateObserver(&observer1);
242 PowerMonitor::RemovePowerStateObserver(&observer2);
243 }
244
245 } // namespace test
246 } // namespace base
247