Chromium Code Reviews| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 53 RenderFrameHostDelegate* render_frame_delegate, | 53 RenderFrameHostDelegate* render_frame_delegate, |
| 54 RenderViewHostDelegate* render_view_delegate, | 54 RenderViewHostDelegate* render_view_delegate, |
| 55 RenderWidgetHostDelegate* render_widget_delegate, | 55 RenderWidgetHostDelegate* render_widget_delegate, |
| 56 Delegate* delegate) | 56 Delegate* delegate) |
| 57 : frame_tree_node_(frame_tree_node), | 57 : frame_tree_node_(frame_tree_node), |
| 58 delegate_(delegate), | 58 delegate_(delegate), |
| 59 cross_navigation_pending_(false), | 59 cross_navigation_pending_(false), |
| 60 render_frame_delegate_(render_frame_delegate), | 60 render_frame_delegate_(render_frame_delegate), |
| 61 render_view_delegate_(render_view_delegate), | 61 render_view_delegate_(render_view_delegate), |
| 62 render_widget_delegate_(render_widget_delegate), | 62 render_widget_delegate_(render_widget_delegate), |
| 63 interstitial_page_(NULL), | 63 interstitial_page_(nullptr), |
| 64 should_reuse_web_ui_(false), | |
| 64 weak_factory_(this) { | 65 weak_factory_(this) { |
| 65 DCHECK(frame_tree_node_); | 66 DCHECK(frame_tree_node_); |
| 66 } | 67 } |
| 67 | 68 |
| 68 RenderFrameHostManager::~RenderFrameHostManager() { | 69 RenderFrameHostManager::~RenderFrameHostManager() { |
| 69 if (pending_render_frame_host_) | 70 if (pending_render_frame_host_) |
| 70 UnsetPendingRenderFrameHost(); | 71 UnsetPendingRenderFrameHost(); |
| 71 | 72 |
| 73 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 74 switches::kEnableBrowserSideNavigation)) { | |
| 75 UnsetSpeculativeRenderFrameHost(); | |
| 76 } | |
| 77 | |
| 72 // We should always have a current RenderFrameHost except in some tests. | 78 // We should always have a current RenderFrameHost except in some tests. |
| 73 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); | 79 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); |
| 74 | 80 |
| 75 // Delete any swapped out RenderFrameHosts. | 81 // Delete any swapped out RenderFrameHosts. |
| 76 STLDeleteValues(&proxy_hosts_); | 82 STLDeleteValues(&proxy_hosts_); |
| 77 } | 83 } |
| 78 | 84 |
| 79 void RenderFrameHostManager::Init(BrowserContext* browser_context, | 85 void RenderFrameHostManager::Init(BrowserContext* browser_context, |
| 80 SiteInstance* site_instance, | 86 SiteInstance* site_instance, |
| 81 int view_routing_id, | 87 int view_routing_id, |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 279 } | 285 } |
| 280 } | 286 } |
| 281 return false; | 287 return false; |
| 282 } | 288 } |
| 283 | 289 |
| 284 void RenderFrameHostManager::OnBeforeUnloadACK( | 290 void RenderFrameHostManager::OnBeforeUnloadACK( |
| 285 bool for_cross_site_transition, | 291 bool for_cross_site_transition, |
| 286 bool proceed, | 292 bool proceed, |
| 287 const base::TimeTicks& proceed_time) { | 293 const base::TimeTicks& proceed_time) { |
| 288 if (for_cross_site_transition) { | 294 if (for_cross_site_transition) { |
| 295 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch( | |
| 296 switches::kEnableBrowserSideNavigation)); | |
| 289 // Ignore if we're not in a cross-site navigation. | 297 // Ignore if we're not in a cross-site navigation. |
| 290 if (!cross_navigation_pending_) | 298 if (!cross_navigation_pending_) |
| 291 return; | 299 return; |
| 292 | 300 |
| 293 if (proceed) { | 301 if (proceed) { |
| 294 // Ok to unload the current page, so proceed with the cross-site | 302 // Ok to unload the current page, so proceed with the cross-site |
| 295 // navigation. Note that if navigations are not currently suspended, it | 303 // navigation. Note that if navigations are not currently suspended, it |
| 296 // might be because the renderer was deemed unresponsive and this call was | 304 // might be because the renderer was deemed unresponsive and this call was |
| 297 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it | 305 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it |
| 298 // is ok to do nothing here. | 306 // is ok to do nothing here. |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 404 | 412 |
| 405 response_started_id_.reset(); | 413 response_started_id_.reset(); |
| 406 } | 414 } |
| 407 | 415 |
| 408 void RenderFrameHostManager::ClearNavigationTransitionData() { | 416 void RenderFrameHostManager::ClearNavigationTransitionData() { |
| 409 render_frame_host_->ClearPendingTransitionRequestData(); | 417 render_frame_host_->ClearPendingTransitionRequestData(); |
| 410 } | 418 } |
| 411 | 419 |
| 412 void RenderFrameHostManager::DidNavigateFrame( | 420 void RenderFrameHostManager::DidNavigateFrame( |
| 413 RenderFrameHostImpl* render_frame_host, | 421 RenderFrameHostImpl* render_frame_host, |
| 414 bool was_caused_by_user_gesture) { | 422 bool was_caused_by_user_gesture, |
| 423 bool was_within_same_page) { | |
| 424 DCHECK(render_frame_host); | |
| 425 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 426 switches::kEnableBrowserSideNavigation)) { | |
| 427 if (render_frame_host == speculative_render_frame_host_.get()) { | |
| 428 CommitPending(); | |
| 429 } else if (render_frame_host == render_frame_host_.get()) { | |
|
nasko
2014/12/20 00:09:09
Can't we simplify this if/else to be if (spectulat
carlosk
2014/12/29 16:40:16
If I understood correctly what you meant I think i
| |
| 430 if (!was_within_same_page) { | |
|
nasko
2014/12/20 00:09:09
If statement just for a DCHECK isn't worthwhile. F
carlosk
2014/12/29 16:40:16
Done.
| |
| 431 // This is a same-site navigation driven by the browser. There should | |
| 432 // not be a speculative RenderFrameHost. | |
| 433 DCHECK(!speculative_render_frame_host_.get()); | |
| 434 } else { | |
| 435 if (was_caused_by_user_gesture) { | |
|
nasko
2014/12/20 00:09:09
Let's skip adding the if statement, just add the c
carlosk
2014/12/29 16:40:16
Done.
| |
| 436 // TODO(carlosk): properly cancel an ongoing navigation request. | |
| 437 } | |
| 438 } | |
| 439 } else { | |
| 440 // No one else should be sending us a DidNavigate in this state. | |
| 441 DCHECK(false); | |
| 442 } | |
| 443 DCHECK(!speculative_render_frame_host_.get()); | |
| 444 return; | |
| 445 } | |
| 446 | |
| 415 if (!cross_navigation_pending_) { | 447 if (!cross_navigation_pending_) { |
| 416 DCHECK(!pending_render_frame_host_); | 448 DCHECK(!pending_render_frame_host_); |
| 417 | 449 |
| 418 // We should only hear this from our current renderer. | 450 // We should only hear this from our current renderer. |
| 419 DCHECK_EQ(render_frame_host_, render_frame_host); | 451 DCHECK_EQ(render_frame_host_, render_frame_host); |
| 420 | 452 |
| 421 // Even when there is no pending RVH, there may be a pending Web UI. | 453 // Even when there is no pending RVH, there may be a pending Web UI. |
| 422 if (pending_web_ui()) | 454 if (pending_web_ui()) |
| 423 CommitPending(); | 455 CommitPending(); |
| 424 return; | 456 return; |
| 425 } | 457 } |
| 426 | 458 |
| 427 if (render_frame_host == pending_render_frame_host_) { | 459 if (render_frame_host == pending_render_frame_host_) { |
| 428 // The pending cross-site navigation completed, so show the renderer. | 460 // The pending cross-site navigation completed, so show the renderer. |
| 429 CommitPending(); | 461 CommitPending(); |
| 430 cross_navigation_pending_ = false; | 462 cross_navigation_pending_ = false; |
| 431 } else if (render_frame_host == render_frame_host_) { | 463 } else if (render_frame_host == render_frame_host_) { |
| 432 if (was_caused_by_user_gesture) { | 464 if (was_caused_by_user_gesture) { |
| 433 // A navigation in the original page has taken place. Cancel the pending | 465 // A navigation in the original page has taken place. Cancel the pending |
| 434 // one. Only do it for user gesture originated navigations to prevent | 466 // one. Only do it for user gesture originated navigations to prevent |
| 435 // page doing any shenanigans to prevent user from navigating. | 467 // page doing any shenanigans to prevent user from navigating. |
| 436 // See https://code.google.com/p/chromium/issues/detail?id=75195 | 468 // See https://crbug.com/75195. |
| 437 CancelPending(); | 469 CancelPending(); |
| 438 cross_navigation_pending_ = false; | 470 cross_navigation_pending_ = false; |
| 439 } | 471 } |
| 440 } else { | 472 } else { |
| 441 // No one else should be sending us DidNavigate in this state. | 473 // No one else should be sending us DidNavigate in this state. |
| 442 DCHECK(false); | 474 DCHECK(false); |
| 443 } | 475 } |
| 444 } | 476 } |
| 445 | 477 |
| 446 void RenderFrameHostManager::DidDisownOpener( | 478 void RenderFrameHostManager::DidDisownOpener( |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 564 // If the SiteInstance for the pending RFH is being used by others don't | 596 // If the SiteInstance for the pending RFH is being used by others don't |
| 565 // delete the RFH. Just swap it out and it can be reused at a later point. | 597 // delete the RFH. Just swap it out and it can be reused at a later point. |
| 566 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance(); | 598 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance(); |
| 567 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) { | 599 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) { |
| 568 // Any currently suspended navigations are no longer needed. | 600 // Any currently suspended navigations are no longer needed. |
| 569 render_frame_host->CancelSuspendedNavigations(); | 601 render_frame_host->CancelSuspendedNavigations(); |
| 570 | 602 |
| 571 RenderFrameProxyHost* proxy = | 603 RenderFrameProxyHost* proxy = |
| 572 new RenderFrameProxyHost(site_instance, frame_tree_node_); | 604 new RenderFrameProxyHost(site_instance, frame_tree_node_); |
| 573 proxy_hosts_[site_instance->GetId()] = proxy; | 605 proxy_hosts_[site_instance->GetId()] = proxy; |
| 574 render_frame_host->SwapOut(proxy, false); | 606 |
| 607 if (!render_frame_host->is_swapped_out()) | |
| 608 render_frame_host->SwapOut(proxy, false); | |
| 609 | |
| 575 if (frame_tree_node_->IsMainFrame()) | 610 if (frame_tree_node_->IsMainFrame()) |
| 576 proxy->TakeFrameHostOwnership(render_frame_host.Pass()); | 611 proxy->TakeFrameHostOwnership(render_frame_host.Pass()); |
| 577 } else { | 612 } else { |
| 578 // We won't be coming back, so delete this one. | 613 // We won't be coming back, so delete this one. |
| 579 render_frame_host.reset(); | 614 render_frame_host.reset(); |
| 580 } | 615 } |
| 581 } | 616 } |
| 582 | 617 |
| 583 void RenderFrameHostManager::MoveToPendingDeleteHosts( | 618 void RenderFrameHostManager::MoveToPendingDeleteHosts( |
| 584 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 619 scoped_ptr<RenderFrameHostImpl> render_frame_host) { |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 609 } | 644 } |
| 610 } | 645 } |
| 611 return false; | 646 return false; |
| 612 } | 647 } |
| 613 | 648 |
| 614 void RenderFrameHostManager::ResetProxyHosts() { | 649 void RenderFrameHostManager::ResetProxyHosts() { |
| 615 STLDeleteValues(&proxy_hosts_); | 650 STLDeleteValues(&proxy_hosts_); |
| 616 } | 651 } |
| 617 | 652 |
| 618 // PlzNavigate | 653 // PlzNavigate |
| 654 void RenderFrameHostManager::BeginNavigation( | |
| 655 const FrameHostMsg_BeginNavigation_Params& params, | |
| 656 const CommonNavigationParams& common_params) { | |
| 657 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | |
| 658 switches::kEnableBrowserSideNavigation)); | |
| 659 // Cleans up any state in case there's an ongoing navigation. | |
| 660 // TODO(carlosk): remove this cleanup here once we properly cancel ongoing | |
| 661 // navigations. | |
| 662 CleanUpNavigation(); | |
| 663 | |
| 664 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | |
|
nasko
2014/12/20 00:09:09
The block of code from here to 692 looks almost id
carlosk
2014/12/29 16:40:16
I replied to a very similar comment from creis@ in
clamy
2014/12/29 17:36:21
The thing is we should also make sure here that th
carlosk
2014/12/30 15:54:50
Yes, you are both right in fact! I was utterly con
| |
| 665 // TODO(carlosk): Replace the default values with the right ones for | |
| 666 // source_instance, dest_instance, dest_is_restore, dest_is_view_source_mode. | |
| 667 scoped_refptr<SiteInstanceImpl> new_instance = static_cast<SiteInstanceImpl*>( | |
| 668 GetSiteInstanceForNavigation(common_params.url, nullptr, nullptr, | |
| 669 common_params.transition, false, false)); | |
| 670 | |
| 671 // Will keep the current RFH if its SiteInstance matches the new one from | |
| 672 // the navigation or if this is a subframe navigation. If --site-per-process | |
| 673 // is enabled the RFH is never kept when sites don't match. | |
| 674 // TODO(carlosk): do not swap processes for renderer initiated navigations | |
| 675 // (see crbug.com/440266). | |
| 676 if (current_instance == new_instance.get() || | |
| 677 (!frame_tree_node_->IsMainFrame() && | |
| 678 !CommandLine::ForCurrentProcess()->HasSwitch( | |
| 679 switches::kSitePerProcess))) { | |
| 680 // Make sure the current RFH is alive. | |
| 681 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) { | |
| 682 // Recreate the opener chain. | |
| 683 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( | |
| 684 render_frame_host_->GetSiteInstance()); | |
| 685 bool success = InitRenderView(render_frame_host_->render_view_host(), | |
| 686 opener_route_id, MSG_ROUTING_NONE, | |
| 687 frame_tree_node_->IsMainFrame()); | |
| 688 DCHECK(success); | |
| 689 } | |
| 690 DCHECK(current_instance->GetProcess()->HasConnection()); | |
| 691 return; | |
| 692 } | |
| 693 | |
| 694 // Speculatively create a new RFH. | |
| 695 // TODO(carlosk): enable bindings check below. | |
| 696 bool success = CreateSpeculativeRenderFrameHost( | |
| 697 common_params.url, current_instance, new_instance.get(), | |
| 698 NavigationEntryImpl::kInvalidBindings); | |
| 699 DCHECK(success); | |
| 700 DCHECK(new_instance->GetProcess()->HasConnection()); | |
| 701 } | |
| 702 | |
| 703 // PlzNavigate | |
| 704 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( | |
| 705 const GURL& url, | |
| 706 SiteInstance* old_instance, | |
| 707 SiteInstance* new_instance, | |
| 708 int bindings) { | |
| 709 CHECK(new_instance); | |
| 710 CHECK_NE(old_instance, new_instance); | |
| 711 | |
| 712 const NavigationEntry* current_navigation_entry = | |
| 713 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | |
| 714 scoped_ptr<WebUIImpl> new_web_ui; | |
| 715 should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry, url); | |
| 716 if (!should_reuse_web_ui_) | |
| 717 new_web_ui = CreateWebUI(url, bindings); | |
| 718 | |
| 719 int opener_route_id = | |
| 720 CreateOpenerRenderViewsIfNeeded(old_instance, new_instance); | |
| 721 | |
| 722 int create_render_frame_flags = 0; | |
| 723 if (frame_tree_node_->IsMainFrame()) | |
| 724 create_render_frame_flags |= CREATE_RF_FOR_MAIN_FRAME_NAVIGATION; | |
| 725 if (delegate_->IsHidden()) | |
| 726 create_render_frame_flags |= CREATE_RF_HIDDEN; | |
| 727 scoped_ptr<RenderFrameHostImpl> new_render_frame_host = | |
| 728 CreateRenderFrame(new_instance, new_web_ui.get(), opener_route_id, | |
| 729 create_render_frame_flags, nullptr); | |
| 730 if (!new_render_frame_host) { | |
| 731 return false; | |
| 732 } | |
| 733 speculative_render_frame_host_.reset(new_render_frame_host.release()); | |
| 734 speculative_web_ui_.reset(new_web_ui.release()); | |
| 735 return true; | |
| 736 } | |
| 737 | |
| 738 // PlzNavigate | |
| 619 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( | 739 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( |
| 620 const GURL& url, | 740 const GURL& url, |
| 621 ui::PageTransition transition) { | 741 ui::PageTransition transition) { |
| 622 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | 742 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( |
| 623 switches::kEnableBrowserSideNavigation)); | 743 switches::kEnableBrowserSideNavigation)); |
| 624 // TODO(clamy): When we handle renderer initiated navigations, make sure not | 744 // Pick the right RenderFrameHost to commit the navigation. |
| 625 // to use a different process for subframes if --site-per-process is not | 745 RenderFrameHostImpl* rfh_for_navigation = nullptr; |
| 626 // enabled. | |
| 627 | 746 |
| 628 // Pick the right RenderFrameHost to commit the navigation. | 747 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
| 629 // TODO(clamy): Replace the default values by the right ones. | 748 // TODO(clamy): Replace the default values with the right ones for |
| 630 RenderFrameHostImpl* render_frame_host = UpdateStateForNavigate( | 749 // source_instance, dest_instance, dest_is_restore, dest_is_view_source_mode. |
| 631 url, nullptr, nullptr, transition, false, false, GlobalRequestID(), | 750 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( |
| 632 NavigationEntryImpl::kInvalidBindings); | 751 url, nullptr, nullptr, transition, false, false); |
| 633 | 752 |
| 634 // If the renderer that needs to navigate is not live (it was just created or | 753 // Will keep the current RFH if its SiteInstance matches the new one from |
| 635 // it crashed), initialize it. | 754 // the navigation or if this is a subframe navigation. If --site-per-process |
| 636 if (!render_frame_host->render_view_host()->IsRenderViewLive()) { | 755 // is enabled the RFH is never kept when sites don't match. |
| 756 // TODO(carlosk): do not swap processes for renderer initiated navigations | |
| 757 // (see crbug.com/440266). | |
| 758 if (current_instance == new_instance.get() || | |
| 759 (!frame_tree_node_->IsMainFrame() && | |
| 760 !CommandLine::ForCurrentProcess()->HasSwitch( | |
| 761 switches::kSitePerProcess))) { | |
| 762 CleanUpNavigation(); | |
| 763 rfh_for_navigation = render_frame_host_.get(); | |
| 764 } else { | |
| 765 // If the SiteInstance for the final URL doesn't match the one from the | |
| 766 // speculatively created RenderFrameHost, create a new one using the | |
| 767 // former. | |
|
nasko
2014/12/20 00:09:09
nit: former is what? SiteInstance, URL, or RFH?
carlosk
2014/12/29 16:40:16
I made the comment clearer.
| |
| 768 if (!speculative_render_frame_host_ || | |
| 769 speculative_render_frame_host_->GetSiteInstance() != | |
| 770 new_instance.get()) { | |
| 771 CleanUpNavigation(); | |
| 772 // TODO(clamy): Replace the binding value with the right one. | |
| 773 bool success = CreateSpeculativeRenderFrameHost( | |
| 774 url, current_instance, new_instance.get(), | |
| 775 NavigationEntryImpl::kInvalidBindings); | |
| 776 CHECK(success); | |
| 777 } | |
| 778 DCHECK(speculative_render_frame_host_); | |
| 779 rfh_for_navigation = speculative_render_frame_host_.get(); | |
| 780 } | |
| 781 DCHECK(rfh_for_navigation); | |
| 782 | |
| 783 // If the renderer that needs to navigate is not live (it was just created | |
| 784 // or it crashed), initialize it. | |
| 785 if (!rfh_for_navigation->render_view_host()->IsRenderViewLive()) { | |
| 637 // Recreate the opener chain. | 786 // Recreate the opener chain. |
| 638 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( | 787 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( |
| 639 render_frame_host->GetSiteInstance()); | 788 rfh_for_navigation->GetSiteInstance()); |
| 640 if (!InitRenderView(render_frame_host->render_view_host(), | 789 if (!InitRenderView(rfh_for_navigation->render_view_host(), opener_route_id, |
| 641 opener_route_id, | 790 MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame())) { |
| 642 MSG_ROUTING_NONE, | |
| 643 frame_tree_node_->IsMainFrame())) { | |
| 644 return nullptr; | 791 return nullptr; |
| 645 } | 792 } |
| 646 } | 793 } |
| 647 return render_frame_host; | 794 |
| 795 return rfh_for_navigation; | |
| 796 } | |
| 797 | |
| 798 // PlzNavigate | |
| 799 void RenderFrameHostManager::CleanUpNavigation() { | |
| 800 scoped_ptr<RenderFrameHostImpl> rfh = UnsetSpeculativeRenderFrameHost(); | |
| 801 if (rfh) | |
| 802 DiscardUnusedFrame(rfh.Pass()); | |
| 803 } | |
| 804 | |
| 805 // PlzNavigate | |
| 806 scoped_ptr<RenderFrameHostImpl> | |
| 807 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() { | |
| 808 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | |
| 809 switches::kEnableBrowserSideNavigation)); | |
| 810 if (speculative_web_ui_) | |
| 811 speculative_web_ui_.reset(); | |
| 812 should_reuse_web_ui_ = false; | |
| 813 if (speculative_render_frame_host_) { | |
| 814 speculative_render_frame_host_->GetProcess()->RemovePendingView(); | |
| 815 return speculative_render_frame_host_.Pass(); | |
| 816 } | |
| 817 return nullptr; | |
| 648 } | 818 } |
| 649 | 819 |
| 650 void RenderFrameHostManager::OnDidStartLoading() { | 820 void RenderFrameHostManager::OnDidStartLoading() { |
| 651 for (const auto& pair : proxy_hosts_) { | 821 for (const auto& pair : proxy_hosts_) { |
| 652 pair.second->Send( | 822 pair.second->Send( |
| 653 new FrameMsg_DidStartLoading(pair.second->GetRoutingID())); | 823 new FrameMsg_DidStartLoading(pair.second->GetRoutingID())); |
| 654 } | 824 } |
| 655 } | 825 } |
| 656 | 826 |
| 657 void RenderFrameHostManager::OnDidStopLoading() { | 827 void RenderFrameHostManager::OnDidStopLoading() { |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1078 int frame_routing_id, | 1248 int frame_routing_id, |
| 1079 int flags) { | 1249 int flags) { |
| 1080 if (frame_routing_id == MSG_ROUTING_NONE) | 1250 if (frame_routing_id == MSG_ROUTING_NONE) |
| 1081 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); | 1251 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); |
| 1082 | 1252 |
| 1083 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); | 1253 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); |
| 1084 bool hidden = !!(flags & CREATE_RF_HIDDEN); | 1254 bool hidden = !!(flags & CREATE_RF_HIDDEN); |
| 1085 | 1255 |
| 1086 // Create a RVH for main frames, or find the existing one for subframes. | 1256 // Create a RVH for main frames, or find the existing one for subframes. |
| 1087 FrameTree* frame_tree = frame_tree_node_->frame_tree(); | 1257 FrameTree* frame_tree = frame_tree_node_->frame_tree(); |
| 1088 RenderViewHostImpl* render_view_host = NULL; | 1258 RenderViewHostImpl* render_view_host = nullptr; |
| 1089 if (frame_tree_node_->IsMainFrame()) { | 1259 if (frame_tree_node_->IsMainFrame()) { |
| 1090 render_view_host = frame_tree->CreateRenderViewHost( | 1260 render_view_host = frame_tree->CreateRenderViewHost( |
| 1091 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden); | 1261 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden); |
| 1092 } else { | 1262 } else { |
| 1093 render_view_host = frame_tree->GetRenderViewHost(site_instance); | 1263 render_view_host = frame_tree->GetRenderViewHost(site_instance); |
| 1094 | 1264 |
| 1095 CHECK(render_view_host); | 1265 CHECK(render_view_host); |
| 1096 } | 1266 } |
| 1097 | 1267 |
| 1098 // TODO(creis): Pass hidden to RFH. | 1268 // TODO(creis): Pass hidden to RFH. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1118 // longer relies on swapped out RFH for the top-level frame. | 1288 // longer relies on swapped out RFH for the top-level frame. |
| 1119 if (!frame_tree_node_->IsMainFrame()) { | 1289 if (!frame_tree_node_->IsMainFrame()) { |
| 1120 CHECK(!swapped_out); | 1290 CHECK(!swapped_out); |
| 1121 } | 1291 } |
| 1122 | 1292 |
| 1123 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; | 1293 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; |
| 1124 bool success = true; | 1294 bool success = true; |
| 1125 if (view_routing_id_ptr) | 1295 if (view_routing_id_ptr) |
| 1126 *view_routing_id_ptr = MSG_ROUTING_NONE; | 1296 *view_routing_id_ptr = MSG_ROUTING_NONE; |
| 1127 | 1297 |
| 1128 // We are creating a pending or swapped out RFH here. We should never create | 1298 // We are creating a pending, speculative or swapped out RFH here. We should |
| 1129 // it in the same SiteInstance as our current RFH. | 1299 // never create it in the same SiteInstance as our current RFH. |
| 1130 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); | 1300 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); |
| 1131 | 1301 |
| 1132 // Check if we've already created an RFH for this SiteInstance. If so, try | 1302 // Check if we've already created an RFH for this SiteInstance. If so, try |
| 1133 // to re-use the existing one, which has already been initialized. We'll | 1303 // to re-use the existing one, which has already been initialized. We'll |
| 1134 // remove it from the list of proxy hosts below if it will be active. | 1304 // remove it from the list of proxy hosts below if it will be active. |
| 1135 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); | 1305 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); |
| 1136 if (proxy && proxy->render_frame_host()) { | 1306 if (proxy && proxy->render_frame_host()) { |
| 1137 if (view_routing_id_ptr) | 1307 if (view_routing_id_ptr) |
| 1138 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID(); | 1308 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID(); |
| 1139 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. | 1309 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1296 proxy_hosts_.find(site_instance->GetId()); | 1466 proxy_hosts_.find(site_instance->GetId()); |
| 1297 if (iter != proxy_hosts_.end()) | 1467 if (iter != proxy_hosts_.end()) |
| 1298 return iter->second->GetRoutingID(); | 1468 return iter->second->GetRoutingID(); |
| 1299 | 1469 |
| 1300 return MSG_ROUTING_NONE; | 1470 return MSG_ROUTING_NONE; |
| 1301 } | 1471 } |
| 1302 | 1472 |
| 1303 void RenderFrameHostManager::CommitPending() { | 1473 void RenderFrameHostManager::CommitPending() { |
| 1304 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", | 1474 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", |
| 1305 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 1475 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
| 1476 bool browser_side_navigation = CommandLine::ForCurrentProcess()->HasSwitch( | |
| 1477 switches::kEnableBrowserSideNavigation); | |
| 1306 // First check whether we're going to want to focus the location bar after | 1478 // First check whether we're going to want to focus the location bar after |
| 1307 // this commit. We do this now because the navigation hasn't formally | 1479 // this commit. We do this now because the navigation hasn't formally |
| 1308 // committed yet, so if we've already cleared |pending_web_ui_| the call chain | 1480 // committed yet, so if we've already cleared |pending_web_ui_| the call chain |
| 1309 // this triggers won't be able to figure out what's going on. | 1481 // this triggers won't be able to figure out what's going on. |
| 1310 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); | 1482 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); |
| 1311 | 1483 |
| 1312 // Next commit the Web UI, if any. Either replace |web_ui_| with | 1484 if (!browser_side_navigation) { |
| 1313 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or | 1485 DCHECK(!speculative_web_ui_); |
| 1314 // leave |web_ui_| as is if reusing it. | 1486 // Next commit the Web UI, if any. Either replace |web_ui_| with |
| 1315 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); | 1487 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or |
| 1316 if (pending_web_ui_) { | 1488 // leave |web_ui_| as is if reusing it. |
| 1317 web_ui_.reset(pending_web_ui_.release()); | 1489 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); |
| 1318 } else if (!pending_and_current_web_ui_.get()) { | 1490 if (pending_web_ui_) { |
| 1319 web_ui_.reset(); | 1491 web_ui_.reset(pending_web_ui_.release()); |
| 1492 } else if (!pending_and_current_web_ui_.get()) { | |
| 1493 web_ui_.reset(); | |
| 1494 } else { | |
| 1495 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); | |
| 1496 pending_and_current_web_ui_.reset(); | |
| 1497 } | |
| 1320 } else { | 1498 } else { |
| 1321 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); | 1499 // PlzNavigate |
| 1322 pending_and_current_web_ui_.reset(); | 1500 if (!should_reuse_web_ui_) |
| 1501 web_ui_.reset(speculative_web_ui_.release()); | |
| 1502 DCHECK(!speculative_web_ui_); | |
| 1323 } | 1503 } |
| 1324 | 1504 |
| 1325 // It's possible for the pending_render_frame_host_ to be NULL when we aren't | 1505 // It's possible for the pending_render_frame_host_ to be nullptr when we |
| 1326 // crossing process boundaries. If so, we just needed to handle the Web UI | 1506 // aren't crossing process boundaries. If so, we just needed to handle the Web |
| 1327 // committing above and we're done. | 1507 // UI committing above and we're done. |
| 1328 if (!pending_render_frame_host_) { | 1508 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { |
| 1329 if (will_focus_location_bar) | 1509 if (will_focus_location_bar) |
| 1330 delegate_->SetFocusToLocationBar(false); | 1510 delegate_->SetFocusToLocationBar(false); |
| 1331 return; | 1511 return; |
| 1332 } | 1512 } |
| 1333 | 1513 |
| 1334 // Remember if the page was focused so we can focus the new renderer in | 1514 // Remember if the page was focused so we can focus the new renderer in |
| 1335 // that case. | 1515 // that case. |
| 1336 bool focus_render_view = !will_focus_location_bar && | 1516 bool focus_render_view = !will_focus_location_bar && |
| 1337 render_frame_host_->render_view_host()->GetView() && | 1517 render_frame_host_->render_view_host()->GetView() && |
| 1338 render_frame_host_->render_view_host()->GetView()->HasFocus(); | 1518 render_frame_host_->render_view_host()->GetView()->HasFocus(); |
| 1339 | 1519 |
| 1340 bool is_main_frame = frame_tree_node_->IsMainFrame(); | 1520 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
| 1341 | 1521 |
| 1342 // Swap in the pending frame and make it active. Also ensure the FrameTree | 1522 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; |
| 1343 // stays in sync. | 1523 if (!browser_side_navigation) { |
| 1344 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = | 1524 DCHECK(!speculative_render_frame_host_); |
| 1345 SetRenderFrameHost(pending_render_frame_host_.Pass()); | 1525 // Swap in the pending frame and make it active. Also ensure the FrameTree |
|
nasko
2014/12/20 00:09:09
I think this comment can be updated and put above
carlosk
2014/12/29 16:40:16
Done.
| |
| 1526 // stays in sync. | |
| 1527 old_render_frame_host = | |
| 1528 SetRenderFrameHost(pending_render_frame_host_.Pass()); | |
| 1529 } else { | |
| 1530 // PlzNavigate | |
| 1531 DCHECK(speculative_render_frame_host_); | |
| 1532 old_render_frame_host = | |
| 1533 SetRenderFrameHost(speculative_render_frame_host_.Pass()); | |
| 1534 } | |
| 1535 | |
| 1346 if (is_main_frame) | 1536 if (is_main_frame) |
| 1347 render_frame_host_->render_view_host()->AttachToFrameTree(); | 1537 render_frame_host_->render_view_host()->AttachToFrameTree(); |
| 1348 | 1538 |
| 1349 // The process will no longer try to exit, so we can decrement the count. | 1539 // The process will no longer try to exit, so we can decrement the count. |
| 1350 render_frame_host_->GetProcess()->RemovePendingView(); | 1540 render_frame_host_->GetProcess()->RemovePendingView(); |
| 1351 | 1541 |
| 1352 // Show the new view (or a sad tab) if necessary. | 1542 // Show the new view (or a sad tab) if necessary. |
| 1353 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); | 1543 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); |
| 1354 if (!delegate_->IsHidden() && new_rfh_has_view) { | 1544 if (!delegate_->IsHidden() && new_rfh_has_view) { |
| 1355 // In most cases, we need to show the new view. | 1545 // In most cases, we need to show the new view. |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1480 TRACE_EVENT_INSTANT2( | 1670 TRACE_EVENT_INSTANT2( |
| 1481 "navigation", | 1671 "navigation", |
| 1482 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", | 1672 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", |
| 1483 TRACE_EVENT_SCOPE_THREAD, | 1673 TRACE_EVENT_SCOPE_THREAD, |
| 1484 "current_instance id", current_instance->GetId(), | 1674 "current_instance id", current_instance->GetId(), |
| 1485 "new_instance id", new_instance->GetId()); | 1675 "new_instance id", new_instance->GetId()); |
| 1486 | 1676 |
| 1487 // New SiteInstance: create a pending RFH to navigate. | 1677 // New SiteInstance: create a pending RFH to navigate. |
| 1488 DCHECK(!cross_navigation_pending_); | 1678 DCHECK(!cross_navigation_pending_); |
| 1489 | 1679 |
| 1490 // This will possibly create (set to NULL) a Web UI object for the pending | 1680 // This will possibly create (set to nullptr) a Web UI object for the |
| 1491 // page. We'll use this later to give the page special access. This must | 1681 // pending page. We'll use this later to give the page special access. This |
| 1492 // happen before the new renderer is created below so it will get bindings. | 1682 // must happen before the new renderer is created below so it will get |
| 1493 // It must also happen after the above conditional call to CancelPending(), | 1683 // bindings. It must also happen after the above conditional call to |
| 1494 // otherwise CancelPending may clear the pending_web_ui_ and the page will | 1684 // CancelPending(), otherwise CancelPending may clear the pending_web_ui_ |
| 1495 // not have its bindings set appropriately. | 1685 // and the page will not have its bindings set appropriately. |
| 1496 SetPendingWebUI(dest_url, bindings); | 1686 SetPendingWebUI(dest_url, bindings); |
| 1497 CreatePendingRenderFrameHost(current_instance, new_instance.get(), | 1687 CreatePendingRenderFrameHost(current_instance, new_instance.get(), |
| 1498 frame_tree_node_->IsMainFrame()); | 1688 frame_tree_node_->IsMainFrame()); |
| 1499 if (!pending_render_frame_host_.get()) { | 1689 if (!pending_render_frame_host_.get()) { |
| 1500 return NULL; | 1690 return nullptr; |
| 1501 } | 1691 } |
| 1502 | 1692 |
| 1503 // Check if our current RFH is live before we set up a transition. | 1693 // Check if our current RFH is live before we set up a transition. |
| 1504 if (!render_frame_host_->IsRenderFrameLive()) { | 1694 if (!render_frame_host_->IsRenderFrameLive()) { |
| 1505 if (!cross_navigation_pending_) { | 1695 if (!cross_navigation_pending_) { |
| 1506 // The current RFH is not live. There's no reason to sit around with a | 1696 // The current RFH is not live. There's no reason to sit around with a |
| 1507 // sad tab or a newly created RFH while we wait for the pending RFH to | 1697 // sad tab or a newly created RFH while we wait for the pending RFH to |
| 1508 // navigate. Just switch to the pending RFH now and go back to non | 1698 // navigate. Just switch to the pending RFH now and go back to non |
| 1509 // cross-navigating (Note that we don't care about on{before}unload | 1699 // cross-navigating (Note that we don't care about on{before}unload |
| 1510 // handlers if the current RFH isn't live.) | 1700 // handlers if the current RFH isn't live.) |
| 1511 CommitPending(); | 1701 CommitPending(); |
| 1512 return render_frame_host_.get(); | 1702 return render_frame_host_.get(); |
| 1513 } else { | 1703 } else { |
| 1514 NOTREACHED(); | 1704 NOTREACHED(); |
| 1515 return render_frame_host_.get(); | 1705 return render_frame_host_.get(); |
| 1516 } | 1706 } |
| 1517 } | 1707 } |
| 1518 // Otherwise, it's safe to treat this as a pending cross-site transition. | 1708 // Otherwise, it's safe to treat this as a pending cross-site transition. |
| 1519 | 1709 |
| 1520 // We now have a pending RFH. | 1710 // We now have a pending RFH. |
| 1521 DCHECK(!cross_navigation_pending_); | 1711 DCHECK(!cross_navigation_pending_); |
| 1522 cross_navigation_pending_ = true; | 1712 cross_navigation_pending_ = true; |
| 1523 | 1713 |
| 1524 // PlzNavigate: There is no notion of transfer navigations, and the old | |
| 1525 // renderer before unload handler has already run at that point, so return | |
| 1526 // here. | |
| 1527 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 1528 switches::kEnableBrowserSideNavigation)) { | |
| 1529 return pending_render_frame_host_.get(); | |
| 1530 } | |
| 1531 | |
|
carlosk
2014/12/19 04:27:15
UpdateStateForNavigate is not called by PlzNavigat
| |
| 1532 // We need to wait until the beforeunload handler has run, unless we are | 1714 // We need to wait until the beforeunload handler has run, unless we are |
| 1533 // transferring an existing request (in which case it has already run). | 1715 // transferring an existing request (in which case it has already run). |
| 1534 // Suspend the new render view (i.e., don't let it send the cross-site | 1716 // Suspend the new render view (i.e., don't let it send the cross-site |
| 1535 // Navigate message) until we hear back from the old renderer's | 1717 // Navigate message) until we hear back from the old renderer's |
| 1536 // beforeunload handler. If the handler returns false, we'll have to | 1718 // beforeunload handler. If the handler returns false, we'll have to |
| 1537 // cancel the request. | 1719 // cancel the request. |
| 1538 // | 1720 // |
| 1539 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); | 1721 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); |
| 1540 bool is_transfer = transferred_request_id != GlobalRequestID(); | 1722 bool is_transfer = transferred_request_id != GlobalRequestID(); |
| 1541 if (is_transfer) { | 1723 if (is_transfer) { |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1696 void RenderFrameHostManager::DeleteRenderFrameProxyHost( | 1878 void RenderFrameHostManager::DeleteRenderFrameProxyHost( |
| 1697 SiteInstance* instance) { | 1879 SiteInstance* instance) { |
| 1698 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); | 1880 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); |
| 1699 if (iter != proxy_hosts_.end()) { | 1881 if (iter != proxy_hosts_.end()) { |
| 1700 delete iter->second; | 1882 delete iter->second; |
| 1701 proxy_hosts_.erase(iter); | 1883 proxy_hosts_.erase(iter); |
| 1702 } | 1884 } |
| 1703 } | 1885 } |
| 1704 | 1886 |
| 1705 } // namespace content | 1887 } // namespace content |
| OLD | NEW |