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

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: Misc cleanup 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 RenderViewHostImpl* render_view_host = render_view_host_; 56 RenderViewHostImpl* render_view_host = render_view_host_;
57 render_view_host_ = NULL; 57 render_view_host_ = NULL;
58 render_view_host->Shutdown(); 58 render_view_host->Shutdown();
59 59
60 // Shut down any swapped out RenderViewHosts. 60 // Shut down any swapped out RenderViewHosts.
61 for (RenderViewHostMap::iterator iter = swapped_out_hosts_.begin(); 61 for (RenderViewHostMap::iterator iter = swapped_out_hosts_.begin();
62 iter != swapped_out_hosts_.end(); 62 iter != swapped_out_hosts_.end();
63 ++iter) { 63 ++iter) {
64 iter->second->Shutdown(); 64 iter->second->Shutdown();
65 } 65 }
66
67 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSING,
Matt Perry 2012/05/01 20:45:17 Is this needed? See comment in web_contents_impl.c
Charlie Reis 2012/05/01 21:25:53 Ah, this one's not needed if registrar_ takes care
Charlie Reis 2012/05/01 21:41:46 Removed.
68 content::NotificationService::AllSources());
66 } 69 }
67 70
68 void RenderViewHostManager::Init(content::BrowserContext* browser_context, 71 void RenderViewHostManager::Init(content::BrowserContext* browser_context,
69 SiteInstance* site_instance, 72 SiteInstance* site_instance,
70 int routing_id) { 73 int routing_id) {
71 // Create a RenderViewHost, once we have an instance. It is important to 74 // Create a RenderViewHost, once we have an instance. It is important to
72 // immediately give this SiteInstance to a RenderViewHost so that it is 75 // immediately give this SiteInstance to a RenderViewHost so that it is
73 // ref counted. 76 // ref counted.
74 if (!site_instance) 77 if (!site_instance)
75 site_instance = SiteInstance::Create(browser_context); 78 site_instance = SiteInstance::Create(browser_context);
76 render_view_host_ = static_cast<RenderViewHostImpl*>( 79 render_view_host_ = static_cast<RenderViewHostImpl*>(
77 RenderViewHostFactory::Create( 80 RenderViewHostFactory::Create(
78 site_instance, render_view_delegate_, routing_id, delegate_-> 81 site_instance, render_view_delegate_, routing_id, false, delegate_->
79 GetControllerForRenderManager().GetSessionStorageNamespace())); 82 GetControllerForRenderManager().GetSessionStorageNamespace()));
80 83
81 // Keep track of renderer processes as they start to shut down. 84 // Keep track of renderer processes as they start to shut down.
82 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSING, 85 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSING,
83 content::NotificationService::AllSources()); 86 content::NotificationService::AllSources());
84 } 87 }
85 88
86 RenderViewHostImpl* RenderViewHostManager::current_host() const { 89 RenderViewHostImpl* RenderViewHostManager::current_host() const {
87 return render_view_host_; 90 return render_view_host_;
88 } 91 }
(...skipping 16 matching lines...) Expand all
105 if (!dest_render_view_host) 108 if (!dest_render_view_host)
106 return NULL; // We weren't able to create a pending render view host. 109 return NULL; // We weren't able to create a pending render view host.
107 110
108 // If the current render_view_host_ isn't live, we should create it so 111 // 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 112 // that we don't show a sad tab while the dest_render_view_host fetches
110 // its first page. (Bug 1145340) 113 // its first page. (Bug 1145340)
111 if (dest_render_view_host != render_view_host_ && 114 if (dest_render_view_host != render_view_host_ &&
112 !render_view_host_->IsRenderViewLive()) { 115 !render_view_host_->IsRenderViewLive()) {
113 // Note: we don't call InitRenderView here because we are navigating away 116 // 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. 117 // soon anyway, and we don't have the NavigationEntry for this host.
115 delegate_->CreateRenderViewForRenderManager(render_view_host_); 118 delegate_->CreateRenderViewForRenderManager(render_view_host_,
119 MSG_ROUTING_NONE);
116 } 120 }
117 121
118 // If the renderer crashed, then try to create a new one to satisfy this 122 // If the renderer crashed, then try to create a new one to satisfy this
119 // navigation request. 123 // navigation request.
120 if (!dest_render_view_host->IsRenderViewLive()) { 124 if (!dest_render_view_host->IsRenderViewLive()) {
121 if (!InitRenderView(dest_render_view_host, entry)) 125 if (!InitRenderView(dest_render_view_host, MSG_ROUTING_NONE))
122 return NULL; 126 return NULL;
123 127
124 // Now that we've created a new renderer, be sure to hide it if it isn't 128 // 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() 129 // our primary one. Otherwise, we might crash if we try to call Show()
126 // on it later. 130 // on it later.
127 if (dest_render_view_host != render_view_host_ && 131 if (dest_render_view_host != render_view_host_ &&
128 dest_render_view_host->GetView()) { 132 dest_render_view_host->GetView()) {
129 dest_render_view_host->GetView()->Hide(); 133 dest_render_view_host->GetView()->Hide();
130 } else { 134 } else {
131 // This is our primary renderer, notify here as we won't be calling 135 // 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 540 // 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 541 // Pages), keeping them in the same process. When you navigate away from
538 // that page, we want to explicity ignore that BrowsingInstance and group 542 // that page, we want to explicity ignore that BrowsingInstance and group
539 // this page into the appropriate SiteInstance for its URL. 543 // this page into the appropriate SiteInstance for its URL.
540 return SiteInstance::CreateForURL(browser_context, dest_url); 544 return SiteInstance::CreateForURL(browser_context, dest_url);
541 } else { 545 } else {
542 // Start the new renderer in a new SiteInstance, but in the current 546 // Start the new renderer in a new SiteInstance, but in the current
543 // BrowsingInstance. It is important to immediately give this new 547 // BrowsingInstance. It is important to immediately give this new
544 // SiteInstance to a RenderViewHost (if it is different than our current 548 // SiteInstance to a RenderViewHost (if it is different than our current
545 // SiteInstance), so that it is ref counted. This will happen in 549 // SiteInstance), so that it is ref counted. This will happen in
546 // CreatePendingRenderView. 550 // CreateRenderView.
547 return curr_instance->GetRelatedSiteInstance(dest_url); 551 return curr_instance->GetRelatedSiteInstance(dest_url);
548 } 552 }
549 } 553 }
550 554
551 bool RenderViewHostManager::CreatePendingRenderView( 555 int RenderViewHostManager::CreateRenderView(
552 const NavigationEntryImpl& entry, SiteInstance* instance) { 556 SiteInstance* instance,
553 NavigationEntry* curr_entry = 557 int opener_route_id,
554 delegate_->GetControllerForRenderManager().GetLastCommittedEntry(); 558 bool swapped_out) {
555 if (curr_entry) {
556 DCHECK(!curr_entry->GetContentState().empty());
557 // TODO(creis): Should send a message to the RenderView to let it know
558 // we're about to switch away, so that it sends an UpdateState message.
559 }
560
561 // Check if we've already created an RVH for this SiteInstance. 559 // Check if we've already created an RVH for this SiteInstance.
562 CHECK(instance); 560 CHECK(instance);
563 RenderViewHostMap::iterator iter = 561 RenderViewHostImpl* new_render_view_host = NULL;
564 swapped_out_hosts_.find(instance->GetId()); 562 RenderViewHostMap::iterator iter = swapped_out_hosts_.find(instance->GetId());
Matt Perry 2012/05/01 21:45:56 nit: you can use GetSwappedOutRenderViewHost() now
Charlie Reis 2012/05/01 21:57:06 Good catch. Fixed.
565 if (iter != swapped_out_hosts_.end()) { 563 if (iter != swapped_out_hosts_.end()) {
566 // Re-use the existing RenderViewHost, which has already been initialized. 564 // 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. 565 // We'll remove it from the list of swapped out hosts if it commits.
568 pending_render_view_host_ = iter->second; 566 new_render_view_host = iter->second;
569 567
570 // Prevent the process from exiting while we're trying to use it. 568 // Prevent the process from exiting while we're trying to use it.
571 pending_render_view_host_->GetProcess()->AddPendingView(); 569 new_render_view_host->GetProcess()->AddPendingView();
570 } else {
571 // Create a new RenderViewHost if we don't find an existing one.
572 new_render_view_host = static_cast<RenderViewHostImpl*>(
573 RenderViewHostFactory::Create(instance,
574 render_view_delegate_, MSG_ROUTING_NONE, swapped_out, delegate_->
575 GetControllerForRenderManager().GetSessionStorageNamespace()));
572 576
573 return true; 577 // Prevent the process from exiting while we're trying to use it.
578 new_render_view_host->GetProcess()->AddPendingView();
579
580 // Store the new RVH as swapped out if necessary.
581 if (swapped_out)
582 swapped_out_hosts_[instance->GetId()] = new_render_view_host;
583
584 bool success = InitRenderView(new_render_view_host, opener_route_id);
585 if (success) {
586 // Don't show the view until we get a DidNavigate from it.
587 new_render_view_host->GetView()->Hide();
588 } else if (!swapped_out) {
589 CancelPending();
590 }
574 } 591 }
575 592
576 pending_render_view_host_ = static_cast<RenderViewHostImpl*>( 593 // Use this as our new pending RVH if it isn't swapped out.
577 RenderViewHostFactory::Create( 594 if (!swapped_out)
578 instance, render_view_delegate_, MSG_ROUTING_NONE, delegate_-> 595 pending_render_view_host_ = new_render_view_host;
579 GetControllerForRenderManager().GetSessionStorageNamespace()));
580 596
581 // Prevent the process from exiting while we're trying to use it. 597 return new_render_view_host->GetRoutingID();
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 } 598 }
593 599
594 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host, 600 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host,
595 const NavigationEntryImpl& entry) { 601 int opener_route_id) {
596 // If the pending navigation is to a WebUI, tell the RenderView about any 602 // If the pending navigation is to a WebUI, tell the RenderView about any
597 // bindings it will need enabled. 603 // bindings it will need enabled.
598 if (pending_web_ui()) 604 if (pending_web_ui())
599 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); 605 render_view_host->AllowBindings(pending_web_ui()->GetBindings());
600 606
601 return delegate_->CreateRenderViewForRenderManager(render_view_host); 607 return delegate_->CreateRenderViewForRenderManager(render_view_host,
608 opener_route_id);
602 } 609 }
603 610
604 void RenderViewHostManager::CommitPending() { 611 void RenderViewHostManager::CommitPending() {
605 // First check whether we're going to want to focus the location bar after 612 // 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 613 // 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 614 // 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. 615 // this triggers won't be able to figure out what's going on.
609 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 616 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
610 617
611 // Next commit the Web UI, if any. Either replace |web_ui_| with 618 // 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 737 // 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 738 // 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. 739 // 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(), 740 // It must also happen after the above conditional call to CancelPending(),
734 // otherwise CancelPending may clear the pending_web_ui_ and the page will 741 // otherwise CancelPending may clear the pending_web_ui_ and the page will
735 // not have its bindings set appropriately. 742 // not have its bindings set appropriately.
736 pending_web_ui_.reset( 743 pending_web_ui_.reset(
737 delegate_->CreateWebUIForRenderManager(entry.GetURL())); 744 delegate_->CreateWebUIForRenderManager(entry.GetURL()));
738 pending_and_current_web_ui_.reset(); 745 pending_and_current_web_ui_.reset();
739 746
740 // Create a pending RVH and navigate it. 747 // Ensure that we have created RVHs for the new RVH's opener chain if
741 bool success = CreatePendingRenderView(entry, new_instance); 748 // we are staying in the same BrowsingInstance. This allows the pending RVH
742 if (!success) 749 // to send cross-process script calls to its opener(s).
750 int opener_route_id = MSG_ROUTING_NONE;
751 if (new_instance->IsRelatedSiteInstance(curr_instance)) {
752 opener_route_id =
753 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance);
754 }
755
756 // Create a non-swapped-out pending RVH with the given opener and navigate
757 // it.
758 int route_id = CreateRenderView(new_instance, opener_route_id, false);
759 if (route_id == MSG_ROUTING_NONE)
743 return NULL; 760 return NULL;
744 761
745 // Check if our current RVH is live before we set up a transition. 762 // Check if our current RVH is live before we set up a transition.
746 if (!render_view_host_->IsRenderViewLive()) { 763 if (!render_view_host_->IsRenderViewLive()) {
747 if (!cross_navigation_pending_) { 764 if (!cross_navigation_pending_) {
748 // The current RVH is not live. There's no reason to sit around with a 765 // 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 766 // 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 767 // 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 768 // cross-navigating (Note that we don't care about on{before}unload
752 // handlers if the current RVH isn't live.) 769 // handlers if the current RVH isn't live.)
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 } 888 }
872 } 889 }
873 890
874 bool RenderViewHostManager::IsSwappedOut(RenderViewHost* rvh) { 891 bool RenderViewHostManager::IsSwappedOut(RenderViewHost* rvh) {
875 if (!rvh->GetSiteInstance()) 892 if (!rvh->GetSiteInstance())
876 return false; 893 return false;
877 894
878 return swapped_out_hosts_.find(rvh->GetSiteInstance()->GetId()) != 895 return swapped_out_hosts_.find(rvh->GetSiteInstance()->GetId()) !=
879 swapped_out_hosts_.end(); 896 swapped_out_hosts_.end();
880 } 897 }
898
899 RenderViewHost* RenderViewHostManager::GetSwappedOutRenderViewHost(
900 SiteInstance* instance) {
901 RenderViewHostMap::iterator iter = swapped_out_hosts_.find(instance->GetId());
902 if (iter != swapped_out_hosts_.end())
903 return iter->second;
904
905 return NULL;
906 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698