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

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

Issue 10171018: Create swapped-out opener RVHs after a process swap. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove parameter comments. Created 8 years, 7 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 | Annotate | Revision Log
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/render_view_host_manager.h" 5 #include "content/browser/web_contents/render_view_host_manager.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 void RenderViewHostManager::Init(content::BrowserContext* browser_context, 68 void RenderViewHostManager::Init(content::BrowserContext* browser_context,
69 SiteInstance* site_instance, 69 SiteInstance* site_instance,
70 int routing_id) { 70 int routing_id) {
71 // Create a RenderViewHost, once we have an instance. It is important to 71 // Create a RenderViewHost, once we have an instance. It is important to
72 // immediately give this SiteInstance to a RenderViewHost so that it is 72 // immediately give this SiteInstance to a RenderViewHost so that it is
73 // ref counted. 73 // ref counted.
74 if (!site_instance) 74 if (!site_instance)
75 site_instance = SiteInstance::Create(browser_context); 75 site_instance = SiteInstance::Create(browser_context);
76 render_view_host_ = static_cast<RenderViewHostImpl*>( 76 render_view_host_ = static_cast<RenderViewHostImpl*>(
77 RenderViewHostFactory::Create( 77 RenderViewHostFactory::Create(
78 site_instance, render_view_delegate_, routing_id, delegate_-> 78 site_instance, render_view_delegate_, routing_id, false, delegate_->
79 GetControllerForRenderManager().GetSessionStorageNamespace())); 79 GetControllerForRenderManager().GetSessionStorageNamespace()));
80 80
81 // Keep track of renderer processes as they start to shut down. 81 // Keep track of renderer processes as they start to shut down.
82 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSING, 82 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSING,
83 content::NotificationService::AllSources()); 83 content::NotificationService::AllSources());
84 } 84 }
85 85
86 RenderViewHostImpl* RenderViewHostManager::current_host() const { 86 RenderViewHostImpl* RenderViewHostManager::current_host() const {
87 return render_view_host_; 87 return render_view_host_;
88 } 88 }
(...skipping 16 matching lines...) Expand all
105 if (!dest_render_view_host) 105 if (!dest_render_view_host)
106 return NULL; // We weren't able to create a pending render view host. 106 return NULL; // We weren't able to create a pending render view host.
107 107
108 // If the current render_view_host_ isn't live, we should create it so 108 // If the current render_view_host_ isn't live, we should create it so
109 // that we don't show a sad tab while the dest_render_view_host fetches 109 // that we don't show a sad tab while the dest_render_view_host fetches
110 // its first page. (Bug 1145340) 110 // its first page. (Bug 1145340)
111 if (dest_render_view_host != render_view_host_ && 111 if (dest_render_view_host != render_view_host_ &&
112 !render_view_host_->IsRenderViewLive()) { 112 !render_view_host_->IsRenderViewLive()) {
113 // Note: we don't call InitRenderView here because we are navigating away 113 // Note: we don't call InitRenderView here because we are navigating away
114 // soon anyway, and we don't have the NavigationEntry for this host. 114 // soon anyway, and we don't have the NavigationEntry for this host.
115 delegate_->CreateRenderViewForRenderManager(render_view_host_); 115 delegate_->CreateRenderViewForRenderManager(render_view_host_,
116 MSG_ROUTING_NONE);
116 } 117 }
117 118
118 // If the renderer crashed, then try to create a new one to satisfy this 119 // If the renderer crashed, then try to create a new one to satisfy this
119 // navigation request. 120 // navigation request.
120 if (!dest_render_view_host->IsRenderViewLive()) { 121 if (!dest_render_view_host->IsRenderViewLive()) {
121 if (!InitRenderView(dest_render_view_host, entry)) 122 if (!InitRenderView(dest_render_view_host, MSG_ROUTING_NONE))
122 return NULL; 123 return NULL;
123 124
124 // Now that we've created a new renderer, be sure to hide it if it isn't 125 // Now that we've created a new renderer, be sure to hide it if it isn't
125 // our primary one. Otherwise, we might crash if we try to call Show() 126 // our primary one. Otherwise, we might crash if we try to call Show()
126 // on it later. 127 // on it later.
127 if (dest_render_view_host != render_view_host_ && 128 if (dest_render_view_host != render_view_host_ &&
128 dest_render_view_host->GetView()) { 129 dest_render_view_host->GetView()) {
129 dest_render_view_host->GetView()->Hide(); 130 dest_render_view_host->GetView()->Hide();
130 } else { 131 } else {
131 // This is our primary renderer, notify here as we won't be calling 132 // This is our primary renderer, notify here as we won't be calling
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 // a single BrowsingInstance for all pages of a certain type (e.g., New Tab 537 // a single BrowsingInstance for all pages of a certain type (e.g., New Tab
537 // Pages), keeping them in the same process. When you navigate away from 538 // Pages), keeping them in the same process. When you navigate away from
538 // that page, we want to explicity ignore that BrowsingInstance and group 539 // that page, we want to explicity ignore that BrowsingInstance and group
539 // this page into the appropriate SiteInstance for its URL. 540 // this page into the appropriate SiteInstance for its URL.
540 return SiteInstance::CreateForURL(browser_context, dest_url); 541 return SiteInstance::CreateForURL(browser_context, dest_url);
541 } else { 542 } else {
542 // Start the new renderer in a new SiteInstance, but in the current 543 // Start the new renderer in a new SiteInstance, but in the current
543 // BrowsingInstance. It is important to immediately give this new 544 // BrowsingInstance. It is important to immediately give this new
544 // SiteInstance to a RenderViewHost (if it is different than our current 545 // SiteInstance to a RenderViewHost (if it is different than our current
545 // SiteInstance), so that it is ref counted. This will happen in 546 // SiteInstance), so that it is ref counted. This will happen in
546 // CreatePendingRenderView. 547 // CreateRenderView.
547 return curr_instance->GetRelatedSiteInstance(dest_url); 548 return curr_instance->GetRelatedSiteInstance(dest_url);
548 } 549 }
549 } 550 }
550 551
551 bool RenderViewHostManager::CreatePendingRenderView( 552 int RenderViewHostManager::CreateRenderView(
552 const NavigationEntryImpl& entry, SiteInstance* instance) { 553 SiteInstance* instance,
553 NavigationEntry* curr_entry = 554 int opener_route_id,
554 delegate_->GetControllerForRenderManager().GetLastCommittedEntry(); 555 bool swapped_out) {
555 if (curr_entry) { 556 CHECK(instance);
556 DCHECK(!curr_entry->GetContentState().empty()); 557
557 // TODO(creis): Should send a message to the RenderView to let it know 558 // Check if we've already created an RVH for this SiteInstance. If so, try
558 // we're about to switch away, so that it sends an UpdateState message. 559 // to re-use the existing one, which has already been initialized. We'll
560 // remove it from the list of swapped out hosts if it commits.
561 RenderViewHostImpl* new_render_view_host = static_cast<RenderViewHostImpl*>(
562 GetSwappedOutRenderViewHost(instance));
563 if (new_render_view_host) {
564 // Prevent the process from exiting while we're trying to use it.
565 new_render_view_host->GetProcess()->AddPendingView();
566 } else {
567 // Create a new RenderViewHost if we don't find an existing one.
568 new_render_view_host = static_cast<RenderViewHostImpl*>(
569 RenderViewHostFactory::Create(instance,
570 render_view_delegate_, MSG_ROUTING_NONE, swapped_out, delegate_->
571 GetControllerForRenderManager().GetSessionStorageNamespace()));
572
573 // Prevent the process from exiting while we're trying to use it.
574 new_render_view_host->GetProcess()->AddPendingView();
575
576 // Store the new RVH as swapped out if necessary.
577 if (swapped_out)
578 swapped_out_hosts_[instance->GetId()] = new_render_view_host;
579
580 bool success = InitRenderView(new_render_view_host, opener_route_id);
581 if (success) {
582 // Don't show the view until we get a DidNavigate from it.
583 new_render_view_host->GetView()->Hide();
584 } else if (!swapped_out) {
585 CancelPending();
586 }
559 } 587 }
560 588
561 // Check if we've already created an RVH for this SiteInstance. 589 // Use this as our new pending RVH if it isn't swapped out.
562 CHECK(instance); 590 if (!swapped_out)
563 RenderViewHostMap::iterator iter = 591 pending_render_view_host_ = new_render_view_host;
564 swapped_out_hosts_.find(instance->GetId());
565 if (iter != swapped_out_hosts_.end()) {
566 // Re-use the existing RenderViewHost, which has already been initialized.
567 // We'll remove it from the list of swapped out hosts if it commits.
568 pending_render_view_host_ = iter->second;
569 592
570 // Prevent the process from exiting while we're trying to use it. 593 return new_render_view_host->GetRoutingID();
571 pending_render_view_host_->GetProcess()->AddPendingView();
572
573 return true;
574 }
575
576 pending_render_view_host_ = static_cast<RenderViewHostImpl*>(
577 RenderViewHostFactory::Create(
578 instance, render_view_delegate_, MSG_ROUTING_NONE, delegate_->
579 GetControllerForRenderManager().GetSessionStorageNamespace()));
580
581 // Prevent the process from exiting while we're trying to use it.
582 pending_render_view_host_->GetProcess()->AddPendingView();
583
584 bool success = InitRenderView(pending_render_view_host_, entry);
585 if (success) {
586 // Don't show the view until we get a DidNavigate from it.
587 pending_render_view_host_->GetView()->Hide();
588 } else {
589 CancelPending();
590 }
591 return success;
592 } 594 }
593 595
594 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host, 596 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host,
595 const NavigationEntryImpl& entry) { 597 int opener_route_id) {
596 // If the pending navigation is to a WebUI, tell the RenderView about any 598 // If the pending navigation is to a WebUI, tell the RenderView about any
597 // bindings it will need enabled. 599 // bindings it will need enabled.
598 if (pending_web_ui()) 600 if (pending_web_ui())
599 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); 601 render_view_host->AllowBindings(pending_web_ui()->GetBindings());
600 602
601 return delegate_->CreateRenderViewForRenderManager(render_view_host); 603 return delegate_->CreateRenderViewForRenderManager(render_view_host,
604 opener_route_id);
602 } 605 }
603 606
604 void RenderViewHostManager::CommitPending() { 607 void RenderViewHostManager::CommitPending() {
605 // First check whether we're going to want to focus the location bar after 608 // First check whether we're going to want to focus the location bar after
606 // this commit. We do this now because the navigation hasn't formally 609 // this commit. We do this now because the navigation hasn't formally
607 // committed yet, so if we've already cleared |pending_web_ui_| the call chain 610 // committed yet, so if we've already cleared |pending_web_ui_| the call chain
608 // this triggers won't be able to figure out what's going on. 611 // this triggers won't be able to figure out what's going on.
609 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 612 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
610 613
611 // Next commit the Web UI, if any. Either replace |web_ui_| with 614 // Next commit the Web UI, if any. Either replace |web_ui_| with
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 // This will possibly create (set to NULL) a Web UI object for the pending 733 // This will possibly create (set to NULL) a Web UI object for the pending
731 // page. We'll use this later to give the page special access. This must 734 // page. We'll use this later to give the page special access. This must
732 // happen before the new renderer is created below so it will get bindings. 735 // happen before the new renderer is created below so it will get bindings.
733 // It must also happen after the above conditional call to CancelPending(), 736 // It must also happen after the above conditional call to CancelPending(),
734 // otherwise CancelPending may clear the pending_web_ui_ and the page will 737 // otherwise CancelPending may clear the pending_web_ui_ and the page will
735 // not have its bindings set appropriately. 738 // not have its bindings set appropriately.
736 pending_web_ui_.reset( 739 pending_web_ui_.reset(
737 delegate_->CreateWebUIForRenderManager(entry.GetURL())); 740 delegate_->CreateWebUIForRenderManager(entry.GetURL()));
738 pending_and_current_web_ui_.reset(); 741 pending_and_current_web_ui_.reset();
739 742
740 // Create a pending RVH and navigate it. 743 // Ensure that we have created RVHs for the new RVH's opener chain if
741 bool success = CreatePendingRenderView(entry, new_instance); 744 // we are staying in the same BrowsingInstance. This allows the pending RVH
742 if (!success) 745 // to send cross-process script calls to its opener(s).
746 int opener_route_id = MSG_ROUTING_NONE;
747 if (new_instance->IsRelatedSiteInstance(curr_instance)) {
748 opener_route_id =
749 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance);
750 }
751
752 // Create a non-swapped-out pending RVH with the given opener and navigate
753 // it.
754 int route_id = CreateRenderView(new_instance, opener_route_id, false);
755 if (route_id == MSG_ROUTING_NONE)
743 return NULL; 756 return NULL;
744 757
745 // Check if our current RVH is live before we set up a transition. 758 // Check if our current RVH is live before we set up a transition.
746 if (!render_view_host_->IsRenderViewLive()) { 759 if (!render_view_host_->IsRenderViewLive()) {
747 if (!cross_navigation_pending_) { 760 if (!cross_navigation_pending_) {
748 // The current RVH is not live. There's no reason to sit around with a 761 // The current RVH is not live. There's no reason to sit around with a
749 // sad tab or a newly created RVH while we wait for the pending RVH to 762 // sad tab or a newly created RVH while we wait for the pending RVH to
750 // navigate. Just switch to the pending RVH now and go back to non 763 // navigate. Just switch to the pending RVH now and go back to non
751 // cross-navigating (Note that we don't care about on{before}unload 764 // cross-navigating (Note that we don't care about on{before}unload
752 // handlers if the current RVH isn't live.) 765 // handlers if the current RVH isn't live.)
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 } 884 }
872 } 885 }
873 886
874 bool RenderViewHostManager::IsSwappedOut(RenderViewHost* rvh) { 887 bool RenderViewHostManager::IsSwappedOut(RenderViewHost* rvh) {
875 if (!rvh->GetSiteInstance()) 888 if (!rvh->GetSiteInstance())
876 return false; 889 return false;
877 890
878 return swapped_out_hosts_.find(rvh->GetSiteInstance()->GetId()) != 891 return swapped_out_hosts_.find(rvh->GetSiteInstance()->GetId()) !=
879 swapped_out_hosts_.end(); 892 swapped_out_hosts_.end();
880 } 893 }
894
895 RenderViewHost* RenderViewHostManager::GetSwappedOutRenderViewHost(
896 SiteInstance* instance) {
897 RenderViewHostMap::iterator iter = swapped_out_hosts_.find(instance->GetId());
898 if (iter != swapped_out_hosts_.end())
899 return iter->second;
900
901 return NULL;
902 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698