Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: content/browser/frame_host/navigator_impl.cc

Issue 615633005: PlzNavigate: Move the navigation logic to NavigatorImpl (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@commit-nav
Patch Set: Addressed comment Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "content/browser/frame_host/frame_tree_node.h" 11 #include "content/browser/frame_host/frame_tree_node.h"
12 #include "content/browser/frame_host/navigation_before_commit_info.h" 12 #include "content/browser/frame_host/navigation_before_commit_info.h"
13 #include "content/browser/frame_host/navigation_controller_impl.h" 13 #include "content/browser/frame_host/navigation_controller_impl.h"
14 #include "content/browser/frame_host/navigation_entry_impl.h" 14 #include "content/browser/frame_host/navigation_entry_impl.h"
15 #include "content/browser/frame_host/navigation_request.h" 15 #include "content/browser/frame_host/navigation_request.h"
16 #include "content/browser/frame_host/navigation_request_info.h"
16 #include "content/browser/frame_host/navigator_delegate.h" 17 #include "content/browser/frame_host/navigator_delegate.h"
17 #include "content/browser/frame_host/render_frame_host_impl.h" 18 #include "content/browser/frame_host/render_frame_host_impl.h"
18 #include "content/browser/renderer_host/render_view_host_impl.h" 19 #include "content/browser/renderer_host/render_view_host_impl.h"
19 #include "content/browser/site_instance_impl.h" 20 #include "content/browser/site_instance_impl.h"
20 #include "content/browser/webui/web_ui_controller_factory_registry.h" 21 #include "content/browser/webui/web_ui_controller_factory_registry.h"
21 #include "content/browser/webui/web_ui_impl.h" 22 #include "content/browser/webui/web_ui_impl.h"
22 #include "content/common/frame_messages.h"
23 #include "content/common/navigation_params.h" 23 #include "content/common/navigation_params.h"
24 #include "content/common/view_messages.h" 24 #include "content/common/view_messages.h"
25 #include "content/public/browser/browser_context.h" 25 #include "content/public/browser/browser_context.h"
26 #include "content/public/browser/content_browser_client.h" 26 #include "content/public/browser/content_browser_client.h"
27 #include "content/public/browser/global_request_id.h" 27 #include "content/public/browser/global_request_id.h"
28 #include "content/public/browser/invalidate_type.h" 28 #include "content/public/browser/invalidate_type.h"
29 #include "content/public/browser/navigation_controller.h" 29 #include "content/public/browser/navigation_controller.h"
30 #include "content/public/browser/navigation_details.h" 30 #include "content/public/browser/navigation_details.h"
31 #include "content/public/browser/page_navigator.h" 31 #include "content/public/browser/page_navigator.h"
32 #include "content/public/browser/render_view_host.h" 32 #include "content/public/browser/render_view_host.h"
33 #include "content/public/common/bindings_policy.h" 33 #include "content/public/common/bindings_policy.h"
34 #include "content/public/common/content_client.h" 34 #include "content/public/common/content_client.h"
35 #include "content/public/common/content_switches.h" 35 #include "content/public/common/content_switches.h"
36 #include "content/public/common/url_constants.h" 36 #include "content/public/common/url_constants.h"
37 #include "content/public/common/url_utils.h" 37 #include "content/public/common/url_utils.h"
38 #include "net/base/load_flags.h"
38 39
39 namespace content { 40 namespace content {
40 41
41 namespace { 42 namespace {
42 43
43 FrameMsg_Navigate_Type::Value GetNavigationType( 44 FrameMsg_Navigate_Type::Value GetNavigationType(
44 BrowserContext* browser_context, const NavigationEntryImpl& entry, 45 BrowserContext* browser_context, const NavigationEntryImpl& entry,
45 NavigationController::ReloadType reload_type) { 46 NavigationController::ReloadType reload_type) {
46 switch (reload_type) { 47 switch (reload_type) {
47 case NavigationControllerImpl::RELOAD: 48 case NavigationControllerImpl::RELOAD:
(...skipping 11 matching lines...) Expand all
59 if (entry.restore_type() == 60 if (entry.restore_type() ==
60 NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY) { 61 NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY) {
61 if (entry.GetHasPostData()) 62 if (entry.GetHasPostData())
62 return FrameMsg_Navigate_Type::RESTORE_WITH_POST; 63 return FrameMsg_Navigate_Type::RESTORE_WITH_POST;
63 return FrameMsg_Navigate_Type::RESTORE; 64 return FrameMsg_Navigate_Type::RESTORE;
64 } 65 }
65 66
66 return FrameMsg_Navigate_Type::NORMAL; 67 return FrameMsg_Navigate_Type::NORMAL;
67 } 68 }
68 69
70 // PlzNavigate
71 // Returns the net load flags to use based on the navigation type.
72 // TODO(clamy): unify the code with what is happening on the renderer side.
73 int LoadFlagFromNavigationType(FrameMsg_Navigate_Type::Value navigation_type) {
74 int load_flags = net::LOAD_NORMAL;
75 switch (navigation_type) {
76 case FrameMsg_Navigate_Type::RELOAD:
77 case FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL:
78 load_flags |= net::LOAD_VALIDATE_CACHE;
79 break;
80 case FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE:
81 load_flags |= net::LOAD_BYPASS_CACHE;
82 break;
83 case FrameMsg_Navigate_Type::RESTORE:
84 load_flags |= net::LOAD_PREFERRING_CACHE;
85 break;
86 case FrameMsg_Navigate_Type::RESTORE_WITH_POST:
87 load_flags |= net::LOAD_ONLY_FROM_CACHE;
88 break;
89 case FrameMsg_Navigate_Type::NORMAL:
90 default:
91 break;
92 }
93 return load_flags;
94 }
95
96 // PlzNavigate
97 // Generates a default FrameHostMsg_BeginNavigation_Params to be used when there
98 // is no live renderer.
99 FrameHostMsg_BeginNavigation_Params MakeDefaultBeginNavigation(
100 const RequestNavigationParams& request_params,
101 FrameMsg_Navigate_Type::Value navigation_type) {
102 FrameHostMsg_BeginNavigation_Params begin_navigation_params;
103 begin_navigation_params.method = request_params.is_post ? "POST" : "GET";
104 begin_navigation_params.load_flags =
105 LoadFlagFromNavigationType(navigation_type);
106
107 // TODO(clamy): Post data from the browser should be put in the request body.
108 // Headers should be filled in as well.
109
110 begin_navigation_params.has_user_gesture = false;
111 return begin_navigation_params;
112 }
113
69 RenderFrameHostManager* GetRenderManager(RenderFrameHostImpl* rfh) { 114 RenderFrameHostManager* GetRenderManager(RenderFrameHostImpl* rfh) {
70 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 115 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
71 switches::kSitePerProcess)) 116 switches::kSitePerProcess))
72 return rfh->frame_tree_node()->render_manager(); 117 return rfh->frame_tree_node()->render_manager();
73 118
74 return rfh->frame_tree_node()->frame_tree()->root()->render_manager(); 119 return rfh->frame_tree_node()->frame_tree()->root()->render_manager();
75 } 120 }
76 121
77 void MakeNavigateParams(const NavigationEntryImpl& entry, 122 void MakeNavigateParams(const NavigationEntryImpl& entry,
78 NavigationControllerImpl* controller, 123 NavigationControllerImpl* controller,
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 349
305 // This will be used to set the Navigation Timing API navigationStart 350 // This will be used to set the Navigation Timing API navigationStart
306 // parameter for browser navigations in new tabs (intents, tabs opened through 351 // parameter for browser navigations in new tabs (intents, tabs opened through
307 // "Open link in new tab"). We need to keep it above RFHM::Navigate() call to 352 // "Open link in new tab"). We need to keep it above RFHM::Navigate() call to
308 // capture the time needed for the RenderFrameHost initialization. 353 // capture the time needed for the RenderFrameHost initialization.
309 base::TimeTicks navigation_start = base::TimeTicks::Now(); 354 base::TimeTicks navigation_start = base::TimeTicks::Now();
310 355
311 RenderFrameHostManager* manager = 356 RenderFrameHostManager* manager =
312 render_frame_host->frame_tree_node()->render_manager(); 357 render_frame_host->frame_tree_node()->render_manager();
313 358
314 // PlzNavigate: the RenderFrameHosts are no longer asked to navigate. Instead 359 // PlzNavigate: the RenderFrameHosts are no longer asked to navigate.
315 // the RenderFrameHostManager handles the navigation requests for that frame
316 // node.
317 if (CommandLine::ForCurrentProcess()->HasSwitch( 360 if (CommandLine::ForCurrentProcess()->HasSwitch(
318 switches::kEnableBrowserSideNavigation)) { 361 switches::kEnableBrowserSideNavigation)) {
319 navigation_start_time_and_url = MakeTuple(navigation_start, entry.GetURL()); 362 navigation_start_time_and_url = MakeTuple(navigation_start, entry.GetURL());
320 FrameMsg_Navigate_Type::Value navigation_type = 363 return RequestNavigation(render_frame_host->frame_tree_node(),
321 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); 364 entry,
322 scoped_ptr<NavigationRequest> navigation_request(new NavigationRequest( 365 reload_type,
323 render_frame_host->frame_tree_node()->frame_tree_node_id(), 366 navigation_start);
324 CommonNavigationParams(entry.GetURL(),
325 entry.GetReferrer(),
326 entry.GetTransitionType(),
327 navigation_type,
328 !entry.IsViewSourceMode()),
329 CommitNavigationParams(entry.GetPageState(),
330 entry.GetIsOverridingUserAgent(),
331 navigation_start)));
332 RequestNavigationParams request_params(entry.GetHasPostData(),
333 entry.extra_headers(),
334 entry.GetBrowserInitiatedPostData());
335 return manager->RequestNavigation(navigation_request.Pass(),
336 request_params);
337 } 367 }
338 368
339 RenderFrameHostImpl* dest_render_frame_host = manager->Navigate(entry); 369 RenderFrameHostImpl* dest_render_frame_host = manager->Navigate(entry);
340 if (!dest_render_frame_host) 370 if (!dest_render_frame_host)
341 return false; // Unable to create the desired RenderFrameHost. 371 return false; // Unable to create the desired RenderFrameHost.
342 372
343 // Make sure no code called via RFHM::Navigate clears the pending entry. 373 // Make sure no code called via RFHM::Navigate clears the pending entry.
344 CHECK_EQ(controller_->GetPendingEntry(), &entry); 374 CHECK_EQ(controller_->GetPendingEntry(), &entry);
345 375
346 // For security, we should never send non-Web-UI URLs to a Web UI renderer. 376 // For security, we should never send non-Web-UI URLs to a Web UI renderer.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 NavigationController::ReloadType reload_type) { 435 NavigationController::ReloadType reload_type) {
406 return NavigateToEntry( 436 return NavigateToEntry(
407 render_frame_host, 437 render_frame_host,
408 *NavigationEntryImpl::FromNavigationEntry(controller_->GetPendingEntry()), 438 *NavigationEntryImpl::FromNavigationEntry(controller_->GetPendingEntry()),
409 reload_type); 439 reload_type);
410 } 440 }
411 441
412 void NavigatorImpl::DidNavigate( 442 void NavigatorImpl::DidNavigate(
413 RenderFrameHostImpl* render_frame_host, 443 RenderFrameHostImpl* render_frame_host,
414 const FrameHostMsg_DidCommitProvisionalLoad_Params& input_params) { 444 const FrameHostMsg_DidCommitProvisionalLoad_Params& input_params) {
445 // PlzNavigate
446 // The navigation request has been committed so the browser process doesn't
447 // need to care about it anymore.
448 if (CommandLine::ForCurrentProcess()->HasSwitch(
449 switches::kEnableBrowserSideNavigation)) {
450 navigation_request_map_.erase(
451 render_frame_host->frame_tree_node()->frame_tree_node_id());
452 }
453
415 FrameHostMsg_DidCommitProvisionalLoad_Params params(input_params); 454 FrameHostMsg_DidCommitProvisionalLoad_Params params(input_params);
416 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); 455 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree();
417 bool use_site_per_process = base::CommandLine::ForCurrentProcess()->HasSwitch( 456 bool use_site_per_process = base::CommandLine::ForCurrentProcess()->HasSwitch(
418 switches::kSitePerProcess); 457 switches::kSitePerProcess);
419 458
420 if (use_site_per_process) { 459 if (use_site_per_process) {
421 // TODO(creis): Until we mirror the frame tree in the subframe's process, 460 // TODO(creis): Until we mirror the frame tree in the subframe's process,
422 // cross-process subframe navigations happen in a renderer's main frame. 461 // cross-process subframe navigations happen in a renderer's main frame.
423 // Correct the transition type here if we know it is for a subframe. 462 // Correct the transition type here if we know it is for a subframe.
424 NavigationEntryImpl* pending_entry = 463 NavigationEntryImpl* pending_entry =
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 params.referrer = Referrer(); 688 params.referrer = Referrer();
650 689
651 // Navigations in Web UI pages count as browser-initiated navigations. 690 // Navigations in Web UI pages count as browser-initiated navigations.
652 params.is_renderer_initiated = false; 691 params.is_renderer_initiated = false;
653 } 692 }
654 693
655 if (delegate_) 694 if (delegate_)
656 delegate_->RequestOpenURL(render_frame_host, params); 695 delegate_->RequestOpenURL(render_frame_host, params);
657 } 696 }
658 697
698 // PlzNavigate
699 void NavigatorImpl::OnBeginNavigation(
700 FrameTreeNode* frame_tree_node,
701 const FrameHostMsg_BeginNavigation_Params& params,
702 const CommonNavigationParams& common_params) {
703 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
704 switches::kEnableBrowserSideNavigation));
705 DCHECK(frame_tree_node);
706
707 // TODO(clamy): In case of a renderer initiated navigation create a new
708 // NavigationRequest.
709 NavigationRequest* navigation_request =
710 navigation_request_map_.get(frame_tree_node->frame_tree_node_id());
711 DCHECK(navigation_request);
712
713 // Update the referrer with the one received from the renderer.
714 navigation_request->common_params().referrer = common_params.referrer;
715
716 scoped_ptr<NavigationRequestInfo> info(new NavigationRequestInfo(params));
717
718 info->first_party_for_cookies =
719 frame_tree_node->IsMainFrame()
720 ? navigation_request->common_params().url
721 : frame_tree_node->frame_tree()->root()->current_url();
722 info->is_main_frame = frame_tree_node->IsMainFrame();
723 info->parent_is_main_frame = !frame_tree_node->parent() ?
724 false : frame_tree_node->parent()->IsMainFrame();
725
726 // TODO(clamy): Inform the RenderFrameHostManager that a navigation is about
727 // to begin, so that it can speculatively spawn a new renderer if needed.
728
729 navigation_request->BeginNavigation(info.Pass(), params.request_body);
730 }
731
732 // PlzNavigate
659 void NavigatorImpl::CommitNavigation( 733 void NavigatorImpl::CommitNavigation(
660 RenderFrameHostImpl* render_frame_host, 734 FrameTreeNode* frame_tree_node,
661 const GURL& stream_url, 735 const NavigationBeforeCommitInfo& info) {
662 const CommonNavigationParams& common_params, 736 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
663 const CommitNavigationParams& commit_params) { 737 switches::kEnableBrowserSideNavigation));
664 CheckWebUIRendererDoesNotDisplayNormalURL(render_frame_host, 738 NavigationRequest* navigation_request =
665 common_params.url); 739 navigation_request_map_.get(frame_tree_node->frame_tree_node_id());
666 render_frame_host->CommitNavigation(stream_url, common_params, commit_params); 740 DCHECK(navigation_request);
741
742 // Ignores navigation commits if the request ID doesn't match the current
743 // active request.
744 if (navigation_request->navigation_request_id() !=
745 info.navigation_request_id) {
746 return;
747 }
748
749 // Update the navigation url.
750 navigation_request->common_params().url = info.navigation_url;
751
752 // Select an appropriate renderer to commit the navigation.
753 RenderFrameHostImpl* render_frame_host =
754 frame_tree_node->render_manager()->GetFrameHostForNavigation(
755 info.navigation_url, navigation_request->common_params().transition);
756 CheckWebUIRendererDoesNotDisplayNormalURL(
757 render_frame_host, navigation_request->common_params().url);
758
759 render_frame_host->CommitNavigation(info.stream_url,
760 navigation_request->common_params(),
761 navigation_request->commit_params());
762 }
763
764 // PlzNavigate
765 void NavigatorImpl::CancelNavigation(FrameTreeNode* frame_tree_node) {
766 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
767 switches::kEnableBrowserSideNavigation));
768 NavigationRequest* navigation_request =
769 navigation_request_map_.get(frame_tree_node->frame_tree_node_id());
770 if (!navigation_request)
771 return;
772 navigation_request->CancelNavigation();
773 navigation_request_map_.erase(frame_tree_node->frame_tree_node_id());
667 } 774 }
668 775
669 void NavigatorImpl::LogResourceRequestTime( 776 void NavigatorImpl::LogResourceRequestTime(
670 base::TimeTicks timestamp, const GURL& url) { 777 base::TimeTicks timestamp, const GURL& url) {
671 if (navigation_start_time_and_url.a.ToInternalValue() != 0 778 if (navigation_start_time_and_url.a.ToInternalValue() != 0
672 && navigation_start_time_and_url.b == url) { 779 && navigation_start_time_and_url.b == url) {
673 base::TimeDelta time_to_network = 780 base::TimeDelta time_to_network =
674 timestamp - navigation_start_time_and_url.a; 781 timestamp - navigation_start_time_and_url.a;
675 UMA_HISTOGRAM_TIMES("Navigation.TimeToURLJobStart", time_to_network); 782 UMA_HISTOGRAM_TIMES("Navigation.TimeToURLJobStart", time_to_network);
676 } 783 }
677 } 784 }
678 785
679 void NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL( 786 void NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL(
680 RenderFrameHostImpl* render_frame_host, 787 RenderFrameHostImpl* render_frame_host,
681 const GURL& url) { 788 const GURL& url) {
682 int enabled_bindings = 789 int enabled_bindings =
683 render_frame_host->render_view_host()->GetEnabledBindings(); 790 render_frame_host->render_view_host()->GetEnabledBindings();
684 bool is_allowed_in_web_ui_renderer = 791 bool is_allowed_in_web_ui_renderer =
685 WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI( 792 WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI(
686 controller_->GetBrowserContext(), url); 793 controller_->GetBrowserContext(), url);
687 if ((enabled_bindings & BINDINGS_POLICY_WEB_UI) && 794 if ((enabled_bindings & BINDINGS_POLICY_WEB_UI) &&
688 !is_allowed_in_web_ui_renderer) { 795 !is_allowed_in_web_ui_renderer) {
689 // Log the URL to help us diagnose any future failures of this CHECK. 796 // Log the URL to help us diagnose any future failures of this CHECK.
690 GetContentClient()->SetActiveURL(url); 797 GetContentClient()->SetActiveURL(url);
691 CHECK(0); 798 CHECK(0);
692 } 799 }
693 } 800 }
694 801
802 // PlzNavigate
803 bool NavigatorImpl::RequestNavigation(
804 FrameTreeNode* frame_tree_node,
805 const NavigationEntryImpl& entry,
806 NavigationController::ReloadType reload_type,
807 base::TimeTicks navigation_start) {
808 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
809 switches::kEnableBrowserSideNavigation));
810 DCHECK(frame_tree_node);
811 int64 frame_tree_node_id = frame_tree_node->frame_tree_node_id();
812 FrameMsg_Navigate_Type::Value navigation_type =
813 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type);
814 scoped_ptr<NavigationRequest> navigation_request(new NavigationRequest(
815 frame_tree_node_id,
816 CommonNavigationParams(entry.GetURL(),
817 entry.GetReferrer(),
818 entry.GetTransitionType(),
819 navigation_type,
820 !entry.IsViewSourceMode()),
821 CommitNavigationParams(entry.GetPageState(),
822 entry.GetIsOverridingUserAgent(),
823 navigation_start)));
824 RequestNavigationParams request_params(entry.GetHasPostData(),
825 entry.extra_headers(),
826 entry.GetBrowserInitiatedPostData());
827 // TODO(clamy): Check if navigations are blocked and if so store the
828 // parameters.
829
830 // If there is an ongoing request it must be canceled.
831 NavigationRequest* current_request =
832 navigation_request_map_.get(frame_tree_node_id);
833 if (current_request) {
834 current_request->CancelNavigation();
835 }
836
837 navigation_request_map_.set(frame_tree_node_id, navigation_request.Pass());
838
839 if (frame_tree_node->current_frame_host()->IsRenderFrameLive()) {
840 // TODO(clamy): send a RequestNavigation IPC.
841 return true;
842 }
843
844 // The navigation request is sent directly to the IO thread.
845 OnBeginNavigation(
846 frame_tree_node,
847 MakeDefaultBeginNavigation(request_params, navigation_type),
848 navigation_request_map_.get(frame_tree_node_id)->common_params());
849 return true;
850 }
851
695 } // namespace content 852 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/navigator_impl.h ('k') | content/browser/frame_host/navigator_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698