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

Side by Side Diff: content/browser/web_contents/web_contents_impl.cc

Issue 118443008: Support cross-process navigations in a single subframe RenderFrameHost. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Minor cleanup Created 7 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/web_contents/web_contents_impl.h" 5 #include "content/browser/web_contents/web_contents_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 1720 matching lines...) Expand 10 before | Expand all | Expand 10 after
1731 TRACE_EVENT0("browser", "WebContentsImpl::NavigateToEntry"); 1731 TRACE_EVENT0("browser", "WebContentsImpl::NavigateToEntry");
1732 1732
1733 // The renderer will reject IPC messages with URLs longer than 1733 // The renderer will reject IPC messages with URLs longer than
1734 // this limit, so don't attempt to navigate with a longer URL. 1734 // this limit, so don't attempt to navigate with a longer URL.
1735 if (entry.GetURL().spec().size() > GetMaxURLChars()) { 1735 if (entry.GetURL().spec().size() > GetMaxURLChars()) {
1736 LOG(WARNING) << "Refusing to load URL as it exceeds " << GetMaxURLChars() 1736 LOG(WARNING) << "Refusing to load URL as it exceeds " << GetMaxURLChars()
1737 << " characters."; 1737 << " characters.";
1738 return false; 1738 return false;
1739 } 1739 }
1740 1740
1741 // TODO(creis): Use entry->frame_tree_node_id() to pick which 1741 // Use entry->frame_tree_node_id() to pick which RenderFrameHostManager to
1742 // RenderFrameHostManager to use. 1742 // use when --site-per-process is used.
1743 RenderFrameHostManager* manager = GetRenderManager();
1744 if (entry.frame_tree_node_id() != -1 &&
1745 CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) {
1746 int64 frame_tree_node_id = entry.frame_tree_node_id();
1747 manager = frame_tree_.FindByID(frame_tree_node_id)->render_manager();
1748 }
1749
1743 RenderViewHostImpl* dest_render_view_host = 1750 RenderViewHostImpl* dest_render_view_host =
1744 static_cast<RenderViewHostImpl*>(GetRenderManager()->Navigate(entry)); 1751 static_cast<RenderViewHostImpl*>(manager->Navigate(entry));
1745 if (!dest_render_view_host) 1752 if (!dest_render_view_host)
1746 return false; // Unable to create the desired render view host. 1753 return false; // Unable to create the desired render view host.
1747 1754
1748 // For security, we should never send non-Web-UI URLs to a Web UI renderer. 1755 // For security, we should never send non-Web-UI URLs to a Web UI renderer.
1749 // Double check that here. 1756 // Double check that here.
1750 int enabled_bindings = dest_render_view_host->GetEnabledBindings(); 1757 int enabled_bindings = dest_render_view_host->GetEnabledBindings();
1751 bool data_urls_allowed = delegate_ && delegate_->CanLoadDataURLsInWebUI(); 1758 bool data_urls_allowed = delegate_ && delegate_->CanLoadDataURLsInWebUI();
1752 bool is_allowed_in_web_ui_renderer = 1759 bool is_allowed_in_web_ui_renderer =
1753 WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI( 1760 WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI(
1754 GetBrowserContext(), entry.GetURL(), data_urls_allowed); 1761 GetBrowserContext(), entry.GetURL(), data_urls_allowed);
1755 if ((enabled_bindings & BINDINGS_POLICY_WEB_UI) && 1762 if ((enabled_bindings & BINDINGS_POLICY_WEB_UI) &&
1756 !is_allowed_in_web_ui_renderer) { 1763 !is_allowed_in_web_ui_renderer) {
1757 // Log the URL to help us diagnose any future failures of this CHECK. 1764 // Log the URL to help us diagnose any future failures of this CHECK.
1758 GetContentClient()->SetActiveURL(entry.GetURL()); 1765 GetContentClient()->SetActiveURL(entry.GetURL());
1759 CHECK(0); 1766 CHECK(0);
1760 } 1767 }
1761 1768
1762 // Notify observers that we will navigate in this RV. 1769 // Notify observers that we will navigate in this RV.
1763 FOR_EACH_OBSERVER(WebContentsObserver, 1770 FOR_EACH_OBSERVER(WebContentsObserver,
1764 observers_, 1771 observers_,
1765 AboutToNavigateRenderView(dest_render_view_host)); 1772 AboutToNavigateRenderView(dest_render_view_host));
1766 1773
1767 // Used for page load time metrics. 1774 // Used for page load time metrics.
1768 current_load_start_ = base::TimeTicks::Now(); 1775 current_load_start_ = base::TimeTicks::Now();
1769 1776
1770 // Navigate in the desired RenderViewHost. 1777 // Navigate in the desired RenderViewHost.
1778 // TODO(creis): As a temporary hack, we currently do cross-process subframe
1779 // navigations in a top-level frame of the new process. Thus, we don't yet
1780 // need to store the correct frame ID in ViewMsg_Navigate_Params.
1771 ViewMsg_Navigate_Params navigate_params; 1781 ViewMsg_Navigate_Params navigate_params;
1772 MakeNavigateParams(entry, controller_, delegate_, reload_type, 1782 MakeNavigateParams(entry, controller_, delegate_, reload_type,
1773 &navigate_params); 1783 &navigate_params);
1774 dest_render_view_host->Navigate(navigate_params); 1784 dest_render_view_host->Navigate(navigate_params);
1775 1785
1776 if (entry.GetPageID() == -1) { 1786 if (entry.GetPageID() == -1) {
1777 // HACK!! This code suppresses javascript: URLs from being added to 1787 // HACK!! This code suppresses javascript: URLs from being added to
1778 // session history, which is what we want to do for javascript: URLs that 1788 // session history, which is what we want to do for javascript: URLs that
1779 // do not generate content. What we really need is a message from the 1789 // do not generate content. What we really need is a message from the
1780 // renderer telling us that a new page was not created. The same message 1790 // renderer telling us that a new page was not created. The same message
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
2285 FOR_EACH_OBSERVER( 2295 FOR_EACH_OBSERVER(
2286 WebContentsObserver, observers_, 2296 WebContentsObserver, observers_,
2287 DocumentLoadedInFrame(frame_id, render_view_message_source_)); 2297 DocumentLoadedInFrame(frame_id, render_view_message_source_));
2288 } 2298 }
2289 2299
2290 void WebContentsImpl::OnDidFinishLoad( 2300 void WebContentsImpl::OnDidFinishLoad(
2291 int64 frame_id, 2301 int64 frame_id,
2292 const GURL& url, 2302 const GURL& url,
2293 bool is_main_frame) { 2303 bool is_main_frame) {
2294 GURL validated_url(url); 2304 GURL validated_url(url);
2305
2306 // --site-per-process mode has a short-term hack allowing cross-process
2307 // subframe pages to commit thinking they are top-level. Correct it here to
2308 // avoid confusing the observers.
2309 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess) &&
2310 render_view_message_source_ != GetRenderViewHost())
2311 is_main_frame = false;
Charlie Reis 2013/12/20 23:20:08 This eliminates the need for the web_navigation_ap
2312
2295 RenderProcessHost* render_process_host = 2313 RenderProcessHost* render_process_host =
2296 render_view_message_source_->GetProcess(); 2314 render_view_message_source_->GetProcess();
2297 RenderViewHost::FilterURL(render_process_host, false, &validated_url); 2315 RenderViewHost::FilterURL(render_process_host, false, &validated_url);
2298 FOR_EACH_OBSERVER(WebContentsObserver, observers_, 2316 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2299 DidFinishLoad(frame_id, validated_url, is_main_frame, 2317 DidFinishLoad(frame_id, validated_url, is_main_frame,
2300 render_view_message_source_)); 2318 render_view_message_source_));
2301 } 2319 }
2302 2320
2303 void WebContentsImpl::OnDidFailLoadWithError( 2321 void WebContentsImpl::OnDidFailLoadWithError(
2304 int64 frame_id, 2322 int64 frame_id,
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after
2961 2979
2962 // TODO(avi): Remove. http://crbug.com/170921 2980 // TODO(avi): Remove. http://crbug.com/170921
2963 NotificationService::current()->Notify( 2981 NotificationService::current()->Notify(
2964 NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, 2982 NOTIFICATION_RESOURCE_RECEIVED_REDIRECT,
2965 Source<WebContents>(this), 2983 Source<WebContents>(this),
2966 Details<const ResourceRedirectDetails>(&details)); 2984 Details<const ResourceRedirectDetails>(&details));
2967 } 2985 }
2968 2986
2969 void WebContentsImpl::DidNavigate( 2987 void WebContentsImpl::DidNavigate(
2970 RenderViewHost* rvh, 2988 RenderViewHost* rvh,
2971 const ViewHostMsg_FrameNavigate_Params& params) { 2989 const ViewHostMsg_FrameNavigate_Params& orig_params) {
2990 ViewHostMsg_FrameNavigate_Params params(orig_params);
2991 bool use_site_per_process =
2992 CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess);
2972 if (frame_tree_.IsFirstNavigationAfterSwap()) { 2993 if (frame_tree_.IsFirstNavigationAfterSwap()) {
2973 // First navigation should be a main frame navigation. 2994 // First navigation should be a main frame navigation.
2974 DCHECK(PageTransitionIsMainFrame(params.transition)); 2995 // TODO(creis): This DCHECK is currently disabled for --site-per-process
2996 // because cross-process subframe navigations still have a main frame
2997 // PageTransition.
2998 if (!use_site_per_process)
2999 DCHECK(PageTransitionIsMainFrame(params.transition));
2975 frame_tree_.OnFirstNavigationAfterSwap(params.frame_id); 3000 frame_tree_.OnFirstNavigationAfterSwap(params.frame_id);
2976 } 3001 }
2977 3002
3003 // When using --site-per-process, look up the FrameTreeNode ID that the
3004 // renderer-specific frame ID corresponds to.
3005 int64 frame_tree_node_id = frame_tree_.root()->frame_tree_node_id();
3006 if (use_site_per_process) {
3007 FrameTreeNode* source_node = frame_tree_.FindByFrameID(params.frame_id);
3008 if (source_node)
3009 frame_tree_node_id = source_node->frame_tree_node_id();
3010
3011 // TODO(creis): In the short term, cross-process subframe navigations are
3012 // happening in the pending RenderViewHost's top-level frame. (We need to
3013 // both mirror the frame tree and get the navigation to occur in the correct
3014 // subframe to fix this.) Until then, we should check whether we have a
3015 // pending NavigationEntry with a frame ID and if so, treat the
3016 // cross-process "main frame" navigation as a subframe navigation. This
3017 // limits us to a single cross-process subframe per RVH, and it affects
3018 // NavigateToEntry, NavigatorImpl::DidStartProvisionalLoad, and
3019 // OnDidFinishLoad.
3020 NavigationEntryImpl* pending_entry =
3021 NavigationEntryImpl::FromNavigationEntry(controller_.GetPendingEntry());
3022 int root_ftn_id = frame_tree_.root()->frame_tree_node_id();
3023 if (pending_entry &&
3024 pending_entry->frame_tree_node_id() != -1 &&
3025 pending_entry->frame_tree_node_id() != root_ftn_id) {
3026 params.transition = PAGE_TRANSITION_AUTO_SUBFRAME;
3027 frame_tree_node_id = pending_entry->frame_tree_node_id();
3028 }
3029 }
3030
2978 if (PageTransitionIsMainFrame(params.transition)) { 3031 if (PageTransitionIsMainFrame(params.transition)) {
2979 // When overscroll navigation gesture is enabled, a screenshot of the page 3032 // When overscroll navigation gesture is enabled, a screenshot of the page
2980 // in its current state is taken so that it can be used during the 3033 // in its current state is taken so that it can be used during the
2981 // nav-gesture. It is necessary to take the screenshot here, before calling 3034 // nav-gesture. It is necessary to take the screenshot here, before calling
2982 // RenderFrameHostManager::DidNavigateMainFrame, because that can change 3035 // RenderFrameHostManager::DidNavigateMainFrame, because that can change
2983 // WebContents::GetRenderViewHost to return the new host, instead of the one 3036 // WebContents::GetRenderViewHost to return the new host, instead of the one
2984 // that may have just been swapped out. 3037 // that may have just been swapped out.
2985 if (delegate_ && delegate_->CanOverscrollContent()) 3038 if (delegate_ && delegate_->CanOverscrollContent())
2986 controller_.TakeScreenshot(); 3039 controller_.TakeScreenshot();
2987 3040
2988 GetRenderManager()->DidNavigateMainFrame(rvh); 3041 if (!use_site_per_process)
3042 GetRenderManager()->DidNavigateMainFrame(rvh);
3043 }
3044
3045 // When using --site-per-process, we notify the RFHM for all navigations,
3046 // not just main frame navigations.
3047 if (use_site_per_process) {
3048 FrameTreeNode* frame = frame_tree_.FindByID(frame_tree_node_id);
3049 // TODO(creis): Rename to DidNavigateFrame.
3050 frame->render_manager()->DidNavigateMainFrame(rvh);
2989 } 3051 }
2990 3052
2991 // Update the site of the SiteInstance if it doesn't have one yet, unless 3053 // Update the site of the SiteInstance if it doesn't have one yet, unless
2992 // assigning a site is not necessary for this URL. In that case, the 3054 // assigning a site is not necessary for this URL. In that case, the
2993 // SiteInstance can still be considered unused until a navigation to a real 3055 // SiteInstance can still be considered unused until a navigation to a real
2994 // page. 3056 // page.
2995 if (!static_cast<SiteInstanceImpl*>(GetSiteInstance())->HasSite() && 3057 if (!static_cast<SiteInstanceImpl*>(GetSiteInstance())->HasSite() &&
2996 ShouldAssignSiteForURL(params.url)) { 3058 ShouldAssignSiteForURL(params.url)) {
2997 static_cast<SiteInstanceImpl*>(GetSiteInstance())->SetSite(params.url); 3059 static_cast<SiteInstanceImpl*>(GetSiteInstance())->SetSite(params.url);
2998 } 3060 }
2999 3061
3000 // Need to update MIME type here because it's referred to in 3062 // Need to update MIME type here because it's referred to in
3001 // UpdateNavigationCommands() called by RendererDidNavigate() to 3063 // UpdateNavigationCommands() called by RendererDidNavigate() to
3002 // determine whether or not to enable the encoding menu. 3064 // determine whether or not to enable the encoding menu.
3003 // It's updated only for the main frame. For a subframe, 3065 // It's updated only for the main frame. For a subframe,
3004 // RenderView::UpdateURL does not set params.contents_mime_type. 3066 // RenderView::UpdateURL does not set params.contents_mime_type.
3005 // (see http://code.google.com/p/chromium/issues/detail?id=2929 ) 3067 // (see http://code.google.com/p/chromium/issues/detail?id=2929 )
3006 // TODO(jungshik): Add a test for the encoding menu to avoid 3068 // TODO(jungshik): Add a test for the encoding menu to avoid
3007 // regressing it again. 3069 // regressing it again.
3008 if (PageTransitionIsMainFrame(params.transition)) 3070 if (PageTransitionIsMainFrame(params.transition))
3009 contents_mime_type_ = params.contents_mime_type; 3071 contents_mime_type_ = params.contents_mime_type;
3010 3072
3011 LoadCommittedDetails details; 3073 LoadCommittedDetails details;
3012 bool did_navigate = controller_.RendererDidNavigate(params, &details); 3074 bool did_navigate = controller_.RendererDidNavigate(rvh, params, &details);
3013 3075
3014 // For now, keep track of each frame's URL in its FrameTreeNode. This lets 3076 // For now, keep track of each frame's URL in its FrameTreeNode. This lets
3015 // us estimate our process count for implementing OOP iframes. 3077 // us estimate our process count for implementing OOP iframes.
3016 // TODO(creis): Remove this when we track which pages commit in each frame. 3078 // TODO(creis): Remove this when we track which pages commit in each frame.
3017 frame_tree_.SetFrameUrl(params.frame_id, params.url); 3079 frame_tree_.SetFrameUrl(params.frame_id, params.url);
3018 3080
3019 // Send notification about committed provisional loads. This notification is 3081 // Send notification about committed provisional loads. This notification is
3020 // different from the NAV_ENTRY_COMMITTED notification which doesn't include 3082 // different from the NAV_ENTRY_COMMITTED notification which doesn't include
3021 // the actual URL navigated to and isn't sent for AUTO_SUBFRAME navigations. 3083 // the actual URL navigated to and isn't sent for AUTO_SUBFRAME navigations.
3022 if (details.type != NAVIGATION_TYPE_NAV_IGNORE) { 3084 if (details.type != NAVIGATION_TYPE_NAV_IGNORE) {
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
3277 int64 source_frame_id, 3339 int64 source_frame_id,
3278 const GlobalRequestID& old_request_id, 3340 const GlobalRequestID& old_request_id,
3279 bool should_replace_current_entry, 3341 bool should_replace_current_entry,
3280 bool user_gesture) { 3342 bool user_gesture) {
3281 WebContents* new_contents = NULL; 3343 WebContents* new_contents = NULL;
3282 GURL dest_url(url); 3344 GURL dest_url(url);
3283 if (!GetContentClient()->browser()->ShouldAllowOpenURL( 3345 if (!GetContentClient()->browser()->ShouldAllowOpenURL(
3284 GetSiteInstance(), url)) 3346 GetSiteInstance(), url))
3285 dest_url = GURL(kAboutBlankURL); 3347 dest_url = GURL(kAboutBlankURL);
3286 3348
3287 // TODO(creis): Look up the FrameTreeNode ID corresponding to source_frame_id. 3349 // Look up the FrameTreeNode ID corresponding to source_frame_id.
3288 int frame_tree_node_id = -1; 3350 int64 frame_tree_node_id = -1;
3351 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess) &&
3352 source_frame_id != -1) {
3353 FrameTreeNode* source_node = frame_tree_.FindByFrameID(source_frame_id);
3354 if (source_node)
3355 frame_tree_node_id = source_node->frame_tree_node_id();
3356 }
3289 OpenURLParams params(dest_url, referrer, source_frame_id, 3357 OpenURLParams params(dest_url, referrer, source_frame_id,
3290 frame_tree_node_id, disposition, 3358 frame_tree_node_id, disposition,
3291 page_transition, true /* is_renderer_initiated */); 3359 page_transition, true /* is_renderer_initiated */);
3292 if (redirect_chain.size() > 0) 3360 if (redirect_chain.size() > 0)
3293 params.redirect_chain = redirect_chain; 3361 params.redirect_chain = redirect_chain;
3294 params.transferred_global_request_id = old_request_id; 3362 params.transferred_global_request_id = old_request_id;
3295 params.should_replace_current_entry = should_replace_current_entry; 3363 params.should_replace_current_entry = should_replace_current_entry;
3296 params.user_gesture = user_gesture; 3364 params.user_gesture = user_gesture;
3297 3365
3298 if (GetRenderManager()->web_ui()) { 3366 if (GetRenderManager()->web_ui()) {
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
3824 } 3892 }
3825 3893
3826 void WebContentsImpl::OnFrameRemoved( 3894 void WebContentsImpl::OnFrameRemoved(
3827 RenderViewHostImpl* render_view_host, 3895 RenderViewHostImpl* render_view_host,
3828 int64 frame_id) { 3896 int64 frame_id) {
3829 FOR_EACH_OBSERVER(WebContentsObserver, observers_, 3897 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
3830 FrameDetached(render_view_host, frame_id)); 3898 FrameDetached(render_view_host, frame_id));
3831 } 3899 }
3832 3900
3833 } // namespace content 3901 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698