blob: c4bf62c78b7049f61b1ce5e79d80f44893f59f74 [file] [log] [blame]
leon.handa7e1a12017-05-20 12:40:551// Copyright 2017 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 <utility>
6
7#include "base/bind.h"
8#include "base/macros.h"
9#include "content/public/browser/web_contents.h"
10#include "content/public/test/browser_test_utils.h"
11#include "content/public/test/content_browser_test.h"
12#include "content/public/test/content_browser_test_utils.h"
13#include "content/public/test/test_navigation_observer.h"
14#include "content/public/test/test_utils.h"
15#include "content/shell/browser/shell.h"
16#include "mojo/public/cpp/bindings/binding.h"
17#include "services/device/public/interfaces/battery_monitor.mojom.h"
18#include "services/device/public/interfaces/constants.mojom.h"
19#include "services/service_manager/public/cpp/service_context.h"
20
21namespace content {
22
23namespace {
24
25class MockBatteryMonitor : public device::mojom::BatteryMonitor {
26 public:
27 MockBatteryMonitor() : binding_(this) {}
28 ~MockBatteryMonitor() override = default;
29
30 void Bind(const service_manager::BindSourceInfo& source_info,
31 const std::string& interface_name,
32 mojo::ScopedMessagePipeHandle handle) {
33 DCHECK(!binding_.is_bound());
34 binding_.Bind(device::mojom::BatteryMonitorRequest(std::move(handle)));
35 }
36
37 void DidChange(const device::mojom::BatteryStatus& battery_status) {
38 status_ = battery_status;
39 status_to_report_ = true;
40
41 if (!callback_.is_null())
42 ReportStatus();
43 }
44
45 private:
46 // mojom::BatteryMonitor methods:
47 void QueryNextStatus(const QueryNextStatusCallback& callback) override {
48 if (!callback_.is_null()) {
49 DVLOG(1) << "Overlapped call to QueryNextStatus!";
50 binding_.Close();
51 return;
52 }
53 callback_ = callback;
54
55 if (status_to_report_)
56 ReportStatus();
57 }
58
59 void ReportStatus() {
60 callback_.Run(status_.Clone());
61 callback_.Reset();
62
63 status_to_report_ = false;
64 }
65
66 QueryNextStatusCallback callback_;
67 device::mojom::BatteryStatus status_;
68 bool status_to_report_ = false;
69 mojo::Binding<device::mojom::BatteryMonitor> binding_;
70
71 DISALLOW_COPY_AND_ASSIGN(MockBatteryMonitor);
72};
73
74class BatteryMonitorTest : public ContentBrowserTest {
75 public:
76 BatteryMonitorTest() = default;
77
78 void SetUpOnMainThread() override {
79 mock_battery_monitor_ = base::MakeUnique<MockBatteryMonitor>();
80 // Because Device Service also runs in this process(browser process), here
81 // we can directly set our binder to intercept interface requests against
82 // it.
83 service_manager::ServiceContext::SetGlobalBinderForTesting(
84 device::mojom::kServiceName, device::mojom::BatteryMonitor::Name_,
85 base::Bind(&MockBatteryMonitor::Bind,
86 base::Unretained(mock_battery_monitor_.get())));
87 }
88
89 protected:
90 MockBatteryMonitor* mock_battery_monitor() {
91 return mock_battery_monitor_.get();
92 }
93
94 private:
95 std::unique_ptr<MockBatteryMonitor> mock_battery_monitor_;
96
97 DISALLOW_COPY_AND_ASSIGN(BatteryMonitorTest);
98};
99
100IN_PROC_BROWSER_TEST_F(BatteryMonitorTest, NavigatorGetBatteryInfo) {
101 // From JavaScript request a promise for the battery status information and
102 // once it resolves check the values and navigate to #pass.
103 device::mojom::BatteryStatus status;
104 status.charging = true;
105 status.charging_time = 100;
106 status.discharging_time = std::numeric_limits<double>::infinity();
107 status.level = 0.5;
108 mock_battery_monitor()->DidChange(status);
109
110 GURL test_url = GetTestUrl("battery_monitor",
111 "battery_status_promise_resolution_test.html");
112 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2);
113 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
114}
115
116IN_PROC_BROWSER_TEST_F(BatteryMonitorTest, NavigatorGetBatteryListenChange) {
117 // From JavaScript request a promise for the battery status information.
118 // Once it resolves add an event listener for battery level change. Set
119 // battery level to 0.6 and invoke update. Check that the event listener
120 // is invoked with the correct value for level and navigate to #pass.
121 device::mojom::BatteryStatus status;
122 mock_battery_monitor()->DidChange(status);
123
124 TestNavigationObserver same_tab_observer(shell()->web_contents(), 2);
125 GURL test_url =
126 GetTestUrl("battery_monitor", "battery_status_event_listener_test.html");
127 shell()->LoadURL(test_url);
128 same_tab_observer.Wait();
129 EXPECT_EQ("resolved", shell()->web_contents()->GetLastCommittedURL().ref());
130
131 TestNavigationObserver same_tab_observer2(shell()->web_contents(), 1);
132 status.level = 0.6;
133 mock_battery_monitor()->DidChange(status);
134 same_tab_observer2.Wait();
135 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
136}
137
138} // namespace
139
140} // namespace content