// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "device/battery/battery_status_service.h" #include #include "base/bind.h" #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "device/battery/battery_status_manager.h" #include "testing/gtest/include/gtest/gtest.h" namespace device { namespace { class FakeBatteryManager : public BatteryStatusManager { public: explicit FakeBatteryManager( const BatteryStatusService::BatteryUpdateCallback& callback) : callback_(callback), start_invoked_count_(0), stop_invoked_count_(0) {} ~FakeBatteryManager() override {} // Methods from Battery Status Manager bool StartListeningBatteryChange() override { start_invoked_count_++; return true; } void StopListeningBatteryChange() override { stop_invoked_count_++; } void InvokeUpdateCallback(const BatteryStatus& status) { callback_.Run(status); } int start_invoked_count() const { return start_invoked_count_; } int stop_invoked_count() const { return stop_invoked_count_; } private: BatteryStatusService::BatteryUpdateCallback callback_; int start_invoked_count_; int stop_invoked_count_; DISALLOW_COPY_AND_ASSIGN(FakeBatteryManager); }; } // namespace class BatteryStatusServiceTest : public testing::Test { public: BatteryStatusServiceTest() : battery_manager_(nullptr), callback1_invoked_count_(0), callback2_invoked_count_(0) {} ~BatteryStatusServiceTest() override {} protected: typedef BatteryStatusService::BatteryUpdateSubscription BatterySubscription; void SetUp() override { callback1_ = base::Bind(&BatteryStatusServiceTest::Callback1, base::Unretained(this)); callback2_ = base::Bind(&BatteryStatusServiceTest::Callback2, base::Unretained(this)); // We keep a raw pointer to the FakeBatteryManager, which we expect to // remain valid for the lifetime of the BatteryStatusService. scoped_ptr battery_manager( new FakeBatteryManager(battery_service_.GetUpdateCallbackForTesting())); battery_manager_ = battery_manager.get(); battery_service_.SetBatteryManagerForTesting(std::move(battery_manager)); } void TearDown() override { base::RunLoop().RunUntilIdle(); } FakeBatteryManager* battery_manager() { return battery_manager_; } scoped_ptr AddCallback( const BatteryStatusService::BatteryUpdateCallback& callback) { return battery_service_.AddCallback(callback); } int callback1_invoked_count() const { return callback1_invoked_count_; } int callback2_invoked_count() const { return callback2_invoked_count_; } const BatteryStatus& battery_status() const { return battery_status_; } const BatteryStatusService::BatteryUpdateCallback& callback1() const { return callback1_; } const BatteryStatusService::BatteryUpdateCallback& callback2() const { return callback2_; } private: void Callback1(const BatteryStatus& status) { callback1_invoked_count_++; battery_status_ = status; } void Callback2(const BatteryStatus& status) { callback2_invoked_count_++; battery_status_ = status; } base::MessageLoop message_loop_; BatteryStatusService battery_service_; FakeBatteryManager* battery_manager_; BatteryStatusService::BatteryUpdateCallback callback1_; BatteryStatusService::BatteryUpdateCallback callback2_; int callback1_invoked_count_; int callback2_invoked_count_; BatteryStatus battery_status_; DISALLOW_COPY_AND_ASSIGN(BatteryStatusServiceTest); }; TEST_F(BatteryStatusServiceTest, AddFirstCallback) { scoped_ptr subscription1 = AddCallback(callback1()); EXPECT_EQ(1, battery_manager()->start_invoked_count()); EXPECT_EQ(0, battery_manager()->stop_invoked_count()); subscription1.reset(); EXPECT_EQ(1, battery_manager()->start_invoked_count()); EXPECT_EQ(1, battery_manager()->stop_invoked_count()); } TEST_F(BatteryStatusServiceTest, AddCallbackAfterUpdate) { scoped_ptr subscription1 = AddCallback(callback1()); BatteryStatus status; battery_manager()->InvokeUpdateCallback(status); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, callback1_invoked_count()); EXPECT_EQ(0, callback2_invoked_count()); scoped_ptr subscription2 = AddCallback(callback2()); EXPECT_EQ(1, callback1_invoked_count()); EXPECT_EQ(1, callback2_invoked_count()); } TEST_F(BatteryStatusServiceTest, TwoCallbacksUpdate) { scoped_ptr subscription1 = AddCallback(callback1()); scoped_ptr subscription2 = AddCallback(callback2()); BatteryStatus status; status.charging = true; status.charging_time = 100; status.discharging_time = 200; status.level = 0.5; battery_manager()->InvokeUpdateCallback(status); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, callback1_invoked_count()); EXPECT_EQ(1, callback2_invoked_count()); EXPECT_EQ(status.charging, battery_status().charging); EXPECT_EQ(status.charging_time, battery_status().charging_time); EXPECT_EQ(status.discharging_time, battery_status().discharging_time); EXPECT_EQ(status.level, battery_status().level); } TEST_F(BatteryStatusServiceTest, RemoveOneCallback) { scoped_ptr subscription1 = AddCallback(callback1()); scoped_ptr subscription2 = AddCallback(callback2()); BatteryStatus status; battery_manager()->InvokeUpdateCallback(status); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, callback1_invoked_count()); EXPECT_EQ(1, callback2_invoked_count()); subscription1.reset(); battery_manager()->InvokeUpdateCallback(status); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, callback1_invoked_count()); EXPECT_EQ(2, callback2_invoked_count()); } } // namespace device