Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: ash/common/system/chromeos/power/tray_power_unittest.cc

Issue 2732813002: chromeos: Move files in //ash/common to //ash, part 1 (Closed)
Patch Set: rebase Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 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/tray_power.h"
6
7 #include <map>
8 #include <memory>
9 #include <string>
10
11 #include "ash/test/ash_test_base.h"
12 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
13 #include "ui/message_center/fake_message_center.h"
14
15 using message_center::Notification;
16 using power_manager::PowerSupplyProperties;
17
18 namespace {
19
20 class MockMessageCenter : public message_center::FakeMessageCenter {
21 public:
22 MockMessageCenter() : add_count_(0), remove_count_(0), update_count_(0) {}
23 ~MockMessageCenter() override {}
24
25 int add_count() const { return add_count_; }
26 int remove_count() const { return remove_count_; }
27 int update_count() const { return update_count_; }
28
29 // message_center::FakeMessageCenter overrides:
30 void AddNotification(std::unique_ptr<Notification> notification) override {
31 add_count_++;
32 notifications_.insert(
33 std::make_pair(notification->id(), std::move(notification)));
34 }
35 void RemoveNotification(const std::string& id, bool by_user) override {
36 Notification* notification = FindVisibleNotificationById(id);
37 if (notification && notification->delegate())
38 notification->delegate()->Close(by_user);
39 remove_count_++;
40 notifications_.erase(id);
41 }
42 void UpdateNotification(
43 const std::string& id,
44 std::unique_ptr<Notification> new_notification) override {
45 update_count_++;
46 Notification* notification = FindVisibleNotificationById(id);
47 if (notification)
48 notifications_.erase(id);
49 notifications_.insert(
50 std::make_pair(new_notification->id(), std::move(new_notification)));
51 }
52
53 Notification* FindVisibleNotificationById(const std::string& id) override {
54 auto it = notifications_.find(id);
55 return it == notifications_.end() ? NULL : it->second.get();
56 }
57
58 private:
59 int add_count_;
60 int remove_count_;
61 int update_count_;
62 std::map<std::string, std::unique_ptr<Notification>> notifications_;
63
64 DISALLOW_COPY_AND_ASSIGN(MockMessageCenter);
65 };
66
67 } // namespace
68
69 namespace ash {
70
71 class TrayPowerTest : public test::AshTestBase {
72 public:
73 TrayPowerTest() {}
74 ~TrayPowerTest() override {}
75
76 MockMessageCenter* message_center() { return message_center_.get(); }
77 TrayPower* tray_power() { return tray_power_.get(); }
78
79 // test::AshTestBase::SetUp() overrides:
80 void SetUp() override {
81 test::AshTestBase::SetUp();
82 message_center_.reset(new MockMessageCenter());
83 tray_power_.reset(new TrayPower(NULL, message_center_.get()));
84 }
85
86 void TearDown() override {
87 tray_power_.reset();
88 message_center_.reset();
89 test::AshTestBase::TearDown();
90 }
91
92 TrayPower::NotificationState notification_state() const {
93 return tray_power_->notification_state_;
94 }
95
96 bool MaybeShowUsbChargerNotification(const PowerSupplyProperties& proto) {
97 PowerStatus::Get()->SetProtoForTesting(proto);
98 return tray_power_->MaybeShowUsbChargerNotification();
99 }
100
101 void MaybeShowDualRoleNotification(const PowerSupplyProperties& proto) {
102 PowerStatus::Get()->SetProtoForTesting(proto);
103 tray_power_->MaybeShowDualRoleNotification();
104 }
105
106 void UpdateNotificationState(const PowerSupplyProperties& proto,
107 TrayPower::NotificationState expected_state,
108 bool expected_add,
109 bool expected_remove) {
110 int prev_add = message_center_->add_count();
111 int prev_remove = message_center_->remove_count();
112 PowerStatus::Get()->SetProtoForTesting(proto);
113 tray_power_->OnPowerStatusChanged();
114 EXPECT_EQ(expected_state, notification_state());
115 EXPECT_EQ(expected_add, message_center_->add_count() == prev_add + 1);
116 EXPECT_EQ(expected_remove,
117 message_center_->remove_count() == prev_remove + 1);
118 }
119
120 void SetUsbChargerConnected(bool connected) {
121 tray_power_->usb_charger_was_connected_ = connected;
122 }
123
124 // Returns a discharging PowerSupplyProperties more appropriate for testing.
125 static PowerSupplyProperties DefaultPowerSupplyProperties() {
126 PowerSupplyProperties proto;
127 proto.set_external_power(
128 power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED);
129 proto.set_battery_state(
130 power_manager::PowerSupplyProperties_BatteryState_DISCHARGING);
131 proto.set_battery_percent(50.0);
132 proto.set_battery_time_to_empty_sec(3 * 60 * 60);
133 proto.set_battery_time_to_full_sec(2 * 60 * 60);
134 proto.set_is_calculating_battery_time(false);
135 return proto;
136 }
137
138 private:
139 std::unique_ptr<MockMessageCenter> message_center_;
140 std::unique_ptr<TrayPower> tray_power_;
141
142 DISALLOW_COPY_AND_ASSIGN(TrayPowerTest);
143 };
144
145 TEST_F(TrayPowerTest, MaybeShowUsbChargerNotification) {
146 PowerSupplyProperties discharging = DefaultPowerSupplyProperties();
147 EXPECT_FALSE(MaybeShowUsbChargerNotification(discharging));
148 EXPECT_EQ(0, message_center()->add_count());
149 EXPECT_EQ(0, message_center()->remove_count());
150
151 // Notification shows when connecting a USB charger.
152 PowerSupplyProperties usb_connected = DefaultPowerSupplyProperties();
153 usb_connected.set_external_power(
154 power_manager::PowerSupplyProperties_ExternalPower_USB);
155 EXPECT_TRUE(MaybeShowUsbChargerNotification(usb_connected));
156 EXPECT_EQ(1, message_center()->add_count());
157 EXPECT_EQ(0, message_center()->remove_count());
158 SetUsbChargerConnected(true);
159
160 // Change in charge does not trigger the notification again.
161 PowerSupplyProperties more_charge = DefaultPowerSupplyProperties();
162 more_charge.set_external_power(
163 power_manager::PowerSupplyProperties_ExternalPower_USB);
164 more_charge.set_battery_time_to_full_sec(60 * 60);
165 more_charge.set_battery_percent(75.0);
166 EXPECT_FALSE(MaybeShowUsbChargerNotification(more_charge));
167 EXPECT_EQ(1, message_center()->add_count());
168 EXPECT_EQ(0, message_center()->remove_count());
169
170 // Disconnecting a USB charger with the notification showing should close
171 // the notification.
172 EXPECT_TRUE(MaybeShowUsbChargerNotification(discharging));
173 EXPECT_EQ(1, message_center()->add_count());
174 EXPECT_EQ(1, message_center()->remove_count());
175 SetUsbChargerConnected(false);
176
177 // Notification shows when connecting a USB charger again.
178 EXPECT_TRUE(MaybeShowUsbChargerNotification(usb_connected));
179 EXPECT_EQ(2, message_center()->add_count());
180 EXPECT_EQ(1, message_center()->remove_count());
181 SetUsbChargerConnected(true);
182
183 // Notification hides when external power switches to AC.
184 PowerSupplyProperties ac_charger = DefaultPowerSupplyProperties();
185 ac_charger.set_external_power(
186 power_manager::PowerSupplyProperties_ExternalPower_AC);
187 EXPECT_TRUE(MaybeShowUsbChargerNotification(ac_charger));
188 EXPECT_EQ(2, message_center()->add_count());
189 EXPECT_EQ(2, message_center()->remove_count());
190 SetUsbChargerConnected(false);
191
192 // Notification shows when external power switches back to USB.
193 EXPECT_TRUE(MaybeShowUsbChargerNotification(usb_connected));
194 EXPECT_EQ(3, message_center()->add_count());
195 EXPECT_EQ(2, message_center()->remove_count());
196 SetUsbChargerConnected(true);
197
198 // Notification does not re-appear after being manually dismissed if
199 // power supply flickers between AC and USB charger.
200 message_center()->RemoveNotification(TrayPower::kUsbNotificationId, true);
201 EXPECT_EQ(3, message_center()->remove_count());
202 EXPECT_TRUE(MaybeShowUsbChargerNotification(ac_charger));
203 SetUsbChargerConnected(false);
204 EXPECT_FALSE(MaybeShowUsbChargerNotification(usb_connected));
205 EXPECT_EQ(3, message_center()->add_count());
206 SetUsbChargerConnected(true);
207
208 // Notification appears again after being manually dismissed if the charger
209 // is removed, and then a USB charger is attached.
210 MaybeShowUsbChargerNotification(discharging);
211 EXPECT_EQ(3, message_center()->add_count());
212 SetUsbChargerConnected(false);
213 MaybeShowUsbChargerNotification(usb_connected);
214 EXPECT_EQ(4, message_center()->add_count());
215 SetUsbChargerConnected(true);
216 }
217
218 TEST_F(TrayPowerTest, MaybeShowDualRoleNotification) {
219 PowerSupplyProperties discharging = DefaultPowerSupplyProperties();
220 discharging.set_supports_dual_role_devices(true);
221 MaybeShowDualRoleNotification(discharging);
222 EXPECT_EQ(0, message_center()->add_count());
223 EXPECT_EQ(0, message_center()->update_count());
224 EXPECT_EQ(0, message_center()->remove_count());
225
226 // Notification shows when connecting a dual-role device.
227 PowerSupplyProperties dual_role = DefaultPowerSupplyProperties();
228 dual_role.set_supports_dual_role_devices(true);
229 power_manager::PowerSupplyProperties_PowerSource* source =
230 dual_role.add_available_external_power_source();
231 source->set_id("dual-role1");
232 source->set_active_by_default(false);
233 MaybeShowDualRoleNotification(dual_role);
234 EXPECT_EQ(1, message_center()->add_count());
235 EXPECT_EQ(0, message_center()->update_count());
236 EXPECT_EQ(0, message_center()->remove_count());
237
238 // Connecting another dual-role device updates the notification to be plural.
239 source = dual_role.add_available_external_power_source();
240 source->set_id("dual-role2");
241 source->set_active_by_default(false);
242 MaybeShowDualRoleNotification(dual_role);
243 EXPECT_EQ(1, message_center()->add_count());
244 EXPECT_EQ(1, message_center()->update_count());
245 EXPECT_EQ(0, message_center()->remove_count());
246
247 // Connecting a 3rd dual-role device doesn't affect the notification.
248 source = dual_role.add_available_external_power_source();
249 source->set_id("dual-role3");
250 source->set_active_by_default(false);
251 MaybeShowDualRoleNotification(dual_role);
252 EXPECT_EQ(1, message_center()->add_count());
253 EXPECT_EQ(1, message_center()->update_count());
254 EXPECT_EQ(0, message_center()->remove_count());
255
256 // Connecting a legacy USB device removes the notification.
257 PowerSupplyProperties legacy(dual_role);
258 power_manager::PowerSupplyProperties_PowerSource* legacy_source =
259 legacy.add_available_external_power_source();
260 legacy_source->set_id("legacy");
261 legacy_source->set_active_by_default(true);
262 legacy.set_external_power_source_id("legacy");
263 legacy.set_external_power(
264 power_manager::PowerSupplyProperties_ExternalPower_USB);
265 MaybeShowDualRoleNotification(legacy);
266 EXPECT_EQ(1, message_center()->add_count());
267 EXPECT_EQ(1, message_center()->update_count());
268 EXPECT_EQ(1, message_center()->remove_count());
269
270 // Removing the legacy USB device adds the notification again.
271 MaybeShowDualRoleNotification(dual_role);
272 EXPECT_EQ(2, message_center()->add_count());
273 EXPECT_EQ(1, message_center()->update_count());
274 EXPECT_EQ(1, message_center()->remove_count());
275
276 // Charging from the device updates the notification.
277 dual_role.set_external_power_source_id("dual-role1");
278 dual_role.set_external_power(
279 power_manager::PowerSupplyProperties_ExternalPower_USB);
280 MaybeShowDualRoleNotification(dual_role);
281 EXPECT_EQ(2, message_center()->add_count());
282 EXPECT_EQ(2, message_center()->update_count());
283 EXPECT_EQ(1, message_center()->remove_count());
284
285 // Adding a device as a sink doesn't change the notification, because the
286 // notification exposes the source.
287 source = dual_role.add_available_external_power_source();
288 source->set_active_by_default(false);
289 MaybeShowDualRoleNotification(dual_role);
290 EXPECT_EQ(2, message_center()->add_count());
291 EXPECT_EQ(2, message_center()->update_count());
292 EXPECT_EQ(1, message_center()->remove_count());
293
294 // Changing the source to a sink changes the notification.
295 dual_role.set_external_power_source_id("");
296 dual_role.set_external_power(
297 power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED);
298 MaybeShowDualRoleNotification(dual_role);
299 EXPECT_EQ(2, message_center()->add_count());
300 EXPECT_EQ(3, message_center()->update_count());
301 EXPECT_EQ(1, message_center()->remove_count());
302
303 // An unrelated change has no effect.
304 dual_role.set_battery_time_to_empty_sec(2 * 60 * 60);
305 MaybeShowDualRoleNotification(dual_role);
306 EXPECT_EQ(2, message_center()->add_count());
307 EXPECT_EQ(3, message_center()->update_count());
308 EXPECT_EQ(1, message_center()->remove_count());
309
310 // Removing devices hides the notification.
311 MaybeShowDualRoleNotification(discharging);
312 EXPECT_EQ(2, message_center()->add_count());
313 EXPECT_EQ(3, message_center()->update_count());
314 EXPECT_EQ(2, message_center()->remove_count());
315 }
316
317 TEST_F(TrayPowerTest, UpdateNotificationState) {
318 // No notifications when no battery present.
319 PowerSupplyProperties no_battery = DefaultPowerSupplyProperties();
320 no_battery.set_external_power(
321 power_manager::PowerSupplyProperties_ExternalPower_AC);
322 no_battery.set_battery_state(
323 power_manager::PowerSupplyProperties_BatteryState_NOT_PRESENT);
324 {
325 SCOPED_TRACE("No notifications when no battery present");
326 UpdateNotificationState(no_battery, TrayPower::NOTIFICATION_NONE, false,
327 false);
328 }
329
330 // No notification when calculating remaining battery time.
331 PowerSupplyProperties calculating = DefaultPowerSupplyProperties();
332 calculating.set_is_calculating_battery_time(true);
333 {
334 SCOPED_TRACE("No notification when calculating remaining battery time");
335 UpdateNotificationState(calculating, TrayPower::NOTIFICATION_NONE, false,
336 false);
337 }
338
339 // No notification when charging.
340 PowerSupplyProperties charging = DefaultPowerSupplyProperties();
341 charging.set_external_power(
342 power_manager::PowerSupplyProperties_ExternalPower_AC);
343 charging.set_battery_state(
344 power_manager::PowerSupplyProperties_BatteryState_CHARGING);
345 {
346 SCOPED_TRACE("No notification when charging");
347 UpdateNotificationState(charging, TrayPower::NOTIFICATION_NONE, false,
348 false);
349 }
350
351 // When the rounded minutes-to-empty are above the threshold, no notification
352 // should be shown.
353 PowerSupplyProperties low = DefaultPowerSupplyProperties();
354 low.set_battery_time_to_empty_sec(TrayPower::kLowPowerMinutes * 60 + 30);
355 {
356 SCOPED_TRACE("No notification when time to empty above threshold");
357 UpdateNotificationState(low, TrayPower::NOTIFICATION_NONE, false, false);
358 }
359
360 // When the rounded value matches the threshold, the notification should
361 // appear.
362 low.set_battery_time_to_empty_sec(TrayPower::kLowPowerMinutes * 60 + 29);
363 {
364 SCOPED_TRACE("Notification when time to empty matches threshold");
365 UpdateNotificationState(low, TrayPower::NOTIFICATION_LOW_POWER, true,
366 false);
367 }
368
369 // It should persist at lower values.
370 low.set_battery_time_to_empty_sec(TrayPower::kLowPowerMinutes * 60 - 20);
371 {
372 SCOPED_TRACE("Notification persists at lower values");
373 UpdateNotificationState(low, TrayPower::NOTIFICATION_LOW_POWER, false,
374 false);
375 }
376
377 // The critical low battery notification should be shown when the rounded
378 // value is at the lower threshold.
379 PowerSupplyProperties critical = DefaultPowerSupplyProperties();
380 critical.set_battery_time_to_empty_sec(TrayPower::kCriticalMinutes * 60 + 29);
381 {
382 SCOPED_TRACE("Critical notification when time to empty is critical");
383 UpdateNotificationState(critical, TrayPower::NOTIFICATION_CRITICAL, true,
384 true);
385 }
386
387 // The notification should be dismissed when the no-warning threshold is
388 // reached.
389 PowerSupplyProperties safe = DefaultPowerSupplyProperties();
390 safe.set_battery_time_to_empty_sec(TrayPower::kNoWarningMinutes * 60 - 29);
391 {
392 SCOPED_TRACE("Notification removed when battery not low");
393 UpdateNotificationState(safe, TrayPower::NOTIFICATION_NONE, false, true);
394 }
395
396 // Test that rounded percentages are used when a USB charger is connected.
397 PowerSupplyProperties low_usb = DefaultPowerSupplyProperties();
398 low_usb.set_external_power(
399 power_manager::PowerSupplyProperties_ExternalPower_USB);
400 low_usb.set_battery_percent(TrayPower::kLowPowerPercentage + 0.5);
401 {
402 SCOPED_TRACE("No notification for rounded battery percent");
403 UpdateNotificationState(low_usb, TrayPower::NOTIFICATION_NONE, true, false);
404 }
405
406 low_usb.set_battery_percent(TrayPower::kLowPowerPercentage + 0.49);
407 {
408 SCOPED_TRACE("Notification for rounded low power percent");
409 UpdateNotificationState(low_usb, TrayPower::NOTIFICATION_LOW_POWER, true,
410 false);
411 }
412
413 PowerSupplyProperties critical_usb = DefaultPowerSupplyProperties();
414 critical_usb.set_external_power(
415 power_manager::PowerSupplyProperties_ExternalPower_USB);
416 critical_usb.set_battery_percent(TrayPower::kCriticalPercentage + 0.2);
417 {
418 SCOPED_TRACE("Notification for rounded critical power percent");
419 UpdateNotificationState(critical_usb, TrayPower::NOTIFICATION_CRITICAL,
420 true, true);
421 }
422
423 PowerSupplyProperties safe_usb = DefaultPowerSupplyProperties();
424 safe_usb.set_external_power(
425 power_manager::PowerSupplyProperties_ExternalPower_USB);
426 safe_usb.set_battery_percent(TrayPower::kNoWarningPercentage - 0.1);
427 {
428 SCOPED_TRACE("Notification removed for rounded percent above threshold");
429 UpdateNotificationState(safe_usb, TrayPower::NOTIFICATION_NONE, false,
430 true);
431 }
432 }
433
434 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/system/chromeos/power/tray_power.cc ('k') | ash/common/system/chromeos/screen_security/screen_capture_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698