| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 cross_navigation_pending_ = false; | 240 cross_navigation_pending_ = false; |
| 238 } | 241 } |
| 239 } else { | 242 } else { |
| 240 // Non-cross site transition means closing the entire tab. | 243 // Non-cross site transition means closing the entire tab. |
| 241 bool proceed_to_fire_unload; | 244 bool proceed_to_fire_unload; |
| 242 delegate_->BeforeUnloadFiredFromRenderManager(proceed, | 245 delegate_->BeforeUnloadFiredFromRenderManager(proceed, |
| 243 &proceed_to_fire_unload); | 246 &proceed_to_fire_unload); |
| 244 | 247 |
| 245 if (proceed_to_fire_unload) { | 248 if (proceed_to_fire_unload) { |
| 246 // This is not a cross-site navigation, the tab is being closed. | 249 // This is not a cross-site navigation, the tab is being closed. |
| 247 render_view_host_->ClosePage(false, -1, -1); | 250 render_view_host_->ClosePage(); |
| 248 } | 251 } |
| 249 } | 252 } |
| 250 } | 253 } |
| 251 | 254 |
| 252 void RenderViewHostManager::OnCrossSiteResponse(int new_render_process_host_id, | 255 void RenderViewHostManager::OnCrossSiteResponse(int new_render_process_host_id, |
| 253 int new_request_id) { | 256 int new_request_id) { |
| 254 // Should only see this while we have a pending renderer. | 257 // Should only see this while we have a pending renderer. |
| 255 if (!cross_navigation_pending_) | 258 if (!cross_navigation_pending_) |
| 256 return; | 259 return; |
| 257 DCHECK(pending_render_view_host_); | 260 DCHECK(pending_render_view_host_); |
| 258 | 261 |
| 259 // Tell the old renderer to run its onunload handler. When it finishes, it | 262 // 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 | 263 // 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 | 264 // unload handler finishes and the navigation completes, we will send a |
| 262 // resume. | 265 // message to the ResourceDispatcherHost with the given pending request IDs, |
| 263 render_view_host_->ClosePage(true, | 266 // allowing the pending RVH's response to resume. |
| 264 new_render_process_host_id, new_request_id); | 267 render_view_host_->SwapOut(new_render_process_host_id, new_request_id); |
| 265 | 268 |
| 266 // ResourceDispatcherHost has told us to run the onunload handler, which | 269 // 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 | 270 // 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 | 271 // navigation. Thus, we no longer need to remember that the RenderViewHost |
| 269 // is part of a pending cross-site request. | 272 // is part of a pending cross-site request. |
| 270 pending_render_view_host_->SetHasPendingCrossSiteRequest(false, | 273 pending_render_view_host_->SetHasPendingCrossSiteRequest(false, |
| 271 new_request_id); | 274 new_request_id); |
| 272 } | 275 } |
| 273 | 276 |
| 274 void RenderViewHostManager::OnCrossSiteNavigationCanceled() { | 277 void RenderViewHostManager::OnCrossSiteNavigationCanceled() { |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 bool RenderViewHostManager::CreatePendingRenderView( | 455 bool RenderViewHostManager::CreatePendingRenderView( |
| 453 const NavigationEntry& entry, SiteInstance* instance) { | 456 const NavigationEntry& entry, SiteInstance* instance) { |
| 454 NavigationEntry* curr_entry = | 457 NavigationEntry* curr_entry = |
| 455 delegate_->GetControllerForRenderManager().GetLastCommittedEntry(); | 458 delegate_->GetControllerForRenderManager().GetLastCommittedEntry(); |
| 456 if (curr_entry) { | 459 if (curr_entry) { |
| 457 DCHECK(!curr_entry->content_state().empty()); | 460 DCHECK(!curr_entry->content_state().empty()); |
| 458 // TODO(creis): Should send a message to the RenderView to let it know | 461 // 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. | 462 // we're about to switch away, so that it sends an UpdateState message. |
| 460 } | 463 } |
| 461 | 464 |
| 465 // Check if we've already created an RVH for this SiteInstance. |
| 466 CHECK(instance); |
| 467 RenderViewHostMap::iterator iter = |
| 468 swapped_out_hosts_.find(instance->id()); |
| 469 if (iter != swapped_out_hosts_.end()) { |
| 470 // Re-use the existing RenderViewHost, which has already been initialized. |
| 471 // We'll remove it from the list of swapped out hosts if it commits. |
| 472 pending_render_view_host_ = iter->second; |
| 473 return true; |
| 474 } |
| 475 |
| 462 pending_render_view_host_ = RenderViewHostFactory::Create( | 476 pending_render_view_host_ = RenderViewHostFactory::Create( |
| 463 instance, render_view_delegate_, MSG_ROUTING_NONE, delegate_-> | 477 instance, render_view_delegate_, MSG_ROUTING_NONE, delegate_-> |
| 464 GetControllerForRenderManager().session_storage_namespace()); | 478 GetControllerForRenderManager().session_storage_namespace()); |
| 465 | 479 |
| 466 bool success = InitRenderView(pending_render_view_host_, entry); | 480 bool success = InitRenderView(pending_render_view_host_, entry); |
| 467 if (success) { | 481 if (success) { |
| 468 // Don't show the view until we get a DidNavigate from it. | 482 // Don't show the view until we get a DidNavigate from it. |
| 469 pending_render_view_host_->view()->Hide(); | 483 pending_render_view_host_->view()->Hide(); |
| 470 } else { | 484 } else { |
| 471 CancelPending(); | 485 CancelPending(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 if (will_focus_location_bar) | 522 if (will_focus_location_bar) |
| 509 delegate_->SetFocusToLocationBar(false); | 523 delegate_->SetFocusToLocationBar(false); |
| 510 return; | 524 return; |
| 511 } | 525 } |
| 512 | 526 |
| 513 // Remember if the page was focused so we can focus the new renderer in | 527 // Remember if the page was focused so we can focus the new renderer in |
| 514 // that case. | 528 // that case. |
| 515 bool focus_render_view = !will_focus_location_bar && | 529 bool focus_render_view = !will_focus_location_bar && |
| 516 render_view_host_->view() && render_view_host_->view()->HasFocus(); | 530 render_view_host_->view() && render_view_host_->view()->HasFocus(); |
| 517 | 531 |
| 518 // Hide the current view and prepare to destroy it. | 532 // Hide the current view and prepare to swap it out. |
| 519 // TODO(creis): Get the old RenderViewHost to send us an UpdateState message | |
| 520 // before we destroy it. | |
| 521 if (render_view_host_->view()) | 533 if (render_view_host_->view()) |
| 522 render_view_host_->view()->Hide(); | 534 render_view_host_->view()->Hide(); |
| 523 RenderViewHost* old_render_view_host = render_view_host_; | 535 RenderViewHost* old_render_view_host = render_view_host_; |
| 524 | 536 |
| 525 // Swap in the pending view and make it active. | 537 // Swap in the pending view and make it active. |
| 526 render_view_host_ = pending_render_view_host_; | 538 render_view_host_ = pending_render_view_host_; |
| 527 pending_render_view_host_ = NULL; | 539 pending_render_view_host_ = NULL; |
| 528 | 540 |
| 541 // If the pending view was on the swapped out list, we can remove it. |
| 542 RenderViewHostMap::iterator iter = swapped_out_hosts_.find( |
| 543 render_view_host_->site_instance()->id()); |
| 544 if (iter != swapped_out_hosts_.end()) { |
| 545 swapped_out_hosts_.erase(iter); |
| 546 } |
| 547 |
| 529 // If the view is gone, then this RenderViewHost died while it was hidden. | 548 // 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 | 549 // We ignored the RenderViewGone call at the time, so we should send it now |
| 531 // to make sure the sad tab shows up, etc. | 550 // to make sure the sad tab shows up, etc. |
| 532 if (render_view_host_->view()) | 551 if (render_view_host_->view()) |
| 533 render_view_host_->view()->Show(); | 552 render_view_host_->view()->Show(); |
| 534 else | 553 else |
| 535 delegate_->RenderViewGoneFromRenderManager(render_view_host_); | 554 delegate_->RenderViewGoneFromRenderManager(render_view_host_); |
| 536 | 555 |
| 537 // Make sure the size is up to date. (Fix for bug 1079768.) | 556 // Make sure the size is up to date. (Fix for bug 1079768.) |
| 538 delegate_->UpdateRenderViewSizeForRenderManager(); | 557 delegate_->UpdateRenderViewSizeForRenderManager(); |
| 539 | 558 |
| 540 if (will_focus_location_bar) | 559 if (will_focus_location_bar) |
| 541 delegate_->SetFocusToLocationBar(false); | 560 delegate_->SetFocusToLocationBar(false); |
| 542 else if (focus_render_view && render_view_host_->view()) | 561 else if (focus_render_view && render_view_host_->view()) |
| 543 render_view_host_->view()->Focus(); | 562 render_view_host_->view()->Focus(); |
| 544 | 563 |
| 545 RenderViewHostSwitchedDetails details; | 564 RenderViewHostSwitchedDetails details; |
| 546 details.new_host = render_view_host_; | 565 details.new_host = render_view_host_; |
| 547 details.old_host = old_render_view_host; | 566 details.old_host = old_render_view_host; |
| 548 NotificationService::current()->Notify( | 567 NotificationService::current()->Notify( |
| 549 NotificationType::RENDER_VIEW_HOST_CHANGED, | 568 NotificationType::RENDER_VIEW_HOST_CHANGED, |
| 550 Source<NavigationController>(&delegate_->GetControllerForRenderManager()), | 569 Source<NavigationController>(&delegate_->GetControllerForRenderManager()), |
| 551 Details<RenderViewHostSwitchedDetails>(&details)); | 570 Details<RenderViewHostSwitchedDetails>(&details)); |
| 552 | 571 |
| 553 old_render_view_host->Shutdown(); | 572 // Keep track of the old swapped out RVH in case we navigate back to it. |
| 573 swapped_out_hosts_[old_render_view_host->site_instance()->id()] = |
| 574 old_render_view_host; |
| 554 | 575 |
| 555 // Let the task manager know that we've swapped RenderViewHosts, since it | 576 // Let the task manager know that we've swapped RenderViewHosts, since it |
| 556 // might need to update its process groupings. | 577 // might need to update its process groupings. |
| 557 delegate_->NotifySwappedFromRenderManager(); | 578 delegate_->NotifySwappedFromRenderManager(); |
| 558 } | 579 } |
| 559 | 580 |
| 560 RenderViewHost* RenderViewHostManager::UpdateRendererStateForNavigate( | 581 RenderViewHost* RenderViewHostManager::UpdateRendererStateForNavigate( |
| 561 const NavigationEntry& entry) { | 582 const NavigationEntry& entry) { |
| 562 // If we are cross-navigating, then we want to get back to normal and navigate | 583 // If we are cross-navigating, then we want to get back to normal and navigate |
| 563 // as usual. | 584 // as usual. |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 | 675 |
| 655 // Same SiteInstance can be used. Navigate render_view_host_ if we are not | 676 // Same SiteInstance can be used. Navigate render_view_host_ if we are not |
| 656 // cross navigating. | 677 // cross navigating. |
| 657 DCHECK(!cross_navigation_pending_); | 678 DCHECK(!cross_navigation_pending_); |
| 658 return render_view_host_; | 679 return render_view_host_; |
| 659 } | 680 } |
| 660 | 681 |
| 661 void RenderViewHostManager::CancelPending() { | 682 void RenderViewHostManager::CancelPending() { |
| 662 RenderViewHost* pending_render_view_host = pending_render_view_host_; | 683 RenderViewHost* pending_render_view_host = pending_render_view_host_; |
| 663 pending_render_view_host_ = NULL; | 684 pending_render_view_host_ = NULL; |
| 664 pending_render_view_host->Shutdown(); | 685 |
| 686 // Only shutdown the pending RVH if it isn't currently swapped out. |
| 687 // This can happen if we abort a pending load. |
| 688 if (!IsSwappedOut(pending_render_view_host)) |
| 689 pending_render_view_host->Shutdown(); |
| 665 | 690 |
| 666 pending_web_ui_.reset(); | 691 pending_web_ui_.reset(); |
| 667 } | 692 } |
| 668 | 693 |
| 669 void RenderViewHostManager::RenderViewDeleted(RenderViewHost* rvh) { | 694 void RenderViewHostManager::RenderViewDeleted(RenderViewHost* rvh) { |
| 670 // We are doing this in order to work around and to track a crasher | 695 // 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 | 696 // (http://crbug.com/23411) where it seems that pending_render_view_host_ is |
| 672 // deleted (not sure from where) but not NULLed. | 697 // deleted (not sure from where) but not NULLed. |
| 673 if (rvh == pending_render_view_host_) { | 698 if (rvh == pending_render_view_host_) { |
| 674 // If you hit this NOTREACHED, please report it in the following bug | 699 // 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 | 700 // 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 | 701 // happened (navigating to a new page, closing a tab...) and if you can |
| 677 // reproduce. | 702 // reproduce. |
| 678 NOTREACHED(); | 703 NOTREACHED(); |
| 679 pending_render_view_host_ = NULL; | 704 pending_render_view_host_ = NULL; |
| 680 } | 705 } |
| 681 } | 706 } |
| 682 | 707 |
| 683 void RenderViewHostManager::SwapInRenderViewHost(RenderViewHost* rvh) { | 708 void RenderViewHostManager::SwapInRenderViewHost(RenderViewHost* rvh) { |
| 709 // TODO(creis): Abstract out the common code between this and CommitPending. |
| 684 web_ui_.reset(); | 710 web_ui_.reset(); |
| 685 | 711 |
| 686 // Hide the current view and prepare to destroy it. | 712 // Hide the current view and prepare to swap it out. |
| 687 if (render_view_host_->view()) | 713 if (render_view_host_->view()) |
| 688 render_view_host_->view()->Hide(); | 714 render_view_host_->view()->Hide(); |
| 689 RenderViewHost* old_render_view_host = render_view_host_; | 715 RenderViewHost* old_render_view_host = render_view_host_; |
| 690 | 716 |
| 691 // Swap in the new view and make it active. | 717 // Swap in the new view and make it active. |
| 692 render_view_host_ = rvh; | 718 render_view_host_ = rvh; |
| 693 render_view_host_->set_delegate(render_view_delegate_); | 719 render_view_host_->set_delegate(render_view_delegate_); |
| 694 delegate_->CreateViewAndSetSizeForRVH(render_view_host_); | 720 delegate_->CreateViewAndSetSizeForRVH(render_view_host_); |
| 695 render_view_host_->ActivateDeferredPluginHandles(); | 721 render_view_host_->ActivateDeferredPluginHandles(); |
| 696 // If the view is gone, then this RenderViewHost died while it was hidden. | 722 // If the view is gone, then this RenderViewHost died while it was hidden. |
| 697 // We ignored the RenderViewGone call at the time, so we should send it now | 723 // We ignored the RenderViewGone call at the time, so we should send it now |
| 698 // to make sure the sad tab shows up, etc. | 724 // to make sure the sad tab shows up, etc. |
| 699 if (render_view_host_->view()) { | 725 if (render_view_host_->view()) { |
| 700 // TODO(tburkard,cbentzel): Figure out why this hack is needed and/or | 726 // TODO(tburkard,cbentzel): Figure out why this hack is needed and/or |
| 701 // if it can be removed. On Windows, prerendering will not work without | 727 // if it can be removed. On Windows, prerendering will not work without |
| 702 // doing a Hide before the Show. | 728 // doing a Hide before the Show. |
| 703 render_view_host_->view()->Hide(); | 729 render_view_host_->view()->Hide(); |
| 704 render_view_host_->view()->Show(); | 730 render_view_host_->view()->Show(); |
| 705 } | 731 } |
| 706 | 732 |
| 733 // If the given RVH was on the swapped out list, we can remove it. |
| 734 RenderViewHostMap::iterator iter = swapped_out_hosts_.find( |
| 735 render_view_host_->site_instance()->id()); |
| 736 if (iter != swapped_out_hosts_.end()) { |
| 737 swapped_out_hosts_.erase(iter); |
| 738 } |
| 739 |
| 707 delegate_->UpdateRenderViewSizeForRenderManager(); | 740 delegate_->UpdateRenderViewSizeForRenderManager(); |
| 708 | 741 |
| 709 RenderViewHostSwitchedDetails details; | 742 RenderViewHostSwitchedDetails details; |
| 710 details.new_host = render_view_host_; | 743 details.new_host = render_view_host_; |
| 711 details.old_host = old_render_view_host; | 744 details.old_host = old_render_view_host; |
| 712 NotificationService::current()->Notify( | 745 NotificationService::current()->Notify( |
| 713 NotificationType::RENDER_VIEW_HOST_CHANGED, | 746 NotificationType::RENDER_VIEW_HOST_CHANGED, |
| 714 Source<NavigationController>(&delegate_->GetControllerForRenderManager()), | 747 Source<NavigationController>(&delegate_->GetControllerForRenderManager()), |
| 715 Details<RenderViewHostSwitchedDetails>(&details)); | 748 Details<RenderViewHostSwitchedDetails>(&details)); |
| 716 | 749 |
| 717 // This will cause the old RenderViewHost to delete itself. | 750 // Keep track of the old swapped out RVH in case we navigate back to it. |
| 718 old_render_view_host->Shutdown(); | 751 swapped_out_hosts_[old_render_view_host->site_instance()->id()] = |
| 752 old_render_view_host; |
| 719 | 753 |
| 720 // Let the task manager know that we've swapped RenderViewHosts, since it | 754 // Let the task manager know that we've swapped RenderViewHosts, since it |
| 721 // might need to update its process groupings. | 755 // might need to update its process groupings. |
| 722 delegate_->NotifySwappedFromRenderManager(); | 756 delegate_->NotifySwappedFromRenderManager(); |
| 723 } | 757 } |
| 758 |
| 759 bool RenderViewHostManager::IsSwappedOut(RenderViewHost* rvh) { |
| 760 if (!rvh->site_instance()) |
| 761 return false; |
| 762 |
| 763 return swapped_out_hosts_.find(rvh->site_instance()->id()) != |
| 764 swapped_out_hosts_.end(); |
| 765 } |
| OLD | NEW |