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/logging.h" | 10 #include "base/logging.h" |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 pending_render_frame_host_->DisownOpener(); | 495 pending_render_frame_host_->DisownOpener(); |
496 } | 496 } |
497 } | 497 } |
498 | 498 |
499 void RenderFrameHostManager::RendererProcessClosing( | 499 void RenderFrameHostManager::RendererProcessClosing( |
500 RenderProcessHost* render_process_host) { | 500 RenderProcessHost* render_process_host) { |
501 // Remove any swapped out RVHs from this process, so that we don't try to | 501 // Remove any swapped out RVHs from this process, so that we don't try to |
502 // swap them back in while the process is exiting. Start by finding them, | 502 // swap them back in while the process is exiting. Start by finding them, |
503 // since there could be more than one. | 503 // since there could be more than one. |
504 std::list<int> ids_to_remove; | 504 std::list<int> ids_to_remove; |
| 505 // Do not remove proxies in the dead process that still have active frame |
| 506 // count though, we just reset them to be uninitialized. |
| 507 std::list<int> ids_to_keep; |
505 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin(); | 508 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin(); |
506 iter != proxy_hosts_.end(); | 509 iter != proxy_hosts_.end(); |
507 ++iter) { | 510 ++iter) { |
508 if (iter->second->GetProcess() == render_process_host) | 511 RenderFrameProxyHost* proxy = iter->second; |
| 512 if (proxy->GetProcess() != render_process_host) |
| 513 continue; |
| 514 |
| 515 if (static_cast<SiteInstanceImpl*>(proxy->GetSiteInstance()) |
| 516 ->active_frame_count() >= 1U) { |
| 517 ids_to_keep.push_back(iter->first); |
| 518 } else { |
509 ids_to_remove.push_back(iter->first); | 519 ids_to_remove.push_back(iter->first); |
| 520 } |
510 } | 521 } |
511 | 522 |
512 // Now delete them. | 523 // Now delete them. |
513 while (!ids_to_remove.empty()) { | 524 while (!ids_to_remove.empty()) { |
514 delete proxy_hosts_[ids_to_remove.back()]; | 525 delete proxy_hosts_[ids_to_remove.back()]; |
515 proxy_hosts_.erase(ids_to_remove.back()); | 526 proxy_hosts_.erase(ids_to_remove.back()); |
516 ids_to_remove.pop_back(); | 527 ids_to_remove.pop_back(); |
517 } | 528 } |
| 529 |
| 530 while (!ids_to_keep.empty()) { |
| 531 frame_tree_node_->frame_tree()->ForEach( |
| 532 base::Bind( |
| 533 &RenderFrameHostManager::ResetProxiesInSiteInstance, |
| 534 ids_to_keep.back())); |
| 535 ids_to_keep.pop_back(); |
| 536 } |
518 } | 537 } |
519 | 538 |
520 void RenderFrameHostManager::SwapOutOldFrame( | 539 void RenderFrameHostManager::SwapOutOldFrame( |
521 scoped_ptr<RenderFrameHostImpl> old_render_frame_host) { | 540 scoped_ptr<RenderFrameHostImpl> old_render_frame_host) { |
522 TRACE_EVENT1("navigation", "RenderFrameHostManager::SwapOutOldFrame", | 541 TRACE_EVENT1("navigation", "RenderFrameHostManager::SwapOutOldFrame", |
523 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 542 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
524 | 543 |
525 // Tell the renderer to suppress any further modal dialogs so that we can swap | 544 // Tell the renderer to suppress any further modal dialogs so that we can swap |
526 // it out. This must be done before canceling any current dialog, in case | 545 // it out. This must be done before canceling any current dialog, in case |
527 // there is a loop creating additional dialogs. | 546 // there is a loop creating additional dialogs. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 // (There should not be one yet.) | 582 // (There should not be one yet.) |
564 CHECK(!GetRenderFrameProxyHost(old_render_frame_host->GetSiteInstance())); | 583 CHECK(!GetRenderFrameProxyHost(old_render_frame_host->GetSiteInstance())); |
565 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( | 584 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( |
566 old_render_frame_host->GetSiteInstance(), frame_tree_node_); | 585 old_render_frame_host->GetSiteInstance(), frame_tree_node_); |
567 CHECK(proxy_hosts_.insert(std::make_pair(old_site_instance_id, proxy)).second) | 586 CHECK(proxy_hosts_.insert(std::make_pair(old_site_instance_id, proxy)).second) |
568 << "Inserting a duplicate item."; | 587 << "Inserting a duplicate item."; |
569 | 588 |
570 // Tell the old RenderFrameHost to swap out and be replaced by the proxy. | 589 // Tell the old RenderFrameHost to swap out and be replaced by the proxy. |
571 old_render_frame_host->SwapOut(proxy, true); | 590 old_render_frame_host->SwapOut(proxy, true); |
572 | 591 |
| 592 // SwapOut creates a RenderFrameProxy, so set the proxy to be initialized. |
| 593 proxy->set_render_frame_proxy_created(true); |
| 594 |
573 bool is_main_frame = frame_tree_node_->IsMainFrame(); | 595 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
574 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 596 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
575 switches::kSitePerProcess) && | 597 switches::kSitePerProcess) && |
576 !is_main_frame) { | 598 !is_main_frame) { |
577 // In --site-per-process, subframes delete their RFH rather than storing it | 599 // In --site-per-process, subframes delete their RFH rather than storing it |
578 // in the proxy. Schedule it for deletion once the SwapOutACK comes in. | 600 // in the proxy. Schedule it for deletion once the SwapOutACK comes in. |
579 // TODO(creis): This will be the default when we remove swappedout://. | 601 // TODO(creis): This will be the default when we remove swappedout://. |
580 MoveToPendingDeleteHosts(old_render_frame_host.Pass()); | 602 MoveToPendingDeleteHosts(old_render_frame_host.Pass()); |
581 } else { | 603 } else { |
582 // We shouldn't get here for subframes, since we only swap subframes when | 604 // We shouldn't get here for subframes, since we only swap subframes when |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 proxy->PassFrameHostOwnership(); | 826 proxy->PassFrameHostOwnership(); |
805 node->render_manager()->MoveToPendingDeleteHosts(swapped_out_rfh.Pass()); | 827 node->render_manager()->MoveToPendingDeleteHosts(swapped_out_rfh.Pass()); |
806 } | 828 } |
807 delete proxy; | 829 delete proxy; |
808 node->render_manager()->proxy_hosts_.erase(site_instance_id); | 830 node->render_manager()->proxy_hosts_.erase(site_instance_id); |
809 } | 831 } |
810 | 832 |
811 return true; | 833 return true; |
812 } | 834 } |
813 | 835 |
| 836 // static. |
| 837 bool RenderFrameHostManager::ResetProxiesInSiteInstance(int32 site_instance_id, |
| 838 FrameTreeNode* node) { |
| 839 RenderFrameProxyHostMap::iterator iter = |
| 840 node->render_manager()->proxy_hosts_.find(site_instance_id); |
| 841 if (iter != node->render_manager()->proxy_hosts_.end()) |
| 842 iter->second->set_render_frame_proxy_created(false); |
| 843 |
| 844 return true; |
| 845 } |
| 846 |
814 bool RenderFrameHostManager::ShouldTransitionCrossSite() { | 847 bool RenderFrameHostManager::ShouldTransitionCrossSite() { |
815 // False in the single-process mode, as it makes RVHs to accumulate | 848 // False in the single-process mode, as it makes RVHs to accumulate |
816 // in swapped_out_hosts_. | 849 // in swapped_out_hosts_. |
817 // True if we are using process-per-site-instance (default) or | 850 // True if we are using process-per-site-instance (default) or |
818 // process-per-site (kProcessPerSite). | 851 // process-per-site (kProcessPerSite). |
819 return !base::CommandLine::ForCurrentProcess()->HasSwitch( | 852 return !base::CommandLine::ForCurrentProcess()->HasSwitch( |
820 switches::kSingleProcess) && | 853 switches::kSingleProcess) && |
821 !base::CommandLine::ForCurrentProcess()->HasSwitch( | 854 !base::CommandLine::ForCurrentProcess()->HasSwitch( |
822 switches::kProcessPerTab); | 855 switches::kProcessPerTab); |
823 } | 856 } |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); | 1419 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); |
1387 if (proxy) | 1420 if (proxy) |
1388 return proxy->GetRoutingID(); | 1421 return proxy->GetRoutingID(); |
1389 | 1422 |
1390 proxy = new RenderFrameProxyHost(instance, frame_tree_node_); | 1423 proxy = new RenderFrameProxyHost(instance, frame_tree_node_); |
1391 proxy_hosts_[instance->GetId()] = proxy; | 1424 proxy_hosts_[instance->GetId()] = proxy; |
1392 proxy->InitRenderFrameProxy(); | 1425 proxy->InitRenderFrameProxy(); |
1393 return proxy->GetRoutingID(); | 1426 return proxy->GetRoutingID(); |
1394 } | 1427 } |
1395 | 1428 |
| 1429 void RenderFrameHostManager::EnsureRenderViewInitialized( |
| 1430 FrameTreeNode* source, |
| 1431 RenderViewHostImpl* render_view_host, |
| 1432 SiteInstance* instance) { |
| 1433 DCHECK(frame_tree_node_->IsMainFrame()); |
| 1434 |
| 1435 if (render_view_host->IsRenderViewLive()) |
| 1436 return; |
| 1437 |
| 1438 // Recreate the opener chain. |
| 1439 int opener_route_id = |
| 1440 delegate_->CreateOpenerRenderViewsForRenderManager(instance); |
| 1441 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); |
| 1442 InitRenderView(render_view_host, opener_route_id, proxy->GetRoutingID(), |
| 1443 source->IsMainFrame()); |
| 1444 } |
| 1445 |
1396 bool RenderFrameHostManager::InitRenderView( | 1446 bool RenderFrameHostManager::InitRenderView( |
1397 RenderViewHostImpl* render_view_host, | 1447 RenderViewHostImpl* render_view_host, |
1398 int opener_route_id, | 1448 int opener_route_id, |
1399 int proxy_routing_id, | 1449 int proxy_routing_id, |
1400 bool for_main_frame_navigation) { | 1450 bool for_main_frame_navigation) { |
1401 // We may have initialized this RenderViewHost for another RenderFrameHost. | 1451 // We may have initialized this RenderViewHost for another RenderFrameHost. |
1402 if (render_view_host->IsRenderViewLive()) | 1452 if (render_view_host->IsRenderViewLive()) |
1403 return true; | 1453 return true; |
1404 | 1454 |
1405 // If the ongoing navigation is to a WebUI and the RenderView is not in a | 1455 // If the ongoing navigation is to a WebUI and the RenderView is not in a |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1447 // the proxy it is replacing, so that it can fully initialize itself. | 1497 // the proxy it is replacing, so that it can fully initialize itself. |
1448 // NOTE: This is the only time that a RenderFrameProxyHost can be in the same | 1498 // NOTE: This is the only time that a RenderFrameProxyHost can be in the same |
1449 // SiteInstance as its RenderFrameHost. This is only the case until the | 1499 // SiteInstance as its RenderFrameHost. This is only the case until the |
1450 // RenderFrameHost commits, at which point it will replace and delete the | 1500 // RenderFrameHost commits, at which point it will replace and delete the |
1451 // RenderFrameProxyHost. | 1501 // RenderFrameProxyHost. |
1452 RenderFrameProxyHost* existing_proxy = | 1502 RenderFrameProxyHost* existing_proxy = |
1453 GetRenderFrameProxyHost(render_frame_host->GetSiteInstance()); | 1503 GetRenderFrameProxyHost(render_frame_host->GetSiteInstance()); |
1454 if (existing_proxy) { | 1504 if (existing_proxy) { |
1455 proxy_routing_id = existing_proxy->GetRoutingID(); | 1505 proxy_routing_id = existing_proxy->GetRoutingID(); |
1456 CHECK_NE(proxy_routing_id, MSG_ROUTING_NONE); | 1506 CHECK_NE(proxy_routing_id, MSG_ROUTING_NONE); |
| 1507 if (!existing_proxy->is_render_frame_proxy_live()) |
| 1508 existing_proxy->InitRenderFrameProxy(); |
1457 } | 1509 } |
1458 return delegate_->CreateRenderFrameForRenderManager(render_frame_host, | 1510 return delegate_->CreateRenderFrameForRenderManager(render_frame_host, |
1459 parent_routing_id, | 1511 parent_routing_id, |
1460 proxy_routing_id); | 1512 proxy_routing_id); |
1461 } | 1513 } |
1462 | 1514 |
1463 int RenderFrameHostManager::GetRoutingIdForSiteInstance( | 1515 int RenderFrameHostManager::GetRoutingIdForSiteInstance( |
1464 SiteInstance* site_instance) { | 1516 SiteInstance* site_instance) { |
1465 if (render_frame_host_->GetSiteInstance() == site_instance) | 1517 if (render_frame_host_->GetSiteInstance() == site_instance) |
1466 return render_frame_host_->GetRoutingID(); | 1518 return render_frame_host_->GetRoutingID(); |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1882 void RenderFrameHostManager::DeleteRenderFrameProxyHost( | 1934 void RenderFrameHostManager::DeleteRenderFrameProxyHost( |
1883 SiteInstance* instance) { | 1935 SiteInstance* instance) { |
1884 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); | 1936 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); |
1885 if (iter != proxy_hosts_.end()) { | 1937 if (iter != proxy_hosts_.end()) { |
1886 delete iter->second; | 1938 delete iter->second; |
1887 proxy_hosts_.erase(iter); | 1939 proxy_hosts_.erase(iter); |
1888 } | 1940 } |
1889 } | 1941 } |
1890 | 1942 |
1891 } // namespace content | 1943 } // namespace content |
OLD | NEW |