Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / content / browser / webui / web_ui_mojo_browsertest.cc
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.
4
5 #include "base/command_line.h"
6 #include "base/file_util.h"
7 #include "base/files/file_path.h"
8 #include "base/path_service.h"
9 #include "base/run_loop.h"
10 #include "base/strings/string_util.h"
11 #include "content/browser/webui/web_ui_controller_factory_registry.h"
12 #include "content/common/mojo/mojo_channel_init.h"
13 #include "content/public/browser/browser_context.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/web_contents.h"
16 #include "content/public/browser/web_ui_controller.h"
17 #include "content/public/browser/web_ui_data_source.h"
18 #include "content/public/common/content_paths.h"
19 #include "content/public/common/content_switches.h"
20 #include "content/public/common/url_utils.h"
21 #include "content/public/test/content_browser_test.h"
22 #include "content/public/test/content_browser_test_utils.h"
23 #include "content/test/data/web_ui_test_mojo_bindings.mojom.h"
24 #include "grit/content_resources.h"
25 #include "mojo/public/bindings/js/constants.h"
26 #include "mojo/public/bindings/remote_ptr.h"
27
28 namespace content {
29 namespace {
30
31 bool got_message = false;
32
33 // Returns the path to the mojom js bindings file.
34 base::FilePath GetFilePathForJSResource(const std::string& path) {
35   std::string binding_path = "gen/" + path + ".js";
36 #if defined(OS_WIN)
37   std::string tmp;
38   base::ReplaceChars(binding_path, "//", "\\", &tmp);
39   binding_path.swap(tmp);
40 #endif
41   base::FilePath file_path;
42   PathService::Get(CHILD_PROCESS_EXE, &file_path);
43   return file_path.DirName().AppendASCII(binding_path);
44 }
45
46 // The bindings for the page are generated from a .mojom file. This code looks
47 // up the generated file from disk and returns it.
48 bool GetResource(const std::string& id,
49                  const WebUIDataSource::GotDataCallback& callback) {
50   // These are handled by the WebUIDataSource that AddMojoDataSource() creates.
51   if (id == mojo::kCodecModuleName ||
52       id == mojo::kConnectionModuleName ||
53       id == mojo::kConnectorModuleName ||
54       id == mojo::kRouterModuleName)
55     return false;
56
57   std::string contents;
58   CHECK(base::ReadFileToString(GetFilePathForJSResource(id), &contents,
59                                std::string::npos));
60   base::RefCountedString* ref_contents = new base::RefCountedString;
61   ref_contents->data() = contents;
62   callback.Run(ref_contents);
63   return true;
64 }
65
66 // BrowserTarget implementation that quits a RunLoop when BrowserTarget::Test()
67 // is called.
68 class BrowserTargetImpl : public mojo::BrowserTarget {
69  public:
70   BrowserTargetImpl(mojo::ScopedRendererTargetHandle handle,
71                     base::RunLoop* run_loop)
72       : client_(handle.Pass(), this),
73         run_loop_(run_loop) {
74     client_->Test();
75   }
76   virtual ~BrowserTargetImpl() {}
77
78   // mojo::BrowserTarget overrides:
79   virtual void Test() OVERRIDE {
80     got_message = true;
81     run_loop_->Quit();
82   }
83
84  private:
85   mojo::RemotePtr<mojo::RendererTarget> client_;
86
87   base::RunLoop* run_loop_;
88
89   DISALLOW_COPY_AND_ASSIGN(BrowserTargetImpl);
90 };
91
92 // WebUIController that sets up mojo bindings. Additionally it creates the
93 // BrowserTarget implementation at the right time.
94 class TestWebUIController : public WebUIController {
95  public:
96   explicit TestWebUIController(WebUI* web_ui, base::RunLoop* run_loop)
97       : WebUIController(web_ui),
98         run_loop_(run_loop) {
99     content::WebUIDataSource* data_source =
100         WebUIDataSource::AddMojoDataSource(
101             web_ui->GetWebContents()->GetBrowserContext());
102     data_source->SetRequestFilter(base::Bind(&GetResource));
103   }
104
105   // WebUIController overrides:
106   virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE {
107     mojo::InterfacePipe<mojo::BrowserTarget, mojo::RendererTarget> pipe;
108     browser_target_.reset(
109         new BrowserTargetImpl(pipe.handle_to_peer.Pass(), run_loop_));
110     render_view_host->SetWebUIHandle(
111         mojo::ScopedMessagePipeHandle(pipe.handle_to_self.release()));
112   }
113
114  private:
115   base::RunLoop* run_loop_;
116
117   scoped_ptr<BrowserTargetImpl> browser_target_;
118
119   DISALLOW_COPY_AND_ASSIGN(TestWebUIController);
120 };
121
122 // WebUIControllerFactory that creates TestWebUIController.
123 class TestWebUIControllerFactory : public WebUIControllerFactory {
124  public:
125   TestWebUIControllerFactory() : run_loop_(NULL) {}
126
127   void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; }
128
129   virtual WebUIController* CreateWebUIControllerForURL(
130       WebUI* web_ui, const GURL& url) const OVERRIDE {
131     return new TestWebUIController(web_ui, run_loop_);
132   }
133   virtual WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
134       const GURL& url) const OVERRIDE {
135     return reinterpret_cast<WebUI::TypeID>(1);
136   }
137   virtual bool UseWebUIForURL(BrowserContext* browser_context,
138                               const GURL& url) const OVERRIDE {
139     return true;
140   }
141   virtual bool UseWebUIBindingsForURL(BrowserContext* browser_context,
142                                       const GURL& url) const OVERRIDE {
143     return true;
144   }
145
146  private:
147   base::RunLoop* run_loop_;
148
149   DISALLOW_COPY_AND_ASSIGN(TestWebUIControllerFactory);
150 };
151
152 class WebUIMojoTest : public ContentBrowserTest {
153  public:
154   WebUIMojoTest() {
155     WebUIControllerFactory::RegisterFactory(&factory_);
156   }
157
158   virtual ~WebUIMojoTest() {
159     WebUIControllerFactory::UnregisterFactoryForTesting(&factory_);
160   }
161
162   TestWebUIControllerFactory* factory() { return &factory_; }
163
164  private:
165   TestWebUIControllerFactory factory_;
166
167   DISALLOW_COPY_AND_ASSIGN(WebUIMojoTest);
168 };
169
170 // Loads a webui page that contains mojo bindings and verifies a message makes
171 // it from the browser to the page and back.
172 IN_PROC_BROWSER_TEST_F(WebUIMojoTest, EndToEnd) {
173   // Currently there is no way to have a generated file included in the isolate
174   // files. If the bindings file doesn't exist assume we're on such a bot and
175   // pass.
176   // TODO(sky): remove this conditional when isolates support copying from gen.
177   const base::FilePath test_file_path(
178       GetFilePathForJSResource(
179           "content/test/data/web_ui_test_mojo_bindings.mojom"));
180   if (!base::PathExists(test_file_path)) {
181     LOG(WARNING) << " mojom binding file doesn't exist, assuming on isolate";
182     return;
183   }
184
185   got_message = false;
186   ASSERT_TRUE(test_server()->Start());
187   base::RunLoop run_loop;
188   factory()->set_run_loop(&run_loop);
189   GURL test_url(test_server()->GetURL("files/web_ui_mojo.html"));
190   NavigateToURL(shell(), test_url);
191   // RunLoop is quit when message received from page.
192   run_loop.Run();
193   EXPECT_TRUE(got_message);
194 }
195
196 }  // namespace
197 }  // namespace content