Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |