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

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

Issue 10154004: re-use WebUIs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix reload DCHECKs Created 8 years, 8 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 27 matching lines...) Expand all
38 using content::WebUIControllerFactory; 38 using content::WebUIControllerFactory;
39 39
40 RenderViewHostManager::RenderViewHostManager( 40 RenderViewHostManager::RenderViewHostManager(
41 content::RenderViewHostDelegate* render_view_delegate, 41 content::RenderViewHostDelegate* render_view_delegate,
42 Delegate* delegate) 42 Delegate* delegate)
43 : delegate_(delegate), 43 : delegate_(delegate),
44 cross_navigation_pending_(false), 44 cross_navigation_pending_(false),
45 render_view_delegate_(render_view_delegate), 45 render_view_delegate_(render_view_delegate),
46 render_view_host_(NULL), 46 render_view_host_(NULL),
47 pending_render_view_host_(NULL), 47 pending_render_view_host_(NULL),
48 pending_web_ui_(NULL),
48 interstitial_page_(NULL) { 49 interstitial_page_(NULL) {
49 } 50 }
50 51
51 RenderViewHostManager::~RenderViewHostManager() { 52 RenderViewHostManager::~RenderViewHostManager() {
52 if (pending_render_view_host_) 53 if (pending_render_view_host_)
53 CancelPending(); 54 CancelPending();
54 55
55 // We should always have a main RenderViewHost. 56 // We should always have a main RenderViewHost.
56 RenderViewHostImpl* render_view_host = render_view_host_; 57 RenderViewHostImpl* render_view_host = render_view_host_;
57 render_view_host_ = NULL; 58 render_view_host_ = NULL;
58 render_view_host->Shutdown(); 59 render_view_host->Shutdown();
59 60
60 // Shut down any swapped out RenderViewHosts. 61 // Shut down any swapped out RenderViewHosts.
61 for (RenderViewHostMap::iterator iter = swapped_out_hosts_.begin(); 62 for (RenderViewHostMap::iterator iter = swapped_out_hosts_.begin();
62 iter != swapped_out_hosts_.end(); 63 iter != swapped_out_hosts_.end();
63 ++iter) { 64 ++iter) {
64 iter->second->Shutdown(); 65 iter->second->Shutdown();
65 } 66 }
67
68 FreePendingWebUI();
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);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 202
200 void RenderViewHostManager::DidNavigateMainFrame( 203 void RenderViewHostManager::DidNavigateMainFrame(
201 RenderViewHost* render_view_host) { 204 RenderViewHost* render_view_host) {
202 if (!cross_navigation_pending_) { 205 if (!cross_navigation_pending_) {
203 DCHECK(!pending_render_view_host_); 206 DCHECK(!pending_render_view_host_);
204 207
205 // We should only hear this from our current renderer. 208 // We should only hear this from our current renderer.
206 DCHECK(render_view_host == render_view_host_); 209 DCHECK(render_view_host == render_view_host_);
207 210
208 // Even when there is no pending RVH, there may be a pending Web UI. 211 // Even when there is no pending RVH, there may be a pending Web UI.
209 if (pending_web_ui_.get()) 212 if (pending_web_ui_)
210 CommitPending(); 213 CommitPending();
211 return; 214 return;
212 } 215 }
213 216
214 if (render_view_host == pending_render_view_host_) { 217 if (render_view_host == pending_render_view_host_) {
215 // The pending cross-site navigation completed, so show the renderer. 218 // The pending cross-site navigation completed, so show the renderer.
216 // If it committed without sending network requests (e.g., data URLs), 219 // If it committed without sending network requests (e.g., data URLs),
217 // then we still need to swap out the old RVH first and run its unload 220 // then we still need to swap out the old RVH first and run its unload
218 // handler. OK for that to happen in the background. 221 // handler. OK for that to happen in the background.
219 if (pending_render_view_host_->GetPendingRequestId() == -1) { 222 if (pending_render_view_host_->GetPendingRequestId() == -1) {
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 // We can't switch a RenderView between view source and non-view source mode 402 // We can't switch a RenderView between view source and non-view source mode
400 // without screwing up the session history sometimes (when navigating between 403 // without screwing up the session history sometimes (when navigating between
401 // "view-source:http://foo.com/" and "http://foo.com/", WebKit doesn't treat 404 // "view-source:http://foo.com/" and "http://foo.com/", WebKit doesn't treat
402 // it as a new navigation). So require a view switch. 405 // it as a new navigation). So require a view switch.
403 if (cur_entry->IsViewSourceMode() != new_entry->IsViewSourceMode()) 406 if (cur_entry->IsViewSourceMode() != new_entry->IsViewSourceMode())
404 return true; 407 return true;
405 408
406 return false; 409 return false;
407 } 410 }
408 411
412 bool RenderViewHostManager::ShouldReuseWebUI(
413 const NavigationEntry* curr_entry,
414 const NavigationEntryImpl* new_entry) const {
415 NavigationControllerImpl& controller =
416 delegate_->GetControllerForRenderManager();
417 WebUIControllerFactory* factory =
418 content::GetContentClient()->browser()->GetWebUIControllerFactory();
419 return curr_entry && web_ui_.get() &&
420 (factory->GetWebUIType(controller.GetBrowserContext(),
Dan Beam 2012/04/21 02:53:07 can you split this into multiple lines?
Evan Stade 2012/04/24 17:52:40 not easily.
421 curr_entry->GetURL()) ==
422 factory->GetWebUIType(controller.GetBrowserContext(),
423 new_entry->GetURL()));
424 }
425
409 SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry( 426 SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry(
410 const NavigationEntryImpl& entry, 427 const NavigationEntryImpl& entry,
411 SiteInstance* curr_instance) { 428 SiteInstance* curr_instance) {
412 // NOTE: This is only called when ShouldTransitionCrossSite is true. 429 // NOTE: This is only called when ShouldTransitionCrossSite is true.
413 430
414 const GURL& dest_url = entry.GetURL(); 431 const GURL& dest_url = entry.GetURL();
415 NavigationControllerImpl& controller = 432 NavigationControllerImpl& controller =
416 delegate_->GetControllerForRenderManager(); 433 delegate_->GetControllerForRenderManager();
417 content::BrowserContext* browser_context = controller.GetBrowserContext(); 434 content::BrowserContext* browser_context = controller.GetBrowserContext();
418 435
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 } else { 591 } else {
575 CancelPending(); 592 CancelPending();
576 } 593 }
577 return success; 594 return success;
578 } 595 }
579 596
580 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host, 597 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host,
581 const NavigationEntryImpl& entry) { 598 const NavigationEntryImpl& entry) {
582 // If the pending navigation is to a WebUI, tell the RenderView about any 599 // If the pending navigation is to a WebUI, tell the RenderView about any
583 // bindings it will need enabled. 600 // bindings it will need enabled.
584 if (pending_web_ui_.get()) 601 if (pending_web_ui_)
585 render_view_host->AllowBindings(pending_web_ui_->GetBindings()); 602 render_view_host->AllowBindings(pending_web_ui_->GetBindings());
586 603
587 return delegate_->CreateRenderViewForRenderManager(render_view_host); 604 return delegate_->CreateRenderViewForRenderManager(render_view_host);
588 } 605 }
589 606
590 void RenderViewHostManager::CommitPending() { 607 void RenderViewHostManager::CommitPending() {
591 // 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
592 // 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
593 // 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
594 // 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.
595 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 612 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
596 613
597 // Next commit the Web UI, if any. 614 // Next commit the Web UI, if any.
598 web_ui_.swap(pending_web_ui_); 615 if (web_ui_.get() != pending_web_ui_)
Dan Beam 2012/04/21 02:53:07 you don't really need .get() operators for scoped_
599 if (web_ui_.get() && pending_web_ui_.get() && !pending_render_view_host_) 616 web_ui_.reset(pending_web_ui_);
600 web_ui_->GetController()->DidBecomeActiveForReusedRenderView(); 617 pending_web_ui_ = NULL;
601 pending_web_ui_.reset();
602 618
603 // It's possible for the pending_render_view_host_ to be NULL when we aren't 619 // It's possible for the pending_render_view_host_ to be NULL when we aren't
604 // crossing process boundaries. If so, we just needed to handle the Web UI 620 // crossing process boundaries. If so, we just needed to handle the Web UI
605 // committing above and we're done. 621 // committing above and we're done.
606 if (!pending_render_view_host_) { 622 if (!pending_render_view_host_) {
607 if (will_focus_location_bar) 623 if (will_focus_location_bar)
608 delegate_->SetFocusToLocationBar(false); 624 delegate_->SetFocusToLocationBar(false);
609 return; 625 return;
610 } 626 }
611 627
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 } 690 }
675 swapped_out_hosts_[old_site_instance_id] = old_render_view_host; 691 swapped_out_hosts_[old_site_instance_id] = old_render_view_host;
676 } else { 692 } else {
677 old_render_view_host->Shutdown(); 693 old_render_view_host->Shutdown();
678 } 694 }
679 695
680 // Let the task manager know that we've swapped RenderViewHosts, since it 696 // Let the task manager know that we've swapped RenderViewHosts, since it
681 // might need to update its process groupings. 697 // might need to update its process groupings.
682 delegate_->NotifySwappedFromRenderManager(); 698 delegate_->NotifySwappedFromRenderManager();
683 } 699 }
684 700
Dan Beam 2012/04/21 02:53:07 why \n?
Evan Stade 2012/04/24 17:52:40 Done.
701
685 RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate( 702 RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate(
686 const NavigationEntryImpl& entry) { 703 const NavigationEntryImpl& entry) {
687 // If we are cross-navigating, then we want to get back to normal and navigate 704 // If we are cross-navigating, then we want to get back to normal and navigate
688 // as usual. 705 // as usual.
689 if (cross_navigation_pending_) { 706 if (cross_navigation_pending_) {
690 if (pending_render_view_host_) 707 if (pending_render_view_host_)
691 CancelPending(); 708 CancelPending();
692 cross_navigation_pending_ = false; 709 cross_navigation_pending_ = false;
693 } 710 }
694 711
695 // This will possibly create (set to NULL) a Web UI object for the pending
696 // page. We'll use this later to give the page special access. This must
697 // happen before the new renderer is created below so it will get bindings.
698 // It must also happen after the above conditional call to CancelPending(),
699 // otherwise CancelPending may clear the pending_web_ui_ and the page will
700 // not have it's bindings set appropriately.
701 pending_web_ui_.reset(delegate_->CreateWebUIForRenderManager(entry.GetURL()));
702
703 // render_view_host_ will not be deleted before the end of this method, so we 712 // render_view_host_ will not be deleted before the end of this method, so we
704 // don't have to worry about this SiteInstance's ref count dropping to zero. 713 // don't have to worry about this SiteInstance's ref count dropping to zero.
705 SiteInstance* curr_instance = render_view_host_->GetSiteInstance(); 714 SiteInstance* curr_instance = render_view_host_->GetSiteInstance();
706 715
707 // Determine if we need a new SiteInstance for this entry. 716 // Determine if we need a new SiteInstance for this entry.
708 // Again, new_instance won't be deleted before the end of this method, so it 717 // Again, new_instance won't be deleted before the end of this method, so it
709 // is safe to use a normal pointer here. 718 // is safe to use a normal pointer here.
710 SiteInstance* new_instance = curr_instance; 719 SiteInstance* new_instance = curr_instance;
711 bool force_swap = ShouldSwapProcessesForNavigation( 720 const content::NavigationEntry* curr_entry =
712 delegate_->GetLastCommittedNavigationEntryForRenderManager(), &entry); 721 delegate_->GetLastCommittedNavigationEntryForRenderManager();
722 bool force_swap = ShouldSwapProcessesForNavigation(curr_entry, &entry);
713 if (ShouldTransitionCrossSite() || force_swap) 723 if (ShouldTransitionCrossSite() || force_swap)
714 new_instance = GetSiteInstanceForEntry(entry, curr_instance); 724 new_instance = GetSiteInstanceForEntry(entry, curr_instance);
715 725
716 if (new_instance != curr_instance || force_swap) { 726 if (new_instance != curr_instance || force_swap) {
717 // New SiteInstance. 727 // New SiteInstance.
718 DCHECK(!cross_navigation_pending_); 728 DCHECK(!cross_navigation_pending_);
719 729
730 // 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
732 // 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(),
734 // otherwise CancelPending may clear the pending_web_ui_ and the page will
735 // not have it's bindings set appropriately.
Dan Beam 2012/04/21 02:53:07 its
Evan Stade 2012/04/24 17:52:40 Done.
736 pending_web_ui_ = delegate_->CreateWebUIForRenderManager(entry.GetURL());
737
720 // Create a pending RVH and navigate it. 738 // Create a pending RVH and navigate it.
721 bool success = CreatePendingRenderView(entry, new_instance); 739 bool success = CreatePendingRenderView(entry, new_instance);
722 if (!success) 740 if (!success)
723 return NULL; 741 return NULL;
724 742
725 // Check if our current RVH is live before we set up a transition. 743 // Check if our current RVH is live before we set up a transition.
726 if (!render_view_host_->IsRenderViewLive()) { 744 if (!render_view_host_->IsRenderViewLive()) {
727 if (!cross_navigation_pending_) { 745 if (!cross_navigation_pending_) {
728 // The current RVH is not live. There's no reason to sit around with a 746 // The current RVH is not live. There's no reason to sit around with a
729 // sad tab or a newly created RVH while we wait for the pending RVH to 747 // sad tab or a newly created RVH while we wait for the pending RVH to
(...skipping 29 matching lines...) Expand all
759 DCHECK(!cross_navigation_pending_); 777 DCHECK(!cross_navigation_pending_);
760 cross_navigation_pending_ = true; 778 cross_navigation_pending_ = true;
761 779
762 // Tell the old render view to run its onbeforeunload handler, since it 780 // Tell the old render view to run its onbeforeunload handler, since it
763 // doesn't otherwise know that the cross-site request is happening. This 781 // doesn't otherwise know that the cross-site request is happening. This
764 // will trigger a call to ShouldClosePage with the reply. 782 // will trigger a call to ShouldClosePage with the reply.
765 render_view_host_->FirePageBeforeUnload(true); 783 render_view_host_->FirePageBeforeUnload(true);
766 784
767 return pending_render_view_host_; 785 return pending_render_view_host_;
768 } else { 786 } else {
769 if (pending_web_ui_.get() && render_view_host_->IsRenderViewLive()) 787 if (ShouldReuseWebUI(curr_entry, &entry))
788 pending_web_ui_ = web_ui_.get();
789 else
790 pending_web_ui_ = delegate_->CreateWebUIForRenderManager(entry.GetURL());
791
792 if (pending_web_ui_ && render_view_host_->IsRenderViewLive())
770 pending_web_ui_->GetController()->RenderViewReused(render_view_host_); 793 pending_web_ui_->GetController()->RenderViewReused(render_view_host_);
771 794
772 // The renderer can exit view source mode when any error or cancellation 795 // The renderer can exit view source mode when any error or cancellation
773 // happen. We must overwrite to recover the mode. 796 // happen. We must overwrite to recover the mode.
774 if (entry.IsViewSourceMode()) { 797 if (entry.IsViewSourceMode()) {
775 render_view_host_->Send( 798 render_view_host_->Send(
776 new ViewMsg_EnableViewSourceMode(render_view_host_->GetRoutingID())); 799 new ViewMsg_EnableViewSourceMode(render_view_host_->GetRoutingID()));
777 } 800 }
778 } 801 }
779 802
(...skipping 23 matching lines...) Expand all
803 pending_render_view_host->CancelSuspendedNavigations(); 826 pending_render_view_host->CancelSuspendedNavigations();
804 827
805 // We can pass -1,-1 because there is no pending response in the 828 // We can pass -1,-1 because there is no pending response in the
806 // ResourceDispatcherHost to unpause. 829 // ResourceDispatcherHost to unpause.
807 pending_render_view_host->SwapOut(-1, -1); 830 pending_render_view_host->SwapOut(-1, -1);
808 } else { 831 } else {
809 // We won't be coming back, so shut this one down. 832 // We won't be coming back, so shut this one down.
810 pending_render_view_host->Shutdown(); 833 pending_render_view_host->Shutdown();
811 } 834 }
812 835
813 pending_web_ui_.reset(); 836 FreePendingWebUI();
814 } 837 }
815 838
816 void RenderViewHostManager::RenderViewDeleted(RenderViewHost* rvh) { 839 void RenderViewHostManager::RenderViewDeleted(RenderViewHost* rvh) {
817 // We are doing this in order to work around and to track a crasher 840 // We are doing this in order to work around and to track a crasher
818 // (http://crbug.com/23411) where it seems that pending_render_view_host_ is 841 // (http://crbug.com/23411) where it seems that pending_render_view_host_ is
819 // deleted (not sure from where) but not NULLed. 842 // deleted (not sure from where) but not NULLed.
820 if (rvh == pending_render_view_host_) { 843 if (rvh == pending_render_view_host_) {
821 // If you hit this NOTREACHED, please report it in the following bug 844 // If you hit this NOTREACHED, please report it in the following bug
822 // http://crbug.com/23411 Make sure to include what you were doing when it 845 // http://crbug.com/23411 Make sure to include what you were doing when it
823 // happened (navigating to a new page, closing a tab...) and if you can 846 // happened (navigating to a new page, closing a tab...) and if you can
(...skipping 17 matching lines...) Expand all
841 } 864 }
842 } 865 }
843 866
844 bool RenderViewHostManager::IsSwappedOut(RenderViewHost* rvh) { 867 bool RenderViewHostManager::IsSwappedOut(RenderViewHost* rvh) {
845 if (!rvh->GetSiteInstance()) 868 if (!rvh->GetSiteInstance())
846 return false; 869 return false;
847 870
848 return swapped_out_hosts_.find(rvh->GetSiteInstance()->GetId()) != 871 return swapped_out_hosts_.find(rvh->GetSiteInstance()->GetId()) !=
849 swapped_out_hosts_.end(); 872 swapped_out_hosts_.end();
850 } 873 }
874
875 void RenderViewHostManager::FreePendingWebUI() {
876 if (pending_web_ui_ && pending_web_ui_ != web_ui_.get())
877 delete pending_web_ui_;
878
879 pending_web_ui_ = NULL;
880 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698