1// Copyright 2014 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 "content/browser/battery_status/battery_status_service.h"
6
7#include "base/bind.h"
8#include "base/run_loop.h"
9#include "content/browser/battery_status/battery_status_manager.h"
10#include "content/public/test/test_browser_thread_bundle.h"
11
12namespace content {
13
14namespace {
15
16class FakeBatteryManager : public BatteryStatusManager {
17 public:
18  explicit FakeBatteryManager(
19      const BatteryStatusService::BatteryUpdateCallback& callback)
20      : callback_(callback), start_invoked_count_(0), stop_invoked_count_(0) {}
21  virtual ~FakeBatteryManager() { }
22
23  // Methods from Battery Status Manager
24  virtual bool StartListeningBatteryChange() OVERRIDE {
25    start_invoked_count_++;
26    return true;
27  }
28
29  virtual void StopListeningBatteryChange() OVERRIDE {
30    stop_invoked_count_++;
31  }
32
33  void InvokeUpdateCallback(const blink::WebBatteryStatus& status) {
34    callback_.Run(status);
35  }
36
37  int start_invoked_count() const { return start_invoked_count_; }
38  int stop_invoked_count() const { return stop_invoked_count_; }
39
40 private:
41  BatteryStatusService::BatteryUpdateCallback callback_;
42  int start_invoked_count_;
43  int stop_invoked_count_;
44
45  DISALLOW_COPY_AND_ASSIGN(FakeBatteryManager);
46};
47
48class BatteryStatusServiceTest : public testing::Test {
49 public:
50    BatteryStatusServiceTest()
51        : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
52          battery_service_(0),
53          battery_manager_(0),
54          callback1_invoked_count_(0),
55          callback2_invoked_count_(0) {
56    }
57    virtual ~BatteryStatusServiceTest() { }
58
59 protected:
60  typedef BatteryStatusService::BatteryUpdateSubscription BatterySubscription;
61
62  virtual void SetUp() OVERRIDE {
63    callback1_ = base::Bind(&BatteryStatusServiceTest::Callback1,
64                            base::Unretained(this));
65    callback2_ = base::Bind(&BatteryStatusServiceTest::Callback2,
66                            base::Unretained(this));
67    battery_service_ = BatteryStatusService::GetInstance();
68    battery_manager_ = new FakeBatteryManager(
69        battery_service_->GetUpdateCallbackForTesting());
70    battery_service_->SetBatteryManagerForTesting(battery_manager_);
71  }
72
73  virtual void TearDown() OVERRIDE {
74    base::RunLoop().RunUntilIdle();
75    battery_service_->SetBatteryManagerForTesting(0);
76  }
77
78  FakeBatteryManager* battery_manager() {
79    return battery_manager_;
80  }
81
82  scoped_ptr<BatterySubscription> AddCallback(
83      const BatteryStatusService::BatteryUpdateCallback& callback) {
84    return battery_service_->AddCallback(callback);
85  }
86
87  int callback1_invoked_count() const {
88    return callback1_invoked_count_;
89  }
90
91  int callback2_invoked_count() const {
92    return callback2_invoked_count_;
93  }
94
95  const blink::WebBatteryStatus& battery_status() const {
96    return battery_status_;
97  }
98
99  const BatteryStatusService::BatteryUpdateCallback& callback1() const {
100    return callback1_;
101  }
102
103  const BatteryStatusService::BatteryUpdateCallback& callback2() const {
104    return callback2_;
105  }
106
107 private:
108  void Callback1(const blink::WebBatteryStatus& status) {
109    callback1_invoked_count_++;
110    battery_status_ = status;
111  }
112
113  void Callback2(const blink::WebBatteryStatus& status) {
114    callback2_invoked_count_++;
115    battery_status_ = status;
116  }
117
118  content::TestBrowserThreadBundle thread_bundle_;
119  BatteryStatusService* battery_service_;
120  FakeBatteryManager* battery_manager_;
121  BatteryStatusService::BatteryUpdateCallback callback1_;
122  BatteryStatusService::BatteryUpdateCallback callback2_;
123  int callback1_invoked_count_;
124  int callback2_invoked_count_;
125  blink::WebBatteryStatus battery_status_;
126
127  DISALLOW_COPY_AND_ASSIGN(BatteryStatusServiceTest);
128};
129
130TEST_F(BatteryStatusServiceTest, AddFirstCallback) {
131  scoped_ptr<BatterySubscription> subscription1 = AddCallback(callback1());
132  EXPECT_EQ(1, battery_manager()->start_invoked_count());
133  EXPECT_EQ(0, battery_manager()->stop_invoked_count());
134  subscription1.reset();
135  EXPECT_EQ(1, battery_manager()->start_invoked_count());
136  EXPECT_EQ(1, battery_manager()->stop_invoked_count());
137}
138
139TEST_F(BatteryStatusServiceTest, AddCallbackAfterUpdate) {
140  scoped_ptr<BatterySubscription> subscription1 = AddCallback(callback1());
141  blink::WebBatteryStatus status;
142  battery_manager()->InvokeUpdateCallback(status);
143  base::RunLoop().RunUntilIdle();
144  EXPECT_EQ(1, callback1_invoked_count());
145  EXPECT_EQ(0, callback2_invoked_count());
146
147  scoped_ptr<BatterySubscription> subscription2 = AddCallback(callback2());
148  EXPECT_EQ(1, callback1_invoked_count());
149  EXPECT_EQ(1, callback2_invoked_count());
150}
151
152TEST_F(BatteryStatusServiceTest, TwoCallbacksUpdate) {
153  scoped_ptr<BatterySubscription> subscription1 = AddCallback(callback1());
154  scoped_ptr<BatterySubscription> subscription2 = AddCallback(callback2());
155
156  blink::WebBatteryStatus status;
157  status.charging = true;
158  status.chargingTime = 100;
159  status.dischargingTime = 200;
160  status.level = 0.5;
161  battery_manager()->InvokeUpdateCallback(status);
162  base::RunLoop().RunUntilIdle();
163
164  EXPECT_EQ(1, callback1_invoked_count());
165  EXPECT_EQ(1, callback2_invoked_count());
166  EXPECT_EQ(status.charging, battery_status().charging);
167  EXPECT_EQ(status.chargingTime, battery_status().chargingTime);
168  EXPECT_EQ(status.dischargingTime, battery_status().dischargingTime);
169  EXPECT_EQ(status.level, battery_status().level);
170}
171
172TEST_F(BatteryStatusServiceTest, RemoveOneCallback) {
173  scoped_ptr<BatterySubscription> subscription1 = AddCallback(callback1());
174  scoped_ptr<BatterySubscription> subscription2 = AddCallback(callback2());
175
176  blink::WebBatteryStatus status;
177  battery_manager()->InvokeUpdateCallback(status);
178  base::RunLoop().RunUntilIdle();
179  EXPECT_EQ(1, callback1_invoked_count());
180  EXPECT_EQ(1, callback2_invoked_count());
181
182  subscription1.reset();
183  battery_manager()->InvokeUpdateCallback(status);
184  base::RunLoop().RunUntilIdle();
185  EXPECT_EQ(1, callback1_invoked_count());
186  EXPECT_EQ(2, callback2_invoked_count());
187}
188
189}  // namespace
190
191}  // namespace content
192