base: Change DCHECK_IS_ON to a macro DCHECK_IS_ON().
[chromium-blink-merge.git] / mojo / services / html_viewer / html_document.cc
blob7688442f7e912faeb438ccaabb6de8dc98fd2b15
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 "mojo/services/html_viewer/html_document.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/stl_util.h"
13 #include "base/strings/string_util.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "media/blink/webencryptedmediaclient_impl.h"
16 #include "media/cdm/default_cdm_factory.h"
17 #include "mojo/public/cpp/application/connect.h"
18 #include "mojo/public/cpp/system/data_pipe.h"
19 #include "mojo/public/interfaces/application/shell.mojom.h"
20 #include "mojo/services/html_viewer/blink_input_events_type_converters.h"
21 #include "mojo/services/html_viewer/blink_url_request_type_converters.h"
22 #include "mojo/services/html_viewer/weblayertreeview_impl.h"
23 #include "mojo/services/html_viewer/webmediaplayer_factory.h"
24 #include "mojo/services/html_viewer/webstoragenamespace_impl.h"
25 #include "mojo/services/html_viewer/weburlloader_impl.h"
26 #include "mojo/services/surfaces/public/interfaces/surfaces_service.mojom.h"
27 #include "mojo/services/view_manager/public/cpp/view.h"
28 #include "skia/ext/refptr.h"
29 #include "third_party/WebKit/public/platform/Platform.h"
30 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
31 #include "third_party/WebKit/public/platform/WebSize.h"
32 #include "third_party/WebKit/public/web/WebConsoleMessage.h"
33 #include "third_party/WebKit/public/web/WebDocument.h"
34 #include "third_party/WebKit/public/web/WebElement.h"
35 #include "third_party/WebKit/public/web/WebInputEvent.h"
36 #include "third_party/WebKit/public/web/WebLocalFrame.h"
37 #include "third_party/WebKit/public/web/WebScriptSource.h"
38 #include "third_party/WebKit/public/web/WebSettings.h"
39 #include "third_party/WebKit/public/web/WebView.h"
40 #include "third_party/skia/include/core/SkCanvas.h"
41 #include "third_party/skia/include/core/SkColor.h"
42 #include "third_party/skia/include/core/SkDevice.h"
44 using mojo::AxProvider;
45 using mojo::Rect;
46 using mojo::ServiceProviderPtr;
47 using mojo::URLResponsePtr;
48 using mojo::View;
49 using mojo::ViewManager;
51 namespace html_viewer {
52 namespace {
54 void ConfigureSettings(blink::WebSettings* settings) {
55 settings->setCookieEnabled(true);
56 settings->setDefaultFixedFontSize(13);
57 settings->setDefaultFontSize(16);
58 settings->setLoadsImagesAutomatically(true);
59 settings->setJavaScriptEnabled(true);
62 mojo::Target WebNavigationPolicyToNavigationTarget(
63 blink::WebNavigationPolicy policy) {
64 switch (policy) {
65 case blink::WebNavigationPolicyCurrentTab:
66 return mojo::TARGET_SOURCE_NODE;
67 case blink::WebNavigationPolicyNewBackgroundTab:
68 case blink::WebNavigationPolicyNewForegroundTab:
69 case blink::WebNavigationPolicyNewWindow:
70 case blink::WebNavigationPolicyNewPopup:
71 return mojo::TARGET_NEW_NODE;
72 default:
73 return mojo::TARGET_DEFAULT;
77 bool CanNavigateLocally(blink::WebFrame* frame,
78 const blink::WebURLRequest& request) {
79 // For now, we just load child frames locally.
80 // TODO(aa): In the future, this should use embedding to connect to a
81 // different instance of Blink if the frame is cross-origin.
82 if (frame->parent())
83 return true;
85 // If we have extraData() it means we already have the url response
86 // (presumably because we are being called via Navigate()). In that case we
87 // can go ahead and navigate locally.
88 if (request.extraData())
89 return true;
91 // Otherwise we don't know if we're the right app to handle this request. Ask
92 // host to do the navigation for us.
93 return false;
96 } // namespace
98 HTMLDocument::HTMLDocument(
99 mojo::ServiceProviderPtr provider,
100 URLResponsePtr response,
101 mojo::Shell* shell,
102 scoped_refptr<base::MessageLoopProxy> compositor_thread,
103 WebMediaPlayerFactory* web_media_player_factory)
104 : response_(response.Pass()),
105 shell_(shell),
106 web_view_(nullptr),
107 root_(nullptr),
108 view_manager_client_factory_(shell_, this),
109 compositor_thread_(compositor_thread),
110 web_media_player_factory_(web_media_player_factory),
111 web_encrypted_media_client_(nullptr) {
112 exported_services_.AddService(this);
113 exported_services_.AddService(&view_manager_client_factory_);
114 WeakBindToPipe(&exported_services_, provider.PassMessagePipe());
115 Load(response_.Pass());
118 HTMLDocument::~HTMLDocument() {
119 STLDeleteElements(&ax_provider_impls_);
121 if (web_view_)
122 web_view_->close();
123 if (root_)
124 root_->RemoveObserver(this);
127 void HTMLDocument::OnEmbed(
128 View* root,
129 mojo::ServiceProviderImpl* embedee_service_provider_impl,
130 scoped_ptr<mojo::ServiceProvider> embedder_service_provider) {
131 root_ = root;
132 embedder_service_provider_ = embedder_service_provider.Pass();
133 navigator_host_.set_service_provider(embedder_service_provider_.get());
135 blink::WebSize root_size(root_->bounds().width, root_->bounds().height);
136 web_view_->resize(root_size);
137 web_layer_tree_view_impl_->setViewportSize(root_size);
138 web_layer_tree_view_impl_->set_view(root_);
139 root_->AddObserver(this);
142 void HTMLDocument::Create(mojo::ApplicationConnection* connection,
143 mojo::InterfaceRequest<AxProvider> request) {
144 if (!web_view_)
145 return;
146 ax_provider_impls_.insert(
147 WeakBindToRequest(new AxProviderImpl(web_view_), &request));
150 void HTMLDocument::OnViewManagerDisconnected(ViewManager* view_manager) {
151 // TODO(aa): Need to figure out how shutdown works.
154 void HTMLDocument::Load(URLResponsePtr response) {
155 web_view_ = blink::WebView::create(this);
156 web_layer_tree_view_impl_->set_widget(web_view_);
157 ConfigureSettings(web_view_->settings());
158 web_view_->setMainFrame(blink::WebLocalFrame::create(this));
160 GURL url(response->url);
162 WebURLRequestExtraData* extra_data = new WebURLRequestExtraData;
163 extra_data->synthetic_response = response.Pass();
165 blink::WebURLRequest web_request;
166 web_request.initialize();
167 web_request.setURL(url);
168 web_request.setExtraData(extra_data);
170 web_view_->mainFrame()->loadRequest(web_request);
173 blink::WebStorageNamespace* HTMLDocument::createSessionStorageNamespace() {
174 return new WebStorageNamespaceImpl();
177 void HTMLDocument::initializeLayerTreeView() {
178 ServiceProviderPtr surfaces_service_provider;
179 shell_->ConnectToApplication("mojo:surfaces_service",
180 GetProxy(&surfaces_service_provider));
181 mojo::SurfacesServicePtr surfaces_service;
182 ConnectToService(surfaces_service_provider.get(), &surfaces_service);
184 ServiceProviderPtr gpu_service_provider;
185 // TODO(jamesr): Should be mojo:gpu_service
186 shell_->ConnectToApplication("mojo:native_viewport_service",
187 GetProxy(&gpu_service_provider));
188 mojo::GpuPtr gpu_service;
189 ConnectToService(gpu_service_provider.get(), &gpu_service);
190 web_layer_tree_view_impl_.reset(new WebLayerTreeViewImpl(
191 compositor_thread_, surfaces_service.Pass(), gpu_service.Pass()));
194 blink::WebLayerTreeView* HTMLDocument::layerTreeView() {
195 return web_layer_tree_view_impl_.get();
198 blink::WebMediaPlayer* HTMLDocument::createMediaPlayer(
199 blink::WebLocalFrame* frame,
200 const blink::WebURL& url,
201 blink::WebMediaPlayerClient* client) {
202 return createMediaPlayer(frame, url, client, nullptr);
205 blink::WebMediaPlayer* HTMLDocument::createMediaPlayer(
206 blink::WebLocalFrame* frame,
207 const blink::WebURL& url,
208 blink::WebMediaPlayerClient* client,
209 blink::WebContentDecryptionModule* initial_cdm) {
210 return web_media_player_factory_->CreateMediaPlayer(frame, url, client,
211 initial_cdm, shell_);
214 blink::WebFrame* HTMLDocument::createChildFrame(
215 blink::WebLocalFrame* parent,
216 const blink::WebString& frameName) {
217 blink::WebLocalFrame* web_frame = blink::WebLocalFrame::create(this);
218 parent->appendChild(web_frame);
219 return web_frame;
222 void HTMLDocument::frameDetached(blink::WebFrame* frame) {
223 if (frame->parent())
224 frame->parent()->removeChild(frame);
226 // |frame| is invalid after here.
227 frame->close();
230 blink::WebCookieJar* HTMLDocument::cookieJar(blink::WebLocalFrame* frame) {
231 // TODO(darin): Blink does not fallback to the Platform provided WebCookieJar.
232 // Either it should, as it once did, or we should find another solution here.
233 return blink::Platform::current()->cookieJar();
236 blink::WebNavigationPolicy HTMLDocument::decidePolicyForNavigation(
237 blink::WebLocalFrame* frame,
238 blink::WebDataSource::ExtraData* data,
239 const blink::WebURLRequest& request,
240 blink::WebNavigationType nav_type,
241 blink::WebNavigationPolicy default_policy,
242 bool is_redirect) {
243 if (CanNavigateLocally(frame, request))
244 return default_policy;
246 if (navigator_host_.get()) {
247 navigator_host_->RequestNavigate(
248 WebNavigationPolicyToNavigationTarget(default_policy),
249 mojo::URLRequest::From(request).Pass());
252 return blink::WebNavigationPolicyIgnore;
255 void HTMLDocument::didAddMessageToConsole(
256 const blink::WebConsoleMessage& message,
257 const blink::WebString& source_name,
258 unsigned source_line,
259 const blink::WebString& stack_trace) {
262 void HTMLDocument::didNavigateWithinPage(
263 blink::WebLocalFrame* frame,
264 const blink::WebHistoryItem& history_item,
265 blink::WebHistoryCommitType commit_type) {
266 if (navigator_host_.get())
267 navigator_host_->DidNavigateLocally(history_item.urlString().utf8());
270 blink::WebEncryptedMediaClient* HTMLDocument::encryptedMediaClient() {
271 if (!web_encrypted_media_client_) {
272 web_encrypted_media_client_ = new media::WebEncryptedMediaClientImpl(
273 make_scoped_ptr(new media::DefaultCdmFactory()));
275 return web_encrypted_media_client_;
278 void HTMLDocument::OnViewBoundsChanged(View* view,
279 const Rect& old_bounds,
280 const Rect& new_bounds) {
281 DCHECK_EQ(view, root_);
282 web_view_->resize(
283 blink::WebSize(view->bounds().width, view->bounds().height));
286 void HTMLDocument::OnViewDestroyed(View* view) {
287 DCHECK_EQ(view, root_);
288 root_ = nullptr;
291 void HTMLDocument::OnViewInputEvent(View* view, const mojo::EventPtr& event) {
292 scoped_ptr<blink::WebInputEvent> web_event =
293 event.To<scoped_ptr<blink::WebInputEvent>>();
294 if (web_event)
295 web_view_->handleInputEvent(*web_event);
298 } // namespace html_viewer