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