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

Side by Side Diff: content/browser/web_contents/web_contents_impl.cc

Issue 1934703002: Fix keyboard focus for OOPIF-<webview>. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed test flakiness and comments in PS 7,8. Created 4 years, 6 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
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698