Chromium Code Reviews| Index: content/renderer/render_frame_impl.cc |
| diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc |
| index d6d922d96be90d58192fdb5d3a85fb791701f115..4732204616a6a694015abae8ed096c0c637a9788 100644 |
| --- a/content/renderer/render_frame_impl.cc |
| +++ b/content/renderer/render_frame_impl.cc |
| @@ -165,6 +165,10 @@ namespace { |
| const size_t kExtraCharsBeforeAndAfterSelection = 100; |
| +typedef std::map<int, RenderFrameImpl*> RoutingIDFrameMap; |
| +static base::LazyInstance<RoutingIDFrameMap> g_routing_id_frame_map = |
| + LAZY_INSTANCE_INITIALIZER; |
| + |
| typedef std::map<blink::WebFrame*, RenderFrameImpl*> FrameMap; |
| base::LazyInstance<FrameMap> g_frame_map = LAZY_INSTANCE_INITIALIZER; |
| @@ -358,6 +362,13 @@ RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view, |
| } |
| // static |
| +RenderFrameImpl* RenderFrameImpl::FromRoutingID(int32 routing_id) { |
|
Charlie Reis
2014/05/15 00:32:50
This code looks fine, but any reason that it diffe
nasko
2014/05/15 18:47:13
Yes, it is identical to the code in RenderViewImpl
|
| + RoutingIDFrameMap* frames = g_routing_id_frame_map.Pointer(); |
| + RoutingIDFrameMap::iterator it = frames->find(routing_id); |
| + return it == frames->end() ? NULL : it->second; |
| +} |
| + |
| +// static |
| RenderFrame* RenderFrame::FromWebFrame(blink::WebFrame* web_frame) { |
| return RenderFrameImpl::FromWebFrame(web_frame); |
| } |
| @@ -380,6 +391,7 @@ void RenderFrameImpl::InstallCreateHook( |
| RenderFrameImpl::RenderFrameImpl(RenderViewImpl* render_view, int routing_id) |
| : frame_(NULL), |
| render_view_(render_view->AsWeakPtr()), |
| + render_frame_proxy_(NULL), |
| routing_id_(routing_id), |
| is_swapped_out_(false), |
| is_detaching_(false), |
| @@ -393,6 +405,10 @@ RenderFrameImpl::RenderFrameImpl(RenderViewImpl* render_view, int routing_id) |
| weak_factory_(this) { |
| RenderThread::Get()->AddRoute(routing_id_, this); |
| + std::pair<RoutingIDFrameMap::iterator, bool> result = |
| + g_routing_id_frame_map.Get().insert(std::make_pair(routing_id_, this)); |
| + CHECK(result.second) << "Inserting a duplicate item."; |
| + |
| #if defined(OS_ANDROID) |
| new JavaBridgeDispatcher(this); |
| #endif |
| @@ -405,6 +421,7 @@ RenderFrameImpl::RenderFrameImpl(RenderViewImpl* render_view, int routing_id) |
| RenderFrameImpl::~RenderFrameImpl() { |
| FOR_EACH_OBSERVER(RenderFrameObserver, observers_, RenderFrameGone()); |
| FOR_EACH_OBSERVER(RenderFrameObserver, observers_, OnDestruct()); |
| + g_routing_id_frame_map.Get().erase(routing_id_); |
| RenderThread::Get()->RemoveRoute(routing_id_); |
| } |
| @@ -624,12 +641,27 @@ void RenderFrameImpl::SetMediaStreamClientForTesting( |
| } |
| bool RenderFrameImpl::Send(IPC::Message* message) { |
| - if (is_detaching_ || |
| - ((is_swapped_out_ || render_view_->is_swapped_out()) && |
| - !SwappedOutMessages::CanSendWhileSwappedOut(message))) { |
| + if (is_detaching_) { |
| delete message; |
| return false; |
| } |
| + if (is_swapped_out_ || render_view_->is_swapped_out()) { |
| + if (render_frame_proxy_) { |
| + // Some call sites use the associated RenderViewImpl routing id to send |
|
Charlie Reis
2014/05/15 00:32:50
Whew, this is tricky! Maybe start with a sentence
nasko
2014/05/15 18:47:13
Done.
|
| + // messages, so it shouldn't be overwritten in that case. Additionally, |
| + // The SwapOut_ACK message must be delivered to the RenderFrameHost |
|
Charlie Reis
2014/05/15 00:32:50
nit: the
nasko
2014/05/15 18:47:13
Done.
|
| + // instead of the proxy object and needs to be special-cased here. |
| + if (message->routing_id() == routing_id_ && |
| + message->type() != FrameHostMsg_SwapOut_ACK::ID) { |
| + return render_frame_proxy_->Send(message); |
| + } |
| + } |
| + |
| + if (!SwappedOutMessages::CanSendWhileSwappedOut(message)) { |
|
Charlie Reis
2014/05/15 00:32:50
I don't think this is right. When CanSendWhileSwa
nasko
2014/05/15 18:47:13
If we ever get to call Send on the RenderFrameProx
|
| + delete message; |
| + return false; |
| + } |
| + } |
| return RenderThread::Get()->Send(message); |
| } |
| @@ -891,13 +923,15 @@ void RenderFrameImpl::OnBeforeUnload() { |
| before_unload_end_time)); |
| } |
| -void RenderFrameImpl::OnSwapOut() { |
| +void RenderFrameImpl::OnSwapOut(int proxy_routing_id) { |
| // Only run unload if we're not swapped out yet, but send the ack either way. |
| if (!is_swapped_out_ || !render_view_->is_swapped_out_) { |
| // Swap this RenderFrame out so the frame can navigate to a page rendered by |
| // a different process. This involves running the unload handler and |
| // clearing the page. Once WasSwappedOut is called, we also allow this |
| // process to exit if there are no other active RenderFrames in it. |
| + RenderFrameProxy* proxy = RenderFrameProxy::CreateFrameProxy( |
|
Charlie Reis
2014/05/15 00:32:50
I'm unclear on why this is declared up here, rathe
nasko
2014/05/15 18:47:13
I think it should be created prior to running the
|
| + proxy_routing_id, routing_id_); |
| // Send an UpdateState message before we get swapped out. |
| render_view_->SyncNavigationState(); |
| @@ -912,6 +946,7 @@ void RenderFrameImpl::OnSwapOut() { |
| if (!frame_->parent()) |
| render_view_->SetSwappedOut(true); |
| is_swapped_out_ = true; |
| + set_render_frame_proxy(proxy); |
| // Now that we're swapped out and filtering IPC messages, stop loading to |
| // ensure that no other in-progress navigation continues. We do this here |