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/render_frame_host_manager.h" | 5 #include "content/browser/frame_host/render_frame_host_manager.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <string> | 10 #include <string> |
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
797 render_frame_host_->IsRenderFrameLive() && | 797 render_frame_host_->IsRenderFrameLive() && |
798 ShouldMakeNetworkRequestForURL(request.common_params().url) && | 798 ShouldMakeNetworkRequestForURL(request.common_params().url) && |
799 IsRendererTransferNeededForNavigation(render_frame_host_.get(), | 799 IsRendererTransferNeededForNavigation(render_frame_host_.get(), |
800 request.common_params().url); | 800 request.common_params().url); |
801 | 801 |
802 no_renderer_swap |= | 802 no_renderer_swap |= |
803 !request.may_transfer() && !can_renderer_initiate_transfer; | 803 !request.may_transfer() && !can_renderer_initiate_transfer; |
804 } else { | 804 } else { |
805 // Subframe navigations will use the current renderer, unless specifically | 805 // Subframe navigations will use the current renderer, unless specifically |
806 // allowed to swap processes. | 806 // allowed to swap processes. |
807 no_renderer_swap |= !CanSubframeSwapProcess(request.common_params().url, | 807 no_renderer_swap |= !CanSubframeSwapProcess( |
808 request.source_site_instance(), | 808 request.common_params().url, request.source_site_instance(), |
809 request.dest_site_instance()); | 809 request.dest_site_instance(), false); |
Charlie Reis
2017/02/02 22:40:46
I think we might have a problem here for PlzNaviga
alexmos
2017/02/14 21:16:06
Yes, getting this working with PlzNavigate needed
Charlie Reis
2017/02/28 00:57:52
Yes, that sounds like the right thing to do. Than
| |
810 } | 810 } |
811 | 811 |
812 if (no_renderer_swap) { | 812 if (no_renderer_swap) { |
813 // GetFrameHostForNavigation will be called more than once during a | 813 // GetFrameHostForNavigation will be called more than once during a |
814 // navigation (currently twice, on request and when it's about to commit in | 814 // navigation (currently twice, on request and when it's about to commit in |
815 // the renderer). In the follow up calls an existing pending WebUI should | 815 // the renderer). In the follow up calls an existing pending WebUI should |
816 // not be recreated if the URL didn't change. So instead of calling | 816 // not be recreated if the URL didn't change. So instead of calling |
817 // CleanUpNavigation just discard the speculative RenderFrameHost if one | 817 // CleanUpNavigation just discard the speculative RenderFrameHost if one |
818 // exists. | 818 // exists. |
819 if (speculative_render_frame_host_) | 819 if (speculative_render_frame_host_) |
(...skipping 1459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2279 RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate( | 2279 RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate( |
2280 const GURL& dest_url, | 2280 const GURL& dest_url, |
2281 SiteInstance* source_instance, | 2281 SiteInstance* source_instance, |
2282 SiteInstance* dest_instance, | 2282 SiteInstance* dest_instance, |
2283 ui::PageTransition transition, | 2283 ui::PageTransition transition, |
2284 bool dest_is_restore, | 2284 bool dest_is_restore, |
2285 bool dest_is_view_source_mode, | 2285 bool dest_is_view_source_mode, |
2286 const GlobalRequestID& transferred_request_id, | 2286 const GlobalRequestID& transferred_request_id, |
2287 int bindings, | 2287 int bindings, |
2288 bool is_reload) { | 2288 bool is_reload) { |
2289 if (!frame_tree_node_->IsMainFrame() && | |
2290 !CanSubframeSwapProcess(dest_url, source_instance, dest_instance)) { | |
2291 // Note: Do not add code here to determine whether the subframe should swap | |
2292 // or not. Add it to CanSubframeSwapProcess instead. | |
2293 return render_frame_host_.get(); | |
2294 } | |
2295 | |
2296 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 2289 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
2297 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( | 2290 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( |
2298 dest_url, source_instance, dest_instance, nullptr, transition, | 2291 dest_url, source_instance, dest_instance, nullptr, transition, |
2299 dest_is_restore, dest_is_view_source_mode); | 2292 dest_is_restore, dest_is_view_source_mode); |
2300 | 2293 |
2301 // Inform the transferring NavigationHandle of a transfer to a different | 2294 // Inform the transferring NavigationHandle of a transfer to a different |
2302 // SiteInstance. It is important do so now, in order to mark the request as | 2295 // SiteInstance. It is important do so now, in order to mark the request as |
2303 // transferring on the IO thread before attempting to destroy the pending RFH. | 2296 // transferring on the IO thread before attempting to destroy the pending RFH. |
2304 // This ensures the network request will not be destroyed along the pending | 2297 // This ensures the network request will not be destroyed along the pending |
2305 // RFH but will persist until it is picked up by the new RFH. | 2298 // RFH but will persist until it is picked up by the new RFH. |
2306 if (transfer_navigation_handle_.get() && | 2299 bool dest_is_transfer = transfer_navigation_handle_.get() && |
2307 transfer_navigation_handle_->GetGlobalRequestID() == | 2300 transfer_navigation_handle_->GetGlobalRequestID() == |
2308 transferred_request_id && | 2301 transferred_request_id; |
2302 if (dest_is_transfer && | |
2309 new_instance.get() != | 2303 new_instance.get() != |
2310 transfer_navigation_handle_->GetRenderFrameHost() | 2304 transfer_navigation_handle_->GetRenderFrameHost() |
2311 ->GetSiteInstance()) { | 2305 ->GetSiteInstance()) { |
2312 transfer_navigation_handle_->Transfer(); | 2306 transfer_navigation_handle_->Transfer(); |
2313 } | 2307 } |
2314 | 2308 |
2315 // If we are currently navigating cross-process to a pending RFH for a | 2309 // If we are currently navigating cross-process to a pending RFH for a |
2316 // different SiteInstance, we want to get back to normal and then navigate as | 2310 // different SiteInstance, we want to get back to normal and then navigate as |
2317 // usual. We will reuse the pending RFH below if it matches the destination | 2311 // usual. We will reuse the pending RFH below if it matches the destination |
2318 // SiteInstance. | 2312 // SiteInstance. |
2319 if (pending_render_frame_host_) { | 2313 if (pending_render_frame_host_) { |
2320 if (pending_render_frame_host_->GetSiteInstance() != new_instance) { | 2314 if (pending_render_frame_host_->GetSiteInstance() != new_instance) { |
2321 CancelPending(); | 2315 CancelPending(); |
2322 } else { | 2316 } else { |
2323 // When a pending RFH is reused, it should always be live, since it is | 2317 // When a pending RFH is reused, it should always be live, since it is |
2324 // cleared whenever a process dies. | 2318 // cleared whenever a process dies. |
2325 CHECK(pending_render_frame_host_->IsRenderFrameLive()); | 2319 CHECK(pending_render_frame_host_->IsRenderFrameLive()); |
2326 } | 2320 } |
2327 } | 2321 } |
2328 | 2322 |
2329 if (new_instance.get() != current_instance) { | 2323 // Note: Do not add code here to determine whether the subframe should swap |
2324 // or not. Add it to CanSubframeSwapProcess instead. | |
2325 bool allowed_to_swap_process = | |
alexmos
2017/01/25 22:30:55
I turned this into a flag so that there's just one
Charlie Reis
2017/02/02 22:40:46
Acknowledged.
| |
2326 frame_tree_node_->IsMainFrame() || | |
2327 CanSubframeSwapProcess(dest_url, source_instance, dest_instance, | |
2328 dest_is_transfer); | |
2329 | |
2330 if (new_instance.get() != current_instance && allowed_to_swap_process) { | |
2330 TRACE_EVENT_INSTANT2( | 2331 TRACE_EVENT_INSTANT2( |
2331 "navigation", | 2332 "navigation", |
2332 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", | 2333 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", |
2333 TRACE_EVENT_SCOPE_THREAD, | 2334 TRACE_EVENT_SCOPE_THREAD, |
2334 "current_instance id", current_instance->GetId(), | 2335 "current_instance id", current_instance->GetId(), |
2335 "new_instance id", new_instance->GetId()); | 2336 "new_instance id", new_instance->GetId()); |
2336 | 2337 |
2337 // New SiteInstance: create a pending RFH to navigate. | 2338 // New SiteInstance: create a pending RFH to navigate. |
2338 | 2339 |
2339 if (!pending_render_frame_host_) | 2340 if (!pending_render_frame_host_) |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2396 // | 2397 // |
2397 // Also make sure the old RenderFrame stops, in case a load is in | 2398 // Also make sure the old RenderFrame stops, in case a load is in |
2398 // progress. (We don't want to do this for transfers, since it will | 2399 // progress. (We don't want to do this for transfers, since it will |
2399 // interrupt the transfer with an unexpected DidStopLoading.) | 2400 // interrupt the transfer with an unexpected DidStopLoading.) |
2400 render_frame_host_->Send(new FrameMsg_Stop( | 2401 render_frame_host_->Send(new FrameMsg_Stop( |
2401 render_frame_host_->GetRoutingID())); | 2402 render_frame_host_->GetRoutingID())); |
2402 pending_render_frame_host_->SetNavigationsSuspended(true, | 2403 pending_render_frame_host_->SetNavigationsSuspended(true, |
2403 base::TimeTicks()); | 2404 base::TimeTicks()); |
2404 render_frame_host_->DispatchBeforeUnload(true, is_reload); | 2405 render_frame_host_->DispatchBeforeUnload(true, is_reload); |
2405 } | 2406 } |
2406 | |
Charlie Reis
2017/02/02 22:40:46
nit: Let's avoid this churn.
alexmos
2017/02/14 21:16:06
Done.
| |
2407 return pending_render_frame_host_.get(); | 2407 return pending_render_frame_host_.get(); |
2408 } | 2408 } |
2409 | 2409 |
2410 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. | 2410 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. |
2411 | 2411 |
2412 // It's possible to swap out the current RFH and then decide to navigate in it | 2412 // It's possible to swap out the current RFH and then decide to navigate in it |
2413 // anyway (e.g., a cross-process navigation that redirects back to the | 2413 // anyway (e.g., a cross-process navigation that redirects back to the |
2414 // original site). In that case, we have a proxy for the current RFH but | 2414 // original site). In that case, we have a proxy for the current RFH but |
2415 // haven't deleted it yet. The new navigation will swap it back in, so we can | 2415 // haven't deleted it yet. The new navigation will swap it back in, so we can |
2416 // delete the proxy. | 2416 // delete the proxy. |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2722 msg->set_routing_id(render_frame_host_->GetRoutingID()); | 2722 msg->set_routing_id(render_frame_host_->GetRoutingID()); |
2723 render_frame_host_->Send(msg); | 2723 render_frame_host_->Send(msg); |
2724 } else { | 2724 } else { |
2725 delete msg; | 2725 delete msg; |
2726 } | 2726 } |
2727 } | 2727 } |
2728 | 2728 |
2729 bool RenderFrameHostManager::CanSubframeSwapProcess( | 2729 bool RenderFrameHostManager::CanSubframeSwapProcess( |
2730 const GURL& dest_url, | 2730 const GURL& dest_url, |
2731 SiteInstance* source_instance, | 2731 SiteInstance* source_instance, |
2732 SiteInstance* dest_instance) { | 2732 SiteInstance* dest_instance, |
2733 bool for_transfer) { | |
2733 // On renderer-initiated navigations, when the frame initiating the navigation | 2734 // On renderer-initiated navigations, when the frame initiating the navigation |
2734 // and the frame being navigated differ, |source_instance| is set to the | 2735 // and the frame being navigated differ, |source_instance| is set to the |
2735 // SiteInstance of the initiating frame. |dest_instance| is present on session | 2736 // SiteInstance of the initiating frame. |dest_instance| is present on session |
2736 // history navigations. The two cannot be set simultaneously. | 2737 // history navigations. The two cannot be set simultaneously. |
2737 DCHECK(!source_instance || !dest_instance); | 2738 DCHECK(!source_instance || !dest_instance); |
2738 | 2739 |
2739 // Don't swap for subframes unless we are in an OOPIF-enabled mode. We can | 2740 // Don't swap for subframes unless we are in an OOPIF-enabled mode. We can |
2740 // get here in tests for subframes (e.g., NavigateFrameToURL). | 2741 // get here in tests for subframes (e.g., NavigateFrameToURL). |
2741 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible()) | 2742 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible()) |
2742 return false; | 2743 return false; |
2743 | 2744 |
2744 // If dest_url is a unique origin like about:blank, then the need for a swap | 2745 // If dest_url is a unique origin like about:blank, then the need for a swap |
2745 // is determined by the source_instance or dest_instance. | 2746 // is determined by the source_instance or dest_instance. |
2746 GURL resolved_url = dest_url; | 2747 GURL resolved_url = dest_url; |
2747 if (url::Origin(resolved_url).unique()) { | 2748 if (url::Origin(resolved_url).unique()) { |
2748 if (source_instance) { | 2749 if (source_instance) { |
2749 resolved_url = source_instance->GetSiteURL(); | 2750 resolved_url = source_instance->GetSiteURL(); |
2750 } else if (dest_instance) { | 2751 } else if (dest_instance) { |
2751 resolved_url = dest_instance->GetSiteURL(); | 2752 resolved_url = dest_instance->GetSiteURL(); |
2752 } else { | 2753 } else { |
2753 // If there is no SiteInstance this unique origin can be associated with, | 2754 // If there is no SiteInstance this unique origin can be associated with, |
2754 // then we should avoid a process swap. | 2755 // there are two cases: |
2755 return false; | 2756 // |
2757 // (1) If we are in a transfer, allow a process swap. Normally, | |
2758 // redirects to data: or about: URLs are disallowed as | |
2759 // net::ERR_UNSAFE_REDIRECT. However, extensions can still redirect | |
2760 // arbitary requests to those URLs using the chrome.declarativeWebRequest | |
2761 // API, which will end up here (for an example, see | |
2762 // ExtensionWebRequestApiTest.WebRequestDeclarative1). It's safest to | |
alexmos
2017/01/25 22:30:55
For reference, here's where these redirects are pe
Charlie Reis
2017/02/02 22:40:46
Interesting! I did just hear Devlin mention that
alexmos
2017/02/14 21:16:06
Unfortunately, this is a problem for regular webRe
| |
2763 // swap processes for those redirects if we are in an appropriate | |
2764 // OOPIF-enabled mode. | |
Charlie Reis
2017/02/02 22:40:46
Sounds like we want this to return true for these
alexmos
2017/02/14 21:16:06
Yes, for instance we don't want to return true her
| |
2765 // | |
2766 // (2) If we are not in a transfer, avoid a process swap. We can get | |
2767 // here during session restore, and this avoids putting all data: and | |
2768 // about:blank subframes in OOPIFs. We can also get here in tests with | |
2769 // browser-initiated subframe navigations (NavigateFrameToURL). | |
2770 if (!for_transfer) | |
alexmos
2017/01/25 22:30:55
I don't know if passing in this as a flag is stric
Charlie Reis
2017/02/02 22:40:46
(See my earlier question about PlzNavigate.)
| |
2771 return false; | |
2756 } | 2772 } |
2757 } | 2773 } |
2758 | 2774 |
2759 // If we are in an OOPIF mode that only applies to some sites, only swap if | 2775 // If we are in an OOPIF mode that only applies to some sites, only swap if |
2760 // the policy determines that a transfer would have been needed. We can get | 2776 // the policy determines that a transfer would have been needed. We can get |
2761 // here for session restore. | 2777 // here for session restore. |
2762 if (!IsRendererTransferNeededForNavigation(render_frame_host_.get(), | 2778 if (!IsRendererTransferNeededForNavigation(render_frame_host_.get(), |
2763 resolved_url)) { | 2779 resolved_url)) { |
2764 DCHECK(!dest_instance || | 2780 DCHECK(!dest_instance || |
2765 dest_instance == render_frame_host_->GetSiteInstance()); | 2781 dest_instance == render_frame_host_->GetSiteInstance()); |
2766 return false; | 2782 return false; |
2767 } | 2783 } |
2768 | 2784 |
2769 return true; | 2785 return true; |
2770 } | 2786 } |
2771 | 2787 |
2772 } // namespace content | 2788 } // namespace content |
OLD | NEW |