| 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 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 identifier(identifier) { | 323 identifier(identifier) { |
| 324 } | 324 } |
| 325 | 325 |
| 326 WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() { | 326 WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() { |
| 327 } | 327 } |
| 328 | 328 |
| 329 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- | 329 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- |
| 330 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() | 330 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() |
| 331 : outer_web_contents_(nullptr), | 331 : outer_web_contents_(nullptr), |
| 332 outer_contents_frame_tree_node_id_( | 332 outer_contents_frame_tree_node_id_( |
| 333 FrameTreeNode::kFrameTreeNodeInvalidId) { | 333 FrameTreeNode::kFrameTreeNodeInvalidId), |
| 334 } | 334 focused_web_contents_(nullptr) {} |
| 335 | 335 |
| 336 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { | 336 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { |
| 337 // Remove child pointer from our parent. | 337 // Remove child pointer from our parent. |
| 338 if (outer_web_contents_) { | 338 if (outer_web_contents_) { |
| 339 ChildrenSet& child_ptrs_in_parent = | 339 ChildrenSet& child_ptrs_in_parent = |
| 340 outer_web_contents_->node_->inner_web_contents_tree_nodes_; | 340 outer_web_contents_->node_->inner_web_contents_tree_nodes_; |
| 341 ChildrenSet::iterator iter = child_ptrs_in_parent.find(this); | 341 ChildrenSet::iterator iter = child_ptrs_in_parent.find(this); |
| 342 DCHECK(iter != child_ptrs_in_parent.end()); | 342 DCHECK(iter != child_ptrs_in_parent.end()); |
| 343 child_ptrs_in_parent.erase(this); | 343 child_ptrs_in_parent.erase(iter); |
| 344 } | 344 } |
| 345 | 345 |
| 346 // Remove parent pointers from our children. | 346 // Remove parent pointers from our children. |
| 347 // TODO(lazyboy): We should destroy the children WebContentses too. If the | 347 // TODO(lazyboy): We should destroy the children WebContentses too. If the |
| 348 // children do not manage their own lifetime, then we would leak their | 348 // children do not manage their own lifetime, then we would leak their |
| 349 // WebContentses. | 349 // WebContentses. |
| 350 for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_) | 350 for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_) |
| 351 child->outer_web_contents_ = nullptr; | 351 child->outer_web_contents_ = nullptr; |
| 352 } | 352 } |
| 353 | 353 |
| 354 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( | 354 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( |
| 355 WebContentsImpl* outer_web_contents, | 355 WebContentsImpl* outer_web_contents, |
| 356 RenderFrameHostImpl* outer_contents_frame) { | 356 RenderFrameHostImpl* outer_contents_frame) { |
| 357 DCHECK(!focused_web_contents_) << "Should not attach a root node."; |
| 357 outer_web_contents_ = outer_web_contents; | 358 outer_web_contents_ = outer_web_contents; |
| 358 outer_contents_frame_tree_node_id_ = | 359 outer_contents_frame_tree_node_id_ = |
| 359 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); | 360 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); |
| 360 | 361 |
| 361 if (!outer_web_contents_->node_) | 362 if (!outer_web_contents_->node_) { |
| 363 // This will only be reached when creating a new WebContents tree. |
| 364 // Initialize the root of this tree and set it as focused. |
| 362 outer_web_contents_->node_.reset(new WebContentsTreeNode()); | 365 outer_web_contents_->node_.reset(new WebContentsTreeNode()); |
| 366 outer_web_contents_->node_->SetFocusedWebContents(outer_web_contents_); |
| 367 } |
| 363 | 368 |
| 364 outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this); | 369 outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this); |
| 365 } | 370 } |
| 366 | 371 |
| 372 void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents( |
| 373 WebContentsImpl* web_contents) { |
| 374 DCHECK(!outer_web_contents()) |
| 375 << "Only the outermost WebContents tracks focus."; |
| 376 focused_web_contents_ = web_contents; |
| 377 } |
| 378 |
| 367 // WebContentsImpl ------------------------------------------------------------- | 379 // WebContentsImpl ------------------------------------------------------------- |
| 368 | 380 |
| 369 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) | 381 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) |
| 370 : delegate_(NULL), | 382 : delegate_(NULL), |
| 371 controller_(this, browser_context), | 383 controller_(this, browser_context), |
| 372 render_view_host_delegate_view_(NULL), | 384 render_view_host_delegate_view_(NULL), |
| 373 created_with_opener_(false), | 385 created_with_opener_(false), |
| 374 frame_tree_(new NavigatorImpl(&controller_, this), | 386 frame_tree_(new NavigatorImpl(&controller_, this), |
| 375 this, | 387 this, |
| 376 this, | 388 this, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 #endif | 440 #endif |
| 429 loader_io_thread_notifier_.reset(new LoaderIOThreadNotifier(this)); | 441 loader_io_thread_notifier_.reset(new LoaderIOThreadNotifier(this)); |
| 430 wake_lock_service_context_.reset(new WakeLockServiceContext(this)); | 442 wake_lock_service_context_.reset(new WakeLockServiceContext(this)); |
| 431 } | 443 } |
| 432 | 444 |
| 433 WebContentsImpl::~WebContentsImpl() { | 445 WebContentsImpl::~WebContentsImpl() { |
| 434 is_being_destroyed_ = true; | 446 is_being_destroyed_ = true; |
| 435 | 447 |
| 436 rwh_input_event_router_.reset(); | 448 rwh_input_event_router_.reset(); |
| 437 | 449 |
| 450 WebContentsImpl* outermost = GetOutermostWebContents(); |
| 451 if (GetFocusedWebContents() == this && this != outermost) { |
| 452 // If the current WebContents is in focus, unset it. |
| 453 outermost->node_->SetFocusedWebContents(outermost); |
| 454 } |
| 455 |
| 438 for (FrameTreeNode* node : frame_tree_.Nodes()) { | 456 for (FrameTreeNode* node : frame_tree_.Nodes()) { |
| 439 // Delete all RFHs pending shutdown, which will lead the corresponding RVHs | 457 // Delete all RFHs pending shutdown, which will lead the corresponding RVHs |
| 440 // to be shutdown and be deleted as well. | 458 // to be shutdown and be deleted as well. |
| 441 node->render_manager()->ClearRFHsPendingShutdown(); | 459 node->render_manager()->ClearRFHsPendingShutdown(); |
| 442 node->render_manager()->ClearWebUIInstances(); | 460 node->render_manager()->ClearWebUIInstances(); |
| 443 } | 461 } |
| 444 | 462 |
| 445 for (RenderWidgetHostImpl* widget : created_widgets_) | 463 for (RenderWidgetHostImpl* widget : created_widgets_) |
| 446 widget->DetachDelegate(); | 464 widget->DetachDelegate(); |
| 447 created_widgets_.clear(); | 465 created_widgets_.clear(); |
| (...skipping 1344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1792 RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost( | 1810 RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost( |
| 1793 RenderWidgetHostImpl* receiving_widget) { | 1811 RenderWidgetHostImpl* receiving_widget) { |
| 1794 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible()) | 1812 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible()) |
| 1795 return receiving_widget; | 1813 return receiving_widget; |
| 1796 | 1814 |
| 1797 // Events for widgets other than the main frame (e.g., popup menus) should be | 1815 // Events for widgets other than the main frame (e.g., popup menus) should be |
| 1798 // forwarded directly to the widget they arrived on. | 1816 // forwarded directly to the widget they arrived on. |
| 1799 if (receiving_widget != GetMainFrame()->GetRenderWidgetHost()) | 1817 if (receiving_widget != GetMainFrame()->GetRenderWidgetHost()) |
| 1800 return receiving_widget; | 1818 return receiving_widget; |
| 1801 | 1819 |
| 1802 FrameTreeNode* focused_frame = frame_tree_.GetFocusedFrame(); | 1820 FrameTreeNode* focused_frame = |
| 1821 GetFocusedWebContents()->frame_tree_.GetFocusedFrame(); |
| 1803 if (!focused_frame) | 1822 if (!focused_frame) |
| 1804 return receiving_widget; | 1823 return receiving_widget; |
| 1805 | 1824 |
| 1806 // The view may be null if a subframe's renderer process has crashed while | 1825 // The view may be null if a subframe's renderer process has crashed while |
| 1807 // the subframe has focus. Drop the event in that case. Do not give | 1826 // the subframe has focus. Drop the event in that case. Do not give |
| 1808 // it to the main frame, so that the user doesn't unexpectedly type into the | 1827 // it to the main frame, so that the user doesn't unexpectedly type into the |
| 1809 // wrong frame if a focused subframe renderer crashes while they type. | 1828 // wrong frame if a focused subframe renderer crashes while they type. |
| 1810 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView(); | 1829 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView(); |
| 1811 if (!view) | 1830 if (!view) |
| 1812 return nullptr; | 1831 return nullptr; |
| (...skipping 2315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4128 if (delegate_) | 4147 if (delegate_) |
| 4129 return delegate_->GetRootWindowResizerRect(); | 4148 return delegate_->GetRootWindowResizerRect(); |
| 4130 return gfx::Rect(); | 4149 return gfx::Rect(); |
| 4131 } | 4150 } |
| 4132 | 4151 |
| 4133 void WebContentsImpl::RemoveBrowserPluginEmbedder() { | 4152 void WebContentsImpl::RemoveBrowserPluginEmbedder() { |
| 4134 if (browser_plugin_embedder_) | 4153 if (browser_plugin_embedder_) |
| 4135 browser_plugin_embedder_.reset(); | 4154 browser_plugin_embedder_.reset(); |
| 4136 } | 4155 } |
| 4137 | 4156 |
| 4157 WebContentsImpl* WebContentsImpl::GetOuterWebContents() { |
| 4158 if (BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) { |
| 4159 if (node_) |
| 4160 return node_->outer_web_contents(); |
| 4161 } else { |
| 4162 if (GetBrowserPluginGuest()) |
| 4163 return GetBrowserPluginGuest()->embedder_web_contents(); |
| 4164 } |
| 4165 return nullptr; |
| 4166 } |
| 4167 |
| 4168 WebContentsImpl* WebContentsImpl::GetFocusedWebContents() { |
| 4169 // There is no inner or outer web contents. |
| 4170 if (!node_) |
| 4171 return this; |
| 4172 |
| 4173 // If we've found root by iterating through outer WebContents, root must have |
| 4174 // a valid node_ since the inner WebContents will have created one when |
| 4175 // connecting. |
| 4176 return GetOutermostWebContents()->node_->focused_web_contents(); |
| 4177 } |
| 4178 |
| 4179 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { |
| 4180 WebContentsImpl* root = this; |
| 4181 while (root->GetOuterWebContents()) |
| 4182 root = root->GetOuterWebContents(); |
| 4183 return root; |
| 4184 } |
| 4185 |
| 4138 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { | 4186 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { |
| 4139 // Don't send notifications if we are just creating a swapped-out RVH for | 4187 // Don't send notifications if we are just creating a swapped-out RVH for |
| 4140 // the opener chain. These won't be used for view-source or WebUI, so it's | 4188 // the opener chain. These won't be used for view-source or WebUI, so it's |
| 4141 // ok to return early. | 4189 // ok to return early. |
| 4142 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) | 4190 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) |
| 4143 return; | 4191 return; |
| 4144 | 4192 |
| 4145 if (delegate_) | 4193 if (delegate_) |
| 4146 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); | 4194 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); |
| 4147 | 4195 |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4535 GetSiteInstance()); | 4583 GetSiteInstance()); |
| 4536 } else { | 4584 } else { |
| 4537 RenderFrameHostImpl* source_rfhi = | 4585 RenderFrameHostImpl* source_rfhi = |
| 4538 static_cast<RenderFrameHostImpl*>(source_rfh); | 4586 static_cast<RenderFrameHostImpl*>(source_rfh); |
| 4539 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies( | 4587 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies( |
| 4540 GetSiteInstance(), nullptr); | 4588 GetSiteInstance(), nullptr); |
| 4541 } | 4589 } |
| 4542 } | 4590 } |
| 4543 } | 4591 } |
| 4544 | 4592 |
| 4593 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, |
| 4594 SiteInstance* source) { |
| 4595 // 1. Find old focused frame and unfocus it. |
| 4596 // 2. Focus the new frame in the current FrameTree. |
| 4597 // 3. Set current WebContents as focused. |
| 4598 WebContentsImpl* old_focused_contents = GetFocusedWebContents(); |
| 4599 if (old_focused_contents != this) { |
| 4600 // Focus is moving between frame trees, unfocus the frame in the old tree. |
| 4601 old_focused_contents->frame_tree_.SetFocusedFrame(nullptr, source); |
| 4602 GetOutermostWebContents()->node_->SetFocusedWebContents(this); |
| 4603 } |
| 4604 |
| 4605 frame_tree_.SetFocusedFrame(node, source); |
| 4606 |
| 4607 // TODO(avallee): Remove this once page focus is fixed. |
| 4608 RenderWidgetHostImpl* rwh = node->current_frame_host()->GetRenderWidgetHost(); |
| 4609 if (rwh && old_focused_contents != this && |
| 4610 BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) |
| 4611 rwh->Focus(); |
| 4612 } |
| 4613 |
| 4545 bool WebContentsImpl::AddMessageToConsole(int32_t level, | 4614 bool WebContentsImpl::AddMessageToConsole(int32_t level, |
| 4546 const base::string16& message, | 4615 const base::string16& message, |
| 4547 int32_t line_no, | 4616 int32_t line_no, |
| 4548 const base::string16& source_id) { | 4617 const base::string16& source_id) { |
| 4549 if (!delegate_) | 4618 if (!delegate_) |
| 4550 return false; | 4619 return false; |
| 4551 return delegate_->AddMessageToConsole(this, level, message, line_no, | 4620 return delegate_->AddMessageToConsole(this, level, message, line_no, |
| 4552 source_id); | 4621 source_id); |
| 4553 } | 4622 } |
| 4554 | 4623 |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4912 if (node_ && node_->outer_web_contents()) | 4981 if (node_ && node_->outer_web_contents()) |
| 4913 return node_->outer_contents_frame_tree_node_id(); | 4982 return node_->outer_contents_frame_tree_node_id(); |
| 4914 | 4983 |
| 4915 return FrameTreeNode::kFrameTreeNodeInvalidId; | 4984 return FrameTreeNode::kFrameTreeNodeInvalidId; |
| 4916 } | 4985 } |
| 4917 | 4986 |
| 4918 RenderFrameHostManager* WebContentsImpl::GetRenderManager() const { | 4987 RenderFrameHostManager* WebContentsImpl::GetRenderManager() const { |
| 4919 return frame_tree_.root()->render_manager(); | 4988 return frame_tree_.root()->render_manager(); |
| 4920 } | 4989 } |
| 4921 | 4990 |
| 4922 WebContentsImpl* WebContentsImpl::GetOuterWebContents() { | |
| 4923 if (BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) { | |
| 4924 if (node_) | |
| 4925 return node_->outer_web_contents(); | |
| 4926 } else { | |
| 4927 if (GetBrowserPluginGuest()) | |
| 4928 return GetBrowserPluginGuest()->embedder_web_contents(); | |
| 4929 } | |
| 4930 return nullptr; | |
| 4931 } | |
| 4932 | |
| 4933 BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const { | 4991 BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const { |
| 4934 return browser_plugin_guest_.get(); | 4992 return browser_plugin_guest_.get(); |
| 4935 } | 4993 } |
| 4936 | 4994 |
| 4937 void WebContentsImpl::SetBrowserPluginGuest(BrowserPluginGuest* guest) { | 4995 void WebContentsImpl::SetBrowserPluginGuest(BrowserPluginGuest* guest) { |
| 4938 CHECK(!browser_plugin_guest_); | 4996 CHECK(!browser_plugin_guest_); |
| 4939 CHECK(guest); | 4997 CHECK(guest); |
| 4940 browser_plugin_guest_.reset(guest); | 4998 browser_plugin_guest_.reset(guest); |
| 4941 } | 4999 } |
| 4942 | 5000 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4980 if (controller) { | 5038 if (controller) { |
| 4981 web_ui->AddMessageHandler(new GenericHandler()); | 5039 web_ui->AddMessageHandler(new GenericHandler()); |
| 4982 web_ui->SetController(controller); | 5040 web_ui->SetController(controller); |
| 4983 return web_ui; | 5041 return web_ui; |
| 4984 } | 5042 } |
| 4985 | 5043 |
| 4986 delete web_ui; | 5044 delete web_ui; |
| 4987 return NULL; | 5045 return NULL; |
| 4988 } | 5046 } |
| 4989 | 5047 |
| 4990 // TODO(paulmeyer): This method will not be used until find-in-page across | |
| 4991 // GuestViews is implemented. | |
| 4992 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { | |
| 4993 // Find the outer-most WebContents. | |
| 4994 WebContentsImpl* outermost_web_contents = this; | |
| 4995 while (outermost_web_contents->node_ && | |
| 4996 outermost_web_contents->node_->outer_web_contents()) { | |
| 4997 outermost_web_contents = | |
| 4998 outermost_web_contents->node_->outer_web_contents(); | |
| 4999 } | |
| 5000 return outermost_web_contents; | |
| 5001 } | |
| 5002 | |
| 5003 FindRequestManager* WebContentsImpl::GetOrCreateFindRequestManager() { | 5048 FindRequestManager* WebContentsImpl::GetOrCreateFindRequestManager() { |
| 5004 // TODO(paulmeyer): This method will need to access (or potentially create) | 5049 // TODO(paulmeyer): This method will need to access (or potentially create) |
| 5005 // the FindRequestManager in the outermost WebContents once find-in-page | 5050 // the FindRequestManager in the outermost WebContents once find-in-page |
| 5006 // across GuestViews is implemented. | 5051 // across GuestViews is implemented. |
| 5007 if (!find_request_manager_) | 5052 if (!find_request_manager_) |
| 5008 find_request_manager_.reset(new FindRequestManager(this)); | 5053 find_request_manager_.reset(new FindRequestManager(this)); |
| 5009 | 5054 |
| 5010 return find_request_manager_.get(); | 5055 return find_request_manager_.get(); |
| 5011 } | 5056 } |
| 5012 | 5057 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5085 for (RenderViewHost* render_view_host : render_view_host_set) | 5130 for (RenderViewHost* render_view_host : render_view_host_set) |
| 5086 render_view_host->OnWebkitPreferencesChanged(); | 5131 render_view_host->OnWebkitPreferencesChanged(); |
| 5087 } | 5132 } |
| 5088 | 5133 |
| 5089 void WebContentsImpl::SetJavaScriptDialogManagerForTesting( | 5134 void WebContentsImpl::SetJavaScriptDialogManagerForTesting( |
| 5090 JavaScriptDialogManager* dialog_manager) { | 5135 JavaScriptDialogManager* dialog_manager) { |
| 5091 dialog_manager_ = dialog_manager; | 5136 dialog_manager_ = dialog_manager; |
| 5092 } | 5137 } |
| 5093 | 5138 |
| 5094 } // namespace content | 5139 } // namespace content |
| OLD | NEW |