Chromium Code Reviews| 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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 172 } else { | 172 } else { |
| 173 params->redirects.clear(); | 173 params->redirects.clear(); |
| 174 } | 174 } |
| 175 | 175 |
| 176 params->can_load_local_resources = entry.GetCanLoadLocalResources(); | 176 params->can_load_local_resources = entry.GetCanLoadLocalResources(); |
| 177 params->frame_to_navigate = entry.GetFrameToNavigate(); | 177 params->frame_to_navigate = entry.GetFrameToNavigate(); |
| 178 } | 178 } |
| 179 | 179 |
| 180 } // namespace | 180 } // namespace |
| 181 | 181 |
| 182 class NavigatorImpl::NavigationMetricsData { | |
|
clamy
2014/10/09 19:02:32
I think this should be a struct. If you keep it a
carlosk
2014/10/10 10:00:04
Done.
| |
| 183 public: | |
| 184 NavigationMetricsData() {} | |
| 185 ~NavigationMetricsData() {} | |
| 182 | 186 |
| 183 NavigatorImpl::NavigatorImpl( | 187 void Reset(); |
| 184 NavigationControllerImpl* navigation_controller, | 188 void Set(base::TimeTicks start_time, GURL url); |
|
clamy
2014/10/09 19:02:32
I would remove those methods and use the scoped_pt
carlosk
2014/10/10 10:00:04
Done! Much better indeed!
| |
| 185 NavigatorDelegate* delegate) | 189 bool IsTracking(); |
| 190 | |
| 191 base::TimeTicks start_time_; | |
| 192 GURL url_; | |
| 193 base::TimeTicks url_job_start_time_; | |
| 194 base::TimeDelta before_unload_delay_; | |
| 195 }; | |
| 196 | |
| 197 void NavigatorImpl::NavigationMetricsData::Reset() { | |
| 198 start_time_ = base::TimeTicks(); | |
| 199 url_ = GURL(); | |
| 200 url_job_start_time_ = base::TimeTicks(); | |
| 201 before_unload_delay_ = base::TimeDelta(); | |
| 202 } | |
| 203 | |
| 204 void NavigatorImpl::NavigationMetricsData::Set(base::TimeTicks start_time, | |
| 205 GURL url) { | |
| 206 start_time_ = start_time; | |
| 207 url_ = url; | |
| 208 url_job_start_time_ = base::TimeTicks(); | |
| 209 before_unload_delay_ = base::TimeDelta(); | |
| 210 } | |
| 211 | |
| 212 bool NavigatorImpl::NavigationMetricsData::IsTracking() { | |
| 213 return !start_time_.is_null(); | |
| 214 } | |
| 215 | |
| 216 NavigatorImpl::NavigatorImpl(NavigationControllerImpl* navigation_controller, | |
| 217 NavigatorDelegate* delegate) | |
| 186 : controller_(navigation_controller), | 218 : controller_(navigation_controller), |
| 187 delegate_(delegate) { | 219 delegate_(delegate), |
| 220 navigation_data_(new NavigationMetricsData()) { | |
| 188 } | 221 } |
| 189 | 222 |
| 190 NavigatorImpl::~NavigatorImpl() {} | 223 NavigatorImpl::~NavigatorImpl() {} |
| 191 | 224 |
| 192 NavigationController* NavigatorImpl::GetController() { | 225 NavigationController* NavigatorImpl::GetController() { |
| 193 return controller_; | 226 return controller_; |
| 194 } | 227 } |
| 195 | 228 |
| 196 void NavigatorImpl::DidStartProvisionalLoad( | 229 void NavigatorImpl::DidStartProvisionalLoad( |
| 197 RenderFrameHostImpl* render_frame_host, | 230 RenderFrameHostImpl* render_frame_host, |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 354 // "Open link in new tab"). We need to keep it above RFHM::Navigate() call to | 387 // "Open link in new tab"). We need to keep it above RFHM::Navigate() call to |
| 355 // capture the time needed for the RenderFrameHost initialization. | 388 // capture the time needed for the RenderFrameHost initialization. |
| 356 base::TimeTicks navigation_start = base::TimeTicks::Now(); | 389 base::TimeTicks navigation_start = base::TimeTicks::Now(); |
| 357 | 390 |
| 358 RenderFrameHostManager* manager = | 391 RenderFrameHostManager* manager = |
| 359 render_frame_host->frame_tree_node()->render_manager(); | 392 render_frame_host->frame_tree_node()->render_manager(); |
| 360 | 393 |
| 361 // PlzNavigate: the RenderFrameHosts are no longer asked to navigate. | 394 // PlzNavigate: the RenderFrameHosts are no longer asked to navigate. |
| 362 if (CommandLine::ForCurrentProcess()->HasSwitch( | 395 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 363 switches::kEnableBrowserSideNavigation)) { | 396 switches::kEnableBrowserSideNavigation)) { |
| 364 navigation_start_time_and_url = MakeTuple(navigation_start, entry.GetURL()); | 397 navigation_data_->Set(navigation_start, entry.GetURL()); |
|
clamy
2014/10/09 19:02:32
I would rather use an explicit reset on the scoped
carlosk
2014/10/10 10:00:04
Done.
| |
| 365 return RequestNavigation(render_frame_host->frame_tree_node(), | 398 return RequestNavigation(render_frame_host->frame_tree_node(), |
| 366 entry, | 399 entry, |
| 367 reload_type, | 400 reload_type, |
| 368 navigation_start); | 401 navigation_start); |
| 369 } | 402 } |
| 370 | 403 |
| 371 RenderFrameHostImpl* dest_render_frame_host = manager->Navigate(entry); | 404 RenderFrameHostImpl* dest_render_frame_host = manager->Navigate(entry); |
| 372 if (!dest_render_frame_host) | 405 if (!dest_render_frame_host) |
| 373 return false; // Unable to create the desired RenderFrameHost. | 406 return false; // Unable to create the desired RenderFrameHost. |
| 374 | 407 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 393 | 426 |
| 394 // Navigate in the desired RenderFrameHost. | 427 // Navigate in the desired RenderFrameHost. |
| 395 // We can skip this step in the rare case that this is a transfer navigation | 428 // We can skip this step in the rare case that this is a transfer navigation |
| 396 // which began in the chosen RenderFrameHost, since the request has already | 429 // which began in the chosen RenderFrameHost, since the request has already |
| 397 // been issued. In that case, simply resume the response. | 430 // been issued. In that case, simply resume the response. |
| 398 bool is_transfer_to_same = | 431 bool is_transfer_to_same = |
| 399 navigate_params.transferred_request_child_id != -1 && | 432 navigate_params.transferred_request_child_id != -1 && |
| 400 navigate_params.transferred_request_child_id == | 433 navigate_params.transferred_request_child_id == |
| 401 dest_render_frame_host->GetProcess()->GetID(); | 434 dest_render_frame_host->GetProcess()->GetID(); |
| 402 if (!is_transfer_to_same) { | 435 if (!is_transfer_to_same) { |
| 403 navigation_start_time_and_url = MakeTuple(navigation_start, entry.GetURL()); | 436 navigation_data_->Set(navigation_start, entry.GetURL()); |
| 404 dest_render_frame_host->Navigate(navigate_params); | 437 dest_render_frame_host->Navigate(navigate_params); |
| 405 } else { | 438 } else { |
| 406 // No need to navigate again. Just resume the deferred request. | 439 // No need to navigate again. Just resume the deferred request. |
| 407 dest_render_frame_host->GetProcess()->ResumeDeferredNavigation( | 440 dest_render_frame_host->GetProcess()->ResumeDeferredNavigation( |
| 408 GlobalRequestID(navigate_params.transferred_request_child_id, | 441 GlobalRequestID(navigate_params.transferred_request_child_id, |
| 409 navigate_params.transferred_request_request_id)); | 442 navigate_params.transferred_request_request_id)); |
| 410 } | 443 } |
| 411 | 444 |
| 412 // Make sure no code called via RFH::Navigate clears the pending entry. | 445 // Make sure no code called via RFH::Navigate clears the pending entry. |
| 413 CHECK_EQ(controller_->GetPendingEntry(), &entry); | 446 CHECK_EQ(controller_->GetPendingEntry(), &entry); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 566 if (!did_navigate) | 599 if (!did_navigate) |
| 567 return; // No navigation happened. | 600 return; // No navigation happened. |
| 568 | 601 |
| 569 // DO NOT ADD MORE STUFF TO THIS FUNCTION! Your component should either listen | 602 // DO NOT ADD MORE STUFF TO THIS FUNCTION! Your component should either listen |
| 570 // for the appropriate notification (best) or you can add it to | 603 // for the appropriate notification (best) or you can add it to |
| 571 // DidNavigateMainFramePostCommit / DidNavigateAnyFramePostCommit (only if | 604 // DidNavigateMainFramePostCommit / DidNavigateAnyFramePostCommit (only if |
| 572 // necessary, please). | 605 // necessary, please). |
| 573 | 606 |
| 574 // TODO(carlosk): Move this out when PlzNavigate implementation properly calls | 607 // TODO(carlosk): Move this out when PlzNavigate implementation properly calls |
| 575 // the observer methods. | 608 // the observer methods. |
| 576 if (details.is_main_frame && | 609 RecordNavigationMetrics(details, params, site_instance); |
| 577 navigation_start_time_and_url.a.ToInternalValue() != 0 | |
| 578 && navigation_start_time_and_url.b == params.original_request_url) { | |
| 579 base::TimeDelta time_to_commit = | |
| 580 base::TimeTicks::Now() - navigation_start_time_and_url.a; | |
| 581 UMA_HISTOGRAM_TIMES("Navigation.TimeToCommit", time_to_commit); | |
| 582 navigation_start_time_and_url = MakeTuple(base::TimeTicks(), GURL()); | |
| 583 } | |
| 584 | 610 |
| 585 // Run post-commit tasks. | 611 // Run post-commit tasks. |
| 586 if (delegate_) { | 612 if (delegate_) { |
| 587 if (details.is_main_frame) | 613 if (details.is_main_frame) |
| 588 delegate_->DidNavigateMainFramePostCommit(details, params); | 614 delegate_->DidNavigateMainFramePostCommit(details, params); |
| 589 | 615 |
| 590 delegate_->DidNavigateAnyFramePostCommit( | 616 delegate_->DidNavigateAnyFramePostCommit( |
| 591 render_frame_host, details, params); | 617 render_frame_host, details, params); |
| 592 } | 618 } |
| 593 } | 619 } |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 766 | 792 |
| 767 // PlzNavigate | 793 // PlzNavigate |
| 768 void NavigatorImpl::CancelNavigation(FrameTreeNode* frame_tree_node) { | 794 void NavigatorImpl::CancelNavigation(FrameTreeNode* frame_tree_node) { |
| 769 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | 795 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( |
| 770 switches::kEnableBrowserSideNavigation)); | 796 switches::kEnableBrowserSideNavigation)); |
| 771 navigation_request_map_.erase(frame_tree_node->frame_tree_node_id()); | 797 navigation_request_map_.erase(frame_tree_node->frame_tree_node_id()); |
| 772 } | 798 } |
| 773 | 799 |
| 774 void NavigatorImpl::LogResourceRequestTime( | 800 void NavigatorImpl::LogResourceRequestTime( |
| 775 base::TimeTicks timestamp, const GURL& url) { | 801 base::TimeTicks timestamp, const GURL& url) { |
| 776 if (navigation_start_time_and_url.a.ToInternalValue() != 0 | 802 if (navigation_data_->IsTracking() && navigation_data_->url_ == url) { |
| 777 && navigation_start_time_and_url.b == url) { | 803 navigation_data_->url_job_start_time_ = timestamp; |
| 778 base::TimeDelta time_to_network = | 804 UMA_HISTOGRAM_TIMES( |
| 779 timestamp - navigation_start_time_and_url.a; | 805 "Navigation.TimeToURLJobStart", |
| 780 UMA_HISTOGRAM_TIMES("Navigation.TimeToURLJobStart", time_to_network); | 806 navigation_data_->url_job_start_time_ - navigation_data_->start_time_); |
| 781 } | 807 } |
| 782 } | 808 } |
| 783 | 809 |
| 810 void NavigatorImpl::LogBeforeUnloadTime( | |
| 811 const base::TimeTicks& renderer_before_unload_start_time, | |
| 812 const base::TimeTicks& renderer_before_unload_end_time) { | |
| 813 // Only stores the beforeunload delay if we're tracking the navigation and it | |
| 814 // happened later than the navigation request | |
| 815 if (navigation_data_->IsTracking() && | |
| 816 renderer_before_unload_start_time > navigation_data_->start_time_) { | |
| 817 navigation_data_->before_unload_delay_ = | |
| 818 renderer_before_unload_end_time - renderer_before_unload_start_time; | |
| 819 } | |
| 820 } | |
| 821 | |
| 784 void NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL( | 822 void NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL( |
| 785 RenderFrameHostImpl* render_frame_host, | 823 RenderFrameHostImpl* render_frame_host, |
| 786 const GURL& url) { | 824 const GURL& url) { |
| 787 int enabled_bindings = | 825 int enabled_bindings = |
| 788 render_frame_host->render_view_host()->GetEnabledBindings(); | 826 render_frame_host->render_view_host()->GetEnabledBindings(); |
| 789 bool is_allowed_in_web_ui_renderer = | 827 bool is_allowed_in_web_ui_renderer = |
| 790 WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI( | 828 WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI( |
| 791 controller_->GetBrowserContext(), url); | 829 controller_->GetBrowserContext(), url); |
| 792 if ((enabled_bindings & BINDINGS_POLICY_WEB_UI) && | 830 if ((enabled_bindings & BINDINGS_POLICY_WEB_UI) && |
| 793 !is_allowed_in_web_ui_renderer) { | 831 !is_allowed_in_web_ui_renderer) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 835 } | 873 } |
| 836 | 874 |
| 837 // The navigation request is sent directly to the IO thread. | 875 // The navigation request is sent directly to the IO thread. |
| 838 OnBeginNavigation( | 876 OnBeginNavigation( |
| 839 frame_tree_node, | 877 frame_tree_node, |
| 840 MakeDefaultBeginNavigation(request_params, navigation_type), | 878 MakeDefaultBeginNavigation(request_params, navigation_type), |
| 841 navigation_request_map_.get(frame_tree_node_id)->common_params()); | 879 navigation_request_map_.get(frame_tree_node_id)->common_params()); |
| 842 return true; | 880 return true; |
| 843 } | 881 } |
| 844 | 882 |
| 883 void NavigatorImpl::RecordNavigationMetrics( | |
| 884 const LoadCommittedDetails& details, | |
| 885 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | |
| 886 SiteInstance* site_instance) { | |
| 887 DCHECK(site_instance->HasProcess()); | |
| 888 if (details.is_main_frame && navigation_data_->IsTracking() && | |
| 889 navigation_data_->url_ == params.original_request_url) { | |
| 890 base::TimeDelta time_to_commit = | |
| 891 base::TimeTicks::Now() - navigation_data_->start_time_; | |
| 892 UMA_HISTOGRAM_TIMES("Navigation.TimeToCommit", time_to_commit); | |
| 893 | |
| 894 time_to_commit -= navigation_data_->before_unload_delay_; | |
| 895 base::TimeDelta time_to_network = navigation_data_->url_job_start_time_ - | |
| 896 navigation_data_->start_time_ - | |
| 897 navigation_data_->before_unload_delay_; | |
| 898 RenderProcessHostImpl* process_host = | |
| 899 static_cast<RenderProcessHostImpl*>(site_instance->GetProcess()); | |
| 900 bool spawned_new_process = | |
| 901 process_host->GetInitTime() > navigation_data_->start_time_; | |
| 902 if (spawned_new_process) { | |
| 903 UMA_HISTOGRAM_TIMES( | |
| 904 "Navigation.TimeToCommit_NewRenderer_BeforeUnloadDiscounted", | |
| 905 time_to_commit); | |
| 906 UMA_HISTOGRAM_TIMES( | |
| 907 "Navigation.TimeToURLJobStart_NewRenderer_BeforeUnloadDiscounted", | |
| 908 time_to_network); | |
| 909 } else { | |
| 910 UMA_HISTOGRAM_TIMES( | |
| 911 "Navigation.TimeToCommit_OldRenderer_BeforeUnloadDiscounted", | |
| 912 time_to_commit); | |
| 913 UMA_HISTOGRAM_TIMES( | |
| 914 "Navigation.TimeToURLJobStart_OldRenderer_BeforeUnloadDiscounted", | |
| 915 time_to_network); | |
| 916 } | |
| 917 | |
| 918 navigation_data_->Reset(); | |
|
clamy
2014/10/09 19:02:32
I would reset the scoped ptr explicitly (navigatio
carlosk
2014/10/10 10:00:04
Done.
| |
| 919 } | |
| 920 } | |
| 921 | |
| 845 } // namespace content | 922 } // namespace content |
| OLD | NEW |