diff --git a/patches/common/chromium/.patches b/patches/common/chromium/.patches index 97177729b07c8..2794ba03b5f5c 100644 --- a/patches/common/chromium/.patches +++ b/patches/common/chromium/.patches @@ -1,3 +1,4 @@ +portals_fix_crash_when_detaching_oopif_from_portal.patch add_realloc.patch build_gn.patch dcheck.patch @@ -47,7 +48,6 @@ enable_widevine.patch chrome_key_systems.patch allow_nested_error_trackers.patch blink_initialization_order.patch -disable_detach_webview_frame.patch ssl_security_state_tab_helper.patch exclude-a-few-test-files-from-build.patch expose-net-observer-api.patch @@ -77,3 +77,4 @@ viz_osr.patch video_capturer_dirty_rect.patch unsandboxed_ppapi_processes_skip_zygote.patch autofill_size_calculation.patch +disable_detach_webview_frame.patch diff --git a/patches/common/chromium/disable_detach_webview_frame.patch b/patches/common/chromium/disable_detach_webview_frame.patch index 158e9cee22af2..ead99bf389f64 100644 --- a/patches/common/chromium/disable_detach_webview_frame.patch +++ b/patches/common/chromium/disable_detach_webview_frame.patch @@ -12,19 +12,19 @@ this patch was introduced in Chrome 66. Update(zcbenz): The bug is still in Chrome 72. diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc -index a5e18f465f79416c05fd3ab630b40b079a7a7cbc..d6f4717ee2122b86611d6149d5d1a9105d1baff1 100644 +index 075810f5553731b56b08b5e6e35854bdebed2021..8252a79c95c42f491fba28955993fff127e8c51a 100644 --- a/content/browser/frame_host/render_frame_proxy_host.cc +++ b/content/browser/frame_host/render_frame_proxy_host.cc -@@ -263,6 +263,12 @@ void RenderFrameProxyHost::SetDestructionCallback( +@@ -261,6 +261,12 @@ void RenderFrameProxyHost::SetDestructionCallback( void RenderFrameProxyHost::OnDetach() { - if (frame_tree_node_->render_manager()->ForInnerDelegate()) { + if (frame_tree_node_->render_manager()->IsMainFrameForInnerDelegate()) { + // Don't detach the frame for webview, we will manage the WebContents + // manually. + // We should revisit this bug after upgrading to newer versions of Chrome, + // this patch was introduced in Chrome 66. + return; + - // Only main frame proxy can detach for inner WebContents. - DCHECK(frame_tree_node_->IsMainFrame()); frame_tree_node_->render_manager()->RemoveOuterDelegateFrame(); + return; + } diff --git a/patches/common/chromium/frame_host_manager.patch b/patches/common/chromium/frame_host_manager.patch index 4f23ba910b294..7f38ef46bbd92 100644 --- a/patches/common/chromium/frame_host_manager.patch +++ b/patches/common/chromium/frame_host_manager.patch @@ -41,10 +41,10 @@ index d439dfbb603876f942ff40fe1a505f9498f57c23..fd576eb894e06fe6c5cb21351b2b95b0 // another SiteInstance for the same site. void RegisterSiteInstance(SiteInstanceImpl* site_instance); diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc -index f9f8e5204d1d92e87370f859c294919d2a1991c3..760965f134e3326676428b9fc6906f9ff740aac2 100644 +index 0e3fc30fae933e0493920ed1823b086ac6ceee61..6dbb73c964601f0dae7ef6460a0ae2a048634a35 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc -@@ -1978,6 +1978,16 @@ bool RenderFrameHostManager::InitRenderView( +@@ -1984,6 +1984,16 @@ bool RenderFrameHostManager::InitRenderView( scoped_refptr RenderFrameHostManager::GetSiteInstanceForNavigationRequest( const NavigationRequest& request) { @@ -61,7 +61,7 @@ index f9f8e5204d1d92e87370f859c294919d2a1991c3..760965f134e3326676428b9fc6906f9f // First, check if the navigation can switch SiteInstances. If not, the // navigation should use the current SiteInstance. SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance(); -@@ -2010,6 +2020,51 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest( +@@ -2016,6 +2026,51 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest( request.common_params().url); no_renderer_swap_allowed |= request.from_begin_navigation() && !can_renderer_initiate_transfer; @@ -113,7 +113,7 @@ index f9f8e5204d1d92e87370f859c294919d2a1991c3..760965f134e3326676428b9fc6906f9f } else { // Subframe navigations will use the current renderer, unless specifically // allowed to swap processes. -@@ -2021,23 +2076,17 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest( +@@ -2027,23 +2082,17 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest( if (no_renderer_swap_allowed && !should_swap_for_error_isolation) return scoped_refptr(current_site_instance); diff --git a/patches/common/chromium/portals_fix_crash_when_detaching_oopif_from_portal.patch b/patches/common/chromium/portals_fix_crash_when_detaching_oopif_from_portal.patch new file mode 100644 index 0000000000000..ba3980226699b --- /dev/null +++ b/patches/common/chromium/portals_fix_crash_when_detaching_oopif_from_portal.patch @@ -0,0 +1,183 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Alexandre=20Lach=C3=A8ze?= +Date: Tue, 25 Jun 2019 17:36:08 +0200 +Subject: Portals: Fix crash when detaching OOPIF from portal. + +Prior to this change, any detachment of a proxy would cause the +inner WebContents to get detached from the outer WebContents. After +this change, we only detach the inner WebContents from the outer +WebContents when the main frame's proxy is detached. + +Bug: 955392 +Change-Id: I41fe61961a26636132ce2f17153b2c08b93af1e1 +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1577636 +Commit-Queue: Lucas Gadani +Reviewed-by: Charlie Reis +Cr-Commit-Position: refs/heads/master@{#654071} + +diff --git a/content/browser/frame_host/cross_process_frame_connector.cc b/content/browser/frame_host/cross_process_frame_connector.cc +index ae486a29d07b773464dc3071dde2a33c8375f3a6..9967d0657c6ab7d72649a82b1f9c3839043b4cda 100644 +--- a/content/browser/frame_host/cross_process_frame_connector.cc ++++ b/content/browser/frame_host/cross_process_frame_connector.cc +@@ -386,7 +386,7 @@ void CrossProcessFrameConnector::OnVisibilityChanged(bool visible) { + // Show/Hide on all the RenderWidgetHostViews (including this) one. + if (frame_proxy_in_parent_renderer_->frame_tree_node() + ->render_manager() +- ->ForInnerDelegate()) { ++ ->IsMainFrameForInnerDelegate()) { + view_->host()->delegate()->OnRenderFrameProxyVisibilityChanged(visible); + return; + } +diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc +index f9f8e5204d1d92e87370f859c294919d2a1991c3..0e3fc30fae933e0493920ed1823b086ac6ceee61 100644 +--- a/content/browser/frame_host/render_frame_host_manager.cc ++++ b/content/browser/frame_host/render_frame_host_manager.cc +@@ -132,14 +132,15 @@ RenderWidgetHostView* RenderFrameHostManager::GetRenderWidgetHostView() const { + return nullptr; + } + +-bool RenderFrameHostManager::ForInnerDelegate() { +- return delegate_->GetOuterDelegateFrameTreeNodeId() != +- FrameTreeNode::kFrameTreeNodeInvalidId; ++bool RenderFrameHostManager::IsMainFrameForInnerDelegate() { ++ return frame_tree_node_->IsMainFrame() && ++ delegate_->GetOuterDelegateFrameTreeNodeId() != ++ FrameTreeNode::kFrameTreeNodeInvalidId; + } + + RenderWidgetHostImpl* + RenderFrameHostManager::GetOuterRenderWidgetHostForKeyboardInput() { +- if (!ForInnerDelegate() || !frame_tree_node_->IsMainFrame()) ++ if (!IsMainFrameForInnerDelegate()) + return nullptr; + + FrameTreeNode* outer_contents_frame_tree_node = +@@ -168,6 +169,8 @@ RenderFrameProxyHost* RenderFrameHostManager::GetProxyToParent() { + } + + RenderFrameProxyHost* RenderFrameHostManager::GetProxyToOuterDelegate() { ++ // Only the main frame should be able to reach the outer WebContents. ++ DCHECK(frame_tree_node_->IsMainFrame()); + int outer_contents_frame_tree_node_id = + delegate_->GetOuterDelegateFrameTreeNodeId(); + FrameTreeNode* outer_contents_frame_tree_node = +@@ -183,6 +186,9 @@ RenderFrameProxyHost* RenderFrameHostManager::GetProxyToOuterDelegate() { + } + + void RenderFrameHostManager::RemoveOuterDelegateFrame() { ++ // Removing the outer delegate frame will destroy the inner WebContents. This ++ // should only be called on the main frame. ++ DCHECK(frame_tree_node_->IsMainFrame()); + FrameTreeNode* outer_delegate_frame_tree_node = + FrameTreeNode::GloballyFindByID( + delegate_->GetOuterDelegateFrameTreeNodeId()); +@@ -1880,7 +1886,7 @@ int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { + + void RenderFrameHostManager::CreateProxiesForChildFrame(FrameTreeNode* child) { + RenderFrameProxyHost* outer_delegate_proxy = +- ForInnerDelegate() ? GetProxyToOuterDelegate() : nullptr; ++ IsMainFrameForInnerDelegate() ? GetProxyToOuterDelegate() : nullptr; + for (const auto& pair : proxy_hosts_) { + // Do not create proxies for subframes in the outer delegate's process, + // since the outer delegate does not need to interact with them. +@@ -1944,7 +1950,7 @@ void RenderFrameHostManager::SwapOuterDelegateFrame( + + void RenderFrameHostManager::SetRWHViewForInnerContents( + RenderWidgetHostView* child_rwhv) { +- DCHECK(ForInnerDelegate() && frame_tree_node_->IsMainFrame()); ++ DCHECK(IsMainFrameForInnerDelegate()); + GetProxyToOuterDelegate()->SetChildRWHView(child_rwhv, nullptr); + } + +@@ -2587,7 +2593,7 @@ void RenderFrameHostManager::SendPageMessage(IPC::Message* msg, + // When sending a PageMessage for an inner WebContents, we don't want to also + // send it to the outer WebContent's frame as well. + RenderFrameProxyHost* outer_delegate_proxy = +- ForInnerDelegate() ? GetProxyToOuterDelegate() : nullptr; ++ IsMainFrameForInnerDelegate() ? GetProxyToOuterDelegate() : nullptr; + for (const auto& pair : proxy_hosts_) { + if (outer_delegate_proxy != pair.second.get()) { + send_msg(pair.second.get(), pair.second->GetRoutingID(), msg, +diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h +index 644175178623ec26f6dfcf51db5833cdb03bd5ae..937ce66cedc2ab6b14b6ba9c247597a2d757613e 100644 +--- a/content/browser/frame_host/render_frame_host_manager.h ++++ b/content/browser/frame_host/render_frame_host_manager.h +@@ -203,9 +203,9 @@ class CONTENT_EXPORT RenderFrameHostManager + // there is no current one. + RenderWidgetHostView* GetRenderWidgetHostView() const; + +- // Returns whether this manager belongs to a FrameTreeNode that belongs to an +- // inner WebContents. +- bool ForInnerDelegate(); ++ // Returns whether this manager is a main frame and belongs to a FrameTreeNode ++ // that belongs to an inner WebContents. ++ bool IsMainFrameForInnerDelegate(); + + // Returns the RenderWidgetHost of the outer WebContents (if any) that can be + // used to fetch the last keyboard event. +@@ -213,8 +213,9 @@ class CONTENT_EXPORT RenderFrameHostManager + // remote frames. + RenderWidgetHostImpl* GetOuterRenderWidgetHostForKeyboardInput(); + +- // Return the FrameTreeNode for the frame in the outer WebContents (if any) +- // that contains the inner WebContents. ++ // If this is a RenderFrameHostManager for a main frame, this method returns ++ // the FrameTreeNode for the frame in the outer WebContents (if any) that ++ // contains the inner WebContents. + FrameTreeNode* GetOuterDelegateNode(); + + // Return a proxy for this frame in the parent frame's SiteInstance. Returns +@@ -222,13 +223,13 @@ class CONTENT_EXPORT RenderFrameHostManager + // example, if this frame is same-site with its parent). + RenderFrameProxyHost* GetProxyToParent(); + +- // Returns the proxy to inner WebContents in the outer WebContents's +- // SiteInstance. Returns nullptr if this WebContents isn't part of inner/outer +- // relationship. ++ // If this is a RenderFrameHostManager for a main frame, returns the proxy to ++ // inner WebContents in the outer WebContents's SiteInstance. Returns nullptr ++ // if this WebContents isn't part of inner/outer relationship. + RenderFrameProxyHost* GetProxyToOuterDelegate(); + +- // Removes the FrameTreeNode in the outer WebContents that represents this +- // FrameTreeNode. ++ // If this is a RenderFrameHostManager for a main frame, removes the ++ // FrameTreeNode in the outer WebContents that represents this FrameTreeNode. + // TODO(lazyboy): This does not belong to RenderFrameHostManager, move it to + // somehwere else. + void RemoveOuterDelegateFrame(); +diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc +index a5e18f465f79416c05fd3ab630b40b079a7a7cbc..075810f5553731b56b08b5e6e35854bdebed2021 100644 +--- a/content/browser/frame_host/render_frame_proxy_host.cc ++++ b/content/browser/frame_host/render_frame_proxy_host.cc +@@ -68,8 +68,7 @@ RenderFrameProxyHost::RenderFrameProxyHost(SiteInstance* site_instance, + RenderFrameProxyHostID(GetProcess()->GetID(), routing_id_), + this)).second); + CHECK(render_view_host || +- (frame_tree_node_->render_manager()->ForInnerDelegate() && +- frame_tree_node_->IsMainFrame())); ++ frame_tree_node_->render_manager()->IsMainFrameForInnerDelegate()); + if (render_view_host) + frame_tree_node_->frame_tree()->AddRenderViewHostRef(render_view_host_); + +@@ -79,8 +78,7 @@ RenderFrameProxyHost::RenderFrameProxyHost(SiteInstance* site_instance, + ->current_frame_host() + ->GetSiteInstance() == site_instance; + bool is_proxy_to_outer_delegate = +- frame_tree_node_->IsMainFrame() && +- frame_tree_node_->render_manager()->ForInnerDelegate(); ++ frame_tree_node_->render_manager()->IsMainFrameForInnerDelegate(); + + // If this is a proxy to parent frame or this proxy is for the inner + // WebContents's FrameTreeNode in outer WebContents's SiteInstance, then we +@@ -262,9 +260,7 @@ void RenderFrameProxyHost::SetDestructionCallback( + } + + void RenderFrameProxyHost::OnDetach() { +- if (frame_tree_node_->render_manager()->ForInnerDelegate()) { +- // Only main frame proxy can detach for inner WebContents. +- DCHECK(frame_tree_node_->IsMainFrame()); ++ if (frame_tree_node_->render_manager()->IsMainFrameForInnerDelegate()) { + frame_tree_node_->render_manager()->RemoveOuterDelegateFrame(); + return; + }