OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/web_contents/web_contents_impl.h" | 5 #include "content/browser/web_contents/web_contents_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <cmath> | 9 #include <cmath> |
10 #include <utility> | 10 #include <utility> |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
369 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- | 369 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- |
370 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() | 370 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() |
371 : outer_web_contents_(nullptr), | 371 : outer_web_contents_(nullptr), |
372 outer_contents_frame_tree_node_id_( | 372 outer_contents_frame_tree_node_id_( |
373 FrameTreeNode::kFrameTreeNodeInvalidId), | 373 FrameTreeNode::kFrameTreeNodeInvalidId), |
374 focused_web_contents_(nullptr) {} | 374 focused_web_contents_(nullptr) {} |
375 | 375 |
376 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { | 376 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { |
377 // Remove child pointer from our parent. | 377 // Remove child pointer from our parent. |
378 if (outer_web_contents_) { | 378 if (outer_web_contents_) { |
379 ChildrenSet& child_ptrs_in_parent = | 379 ChildrenMap& child_ptrs_in_parent = |
380 outer_web_contents_->node_->inner_web_contents_tree_nodes_; | 380 outer_web_contents_->node_->inner_web_contents_tree_nodes_; |
381 ChildrenSet::iterator iter = child_ptrs_in_parent.find(this); | 381 ChildrenMap::iterator iter = |
382 child_ptrs_in_parent.find(outer_contents_frame_tree_node_id_); | |
382 DCHECK(iter != child_ptrs_in_parent.end()); | 383 DCHECK(iter != child_ptrs_in_parent.end()); |
383 child_ptrs_in_parent.erase(iter); | 384 child_ptrs_in_parent.erase(iter); |
384 } | 385 } |
385 | 386 |
386 // Remove parent pointers from our children. | 387 // Remove parent pointers from our children. |
387 // TODO(lazyboy): We should destroy the children WebContentses too. If the | 388 // TODO(lazyboy): We should destroy the children WebContentses too. If the |
388 // children do not manage their own lifetime, then we would leak their | 389 // children do not manage their own lifetime, then we would leak their |
389 // WebContentses. | 390 // WebContentses. |
390 for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_) | 391 for (auto child : inner_web_contents_tree_nodes_) |
391 child->outer_web_contents_ = nullptr; | 392 child.second->node_->outer_web_contents_ = nullptr; |
392 } | 393 } |
393 | 394 |
394 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( | 395 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( |
396 WebContentsImpl* web_contents, | |
395 WebContentsImpl* outer_web_contents, | 397 WebContentsImpl* outer_web_contents, |
396 RenderFrameHostImpl* outer_contents_frame) { | 398 RenderFrameHostImpl* outer_contents_frame) { |
397 DCHECK(!focused_web_contents_) << "Should not attach a root node."; | 399 DCHECK(!focused_web_contents_) << "Should not attach a root node."; |
398 outer_web_contents_ = outer_web_contents; | 400 outer_web_contents_ = outer_web_contents; |
399 outer_contents_frame_tree_node_id_ = | 401 outer_contents_frame_tree_node_id_ = |
400 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); | 402 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); |
401 | 403 |
402 if (!outer_web_contents_->node_) { | 404 if (!outer_web_contents_->node_) { |
403 // This will only be reached when creating a new WebContents tree. | 405 // This will only be reached when creating a new WebContents tree. |
404 // Initialize the root of this tree and set it as focused. | 406 // Initialize the root of this tree and set it as focused. |
405 outer_web_contents_->node_.reset(new WebContentsTreeNode()); | 407 outer_web_contents_->node_.reset(new WebContentsTreeNode()); |
406 outer_web_contents_->node_->SetFocusedWebContents(outer_web_contents_); | 408 outer_web_contents_->node_->SetFocusedWebContents(outer_web_contents_); |
407 } | 409 } |
408 | 410 |
409 outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this); | 411 outer_web_contents_->node_ |
412 ->inner_web_contents_tree_nodes_[outer_contents_frame_tree_node_id_] = | |
413 web_contents; | |
410 } | 414 } |
411 | 415 |
412 void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents( | 416 void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents( |
413 WebContentsImpl* web_contents) { | 417 WebContentsImpl* web_contents) { |
414 DCHECK(!outer_web_contents()) | 418 DCHECK(!outer_web_contents()) |
415 << "Only the outermost WebContents tracks focus."; | 419 << "Only the outermost WebContents tracks focus."; |
416 focused_web_contents_ = web_contents; | 420 focused_web_contents_ = web_contents; |
417 } | 421 } |
418 | 422 |
423 WebContentsImpl* WebContentsImpl::WebContentsTreeNode::find_contents_at_node( | |
424 int frame_tree_node_id) { | |
425 auto iter = inner_web_contents_tree_nodes_.find(frame_tree_node_id); | |
426 if (iter == inner_web_contents_tree_nodes_.end()) | |
427 return nullptr; | |
428 return iter->second; | |
429 } | |
430 | |
419 // WebContentsImpl ------------------------------------------------------------- | 431 // WebContentsImpl ------------------------------------------------------------- |
420 | 432 |
421 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) | 433 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) |
422 : delegate_(NULL), | 434 : delegate_(NULL), |
423 controller_(this, browser_context), | 435 controller_(this, browser_context), |
424 render_view_host_delegate_view_(NULL), | 436 render_view_host_delegate_view_(NULL), |
425 created_with_opener_(false), | 437 created_with_opener_(false), |
426 frame_tree_(new NavigatorImpl(&controller_, this), | 438 frame_tree_(new NavigatorImpl(&controller_, this), |
427 this, | 439 this, |
428 this, | 440 this, |
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1416 // before attaching. If the browser side is already initialized, the calls | 1428 // before attaching. If the browser side is already initialized, the calls |
1417 // below will just early return. | 1429 // below will just early return. |
1418 render_manager->InitRenderView(GetRenderViewHost(), nullptr); | 1430 render_manager->InitRenderView(GetRenderViewHost(), nullptr); |
1419 GetMainFrame()->Init(); | 1431 GetMainFrame()->Init(); |
1420 if (!render_manager->GetRenderWidgetHostView()) | 1432 if (!render_manager->GetRenderWidgetHostView()) |
1421 CreateRenderWidgetHostViewForRenderManager(GetRenderViewHost()); | 1433 CreateRenderWidgetHostViewForRenderManager(GetRenderViewHost()); |
1422 | 1434 |
1423 // Create a link to our outer WebContents. | 1435 // Create a link to our outer WebContents. |
1424 node_.reset(new WebContentsTreeNode()); | 1436 node_.reset(new WebContentsTreeNode()); |
1425 node_->ConnectToOuterWebContents( | 1437 node_->ConnectToOuterWebContents( |
1426 static_cast<WebContentsImpl*>(outer_web_contents), | 1438 this, static_cast<WebContentsImpl*>(outer_web_contents), |
1427 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); | 1439 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); |
1428 | 1440 |
1429 DCHECK(outer_contents_frame); | 1441 DCHECK(outer_contents_frame); |
1430 | 1442 |
1431 // Create a proxy in top-level RenderFrameHostManager, pointing to the | 1443 // Create a proxy in top-level RenderFrameHostManager, pointing to the |
1432 // SiteInstance of the outer WebContents. The proxy will be used to send | 1444 // SiteInstance of the outer WebContents. The proxy will be used to send |
1433 // postMessage to the inner WebContents. | 1445 // postMessage to the inner WebContents. |
1434 render_manager->CreateOuterDelegateProxy( | 1446 render_manager->CreateOuterDelegateProxy( |
1435 outer_contents_frame->GetSiteInstance(), | 1447 outer_contents_frame->GetSiteInstance(), |
1436 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); | 1448 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); |
1437 | 1449 |
1438 render_manager->SetRWHViewForInnerContents( | 1450 render_manager->SetRWHViewForInnerContents( |
1439 render_manager->GetRenderWidgetHostView()); | 1451 render_manager->GetRenderWidgetHostView()); |
1440 | 1452 |
1441 static_cast<RenderWidgetHostViewChildFrame*>( | 1453 static_cast<RenderWidgetHostViewChildFrame*>( |
1442 render_manager->GetRenderWidgetHostView()) | 1454 render_manager->GetRenderWidgetHostView()) |
1443 ->RegisterFrameSinkId(); | 1455 ->RegisterFrameSinkId(); |
1444 | 1456 |
1457 // Set up the the guest's AX tree to point back at the embedder's AX tree. | |
1458 auto* parent_frame = outer_contents_frame->GetParent(); | |
1459 GetMainFrame()->set_browser_plugin_embedder_ax_tree_id( | |
1460 parent_frame->GetAXTreeID()); | |
1461 GetMainFrame()->UpdateAXTreeData(); | |
1462 | |
1445 // At this point, we should destroy the TextInputManager which will notify all | 1463 // At this point, we should destroy the TextInputManager which will notify all |
1446 // the RWHV in this WebContents. The RWHV in this WebContents should use the | 1464 // the RWHV in this WebContents. The RWHV in this WebContents should use the |
1447 // TextInputManager owned by the outer WebContents. | 1465 // TextInputManager owned by the outer WebContents. |
1448 // TODO(ekaramad): Is it possible to have TextInputState before attaching to | 1466 // TODO(ekaramad): Is it possible to have TextInputState before attaching to |
1449 // outer WebContents? In such a case, is this still the right way to hand off | 1467 // outer WebContents? In such a case, is this still the right way to hand off |
1450 // state tracking from inner WebContents's TextInputManager to that of the | 1468 // state tracking from inner WebContents's TextInputManager to that of the |
1451 // outer WebContent (crbug.com/609846)? | 1469 // outer WebContent (crbug.com/609846)? |
1452 text_input_manager_.reset(nullptr); | 1470 text_input_manager_.reset(nullptr); |
1453 } | 1471 } |
1454 | 1472 |
(...skipping 2850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4305 return false; | 4323 return false; |
4306 } | 4324 } |
4307 | 4325 |
4308 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { | 4326 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { |
4309 WebContentsImpl* root = this; | 4327 WebContentsImpl* root = this; |
4310 while (root->GetOuterWebContents()) | 4328 while (root->GetOuterWebContents()) |
4311 root = root->GetOuterWebContents(); | 4329 root = root->GetOuterWebContents(); |
4312 return root; | 4330 return root; |
4313 } | 4331 } |
4314 | 4332 |
4333 void WebContentsImpl::FocusOuterAttachmentFrameChain() { | |
4334 WebContentsImpl* outer_contents = GetOuterWebContents(); | |
4335 if (!outer_contents) | |
4336 return; | |
4337 | |
4338 FrameTreeNode* outer_node = | |
4339 FrameTreeNode::GloballyFindByID(GetOuterDelegateFrameTreeNodeId()); | |
4340 outer_contents->frame_tree_.SetFocusedFrame(outer_node, nullptr); | |
4341 if(GetRenderManager()->GetProxyToOuterDelegate()) | |
dmazzoni
2017/02/22 08:46:41
nit: space before first (
avallee
2017/02/22 16:58:49
Done.
| |
4342 GetRenderManager()->GetProxyToOuterDelegate()->SetFocusedFrame(); | |
4343 | |
4344 outer_contents->FocusOuterAttachmentFrameChain(); | |
4345 } | |
4346 | |
4315 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { | 4347 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { |
4316 // Don't send notifications if we are just creating a swapped-out RVH for | 4348 // Don't send notifications if we are just creating a swapped-out RVH for |
4317 // the opener chain. These won't be used for view-source or WebUI, so it's | 4349 // the opener chain. These won't be used for view-source or WebUI, so it's |
4318 // ok to return early. | 4350 // ok to return early. |
4319 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) | 4351 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) |
4320 return; | 4352 return; |
4321 | 4353 |
4322 if (delegate_) | 4354 if (delegate_) |
4323 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); | 4355 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); |
4324 | 4356 |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4705 return; | 4737 return; |
4706 | 4738 |
4707 // Send a page level blur to the old contents so that it displays inactive UI | 4739 // Send a page level blur to the old contents so that it displays inactive UI |
4708 // and focus this contents to activate it. | 4740 // and focus this contents to activate it. |
4709 if (old_contents) | 4741 if (old_contents) |
4710 old_contents->GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(false); | 4742 old_contents->GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(false); |
4711 | 4743 |
4712 // Make sure the outer web contents knows our frame is focused. Otherwise, the | 4744 // Make sure the outer web contents knows our frame is focused. Otherwise, the |
4713 // outer renderer could have the element before or after the frame element | 4745 // outer renderer could have the element before or after the frame element |
4714 // focused which would return early without actually advancing focus. | 4746 // focused which would return early without actually advancing focus. |
4715 if (GetRenderManager()->GetProxyToOuterDelegate()) | 4747 FocusOuterAttachmentFrameChain(); |
4716 GetRenderManager()->GetProxyToOuterDelegate()->SetFocusedFrame(); | |
4717 | 4748 |
4718 GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(true); | 4749 GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(true); |
4719 GetOutermostWebContents()->node_->SetFocusedWebContents(this); | 4750 GetOutermostWebContents()->node_->SetFocusedWebContents(this); |
4720 } | 4751 } |
4721 | 4752 |
4722 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, | 4753 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, |
4723 SiteInstance* source) { | 4754 SiteInstance* source) { |
4724 // The PDF plugin still runs as a BrowserPlugin and must go through the | 4755 // The PDF plugin still runs as a BrowserPlugin and must go through the |
4725 // input redirection mechanism. It must not become focused direcly. | 4756 // input redirection mechanism. It must not become focused direcly. |
4726 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) { | 4757 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) { |
4727 frame_tree_.SetFocusedFrame(node, source); | 4758 frame_tree_.SetFocusedFrame(node, source); |
4728 return; | 4759 return; |
4729 } | 4760 } |
4730 | 4761 |
4731 SetAsFocusedWebContentsIfNecessary(); | 4762 frame_tree_.SetFocusedFrame(node, source); |
4732 | 4763 |
4733 frame_tree_.SetFocusedFrame(node, source); | 4764 WebContentsImpl* inner_contents = nullptr; |
4765 if (node_) | |
4766 inner_contents = node_->find_contents_at_node(node->frame_tree_node_id()); | |
4767 | |
4768 WebContentsImpl* contents_to_focus = inner_contents ? inner_contents : this; | |
4769 contents_to_focus->SetAsFocusedWebContentsIfNecessary(); | |
4770 } | |
4771 | |
4772 RenderFrameHost* WebContentsImpl::GetFocusedFrameIncludingInnerWebContents() { | |
4773 if (!node_) | |
4774 return GetFocusedFrame(); | |
4775 | |
4776 auto* contents = this; | |
4777 auto* focused_node = contents->frame_tree_.GetFocusedFrame(); | |
4778 | |
4779 // If there is no focused frame in the outer WebContents, we need to return | |
4780 // null. | |
4781 if (!focused_node) | |
4782 return nullptr; | |
4783 | |
4784 // We cannot return the frame where an inner WebContents is attached, if the | |
4785 // inner WebContents does not have a focused frame, return its main frame. | |
4786 while(true) { | |
dmazzoni
2017/02/22 08:46:41
nit: space before (
avallee
2017/02/22 16:58:49
Done.
| |
4787 contents = contents->node_->find_contents_at_node( | |
4788 focused_node->frame_tree_node_id()); | |
4789 if (!contents) | |
4790 return focused_node->current_frame_host(); | |
4791 | |
4792 focused_node = contents->frame_tree_.GetFocusedFrame(); | |
4793 if (!focused_node) | |
4794 return contents->GetMainFrame(); | |
4795 } | |
4734 } | 4796 } |
4735 | 4797 |
4736 void WebContentsImpl::OnFocusedElementChangedInFrame( | 4798 void WebContentsImpl::OnFocusedElementChangedInFrame( |
4737 RenderFrameHostImpl* frame, | 4799 RenderFrameHostImpl* frame, |
4738 const gfx::Rect& bounds_in_root_view) { | 4800 const gfx::Rect& bounds_in_root_view) { |
4739 RenderWidgetHostViewBase* root_view = | 4801 RenderWidgetHostViewBase* root_view = |
4740 static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView()); | 4802 static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView()); |
4741 if (!root_view || !frame->GetView()) | 4803 if (!root_view || !frame->GetView()) |
4742 return; | 4804 return; |
4743 | 4805 |
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5396 GetMainFrame()->AddMessageToConsole( | 5458 GetMainFrame()->AddMessageToConsole( |
5397 content::CONSOLE_MESSAGE_LEVEL_WARNING, | 5459 content::CONSOLE_MESSAGE_LEVEL_WARNING, |
5398 base::StringPrintf("This site does not have a valid SSL " | 5460 base::StringPrintf("This site does not have a valid SSL " |
5399 "certificate! Without SSL, your site's and " | 5461 "certificate! Without SSL, your site's and " |
5400 "visitors' data is vulnerable to theft and " | 5462 "visitors' data is vulnerable to theft and " |
5401 "tampering. Get a valid SSL certificate before" | 5463 "tampering. Get a valid SSL certificate before" |
5402 " releasing your website to the public.")); | 5464 " releasing your website to the public.")); |
5403 } | 5465 } |
5404 | 5466 |
5405 } // namespace content | 5467 } // namespace content |
OLD | NEW |