1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/power/peripheral_battery_observer.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/command_line.h"
89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/browser_process.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/notifications/notification_ui_manager.h"
113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromeos/dbus/dbus_thread_manager.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/test/test_utils.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::_;
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::InSequence;
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::Return;
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ::testing::SaveArg;
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kTestBatteryPath[] = "/sys/class/power_supply/hid-AA:BB:CC-battery";
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kTestBatteryAddress[] = "cc:bb:aa";
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kTestDeviceName[] = "test device";
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos {
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class PeripheralBatteryObserverTest : public InProcessBrowserTest {
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PeripheralBatteryObserverTest() {}
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~PeripheralBatteryObserverTest() {}
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void SetUp() OVERRIDE {
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    chromeos::DBusThreadManager::Initialize();
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUpOnMainThread() OVERRIDE {
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    observer_.reset(new PeripheralBatteryObserver());
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void TearDownOnMainThread() OVERRIDE {
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    observer_.reset();
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<PeripheralBatteryObserver> observer_;
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PeripheralBatteryObserverTest);
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(PeripheralBatteryObserverTest, Basic) {
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::SimpleTestTickClock clock;
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer_->set_testing_clock(&clock);
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NotificationUIManager* notification_manager =
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      g_browser_process->notification_ui_manager();
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Level 50 at time 100, no low-battery notification.
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  clock.Advance(base::TimeDelta::FromSeconds(100));
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             kTestDeviceName, 50);
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(observer_->batteries_.count(kTestBatteryAddress), 1u);
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const PeripheralBatteryObserver::BatteryInfo& info =
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      observer_->batteries_[kTestBatteryAddress];
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(info.name, kTestDeviceName);
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(info.level, 50);
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(info.last_notification_timestamp, base::TimeTicks());
83558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_FALSE(notification_manager->FindById(kTestBatteryAddress) != NULL);
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Level 5 at time 110, low-battery notification.
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  clock.Advance(base::TimeDelta::FromSeconds(10));
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             kTestDeviceName, 5);
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(info.level, 5);
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(info.last_notification_timestamp, clock.NowTicks());
91558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_TRUE(notification_manager->FindById(kTestBatteryAddress) != NULL);
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Level -1 at time 115, cancel previous notification
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  clock.Advance(base::TimeDelta::FromSeconds(5));
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             kTestDeviceName, -1);
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(info.level, 5);
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(info.last_notification_timestamp,
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            clock.NowTicks() - base::TimeDelta::FromSeconds(5));
100558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_FALSE(notification_manager->FindById(kTestBatteryAddress) != NULL);
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Level 50 at time 120, no low-battery notification.
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  clock.Advance(base::TimeDelta::FromSeconds(5));
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             kTestDeviceName, 50);
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(info.level, 50);
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(info.last_notification_timestamp,
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            clock.NowTicks() - base::TimeDelta::FromSeconds(10));
109558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_FALSE(notification_manager->FindById(kTestBatteryAddress) != NULL);
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Level 5 at time 130, no low-battery notification (throttling).
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  clock.Advance(base::TimeDelta::FromSeconds(10));
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             kTestDeviceName, 5);
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(info.level, 5);
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(info.last_notification_timestamp,
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            clock.NowTicks() - base::TimeDelta::FromSeconds(20));
118558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_FALSE(notification_manager->FindById(kTestBatteryAddress) != NULL);
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(PeripheralBatteryObserverTest, InvalidBatteryInfo) {
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer_->PeripheralBatteryStatusReceived("invalid-path", kTestDeviceName,
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             10);
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer_->batteries_.empty());
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer_->PeripheralBatteryStatusReceived(
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "/sys/class/power_supply/hid-battery", kTestDeviceName, 10);
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer_->batteries_.empty());
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             kTestDeviceName, -2);
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer_->batteries_.empty());
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             kTestDeviceName, 101);
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer_->batteries_.empty());
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             kTestDeviceName, -1);
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer_->batteries_.empty());
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(PeripheralBatteryObserverTest, DeviceRemove) {
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NotificationUIManager* notification_manager =
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      g_browser_process->notification_ui_manager();
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer_->PeripheralBatteryStatusReceived(kTestBatteryPath,
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             kTestDeviceName, 5);
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(observer_->batteries_.count(kTestBatteryAddress), 1u);
150558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_TRUE(notification_manager->FindById(kTestBatteryAddress) != NULL);
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer_->RemoveBattery(kTestBatteryAddress);
153558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_FALSE(notification_manager->FindById(kTestBatteryAddress) != NULL);
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace chromeos
157