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

Side by Side Diff: components/html_viewer/frame.cc

Issue 1246053003: Renames html_viewer frame classes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: minor cleanup Created 5 years, 5 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
« no previous file with comments | « components/html_viewer/frame.h ('k') | components/html_viewer/frame_tree_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "components/html_viewer/frame.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/stl_util.h"
12 #include "base/strings/string_util.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "components/html_viewer/ax_provider_impl.h"
15 #include "components/html_viewer/blink_basic_type_converters.h"
16 #include "components/html_viewer/blink_input_events_type_converters.h"
17 #include "components/html_viewer/blink_url_request_type_converters.h"
18 #include "components/html_viewer/frame_tree_manager.h"
19 #include "components/html_viewer/geolocation_client_impl.h"
20 #include "components/html_viewer/global_state.h"
21 #include "components/html_viewer/media_factory.h"
22 #include "components/html_viewer/touch_handler.h"
23 #include "components/html_viewer/web_layer_impl.h"
24 #include "components/html_viewer/web_layer_tree_view_impl.h"
25 #include "components/html_viewer/web_storage_namespace_impl.h"
26 #include "components/html_viewer/web_url_loader_impl.h"
27 #include "components/view_manager/ids.h"
28 #include "components/view_manager/public/cpp/view.h"
29 #include "components/view_manager/public/cpp/view_manager.h"
30 #include "components/view_manager/public/interfaces/surfaces.mojom.h"
31 #include "mandoline/services/navigation/public/interfaces/navigation.mojom.h"
32 #include "mojo/application/public/cpp/application_impl.h"
33 #include "mojo/application/public/cpp/connect.h"
34 #include "mojo/application/public/interfaces/shell.mojom.h"
35 #include "mojo/converters/geometry/geometry_type_converters.h"
36 #include "skia/ext/refptr.h"
37 #include "third_party/WebKit/public/platform/Platform.h"
38 #include "third_party/WebKit/public/platform/WebHTTPHeaderVisitor.h"
39 #include "third_party/WebKit/public/platform/WebSize.h"
40 #include "third_party/WebKit/public/web/WebConsoleMessage.h"
41 #include "third_party/WebKit/public/web/WebDocument.h"
42 #include "third_party/WebKit/public/web/WebElement.h"
43 #include "third_party/WebKit/public/web/WebFrameWidget.h"
44 #include "third_party/WebKit/public/web/WebInputEvent.h"
45 #include "third_party/WebKit/public/web/WebLocalFrame.h"
46 #include "third_party/WebKit/public/web/WebNavigationPolicy.h"
47 #include "third_party/WebKit/public/web/WebRemoteFrame.h"
48 #include "third_party/WebKit/public/web/WebRemoteFrameClient.h"
49 #include "third_party/WebKit/public/web/WebScriptSource.h"
50 #include "third_party/WebKit/public/web/WebSettings.h"
51 #include "third_party/WebKit/public/web/WebView.h"
52 #include "third_party/mojo/src/mojo/public/cpp/system/data_pipe.h"
53 #include "third_party/skia/include/core/SkCanvas.h"
54 #include "third_party/skia/include/core/SkColor.h"
55 #include "third_party/skia/include/core/SkDevice.h"
56 #include "ui/gfx/geometry/dip_util.h"
57 #include "ui/gfx/geometry/size.h"
58
59 using mojo::AxProvider;
60 using mojo::Rect;
61 using mojo::ServiceProviderPtr;
62 using mojo::URLResponsePtr;
63 using mojo::View;
64 using mojo::WeakBindToRequest;
65
66 namespace html_viewer {
67 namespace {
68
69 void ConfigureSettings(blink::WebSettings* settings) {
70 settings->setCookieEnabled(true);
71 settings->setDefaultFixedFontSize(13);
72 settings->setDefaultFontSize(16);
73 settings->setLoadsImagesAutomatically(true);
74 settings->setJavaScriptEnabled(true);
75 }
76
77 Frame* GetPreviousSibling(Frame* frame) {
78 DCHECK(frame->parent());
79 auto iter = std::find(frame->parent()->children().begin(),
80 frame->parent()->children().end(), frame);
81 return (iter == frame->parent()->children().begin()) ? nullptr : *(--iter);
82 }
83
84 } // namespace
85
86 Frame::Frame(const Frame::CreateParams& params)
87 : frame_tree_manager_(params.manager),
88 parent_(params.parent),
89 view_(nullptr),
90 id_(params.id),
91 web_frame_(nullptr),
92 web_widget_(nullptr),
93 scope_(blink::WebTreeScopeType::Document),
94 weak_factory_(this) {
95 if (parent_)
96 parent_->children_.push_back(this);
97 }
98
99 void Frame::Init(mojo::View* local_view,
100 const blink::WebString& remote_frame_name,
101 const blink::WebString& remote_origin) {
102 if (local_view->id() == id_)
103 SetView(local_view);
104
105 // TODO(sky): need to plumb through scope and other args correctly for frame
106 // creation.
107 if (!parent_) {
108 CreateWebWidget();
109 // This is the root of the tree (aka the main frame).
110 // Expected order for creating webframes is:
111 // . Create local webframe (first webframe must always be local).
112 // . Set as main frame on WebView.
113 // . Swap to remote (if not local).
114 blink::WebLocalFrame* local_web_frame =
115 blink::WebLocalFrame::create(blink::WebTreeScopeType::Document, this);
116 // We need to set the main frame before creating children so that state is
117 // properly set up in blink.
118 // TODO(sky): I don't like these casts.
119 web_view()->setMainFrame(local_web_frame);
120 const gfx::Size size_in_pixels(local_view->bounds().width,
121 local_view->bounds().height);
122 const gfx::Size size_in_dips = gfx::ConvertSizeToDIP(
123 local_view->viewport_metrics().device_pixel_ratio, size_in_pixels);
124 web_widget_->resize(size_in_dips);
125 web_frame_ = local_web_frame;
126 web_view()->setDeviceScaleFactor(global_state()->device_pixel_ratio());
127 if (id_ != local_view->id()) {
128 blink::WebRemoteFrame* remote_web_frame = blink::WebRemoteFrame::create(
129 blink::WebTreeScopeType::Document, this);
130 local_web_frame->swap(remote_web_frame);
131 // local_web_frame->close();
132 web_frame_ = remote_web_frame;
133 }
134 } else if (id_ == local_view->id()) {
135 // Frame represents the local frame.
136 Frame* previous_sibling = GetPreviousSibling(this);
137 blink::WebFrame* previous_web_frame =
138 previous_sibling ? previous_sibling->web_frame() : nullptr;
139 DCHECK(!parent_->IsLocal());
140 web_frame_ = parent_->web_frame()->toWebRemoteFrame()->createLocalChild(
141 blink::WebTreeScopeType::Document, "", blink::WebSandboxFlags::None,
142 this, previous_web_frame);
143 CreateWebWidget();
144 } else if (parent_->web_frame()->isWebLocalFrame()) {
145 blink::WebLocalFrame* local_web_frame =
146 blink::WebLocalFrame::create(blink::WebTreeScopeType::Document, this);
147 parent_->web_frame()->appendChild(local_web_frame);
148 blink::WebRemoteFrame* remote_web_frame =
149 blink::WebRemoteFrame::create(blink::WebTreeScopeType::Document, this);
150 // remote_web_frame->swap(local_web_frame);
151 local_web_frame->close();
152 web_frame_ = remote_web_frame;
153 } else {
154 web_frame_ = parent_->web_frame()->toWebRemoteFrame()->createRemoteChild(
155 blink::WebTreeScopeType::Document, remote_frame_name,
156 blink::WebSandboxFlags::None, this);
157 }
158
159 if (!IsLocal()) {
160 blink::WebRemoteFrame* remote_web_frame = web_frame_->toWebRemoteFrame();
161 if (remote_web_frame) {
162 remote_web_frame->setReplicatedName(remote_frame_name);
163 remote_web_frame->setReplicatedOrigin(
164 blink::WebSecurityOrigin::createFromString(remote_origin));
165 }
166 }
167 }
168
169 void Frame::Close() {
170 if (web_widget_) {
171 // Closing the widget implicitly detaches the frame.
172 web_widget_->close();
173 } else {
174 web_frame_->detach();
175 }
176 }
177
178 const Frame* Frame::FindFrame(uint32_t id) const {
179 if (id == id_)
180 return this;
181
182 for (const Frame* child : children_) {
183 const Frame* match = child->FindFrame(id);
184 if (match)
185 return match;
186 }
187 return nullptr;
188 }
189
190 blink::WebView* Frame::web_view() {
191 return web_widget_ && web_widget_->isWebView()
192 ? static_cast<blink::WebView*>(web_widget_)
193 : nullptr;
194 }
195
196 Frame::~Frame() {
197 DCHECK(children_.empty());
198
199 if (parent_) {
200 auto iter =
201 std::find(parent_->children_.begin(), parent_->children_.end(), this);
202 parent_->children_.erase(iter);
203 }
204 parent_ = nullptr;
205
206 frame_tree_manager_->OnFrameDestroyed(this);
207
208 if (view_) {
209 view_->RemoveObserver(this);
210 view_->Destroy();
211 }
212 }
213
214 void Frame::SetRemoteFrameName(const mojo::String& name) {
215 if (IsLocal())
216 return;
217
218 blink::WebRemoteFrame* remote_frame = web_frame_->toWebRemoteFrame();
219 if (remote_frame)
220 remote_frame->setReplicatedName(name.To<blink::WebString>());
221 }
222
223 bool Frame::IsLocal() const {
224 return web_frame_->isWebLocalFrame();
225 }
226
227 void Frame::SetView(mojo::View* view) {
228 DCHECK(!view_);
229 view_ = view;
230 view_->AddObserver(this);
231 }
232
233 void Frame::CreateWebWidget() {
234 DCHECK(!web_widget_);
235 if (parent_) {
236 // TODO(sky): this isn't quite right. I should only have a WebFrameWidget
237 // for local roots. And the cast to local fram definitely isn't right.
238 web_widget_ =
239 blink::WebFrameWidget::create(this, web_frame_->toWebLocalFrame());
240 } else if (view_ && view_->id() == id_) {
241 web_widget_ = blink::WebView::create(this);
242 } else {
243 web_widget_ = blink::WebView::create(nullptr);
244 }
245
246 // Creating the widget calls initializeLayerTreeView() to create the
247 // |web_layer_tree_view_impl_|. As we haven't yet assigned the |web_widget_|
248 // we have to set it here.
249 if (web_layer_tree_view_impl_) {
250 web_layer_tree_view_impl_->set_widget(web_widget_);
251 web_layer_tree_view_impl_->set_view(view_);
252 UpdateWebViewSizeFromViewSize();
253 }
254
255 if (web_view())
256 ConfigureSettings(web_view()->settings());
257 }
258
259 void Frame::UpdateFocus() {
260 if (!web_widget_ || !view_)
261 return;
262 const bool is_focused = view_ && view_->HasFocus();
263 web_widget_->setFocus(is_focused);
264 if (web_widget_->isWebView())
265 static_cast<blink::WebView*>(web_widget_)->setIsActive(is_focused);
266 }
267
268 void Frame::UpdateWebViewSizeFromViewSize() {
269 if (!web_widget_ || !view_)
270 return;
271
272 const gfx::Size size_in_pixels(view_->bounds().width, view_->bounds().height);
273 const gfx::Size size_in_dips = gfx::ConvertSizeToDIP(
274 view_->viewport_metrics().device_pixel_ratio, size_in_pixels);
275 web_widget_->resize(
276 blink::WebSize(size_in_dips.width(), size_in_dips.height()));
277 web_layer_tree_view_impl_->setViewportSize(size_in_pixels);
278 }
279
280 void Frame::SwapToRemote(const blink::WebURLRequest& request) {
281 DCHECK(IsLocal());
282 mojo::URLRequestPtr url_request = mojo::URLRequest::From(request);
283 view_->EmbedAllowingReembed(url_request.Pass());
284
285 // TODO(sky): I tried swapping the frame types here, but that resulted in
286 // the view never getting sized. Figure out why.
287 base::MessageLoop::current()->PostTask(
288 FROM_HERE,
289 base::Bind(&Frame::FinishSwapToRemote, weak_factory_.GetWeakPtr()));
290 }
291
292 void Frame::FinishSwapToRemote() {
293 if (web_frame_->isWebRemoteFrame())
294 return; // We already did the swap.
295
296 blink::WebRemoteFrame* remote_frame =
297 blink::WebRemoteFrame::create(scope_, this);
298 remote_frame->initializeFromFrame(web_frame_->toWebLocalFrame());
299 // swap() ends up calling us back and we then close the frame.
300 web_frame_->swap(remote_frame);
301 web_layer_.reset(new WebLayerImpl(this));
302 remote_frame->setRemoteWebLayer(web_layer_.get());
303 web_frame_ = remote_frame;
304 }
305
306 Frame* Frame::FindFrameWithWebFrame(blink::WebFrame* web_frame) {
307 if (web_frame_ == web_frame)
308 return this;
309 for (Frame* child_frame : children_) {
310 Frame* result = child_frame->FindFrameWithWebFrame(web_frame);
311 if (result)
312 return result;
313 }
314 return nullptr;
315 }
316
317 void Frame::FrameDetachedImpl(blink::WebFrame* web_frame) {
318 DCHECK_EQ(web_frame_, web_frame);
319
320 while (!children_.empty()) {
321 Frame* child = children_.front();
322 child->Close();
323 DCHECK(children_.empty() || children_.front() != child);
324 }
325
326 if (web_frame->parent())
327 web_frame->parent()->removeChild(web_frame);
328
329 delete this;
330 }
331
332 void Frame::OnViewBoundsChanged(View* view,
333 const Rect& old_bounds,
334 const Rect& new_bounds) {
335 DCHECK_EQ(view, view_);
336 UpdateWebViewSizeFromViewSize();
337 }
338
339 void Frame::OnViewDestroyed(View* view) {
340 DCHECK_EQ(view, view_);
341 view_->RemoveObserver(this);
342 view_ = nullptr;
343 Close();
344 }
345
346 void Frame::OnViewInputEvent(View* view, const mojo::EventPtr& event) {
347 if (event->pointer_data) {
348 // Blink expects coordintes to be in DIPs.
349 event->pointer_data->x /= global_state()->device_pixel_ratio();
350 event->pointer_data->y /= global_state()->device_pixel_ratio();
351 event->pointer_data->screen_x /= global_state()->device_pixel_ratio();
352 event->pointer_data->screen_y /= global_state()->device_pixel_ratio();
353 }
354
355 if (!touch_handler_ && web_widget_)
356 touch_handler_.reset(new TouchHandler(web_widget_));
357
358 if ((event->action == mojo::EVENT_TYPE_POINTER_DOWN ||
359 event->action == mojo::EVENT_TYPE_POINTER_UP ||
360 event->action == mojo::EVENT_TYPE_POINTER_CANCEL ||
361 event->action == mojo::EVENT_TYPE_POINTER_MOVE) &&
362 event->pointer_data->kind == mojo::POINTER_KIND_TOUCH) {
363 touch_handler_->OnTouchEvent(*event);
364 return;
365 }
366
367 if (!web_widget_)
368 return;
369
370 scoped_ptr<blink::WebInputEvent> web_event =
371 event.To<scoped_ptr<blink::WebInputEvent>>();
372 if (web_event)
373 web_widget_->handleInputEvent(*web_event);
374 }
375
376 void Frame::OnViewFocusChanged(mojo::View* gained_focus,
377 mojo::View* lost_focus) {
378 UpdateFocus();
379 }
380
381 void Frame::initializeLayerTreeView() {
382 mojo::URLRequestPtr request(mojo::URLRequest::New());
383 request->url = mojo::String::From("mojo:surfaces_service");
384 mojo::SurfacePtr surface;
385 frame_tree_manager_->app()->ConnectToService(request.Pass(), &surface);
386
387 // TODO(jamesr): Should be mojo:gpu_service
388 mojo::URLRequestPtr request2(mojo::URLRequest::New());
389 request2->url = mojo::String::From("mojo:view_manager");
390 mojo::GpuPtr gpu_service;
391 frame_tree_manager_->app()->ConnectToService(request2.Pass(), &gpu_service);
392 web_layer_tree_view_impl_.reset(new WebLayerTreeViewImpl(
393 global_state()->compositor_thread(),
394 global_state()->gpu_memory_buffer_manager(),
395 global_state()->raster_thread_helper()->task_graph_runner(),
396 surface.Pass(), gpu_service.Pass()));
397 }
398
399 blink::WebLayerTreeView* Frame::layerTreeView() {
400 return web_layer_tree_view_impl_.get();
401 }
402
403 blink::WebStorageNamespace* Frame::createSessionStorageNamespace() {
404 return new WebStorageNamespaceImpl();
405 }
406
407 blink::WebMediaPlayer* Frame::createMediaPlayer(
408 blink::WebLocalFrame* frame,
409 const blink::WebURL& url,
410 blink::WebMediaPlayerClient* client,
411 blink::WebMediaPlayerEncryptedMediaClient* encrypted_client,
412 blink::WebContentDecryptionModule* initial_cdm) {
413 return global_state()->media_factory()->CreateMediaPlayer(
414 frame, url, client, encrypted_client, initial_cdm,
415 frame_tree_manager_->app()->shell());
416 }
417
418 blink::WebFrame* Frame::createChildFrame(blink::WebLocalFrame* parent,
419 blink::WebTreeScopeType scope,
420 const blink::WebString& frame_name,
421 blink::WebSandboxFlags sandbox_flags) {
422 DCHECK(IsLocal()); // Can't create children of remote frames.
423 DCHECK_EQ(parent, web_frame_);
424 DCHECK(view_); // If we're local we have to have a view.
425 // Create the view that will house the frame now. We embed once we know the
426 // url (see decidePolicyForNavigation()).
427 mojo::View* child_view = view_->view_manager()->CreateView();
428 child_view->SetVisible(true);
429 view_->AddChild(child_view);
430
431 // TODO(sky): the act of creating needs to notify the browser side, not
432 // navigation.
433 Frame::CreateParams params(frame_tree_manager_, this, child_view->id());
434 Frame* child_frame = new Frame(params);
435 child_frame->scope_ = scope;
436
437 child_frame->SetView(child_view);
438
439 blink::WebLocalFrame* child_web_frame =
440 blink::WebLocalFrame::create(scope, child_frame);
441 child_frame->web_frame_ = child_web_frame;
442 parent->appendChild(child_web_frame);
443 return child_web_frame;
444 }
445
446 void Frame::frameDetached(blink::WebFrame* web_frame,
447 blink::WebFrameClient::DetachType type) {
448 if (type == blink::WebFrameClient::DetachType::Swap) {
449 web_frame->close();
450 return;
451 }
452
453 DCHECK(type == blink::WebFrameClient::DetachType::Remove);
454 FrameDetachedImpl(web_frame);
455 }
456
457 blink::WebCookieJar* Frame::cookieJar(blink::WebLocalFrame* frame) {
458 // TODO(darin): Blink does not fallback to the Platform provided WebCookieJar.
459 // Either it should, as it once did, or we should find another solution here.
460 return blink::Platform::current()->cookieJar();
461 }
462
463 blink::WebNavigationPolicy Frame::decidePolicyForNavigation(
464 const NavigationPolicyInfo& info) {
465 if (parent_ && parent_->IsLocal()) {
466 SwapToRemote(info.urlRequest);
467 return blink::WebNavigationPolicyIgnore;
468 }
469
470 return frame_tree_manager_->DecidePolicyForNavigation(this, info);
471 }
472
473 void Frame::didAddMessageToConsole(const blink::WebConsoleMessage& message,
474 const blink::WebString& source_name,
475 unsigned source_line,
476 const blink::WebString& stack_trace) {
477 VLOG(1) << "[" << source_name.utf8() << "(" << source_line << ")] "
478 << message.text.utf8();
479 }
480
481 void Frame::didFinishLoad(blink::WebLocalFrame* frame) {
482 frame_tree_manager_->OnFrameDidFinishLoad(this);
483 }
484
485 void Frame::didNavigateWithinPage(blink::WebLocalFrame* frame,
486 const blink::WebHistoryItem& history_item,
487 blink::WebHistoryCommitType commit_type) {
488 frame_tree_manager_->OnFrameDidNavigateLocally(
489 this, history_item.urlString().utf8());
490 }
491
492 blink::WebGeolocationClient* Frame::geolocationClient() {
493 if (!geolocation_client_impl_)
494 geolocation_client_impl_.reset(new GeolocationClientImpl);
495 return geolocation_client_impl_.get();
496 }
497
498 blink::WebEncryptedMediaClient* Frame::encryptedMediaClient() {
499 return global_state()->media_factory()->GetEncryptedMediaClient();
500 }
501
502 void Frame::didStartLoading(bool to_different_document) {
503 frame_tree_manager_->LoadingStarted();
504 }
505
506 void Frame::didStopLoading() {
507 frame_tree_manager_->LoadingStopped();
508 }
509
510 void Frame::didChangeLoadProgress(double load_progress) {
511 frame_tree_manager_->ProgressChanged(load_progress);
512 }
513
514 void Frame::didChangeName(blink::WebLocalFrame* frame,
515 const blink::WebString& name) {
516 frame_tree_manager_->OnFrameDidChangeName(this, name);
517 }
518
519 void Frame::frameDetached(blink::WebRemoteFrameClient::DetachType type) {
520 if (type == blink::WebRemoteFrameClient::DetachType::Swap) {
521 web_frame_->close();
522 return;
523 }
524
525 DCHECK(type == blink::WebRemoteFrameClient::DetachType::Remove);
526 FrameDetachedImpl(web_frame_);
527 }
528
529 void Frame::postMessageEvent(blink::WebLocalFrame* source_frame,
530 blink::WebRemoteFrame* target_frame,
531 blink::WebSecurityOrigin target_origin,
532 blink::WebDOMMessageEvent event) {
533 NOTIMPLEMENTED();
534 }
535
536 void Frame::initializeChildFrame(const blink::WebRect& frame_rect,
537 float scale_factor) {
538 // TODO(sky): frame_rect is in dips. Need to convert.
539 mojo::Rect rect;
540 rect.x = frame_rect.x;
541 rect.y = frame_rect.y;
542 rect.width = frame_rect.width;
543 rect.height = frame_rect.height;
544 view_->SetBounds(rect);
545 }
546
547 void Frame::navigate(const blink::WebURLRequest& request,
548 bool should_replace_current_entry) {
549 NOTIMPLEMENTED();
550 }
551
552 void Frame::reload(bool ignore_cache, bool is_client_redirect) {
553 NOTIMPLEMENTED();
554 }
555
556 void Frame::forwardInputEvent(const blink::WebInputEvent* event) {
557 NOTIMPLEMENTED();
558 }
559
560 } // namespace mojo
OLDNEW
« no previous file with comments | « components/html_viewer/frame.h ('k') | components/html_viewer/frame_tree_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698