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

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

Issue 6319001: Support window.opener after a process swap. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Better message filtering approach. Created 9 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/tab_contents/render_view_host_manager.h" 5 #include "content/browser/tab_contents/render_view_host_manager.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "chrome/browser/profiles/profile.h" 9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/common/chrome_switches.h" 10 #include "chrome/common/chrome_switches.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 } 42 }
43 43
44 RenderViewHostManager::~RenderViewHostManager() { 44 RenderViewHostManager::~RenderViewHostManager() {
45 if (pending_render_view_host_) 45 if (pending_render_view_host_)
46 CancelPending(); 46 CancelPending();
47 47
48 // We should always have a main RenderViewHost. 48 // We should always have a main RenderViewHost.
49 RenderViewHost* render_view_host = render_view_host_; 49 RenderViewHost* render_view_host = render_view_host_;
50 render_view_host_ = NULL; 50 render_view_host_ = NULL;
51 render_view_host->Shutdown(); 51 render_view_host->Shutdown();
52
53 // Shut down any swapped out RenderViewHosts.
54 for (RenderViewHostMap::iterator iter = swapped_out_hosts_.begin();
55 iter != swapped_out_hosts_.end();
56 ++iter) {
57 iter->second->Shutdown();
58 }
52 } 59 }
53 60
54 void RenderViewHostManager::Init(Profile* profile, 61 void RenderViewHostManager::Init(Profile* profile,
55 SiteInstance* site_instance, 62 SiteInstance* site_instance,
56 int routing_id) { 63 int routing_id) {
57 // Create a RenderViewHost, once we have an instance. It is important to 64 // Create a RenderViewHost, once we have an instance. It is important to
58 // immediately give this SiteInstance to a RenderViewHost so that it is 65 // immediately give this SiteInstance to a RenderViewHost so that it is
59 // ref counted. 66 // ref counted.
60 if (!site_instance) 67 if (!site_instance)
61 site_instance = SiteInstance::CreateSiteInstance(profile); 68 site_instance = SiteInstance::CreateSiteInstance(profile);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 if (pending_request_id == -1) { 148 if (pending_request_id == -1) {
142 // Haven't gotten around to starting the request, because we're still 149 // Haven't gotten around to starting the request, because we're still
143 // waiting for the beforeunload handler to finish. We'll pretend that it 150 // waiting for the beforeunload handler to finish. We'll pretend that it
144 // did finish, to let the navigation proceed. Note that there's a danger 151 // did finish, to let the navigation proceed. Note that there's a danger
145 // that the beforeunload handler will later finish and possibly return 152 // that the beforeunload handler will later finish and possibly return
146 // false (meaning the navigation should not proceed), but we'll ignore it 153 // false (meaning the navigation should not proceed), but we'll ignore it
147 // in this case because it took too long. 154 // in this case because it took too long.
148 if (pending_render_view_host_->are_navigations_suspended()) 155 if (pending_render_view_host_->are_navigations_suspended())
149 pending_render_view_host_->SetNavigationsSuspended(false); 156 pending_render_view_host_->SetNavigationsSuspended(false);
150 } else { 157 } else {
151 // The request has been started and paused, while we're waiting for the 158 // The request has been started and paused while we're waiting for the
152 // unload handler to finish. We'll pretend that it did, by notifying the 159 // unload handler to finish. We'll pretend that it did, by notifying the
153 // IO thread to let the response continue. The pending renderer will then 160 // IO thread to let the response continue. The pending renderer will then
154 // be swapped in as part of the usual DidNavigate logic. (If the unload 161 // be swapped in as part of the usual DidNavigate logic. (If the unload
155 // handler later finishes, this call will be ignored because the state in 162 // handler later finishes, this call will be ignored because the state in
156 // CrossSiteResourceHandler will already be cleaned up.) 163 // CrossSiteResourceHandler will already be cleaned up.)
157 ViewMsg_ClosePage_Params params; 164 ViewMsg_SwapOut_Params params;
158 params.closing_process_id =
159 render_view_host_->process()->id();
160 params.closing_route_id = render_view_host_->routing_id();
161 params.for_cross_site_transition = true;
162 params.new_render_process_host_id = 165 params.new_render_process_host_id =
163 pending_render_view_host_->process()->id(); 166 pending_render_view_host_->process()->id();
164 params.new_request_id = pending_request_id; 167 params.new_request_id = pending_request_id;
165 current_host()->process()->CrossSiteClosePageACK(params); 168 current_host()->process()->CrossSiteSwapOutACK(params);
166 } 169 }
167 return false; 170 return false;
168 } 171 }
169 172
170 void RenderViewHostManager::DidNavigateMainFrame( 173 void RenderViewHostManager::DidNavigateMainFrame(
171 RenderViewHost* render_view_host) { 174 RenderViewHost* render_view_host) {
172 if (!cross_navigation_pending_) { 175 if (!cross_navigation_pending_) {
173 DCHECK(!pending_render_view_host_); 176 DCHECK(!pending_render_view_host_);
174 177
175 // We should only hear this from our current renderer. 178 // We should only hear this from our current renderer.
176 DCHECK(render_view_host == render_view_host_); 179 DCHECK(render_view_host == render_view_host_);
177 180
178 // Even when there is no pending RVH, there may be a pending Web UI. 181 // Even when there is no pending RVH, there may be a pending Web UI.
179 if (pending_web_ui_.get()) 182 if (pending_web_ui_.get())
180 CommitPending(); 183 CommitPending();
181 return; 184 return;
182 } 185 }
183 186
184 if (render_view_host == pending_render_view_host_) { 187 if (render_view_host == pending_render_view_host_) {
185 // The pending cross-site navigation completed, so show the renderer. 188 // The pending cross-site navigation completed, so show the renderer.
189 // If it committed without sending network requests (e.g., data URLs),
190 // then we still need to swap out the old RVH first and run its unload
191 // handler. OK for that to happen in the background.
192 if (pending_render_view_host_->GetPendingRequestId() == -1)
193 OnCrossSiteResponse(pending_render_view_host_->process()->id(),
194 pending_render_view_host_->routing_id());
195
186 CommitPending(); 196 CommitPending();
187 cross_navigation_pending_ = false; 197 cross_navigation_pending_ = false;
188 } else if (render_view_host == render_view_host_) { 198 } else if (render_view_host == render_view_host_) {
189 // A navigation in the original page has taken place. Cancel the pending 199 // A navigation in the original page has taken place. Cancel the pending
190 // one. 200 // one.
191 CancelPending(); 201 CancelPending();
192 cross_navigation_pending_ = false; 202 cross_navigation_pending_ = false;
193 } else { 203 } else {
194 // No one else should be sending us DidNavigate in this state. 204 // No one else should be sending us DidNavigate in this state.
195 DCHECK(false); 205 DCHECK(false);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 cross_navigation_pending_ = false; 247 cross_navigation_pending_ = false;
238 } 248 }
239 } else { 249 } else {
240 // Non-cross site transition means closing the entire tab. 250 // Non-cross site transition means closing the entire tab.
241 bool proceed_to_fire_unload; 251 bool proceed_to_fire_unload;
242 delegate_->BeforeUnloadFiredFromRenderManager(proceed, 252 delegate_->BeforeUnloadFiredFromRenderManager(proceed,
243 &proceed_to_fire_unload); 253 &proceed_to_fire_unload);
244 254
245 if (proceed_to_fire_unload) { 255 if (proceed_to_fire_unload) {
246 // This is not a cross-site navigation, the tab is being closed. 256 // This is not a cross-site navigation, the tab is being closed.
247 render_view_host_->ClosePage(false, -1, -1); 257 render_view_host_->ClosePage();
248 } 258 }
249 } 259 }
250 } 260 }
251 261
252 void RenderViewHostManager::OnCrossSiteResponse(int new_render_process_host_id, 262 void RenderViewHostManager::OnCrossSiteResponse(int new_render_process_host_id,
253 int new_request_id) { 263 int new_request_id) {
254 // Should only see this while we have a pending renderer. 264 // Should only see this while we have a pending renderer.
255 if (!cross_navigation_pending_) 265 if (!cross_navigation_pending_)
256 return; 266 return;
257 DCHECK(pending_render_view_host_); 267 DCHECK(pending_render_view_host_);
258 268
259 // Tell the old renderer to run its onunload handler. When it finishes, it 269 // Tell the old renderer it is being swapped out. This will fire the unload
260 // will send a ClosePage_ACK to the ResourceDispatcherHost with the given 270 // handler (without firing the beforeunload handler a second time). When the
261 // IDs (of the pending RVH's request), allowing the pending RVH's response to 271 // unload handler finishes and the navigation completes, we will send a
262 // resume. 272 // message to the ResourceDispatcherHost with the given pending request IDs,
263 render_view_host_->ClosePage(true, 273 // allowing the pending RVH's response to resume.
264 new_render_process_host_id, new_request_id); 274 render_view_host_->SwapOut(new_render_process_host_id, new_request_id);
265 275
266 // ResourceDispatcherHost has told us to run the onunload handler, which 276 // ResourceDispatcherHost has told us to run the onunload handler, which
267 // means it is not a download or unsafe page, and we are going to perform the 277 // means it is not a download or unsafe page, and we are going to perform the
268 // navigation. Thus, we no longer need to remember that the RenderViewHost 278 // navigation. Thus, we no longer need to remember that the RenderViewHost
269 // is part of a pending cross-site request. 279 // is part of a pending cross-site request.
270 pending_render_view_host_->SetHasPendingCrossSiteRequest(false, 280 pending_render_view_host_->SetHasPendingCrossSiteRequest(false,
271 new_request_id); 281 new_request_id);
272 } 282 }
273 283
274 void RenderViewHostManager::OnCrossSiteNavigationCanceled() { 284 void RenderViewHostManager::OnCrossSiteNavigationCanceled() {
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 bool RenderViewHostManager::CreatePendingRenderView( 462 bool RenderViewHostManager::CreatePendingRenderView(
453 const NavigationEntry& entry, SiteInstance* instance) { 463 const NavigationEntry& entry, SiteInstance* instance) {
454 NavigationEntry* curr_entry = 464 NavigationEntry* curr_entry =
455 delegate_->GetControllerForRenderManager().GetLastCommittedEntry(); 465 delegate_->GetControllerForRenderManager().GetLastCommittedEntry();
456 if (curr_entry) { 466 if (curr_entry) {
457 DCHECK(!curr_entry->content_state().empty()); 467 DCHECK(!curr_entry->content_state().empty());
458 // TODO(creis): Should send a message to the RenderView to let it know 468 // TODO(creis): Should send a message to the RenderView to let it know
459 // we're about to switch away, so that it sends an UpdateState message. 469 // we're about to switch away, so that it sends an UpdateState message.
460 } 470 }
461 471
472 // Check if we've already created an RVH for this SiteInstance.
473 CHECK(instance);
474 RenderViewHostMap::iterator iter =
475 swapped_out_hosts_.find(instance->id());
476 if (iter != swapped_out_hosts_.end()) {
477 // Re-use the existing RenderViewHost, which has already been initialized.
478 // We'll remove it from the list of swapped out hosts if it commits.
479 pending_render_view_host_ = iter->second;
480 return true;
481 }
482
462 pending_render_view_host_ = RenderViewHostFactory::Create( 483 pending_render_view_host_ = RenderViewHostFactory::Create(
463 instance, render_view_delegate_, MSG_ROUTING_NONE, delegate_-> 484 instance, render_view_delegate_, MSG_ROUTING_NONE, delegate_->
464 GetControllerForRenderManager().session_storage_namespace()); 485 GetControllerForRenderManager().session_storage_namespace());
465 486
466 bool success = InitRenderView(pending_render_view_host_, entry); 487 bool success = InitRenderView(pending_render_view_host_, entry);
467 if (success) { 488 if (success) {
468 // Don't show the view until we get a DidNavigate from it. 489 // Don't show the view until we get a DidNavigate from it.
469 pending_render_view_host_->view()->Hide(); 490 pending_render_view_host_->view()->Hide();
470 } else { 491 } else {
471 CancelPending(); 492 CancelPending();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 if (will_focus_location_bar) 529 if (will_focus_location_bar)
509 delegate_->SetFocusToLocationBar(false); 530 delegate_->SetFocusToLocationBar(false);
510 return; 531 return;
511 } 532 }
512 533
513 // Remember if the page was focused so we can focus the new renderer in 534 // Remember if the page was focused so we can focus the new renderer in
514 // that case. 535 // that case.
515 bool focus_render_view = !will_focus_location_bar && 536 bool focus_render_view = !will_focus_location_bar &&
516 render_view_host_->view() && render_view_host_->view()->HasFocus(); 537 render_view_host_->view() && render_view_host_->view()->HasFocus();
517 538
518 // Hide the current view and prepare to destroy it. 539 // Swap in the pending view and make it active.
519 // TODO(creis): Get the old RenderViewHost to send us an UpdateState message
520 // before we destroy it.
521 if (render_view_host_->view())
522 render_view_host_->view()->Hide();
523 RenderViewHost* old_render_view_host = render_view_host_; 540 RenderViewHost* old_render_view_host = render_view_host_;
524
525 // Swap in the pending view and make it active.
526 render_view_host_ = pending_render_view_host_; 541 render_view_host_ = pending_render_view_host_;
527 pending_render_view_host_ = NULL; 542 pending_render_view_host_ = NULL;
528 543
529 // If the view is gone, then this RenderViewHost died while it was hidden. 544 // If the view is gone, then this RenderViewHost died while it was hidden.
530 // We ignored the RenderViewGone call at the time, so we should send it now 545 // We ignored the RenderViewGone call at the time, so we should send it now
531 // to make sure the sad tab shows up, etc. 546 // to make sure the sad tab shows up, etc.
532 if (render_view_host_->view()) 547 if (render_view_host_->view())
533 render_view_host_->view()->Show(); 548 render_view_host_->view()->Show();
534 else 549 else
535 delegate_->RenderViewGoneFromRenderManager(render_view_host_); 550 delegate_->RenderViewGoneFromRenderManager(render_view_host_);
536 551
552 // Hide the old view now that the new one is visible.
553 if (old_render_view_host->view()) {
554 old_render_view_host->view()->Hide();
555 old_render_view_host->WasSwappedOut();
556 }
557
537 // Make sure the size is up to date. (Fix for bug 1079768.) 558 // Make sure the size is up to date. (Fix for bug 1079768.)
538 delegate_->UpdateRenderViewSizeForRenderManager(); 559 delegate_->UpdateRenderViewSizeForRenderManager();
539 560
540 if (will_focus_location_bar) 561 if (will_focus_location_bar)
541 delegate_->SetFocusToLocationBar(false); 562 delegate_->SetFocusToLocationBar(false);
542 else if (focus_render_view && render_view_host_->view()) 563 else if (focus_render_view && render_view_host_->view())
543 render_view_host_->view()->Focus(); 564 render_view_host_->view()->Focus();
544 565
545 RenderViewHostSwitchedDetails details; 566 RenderViewHostSwitchedDetails details;
546 details.new_host = render_view_host_; 567 details.new_host = render_view_host_;
547 details.old_host = old_render_view_host; 568 details.old_host = old_render_view_host;
548 NotificationService::current()->Notify( 569 NotificationService::current()->Notify(
549 NotificationType::RENDER_VIEW_HOST_CHANGED, 570 NotificationType::RENDER_VIEW_HOST_CHANGED,
550 Source<NavigationController>(&delegate_->GetControllerForRenderManager()), 571 Source<NavigationController>(&delegate_->GetControllerForRenderManager()),
551 Details<RenderViewHostSwitchedDetails>(&details)); 572 Details<RenderViewHostSwitchedDetails>(&details));
552 573
553 old_render_view_host->Shutdown(); 574 // If the pending view was on the swapped out list, we can remove it.
575 RenderViewHostMap::iterator iter = swapped_out_hosts_.find(
576 render_view_host_->site_instance()->id());
577 if (iter != swapped_out_hosts_.end()) {
578 swapped_out_hosts_.erase(iter);
579 }
580
581 // If the old RVH is live, we are swapping it out and should keep track of it
582 // in case we navigate back to it.
583 if (old_render_view_host->IsRenderViewLive()) {
584 DCHECK(old_render_view_host->is_swapped_out());
585 swapped_out_hosts_[old_render_view_host->site_instance()->id()] =
586 old_render_view_host;
587 } else {
588 old_render_view_host->Shutdown();
589 }
554 590
555 // Let the task manager know that we've swapped RenderViewHosts, since it 591 // Let the task manager know that we've swapped RenderViewHosts, since it
556 // might need to update its process groupings. 592 // might need to update its process groupings.
557 delegate_->NotifySwappedFromRenderManager(); 593 delegate_->NotifySwappedFromRenderManager();
558 } 594 }
559 595
560 RenderViewHost* RenderViewHostManager::UpdateRendererStateForNavigate( 596 RenderViewHost* RenderViewHostManager::UpdateRendererStateForNavigate(
561 const NavigationEntry& entry) { 597 const NavigationEntry& entry) {
562 // If we are cross-navigating, then we want to get back to normal and navigate 598 // If we are cross-navigating, then we want to get back to normal and navigate
563 // as usual. 599 // as usual.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 690
655 // Same SiteInstance can be used. Navigate render_view_host_ if we are not 691 // Same SiteInstance can be used. Navigate render_view_host_ if we are not
656 // cross navigating. 692 // cross navigating.
657 DCHECK(!cross_navigation_pending_); 693 DCHECK(!cross_navigation_pending_);
658 return render_view_host_; 694 return render_view_host_;
659 } 695 }
660 696
661 void RenderViewHostManager::CancelPending() { 697 void RenderViewHostManager::CancelPending() {
662 RenderViewHost* pending_render_view_host = pending_render_view_host_; 698 RenderViewHost* pending_render_view_host = pending_render_view_host_;
663 pending_render_view_host_ = NULL; 699 pending_render_view_host_ = NULL;
664 pending_render_view_host->Shutdown(); 700
701 // The pending RVH may already be on the swapped out list if we started to
702 // swap it back in and then canceled. If so, make sure it gets swapped out
703 // again. If it's not on the swapped out list (e.g., aborting a pending
704 // load), then it's safe to shut down.
705 if (IsSwappedOut(pending_render_view_host)) {
706 // Any currently suspended navigations are no longer needed.
707 pending_render_view_host->CancelSuspendedNavigations();
708
709 // We can pass -1,-1 because there is no pending response in the
710 // ResourceDispatcherHost to unpause.
711 pending_render_view_host->SwapOut(-1, -1);
712 } else {
713 // We won't be coming back, so shut this one down.
714 pending_render_view_host->Shutdown();
715 }
665 716
666 pending_web_ui_.reset(); 717 pending_web_ui_.reset();
667 } 718 }
668 719
669 void RenderViewHostManager::RenderViewDeleted(RenderViewHost* rvh) { 720 void RenderViewHostManager::RenderViewDeleted(RenderViewHost* rvh) {
670 // We are doing this in order to work around and to track a crasher 721 // We are doing this in order to work around and to track a crasher
671 // (http://crbug.com/23411) where it seems that pending_render_view_host_ is 722 // (http://crbug.com/23411) where it seems that pending_render_view_host_ is
672 // deleted (not sure from where) but not NULLed. 723 // deleted (not sure from where) but not NULLed.
673 if (rvh == pending_render_view_host_) { 724 if (rvh == pending_render_view_host_) {
674 // If you hit this NOTREACHED, please report it in the following bug 725 // If you hit this NOTREACHED, please report it in the following bug
675 // http://crbug.com/23411 Make sure to include what you were doing when it 726 // http://crbug.com/23411 Make sure to include what you were doing when it
676 // happened (navigating to a new page, closing a tab...) and if you can 727 // happened (navigating to a new page, closing a tab...) and if you can
677 // reproduce. 728 // reproduce.
678 NOTREACHED(); 729 NOTREACHED();
679 pending_render_view_host_ = NULL; 730 pending_render_view_host_ = NULL;
680 } 731 }
732
733 // Make sure deleted RVHs are not kept in the swapped out list while we are
734 // still alive. (If render_view_host_ is null, we're already being deleted.)
735 if (!render_view_host_)
736 return;
737 // We can't look it up by SiteInstance ID, which may no longer be valid.
738 for (RenderViewHostMap::iterator iter = swapped_out_hosts_.begin();
739 iter != swapped_out_hosts_.end();
740 ++iter) {
741 if (iter->second == rvh) {
742 swapped_out_hosts_.erase(iter);
743 break;
744 }
745 }
681 } 746 }
682 747
683 void RenderViewHostManager::SwapInRenderViewHost(RenderViewHost* rvh) { 748 void RenderViewHostManager::SwapInRenderViewHost(RenderViewHost* rvh) {
749 // TODO(creis): Abstract out the common code between this and CommitPending.
684 web_ui_.reset(); 750 web_ui_.reset();
685 751
686 // Hide the current view and prepare to destroy it. 752 // Make sure the current RVH is swapped out so that it filters out any
687 if (render_view_host_->view()) 753 // disruptive messages from the renderer. We can pass -1,-1 because there is
688 render_view_host_->view()->Hide(); 754 // no pending response in the ResourceDispatcherHost to unpause.
689 RenderViewHost* old_render_view_host = render_view_host_; 755 render_view_host_->SwapOut(-1, -1);
690 756
691 // Swap in the new view and make it active. 757 // Swap in the new view and make it active.
758 RenderViewHost* old_render_view_host = render_view_host_;
692 render_view_host_ = rvh; 759 render_view_host_ = rvh;
693 render_view_host_->set_delegate(render_view_delegate_); 760 render_view_host_->set_delegate(render_view_delegate_);
694 // Remove old RenderWidgetHostView with mocked out methods so it can be 761 // Remove old RenderWidgetHostView with mocked out methods so it can be
695 // replaced with a new one that's a child of |delegate_|'s view. 762 // replaced with a new one that's a child of |delegate_|'s view.
696 scoped_ptr<RenderWidgetHostView> old_view(render_view_host_->view()); 763 scoped_ptr<RenderWidgetHostView> old_view(render_view_host_->view());
697 render_view_host_->set_view(NULL); 764 render_view_host_->set_view(NULL);
698 delegate_->CreateViewAndSetSizeForRVH(render_view_host_); 765 delegate_->CreateViewAndSetSizeForRVH(render_view_host_);
699 render_view_host_->ActivateDeferredPluginHandles(); 766 render_view_host_->ActivateDeferredPluginHandles();
700 // If the view is gone, then this RenderViewHost died while it was hidden. 767 // If the view is gone, then this RenderViewHost died while it was hidden.
701 // We ignored the RenderViewGone call at the time, so we should send it now 768 // We ignored the RenderViewGone call at the time, so we should send it now
702 // to make sure the sad tab shows up, etc. 769 // to make sure the sad tab shows up, etc.
703 if (render_view_host_->view()) { 770 if (render_view_host_->view()) {
704 // The Hide() is needed to sync the state of |render_view_host_|, which is 771 // The Hide() is needed to sync the state of |render_view_host_|, which is
705 // hidden, with the newly created view, which does not know the 772 // hidden, with the newly created view, which does not know the
706 // RenderViewHost is hidden. 773 // RenderViewHost is hidden.
707 // TODO(tburkard,cbentzel): Figure out if this hack can be removed 774 // TODO(tburkard,cbentzel): Figure out if this hack can be removed
708 // (http://crbug.com/79891). 775 // (http://crbug.com/79891).
709 render_view_host_->view()->Hide(); 776 render_view_host_->view()->Hide();
710 render_view_host_->view()->Show(); 777 render_view_host_->view()->Show();
711 } 778 }
712 779
780 // Hide the current view and prepare to swap it out.
781 if (old_render_view_host->view()) {
782 old_render_view_host->view()->Hide();
783 old_render_view_host->WasSwappedOut();
784 }
785
713 delegate_->UpdateRenderViewSizeForRenderManager(); 786 delegate_->UpdateRenderViewSizeForRenderManager();
714 787
715 RenderViewHostSwitchedDetails details; 788 RenderViewHostSwitchedDetails details;
716 details.new_host = render_view_host_; 789 details.new_host = render_view_host_;
717 details.old_host = old_render_view_host; 790 details.old_host = old_render_view_host;
718 NotificationService::current()->Notify( 791 NotificationService::current()->Notify(
719 NotificationType::RENDER_VIEW_HOST_CHANGED, 792 NotificationType::RENDER_VIEW_HOST_CHANGED,
720 Source<NavigationController>(&delegate_->GetControllerForRenderManager()), 793 Source<NavigationController>(&delegate_->GetControllerForRenderManager()),
721 Details<RenderViewHostSwitchedDetails>(&details)); 794 Details<RenderViewHostSwitchedDetails>(&details));
722 795
723 // This will cause the old RenderViewHost to delete itself. 796 // If the given RVH was on the swapped out list, we can remove it.
724 old_render_view_host->Shutdown(); 797 RenderViewHostMap::iterator iter = swapped_out_hosts_.find(
798 render_view_host_->site_instance()->id());
799 if (iter != swapped_out_hosts_.end()) {
800 swapped_out_hosts_.erase(iter);
Matt Perry 2011/04/29 19:25:18 I think you can just do: swapped_out_hosts_.erase(
Charlie Reis 2011/05/05 15:17:59 Done.
801 }
802
803 // If the old RVH is live, we are swapping it out and should keep track of it
804 // in case we navigate back to it.
805 if (old_render_view_host->IsRenderViewLive()) {
806 DCHECK(old_render_view_host->is_swapped_out());
807 swapped_out_hosts_[old_render_view_host->site_instance()->id()] =
808 old_render_view_host;
809 } else {
810 old_render_view_host->Shutdown();
811 }
725 812
726 // Let the task manager know that we've swapped RenderViewHosts, since it 813 // Let the task manager know that we've swapped RenderViewHosts, since it
727 // might need to update its process groupings. 814 // might need to update its process groupings.
728 delegate_->NotifySwappedFromRenderManager(); 815 delegate_->NotifySwappedFromRenderManager();
729 } 816 }
817
818 bool RenderViewHostManager::IsSwappedOut(RenderViewHost* rvh) {
819 if (!rvh->site_instance())
820 return false;
821
822 return swapped_out_hosts_.find(rvh->site_instance()->id()) !=
823 swapped_out_hosts_.end();
824 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698