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

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

Powered by Google App Engine
This is Rietveld 408576698