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 22 matching lines...) Expand all Loading... |
719 | 712 |
720 render_frame_host->CommitNavigation(response, body.Pass(), | 713 render_frame_host->CommitNavigation(response, body.Pass(), |
721 navigation_request->common_params(), | 714 navigation_request->common_params(), |
722 navigation_request->request_params()); | 715 navigation_request->request_params()); |
723 } | 716 } |
724 | 717 |
725 // PlzNavigate | 718 // PlzNavigate |
726 void NavigatorImpl::CancelNavigation(FrameTreeNode* frame_tree_node) { | 719 void NavigatorImpl::CancelNavigation(FrameTreeNode* frame_tree_node) { |
727 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 720 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
728 switches::kEnableBrowserSideNavigation)); | 721 switches::kEnableBrowserSideNavigation)); |
729 navigation_request_map_.erase(frame_tree_node->frame_tree_node_id()); | 722 frame_tree_node->ResetNavigationRequest(false); |
730 if (frame_tree_node->IsMainFrame()) | 723 if (frame_tree_node->IsMainFrame()) |
731 navigation_data_.reset(); | 724 navigation_data_.reset(); |
732 // TODO(carlosk): move this cleanup into the NavigationRequest destructor once | |
733 // we properly cancel ongoing navigations. | |
734 frame_tree_node->render_manager()->CleanUpNavigation(); | |
735 } | |
736 | |
737 // PlzNavigate | |
738 NavigationRequest* NavigatorImpl::GetNavigationRequestForNodeForTesting( | |
739 FrameTreeNode* frame_tree_node) { | |
740 return navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | |
741 } | 725 } |
742 | 726 |
743 bool NavigatorImpl::IsWaitingForBeforeUnloadACK( | 727 bool NavigatorImpl::IsWaitingForBeforeUnloadACK( |
744 FrameTreeNode* frame_tree_node) { | 728 FrameTreeNode* frame_tree_node) { |
745 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 729 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
746 switches::kEnableBrowserSideNavigation)); | 730 switches::kEnableBrowserSideNavigation)); |
747 NavigationRequest* request = | 731 NavigationRequest* request = frame_tree_node->navigation_request(); |
748 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | |
749 if (!request) | 732 if (!request) |
750 return false; | 733 return false; |
751 return request->state() == NavigationRequest::WAITING_FOR_RENDERER_RESPONSE; | 734 return request->state() == NavigationRequest::WAITING_FOR_RENDERER_RESPONSE; |
752 } | 735 } |
753 | 736 |
754 void NavigatorImpl::LogResourceRequestTime( | 737 void NavigatorImpl::LogResourceRequestTime( |
755 base::TimeTicks timestamp, const GURL& url) { | 738 base::TimeTicks timestamp, const GURL& url) { |
756 if (navigation_data_ && navigation_data_->url_ == url) { | 739 if (navigation_data_ && navigation_data_->url_ == url) { |
757 navigation_data_->url_job_start_time_ = timestamp; | 740 navigation_data_->url_job_start_time_ = timestamp; |
758 UMA_HISTOGRAM_TIMES( | 741 UMA_HISTOGRAM_TIMES( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
791 | 774 |
792 // PlzNavigate | 775 // PlzNavigate |
793 void NavigatorImpl::RequestNavigation( | 776 void NavigatorImpl::RequestNavigation( |
794 FrameTreeNode* frame_tree_node, | 777 FrameTreeNode* frame_tree_node, |
795 const NavigationEntryImpl& entry, | 778 const NavigationEntryImpl& entry, |
796 NavigationController::ReloadType reload_type, | 779 NavigationController::ReloadType reload_type, |
797 base::TimeTicks navigation_start) { | 780 base::TimeTicks navigation_start) { |
798 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 781 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
799 switches::kEnableBrowserSideNavigation)); | 782 switches::kEnableBrowserSideNavigation)); |
800 DCHECK(frame_tree_node); | 783 DCHECK(frame_tree_node); |
801 int64 frame_tree_node_id = frame_tree_node->frame_tree_node_id(); | |
802 FrameMsg_Navigate_Type::Value navigation_type = | 784 FrameMsg_Navigate_Type::Value navigation_type = |
803 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); | 785 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); |
804 scoped_ptr<NavigationRequest> navigation_request = | 786 scoped_ptr<NavigationRequest> navigation_request = |
805 NavigationRequest::CreateBrowserInitiated(frame_tree_node, entry, | 787 NavigationRequest::CreateBrowserInitiated(frame_tree_node, entry, |
806 navigation_type, | 788 navigation_type, |
807 navigation_start, controller_); | 789 navigation_start, controller_); |
808 // TODO(clamy): Check if navigations are blocked and if so store the | 790 frame_tree_node->SetNavigationRequest(navigation_request.Pass()); |
809 // parameters. | |
810 | |
811 // If there is an ongoing request, cancel and replace it. | |
812 NavigationRequest* ongoing_request = | |
813 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | |
814 if (ongoing_request) | |
815 CancelNavigation(frame_tree_node); | |
816 | |
817 navigation_request_map_.set(frame_tree_node_id, navigation_request.Pass()); | |
818 | 791 |
819 // Have the current renderer execute its beforeUnload event if needed. If it | 792 // Have the current renderer execute its beforeUnload event if needed. If it |
820 // is not needed (eg. the renderer is not live), BeginNavigation should get | 793 // is not needed (eg. the renderer is not live), BeginNavigation should get |
821 // called. | 794 // called. |
822 NavigationRequest* request_to_send = | 795 frame_tree_node->navigation_request()->SetWaitingForRendererResponse(); |
823 navigation_request_map_.get(frame_tree_node_id); | |
824 request_to_send->SetWaitingForRendererResponse(); | |
825 frame_tree_node->current_frame_host()->DispatchBeforeUnload(true); | 796 frame_tree_node->current_frame_host()->DispatchBeforeUnload(true); |
826 } | 797 } |
827 | 798 |
828 void NavigatorImpl::BeginNavigation(FrameTreeNode* frame_tree_node) { | 799 void NavigatorImpl::BeginNavigation(FrameTreeNode* frame_tree_node) { |
829 NavigationRequest* navigation_request = | 800 NavigationRequest* navigation_request = frame_tree_node->navigation_request(); |
830 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | |
831 | 801 |
832 // A browser-initiated navigation could have been cancelled while it was | 802 // A browser-initiated navigation could have been cancelled while it was |
833 // waiting for the BeforeUnload event to execute. | 803 // waiting for the BeforeUnload event to execute. |
834 if (!navigation_request) | 804 if (!navigation_request) |
835 return; | 805 return; |
836 | 806 |
837 // Start the request. | 807 // Start the request. |
838 if (navigation_request->BeginNavigation()) { | 808 if (navigation_request->BeginNavigation()) { |
839 // If the request was sent to the IO thread, notify the | 809 // If the request was sent to the IO thread, notify the |
840 // RenderFrameHostManager so it can speculatively create a RenderFrameHost | 810 // RenderFrameHostManager so it can speculatively create a RenderFrameHost |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 "Navigation.TimeToCommit_ExistingRenderer_BeforeUnloadDiscounted", | 861 "Navigation.TimeToCommit_ExistingRenderer_BeforeUnloadDiscounted", |
892 time_to_commit); | 862 time_to_commit); |
893 UMA_HISTOGRAM_TIMES( | 863 UMA_HISTOGRAM_TIMES( |
894 "Navigation.TimeToURLJobStart_ExistingRenderer_BeforeUnloadDiscounted", | 864 "Navigation.TimeToURLJobStart_ExistingRenderer_BeforeUnloadDiscounted", |
895 time_to_network); | 865 time_to_network); |
896 } | 866 } |
897 navigation_data_.reset(); | 867 navigation_data_.reset(); |
898 } | 868 } |
899 | 869 |
900 } // namespace content | 870 } // namespace content |
OLD | NEW |