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/navigator_impl.h" | 5 #include "content/browser/frame_host/navigator_impl.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "content/browser/frame_host/frame_tree.h" | 10 #include "content/browser/frame_host/frame_tree.h" |
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); | 593 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); |
594 | 594 |
595 // The NavigationRequest may have been canceled while the renderer was | 595 // The NavigationRequest may have been canceled while the renderer was |
596 // executing the BeforeUnload event. | 596 // executing the BeforeUnload event. |
597 if (!navigation_request) | 597 if (!navigation_request) |
598 return; | 598 return; |
599 | 599 |
600 DCHECK_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE, | 600 DCHECK_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE, |
601 navigation_request->state()); | 601 navigation_request->state()); |
602 | 602 |
| 603 // If the navigation is allowed to proceed, send the request to the IO thread. |
603 if (proceed) | 604 if (proceed) |
604 BeginNavigation(frame_tree_node); | 605 navigation_request->BeginNavigation(); |
605 else | 606 else |
606 CancelNavigation(frame_tree_node); | 607 CancelNavigation(frame_tree_node); |
607 } | 608 } |
608 | 609 |
609 // PlzNavigate | 610 // PlzNavigate |
610 void NavigatorImpl::OnBeginNavigation( | 611 void NavigatorImpl::OnBeginNavigation( |
611 FrameTreeNode* frame_tree_node, | 612 FrameTreeNode* frame_tree_node, |
612 const CommonNavigationParams& common_params, | 613 const CommonNavigationParams& common_params, |
613 const BeginNavigationParams& begin_params, | 614 const BeginNavigationParams& begin_params, |
614 scoped_refptr<ResourceRequestBody> body) { | 615 scoped_refptr<ResourceRequestBody> body) { |
(...skipping 12 matching lines...) Expand all Loading... |
627 // request is not user-initiated. | 628 // request is not user-initiated. |
628 if (ongoing_navigation_request && | 629 if (ongoing_navigation_request && |
629 (ongoing_navigation_request->browser_initiated() || | 630 (ongoing_navigation_request->browser_initiated() || |
630 ongoing_navigation_request->begin_params().has_user_gesture) && | 631 ongoing_navigation_request->begin_params().has_user_gesture) && |
631 !begin_params.has_user_gesture) { | 632 !begin_params.has_user_gesture) { |
632 return; | 633 return; |
633 } | 634 } |
634 | 635 |
635 // In all other cases the current navigation, if any, is canceled and a new | 636 // In all other cases the current navigation, if any, is canceled and a new |
636 // NavigationRequest is created for the node. | 637 // NavigationRequest is created for the node. |
637 scoped_ptr<NavigationRequest> navigation_request = | 638 frame_tree_node->CreatedNavigationRequest( |
638 NavigationRequest::CreateRendererInitiated( | 639 NavigationRequest::CreateRendererInitiated( |
639 frame_tree_node, common_params, begin_params, body, | 640 frame_tree_node, common_params, begin_params, body, |
640 controller_->GetLastCommittedEntryIndex(), | 641 controller_->GetLastCommittedEntryIndex(), |
641 controller_->GetEntryCount()); | 642 controller_->GetEntryCount())); |
642 frame_tree_node->SetNavigationRequest(navigation_request.Pass()); | 643 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); |
643 | 644 |
644 if (frame_tree_node->IsMainFrame()) { | 645 if (frame_tree_node->IsMainFrame()) { |
645 // Renderer-initiated main-frame navigations that need to swap processes | 646 // Renderer-initiated main-frame navigations that need to swap processes |
646 // will go to the browser via a OpenURL call, and then be handled by the | 647 // will go to the browser via a OpenURL call, and then be handled by the |
647 // same code path as browser-initiated navigations. For renderer-initiated | 648 // same code path as browser-initiated navigations. For renderer-initiated |
648 // main frame navigation that start via a BeginNavigation IPC, the | 649 // main frame navigation that start via a BeginNavigation IPC, the |
649 // RenderFrameHost will not be swapped. Therefore it is safe to call | 650 // RenderFrameHost will not be swapped. Therefore it is safe to call |
650 // DidStartMainFrameNavigation with the SiteInstance from the current | 651 // DidStartMainFrameNavigation with the SiteInstance from the current |
651 // RenderFrameHost. | 652 // RenderFrameHost. |
652 DidStartMainFrameNavigation( | 653 DidStartMainFrameNavigation( |
653 common_params.url, | 654 common_params.url, |
654 frame_tree_node->current_frame_host()->GetSiteInstance()); | 655 frame_tree_node->current_frame_host()->GetSiteInstance()); |
655 navigation_data_.reset(); | 656 navigation_data_.reset(); |
656 } | 657 } |
657 | 658 |
658 BeginNavigation(frame_tree_node); | 659 navigation_request->BeginNavigation(); |
659 } | 660 } |
660 | 661 |
661 // PlzNavigate | 662 // PlzNavigate |
662 void NavigatorImpl::CommitNavigation(FrameTreeNode* frame_tree_node, | 663 void NavigatorImpl::CommitNavigation(FrameTreeNode* frame_tree_node, |
663 ResourceResponse* response, | 664 ResourceResponse* response, |
664 scoped_ptr<StreamHandle> body) { | 665 scoped_ptr<StreamHandle> body) { |
665 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 666 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
666 switches::kEnableBrowserSideNavigation)); | 667 switches::kEnableBrowserSideNavigation)); |
667 | 668 |
668 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); | 669 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
796 | 797 |
797 // PlzNavigate | 798 // PlzNavigate |
798 void NavigatorImpl::RequestNavigation( | 799 void NavigatorImpl::RequestNavigation( |
799 FrameTreeNode* frame_tree_node, | 800 FrameTreeNode* frame_tree_node, |
800 const NavigationEntryImpl& entry, | 801 const NavigationEntryImpl& entry, |
801 NavigationController::ReloadType reload_type, | 802 NavigationController::ReloadType reload_type, |
802 base::TimeTicks navigation_start) { | 803 base::TimeTicks navigation_start) { |
803 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 804 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
804 switches::kEnableBrowserSideNavigation)); | 805 switches::kEnableBrowserSideNavigation)); |
805 DCHECK(frame_tree_node); | 806 DCHECK(frame_tree_node); |
| 807 |
| 808 // This value must be set here because creating a NavigationRequest might |
| 809 // change the renderer live/non-live status and change this result. |
| 810 bool should_dispatch_beforeunload = |
| 811 frame_tree_node->current_frame_host()->ShouldDispatchBeforeUnload(); |
806 FrameMsg_Navigate_Type::Value navigation_type = | 812 FrameMsg_Navigate_Type::Value navigation_type = |
807 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); | 813 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); |
808 scoped_ptr<NavigationRequest> navigation_request = | 814 frame_tree_node->CreatedNavigationRequest( |
809 NavigationRequest::CreateBrowserInitiated(frame_tree_node, entry, | 815 NavigationRequest::CreateBrowserInitiated(frame_tree_node, entry, |
810 navigation_type, | 816 navigation_type, |
811 navigation_start, controller_); | 817 navigation_start, controller_)); |
812 frame_tree_node->SetNavigationRequest(navigation_request.Pass()); | 818 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); |
813 frame_tree_node->navigation_request()->SetWaitingForRendererResponse(); | |
814 | 819 |
815 // Have the current renderer execute its beforeUnload event if needed. If it | 820 // Have the current renderer execute its beforeunload event if needed. If it |
816 // is not needed (eg. the renderer is not live), BeginNavigation should get | 821 // is not needed (when beforeunload dispatch is not needed or this navigation |
817 // called. If the navigation is synchronous and same-site, then it can be sent | 822 // is synchronous and same-site) then NavigationRequest::BeginNavigation |
818 // directly to the renderer (currently this is the case for navigations that | 823 // should be directly called instead. |
819 // do not make network requests such as data urls or Javascript urls). | 824 if (should_dispatch_beforeunload && |
820 if (NavigationRequest::ShouldMakeNetworkRequest( | 825 NavigationRequest::ShouldMakeNetworkRequest( |
821 frame_tree_node->navigation_request()->common_params().url)) { | 826 navigation_request->common_params().url)) { |
| 827 navigation_request->SetWaitingForRendererResponse(); |
822 frame_tree_node->current_frame_host()->DispatchBeforeUnload(true); | 828 frame_tree_node->current_frame_host()->DispatchBeforeUnload(true); |
823 } else { | 829 } else { |
824 BeginNavigation(frame_tree_node); | 830 navigation_request->BeginNavigation(); |
825 } | 831 } |
826 } | 832 } |
827 | 833 |
828 void NavigatorImpl::BeginNavigation(FrameTreeNode* frame_tree_node) { | |
829 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); | |
830 | |
831 // A browser-initiated navigation could have been cancelled while it was | |
832 // waiting for the BeforeUnload event to execute. | |
833 if (!navigation_request) | |
834 return; | |
835 | |
836 // Start the request. | |
837 if (navigation_request->BeginNavigation()) { | |
838 // If the request was sent to the IO thread, notify the | |
839 // RenderFrameHostManager so it can speculatively create a RenderFrameHost | |
840 // (and potentially a new renderer process) in parallel. | |
841 frame_tree_node->render_manager()->BeginNavigation(*navigation_request); | |
842 } | |
843 } | |
844 | |
845 void NavigatorImpl::RecordNavigationMetrics( | 834 void NavigatorImpl::RecordNavigationMetrics( |
846 const LoadCommittedDetails& details, | 835 const LoadCommittedDetails& details, |
847 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 836 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
848 SiteInstance* site_instance) { | 837 SiteInstance* site_instance) { |
849 DCHECK(site_instance->HasProcess()); | 838 DCHECK(site_instance->HasProcess()); |
850 | 839 |
851 if (!details.is_in_page) | 840 if (!details.is_in_page) |
852 RecordAction(base::UserMetricsAction("FrameLoad")); | 841 RecordAction(base::UserMetricsAction("FrameLoad")); |
853 | 842 |
854 if (!details.is_main_frame || !navigation_data_ || | 843 if (!details.is_main_frame || !navigation_data_ || |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 entry->set_should_replace_entry(pending_entry->should_replace_entry()); | 911 entry->set_should_replace_entry(pending_entry->should_replace_entry()); |
923 entry->SetRedirectChain(pending_entry->GetRedirectChain()); | 912 entry->SetRedirectChain(pending_entry->GetRedirectChain()); |
924 } | 913 } |
925 controller_->SetPendingEntry(entry); | 914 controller_->SetPendingEntry(entry); |
926 if (delegate_) | 915 if (delegate_) |
927 delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL); | 916 delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL); |
928 } | 917 } |
929 } | 918 } |
930 | 919 |
931 } // namespace content | 920 } // namespace content |
OLD | NEW |