| 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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 identifier(identifier) { | 330 identifier(identifier) { |
| 331 } | 331 } |
| 332 | 332 |
| 333 WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() { | 333 WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() { |
| 334 } | 334 } |
| 335 | 335 |
| 336 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- | 336 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- |
| 337 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() | 337 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() |
| 338 : outer_web_contents_(nullptr), | 338 : outer_web_contents_(nullptr), |
| 339 outer_contents_frame_tree_node_id_( | 339 outer_contents_frame_tree_node_id_( |
| 340 FrameTreeNode::kFrameTreeNodeInvalidId) { | 340 FrameTreeNode::kFrameTreeNodeInvalidId), |
| 341 } | 341 focused_web_contents_(nullptr) {} |
| 342 | 342 |
| 343 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { | 343 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { |
| 344 // Remove child pointer from our parent. | 344 // Remove child pointer from our parent. |
| 345 if (outer_web_contents_) { | 345 if (outer_web_contents_) { |
| 346 ChildrenSet& child_ptrs_in_parent = | 346 ChildrenSet& child_ptrs_in_parent = |
| 347 outer_web_contents_->node_->inner_web_contents_tree_nodes_; | 347 outer_web_contents_->node_->inner_web_contents_tree_nodes_; |
| 348 ChildrenSet::iterator iter = child_ptrs_in_parent.find(this); | 348 ChildrenSet::iterator iter = child_ptrs_in_parent.find(this); |
| 349 DCHECK(iter != child_ptrs_in_parent.end()); | 349 DCHECK(iter != child_ptrs_in_parent.end()); |
| 350 child_ptrs_in_parent.erase(this); | 350 child_ptrs_in_parent.erase(iter); |
| 351 } | 351 } |
| 352 | 352 |
| 353 // Remove parent pointers from our children. | 353 // Remove parent pointers from our children. |
| 354 // TODO(lazyboy): We should destroy the children WebContentses too. If the | 354 // TODO(lazyboy): We should destroy the children WebContentses too. If the |
| 355 // children do not manage their own lifetime, then we would leak their | 355 // children do not manage their own lifetime, then we would leak their |
| 356 // WebContentses. | 356 // WebContentses. |
| 357 for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_) | 357 for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_) |
| 358 child->outer_web_contents_ = nullptr; | 358 child->outer_web_contents_ = nullptr; |
| 359 } | 359 } |
| 360 | 360 |
| 361 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( | 361 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( |
| 362 WebContentsImpl* outer_web_contents, | 362 WebContentsImpl* outer_web_contents, |
| 363 RenderFrameHostImpl* outer_contents_frame) { | 363 RenderFrameHostImpl* outer_contents_frame) { |
| 364 DCHECK(!focused_web_contents_) << "Should not attach a root node."; |
| 364 outer_web_contents_ = outer_web_contents; | 365 outer_web_contents_ = outer_web_contents; |
| 365 outer_contents_frame_tree_node_id_ = | 366 outer_contents_frame_tree_node_id_ = |
| 366 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); | 367 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); |
| 367 | 368 |
| 368 if (!outer_web_contents_->node_) | 369 if (!outer_web_contents_->node_) { |
| 370 // This will only be reached when creating a new WebContents tree. |
| 371 // Initialize the root of this tree and set it as focused. |
| 369 outer_web_contents_->node_.reset(new WebContentsTreeNode()); | 372 outer_web_contents_->node_.reset(new WebContentsTreeNode()); |
| 373 outer_web_contents_->node_->SetFocusedWebContents(outer_web_contents_); |
| 374 } |
| 370 | 375 |
| 371 outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this); | 376 outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this); |
| 372 } | 377 } |
| 373 | 378 |
| 379 void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents( |
| 380 WebContentsImpl* web_contents) { |
| 381 DCHECK(!outer_web_contents()) |
| 382 << "Only the outermost WebContents tracks focus."; |
| 383 focused_web_contents_ = web_contents; |
| 384 } |
| 385 |
| 374 // WebContentsImpl ------------------------------------------------------------- | 386 // WebContentsImpl ------------------------------------------------------------- |
| 375 | 387 |
| 376 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) | 388 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) |
| 377 : delegate_(NULL), | 389 : delegate_(NULL), |
| 378 controller_(this, browser_context), | 390 controller_(this, browser_context), |
| 379 render_view_host_delegate_view_(NULL), | 391 render_view_host_delegate_view_(NULL), |
| 380 created_with_opener_(false), | 392 created_with_opener_(false), |
| 381 frame_tree_(new NavigatorImpl(&controller_, this), | 393 frame_tree_(new NavigatorImpl(&controller_, this), |
| 382 this, | 394 this, |
| 383 this, | 395 this, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 #endif | 451 #endif |
| 440 loader_io_thread_notifier_.reset(new LoaderIOThreadNotifier(this)); | 452 loader_io_thread_notifier_.reset(new LoaderIOThreadNotifier(this)); |
| 441 wake_lock_service_context_.reset(new WakeLockServiceContext(this)); | 453 wake_lock_service_context_.reset(new WakeLockServiceContext(this)); |
| 442 } | 454 } |
| 443 | 455 |
| 444 WebContentsImpl::~WebContentsImpl() { | 456 WebContentsImpl::~WebContentsImpl() { |
| 445 is_being_destroyed_ = true; | 457 is_being_destroyed_ = true; |
| 446 | 458 |
| 447 rwh_input_event_router_.reset(); | 459 rwh_input_event_router_.reset(); |
| 448 | 460 |
| 461 WebContentsImpl* outermost = GetOutermostWebContents(); |
| 462 if (GetFocusedWebContents() == this && this != outermost) { |
| 463 // If the current WebContents is in focus, unset it. |
| 464 outermost->node_->SetFocusedWebContents(outermost); |
| 465 } |
| 466 |
| 449 for (FrameTreeNode* node : frame_tree_.Nodes()) { | 467 for (FrameTreeNode* node : frame_tree_.Nodes()) { |
| 450 // Delete all RFHs pending shutdown, which will lead the corresponding RVHs | 468 // Delete all RFHs pending shutdown, which will lead the corresponding RVHs |
| 451 // to be shutdown and be deleted as well. | 469 // to be shutdown and be deleted as well. |
| 452 node->render_manager()->ClearRFHsPendingShutdown(); | 470 node->render_manager()->ClearRFHsPendingShutdown(); |
| 453 node->render_manager()->ClearWebUIInstances(); | 471 node->render_manager()->ClearWebUIInstances(); |
| 454 } | 472 } |
| 455 | 473 |
| 456 for (RenderWidgetHostImpl* widget : created_widgets_) | 474 for (RenderWidgetHostImpl* widget : created_widgets_) |
| 457 widget->DetachDelegate(); | 475 widget->DetachDelegate(); |
| 458 created_widgets_.clear(); | 476 created_widgets_.clear(); |
| (...skipping 1344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1803 RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost( | 1821 RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost( |
| 1804 RenderWidgetHostImpl* receiving_widget) { | 1822 RenderWidgetHostImpl* receiving_widget) { |
| 1805 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible()) | 1823 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible()) |
| 1806 return receiving_widget; | 1824 return receiving_widget; |
| 1807 | 1825 |
| 1808 // Events for widgets other than the main frame (e.g., popup menus) should be | 1826 // Events for widgets other than the main frame (e.g., popup menus) should be |
| 1809 // forwarded directly to the widget they arrived on. | 1827 // forwarded directly to the widget they arrived on. |
| 1810 if (receiving_widget != GetMainFrame()->GetRenderWidgetHost()) | 1828 if (receiving_widget != GetMainFrame()->GetRenderWidgetHost()) |
| 1811 return receiving_widget; | 1829 return receiving_widget; |
| 1812 | 1830 |
| 1813 FrameTreeNode* focused_frame = frame_tree_.GetFocusedFrame(); | 1831 FrameTreeNode* focused_frame = |
| 1832 GetFocusedWebContents()->frame_tree_.GetFocusedFrame(); |
| 1814 if (!focused_frame) | 1833 if (!focused_frame) |
| 1815 return receiving_widget; | 1834 return receiving_widget; |
| 1816 | 1835 |
| 1817 // The view may be null if a subframe's renderer process has crashed while | 1836 // The view may be null if a subframe's renderer process has crashed while |
| 1818 // the subframe has focus. Drop the event in that case. Do not give | 1837 // the subframe has focus. Drop the event in that case. Do not give |
| 1819 // it to the main frame, so that the user doesn't unexpectedly type into the | 1838 // it to the main frame, so that the user doesn't unexpectedly type into the |
| 1820 // wrong frame if a focused subframe renderer crashes while they type. | 1839 // wrong frame if a focused subframe renderer crashes while they type. |
| 1821 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView(); | 1840 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView(); |
| 1822 if (!view) | 1841 if (!view) |
| 1823 return nullptr; | 1842 return nullptr; |
| (...skipping 2344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4168 if (delegate_) | 4187 if (delegate_) |
| 4169 return delegate_->GetRootWindowResizerRect(); | 4188 return delegate_->GetRootWindowResizerRect(); |
| 4170 return gfx::Rect(); | 4189 return gfx::Rect(); |
| 4171 } | 4190 } |
| 4172 | 4191 |
| 4173 void WebContentsImpl::RemoveBrowserPluginEmbedder() { | 4192 void WebContentsImpl::RemoveBrowserPluginEmbedder() { |
| 4174 if (browser_plugin_embedder_) | 4193 if (browser_plugin_embedder_) |
| 4175 browser_plugin_embedder_.reset(); | 4194 browser_plugin_embedder_.reset(); |
| 4176 } | 4195 } |
| 4177 | 4196 |
| 4197 WebContentsImpl* WebContentsImpl::GetOuterWebContents() { |
| 4198 if (BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) { |
| 4199 if (node_) |
| 4200 return node_->outer_web_contents(); |
| 4201 } else { |
| 4202 if (GetBrowserPluginGuest()) |
| 4203 return GetBrowserPluginGuest()->embedder_web_contents(); |
| 4204 } |
| 4205 return nullptr; |
| 4206 } |
| 4207 |
| 4208 WebContentsImpl* WebContentsImpl::GetFocusedWebContents() { |
| 4209 // There is no inner or outer web contents. |
| 4210 if (!node_ && !GetBrowserPluginGuest()) |
| 4211 return this; |
| 4212 |
| 4213 // We may need to create a node_ on the outermost contents in the |
| 4214 // BrowserPlugin case. |
| 4215 WebContentsImpl* outermost = GetOutermostWebContents(); |
| 4216 if (!outermost->node_) { |
| 4217 outermost->node_.reset(new WebContentsTreeNode()); |
| 4218 outermost->node_->SetFocusedWebContents(outermost); |
| 4219 } |
| 4220 return outermost->node_->focused_web_contents(); |
| 4221 } |
| 4222 |
| 4223 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { |
| 4224 WebContentsImpl* root = this; |
| 4225 while (root->GetOuterWebContents()) |
| 4226 root = root->GetOuterWebContents(); |
| 4227 return root; |
| 4228 } |
| 4229 |
| 4178 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { | 4230 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { |
| 4179 // Don't send notifications if we are just creating a swapped-out RVH for | 4231 // Don't send notifications if we are just creating a swapped-out RVH for |
| 4180 // the opener chain. These won't be used for view-source or WebUI, so it's | 4232 // the opener chain. These won't be used for view-source or WebUI, so it's |
| 4181 // ok to return early. | 4233 // ok to return early. |
| 4182 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) | 4234 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) |
| 4183 return; | 4235 return; |
| 4184 | 4236 |
| 4185 if (delegate_) | 4237 if (delegate_) |
| 4186 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); | 4238 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); |
| 4187 | 4239 |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4570 GetSiteInstance()); | 4622 GetSiteInstance()); |
| 4571 } else { | 4623 } else { |
| 4572 RenderFrameHostImpl* source_rfhi = | 4624 RenderFrameHostImpl* source_rfhi = |
| 4573 static_cast<RenderFrameHostImpl*>(source_rfh); | 4625 static_cast<RenderFrameHostImpl*>(source_rfh); |
| 4574 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies( | 4626 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies( |
| 4575 GetSiteInstance(), nullptr); | 4627 GetSiteInstance(), nullptr); |
| 4576 } | 4628 } |
| 4577 } | 4629 } |
| 4578 } | 4630 } |
| 4579 | 4631 |
| 4632 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, |
| 4633 SiteInstance* source) { |
| 4634 if (!BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) { |
| 4635 frame_tree_.SetFocusedFrame(node, source); |
| 4636 return; |
| 4637 } |
| 4638 |
| 4639 // 1. Find old focused frame and unfocus it. |
| 4640 // 2. Focus the new frame in the current FrameTree. |
| 4641 // 3. Set current WebContents as focused. |
| 4642 WebContentsImpl* old_focused_contents = GetFocusedWebContents(); |
| 4643 if (old_focused_contents != this) { |
| 4644 // Focus is moving between frame trees, unfocus the frame in the old tree. |
| 4645 old_focused_contents->frame_tree_.SetFocusedFrame(nullptr, source); |
| 4646 GetOutermostWebContents()->node_->SetFocusedWebContents(this); |
| 4647 } |
| 4648 |
| 4649 frame_tree_.SetFocusedFrame(node, source); |
| 4650 |
| 4651 // TODO(avallee): Remove this once page focus is fixed. |
| 4652 RenderWidgetHostImpl* rwh = node->current_frame_host()->GetRenderWidgetHost(); |
| 4653 if (rwh && old_focused_contents != this && |
| 4654 BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) |
| 4655 rwh->Focus(); |
| 4656 } |
| 4657 |
| 4580 bool WebContentsImpl::AddMessageToConsole(int32_t level, | 4658 bool WebContentsImpl::AddMessageToConsole(int32_t level, |
| 4581 const base::string16& message, | 4659 const base::string16& message, |
| 4582 int32_t line_no, | 4660 int32_t line_no, |
| 4583 const base::string16& source_id) { | 4661 const base::string16& source_id) { |
| 4584 if (!delegate_) | 4662 if (!delegate_) |
| 4585 return false; | 4663 return false; |
| 4586 return delegate_->AddMessageToConsole(this, level, message, line_no, | 4664 return delegate_->AddMessageToConsole(this, level, message, line_no, |
| 4587 source_id); | 4665 source_id); |
| 4588 } | 4666 } |
| 4589 | 4667 |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4953 if (node_ && node_->outer_web_contents()) | 5031 if (node_ && node_->outer_web_contents()) |
| 4954 return node_->outer_contents_frame_tree_node_id(); | 5032 return node_->outer_contents_frame_tree_node_id(); |
| 4955 | 5033 |
| 4956 return FrameTreeNode::kFrameTreeNodeInvalidId; | 5034 return FrameTreeNode::kFrameTreeNodeInvalidId; |
| 4957 } | 5035 } |
| 4958 | 5036 |
| 4959 RenderFrameHostManager* WebContentsImpl::GetRenderManager() const { | 5037 RenderFrameHostManager* WebContentsImpl::GetRenderManager() const { |
| 4960 return frame_tree_.root()->render_manager(); | 5038 return frame_tree_.root()->render_manager(); |
| 4961 } | 5039 } |
| 4962 | 5040 |
| 4963 WebContentsImpl* WebContentsImpl::GetOuterWebContents() { | |
| 4964 if (BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) { | |
| 4965 if (node_) | |
| 4966 return node_->outer_web_contents(); | |
| 4967 } else { | |
| 4968 if (GetBrowserPluginGuest()) | |
| 4969 return GetBrowserPluginGuest()->embedder_web_contents(); | |
| 4970 } | |
| 4971 return nullptr; | |
| 4972 } | |
| 4973 | |
| 4974 BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const { | 5041 BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const { |
| 4975 return browser_plugin_guest_.get(); | 5042 return browser_plugin_guest_.get(); |
| 4976 } | 5043 } |
| 4977 | 5044 |
| 4978 void WebContentsImpl::SetBrowserPluginGuest(BrowserPluginGuest* guest) { | 5045 void WebContentsImpl::SetBrowserPluginGuest(BrowserPluginGuest* guest) { |
| 4979 CHECK(!browser_plugin_guest_); | 5046 CHECK(!browser_plugin_guest_); |
| 4980 CHECK(guest); | 5047 CHECK(guest); |
| 4981 browser_plugin_guest_.reset(guest); | 5048 browser_plugin_guest_.reset(guest); |
| 4982 } | 5049 } |
| 4983 | 5050 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5021 if (controller) { | 5088 if (controller) { |
| 5022 web_ui->AddMessageHandler(new GenericHandler()); | 5089 web_ui->AddMessageHandler(new GenericHandler()); |
| 5023 web_ui->SetController(controller); | 5090 web_ui->SetController(controller); |
| 5024 return web_ui; | 5091 return web_ui; |
| 5025 } | 5092 } |
| 5026 | 5093 |
| 5027 delete web_ui; | 5094 delete web_ui; |
| 5028 return NULL; | 5095 return NULL; |
| 5029 } | 5096 } |
| 5030 | 5097 |
| 5031 // TODO(paulmeyer): This method will not be used until find-in-page across | |
| 5032 // GuestViews is implemented. | |
| 5033 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { | |
| 5034 // Find the outer-most WebContents. | |
| 5035 WebContentsImpl* outermost_web_contents = this; | |
| 5036 while (outermost_web_contents->node_ && | |
| 5037 outermost_web_contents->node_->outer_web_contents()) { | |
| 5038 outermost_web_contents = | |
| 5039 outermost_web_contents->node_->outer_web_contents(); | |
| 5040 } | |
| 5041 return outermost_web_contents; | |
| 5042 } | |
| 5043 | |
| 5044 FindRequestManager* WebContentsImpl::GetOrCreateFindRequestManager() { | 5098 FindRequestManager* WebContentsImpl::GetOrCreateFindRequestManager() { |
| 5045 // TODO(paulmeyer): This method will need to access (or potentially create) | 5099 // TODO(paulmeyer): This method will need to access (or potentially create) |
| 5046 // the FindRequestManager in the outermost WebContents once find-in-page | 5100 // the FindRequestManager in the outermost WebContents once find-in-page |
| 5047 // across GuestViews is implemented. | 5101 // across GuestViews is implemented. |
| 5048 if (!find_request_manager_) | 5102 if (!find_request_manager_) |
| 5049 find_request_manager_.reset(new FindRequestManager(this)); | 5103 find_request_manager_.reset(new FindRequestManager(this)); |
| 5050 | 5104 |
| 5051 return find_request_manager_.get(); | 5105 return find_request_manager_.get(); |
| 5052 } | 5106 } |
| 5053 | 5107 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5153 for (RenderViewHost* render_view_host : render_view_host_set) | 5207 for (RenderViewHost* render_view_host : render_view_host_set) |
| 5154 render_view_host->OnWebkitPreferencesChanged(); | 5208 render_view_host->OnWebkitPreferencesChanged(); |
| 5155 } | 5209 } |
| 5156 | 5210 |
| 5157 void WebContentsImpl::SetJavaScriptDialogManagerForTesting( | 5211 void WebContentsImpl::SetJavaScriptDialogManagerForTesting( |
| 5158 JavaScriptDialogManager* dialog_manager) { | 5212 JavaScriptDialogManager* dialog_manager) { |
| 5159 dialog_manager_ = dialog_manager; | 5213 dialog_manager_ = dialog_manager; |
| 5160 } | 5214 } |
| 5161 | 5215 |
| 5162 } // namespace content | 5216 } // namespace content |
| OLD | NEW |