OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
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 "ash/common/system/chromeos/power/power_status.h" | |
6 | |
7 #include <memory> | |
8 | |
9 #include "base/message_loop/message_loop.h" | |
10 #include "base/run_loop.h" | |
11 #include "chromeos/dbus/dbus_thread_manager.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 #include "third_party/cros_system_api/dbus/service_constants.h" | |
14 | |
15 using power_manager::PowerSupplyProperties; | |
16 | |
17 namespace ash { | |
18 namespace { | |
19 | |
20 class TestObserver : public PowerStatus::Observer { | |
21 public: | |
22 TestObserver() : power_changed_count_(0) {} | |
23 ~TestObserver() override {} | |
24 | |
25 int power_changed_count() const { return power_changed_count_; } | |
26 | |
27 // PowerStatus::Observer overrides: | |
28 void OnPowerStatusChanged() override { ++power_changed_count_; } | |
29 | |
30 private: | |
31 int power_changed_count_; | |
32 | |
33 DISALLOW_COPY_AND_ASSIGN(TestObserver); | |
34 }; | |
35 | |
36 } // namespace | |
37 | |
38 class PowerStatusTest : public testing::Test { | |
39 public: | |
40 PowerStatusTest() : power_status_(NULL) {} | |
41 ~PowerStatusTest() override {} | |
42 | |
43 void SetUp() override { | |
44 chromeos::DBusThreadManager::Initialize(); | |
45 PowerStatus::Initialize(); | |
46 power_status_ = PowerStatus::Get(); | |
47 test_observer_.reset(new TestObserver); | |
48 power_status_->AddObserver(test_observer_.get()); | |
49 } | |
50 | |
51 void TearDown() override { | |
52 power_status_->RemoveObserver(test_observer_.get()); | |
53 test_observer_.reset(); | |
54 PowerStatus::Shutdown(); | |
55 chromeos::DBusThreadManager::Shutdown(); | |
56 } | |
57 | |
58 protected: | |
59 base::MessageLoopForUI message_loop_; | |
60 PowerStatus* power_status_; // Not owned. | |
61 std::unique_ptr<TestObserver> test_observer_; | |
62 | |
63 private: | |
64 DISALLOW_COPY_AND_ASSIGN(PowerStatusTest); | |
65 }; | |
66 | |
67 TEST_F(PowerStatusTest, InitializeAndUpdate) { | |
68 // Test that the initial power supply state should be acquired after | |
69 // PowerStatus is instantiated. This depends on | |
70 // PowerManagerClientStubImpl, which responds to power status update | |
71 // requests, pretends there is a battery present, and generates some valid | |
72 // power supply status data. | |
73 base::RunLoop().RunUntilIdle(); | |
74 EXPECT_EQ(1, test_observer_->power_changed_count()); | |
75 | |
76 // Test RequestUpdate, test_obsever_ should be notified for power suuply | |
77 // status change. | |
78 power_status_->RequestStatusUpdate(); | |
79 base::RunLoop().RunUntilIdle(); | |
80 EXPECT_EQ(2, test_observer_->power_changed_count()); | |
81 } | |
82 | |
83 TEST_F(PowerStatusTest, ShouldDisplayBatteryTime) { | |
84 EXPECT_FALSE( | |
85 PowerStatus::ShouldDisplayBatteryTime(base::TimeDelta::FromSeconds(-1))); | |
86 EXPECT_FALSE( | |
87 PowerStatus::ShouldDisplayBatteryTime(base::TimeDelta::FromSeconds(0))); | |
88 EXPECT_FALSE( | |
89 PowerStatus::ShouldDisplayBatteryTime(base::TimeDelta::FromSeconds(59))); | |
90 EXPECT_TRUE( | |
91 PowerStatus::ShouldDisplayBatteryTime(base::TimeDelta::FromSeconds(60))); | |
92 EXPECT_TRUE( | |
93 PowerStatus::ShouldDisplayBatteryTime(base::TimeDelta::FromSeconds(600))); | |
94 EXPECT_TRUE(PowerStatus::ShouldDisplayBatteryTime( | |
95 base::TimeDelta::FromSeconds(3600))); | |
96 EXPECT_TRUE(PowerStatus::ShouldDisplayBatteryTime( | |
97 base::TimeDelta::FromSeconds(PowerStatus::kMaxBatteryTimeToDisplaySec))); | |
98 EXPECT_FALSE( | |
99 PowerStatus::ShouldDisplayBatteryTime(base::TimeDelta::FromSeconds( | |
100 PowerStatus::kMaxBatteryTimeToDisplaySec + 1))); | |
101 } | |
102 | |
103 TEST_F(PowerStatusTest, SplitTimeIntoHoursAndMinutes) { | |
104 int hours = 0, minutes = 0; | |
105 PowerStatus::SplitTimeIntoHoursAndMinutes(base::TimeDelta::FromSeconds(0), | |
106 &hours, &minutes); | |
107 EXPECT_EQ(0, hours); | |
108 EXPECT_EQ(0, minutes); | |
109 | |
110 PowerStatus::SplitTimeIntoHoursAndMinutes(base::TimeDelta::FromSeconds(60), | |
111 &hours, &minutes); | |
112 EXPECT_EQ(0, hours); | |
113 EXPECT_EQ(1, minutes); | |
114 | |
115 PowerStatus::SplitTimeIntoHoursAndMinutes(base::TimeDelta::FromSeconds(3600), | |
116 &hours, &minutes); | |
117 EXPECT_EQ(1, hours); | |
118 EXPECT_EQ(0, minutes); | |
119 | |
120 PowerStatus::SplitTimeIntoHoursAndMinutes( | |
121 base::TimeDelta::FromSeconds(3600 + 60), &hours, &minutes); | |
122 EXPECT_EQ(1, hours); | |
123 EXPECT_EQ(1, minutes); | |
124 | |
125 PowerStatus::SplitTimeIntoHoursAndMinutes( | |
126 base::TimeDelta::FromSeconds(7 * 3600 + 23 * 60), &hours, &minutes); | |
127 EXPECT_EQ(7, hours); | |
128 EXPECT_EQ(23, minutes); | |
129 | |
130 // Check that minutes are rounded. | |
131 PowerStatus::SplitTimeIntoHoursAndMinutes( | |
132 base::TimeDelta::FromSeconds(2 * 3600 + 3 * 60 + 30), &hours, &minutes); | |
133 EXPECT_EQ(2, hours); | |
134 EXPECT_EQ(4, minutes); | |
135 | |
136 PowerStatus::SplitTimeIntoHoursAndMinutes( | |
137 base::TimeDelta::FromSeconds(2 * 3600 + 3 * 60 + 29), &hours, &minutes); | |
138 EXPECT_EQ(2, hours); | |
139 EXPECT_EQ(3, minutes); | |
140 | |
141 // Check that times close to hour boundaries aren't incorrectly rounded such | |
142 // that they display 60 minutes: http://crbug.com/368261 | |
143 PowerStatus::SplitTimeIntoHoursAndMinutes( | |
144 base::TimeDelta::FromSecondsD(3599.9), &hours, &minutes); | |
145 EXPECT_EQ(1, hours); | |
146 EXPECT_EQ(0, minutes); | |
147 | |
148 PowerStatus::SplitTimeIntoHoursAndMinutes( | |
149 base::TimeDelta::FromSecondsD(3600.1), &hours, &minutes); | |
150 EXPECT_EQ(1, hours); | |
151 EXPECT_EQ(0, minutes); | |
152 } | |
153 | |
154 TEST_F(PowerStatusTest, GetBatteryImageInfo) { | |
155 PowerSupplyProperties prop; | |
156 prop.set_external_power(PowerSupplyProperties::AC); | |
157 prop.set_battery_state(PowerSupplyProperties::CHARGING); | |
158 prop.set_battery_percent(98.0); | |
159 power_status_->SetProtoForTesting(prop); | |
160 const PowerStatus::BatteryImageInfo info_charging_98 = | |
161 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT); | |
162 | |
163 // 99% should use the same icon as 98%. | |
164 prop.set_battery_percent(99.0); | |
165 power_status_->SetProtoForTesting(prop); | |
166 EXPECT_EQ(info_charging_98, | |
167 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT)); | |
168 | |
169 // The dark icon set should use a different image for non-MD, but the | |
170 // same image for MD. | |
171 prop.set_battery_percent(98.0); | |
172 EXPECT_EQ(info_charging_98, | |
173 power_status_->GetBatteryImageInfo(PowerStatus::ICON_DARK)); | |
174 | |
175 // A different icon should be used when the battery is full, too. | |
176 prop.set_battery_state(PowerSupplyProperties::FULL); | |
177 prop.set_battery_percent(100.0); | |
178 power_status_->SetProtoForTesting(prop); | |
179 EXPECT_NE(info_charging_98, | |
180 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT)); | |
181 | |
182 // A much-lower battery level should use a different icon. | |
183 prop.set_battery_state(PowerSupplyProperties::CHARGING); | |
184 prop.set_battery_percent(20.0); | |
185 power_status_->SetProtoForTesting(prop); | |
186 EXPECT_NE(info_charging_98, | |
187 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT)); | |
188 | |
189 // Ditto for 98%, but on USB instead of AC. | |
190 prop.set_external_power(PowerSupplyProperties::USB); | |
191 prop.set_battery_percent(98.0); | |
192 power_status_->SetProtoForTesting(prop); | |
193 EXPECT_NE(info_charging_98, | |
194 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT)); | |
195 } | |
196 | |
197 // Tests that the |icon_badge| member of BatteryImageInfo is set correctly | |
198 // with various power supply property values. | |
199 TEST_F(PowerStatusTest, BatteryImageInfoIconBadge) { | |
200 PowerSupplyProperties prop; | |
201 | |
202 // A charging battery connected to AC power should have an ICON_BADGE_BOLT. | |
203 prop.set_external_power(PowerSupplyProperties::AC); | |
204 prop.set_battery_state(PowerSupplyProperties::CHARGING); | |
205 prop.set_battery_percent(98.0); | |
206 power_status_->SetProtoForTesting(prop); | |
207 EXPECT_EQ( | |
208 PowerStatus::ICON_BADGE_BOLT, | |
209 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).icon_badge); | |
210 | |
211 // A discharging battery connected to AC should also have an ICON_BADGE_BOLT. | |
212 prop.set_battery_state(PowerSupplyProperties::DISCHARGING); | |
213 power_status_->SetProtoForTesting(prop); | |
214 EXPECT_EQ( | |
215 PowerStatus::ICON_BADGE_BOLT, | |
216 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).icon_badge); | |
217 | |
218 // A charging battery connected to USB power should have an | |
219 // ICON_BADGE_UNRELIABLE. | |
220 prop.set_external_power(PowerSupplyProperties::USB); | |
221 prop.set_battery_state(PowerSupplyProperties::CHARGING); | |
222 power_status_->SetProtoForTesting(prop); | |
223 EXPECT_EQ( | |
224 PowerStatus::ICON_BADGE_UNRELIABLE, | |
225 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).icon_badge); | |
226 | |
227 // A discharging battery connected to USB power should also have an | |
228 // ICON_BADGE_UNRELIABLE. | |
229 prop.set_battery_state(PowerSupplyProperties::DISCHARGING); | |
230 power_status_->SetProtoForTesting(prop); | |
231 EXPECT_EQ( | |
232 PowerStatus::ICON_BADGE_UNRELIABLE, | |
233 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).icon_badge); | |
234 | |
235 // Show an ICON_BADGE_X when no battery is present. | |
236 prop.set_external_power(PowerSupplyProperties::DISCONNECTED); | |
237 prop.set_battery_state(PowerSupplyProperties::NOT_PRESENT); | |
238 power_status_->SetProtoForTesting(prop); | |
239 EXPECT_EQ( | |
240 PowerStatus::ICON_BADGE_X, | |
241 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).icon_badge); | |
242 | |
243 // Do not show a badge when the battery is discharging. | |
244 prop.set_battery_state(PowerSupplyProperties::DISCHARGING); | |
245 power_status_->SetProtoForTesting(prop); | |
246 EXPECT_EQ( | |
247 PowerStatus::ICON_BADGE_NONE, | |
248 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).icon_badge); | |
249 | |
250 // Show ICON_BADGE_ALERT for a discharging battery when it falls below | |
251 // a charge level of PowerStatus::kCriticalBatteryChargePercentageMd. | |
252 prop.set_battery_percent(PowerStatus::kCriticalBatteryChargePercentageMd); | |
253 power_status_->SetProtoForTesting(prop); | |
254 EXPECT_EQ( | |
255 PowerStatus::ICON_BADGE_NONE, | |
256 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).icon_badge); | |
257 prop.set_battery_percent(PowerStatus::kCriticalBatteryChargePercentageMd - 1); | |
258 power_status_->SetProtoForTesting(prop); | |
259 EXPECT_EQ( | |
260 PowerStatus::ICON_BADGE_ALERT, | |
261 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).icon_badge); | |
262 } | |
263 | |
264 // Tests that the |charge_level| member of BatteryImageInfo is set correctly | |
265 // with various power supply property values. | |
266 TEST_F(PowerStatusTest, BatteryImageInfoChargeLevel) { | |
267 PowerSupplyProperties prop; | |
268 | |
269 // No charge level is drawn when the battery is not present. | |
270 prop.set_external_power(PowerSupplyProperties::DISCONNECTED); | |
271 prop.set_battery_state(PowerSupplyProperties::NOT_PRESENT); | |
272 power_status_->SetProtoForTesting(prop); | |
273 EXPECT_EQ( | |
274 0, | |
275 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).charge_level); | |
276 | |
277 // A charge level of 0 when the battery is 0% full. | |
278 prop.set_external_power(PowerSupplyProperties::AC); | |
279 prop.set_battery_state(PowerSupplyProperties::CHARGING); | |
280 prop.set_battery_percent(0.0); | |
281 EXPECT_EQ( | |
282 0, | |
283 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).charge_level); | |
284 | |
285 // A charge level of 1 when the battery is up to 16% full, and a level of 2 | |
286 // for 17% full. | |
287 prop.set_battery_percent(16.0); | |
288 power_status_->SetProtoForTesting(prop); | |
289 EXPECT_EQ( | |
290 1, | |
291 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).charge_level); | |
292 prop.set_battery_percent(17.0); | |
293 power_status_->SetProtoForTesting(prop); | |
294 EXPECT_EQ( | |
295 2, | |
296 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).charge_level); | |
297 | |
298 // A charge level of 6 when the battery is 50% full. | |
299 prop.set_battery_percent(50.0); | |
300 power_status_->SetProtoForTesting(prop); | |
301 EXPECT_EQ( | |
302 6, | |
303 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).charge_level); | |
304 | |
305 // A charge level of 11 when the battery is 99% full, and a level of 12 when | |
306 // the battery is 100% full. | |
307 prop.set_battery_percent(99.0); | |
308 power_status_->SetProtoForTesting(prop); | |
309 EXPECT_EQ( | |
310 11, | |
311 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).charge_level); | |
312 prop.set_battery_percent(100.0); | |
313 power_status_->SetProtoForTesting(prop); | |
314 EXPECT_EQ( | |
315 12, | |
316 power_status_->GetBatteryImageInfo(PowerStatus::ICON_LIGHT).charge_level); | |
317 } | |
318 | |
319 } // namespace ash | |
OLD | NEW |