| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/frame_host/render_frame_host_manager.h" | 5 #include "content/browser/frame_host/render_frame_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/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 #include "content/public/browser/render_widget_host_iterator.h" | 36 #include "content/public/browser/render_widget_host_iterator.h" |
| 37 #include "content/public/browser/render_widget_host_view.h" | 37 #include "content/public/browser/render_widget_host_view.h" |
| 38 #include "content/public/browser/user_metrics.h" | 38 #include "content/public/browser/user_metrics.h" |
| 39 #include "content/public/browser/web_ui_controller.h" | 39 #include "content/public/browser/web_ui_controller.h" |
| 40 #include "content/public/common/content_switches.h" | 40 #include "content/public/common/content_switches.h" |
| 41 #include "content/public/common/referrer.h" | 41 #include "content/public/common/referrer.h" |
| 42 #include "content/public/common/url_constants.h" | 42 #include "content/public/common/url_constants.h" |
| 43 | 43 |
| 44 namespace content { | 44 namespace content { |
| 45 | 45 |
| 46 // static |
| 46 bool RenderFrameHostManager::ClearRFHsPendingShutdown(FrameTreeNode* node) { | 47 bool RenderFrameHostManager::ClearRFHsPendingShutdown(FrameTreeNode* node) { |
| 47 node->render_manager()->pending_delete_hosts_.clear(); | 48 node->render_manager()->pending_delete_hosts_.clear(); |
| 48 return true; | 49 return true; |
| 49 } | 50 } |
| 50 | 51 |
| 51 RenderFrameHostManager::RenderFrameHostManager( | 52 RenderFrameHostManager::RenderFrameHostManager( |
| 52 FrameTreeNode* frame_tree_node, | 53 FrameTreeNode* frame_tree_node, |
| 53 RenderFrameHostDelegate* render_frame_delegate, | 54 RenderFrameHostDelegate* render_frame_delegate, |
| 54 RenderViewHostDelegate* render_view_delegate, | 55 RenderViewHostDelegate* render_view_delegate, |
| 55 RenderWidgetHostDelegate* render_widget_delegate, | 56 RenderWidgetHostDelegate* render_widget_delegate, |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 } | 463 } |
| 463 | 464 |
| 464 // Now delete them. | 465 // Now delete them. |
| 465 while (!ids_to_remove.empty()) { | 466 while (!ids_to_remove.empty()) { |
| 466 delete proxy_hosts_[ids_to_remove.back()]; | 467 delete proxy_hosts_[ids_to_remove.back()]; |
| 467 proxy_hosts_.erase(ids_to_remove.back()); | 468 proxy_hosts_.erase(ids_to_remove.back()); |
| 468 ids_to_remove.pop_back(); | 469 ids_to_remove.pop_back(); |
| 469 } | 470 } |
| 470 } | 471 } |
| 471 | 472 |
| 472 void RenderFrameHostManager::SwapOutOldPage( | 473 void RenderFrameHostManager::SwapOutOldFrame( |
| 473 RenderFrameHostImpl* old_render_frame_host) { | 474 scoped_ptr<RenderFrameHostImpl> old_render_frame_host) { |
| 474 TRACE_EVENT1("navigation", "RenderFrameHostManager::SwapOutOldPage", | 475 TRACE_EVENT1("navigation", "RenderFrameHostManager::SwapOutOldFrame", |
| 475 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 476 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
| 476 // Should only see this while we have a pending renderer. | |
| 477 CHECK(cross_navigation_pending_); | |
| 478 | 477 |
| 479 // Tell the renderer to suppress any further modal dialogs so that we can swap | 478 // Tell the renderer to suppress any further modal dialogs so that we can swap |
| 480 // it out. This must be done before canceling any current dialog, in case | 479 // it out. This must be done before canceling any current dialog, in case |
| 481 // there is a loop creating additional dialogs. | 480 // there is a loop creating additional dialogs. |
| 482 // TODO(creis): Handle modal dialogs in subframe processes. | 481 // TODO(creis): Handle modal dialogs in subframe processes. |
| 483 old_render_frame_host->render_view_host()->SuppressDialogsUntilSwapOut(); | 482 old_render_frame_host->render_view_host()->SuppressDialogsUntilSwapOut(); |
| 484 | 483 |
| 485 // Now close any modal dialogs that would prevent us from swapping out. This | 484 // Now close any modal dialogs that would prevent us from swapping out. This |
| 486 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is | 485 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is |
| 487 // no longer on the stack when we send the SwapOut message. | 486 // no longer on the stack when we send the SwapOut message. |
| 488 delegate_->CancelModalDialogsForRenderManager(); | 487 delegate_->CancelModalDialogsForRenderManager(); |
| 489 | 488 |
| 490 // Create the RenderFrameProxyHost that will replace the | 489 // If the old RFH is not live, just return as there is no further work to do. |
| 491 // RenderFrameHost which is swapping out. If one exists, ensure it is deleted | 490 // It will be deleted and there will be no proxy created. |
| 492 // from the map and not leaked. | 491 int32 old_site_instance_id = |
| 493 DeleteRenderFrameProxyHost(old_render_frame_host->GetSiteInstance()); | 492 old_render_frame_host->GetSiteInstance()->GetId(); |
| 493 if (!old_render_frame_host->IsRenderFrameLive()) { |
| 494 ShutdownRenderFrameProxyHostsInSiteInstance(old_site_instance_id); |
| 495 return; |
| 496 } |
| 494 | 497 |
| 498 // If there are no active frames besides this one, we can delete the old |
| 499 // RenderFrameHost once it runs its unload handler, without replacing it with |
| 500 // a proxy. |
| 501 size_t active_frame_count = |
| 502 old_render_frame_host->GetSiteInstance()->active_frame_count(); |
| 503 if (active_frame_count <= 1) { |
| 504 // Tell the old RenderFrameHost to swap out, with no proxy to replace it. |
| 505 old_render_frame_host->SwapOut(NULL); |
| 506 MoveToPendingDeleteHosts(old_render_frame_host.Pass()); |
| 507 |
| 508 // Also clear out any proxies from this SiteInstance, in case this was the |
| 509 // last one keeping other proxies alive. |
| 510 ShutdownRenderFrameProxyHostsInSiteInstance(old_site_instance_id); |
| 511 |
| 512 return; |
| 513 } |
| 514 |
| 515 // Otherwise there are active views and we need a proxy for the old RFH. |
| 516 // (There should not be one yet.) |
| 517 CHECK(!GetRenderFrameProxyHost(old_render_frame_host->GetSiteInstance())); |
| 495 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( | 518 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( |
| 496 old_render_frame_host->GetSiteInstance(), frame_tree_node_); | 519 old_render_frame_host->GetSiteInstance(), frame_tree_node_); |
| 497 std::pair<RenderFrameProxyHostMap::iterator, bool> result = | 520 CHECK(proxy_hosts_.insert(std::make_pair(old_site_instance_id, proxy)).second) |
| 498 proxy_hosts_.insert(std::make_pair( | 521 << "Inserting a duplicate item."; |
| 499 old_render_frame_host->GetSiteInstance()->GetId(), proxy)); | |
| 500 CHECK(result.second) << "Inserting a duplicate item."; | |
| 501 | 522 |
| 502 // Tell the old frame it is being swapped out. This will fire the unload | 523 // Tell the old RenderFrameHost to swap out and be replaced by the proxy. |
| 503 // handler in the background (without firing the beforeunload handler a second | |
| 504 // time). This is done right after we commit the new RenderFrameHost. | |
| 505 old_render_frame_host->SwapOut(proxy); | 524 old_render_frame_host->SwapOut(proxy); |
| 525 |
| 526 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
| 527 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess) && |
| 528 !is_main_frame) { |
| 529 // In --site-per-process, subframes delete their RFH rather than storing it |
| 530 // in the proxy. Schedule it for deletion once the SwapOutACK comes in. |
| 531 // TODO(creis): This will be the default when we remove swappedout://. |
| 532 MoveToPendingDeleteHosts(old_render_frame_host.Pass()); |
| 533 } else { |
| 534 // We shouldn't get here for subframes, since we only swap subframes when |
| 535 // --site-per-process is used. |
| 536 DCHECK(is_main_frame); |
| 537 |
| 538 // The old RenderFrameHost will stay alive inside the proxy so that existing |
| 539 // JavaScript window references to it stay valid. |
| 540 proxy->TakeFrameHostOwnership(old_render_frame_host.Pass()); |
| 541 } |
| 506 } | 542 } |
| 507 | 543 |
| 508 void RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance( | 544 void RenderFrameHostManager::MoveToPendingDeleteHosts( |
| 509 int32 site_instance_id, | 545 scoped_ptr<RenderFrameHostImpl> render_frame_host) { |
| 510 RenderFrameHostImpl* rfh) { | 546 // |render_frame_host| will be deleted when its SwapOut ACK is received, or |
| 511 RFHPendingDeleteMap::iterator iter = | 547 // when the timer times out, or when the RFHM itself is deleted (whichever |
| 512 pending_delete_hosts_.find(site_instance_id); | 548 // comes first). |
| 513 if (iter != pending_delete_hosts_.end() && iter->second.get() == rfh) | 549 pending_delete_hosts_.push_back( |
| 514 pending_delete_hosts_.erase(site_instance_id); | 550 linked_ptr<RenderFrameHostImpl>(render_frame_host.release())); |
| 551 } |
| 552 |
| 553 bool RenderFrameHostManager::IsPendingDeletion( |
| 554 RenderFrameHostImpl* render_frame_host) { |
| 555 for (const auto& rfh : pending_delete_hosts_) { |
| 556 if (rfh == render_frame_host) |
| 557 return true; |
| 558 } |
| 559 return false; |
| 560 } |
| 561 |
| 562 bool RenderFrameHostManager::DeleteFromPendingList( |
| 563 RenderFrameHostImpl* render_frame_host) { |
| 564 for (RFHPendingDeleteList::iterator iter = pending_delete_hosts_.begin(); |
| 565 iter != pending_delete_hosts_.end(); |
| 566 iter++) { |
| 567 if (*iter == render_frame_host) { |
| 568 pending_delete_hosts_.erase(iter); |
| 569 return true; |
| 570 } |
| 571 } |
| 572 return false; |
| 515 } | 573 } |
| 516 | 574 |
| 517 void RenderFrameHostManager::ResetProxyHosts() { | 575 void RenderFrameHostManager::ResetProxyHosts() { |
| 518 STLDeleteValues(&proxy_hosts_); | 576 STLDeleteValues(&proxy_hosts_); |
| 519 } | 577 } |
| 520 | 578 |
| 521 // PlzNavigate | 579 // PlzNavigate |
| 522 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( | 580 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( |
| 523 const GURL& url, | 581 const GURL& url, |
| 524 ui::PageTransition transition) { | 582 ui::PageTransition transition) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 case NOTIFICATION_RENDERER_PROCESS_CLOSING: | 617 case NOTIFICATION_RENDERER_PROCESS_CLOSING: |
| 560 RendererProcessClosing( | 618 RendererProcessClosing( |
| 561 Source<RenderProcessHost>(source).ptr()); | 619 Source<RenderProcessHost>(source).ptr()); |
| 562 break; | 620 break; |
| 563 | 621 |
| 564 default: | 622 default: |
| 565 NOTREACHED(); | 623 NOTREACHED(); |
| 566 } | 624 } |
| 567 } | 625 } |
| 568 | 626 |
| 627 // static |
| 569 bool RenderFrameHostManager::ClearProxiesInSiteInstance( | 628 bool RenderFrameHostManager::ClearProxiesInSiteInstance( |
| 570 int32 site_instance_id, | 629 int32 site_instance_id, |
| 571 FrameTreeNode* node) { | 630 FrameTreeNode* node) { |
| 572 RenderFrameProxyHostMap::iterator iter = | 631 RenderFrameProxyHostMap::iterator iter = |
| 573 node->render_manager()->proxy_hosts_.find(site_instance_id); | 632 node->render_manager()->proxy_hosts_.find(site_instance_id); |
| 574 if (iter != node->render_manager()->proxy_hosts_.end()) { | 633 if (iter != node->render_manager()->proxy_hosts_.end()) { |
| 575 RenderFrameProxyHost* proxy = iter->second; | 634 RenderFrameProxyHost* proxy = iter->second; |
| 576 // If the RVH is pending swap out, it needs to switch state to | 635 // Delete the proxy. If it is for a main frame (and thus the RFH is stored |
| 577 // pending shutdown. Otherwise it is deleted. | 636 // in the proxy) and it was still pending swap out, move the RFH to the |
| 578 if (proxy->render_frame_host()->rfh_state() == | 637 // pending deletion list first. |
| 638 if (node->IsMainFrame() && |
| 639 proxy->render_frame_host()->rfh_state() == |
| 579 RenderFrameHostImpl::STATE_PENDING_SWAP_OUT) { | 640 RenderFrameHostImpl::STATE_PENDING_SWAP_OUT) { |
| 580 scoped_ptr<RenderFrameHostImpl> swapped_out_rfh = | 641 scoped_ptr<RenderFrameHostImpl> swapped_out_rfh = |
| 581 proxy->PassFrameHostOwnership(); | 642 proxy->PassFrameHostOwnership(); |
| 582 | 643 node->render_manager()->MoveToPendingDeleteHosts(swapped_out_rfh.Pass()); |
| 583 swapped_out_rfh->SetPendingShutdown(base::Bind( | |
| 584 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance, | |
| 585 node->render_manager()->weak_factory_.GetWeakPtr(), | |
| 586 site_instance_id, | |
| 587 swapped_out_rfh.get())); | |
| 588 RFHPendingDeleteMap::iterator pending_delete_iter = | |
| 589 node->render_manager()->pending_delete_hosts_.find(site_instance_id); | |
| 590 if (pending_delete_iter == | |
| 591 node->render_manager()->pending_delete_hosts_.end() || | |
| 592 pending_delete_iter->second.get() != swapped_out_rfh) { | |
| 593 node->render_manager()->pending_delete_hosts_[site_instance_id] = | |
| 594 linked_ptr<RenderFrameHostImpl>(swapped_out_rfh.release()); | |
| 595 } | |
| 596 } | 644 } |
| 597 delete proxy; | 645 delete proxy; |
| 598 node->render_manager()->proxy_hosts_.erase(site_instance_id); | 646 node->render_manager()->proxy_hosts_.erase(site_instance_id); |
| 599 } | 647 } |
| 600 | 648 |
| 601 return true; | 649 return true; |
| 602 } | 650 } |
| 603 | 651 |
| 604 bool RenderFrameHostManager::ShouldTransitionCrossSite() { | 652 bool RenderFrameHostManager::ShouldTransitionCrossSite() { |
| 605 // False in the single-process mode, as it makes RVHs to accumulate | 653 // False in the single-process mode, as it makes RVHs to accumulate |
| (...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1179 delegate_->SetFocusToLocationBar(false); | 1227 delegate_->SetFocusToLocationBar(false); |
| 1180 return; | 1228 return; |
| 1181 } | 1229 } |
| 1182 | 1230 |
| 1183 // Remember if the page was focused so we can focus the new renderer in | 1231 // Remember if the page was focused so we can focus the new renderer in |
| 1184 // that case. | 1232 // that case. |
| 1185 bool focus_render_view = !will_focus_location_bar && | 1233 bool focus_render_view = !will_focus_location_bar && |
| 1186 render_frame_host_->render_view_host()->GetView() && | 1234 render_frame_host_->render_view_host()->GetView() && |
| 1187 render_frame_host_->render_view_host()->GetView()->HasFocus(); | 1235 render_frame_host_->render_view_host()->GetView()->HasFocus(); |
| 1188 | 1236 |
| 1189 // TODO(creis): As long as show/hide are on RVH, we don't want to do them for | |
| 1190 // subframe navigations or they'll interfere with the top-level page. | |
| 1191 bool is_main_frame = frame_tree_node_->IsMainFrame(); | 1237 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
| 1192 | 1238 |
| 1193 // Swap in the pending frame and make it active. Also ensure the FrameTree | 1239 // Swap in the pending frame and make it active. Also ensure the FrameTree |
| 1194 // stays in sync. | 1240 // stays in sync. |
| 1195 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = | 1241 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = |
| 1196 SetRenderFrameHost(pending_render_frame_host_.Pass()); | 1242 SetRenderFrameHost(pending_render_frame_host_.Pass()); |
| 1197 if (is_main_frame) | 1243 if (is_main_frame) |
| 1198 render_frame_host_->render_view_host()->AttachToFrameTree(); | 1244 render_frame_host_->render_view_host()->AttachToFrameTree(); |
| 1199 | 1245 |
| 1200 // The process will no longer try to exit, so we can decrement the count. | 1246 // The process will no longer try to exit, so we can decrement the count. |
| 1201 render_frame_host_->GetProcess()->RemovePendingView(); | 1247 render_frame_host_->GetProcess()->RemovePendingView(); |
| 1202 | 1248 |
| 1203 // If the view is gone, then this RenderViewHost died while it was hidden. | 1249 // Show the new view (or a sad tab) if necessary. |
| 1204 // We ignored the RenderProcessGone call at the time, so we should send it now | 1250 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); |
| 1205 // to make sure the sad tab shows up, etc. | 1251 if (!delegate_->IsHidden() && new_rfh_has_view) { |
| 1206 if (!render_frame_host_->render_view_host()->GetView()) { | 1252 // In most cases, we need to show the new view. |
| 1253 render_frame_host_->render_view_host()->GetView()->Show(); |
| 1254 } |
| 1255 if (!new_rfh_has_view) { |
| 1256 // If the view is gone, then this RenderViewHost died while it was hidden. |
| 1257 // We ignored the RenderProcessGone call at the time, so we should send it |
| 1258 // now to make sure the sad tab shows up, etc. |
| 1259 DCHECK(!render_frame_host_->IsRenderFrameLive()); |
| 1260 DCHECK(!render_frame_host_->render_view_host()->IsRenderViewLive()); |
| 1207 delegate_->RenderProcessGoneFromRenderManager( | 1261 delegate_->RenderProcessGoneFromRenderManager( |
| 1208 render_frame_host_->render_view_host()); | 1262 render_frame_host_->render_view_host()); |
| 1209 } else if (!delegate_->IsHidden()) { | |
| 1210 render_frame_host_->render_view_host()->GetView()->Show(); | |
| 1211 } | |
| 1212 | |
| 1213 // If the old frame is live, swap it out now that the new frame is visible. | |
| 1214 int32 old_site_instance_id = | |
| 1215 old_render_frame_host->GetSiteInstance()->GetId(); | |
| 1216 if (old_render_frame_host->IsRenderFrameLive()) { | |
| 1217 SwapOutOldPage(old_render_frame_host.get()); | |
| 1218 | |
| 1219 // Schedule the old frame to shut down after it swaps out, if there are no | |
| 1220 // other active frames in its SiteInstance. | |
| 1221 if (!old_render_frame_host->GetSiteInstance()->active_frame_count()) { | |
| 1222 old_render_frame_host->SetPendingShutdown(base::Bind( | |
| 1223 &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance, | |
| 1224 weak_factory_.GetWeakPtr(), | |
| 1225 old_site_instance_id, | |
| 1226 old_render_frame_host.get())); | |
| 1227 } | |
| 1228 } | 1263 } |
| 1229 | 1264 |
| 1230 // For top-level frames, also hide the old RenderViewHost's view. | 1265 // For top-level frames, also hide the old RenderViewHost's view. |
| 1266 // TODO(creis): As long as show/hide are on RVH, we don't want to hide on |
| 1267 // subframe navigations or we will interfere with the top-level frame. |
| 1231 if (is_main_frame && old_render_frame_host->render_view_host()->GetView()) | 1268 if (is_main_frame && old_render_frame_host->render_view_host()->GetView()) |
| 1232 old_render_frame_host->render_view_host()->GetView()->Hide(); | 1269 old_render_frame_host->render_view_host()->GetView()->Hide(); |
| 1233 | 1270 |
| 1234 // Make sure the size is up to date. (Fix for bug 1079768.) | 1271 // Make sure the size is up to date. (Fix for bug 1079768.) |
| 1235 delegate_->UpdateRenderViewSizeForRenderManager(); | 1272 delegate_->UpdateRenderViewSizeForRenderManager(); |
| 1236 | 1273 |
| 1237 if (will_focus_location_bar) { | 1274 if (will_focus_location_bar) { |
| 1238 delegate_->SetFocusToLocationBar(false); | 1275 delegate_->SetFocusToLocationBar(false); |
| 1239 } else if (focus_render_view && | 1276 } else if (focus_render_view && |
| 1240 render_frame_host_->render_view_host()->GetView()) { | 1277 render_frame_host_->render_view_host()->GetView()) { |
| 1241 render_frame_host_->render_view_host()->GetView()->Focus(); | 1278 render_frame_host_->render_view_host()->GetView()->Focus(); |
| 1242 } | 1279 } |
| 1243 | 1280 |
| 1244 // Notify that we've swapped RenderFrameHosts. We do this before shutting down | 1281 // Notify that we've swapped RenderFrameHosts. We do this before shutting down |
| 1245 // the RFH so that we can clean up RendererResources related to the RFH first. | 1282 // the RFH so that we can clean up RendererResources related to the RFH first. |
| 1246 delegate_->NotifySwappedFromRenderManager( | 1283 delegate_->NotifySwappedFromRenderManager( |
| 1247 old_render_frame_host.get(), render_frame_host_.get(), is_main_frame); | 1284 old_render_frame_host.get(), render_frame_host_.get(), is_main_frame); |
| 1248 | 1285 |
| 1249 // If the old RFH is not live, just return as there is no further work to do. | 1286 // Swap out the old frame now that the new one is visible. |
| 1250 if (!old_render_frame_host->IsRenderFrameLive()) | 1287 // This will swap it out and then put it on the proxy list (if there are other |
| 1251 return; | 1288 // active views in its SiteInstance) or schedule it for deletion when the swap |
| 1252 | 1289 // out ack arrives (or immediately if the process isn't live). |
| 1253 // If the old RFH is live, we are swapping it out and should keep track of | 1290 // In the --site-per-process case, old subframe RHFs are not kept alive inside |
| 1254 // it in case we navigate back to it, or it is waiting for the unload event | 1291 // the proxy. |
| 1255 // to execute in the background. | 1292 SwapOutOldFrame(old_render_frame_host.Pass()); |
| 1256 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | |
| 1257 DCHECK(old_render_frame_host->is_swapped_out() || | |
| 1258 !RenderFrameHostImpl::IsRFHStateActive( | |
| 1259 old_render_frame_host->rfh_state())); | |
| 1260 } | |
| 1261 | |
| 1262 // If the RenderViewHost backing the RenderFrameHost is pending shutdown, | |
| 1263 // the RenderFrameHost should be put in the map of RenderFrameHosts pending | |
| 1264 // shutdown. Otherwise, it is stored in the map of proxy hosts. | |
| 1265 if (old_render_frame_host->rfh_state() == | |
| 1266 RenderFrameHostImpl::STATE_PENDING_SHUTDOWN) { | |
| 1267 // The proxy for this RenderFrameHost is created when sending the | |
| 1268 // SwapOut message, so check if it already exists and delete it. | |
| 1269 RenderFrameProxyHostMap::iterator iter = | |
| 1270 proxy_hosts_.find(old_site_instance_id); | |
| 1271 if (iter != proxy_hosts_.end()) { | |
| 1272 delete iter->second; | |
| 1273 proxy_hosts_.erase(iter); | |
| 1274 } | |
| 1275 RFHPendingDeleteMap::iterator pending_delete_iter = | |
| 1276 pending_delete_hosts_.find(old_site_instance_id); | |
| 1277 if (pending_delete_iter == pending_delete_hosts_.end() || | |
| 1278 pending_delete_iter->second.get() != old_render_frame_host) { | |
| 1279 pending_delete_hosts_[old_site_instance_id] = | |
| 1280 linked_ptr<RenderFrameHostImpl>(old_render_frame_host.release()); | |
| 1281 } | |
| 1282 } else { | |
| 1283 CHECK(proxy_hosts_.find(render_frame_host_->GetSiteInstance()->GetId()) == | |
| 1284 proxy_hosts_.end()); | |
| 1285 | |
| 1286 // Capture the active frame count on the old RFH SiteInstance, since the | |
| 1287 // ownership might be passed into the proxy and the pointer will be | |
| 1288 // invalid. | |
| 1289 int active_frame_count = | |
| 1290 old_render_frame_host->GetSiteInstance()->active_frame_count(); | |
| 1291 | |
| 1292 if (is_main_frame) { | |
| 1293 RenderFrameProxyHostMap::iterator iter = | |
| 1294 proxy_hosts_.find(old_site_instance_id); | |
| 1295 CHECK(iter != proxy_hosts_.end()); | |
| 1296 iter->second->TakeFrameHostOwnership(old_render_frame_host.Pass()); | |
| 1297 } | |
| 1298 | |
| 1299 // If there are no active frames in this SiteInstance, it means that | |
| 1300 // this RFH was the last active one in the SiteInstance. Now that we | |
| 1301 // know that all RFHs are swapped out, we can delete all the RFPHs and | |
| 1302 // RVHs in this SiteInstance. | |
| 1303 if (!active_frame_count) { | |
| 1304 ShutdownRenderFrameProxyHostsInSiteInstance(old_site_instance_id); | |
| 1305 } | |
| 1306 } | |
| 1307 | 1293 |
| 1308 // If this is a subframe, it should have a CrossProcessFrameConnector | 1294 // If this is a subframe, it should have a CrossProcessFrameConnector |
| 1309 // created already and we just need to link it to the proper view in the | 1295 // created already. Use it to link the new RFH's view to the proxy that |
| 1310 // new process. | 1296 // belongs to the parent frame's SiteInstance. |
| 1311 if (!is_main_frame) { | 1297 // Note: We do this after swapping out the old RFH because that may create the |
| 1312 RenderFrameProxyHost* proxy = GetProxyToParent(); | 1298 // proxy we're looking for. |
| 1313 if (proxy) { | 1299 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess) && |
| 1314 proxy->SetChildRWHView( | 1300 !is_main_frame) { |
| 1301 RenderFrameProxyHost* proxy_to_parent = GetProxyToParent(); |
| 1302 if (proxy_to_parent) { |
| 1303 proxy_to_parent->SetChildRWHView( |
| 1315 render_frame_host_->render_view_host()->GetView()); | 1304 render_frame_host_->render_view_host()->GetView()); |
| 1316 } | 1305 } |
| 1317 } | 1306 } |
| 1318 } | 1307 } |
| 1319 | 1308 |
| 1320 void RenderFrameHostManager::ShutdownRenderFrameProxyHostsInSiteInstance( | 1309 void RenderFrameHostManager::ShutdownRenderFrameProxyHostsInSiteInstance( |
| 1321 int32 site_instance_id) { | 1310 int32 site_instance_id) { |
| 1322 // First remove any swapped out RFH for this SiteInstance from our own list. | 1311 // First remove any swapped out RFH for this SiteInstance from our own list. |
| 1323 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); | 1312 ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_); |
| 1324 | 1313 |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1600 void RenderFrameHostManager::DeleteRenderFrameProxyHost( | 1589 void RenderFrameHostManager::DeleteRenderFrameProxyHost( |
| 1601 SiteInstance* instance) { | 1590 SiteInstance* instance) { |
| 1602 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); | 1591 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); |
| 1603 if (iter != proxy_hosts_.end()) { | 1592 if (iter != proxy_hosts_.end()) { |
| 1604 delete iter->second; | 1593 delete iter->second; |
| 1605 proxy_hosts_.erase(iter); | 1594 proxy_hosts_.erase(iter); |
| 1606 } | 1595 } |
| 1607 } | 1596 } |
| 1608 | 1597 |
| 1609 } // namespace content | 1598 } // namespace content |
| OLD | NEW |