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 "chrome/browser/chromeos/power/peripheral_battery_observer.h"
6
7#include "base/command_line.h"
8#include "base/message_loop/message_loop.h"
9#include "chrome/browser/browser_process.h"
10#include "chrome/browser/notifications/notification_ui_manager.h"
11#include "chrome/test/base/in_process_browser_test.h"
12#include "chromeos/dbus/dbus_thread_manager.h"
13#include "content/public/test/test_utils.h"
14#include "testing/gmock/include/gmock/gmock.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17using ::testing::_;
18using ::testing::InSequence;
19using ::testing::Return;
20using ::testing::SaveArg;
21
22namespace {
23
24const char kTestBatteryPath[] = "/sys/class/power_supply/hid-AA:BB:CC-battery";
25const char kTestBatteryAddress[] = "cc:bb:aa";
26const char kTestDeviceName[] = "test device";
27
28}  // namespace
29
30namespace chromeos {
31
32class PeripheralBatteryObserverTest : public InProcessBrowserTest {
33 public:
34  PeripheralBatteryObserverTest() {}
35  virtual ~PeripheralBatteryObserverTest() {}
36
37  virtual void SetUp() OVERRIDE {
38    chromeos::DBusThreadManager::Initialize();
39  }
40
41  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
42    InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
43  }
44
45  virtual void SetUpOnMainThread() OVERRIDE {
46    observer_.reset(new PeripheralBatteryObserver());
47  }
48
49  virtual void TearDownOnMainThread() OVERRIDE {
50    observer_.reset();
51  }
52
53  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
54    InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
55  }
56
57 protected:
58  scoped_ptr<PeripheralBatteryObserver> observer_;
59
60 private:
61  DISALLOW_COPY_AND_ASSIGN(PeripheralBatteryObserverTest);
62};
63
64IN_PROC_BROWSER_TEST_F(PeripheralBatteryObserverTest, Basic) {
65  base::SimpleTestTickClock clock;
66  observer_->set_testing_clock(&clock);
67
68  NotificationUIManager* notification_manager =
69      g_browser_process->notification_ui_manager();
70
71  // Level 50 at time 100, no low-battery notification.
72  clock.Advance(base::TimeDelta::FromSeconds(100));
73  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
74                                             kTestDeviceName, 50);
75  EXPECT_EQ(observer_->batteries_.count(kTestBatteryAddress), 1u);
76
77  const PeripheralBatteryObserver::BatteryInfo& info =
78      observer_->batteries_[kTestBatteryAddress];
79
80  EXPECT_EQ(info.name, kTestDeviceName);
81  EXPECT_EQ(info.level, 50);
82  EXPECT_EQ(info.last_notification_timestamp, base::TimeTicks());
83  EXPECT_FALSE(notification_manager->FindById(kTestBatteryAddress) != NULL);
84
85  // Level 5 at time 110, low-battery notification.
86  clock.Advance(base::TimeDelta::FromSeconds(10));
87  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
88                                             kTestDeviceName, 5);
89  EXPECT_EQ(info.level, 5);
90  EXPECT_EQ(info.last_notification_timestamp, clock.NowTicks());
91  EXPECT_TRUE(notification_manager->FindById(kTestBatteryAddress) != NULL);
92
93  // Level -1 at time 115, cancel previous notification
94  clock.Advance(base::TimeDelta::FromSeconds(5));
95  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
96                                             kTestDeviceName, -1);
97  EXPECT_EQ(info.level, 5);
98  EXPECT_EQ(info.last_notification_timestamp,
99            clock.NowTicks() - base::TimeDelta::FromSeconds(5));
100  EXPECT_FALSE(notification_manager->FindById(kTestBatteryAddress) != NULL);
101
102  // Level 50 at time 120, no low-battery notification.
103  clock.Advance(base::TimeDelta::FromSeconds(5));
104  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
105                                             kTestDeviceName, 50);
106  EXPECT_EQ(info.level, 50);
107  EXPECT_EQ(info.last_notification_timestamp,
108            clock.NowTicks() - base::TimeDelta::FromSeconds(10));
109  EXPECT_FALSE(notification_manager->FindById(kTestBatteryAddress) != NULL);
110
111  // Level 5 at time 130, no low-battery notification (throttling).
112  clock.Advance(base::TimeDelta::FromSeconds(10));
113  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
114                                             kTestDeviceName, 5);
115  EXPECT_EQ(info.level, 5);
116  EXPECT_EQ(info.last_notification_timestamp,
117            clock.NowTicks() - base::TimeDelta::FromSeconds(20));
118  EXPECT_FALSE(notification_manager->FindById(kTestBatteryAddress) != NULL);
119}
120
121IN_PROC_BROWSER_TEST_F(PeripheralBatteryObserverTest, InvalidBatteryInfo) {
122  observer_->PeripheralBatteryStatusReceived("invalid-path", kTestDeviceName,
123                                             10);
124  EXPECT_TRUE(observer_->batteries_.empty());
125
126  observer_->PeripheralBatteryStatusReceived(
127      "/sys/class/power_supply/hid-battery", kTestDeviceName, 10);
128  EXPECT_TRUE(observer_->batteries_.empty());
129
130  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
131                                             kTestDeviceName, -2);
132  EXPECT_TRUE(observer_->batteries_.empty());
133
134  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
135                                             kTestDeviceName, 101);
136  EXPECT_TRUE(observer_->batteries_.empty());
137
138  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
139                                             kTestDeviceName, -1);
140  EXPECT_TRUE(observer_->batteries_.empty());
141}
142
143IN_PROC_BROWSER_TEST_F(PeripheralBatteryObserverTest, DeviceRemove) {
144  NotificationUIManager* notification_manager =
145      g_browser_process->notification_ui_manager();
146
147  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
148                                             kTestDeviceName, 5);
149  EXPECT_EQ(observer_->batteries_.count(kTestBatteryAddress), 1u);
150  EXPECT_TRUE(notification_manager->FindById(kTestBatteryAddress) != NULL);
151
152  observer_->RemoveBattery(kTestBatteryAddress);
153  EXPECT_FALSE(notification_manager->FindById(kTestBatteryAddress) != NULL);
154}
155
156}  // namespace chromeos
157