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 |