| 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/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 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view, | 94 RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view, |
| 95 int32 routing_id) { | 95 int32 routing_id) { |
| 96 DCHECK(routing_id != MSG_ROUTING_NONE); | 96 DCHECK(routing_id != MSG_ROUTING_NONE); |
| 97 | 97 |
| 98 if (g_create_render_frame_impl) | 98 if (g_create_render_frame_impl) |
| 99 return g_create_render_frame_impl(render_view, routing_id); | 99 return g_create_render_frame_impl(render_view, routing_id); |
| 100 else | 100 else |
| 101 return new RenderFrameImpl(render_view, routing_id); | 101 return new RenderFrameImpl(render_view, routing_id); |
| 102 } | 102 } |
| 103 | 103 |
| 104 RenderFrameImpl* RenderFrameImpl::FindByWebFrame(blink::WebFrame* web_frame) { |
| 105 return g_child_frame_map.Get().find(web_frame)->second; |
| 106 } |
| 107 |
| 104 // static | 108 // static |
| 105 void RenderFrameImpl::InstallCreateHook( | 109 void RenderFrameImpl::InstallCreateHook( |
| 106 RenderFrameImpl* (*create_render_frame_impl)(RenderViewImpl*, int32)) { | 110 RenderFrameImpl* (*create_render_frame_impl)(RenderViewImpl*, int32)) { |
| 107 CHECK(!g_create_render_frame_impl); | 111 CHECK(!g_create_render_frame_impl); |
| 108 g_create_render_frame_impl = create_render_frame_impl; | 112 g_create_render_frame_impl = create_render_frame_impl; |
| 109 } | 113 } |
| 110 | 114 |
| 111 // RenderFrameImpl ---------------------------------------------------------- | 115 // RenderFrameImpl ---------------------------------------------------------- |
| 112 RenderFrameImpl::RenderFrameImpl(RenderViewImpl* render_view, int routing_id) | 116 RenderFrameImpl::RenderFrameImpl(RenderViewImpl* render_view, int routing_id) |
| 113 : render_view_(render_view), | 117 : frame_(NULL), |
| 118 render_view_(render_view), |
| 114 routing_id_(routing_id), | 119 routing_id_(routing_id), |
| 115 is_swapped_out_(false), | 120 is_swapped_out_(false), |
| 116 is_detaching_(false) { | 121 is_detaching_(false) { |
| 122 RenderThread::Get()->AddRoute(routing_id_, this); |
| 117 } | 123 } |
| 118 | 124 |
| 119 RenderFrameImpl::~RenderFrameImpl() { | 125 RenderFrameImpl::~RenderFrameImpl() { |
| 120 } | 126 } |
| 121 | 127 |
| 122 int RenderFrameImpl::GetRoutingID() const { | 128 int RenderFrameImpl::GetRoutingID() const { |
| 123 return routing_id_; | 129 return routing_id_; |
| 124 } | 130 } |
| 125 | 131 |
| 126 bool RenderFrameImpl::Send(IPC::Message* message) { | 132 bool RenderFrameImpl::Send(IPC::Message* message) { |
| 127 if (is_detaching_ || | 133 if (is_detaching_ || |
| 128 ((is_swapped_out_ || render_view_->is_swapped_out()) && | 134 ((is_swapped_out_ || render_view_->is_swapped_out()) && |
| 129 !SwappedOutMessages::CanSendWhileSwappedOut(message))) { | 135 !SwappedOutMessages::CanSendWhileSwappedOut(message))) { |
| 130 delete message; | 136 delete message; |
| 131 return false; | 137 return false; |
| 132 } | 138 } |
| 133 | 139 |
| 134 return RenderThread::Get()->Send(message); | 140 return RenderThread::Get()->Send(message); |
| 135 } | 141 } |
| 136 | 142 |
| 137 bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) { | 143 bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) { |
| 138 // TODO(ajwong): Fill in with message handlers as various components | 144 bool handled = true; |
| 139 // are migrated over to understand frames. | 145 bool msg_is_ok = true; |
| 140 return false; | 146 IPC_BEGIN_MESSAGE_MAP_EX(RenderFrameImpl, msg, msg_is_ok) |
| 147 IPC_MESSAGE_HANDLER(FrameMsg_SwapOut, OnSwapOut) |
| 148 |
| 149 IPC_END_MESSAGE_MAP() |
| 150 |
| 151 if (!msg_is_ok) { |
| 152 // The message had a handler, but its deserialization failed. |
| 153 // Kill the renderer to avoid potential spoofing attacks. |
| 154 CHECK(false) << "Unable to deserialize message in RenderFrameImpl."; |
| 155 } |
| 156 |
| 157 return handled; |
| 158 } |
| 159 |
| 160 void RenderFrameImpl::OnSwapOut() { |
| 161 // Only run unload if we're not swapped out yet, but send the ack either way. |
| 162 if (!is_swapped_out_) { |
| 163 // Swap this RenderView out so the tab can navigate to a page rendered by a |
| 164 // different process. This involves running the unload handler and clearing |
| 165 // the page. Once WasSwappedOut is called, we also allow this process to |
| 166 // exit if there are no other active RenderViews in it. |
| 167 |
| 168 // Send an UpdateState message before we get swapped out. |
| 169 render_view_->SyncNavigationState(); |
| 170 |
| 171 // Synchronously run the unload handler before sending the ACK. |
| 172 // TODO(creis): Add a WebFrame::dispatchUnloadEvent. |
| 173 //webview()->dispatchUnloadEvent(); |
| 174 |
| 175 // Swap out and stop sending any IPC messages that are not ACKs. |
| 176 is_swapped_out_ = true; |
| 177 |
| 178 // Now that we're swapped out and filtering IPC messages, stop loading to |
| 179 // ensure that no other in-progress navigation continues. We do this here |
| 180 // to avoid sending a DidStopLoading message to the browser process. |
| 181 frame_->stopLoading(); |
| 182 |
| 183 // Replace the page with a blank dummy URL. The unload handler will not be |
| 184 // run a second time, thanks to a check in FrameLoader::stopLoading. |
| 185 // TODO(creis): Need to add a better way to do this that avoids running the |
| 186 // beforeunload handler. For now, we just run it a second time silently. |
| 187 render_view_->NavigateToSwappedOutURL(frame_); |
| 188 } |
| 189 |
| 190 Send(new FrameHostMsg_SwapOut_ACK(routing_id_)); |
| 141 } | 191 } |
| 142 | 192 |
| 143 // blink::WebFrameClient implementation ------------------------------------- | 193 // blink::WebFrameClient implementation ------------------------------------- |
| 144 | 194 |
| 145 blink::WebPlugin* RenderFrameImpl::createPlugin( | 195 blink::WebPlugin* RenderFrameImpl::createPlugin( |
| 146 blink::WebFrame* frame, | 196 blink::WebFrame* frame, |
| 147 const blink::WebPluginParams& params) { | 197 const blink::WebPluginParams& params) { |
| 148 blink::WebPlugin* plugin = NULL; | 198 blink::WebPlugin* plugin = NULL; |
| 149 if (GetContentClient()->renderer()->OverrideCreatePlugin( | 199 if (GetContentClient()->renderer()->OverrideCreatePlugin( |
| 150 render_view_, frame, params, &plugin)) { | 200 render_view_, frame, params, &plugin)) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 | 267 |
| 218 void RenderFrameImpl::didAccessInitialDocument(blink::WebFrame* frame) { | 268 void RenderFrameImpl::didAccessInitialDocument(blink::WebFrame* frame) { |
| 219 render_view_->didAccessInitialDocument(frame); | 269 render_view_->didAccessInitialDocument(frame); |
| 220 } | 270 } |
| 221 | 271 |
| 222 blink::WebFrame* RenderFrameImpl::createChildFrame( | 272 blink::WebFrame* RenderFrameImpl::createChildFrame( |
| 223 blink::WebFrame* parent, | 273 blink::WebFrame* parent, |
| 224 const blink::WebString& name) { | 274 const blink::WebString& name) { |
| 225 RenderFrameImpl* child_render_frame = this; | 275 RenderFrameImpl* child_render_frame = this; |
| 226 long long child_frame_identifier = WebFrame::generateEmbedderIdentifier(); | 276 long long child_frame_identifier = WebFrame::generateEmbedderIdentifier(); |
| 227 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | 277 // Synchronously notify the browser of a child frame creation to get the |
| 228 // Synchronously notify the browser of a child frame creation to get the | 278 // routing_id for the RenderFrame. |
| 229 // routing_id for the RenderFrame. | 279 int routing_id; |
| 230 int routing_id; | 280 Send(new FrameHostMsg_CreateChildFrame(GetRoutingID(), |
| 231 Send(new FrameHostMsg_CreateChildFrame(GetRoutingID(), | 281 parent->identifier(), |
| 232 parent->identifier(), | 282 child_frame_identifier, |
| 233 child_frame_identifier, | 283 UTF16ToUTF8(name), |
| 234 UTF16ToUTF8(name), | 284 &routing_id)); |
| 235 &routing_id)); | 285 child_render_frame = RenderFrameImpl::Create(render_view_, routing_id); |
| 236 child_render_frame = RenderFrameImpl::Create(render_view_, routing_id); | |
| 237 } | |
| 238 | 286 |
| 239 blink::WebFrame* web_frame = WebFrame::create(child_render_frame, | 287 blink::WebFrame* web_frame = WebFrame::create(child_render_frame, |
| 240 child_frame_identifier); | 288 child_frame_identifier); |
| 289 child_render_frame->set_web_frame(web_frame); |
| 241 | 290 |
| 242 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | 291 g_child_frame_map.Get().insert( |
| 243 g_child_frame_map.Get().insert( | 292 std::make_pair(web_frame, child_render_frame)); |
| 244 std::make_pair(web_frame, child_render_frame)); | |
| 245 } | |
| 246 | 293 |
| 247 return web_frame; | 294 return web_frame; |
| 248 } | 295 } |
| 249 | 296 |
| 250 void RenderFrameImpl::didDisownOpener(blink::WebFrame* frame) { | 297 void RenderFrameImpl::didDisownOpener(blink::WebFrame* frame) { |
| 251 render_view_->didDisownOpener(frame); | 298 render_view_->didDisownOpener(frame); |
| 252 } | 299 } |
| 253 | 300 |
| 254 void RenderFrameImpl::frameDetached(blink::WebFrame* frame) { | 301 void RenderFrameImpl::frameDetached(blink::WebFrame* frame) { |
| 255 // NOTE: This function is called on the frame that is being detached and not | 302 // NOTE: This function is called on the frame that is being detached and not |
| 256 // the parent frame. This is different from createChildFrame() which is | 303 // the parent frame. This is different from createChildFrame() which is |
| 257 // called on the parent frame. | 304 // called on the parent frame. |
| 258 CHECK(!is_detaching_); | 305 CHECK(!is_detaching_); |
| 259 | 306 |
| 260 int64 parent_frame_id = -1; | 307 int64 parent_frame_id = -1; |
| 261 if (frame->parent()) | 308 if (frame->parent()) |
| 262 parent_frame_id = frame->parent()->identifier(); | 309 parent_frame_id = frame->parent()->identifier(); |
| 263 | 310 |
| 264 Send(new FrameHostMsg_Detach(GetRoutingID(), parent_frame_id, | 311 Send(new FrameHostMsg_Detach(GetRoutingID(), parent_frame_id, |
| 265 frame->identifier())); | 312 frame->identifier())); |
| 266 | 313 |
| 267 // Currently multiple WebCore::Frames can send frameDetached to a single | 314 // Currently multiple WebCore::Frames can send frameDetached to a single |
| 268 // RenderFrameImpl. This is legacy behavior from when RenderViewImpl served | 315 // RenderFrameImpl. This is legacy behavior from when RenderViewImpl served |
| 269 // as a shared WebFrameClient for multiple Webcore::Frame objects. It also | 316 // as a shared WebFrameClient for multiple Webcore::Frame objects. It also |
| 270 // prevents this class from entering the |is_detaching_| state because | 317 // prevents this class from entering the |is_detaching_| state because |
| 271 // even though one WebCore::Frame may have detached itself, others will | 318 // even though one WebCore::Frame may have detached itself, others will |
| 272 // still need to use this object. | 319 // still need to use this object. |
| 273 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | 320 // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be |
| 274 // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be | 321 // sent before setting |is_detaching_| to true. In contrast, Observers |
| 275 // sent before setting |is_detaching_| to true. In contrast, Observers | 322 // should only be notified afterwards so they cannot call back into and |
| 276 // should only be notified afterwards so they cannot call back into and | 323 // have IPCs fired off. |
| 277 // have IPCs fired off. | 324 is_detaching_ = true; |
| 278 is_detaching_ = true; | |
| 279 } | |
| 280 | 325 |
| 281 // Call back to RenderViewImpl for observers to be notified. | 326 // Call back to RenderViewImpl for observers to be notified. |
| 282 // TODO(nasko): Remove once we have RenderFrameObserver. | 327 // TODO(nasko): Remove once we have RenderFrameObserver. |
| 283 render_view_->frameDetached(frame); | 328 render_view_->frameDetached(frame); |
| 284 | 329 |
| 285 frame->close(); | 330 frame->close(); |
| 286 | 331 |
| 287 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | 332 // If the frame does not have a parent, it is the main frame. The main |
| 288 // If the frame does not have a parent, it is the main frame. The main | 333 // frame is owned by the containing RenderViewHost so it does not require |
| 289 // frame is owned by the containing RenderViewHost so it does not require | 334 // any cleanup here. |
| 290 // any cleanup here. | 335 if (frame->parent()) { |
| 291 if (frame->parent()) { | 336 FrameMap::iterator it = g_child_frame_map.Get().find(frame); |
| 292 FrameMap::iterator it = g_child_frame_map.Get().find(frame); | 337 DCHECK(it != g_child_frame_map.Get().end()); |
| 293 DCHECK(it != g_child_frame_map.Get().end()); | 338 DCHECK_EQ(it->second, this); |
| 294 DCHECK_EQ(it->second, this); | 339 g_child_frame_map.Get().erase(it); |
| 295 g_child_frame_map.Get().erase(it); | 340 delete this; |
| 296 delete this; | 341 // Object is invalid after this point. |
| 297 // Object is invalid after this point. | |
| 298 } | |
| 299 } | 342 } |
| 300 } | 343 } |
| 301 | 344 |
| 302 void RenderFrameImpl::willClose(blink::WebFrame* frame) { | 345 void RenderFrameImpl::willClose(blink::WebFrame* frame) { |
| 303 // Call back to RenderViewImpl for observers to be notified. | 346 // Call back to RenderViewImpl for observers to be notified. |
| 304 // TODO(nasko): Remove once we have RenderFrameObserver. | 347 // TODO(nasko): Remove once we have RenderFrameObserver. |
| 305 render_view_->willClose(frame); | 348 render_view_->willClose(frame); |
| 306 } | 349 } |
| 307 | 350 |
| 308 void RenderFrameImpl::didChangeName(blink::WebFrame* frame, | 351 void RenderFrameImpl::didChangeName(blink::WebFrame* frame, |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 | 457 |
| 415 // In fast/loader/stop-provisional-loads.html, we abort the load before this | 458 // In fast/loader/stop-provisional-loads.html, we abort the load before this |
| 416 // callback is invoked. | 459 // callback is invoked. |
| 417 if (!ds) | 460 if (!ds) |
| 418 return; | 461 return; |
| 419 | 462 |
| 420 DocumentState* document_state = DocumentState::FromDataSource(ds); | 463 DocumentState* document_state = DocumentState::FromDataSource(ds); |
| 421 | 464 |
| 422 // We should only navigate to swappedout:// when is_swapped_out_ is true. | 465 // We should only navigate to swappedout:// when is_swapped_out_ is true. |
| 423 CHECK((ds->request().url() != GURL(kSwappedOutURL)) || | 466 CHECK((ds->request().url() != GURL(kSwappedOutURL)) || |
| 467 is_swapped_out_ || |
| 424 render_view_->is_swapped_out()) << | 468 render_view_->is_swapped_out()) << |
| 425 "Heard swappedout:// when not swapped out."; | 469 "Heard swappedout:// when not swapped out."; |
| 426 | 470 |
| 427 // Update the request time if WebKit has better knowledge of it. | 471 // Update the request time if WebKit has better knowledge of it. |
| 428 if (document_state->request_time().is_null()) { | 472 if (document_state->request_time().is_null()) { |
| 429 double event_time = ds->triggeringEventTime(); | 473 double event_time = ds->triggeringEventTime(); |
| 430 if (event_time != 0.0) | 474 if (event_time != 0.0) |
| 431 document_state->set_request_time(Time::FromDoubleT(event_time)); | 475 document_state->set_request_time(Time::FromDoubleT(event_time)); |
| 432 } | 476 } |
| 433 | 477 |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 | 1006 |
| 963 void RenderFrameImpl::didLoseWebGLContext(blink::WebFrame* frame, | 1007 void RenderFrameImpl::didLoseWebGLContext(blink::WebFrame* frame, |
| 964 int arb_robustness_status_code) { | 1008 int arb_robustness_status_code) { |
| 965 render_view_->Send(new ViewHostMsg_DidLose3DContext( | 1009 render_view_->Send(new ViewHostMsg_DidLose3DContext( |
| 966 GURL(frame->top()->document().securityOrigin().toString()), | 1010 GURL(frame->top()->document().securityOrigin().toString()), |
| 967 THREE_D_API_TYPE_WEBGL, | 1011 THREE_D_API_TYPE_WEBGL, |
| 968 arb_robustness_status_code)); | 1012 arb_robustness_status_code)); |
| 969 } | 1013 } |
| 970 | 1014 |
| 971 } // namespace content | 1015 } // namespace content |
| OLD | NEW |