| 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 |