• 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 "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