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 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 } | 360 } |
361 | 361 |
362 void NavigatorImpl::DidNavigate( | 362 void NavigatorImpl::DidNavigate( |
363 RenderFrameHostImpl* render_frame_host, | 363 RenderFrameHostImpl* render_frame_host, |
364 const FrameHostMsg_DidCommitProvisionalLoad_Params& input_params) { | 364 const FrameHostMsg_DidCommitProvisionalLoad_Params& input_params) { |
365 // PlzNavigate | 365 // PlzNavigate |
366 // The navigation request has been committed so the browser process doesn't | 366 // The navigation request has been committed so the browser process doesn't |
367 // need to care about it anymore. | 367 // need to care about it anymore. |
368 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 368 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
369 switches::kEnableBrowserSideNavigation)) { | 369 switches::kEnableBrowserSideNavigation)) { |
370 navigation_request_map_.erase( | 370 render_frame_host->frame_tree_node()->ResetNavigationRequest(true); |
371 render_frame_host->frame_tree_node()->frame_tree_node_id()); | |
372 } | 371 } |
373 | 372 |
374 FrameHostMsg_DidCommitProvisionalLoad_Params params(input_params); | 373 FrameHostMsg_DidCommitProvisionalLoad_Params params(input_params); |
375 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); | 374 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); |
376 bool use_site_per_process = base::CommandLine::ForCurrentProcess()->HasSwitch( | 375 bool use_site_per_process = base::CommandLine::ForCurrentProcess()->HasSwitch( |
377 switches::kSitePerProcess); | 376 switches::kSitePerProcess); |
378 | 377 |
379 if (ui::PageTransitionIsMainFrame(params.transition)) { | 378 if (ui::PageTransitionIsMainFrame(params.transition)) { |
380 if (delegate_) { | 379 if (delegate_) { |
381 // When overscroll navigation gesture is enabled, a screenshot of the page | 380 // When overscroll navigation gesture is enabled, a screenshot of the page |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 delegate_->RequestOpenURL(render_frame_host, params); | 607 delegate_->RequestOpenURL(render_frame_host, params); |
609 } | 608 } |
610 | 609 |
611 // PlzNavigate | 610 // PlzNavigate |
612 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, | 611 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, |
613 bool proceed) { | 612 bool proceed) { |
614 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 613 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
615 switches::kEnableBrowserSideNavigation)); | 614 switches::kEnableBrowserSideNavigation)); |
616 DCHECK(frame_tree_node); | 615 DCHECK(frame_tree_node); |
617 | 616 |
618 NavigationRequest* navigation_request = | 617 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); |
619 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | |
620 | 618 |
621 // The NavigationRequest may have been canceled while the renderer was | 619 // The NavigationRequest may have been canceled while the renderer was |
622 // executing the BeforeUnload event. | 620 // executing the BeforeUnload event. |
623 if (!navigation_request) | 621 if (!navigation_request) |
624 return; | 622 return; |
625 | 623 |
626 DCHECK_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE, | 624 DCHECK_EQ(NavigationRequest::WAITING_FOR_RENDERER_RESPONSE, |
627 navigation_request->state()); | 625 navigation_request->state()); |
628 | 626 |
629 if (proceed) | 627 if (proceed) |
630 BeginNavigation(frame_tree_node); | 628 BeginNavigation(frame_tree_node); |
631 else | 629 else |
632 CancelNavigation(frame_tree_node); | 630 CancelNavigation(frame_tree_node); |
633 } | 631 } |
634 | 632 |
635 // PlzNavigate | 633 // PlzNavigate |
636 void NavigatorImpl::OnBeginNavigation( | 634 void NavigatorImpl::OnBeginNavigation( |
637 FrameTreeNode* frame_tree_node, | 635 FrameTreeNode* frame_tree_node, |
638 const CommonNavigationParams& common_params, | 636 const CommonNavigationParams& common_params, |
639 const BeginNavigationParams& begin_params, | 637 const BeginNavigationParams& begin_params, |
640 scoped_refptr<ResourceRequestBody> body) { | 638 scoped_refptr<ResourceRequestBody> body) { |
641 // This is a renderer-initiated navigation. | 639 // This is a renderer-initiated navigation. |
642 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 640 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
643 switches::kEnableBrowserSideNavigation)); | 641 switches::kEnableBrowserSideNavigation)); |
644 DCHECK(frame_tree_node); | 642 DCHECK(frame_tree_node); |
645 | 643 |
646 NavigationRequest* ongoing_navigation_request = | 644 NavigationRequest* ongoing_navigation_request = |
647 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | 645 frame_tree_node->navigation_request(); |
648 | 646 |
649 // The renderer-initiated navigation request is ignored iff a) there is an | 647 // The renderer-initiated navigation request is ignored iff a) there is an |
650 // ongoing request b) which is browser or user-initiated and c) the renderer | 648 // ongoing request b) which is browser or user-initiated and c) the renderer |
651 // request is not user-initiated. | 649 // request is not user-initiated. |
652 if (ongoing_navigation_request && | 650 if (ongoing_navigation_request && |
653 (ongoing_navigation_request->browser_initiated() || | 651 (ongoing_navigation_request->browser_initiated() || |
654 ongoing_navigation_request->begin_params().has_user_gesture) && | 652 ongoing_navigation_request->begin_params().has_user_gesture) && |
655 !begin_params.has_user_gesture) { | 653 !begin_params.has_user_gesture) { |
656 return; | 654 return; |
657 } | 655 } |
658 | 656 |
659 // In all other cases the current navigation, if any, is canceled and a new | 657 // In all other cases the current navigation, if any, is canceled and a new |
660 // NavigationRequest is created and stored in the map. | 658 // NavigationRequest is created for the node. |
661 if (ongoing_navigation_request) | |
662 CancelNavigation(frame_tree_node); | |
663 | |
664 scoped_ptr<NavigationRequest> navigation_request = | 659 scoped_ptr<NavigationRequest> navigation_request = |
665 NavigationRequest::CreateRendererInitiated( | 660 NavigationRequest::CreateRendererInitiated( |
666 frame_tree_node, common_params, begin_params, body, | 661 frame_tree_node, common_params, begin_params, body, |
667 controller_->GetLastCommittedEntryIndex(), | 662 controller_->GetLastCommittedEntryIndex(), |
668 controller_->GetEntryCount()); | 663 controller_->GetEntryCount()); |
669 navigation_request_map_.set( | 664 frame_tree_node->SetNavigationRequest(navigation_request.Pass()); |
670 frame_tree_node->frame_tree_node_id(), navigation_request.Pass()); | |
671 | 665 |
672 if (frame_tree_node->IsMainFrame()) | 666 if (frame_tree_node->IsMainFrame()) |
673 navigation_data_.reset(); | 667 navigation_data_.reset(); |
674 | 668 |
675 BeginNavigation(frame_tree_node); | 669 BeginNavigation(frame_tree_node); |
676 } | 670 } |
677 | 671 |
678 // PlzNavigate | 672 // PlzNavigate |
679 void NavigatorImpl::CommitNavigation(FrameTreeNode* frame_tree_node, | 673 void NavigatorImpl::CommitNavigation(FrameTreeNode* frame_tree_node, |
680 ResourceResponse* response, | 674 ResourceResponse* response, |
681 scoped_ptr<StreamHandle> body) { | 675 scoped_ptr<StreamHandle> body) { |
682 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 676 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
683 switches::kEnableBrowserSideNavigation)); | 677 switches::kEnableBrowserSideNavigation)); |
684 | 678 |
685 NavigationRequest* navigation_request = | 679 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); |
686 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | |
687 DCHECK(navigation_request); | 680 DCHECK(navigation_request); |
688 DCHECK(response || | 681 DCHECK(response || |
689 !NavigationRequest::ShouldMakeNetworkRequest( | 682 !NavigationRequest::ShouldMakeNetworkRequest( |
690 navigation_request->common_params().url)); | 683 navigation_request->common_params().url)); |
691 | 684 |
692 // HTTP 204 (No Content) and HTTP 205 (Reset Content) responses should not | 685 // HTTP 204 (No Content) and HTTP 205 (Reset Content) responses should not |
693 // commit; they leave the frame showing the previous page. | 686 // commit; they leave the frame showing the previous page. |
694 if (response && response->head.headers.get() && | 687 if (response && response->head.headers.get() && |
695 (response->head.headers->response_code() == 204 || | 688 (response->head.headers->response_code() == 204 || |
696 response->head.headers->response_code() == 205)) { | 689 response->head.headers->response_code() == 205)) { |
(...skipping 25 matching lines...) Expand all Loading... |
722 navigation_request->request_params()); | 715 navigation_request->request_params()); |
723 } | 716 } |
724 | 717 |
725 // PlzNavigate | 718 // PlzNavigate |
726 void NavigatorImpl::FailedNavigation(FrameTreeNode* frame_tree_node, | 719 void NavigatorImpl::FailedNavigation(FrameTreeNode* frame_tree_node, |
727 bool has_stale_copy_in_cache, | 720 bool has_stale_copy_in_cache, |
728 int error_code) { | 721 int error_code) { |
729 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 722 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
730 switches::kEnableBrowserSideNavigation)); | 723 switches::kEnableBrowserSideNavigation)); |
731 | 724 |
732 NavigationRequest* navigation_request = | 725 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); |
733 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | |
734 DCHECK(navigation_request); | 726 DCHECK(navigation_request); |
735 | 727 |
736 // Select an appropriate renderer to show the error page. | 728 // Select an appropriate renderer to show the error page. |
737 RenderFrameHostImpl* render_frame_host = | 729 RenderFrameHostImpl* render_frame_host = |
738 frame_tree_node->render_manager()->GetFrameHostForNavigation( | 730 frame_tree_node->render_manager()->GetFrameHostForNavigation( |
739 *navigation_request); | 731 *navigation_request); |
740 CheckWebUIRendererDoesNotDisplayNormalURL( | 732 CheckWebUIRendererDoesNotDisplayNormalURL( |
741 render_frame_host, navigation_request->common_params().url); | 733 render_frame_host, navigation_request->common_params().url); |
742 | 734 |
743 render_frame_host->FailedNavigation(navigation_request->common_params(), | 735 render_frame_host->FailedNavigation(navigation_request->common_params(), |
744 navigation_request->request_params(), | 736 navigation_request->request_params(), |
745 has_stale_copy_in_cache, error_code); | 737 has_stale_copy_in_cache, error_code); |
746 } | 738 } |
747 | 739 |
748 // PlzNavigate | 740 // PlzNavigate |
749 void NavigatorImpl::CancelNavigation(FrameTreeNode* frame_tree_node) { | 741 void NavigatorImpl::CancelNavigation(FrameTreeNode* frame_tree_node) { |
750 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 742 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
751 switches::kEnableBrowserSideNavigation)); | 743 switches::kEnableBrowserSideNavigation)); |
752 navigation_request_map_.erase(frame_tree_node->frame_tree_node_id()); | 744 frame_tree_node->ResetNavigationRequest(false); |
753 if (frame_tree_node->IsMainFrame()) | 745 if (frame_tree_node->IsMainFrame()) |
754 navigation_data_.reset(); | 746 navigation_data_.reset(); |
755 // TODO(carlosk): move this cleanup into the NavigationRequest destructor once | |
756 // we properly cancel ongoing navigations. | |
757 frame_tree_node->render_manager()->CleanUpNavigation(); | |
758 } | |
759 | |
760 // PlzNavigate | |
761 NavigationRequest* NavigatorImpl::GetNavigationRequestForNodeForTesting( | |
762 FrameTreeNode* frame_tree_node) { | |
763 return navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | |
764 } | 747 } |
765 | 748 |
766 bool NavigatorImpl::IsWaitingForBeforeUnloadACK( | 749 bool NavigatorImpl::IsWaitingForBeforeUnloadACK( |
767 FrameTreeNode* frame_tree_node) { | 750 FrameTreeNode* frame_tree_node) { |
768 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 751 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
769 switches::kEnableBrowserSideNavigation)); | 752 switches::kEnableBrowserSideNavigation)); |
770 NavigationRequest* request = | 753 NavigationRequest* request = frame_tree_node->navigation_request(); |
771 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | |
772 if (!request) | 754 if (!request) |
773 return false; | 755 return false; |
774 return request->state() == NavigationRequest::WAITING_FOR_RENDERER_RESPONSE; | 756 return request->state() == NavigationRequest::WAITING_FOR_RENDERER_RESPONSE; |
775 } | 757 } |
776 | 758 |
777 void NavigatorImpl::LogResourceRequestTime( | 759 void NavigatorImpl::LogResourceRequestTime( |
778 base::TimeTicks timestamp, const GURL& url) { | 760 base::TimeTicks timestamp, const GURL& url) { |
779 if (navigation_data_ && navigation_data_->url_ == url) { | 761 if (navigation_data_ && navigation_data_->url_ == url) { |
780 navigation_data_->url_job_start_time_ = timestamp; | 762 navigation_data_->url_job_start_time_ = timestamp; |
781 UMA_HISTOGRAM_TIMES( | 763 UMA_HISTOGRAM_TIMES( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 | 796 |
815 // PlzNavigate | 797 // PlzNavigate |
816 void NavigatorImpl::RequestNavigation( | 798 void NavigatorImpl::RequestNavigation( |
817 FrameTreeNode* frame_tree_node, | 799 FrameTreeNode* frame_tree_node, |
818 const NavigationEntryImpl& entry, | 800 const NavigationEntryImpl& entry, |
819 NavigationController::ReloadType reload_type, | 801 NavigationController::ReloadType reload_type, |
820 base::TimeTicks navigation_start) { | 802 base::TimeTicks navigation_start) { |
821 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 803 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
822 switches::kEnableBrowserSideNavigation)); | 804 switches::kEnableBrowserSideNavigation)); |
823 DCHECK(frame_tree_node); | 805 DCHECK(frame_tree_node); |
824 int64 frame_tree_node_id = frame_tree_node->frame_tree_node_id(); | |
825 FrameMsg_Navigate_Type::Value navigation_type = | 806 FrameMsg_Navigate_Type::Value navigation_type = |
826 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); | 807 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); |
827 scoped_ptr<NavigationRequest> navigation_request = | 808 scoped_ptr<NavigationRequest> navigation_request = |
828 NavigationRequest::CreateBrowserInitiated(frame_tree_node, entry, | 809 NavigationRequest::CreateBrowserInitiated(frame_tree_node, entry, |
829 navigation_type, | 810 navigation_type, |
830 navigation_start, controller_); | 811 navigation_start, controller_); |
831 // TODO(clamy): Check if navigations are blocked and if so store the | 812 frame_tree_node->SetNavigationRequest(navigation_request.Pass()); |
832 // parameters. | |
833 | |
834 // If there is an ongoing request, cancel and replace it. | |
835 NavigationRequest* ongoing_request = | |
836 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | |
837 if (ongoing_request) | |
838 CancelNavigation(frame_tree_node); | |
839 | |
840 navigation_request_map_.set(frame_tree_node_id, navigation_request.Pass()); | |
841 | 813 |
842 // Have the current renderer execute its beforeUnload event if needed. If it | 814 // Have the current renderer execute its beforeUnload event if needed. If it |
843 // is not needed (eg. the renderer is not live), BeginNavigation should get | 815 // is not needed (eg. the renderer is not live), BeginNavigation should get |
844 // called. | 816 // called. |
845 NavigationRequest* request_to_send = | 817 frame_tree_node->navigation_request()->SetWaitingForRendererResponse(); |
846 navigation_request_map_.get(frame_tree_node_id); | |
847 request_to_send->SetWaitingForRendererResponse(); | |
848 frame_tree_node->current_frame_host()->DispatchBeforeUnload(true); | 818 frame_tree_node->current_frame_host()->DispatchBeforeUnload(true); |
849 } | 819 } |
850 | 820 |
851 void NavigatorImpl::BeginNavigation(FrameTreeNode* frame_tree_node) { | 821 void NavigatorImpl::BeginNavigation(FrameTreeNode* frame_tree_node) { |
852 NavigationRequest* navigation_request = | 822 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); |
853 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | |
854 | 823 |
855 // A browser-initiated navigation could have been cancelled while it was | 824 // A browser-initiated navigation could have been cancelled while it was |
856 // waiting for the BeforeUnload event to execute. | 825 // waiting for the BeforeUnload event to execute. |
857 if (!navigation_request) | 826 if (!navigation_request) |
858 return; | 827 return; |
859 | 828 |
860 // Start the request. | 829 // Start the request. |
861 if (navigation_request->BeginNavigation()) { | 830 if (navigation_request->BeginNavigation()) { |
862 // If the request was sent to the IO thread, notify the | 831 // If the request was sent to the IO thread, notify the |
863 // RenderFrameHostManager so it can speculatively create a RenderFrameHost | 832 // RenderFrameHostManager so it can speculatively create a RenderFrameHost |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 "Navigation.TimeToCommit_ExistingRenderer_BeforeUnloadDiscounted", | 883 "Navigation.TimeToCommit_ExistingRenderer_BeforeUnloadDiscounted", |
915 time_to_commit); | 884 time_to_commit); |
916 UMA_HISTOGRAM_TIMES( | 885 UMA_HISTOGRAM_TIMES( |
917 "Navigation.TimeToURLJobStart_ExistingRenderer_BeforeUnloadDiscounted", | 886 "Navigation.TimeToURLJobStart_ExistingRenderer_BeforeUnloadDiscounted", |
918 time_to_network); | 887 time_to_network); |
919 } | 888 } |
920 navigation_data_.reset(); | 889 navigation_data_.reset(); |
921 } | 890 } |
922 | 891 |
923 } // namespace content | 892 } // namespace content |
OLD | NEW |