Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ash / system / chromeos / power / tray_power_unittest.cc
blob8ed6a0fe834b61b68911c0bd3d73cca8c93ddb76
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.
5 #include "ash/system/chromeos/power/tray_power.h"
7 #include <map>
8 #include <string>
10 #include "ash/ash_switches.h"
11 #include "ash/test/ash_test_base.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
14 #include "ui/message_center/fake_message_center.h"
16 using message_center::Notification;
17 using power_manager::PowerSupplyProperties;
19 namespace {
21 class MockMessageCenter : public message_center::FakeMessageCenter {
22 public:
23 MockMessageCenter() : add_count_(0), remove_count_(0) {}
24 ~MockMessageCenter() override {}
26 int add_count() const { return add_count_; }
27 int remove_count() const { return remove_count_; }
29 // message_center::FakeMessageCenter overrides:
30 void AddNotification(scoped_ptr<Notification> notification) override {
31 add_count_++;
32 notifications_[notification->id()] = notification.get();
34 void RemoveNotification(const std::string& id, bool by_user) override {
35 remove_count_++;
36 notifications_.erase(id);
39 Notification* FindVisibleNotificationById(const std::string& id) override {
40 auto it = notifications_.find(id);
41 return it == notifications_.end() ? NULL : it->second;
44 private:
45 int add_count_;
46 int remove_count_;
47 std::map<std::string, Notification*> notifications_;
49 DISALLOW_COPY_AND_ASSIGN(MockMessageCenter);
52 } // namespace
54 namespace ash {
56 class TrayPowerTest : public test::AshTestBase {
57 public:
58 TrayPowerTest() {}
59 ~TrayPowerTest() override {}
61 MockMessageCenter* message_center() { return message_center_.get(); }
62 TrayPower* tray_power() { return tray_power_.get(); }
64 // test::AshTestBase::SetUp() overrides:
65 void SetUp() override {
66 test::AshTestBase::SetUp();
67 message_center_.reset(new MockMessageCenter());
68 tray_power_.reset(new TrayPower(NULL, message_center_.get()));
71 void TearDown() override {
72 tray_power_.reset();
73 message_center_.reset();
74 test::AshTestBase::TearDown();
77 TrayPower::NotificationState notification_state() const {
78 return tray_power_->notification_state_;
81 bool MaybeShowUsbChargerNotification(const PowerSupplyProperties& proto) {
82 PowerStatus::Get()->SetProtoForTesting(proto);
83 return tray_power_->MaybeShowUsbChargerNotification();
86 void UpdateNotificationState(const PowerSupplyProperties& proto,
87 TrayPower::NotificationState expected_state,
88 bool expected_add,
89 bool expected_remove) {
90 int prev_add = message_center_->add_count();
91 int prev_remove = message_center_->remove_count();
92 PowerStatus::Get()->SetProtoForTesting(proto);
93 tray_power_->OnPowerStatusChanged();
94 EXPECT_EQ(expected_state, notification_state());
95 EXPECT_EQ(expected_add, message_center_->add_count() == prev_add + 1);
96 EXPECT_EQ(expected_remove,
97 message_center_->remove_count() == prev_remove + 1);
100 void SetUsbChargerConnected(bool connected) {
101 tray_power_->usb_charger_was_connected_ = connected;
104 // Returns a discharging PowerSupplyProperties more appropriate for testing.
105 static PowerSupplyProperties DefaultPowerSupplyProperties() {
106 PowerSupplyProperties proto;
107 proto.set_external_power(
108 power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED);
109 proto.set_battery_state(
110 power_manager::PowerSupplyProperties_BatteryState_DISCHARGING);
111 proto.set_battery_percent(50.0);
112 proto.set_battery_time_to_empty_sec(3 * 60 * 60);
113 proto.set_battery_time_to_full_sec(2 * 60 * 60);
114 proto.set_is_calculating_battery_time(false);
115 return proto;
118 private:
119 scoped_ptr<MockMessageCenter> message_center_;
120 scoped_ptr<TrayPower> tray_power_;
122 DISALLOW_COPY_AND_ASSIGN(TrayPowerTest);
125 TEST_F(TrayPowerTest, MaybeShowUsbChargerNotification) {
126 PowerSupplyProperties discharging = DefaultPowerSupplyProperties();
127 EXPECT_FALSE(MaybeShowUsbChargerNotification(discharging));
128 EXPECT_EQ(0, message_center()->add_count());
129 EXPECT_EQ(0, message_center()->remove_count());
131 // Notification shows when connecting a USB charger.
132 PowerSupplyProperties usb_connected = DefaultPowerSupplyProperties();
133 usb_connected.set_external_power(
134 power_manager::PowerSupplyProperties_ExternalPower_USB);
135 EXPECT_TRUE(MaybeShowUsbChargerNotification(usb_connected));
136 EXPECT_EQ(1, message_center()->add_count());
137 EXPECT_EQ(0, message_center()->remove_count());
139 // Change in charge does not trigger the notification again.
140 PowerSupplyProperties more_charge = DefaultPowerSupplyProperties();
141 more_charge.set_external_power(
142 power_manager::PowerSupplyProperties_ExternalPower_USB);
143 more_charge.set_battery_time_to_full_sec(60 * 60);
144 more_charge.set_battery_percent(75.0);
145 SetUsbChargerConnected(true);
146 EXPECT_FALSE(MaybeShowUsbChargerNotification(more_charge));
147 EXPECT_EQ(1, message_center()->add_count());
148 EXPECT_EQ(0, message_center()->remove_count());
150 // Disconnecting a USB charger with the notification showing should close
151 // the notification.
152 EXPECT_TRUE(MaybeShowUsbChargerNotification(discharging));
153 EXPECT_EQ(1, message_center()->add_count());
154 EXPECT_EQ(1, message_center()->remove_count());
157 TEST_F(TrayPowerTest, UpdateNotificationState) {
158 // No notifications when no battery present.
159 PowerSupplyProperties no_battery = DefaultPowerSupplyProperties();
160 no_battery.set_external_power(
161 power_manager::PowerSupplyProperties_ExternalPower_AC);
162 no_battery.set_battery_state(
163 power_manager::PowerSupplyProperties_BatteryState_NOT_PRESENT);
165 SCOPED_TRACE("No notifications when no battery present");
166 UpdateNotificationState(no_battery, TrayPower::NOTIFICATION_NONE, false,
167 false);
170 // No notification when calculating remaining battery time.
171 PowerSupplyProperties calculating = DefaultPowerSupplyProperties();
172 calculating.set_is_calculating_battery_time(true);
174 SCOPED_TRACE("No notification when calculating remaining battery time");
175 UpdateNotificationState(calculating, TrayPower::NOTIFICATION_NONE, false,
176 false);
179 // No notification when charging.
180 PowerSupplyProperties charging = DefaultPowerSupplyProperties();
181 charging.set_external_power(
182 power_manager::PowerSupplyProperties_ExternalPower_AC);
183 charging.set_battery_state(
184 power_manager::PowerSupplyProperties_BatteryState_CHARGING);
186 SCOPED_TRACE("No notification when charging");
187 UpdateNotificationState(charging, TrayPower::NOTIFICATION_NONE, false,
188 false);
191 // When the rounded minutes-to-empty are above the threshold, no notification
192 // should be shown.
193 PowerSupplyProperties low = DefaultPowerSupplyProperties();
194 low.set_battery_time_to_empty_sec(TrayPower::kLowPowerMinutes * 60 + 30);
196 SCOPED_TRACE("No notification when time to empty above threshold");
197 UpdateNotificationState(low, TrayPower::NOTIFICATION_NONE, false, false);
200 // When the rounded value matches the threshold, the notification should
201 // appear.
202 low.set_battery_time_to_empty_sec(TrayPower::kLowPowerMinutes * 60 + 29);
204 SCOPED_TRACE("Notification when time to empty matches threshold");
205 UpdateNotificationState(low, TrayPower::NOTIFICATION_LOW_POWER, true,
206 false);
209 // It should persist at lower values.
210 low.set_battery_time_to_empty_sec(TrayPower::kLowPowerMinutes * 60 - 20);
212 SCOPED_TRACE("Notification persists at lower values");
213 UpdateNotificationState(low, TrayPower::NOTIFICATION_LOW_POWER, false,
214 false);
217 // The critical low battery notification should be shown when the rounded
218 // value is at the lower threshold.
219 PowerSupplyProperties critical = DefaultPowerSupplyProperties();
220 critical.set_battery_time_to_empty_sec(TrayPower::kCriticalMinutes * 60 + 29);
222 SCOPED_TRACE("Critical notification when time to empty is critical");
223 UpdateNotificationState(critical, TrayPower::NOTIFICATION_CRITICAL, true,
224 true);
227 // The notification should be dismissed when the no-warning threshold is
228 // reached.
229 PowerSupplyProperties safe = DefaultPowerSupplyProperties();
230 safe.set_battery_time_to_empty_sec(TrayPower::kNoWarningMinutes * 60 - 29);
232 SCOPED_TRACE("Notification removed when battery not low");
233 UpdateNotificationState(safe, TrayPower::NOTIFICATION_NONE, false, true);
236 // Test that rounded percentages are used when a USB charger is connected.
237 PowerSupplyProperties low_usb = DefaultPowerSupplyProperties();
238 low_usb.set_external_power(
239 power_manager::PowerSupplyProperties_ExternalPower_USB);
240 low_usb.set_battery_percent(TrayPower::kLowPowerPercentage + 0.5);
242 SCOPED_TRACE("No notification for rounded battery percent");
243 UpdateNotificationState(low_usb, TrayPower::NOTIFICATION_NONE, true, false);
246 low_usb.set_battery_percent(TrayPower::kLowPowerPercentage + 0.49);
248 SCOPED_TRACE("Notification for rounded low power percent");
249 UpdateNotificationState(low_usb, TrayPower::NOTIFICATION_LOW_POWER, true,
250 false);
253 PowerSupplyProperties critical_usb = DefaultPowerSupplyProperties();
254 critical_usb.set_external_power(
255 power_manager::PowerSupplyProperties_ExternalPower_USB);
256 critical_usb.set_battery_percent(TrayPower::kCriticalPercentage + 0.2);
258 SCOPED_TRACE("Notification for rounded critical power percent");
259 UpdateNotificationState(critical_usb, TrayPower::NOTIFICATION_CRITICAL,
260 true, true);
263 PowerSupplyProperties safe_usb = DefaultPowerSupplyProperties();
264 safe_usb.set_external_power(
265 power_manager::PowerSupplyProperties_ExternalPower_USB);
266 safe_usb.set_battery_percent(TrayPower::kNoWarningPercentage - 0.1);
268 SCOPED_TRACE("Notification removed for rounded percent above threshold");
269 UpdateNotificationState(safe_usb, TrayPower::NOTIFICATION_NONE, false,
270 true);
274 } // namespace ash