Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: headless/lib/browser/headless_web_contents_impl.cc

Issue 2049363003: Adds support for headless chrome embedder mojo services (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added a comment Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "headless/lib/browser/headless_web_contents_impl.h" 5 #include "headless/lib/browser/headless_web_contents_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/memory/weak_ptr.h" 9 #include "base/memory/weak_ptr.h"
10 #include "base/strings/utf_string_conversions.h"
10 #include "base/trace_event/trace_event.h" 11 #include "base/trace_event/trace_event.h"
11 #include "content/public/browser/devtools_agent_host.h" 12 #include "content/public/browser/devtools_agent_host.h"
12 #include "content/public/browser/navigation_handle.h" 13 #include "content/public/browser/navigation_handle.h"
13 #include "content/public/browser/render_frame_host.h" 14 #include "content/public/browser/render_frame_host.h"
14 #include "content/public/browser/render_process_host.h" 15 #include "content/public/browser/render_process_host.h"
15 #include "content/public/browser/render_view_host.h" 16 #include "content/public/browser/render_view_host.h"
16 #include "content/public/browser/render_widget_host_view.h" 17 #include "content/public/browser/render_widget_host_view.h"
17 #include "content/public/browser/web_contents.h" 18 #include "content/public/browser/web_contents.h"
18 #include "content/public/browser/web_contents_delegate.h" 19 #include "content/public/browser/web_contents_delegate.h"
19 #include "content/public/browser/web_contents_observer.h" 20 #include "content/public/browser/web_contents_observer.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 HeadlessBrowserImpl* browser) { 73 HeadlessBrowserImpl* browser) {
73 content::BrowserContext* context = 74 content::BrowserContext* context =
74 HeadlessBrowserContextImpl::From(builder->browser_context_); 75 HeadlessBrowserContextImpl::From(builder->browser_context_);
75 content::WebContents::CreateParams create_params(context, nullptr); 76 content::WebContents::CreateParams create_params(context, nullptr);
76 create_params.initial_size = builder->window_size_; 77 create_params.initial_size = builder->window_size_;
77 78
78 std::unique_ptr<HeadlessWebContentsImpl> headless_web_contents = 79 std::unique_ptr<HeadlessWebContentsImpl> headless_web_contents =
79 base::WrapUnique(new HeadlessWebContentsImpl( 80 base::WrapUnique(new HeadlessWebContentsImpl(
80 content::WebContents::Create(create_params), browser)); 81 content::WebContents::Create(create_params), browser));
81 82
83 headless_web_contents->InstallMojoServices(builder->embedder_mojo_services_);
82 headless_web_contents->InitializeScreen(parent_window, builder->window_size_); 84 headless_web_contents->InitializeScreen(parent_window, builder->window_size_);
83 if (!headless_web_contents->OpenURL(builder->initial_url_)) 85 if (!headless_web_contents->OpenURL(builder->initial_url_))
84 return nullptr; 86 return nullptr;
85 return headless_web_contents; 87 return headless_web_contents;
86 } 88 }
87 89
88 // static 90 // static
89 std::unique_ptr<HeadlessWebContentsImpl> 91 std::unique_ptr<HeadlessWebContentsImpl>
90 HeadlessWebContentsImpl::CreateFromWebContents( 92 HeadlessWebContentsImpl::CreateFromWebContents(
91 content::WebContents* web_contents, 93 content::WebContents* web_contents,
(...skipping 11 matching lines...) Expand all
103 parent_window->AddChild(contents); 105 parent_window->AddChild(contents);
104 contents->Show(); 106 contents->Show();
105 107
106 contents->SetBounds(gfx::Rect(initial_size)); 108 contents->SetBounds(gfx::Rect(initial_size));
107 content::RenderWidgetHostView* host_view = 109 content::RenderWidgetHostView* host_view =
108 web_contents_->GetRenderWidgetHostView(); 110 web_contents_->GetRenderWidgetHostView();
109 if (host_view) 111 if (host_view)
110 host_view->SetSize(initial_size); 112 host_view->SetSize(initial_size);
111 } 113 }
112 114
115 void HeadlessWebContentsImpl::InstallMojoServices(
116 std::list<EmbedderMojoService>& embedder_mojo_services) {
117 embedder_mojo_services_ = std::move(embedder_mojo_services);
118
119 if (embedder_mojo_services_.empty())
120 return;
121
122 web_contents_->GetRenderViewHost()->AllowBindings(
123 content::BINDINGS_POLICY_MOJO);
124 content::ServiceRegistry* service_registry =
125 web_contents_->GetRenderViewHost()->GetMainFrame()->GetServiceRegistry();
126
127 for (const EmbedderMojoService& service : embedder_mojo_services_) {
128 service_registry->AddService(service.service_name,
129 std::move(service.service_factory),
130 browser_->BrowserMainThread());
131 }
132 }
133
134 void HeadlessWebContentsImpl::DocumentOnLoadCompletedInMainFrame() {
Sami 2016/06/10 10:27:38 Is there an earlier event we could use? It might b
alex clarke (OOO till 29th) 2016/06/11 20:51:50 I've refactored this to: 1. Install the mojo.def
135 if (embedder_mojo_services_.empty())
136 return;
137
138 // content::BINDINGS_POLICY_MOJO causes 'mojo.define' to be installed in the
139 // global v8 context. However the autogenerated mojo bindings assume 'define'
140 // is installed. We run some JS here to implement the expected 'define'
141 // method.
142 content::RenderFrameHost* render_frame_host = web_contents_->GetMainFrame();
143 render_frame_host->ExecuteJavaScriptForTests(base::UTF8ToUTF16(R"(
Sami 2016/06/10 10:27:38 Was there a non-test interface we could use for th
alex clarke (OOO till 29th) 2016/06/11 20:51:50 Yes. this has been moved.
144 window.define = (function() {
145 let moduleCache = new Map();
146 return function(name, deps, factory) {
147 let promise = moduleCache.get(name);
148 if (promise === undefined) {
149 // This promise must be cached as mojo.define will only call the
150 // factory function the first time the module is defined.
151 promise = new Promise(resolve => {
152 mojo.define(name, deps, (...modules) => {
153 let result = factory(...modules);
154 resolve(result);
155 return result;
Sami 2016/06/10 10:27:38 Do you need both resolve and return?
alex clarke (OOO till 29th) 2016/06/11 20:51:50 Apparently the resolve isn't needed?!
156 });
157 });
158 moduleCache.set(name, promise);
159 }
160 return promise;
161 }
162 })(); )"));
163
164 for (const EmbedderMojoService& service : embedder_mojo_services_) {
165 render_frame_host->ExecuteJavaScript(base::UTF8ToUTF16(service.js_binding));
166 }
167 }
168
113 HeadlessWebContentsImpl::HeadlessWebContentsImpl( 169 HeadlessWebContentsImpl::HeadlessWebContentsImpl(
114 content::WebContents* web_contents, 170 content::WebContents* web_contents,
115 HeadlessBrowserImpl* browser) 171 HeadlessBrowserImpl* browser)
116 : web_contents_delegate_(new HeadlessWebContentsImpl::Delegate(browser)), 172 : content::WebContentsObserver(web_contents),
173 web_contents_delegate_(new HeadlessWebContentsImpl::Delegate(browser)),
117 web_contents_(web_contents), 174 web_contents_(web_contents),
118 browser_(browser) { 175 browser_(browser) {
119 web_contents_->SetDelegate(web_contents_delegate_.get()); 176 web_contents_->SetDelegate(web_contents_delegate_.get());
120 } 177 }
121 178
122 HeadlessWebContentsImpl::~HeadlessWebContentsImpl() { 179 HeadlessWebContentsImpl::~HeadlessWebContentsImpl() {
123 web_contents_->Close(); 180 web_contents_->Close();
124 } 181 }
125 182
126 bool HeadlessWebContentsImpl::OpenURL(const GURL& url) { 183 bool HeadlessWebContentsImpl::OpenURL(const GURL& url) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 window_size_ = size; 246 window_size_ = size;
190 return *this; 247 return *this;
191 } 248 }
192 249
193 HeadlessWebContents::Builder& HeadlessWebContents::Builder::SetBrowserContext( 250 HeadlessWebContents::Builder& HeadlessWebContents::Builder::SetBrowserContext(
194 HeadlessBrowserContext* browser_context) { 251 HeadlessBrowserContext* browser_context) {
195 browser_context_ = browser_context; 252 browser_context_ = browser_context;
196 return *this; 253 return *this;
197 } 254 }
198 255
256 HeadlessWebContents::Builder&
257 HeadlessWebContents::Builder::AddEmbedderMojoService(
258 const std::string& service_name,
259 const base::Callback<void(mojo::ScopedMessagePipeHandle)>& service_factory,
260 const std::string& js_binding) {
261 embedder_mojo_services_.emplace_back(service_name, service_factory,
262 js_binding);
263 return *this;
264 }
265
199 HeadlessWebContents* HeadlessWebContents::Builder::Build() { 266 HeadlessWebContents* HeadlessWebContents::Builder::Build() {
200 return browser_->CreateWebContents(this); 267 return browser_->CreateWebContents(this);
201 } 268 }
202 269
270 HeadlessWebContents::Builder::EmbedderMojoService::EmbedderMojoService() {}
271
272 HeadlessWebContents::Builder::EmbedderMojoService::EmbedderMojoService(
273 const std::string& service_name,
274 const base::Callback<void(mojo::ScopedMessagePipeHandle)>& service_factory,
275 const std::string& js_binding)
276 : service_name(service_name),
277 service_factory(service_factory),
278 js_binding(js_binding) {}
279
280 HeadlessWebContents::Builder::EmbedderMojoService::~EmbedderMojoService() {}
281
203 } // namespace headless 282 } // namespace headless
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698