Compositor bindings for mojo html_viewer
[chromium-blink-merge.git] / mojo / services / html_viewer / html_document_view.cc
blob8bdd50108375be9db6b1248243177ded2841c2a7
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_view.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/strings/string_util.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "mojo/public/cpp/application/connect.h"
14 #include "mojo/public/cpp/application/service_provider_impl.h"
15 #include "mojo/public/cpp/system/data_pipe.h"
16 #include "mojo/public/interfaces/application/shell.mojom.h"
17 #include "mojo/services/html_viewer/blink_input_events_type_converters.h"
18 #include "mojo/services/html_viewer/blink_url_request_type_converters.h"
19 #include "mojo/services/html_viewer/weblayertreeview_impl.h"
20 #include "mojo/services/html_viewer/webstoragenamespace_impl.h"
21 #include "mojo/services/html_viewer/weburlloader_impl.h"
22 #include "mojo/services/public/cpp/view_manager/view.h"
23 #include "mojo/services/public/interfaces/surfaces/surfaces_service.mojom.h"
24 #include "skia/ext/refptr.h"
25 #include "third_party/WebKit/public/platform/Platform.h"
26 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
27 #include "third_party/WebKit/public/web/WebConsoleMessage.h"
28 #include "third_party/WebKit/public/web/WebDocument.h"
29 #include "third_party/WebKit/public/web/WebElement.h"
30 #include "third_party/WebKit/public/web/WebInputEvent.h"
31 #include "third_party/WebKit/public/web/WebLocalFrame.h"
32 #include "third_party/WebKit/public/web/WebScriptSource.h"
33 #include "third_party/WebKit/public/web/WebSettings.h"
34 #include "third_party/WebKit/public/web/WebView.h"
35 #include "third_party/skia/include/core/SkCanvas.h"
36 #include "third_party/skia/include/core/SkColor.h"
37 #include "third_party/skia/include/core/SkDevice.h"
39 namespace mojo {
40 namespace {
42 void ConfigureSettings(blink::WebSettings* settings) {
43 settings->setCookieEnabled(true);
44 settings->setDefaultFixedFontSize(13);
45 settings->setDefaultFontSize(16);
46 settings->setLoadsImagesAutomatically(true);
47 settings->setJavaScriptEnabled(true);
50 Target WebNavigationPolicyToNavigationTarget(
51 blink::WebNavigationPolicy policy) {
52 switch (policy) {
53 case blink::WebNavigationPolicyCurrentTab:
54 return TARGET_SOURCE_NODE;
55 case blink::WebNavigationPolicyNewBackgroundTab:
56 case blink::WebNavigationPolicyNewForegroundTab:
57 case blink::WebNavigationPolicyNewWindow:
58 case blink::WebNavigationPolicyNewPopup:
59 return TARGET_NEW_NODE;
60 default:
61 return TARGET_DEFAULT;
65 bool CanNavigateLocally(blink::WebFrame* frame,
66 const blink::WebURLRequest& request) {
67 // For now, we just load child frames locally.
68 // TODO(aa): In the future, this should use embedding to connect to a
69 // different instance of Blink if the frame is cross-origin.
70 if (frame->parent())
71 return true;
73 // If we have extraData() it means we already have the url response
74 // (presumably because we are being called via Navigate()). In that case we
75 // can go ahead and navigate locally.
76 if (request.extraData())
77 return true;
79 // Otherwise we don't know if we're the right app to handle this request. Ask
80 // host to do the navigation for us.
81 return false;
84 } // namespace
86 HTMLDocumentView::HTMLDocumentView(
87 URLResponsePtr response,
88 InterfaceRequest<ServiceProvider> service_provider_request,
89 Shell* shell,
90 scoped_refptr<base::MessageLoopProxy> compositor_thread)
91 : shell_(shell),
92 web_view_(NULL),
93 root_(NULL),
94 view_manager_client_factory_(shell, this),
95 compositor_thread_(compositor_thread),
96 weak_factory_(this) {
97 ServiceProviderImpl* exported_services = new ServiceProviderImpl();
98 exported_services->AddService(&view_manager_client_factory_);
99 BindToRequest(exported_services, &service_provider_request);
100 Load(response.Pass());
103 HTMLDocumentView::~HTMLDocumentView() {
104 if (web_view_)
105 web_view_->close();
106 if (root_)
107 root_->RemoveObserver(this);
110 void HTMLDocumentView::OnEmbed(
111 ViewManager* view_manager,
112 View* root,
113 ServiceProviderImpl* embedee_service_provider_impl,
114 scoped_ptr<ServiceProvider> embedder_service_provider) {
115 root_ = root;
116 embedder_service_provider_ = embedder_service_provider.Pass();
117 navigator_host_.set_service_provider(embedder_service_provider_.get());
119 web_view_->resize(root_->bounds().size());
120 web_layer_tree_view_impl_->setViewportSize(root_->bounds().size());
121 web_layer_tree_view_impl_->set_view(root_);
122 root_->AddObserver(this);
125 void HTMLDocumentView::OnViewManagerDisconnected(ViewManager* view_manager) {
126 // TODO(aa): Need to figure out how shutdown works.
129 void HTMLDocumentView::Load(URLResponsePtr response) {
130 web_view_ = blink::WebView::create(this);
131 web_layer_tree_view_impl_->set_widget(web_view_);
132 ConfigureSettings(web_view_->settings());
133 web_view_->setMainFrame(blink::WebLocalFrame::create(this));
135 GURL url(response->url);
137 WebURLRequestExtraData* extra_data = new WebURLRequestExtraData;
138 extra_data->synthetic_response = response.Pass();
140 blink::WebURLRequest web_request;
141 web_request.initialize();
142 web_request.setURL(url);
143 web_request.setExtraData(extra_data);
145 web_view_->mainFrame()->loadRequest(web_request);
148 blink::WebStorageNamespace* HTMLDocumentView::createSessionStorageNamespace() {
149 return new WebStorageNamespaceImpl();
152 void HTMLDocumentView::initializeLayerTreeView() {
153 ServiceProviderPtr surfaces_service_provider;
154 shell_->ConnectToApplication("mojo:mojo_surfaces_service",
155 Get(&surfaces_service_provider));
156 InterfacePtr<SurfacesService> surfaces_service;
157 ConnectToService(surfaces_service_provider.get(), &surfaces_service);
159 ServiceProviderPtr gpu_service_provider;
160 // TODO(jamesr): Should be mojo:mojo_gpu_service
161 shell_->ConnectToApplication("mojo:mojo_native_viewport_service",
162 Get(&gpu_service_provider));
163 InterfacePtr<Gpu> gpu_service;
164 ConnectToService(gpu_service_provider.get(), &gpu_service);
165 web_layer_tree_view_impl_.reset(new WebLayerTreeViewImpl(
166 compositor_thread_, surfaces_service.Pass(), gpu_service.Pass()));
169 blink::WebLayerTreeView* HTMLDocumentView::layerTreeView() {
170 return web_layer_tree_view_impl_.get();
173 blink::WebFrame* HTMLDocumentView::createChildFrame(
174 blink::WebLocalFrame* parent,
175 const blink::WebString& frameName) {
176 blink::WebLocalFrame* web_frame = blink::WebLocalFrame::create(this);
177 parent->appendChild(web_frame);
178 return web_frame;
181 void HTMLDocumentView::frameDetached(blink::WebFrame* frame) {
182 if (frame->parent())
183 frame->parent()->removeChild(frame);
185 // |frame| is invalid after here.
186 frame->close();
189 blink::WebCookieJar* HTMLDocumentView::cookieJar(blink::WebLocalFrame* frame) {
190 // TODO(darin): Blink does not fallback to the Platform provided WebCookieJar.
191 // Either it should, as it once did, or we should find another solution here.
192 return blink::Platform::current()->cookieJar();
195 blink::WebNavigationPolicy HTMLDocumentView::decidePolicyForNavigation(
196 blink::WebLocalFrame* frame, blink::WebDataSource::ExtraData* data,
197 const blink::WebURLRequest& request, blink::WebNavigationType nav_type,
198 blink::WebNavigationPolicy default_policy, bool is_redirect) {
199 if (CanNavigateLocally(frame, request))
200 return default_policy;
202 navigator_host_->RequestNavigate(
203 WebNavigationPolicyToNavigationTarget(default_policy),
204 URLRequest::From(request).Pass());
206 return blink::WebNavigationPolicyIgnore;
209 void HTMLDocumentView::didAddMessageToConsole(
210 const blink::WebConsoleMessage& message,
211 const blink::WebString& source_name,
212 unsigned source_line,
213 const blink::WebString& stack_trace) {
216 void HTMLDocumentView::didNavigateWithinPage(
217 blink::WebLocalFrame* frame, const blink::WebHistoryItem& history_item,
218 blink::WebHistoryCommitType commit_type) {
219 navigator_host_->DidNavigateLocally(history_item.urlString().utf8());
222 void HTMLDocumentView::OnViewBoundsChanged(View* view,
223 const gfx::Rect& old_bounds,
224 const gfx::Rect& new_bounds) {
225 DCHECK_EQ(view, root_);
226 web_view_->resize(view->bounds().size());
229 void HTMLDocumentView::OnViewDestroyed(View* view) {
230 DCHECK_EQ(view, root_);
231 view->RemoveObserver(this);
232 root_ = NULL;
235 void HTMLDocumentView::OnViewInputEvent(View* view, const EventPtr& event) {
236 scoped_ptr<blink::WebInputEvent> web_event =
237 event.To<scoped_ptr<blink::WebInputEvent> >();
238 if (web_event)
239 web_view_->handleInputEvent(*web_event);
242 } // namespace mojo