blob: e7e09fae1b30b51d242d512f56ba1e9071e14a9b [file] [log] [blame]
leon.hana0c5fa32017-06-13 08:14:111// 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 "base/bind.h"
6#include "base/macros.h"
7#include "base/run_loop.h"
Han Leon18ea6202017-06-19 03:34:498#include "base/strings/utf_string_conversions.h"
9#include "content/public/browser/browser_thread.h"
leon.hana0c5fa32017-06-13 08:14:1110#include "content/public/browser/render_frame_host.h"
11#include "content/public/browser/render_process_host.h"
Han Leon18ea6202017-06-19 03:34:4912#include "content/public/browser/utility_process_host.h"
13#include "content/public/browser/utility_process_host_client.h"
leon.hana0c5fa32017-06-13 08:14:1114#include "content/public/browser/web_contents.h"
15#include "content/public/common/service_names.mojom.h"
16#include "content/public/test/browser_test_utils.h"
17#include "content/public/test/content_browser_test.h"
18#include "content/public/test/content_browser_test_utils.h"
19#include "content/shell/browser/shell.h"
20#include "content/shell/common/power_monitor_test.mojom.h"
21#include "mojo/public/cpp/bindings/binding_set.h"
22#include "mojo/public/cpp/bindings/interface_ptr_set.h"
23#include "services/device/public/interfaces/constants.mojom.h"
24#include "services/device/public/interfaces/power_monitor.mojom.h"
25#include "services/service_manager/public/cpp/service_context.h"
26
27namespace content {
28
29namespace {
30
31void VerifyPowerStateInChildProcess(mojom::PowerMonitorTest* power_monitor_test,
32 bool expected_state) {
33 base::RunLoop run_loop;
34 power_monitor_test->QueryNextState(base::Bind(
35 [](const base::Closure& quit, bool expected_state,
36 bool on_battery_power) {
37 EXPECT_EQ(expected_state, on_battery_power);
38 quit.Run();
39 },
40 run_loop.QuitClosure(), expected_state));
41 run_loop.Run();
42}
43
Han Leon18ea6202017-06-19 03:34:4944void StartUtilityProcessOnIOThread(mojom::PowerMonitorTestRequest request) {
45 UtilityProcessHost* host = UtilityProcessHost::Create(nullptr, nullptr);
46 host->SetName(base::ASCIIToUTF16("TestProcess"));
47 EXPECT_TRUE(host->Start());
48
49 BindInterface(host, std::move(request));
50}
51
leon.hana0c5fa32017-06-13 08:14:1152class MockPowerMonitorMessageBroadcaster : public device::mojom::PowerMonitor {
53 public:
54 MockPowerMonitorMessageBroadcaster() = default;
55 ~MockPowerMonitorMessageBroadcaster() override = default;
56
57 void Bind(device::mojom::PowerMonitorRequest request) {
58 bindings_.AddBinding(this, std::move(request));
59 }
60
61 // device::mojom::PowerMonitor:
62 void AddClient(
63 device::mojom::PowerMonitorClientPtr power_monitor_client) override {
64 power_monitor_client->PowerStateChange(on_battery_power_);
65 clients_.AddPtr(std::move(power_monitor_client));
66 }
67
68 void OnPowerStateChange(bool on_battery_power) {
69 on_battery_power_ = on_battery_power;
70 clients_.ForAllPtrs(
71 [&on_battery_power](device::mojom::PowerMonitorClient* client) {
72 client->PowerStateChange(on_battery_power);
73 });
74 }
75
76 private:
77 bool on_battery_power_ = false;
78
79 mojo::BindingSet<device::mojom::PowerMonitor> bindings_;
80 mojo::InterfacePtrSet<device::mojom::PowerMonitorClient> clients_;
81
82 DISALLOW_COPY_AND_ASSIGN(MockPowerMonitorMessageBroadcaster);
83};
84
85class PowerMonitorTest : public ContentBrowserTest {
86 public:
87 PowerMonitorTest() = default;
88
89 void SetUpOnMainThread() override {
90 // Because Device Service also runs in this process(browser process), we can
91 // set our binder to intercept requests for PowerMonitor interface to it.
92 service_manager::ServiceContext::SetGlobalBinderForTesting(
93 device::mojom::kServiceName, device::mojom::PowerMonitor::Name_,
94 base::Bind(&PowerMonitorTest::BindPowerMonitor,
95 base::Unretained(this)));
96 }
97
98 void BindPowerMonitor(const service_manager::BindSourceInfo& source_info,
99 const std::string& interface_name,
100 mojo::ScopedMessagePipeHandle handle) {
Han Leon18ea6202017-06-19 03:34:49101 if (source_info.identity.name() == mojom::kRendererServiceName) {
leon.hana0c5fa32017-06-13 08:14:11102 ++request_count_from_renderer_;
103
Han Leon18ea6202017-06-19 03:34:49104 DCHECK(renderer_bound_closure_);
105 std::move(renderer_bound_closure_).Run();
106 } else if (source_info.identity.name() == mojom::kUtilityServiceName) {
107 ++request_count_from_utility_;
108
109 DCHECK(utility_bound_closure_);
110 std::move(utility_bound_closure_).Run();
111 }
112
leon.hana0c5fa32017-06-13 08:14:11113 power_monitor_message_broadcaster_.Bind(
114 device::mojom::PowerMonitorRequest(std::move(handle)));
115 }
116
117 protected:
Han Leon18ea6202017-06-19 03:34:49118 void StartUtilityProcess(mojom::PowerMonitorTestPtr* power_monitor_test,
119 base::Closure utility_bound_closure) {
120 utility_bound_closure_ = utility_bound_closure;
121 BrowserThread::PostTask(
122 BrowserThread::IO, FROM_HERE,
123 base::BindOnce(&StartUtilityProcessOnIOThread,
124 mojo::MakeRequest(power_monitor_test)));
125 }
126
127 void set_renderer_bound_closure(base::Closure closure) {
128 renderer_bound_closure_ = closure;
129 }
130
leon.hana0c5fa32017-06-13 08:14:11131 int request_count_from_renderer() { return request_count_from_renderer_; }
Han Leon18ea6202017-06-19 03:34:49132 int request_count_from_utility() { return request_count_from_utility_; }
leon.hana0c5fa32017-06-13 08:14:11133
134 void SimulatePowerStateChange(bool on_battery_power) {
135 power_monitor_message_broadcaster_.OnPowerStateChange(on_battery_power);
136 }
137
138 private:
139 int request_count_from_renderer_ = 0;
Han Leon18ea6202017-06-19 03:34:49140 int request_count_from_utility_ = 0;
141 base::OnceClosure renderer_bound_closure_;
142 base::OnceClosure utility_bound_closure_;
leon.hana0c5fa32017-06-13 08:14:11143
144 MockPowerMonitorMessageBroadcaster power_monitor_message_broadcaster_;
145
146 DISALLOW_COPY_AND_ASSIGN(PowerMonitorTest);
147};
148
Han Leon18ea6202017-06-19 03:34:49149IN_PROC_BROWSER_TEST_F(PowerMonitorTest, TestRendererProcess) {
leon.hana0c5fa32017-06-13 08:14:11150 ASSERT_EQ(0, request_count_from_renderer());
Han Leon18ea6202017-06-19 03:34:49151 base::RunLoop run_loop;
152 set_renderer_bound_closure(run_loop.QuitClosure());
leon.hana0c5fa32017-06-13 08:14:11153 ASSERT_TRUE(NavigateToURL(shell(), GetTestUrl(".", "simple_page.html")));
Han Leon18ea6202017-06-19 03:34:49154 run_loop.Run();
leon.hana0c5fa32017-06-13 08:14:11155 EXPECT_EQ(1, request_count_from_renderer());
156
157 mojom::PowerMonitorTestPtr power_monitor_renderer;
158 RenderProcessHost* rph =
159 shell()->web_contents()->GetMainFrame()->GetProcess();
160 BindInterface(rph, &power_monitor_renderer);
161
162 SimulatePowerStateChange(true);
163 // Verify renderer process on_battery_power changed to true.
164 VerifyPowerStateInChildProcess(power_monitor_renderer.get(), true);
165
166 SimulatePowerStateChange(false);
167 // Verify renderer process on_battery_power changed to false.
168 VerifyPowerStateInChildProcess(power_monitor_renderer.get(), false);
169}
170
Han Leon18ea6202017-06-19 03:34:49171IN_PROC_BROWSER_TEST_F(PowerMonitorTest, TestUtilityProcess) {
172 mojom::PowerMonitorTestPtr power_monitor_utility;
173
174 ASSERT_EQ(0, request_count_from_utility());
175 base::RunLoop run_loop;
176 StartUtilityProcess(&power_monitor_utility, run_loop.QuitClosure());
177 run_loop.Run();
178 EXPECT_EQ(1, request_count_from_utility());
179
180 SimulatePowerStateChange(true);
181 // Verify utility process on_battery_power changed to true.
182 VerifyPowerStateInChildProcess(power_monitor_utility.get(), true);
183
184 SimulatePowerStateChange(false);
185 // Verify utility process on_battery_power changed to false.
186 VerifyPowerStateInChildProcess(power_monitor_utility.get(), false);
187}
188
leon.hana0c5fa32017-06-13 08:14:11189} // namespace
190
191} // namespace content