Index: services/device/battery/battery_monitor_impl_unittest.cc |
diff --git a/services/device/battery/battery_monitor_impl_unittest.cc b/services/device/battery/battery_monitor_impl_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..86d5ac18b084c012a2dfbc85542c4d2771aef182 |
--- /dev/null |
+++ b/services/device/battery/battery_monitor_impl_unittest.cc |
@@ -0,0 +1,192 @@ |
+// Copyright (c) 2017 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_monitor_impl.h" |
+ |
+#include <utility> |
+ |
+#include "base/macros.h" |
+#include "base/run_loop.h" |
+#include "base/threading/thread_task_runner_handle.h" |
+#include "device/battery/battery_monitor.mojom.h" |
+#include "device/battery/battery_status_manager.h" |
+#include "device/battery/battery_status_service.h" |
+#include "services/device/device_service_test_base.h" |
+#include "services/device/public/interfaces/constants.mojom.h" |
+ |
+// These tests run against the implementation of the BatteryMonitor interface |
+// inside Device Service, with a dummy BatteryManager set as a source of the |
+// battery information. They can be run only on platforms that use the default |
+// battery service implementation, ie. on the platforms where |
+// BatteryStatusService is used. |
+ |
+namespace device { |
+ |
+namespace { |
+ |
+void ExpectBatteryStatus(bool* out_called, |
+ const mojom::BatteryStatus& expected, |
+ const base::Closure& quit_closure, |
+ mojom::BatteryStatusPtr status) { |
+ if (out_called) |
+ *out_called = true; |
+ EXPECT_EQ(expected.charging, status->charging); |
+ EXPECT_EQ(expected.charging_time, status->charging_time); |
+ EXPECT_EQ(expected.discharging_time, status->discharging_time); |
+ EXPECT_EQ(expected.level, status->level); |
+ quit_closure.Run(); |
+} |
+ |
+class FakeBatteryManager : public BatteryStatusManager { |
+ public: |
+ explicit FakeBatteryManager( |
+ const BatteryStatusService::BatteryUpdateCallback& callback) |
+ : callback_(callback), battery_status_available_(true), started_(false) {} |
+ ~FakeBatteryManager() override {} |
+ |
+ // Methods from BatteryStatusManager. |
+ bool StartListeningBatteryChange() override { |
+ started_ = true; |
+ if (battery_status_available_) |
+ InvokeUpdateCallback(); |
+ return battery_status_available_; |
+ } |
+ |
+ void StopListeningBatteryChange() override {} |
+ |
+ void InvokeUpdateCallback() { |
+ // Invoke asynchronously to mimic the OS-specific battery managers. |
+ base::ThreadTaskRunnerHandle::Get()->PostTask( |
+ FROM_HERE, base::Bind(callback_, status_)); |
+ } |
+ |
+ void set_battery_status(const mojom::BatteryStatus& status) { |
+ status_ = status; |
+ } |
+ |
+ void set_battery_status_available(bool value) { |
+ battery_status_available_ = value; |
+ } |
+ |
+ bool started() { return started_; } |
+ |
+ private: |
+ BatteryStatusService::BatteryUpdateCallback callback_; |
+ bool battery_status_available_; |
+ bool started_; |
+ mojom::BatteryStatus status_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FakeBatteryManager); |
+}; |
+ |
+class BatteryMonitorImplTest : public DeviceServiceTestBase { |
+ public: |
+ BatteryMonitorImplTest() = default; |
+ ~BatteryMonitorImplTest() override = default; |
+ |
+ protected: |
+ void SetUp() override { |
+ DeviceServiceTestBase::SetUp(); |
+ |
+ BatteryStatusService* battery_service = BatteryStatusService::GetInstance(); |
+ std::unique_ptr<FakeBatteryManager> battery_manager( |
+ new FakeBatteryManager(battery_service->GetUpdateCallbackForTesting())); |
+ battery_manager_ = battery_manager.get(); |
+ battery_service->SetBatteryManagerForTesting(std::move(battery_manager)); |
+ |
+ connector()->BindInterface(mojom::kServiceName, &battery_monitor_); |
+ } |
+ |
+ void TearDown() override { |
+ battery_monitor_.reset(); |
+ // Enforce BatteryMonitorImpl destruction to run before Device Service |
+ // destruction shutting down battery status service, thus the |
+ // BatteryMonitorImpl instance can detach from battery status service |
+ // completely. |
+ base::RunLoop().RunUntilIdle(); |
+ } |
+ |
+ FakeBatteryManager* battery_manager() { return battery_manager_; } |
+ |
+ mojom::BatteryMonitorPtr battery_monitor_; |
+ |
+ private: |
+ FakeBatteryManager* battery_manager_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(BatteryMonitorImplTest); |
+}; |
+ |
+TEST_F(BatteryMonitorImplTest, BatteryManagerDefaultValues) { |
+ // Set the fake battery manager to return false on start. Verify that the |
+ // default battery values will be returned to consumers of Device Service. |
+ battery_manager()->set_battery_status_available(false); |
+ |
+ mojom::BatteryStatus default_status; |
+ default_status.charging = true; |
+ default_status.charging_time = 0; |
+ default_status.discharging_time = std::numeric_limits<double>::infinity(); |
+ default_status.level = 1.0; |
+ base::RunLoop run_loop; |
+ battery_monitor_->QueryNextStatus(base::Bind( |
+ &ExpectBatteryStatus, nullptr, default_status, run_loop.QuitClosure())); |
+ run_loop.Run(); |
+ EXPECT_TRUE(battery_manager()->started()); |
+} |
+ |
+TEST_F(BatteryMonitorImplTest, BatteryManagerPredefinedValues) { |
+ // Set the fake battery manager to return predefined battery status values. |
+ // Verify that the predefined values will be returned to consumers of Device |
+ // Service. |
+ mojom::BatteryStatus status; |
+ status.charging = true; |
+ status.charging_time = 100; |
+ status.discharging_time = std::numeric_limits<double>::infinity(); |
+ status.level = 0.5; |
+ battery_manager()->set_battery_status(status); |
+ |
+ base::RunLoop run_loop; |
+ battery_monitor_->QueryNextStatus(base::Bind(&ExpectBatteryStatus, nullptr, |
+ status, run_loop.QuitClosure())); |
+ run_loop.Run(); |
+ EXPECT_TRUE(battery_manager()->started()); |
+} |
+ |
+TEST_F(BatteryMonitorImplTest, BatteryManagerInvokeUpdate) { |
+ // Set the fake battery manager to return predefined battery status values, |
+ // after queried the battery status first time, query again, the second time |
+ // query will be pending, and then we change battery level to 0.6 and invoke |
+ // update. Verify that the second query will get the new level 0.6 correctly. |
+ mojom::BatteryStatus status; |
+ status.charging = true; |
+ status.charging_time = 100; |
+ status.discharging_time = std::numeric_limits<double>::infinity(); |
+ status.level = 0.5; |
+ battery_manager()->set_battery_status(status); |
+ |
+ // The first time query should succeed. |
+ base::RunLoop run_loop1; |
+ battery_monitor_->QueryNextStatus(base::Bind( |
+ &ExpectBatteryStatus, nullptr, status, run_loop1.QuitClosure())); |
+ run_loop1.Run(); |
+ EXPECT_TRUE(battery_manager()->started()); |
+ |
+ // The second time query should be pending. |
+ bool called = false; |
+ status.level = 0.6; |
+ base::RunLoop run_loop2; |
+ battery_monitor_->QueryNextStatus(base::Bind( |
+ &ExpectBatteryStatus, &called, status, run_loop2.QuitClosure())); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_FALSE(called); |
+ |
+ // InvokeUpdateCallback should fire the pending query correctly. |
+ battery_manager()->set_battery_status(status); |
+ battery_manager()->InvokeUpdateCallback(); |
+ run_loop2.Run(); |
+ EXPECT_TRUE(called); |
+} |
+ |
+} // namespace |
+ |
+} // namespace device |