Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / content / browser / webui / web_ui_mojo_browsertest.cc
blob2d23ecec8291c1a852b5a1c33a8188d9de4da2b4
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.
5 #include <limits>
7 #include "base/command_line.h"
8 #include "base/file_util.h"
9 #include "base/files/file_path.h"
10 #include "base/path_service.h"
11 #include "base/run_loop.h"
12 #include "base/strings/string_util.h"
13 #include "content/browser/webui/web_ui_controller_factory_registry.h"
14 #include "content/public/browser/browser_context.h"
15 #include "content/public/browser/render_frame_host.h"
16 #include "content/public/browser/render_process_host.h"
17 #include "content/public/browser/render_view_host.h"
18 #include "content/public/browser/web_contents.h"
19 #include "content/public/browser/web_ui_controller.h"
20 #include "content/public/browser/web_ui_data_source.h"
21 #include "content/public/common/content_paths.h"
22 #include "content/public/common/content_switches.h"
23 #include "content/public/common/service_registry.h"
24 #include "content/public/common/url_utils.h"
25 #include "content/public/test/content_browser_test.h"
26 #include "content/public/test/content_browser_test_utils.h"
27 #include "content/shell/browser/shell.h"
28 #include "content/test/data/web_ui_test_mojo_bindings.mojom.h"
29 #include "mojo/common/test/test_utils.h"
30 #include "mojo/public/cpp/bindings/interface_impl.h"
31 #include "mojo/public/cpp/bindings/interface_request.h"
32 #include "mojo/public/js/bindings/constants.h"
34 namespace content {
35 namespace {
37 bool got_message = false;
39 // The bindings for the page are generated from a .mojom file. This code looks
40 // up the generated file from disk and returns it.
41 bool GetResource(const std::string& id,
42 const WebUIDataSource::GotDataCallback& callback) {
43 // These are handled by the WebUIDataSource that AddMojoDataSource() creates.
44 if (id == mojo::kBufferModuleName ||
45 id == mojo::kCodecModuleName ||
46 id == mojo::kConnectionModuleName ||
47 id == mojo::kConnectorModuleName ||
48 id == mojo::kUnicodeModuleName ||
49 id == mojo::kRouterModuleName ||
50 id == mojo::kValidatorModuleName)
51 return false;
53 std::string contents;
54 CHECK(base::ReadFileToString(mojo::test::GetFilePathForJSResource(id),
55 &contents,
56 std::string::npos)) << id;
57 base::RefCountedString* ref_contents = new base::RefCountedString;
58 ref_contents->data() = contents;
59 callback.Run(ref_contents);
60 return true;
63 class BrowserTargetImpl : public mojo::InterfaceImpl<BrowserTarget> {
64 public:
65 explicit BrowserTargetImpl(base::RunLoop* run_loop) : run_loop_(run_loop) {}
67 virtual ~BrowserTargetImpl() {}
69 // mojo::InterfaceImpl<BrowserTarget> overrides:
70 virtual void PingResponse() OVERRIDE {
71 NOTREACHED();
74 protected:
75 base::RunLoop* run_loop_;
77 private:
78 DISALLOW_COPY_AND_ASSIGN(BrowserTargetImpl);
81 class PingBrowserTargetImpl : public BrowserTargetImpl {
82 public:
83 explicit PingBrowserTargetImpl(base::RunLoop* run_loop)
84 : BrowserTargetImpl(run_loop) {}
86 virtual ~PingBrowserTargetImpl() {}
88 // mojo::InterfaceImpl<BrowserTarget> overrides:
89 virtual void OnConnectionEstablished() OVERRIDE {
90 client()->Ping();
93 // Quit the RunLoop when called.
94 virtual void PingResponse() OVERRIDE {
95 got_message = true;
96 run_loop_->Quit();
99 private:
100 DISALLOW_COPY_AND_ASSIGN(PingBrowserTargetImpl);
103 // WebUIController that sets up mojo bindings.
104 class TestWebUIController : public WebUIController {
105 public:
106 TestWebUIController(WebUI* web_ui, base::RunLoop* run_loop)
107 : WebUIController(web_ui),
108 run_loop_(run_loop) {
109 content::WebUIDataSource* data_source =
110 WebUIDataSource::AddMojoDataSource(
111 web_ui->GetWebContents()->GetBrowserContext());
112 data_source->SetRequestFilter(base::Bind(&GetResource));
115 protected:
116 base::RunLoop* run_loop_;
117 scoped_ptr<BrowserTargetImpl> browser_target_;
119 private:
120 DISALLOW_COPY_AND_ASSIGN(TestWebUIController);
123 // TestWebUIController that additionally creates the ping test BrowserTarget
124 // implementation at the right time.
125 class PingTestWebUIController : public TestWebUIController {
126 public:
127 PingTestWebUIController(WebUI* web_ui, base::RunLoop* run_loop)
128 : TestWebUIController(web_ui, run_loop) {
130 virtual ~PingTestWebUIController() {}
132 // WebUIController overrides:
133 virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE {
134 render_view_host->GetMainFrame()->GetServiceRegistry()->
135 AddService<BrowserTarget>(base::Bind(
136 &PingTestWebUIController::CreateHandler, base::Unretained(this)));
139 void CreateHandler(mojo::InterfaceRequest<BrowserTarget> request) {
140 browser_target_.reset(mojo::WeakBindToRequest(
141 new PingBrowserTargetImpl(run_loop_), &request));
144 private:
145 DISALLOW_COPY_AND_ASSIGN(PingTestWebUIController);
148 // WebUIControllerFactory that creates TestWebUIController.
149 class TestWebUIControllerFactory : public WebUIControllerFactory {
150 public:
151 TestWebUIControllerFactory() : run_loop_(NULL) {}
153 void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; }
155 virtual WebUIController* CreateWebUIControllerForURL(
156 WebUI* web_ui, const GURL& url) const OVERRIDE {
157 if (url.query() == "ping")
158 return new PingTestWebUIController(web_ui, run_loop_);
159 return NULL;
161 virtual WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
162 const GURL& url) const OVERRIDE {
163 return reinterpret_cast<WebUI::TypeID>(1);
165 virtual bool UseWebUIForURL(BrowserContext* browser_context,
166 const GURL& url) const OVERRIDE {
167 return true;
169 virtual bool UseWebUIBindingsForURL(BrowserContext* browser_context,
170 const GURL& url) const OVERRIDE {
171 return true;
174 private:
175 base::RunLoop* run_loop_;
177 DISALLOW_COPY_AND_ASSIGN(TestWebUIControllerFactory);
180 class WebUIMojoTest : public ContentBrowserTest {
181 public:
182 WebUIMojoTest() {
183 WebUIControllerFactory::RegisterFactory(&factory_);
186 virtual ~WebUIMojoTest() {
187 WebUIControllerFactory::UnregisterFactoryForTesting(&factory_);
190 TestWebUIControllerFactory* factory() { return &factory_; }
192 private:
193 TestWebUIControllerFactory factory_;
195 DISALLOW_COPY_AND_ASSIGN(WebUIMojoTest);
198 // Loads a webui page that contains mojo bindings and verifies a message makes
199 // it from the browser to the page and back.
200 IN_PROC_BROWSER_TEST_F(WebUIMojoTest, EndToEndPing) {
201 // Currently there is no way to have a generated file included in the isolate
202 // files. If the bindings file doesn't exist assume we're on such a bot and
203 // pass.
204 // TODO(sky): remove this conditional when isolates support copying from gen.
205 const base::FilePath test_file_path(
206 mojo::test::GetFilePathForJSResource(
207 "content/test/data/web_ui_test_mojo_bindings.mojom"));
208 if (!base::PathExists(test_file_path)) {
209 LOG(WARNING) << " mojom binding file doesn't exist, assuming on isolate";
210 return;
213 got_message = false;
214 ASSERT_TRUE(test_server()->Start());
215 base::RunLoop run_loop;
216 factory()->set_run_loop(&run_loop);
217 GURL test_url(test_server()->GetURL("files/web_ui_mojo.html?ping"));
218 NavigateToURL(shell(), test_url);
219 // RunLoop is quit when message received from page.
220 run_loop.Run();
221 EXPECT_TRUE(got_message);
223 // Check that a second render frame in the same renderer process works
224 // correctly.
225 Shell* other_shell = CreateBrowser();
226 got_message = false;
227 base::RunLoop other_run_loop;
228 factory()->set_run_loop(&other_run_loop);
229 NavigateToURL(other_shell, test_url);
230 // RunLoop is quit when message received from page.
231 other_run_loop.Run();
232 EXPECT_TRUE(got_message);
233 EXPECT_EQ(shell()->web_contents()->GetRenderProcessHost(),
234 other_shell->web_contents()->GetRenderProcessHost());
237 } // namespace
238 } // namespace content