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