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

Side by Side Diff: content/renderer/render_frame_impl.cc

Issue 2619123002: Fix remote-to-local navigations in crashed subframes. (Closed)
Patch Set: Charlie's comments Created 3 years, 11 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
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/renderer/render_frame_impl.h" 5 #include "content/renderer/render_frame_impl.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 1477 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 for (auto& observer : observers_) { 1488 for (auto& observer : observers_) {
1489 if (observer.OnMessageReceived(msg)) 1489 if (observer.OnMessageReceived(msg))
1490 return true; 1490 return true;
1491 } 1491 }
1492 1492
1493 bool handled = true; 1493 bool handled = true;
1494 IPC_BEGIN_MESSAGE_MAP(RenderFrameImpl, msg) 1494 IPC_BEGIN_MESSAGE_MAP(RenderFrameImpl, msg)
1495 IPC_MESSAGE_HANDLER(FrameMsg_Navigate, OnNavigate) 1495 IPC_MESSAGE_HANDLER(FrameMsg_Navigate, OnNavigate)
1496 IPC_MESSAGE_HANDLER(FrameMsg_BeforeUnload, OnBeforeUnload) 1496 IPC_MESSAGE_HANDLER(FrameMsg_BeforeUnload, OnBeforeUnload)
1497 IPC_MESSAGE_HANDLER(FrameMsg_SwapOut, OnSwapOut) 1497 IPC_MESSAGE_HANDLER(FrameMsg_SwapOut, OnSwapOut)
1498 IPC_MESSAGE_HANDLER(FrameMsg_SwapIn, OnSwapIn)
1498 IPC_MESSAGE_HANDLER(FrameMsg_Delete, OnDeleteFrame) 1499 IPC_MESSAGE_HANDLER(FrameMsg_Delete, OnDeleteFrame)
1499 IPC_MESSAGE_HANDLER(FrameMsg_Stop, OnStop) 1500 IPC_MESSAGE_HANDLER(FrameMsg_Stop, OnStop)
1500 IPC_MESSAGE_HANDLER(FrameMsg_ContextMenuClosed, OnContextMenuClosed) 1501 IPC_MESSAGE_HANDLER(FrameMsg_ContextMenuClosed, OnContextMenuClosed)
1501 IPC_MESSAGE_HANDLER(FrameMsg_CustomContextMenuAction, 1502 IPC_MESSAGE_HANDLER(FrameMsg_CustomContextMenuAction,
1502 OnCustomContextMenuAction) 1503 OnCustomContextMenuAction)
1503 #if BUILDFLAG(ENABLE_PLUGINS) 1504 #if BUILDFLAG(ENABLE_PLUGINS)
1504 IPC_MESSAGE_HANDLER(FrameMsg_SetPepperVolume, OnSetPepperVolume) 1505 IPC_MESSAGE_HANDLER(FrameMsg_SetPepperVolume, OnSetPepperVolume)
1505 #endif 1506 #endif
1506 IPC_MESSAGE_HANDLER(InputMsg_Undo, OnUndo) 1507 IPC_MESSAGE_HANDLER(InputMsg_Undo, OnUndo)
1507 IPC_MESSAGE_HANDLER(InputMsg_Redo, OnRedo) 1508 IPC_MESSAGE_HANDLER(InputMsg_Redo, OnRedo)
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1761 // TODO(nasko): Remove the dependency on RenderViewImpl here and ref count 1762 // TODO(nasko): Remove the dependency on RenderViewImpl here and ref count
1762 // the process based on the lifetime of this RenderFrameImpl object. 1763 // the process based on the lifetime of this RenderFrameImpl object.
1763 if (is_main_frame) 1764 if (is_main_frame)
1764 render_view->WasSwappedOut(); 1765 render_view->WasSwappedOut();
1765 1766
1766 // Notify the browser that this frame was swapped. Use the RenderThread 1767 // Notify the browser that this frame was swapped. Use the RenderThread
1767 // directly because |this| is deleted. 1768 // directly because |this| is deleted.
1768 RenderThread::Get()->Send(new FrameHostMsg_SwapOut_ACK(routing_id)); 1769 RenderThread::Get()->Send(new FrameHostMsg_SwapOut_ACK(routing_id));
1769 } 1770 }
1770 1771
1772 void RenderFrameImpl::OnSwapIn() {
1773 SwapIn();
1774 }
1775
1771 void RenderFrameImpl::OnDeleteFrame() { 1776 void RenderFrameImpl::OnDeleteFrame() {
1772 // TODO(nasko): If this message is received right after a commit has 1777 // TODO(nasko): If this message is received right after a commit has
1773 // swapped a RenderFrameProxy with this RenderFrame, the proxy needs to be 1778 // swapped a RenderFrameProxy with this RenderFrame, the proxy needs to be
1774 // recreated in addition to the RenderFrame being deleted. 1779 // recreated in addition to the RenderFrame being deleted.
1775 // See https://crbug.com/569683 for details. 1780 // See https://crbug.com/569683 for details.
1776 in_browser_initiated_detach_ = true; 1781 in_browser_initiated_detach_ = true;
1777 1782
1778 // This will result in a call to RendeFrameImpl::frameDetached, which 1783 // This will result in a call to RendeFrameImpl::frameDetached, which
1779 // deletes the object. Do not access |this| after detach. 1784 // deletes the object. Do not access |this| after detach.
1780 frame_->detach(); 1785 frame_->detach();
(...skipping 1802 matching lines...) Expand 10 before | Expand all | Expand 10 after
3583 if (is_main_frame_ && !navigation_state->WasWithinSamePage()) { 3588 if (is_main_frame_ && !navigation_state->WasWithinSamePage()) {
3584 is_using_lofi_ = extra_data && extra_data->is_using_lofi(); 3589 is_using_lofi_ = extra_data && extra_data->is_using_lofi();
3585 if (extra_data) { 3590 if (extra_data) {
3586 effective_connection_type_ = 3591 effective_connection_type_ =
3587 EffectiveConnectionTypeToWebEffectiveConnectionType( 3592 EffectiveConnectionTypeToWebEffectiveConnectionType(
3588 extra_data->effective_connection_type()); 3593 extra_data->effective_connection_type());
3589 } 3594 }
3590 } 3595 }
3591 3596
3592 if (proxy_routing_id_ != MSG_ROUTING_NONE) { 3597 if (proxy_routing_id_ != MSG_ROUTING_NONE) {
3593 RenderFrameProxy* proxy = 3598 // If this is a provisional frame associated with a proxy (i.e., a frame
3594 RenderFrameProxy::FromRoutingID(proxy_routing_id_); 3599 // created for a remote-to-local navigation), swap it into the frame tree
3595 3600 // now.
3596 // The proxy might have been detached while the provisional LocalFrame was 3601 if (!SwapIn())
3597 // being navigated. In that case, don't swap the frame back in the tree
3598 // and return early (to avoid sending confusing IPCs to the browser
3599 // process). See https://crbug.com/526304 and https://crbug.com/568676.
3600 // TODO(nasko, alexmos): Eventually, the browser process will send an IPC
3601 // to clean this frame up after https://crbug.com/548275 is fixed.
3602 if (!proxy)
3603 return; 3602 return;
3604
3605 int proxy_routing_id = proxy_routing_id_;
3606 if (!proxy->web_frame()->swap(frame_))
3607 return;
3608 proxy_routing_id_ = MSG_ROUTING_NONE;
3609 in_frame_tree_ = true;
3610
3611 // If this is the main frame going from a remote frame to a local frame,
3612 // it needs to set RenderViewImpl's pointer for the main frame to itself
3613 // and ensure RenderWidget is no longer in swapped out mode.
3614 if (is_main_frame_) {
3615 // Debug cases of https://crbug.com/575245.
3616 base::debug::SetCrashKeyValue("commit_frame_id",
3617 base::IntToString(GetRoutingID()));
3618 base::debug::SetCrashKeyValue("commit_proxy_id",
3619 base::IntToString(proxy_routing_id));
3620 base::debug::SetCrashKeyValue(
3621 "commit_view_id", base::IntToString(render_view_->GetRoutingID()));
3622 if (render_view_->main_render_frame_) {
3623 base::debug::SetCrashKeyValue(
3624 "commit_main_render_frame_id",
3625 base::IntToString(
3626 render_view_->main_render_frame_->GetRoutingID()));
3627 }
3628 CHECK(!render_view_->main_render_frame_);
3629 render_view_->main_render_frame_ = this;
3630 if (render_view_->is_swapped_out())
3631 render_view_->SetSwappedOut(false);
3632 }
3633 } 3603 }
3634 3604
3635 // For new page navigations, the browser process needs to be notified of the 3605 // For new page navigations, the browser process needs to be notified of the
3636 // first paint of that page, so it can cancel the timer that waits for it. 3606 // first paint of that page, so it can cancel the timer that waits for it.
3637 if (is_main_frame_ && !navigation_state->WasWithinSamePage()) { 3607 if (is_main_frame_ && !navigation_state->WasWithinSamePage()) {
3638 render_view_->QueueMessage( 3608 render_view_->QueueMessage(
3639 new ViewHostMsg_DidFirstPaintAfterLoad(render_view_->routing_id_), 3609 new ViewHostMsg_DidFirstPaintAfterLoad(render_view_->routing_id_),
3640 MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE); 3610 MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE);
3641 } 3611 }
3642 3612
(...skipping 1371 matching lines...) Expand 10 before | Expand all | Expand 10 after
5014 // allowImages(), allowPlugins() is called for the new page, so that when 4984 // allowImages(), allowPlugins() is called for the new page, so that when
5015 // these functions send a ViewHostMsg_ContentBlocked message, it arrives 4985 // these functions send a ViewHostMsg_ContentBlocked message, it arrives
5016 // after the FrameHostMsg_DidCommitProvisionalLoad message. 4986 // after the FrameHostMsg_DidCommitProvisionalLoad message.
5017 Send(new FrameHostMsg_DidCommitProvisionalLoad(routing_id_, params)); 4987 Send(new FrameHostMsg_DidCommitProvisionalLoad(routing_id_, params));
5018 4988
5019 // If we end up reusing this WebRequest (for example, due to a #ref click), 4989 // If we end up reusing this WebRequest (for example, due to a #ref click),
5020 // we don't want the transition type to persist. Just clear it. 4990 // we don't want the transition type to persist. Just clear it.
5021 navigation_state->set_transition_type(ui::PAGE_TRANSITION_LINK); 4991 navigation_state->set_transition_type(ui::PAGE_TRANSITION_LINK);
5022 } 4992 }
5023 4993
4994 bool RenderFrameImpl::SwapIn() {
4995 CHECK_NE(proxy_routing_id_, MSG_ROUTING_NONE);
4996 CHECK(!in_frame_tree_);
4997 RenderFrameProxy* proxy = RenderFrameProxy::FromRoutingID(proxy_routing_id_);
4998
4999 // The proxy might have been detached while the provisional LocalFrame was
5000 // being navigated. In that case, don't swap the frame back in the tree
5001 // and return early (to avoid sending confusing IPCs to the browser
5002 // process). See https://crbug.com/526304 and https://crbug.com/568676.
5003 if (!proxy)
5004 return false;
5005
5006 int proxy_routing_id = proxy_routing_id_;
5007 if (!proxy->web_frame()->swap(frame_))
5008 return false;
5009
5010 proxy_routing_id_ = MSG_ROUTING_NONE;
5011 in_frame_tree_ = true;
5012
5013 // If this is the main frame going from a remote frame to a local frame,
5014 // it needs to set RenderViewImpl's pointer for the main frame to itself
5015 // and ensure RenderWidget is no longer in swapped out mode.
5016 if (is_main_frame_) {
5017 // Debug cases of https://crbug.com/575245.
5018 base::debug::SetCrashKeyValue("commit_frame_id",
5019 base::IntToString(GetRoutingID()));
5020 base::debug::SetCrashKeyValue("commit_proxy_id",
5021 base::IntToString(proxy_routing_id));
5022 base::debug::SetCrashKeyValue(
5023 "commit_view_id", base::IntToString(render_view_->GetRoutingID()));
5024 if (render_view_->main_render_frame_) {
5025 base::debug::SetCrashKeyValue(
5026 "commit_main_render_frame_id",
5027 base::IntToString(render_view_->main_render_frame_->GetRoutingID()));
5028 }
5029 CHECK(!render_view_->main_render_frame_);
5030 render_view_->main_render_frame_ = this;
5031 if (render_view_->is_swapped_out())
5032 render_view_->SetSwappedOut(false);
5033 }
5034
5035 return true;
5036 }
5037
5024 void RenderFrameImpl::didStartLoading(bool to_different_document) { 5038 void RenderFrameImpl::didStartLoading(bool to_different_document) {
5025 TRACE_EVENT1("navigation,rail", "RenderFrameImpl::didStartLoading", 5039 TRACE_EVENT1("navigation,rail", "RenderFrameImpl::didStartLoading",
5026 "id", routing_id_); 5040 "id", routing_id_);
5027 render_view_->FrameDidStartLoading(frame_); 5041 render_view_->FrameDidStartLoading(frame_);
5028 5042
5029 // PlzNavigate: the browser is responsible for knowing the start of all 5043 // PlzNavigate: the browser is responsible for knowing the start of all
5030 // non-synchronous navigations. 5044 // non-synchronous navigations.
5031 if (!IsBrowserSideNavigationEnabled() || !to_different_document) 5045 if (!IsBrowserSideNavigationEnabled() || !to_different_document)
5032 Send(new FrameHostMsg_DidStartLoading(routing_id_, to_different_document)); 5046 Send(new FrameHostMsg_DidStartLoading(routing_id_, to_different_document));
5033 } 5047 }
(...skipping 1742 matching lines...) Expand 10 before | Expand all | Expand 10 after
6776 // event target. Potentially a Pepper plugin will receive the event. 6790 // event target. Potentially a Pepper plugin will receive the event.
6777 // In order to tell whether a plugin gets the last mouse event and which it 6791 // In order to tell whether a plugin gets the last mouse event and which it
6778 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets 6792 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets
6779 // the event, it will notify us via DidReceiveMouseEvent() and set itself as 6793 // the event, it will notify us via DidReceiveMouseEvent() and set itself as
6780 // |pepper_last_mouse_event_target_|. 6794 // |pepper_last_mouse_event_target_|.
6781 pepper_last_mouse_event_target_ = nullptr; 6795 pepper_last_mouse_event_target_ = nullptr;
6782 #endif 6796 #endif
6783 } 6797 }
6784 6798
6785 } // namespace content 6799 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698