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