Index: content/renderer/render_frame_impl.cc |
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc |
index 0fd1953d11f4ab361b0de24689e997e6e5107d88..1a22fef0a4fc8003365dc5385e7b9b6f2226b262 100644 |
--- a/content/renderer/render_frame_impl.cc |
+++ b/content/renderer/render_frame_impl.cc |
@@ -114,6 +114,10 @@ RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view, |
return new RenderFrameImpl(render_view, routing_id); |
} |
+RenderFrameImpl* RenderFrameImpl::FindByWebFrame(blink::WebFrame* web_frame) { |
+ return g_child_frame_map.Get().find(web_frame)->second; |
+} |
+ |
// static |
void RenderFrameImpl::InstallCreateHook( |
RenderFrameImpl* (*create_render_frame_impl)(RenderViewImpl*, int32)) { |
@@ -123,7 +127,8 @@ void RenderFrameImpl::InstallCreateHook( |
// RenderFrameImpl ---------------------------------------------------------- |
RenderFrameImpl::RenderFrameImpl(RenderViewImpl* render_view, int routing_id) |
- : render_view_(render_view), |
+ : frame_(NULL), |
+ render_view_(render_view), |
routing_id_(routing_id), |
is_swapped_out_(false), |
is_detaching_(false) { |
@@ -461,9 +466,53 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) { |
return true; |
} |
- // TODO(ajwong): Fill in with message handlers as various components |
- // are migrated over to understand frames. |
- return false; |
+ bool handled = true; |
+ bool msg_is_ok = true; |
+ IPC_BEGIN_MESSAGE_MAP_EX(RenderFrameImpl, msg, msg_is_ok) |
+ IPC_MESSAGE_HANDLER(FrameMsg_SwapOut, OnSwapOut) |
+ |
+ IPC_END_MESSAGE_MAP() |
+ |
+ if (!msg_is_ok) { |
+ // The message had a handler, but its deserialization failed. |
+ // Kill the renderer to avoid potential spoofing attacks. |
+ CHECK(false) << "Unable to deserialize message in RenderFrameImpl."; |
+ } |
+ |
+ return handled; |
+} |
+ |
+void RenderFrameImpl::OnSwapOut() { |
+ // Only run unload if we're not swapped out yet, but send the ack either way. |
+ if (!is_swapped_out_) { |
+ // Swap this RenderView out so the tab 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 RenderViews in it. |
+ |
+ // Send an UpdateState message before we get swapped out. |
+ render_view_->SyncNavigationState(); |
+ |
+ // Synchronously run the unload handler before sending the ACK. |
+ // TODO(creis): Add a WebFrame::dispatchUnloadEvent. |
+ //webview()->dispatchUnloadEvent(); |
+ |
+ // Swap out and stop sending any IPC messages that are not ACKs. |
+ is_swapped_out_ = true; |
+ |
+ // 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 |
+ // to avoid sending a DidStopLoading message to the browser process. |
+ frame_->stopLoading(); |
+ |
+ // Replace the page with a blank dummy URL. The unload handler will not be |
+ // run a second time, thanks to a check in FrameLoader::stopLoading. |
+ // TODO(creis): Need to add a better way to do this that avoids running the |
+ // beforeunload handler. For now, we just run it a second time silently. |
+ render_view_->NavigateToSwappedOutURL(frame_); |
+ } |
+ |
+ Send(new FrameHostMsg_SwapOut_ACK(routing_id_)); |
} |
RenderView* RenderFrameImpl::GetRenderView() { |
@@ -605,28 +654,24 @@ blink::WebFrame* RenderFrameImpl::createChildFrame( |
const blink::WebString& name) { |
RenderFrameImpl* child_render_frame = this; |
long long child_frame_identifier = WebFrame::generateEmbedderIdentifier(); |
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { |
- // Synchronously notify the browser of a child frame creation to get the |
- // routing_id for the RenderFrame. |
- int routing_id; |
- Send(new FrameHostMsg_CreateChildFrame(routing_id_, |
- parent->identifier(), |
- child_frame_identifier, |
- UTF16ToUTF8(name), |
- &routing_id)); |
- child_render_frame = RenderFrameImpl::Create(render_view_, routing_id); |
- } |
+ // Synchronously notify the browser of a child frame creation to get the |
+ // routing_id for the RenderFrame. |
+ int routing_id; |
+ Send(new FrameHostMsg_CreateChildFrame(routing_id_, |
+ parent->identifier(), |
+ child_frame_identifier, |
+ UTF16ToUTF8(name), |
+ &routing_id)); |
+ child_render_frame = RenderFrameImpl::Create(render_view_, routing_id); |
blink::WebFrame* web_frame = WebFrame::create(child_render_frame, |
child_frame_identifier); |
+ child_render_frame->set_web_frame(web_frame); |
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { |
- g_child_frame_map.Get().insert( |
- std::make_pair(web_frame, child_render_frame)); |
- } else { |
- FOR_EACH_OBSERVER(RenderFrameObserver, observers_, |
- WebFrameCreated(web_frame)); |
- } |
+ g_child_frame_map.Get().insert( |
+ std::make_pair(web_frame, child_render_frame)); |
+ FOR_EACH_OBSERVER(RenderFrameObserver, observers_, |
+ WebFrameCreated(web_frame)); |
return web_frame; |
} |
@@ -654,13 +699,11 @@ void RenderFrameImpl::frameDetached(blink::WebFrame* frame) { |
// prevents this class from entering the |is_detaching_| state because |
// even though one WebCore::Frame may have detached itself, others will |
// still need to use this object. |
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { |
- // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be |
- // sent before setting |is_detaching_| to true. In contrast, Observers |
- // should only be notified afterwards so they cannot call back into and |
- // have IPCs fired off. |
- is_detaching_ = true; |
- } |
+ // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be |
+ // sent before setting |is_detaching_| to true. In contrast, Observers |
+ // should only be notified afterwards so they cannot call back into and |
+ // have IPCs fired off. |
+ is_detaching_ = true; |
// Call back to RenderViewImpl for observers to be notified. |
// TODO(nasko): Remove once we have RenderFrameObserver. |
@@ -668,18 +711,16 @@ void RenderFrameImpl::frameDetached(blink::WebFrame* frame) { |
frame->close(); |
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { |
- // If the frame does not have a parent, it is the main frame. The main |
- // frame is owned by the containing RenderViewHost so it does not require |
- // any cleanup here. |
- if (frame->parent()) { |
- FrameMap::iterator it = g_child_frame_map.Get().find(frame); |
- DCHECK(it != g_child_frame_map.Get().end()); |
- DCHECK_EQ(it->second, this); |
- g_child_frame_map.Get().erase(it); |
- delete this; |
- // Object is invalid after this point. |
- } |
+ // If the frame does not have a parent, it is the main frame. The main |
+ // frame is owned by the containing RenderViewHost so it does not require |
+ // any cleanup here. |
+ if (frame->parent()) { |
+ FrameMap::iterator it = g_child_frame_map.Get().find(frame); |
+ DCHECK(it != g_child_frame_map.Get().end()); |
+ DCHECK_EQ(it->second, this); |
+ g_child_frame_map.Get().erase(it); |
+ delete this; |
+ // Object is invalid after this point. |
} |
} |
@@ -805,6 +846,7 @@ void RenderFrameImpl::didStartProvisionalLoad(blink::WebFrame* frame) { |
// We should only navigate to swappedout:// when is_swapped_out_ is true. |
CHECK((ds->request().url() != GURL(kSwappedOutURL)) || |
+ is_swapped_out_ || |
render_view_->is_swapped_out()) << |
"Heard swappedout:// when not swapped out."; |