OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_widget.h" | 5 #include "content/renderer/render_widget.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 g_create_render_widget = create_render_widget; | 280 g_create_render_widget = create_render_widget; |
281 g_render_widget_initialized = render_widget_initialized; | 281 g_render_widget_initialized = render_widget_initialized; |
282 } | 282 } |
283 | 283 |
284 // static | 284 // static |
285 RenderWidget* RenderWidget::Create(int32_t opener_id, | 285 RenderWidget* RenderWidget::Create(int32_t opener_id, |
286 CompositorDependencies* compositor_deps, | 286 CompositorDependencies* compositor_deps, |
287 blink::WebPopupType popup_type, | 287 blink::WebPopupType popup_type, |
288 const ScreenInfo& screen_info) { | 288 const ScreenInfo& screen_info) { |
289 DCHECK(opener_id != MSG_ROUTING_NONE); | 289 DCHECK(opener_id != MSG_ROUTING_NONE); |
290 | |
291 // Do a synchronous IPC to obtain a routing ID. | |
292 int32_t routing_id = MSG_ROUTING_NONE; | |
293 if (!RenderThreadImpl::current_render_message_filter()->CreateNewWidget( | |
294 opener_id, popup_type, &routing_id)) { | |
295 return nullptr; | |
296 } | |
297 | |
298 scoped_refptr<RenderWidget> widget(new RenderWidget( | 290 scoped_refptr<RenderWidget> widget(new RenderWidget( |
299 compositor_deps, popup_type, screen_info, false, false, false)); | 291 compositor_deps, popup_type, screen_info, false, false, false)); |
300 widget->InitRoutingID(routing_id); | 292 if (widget->Init(opener_id)) { // adds reference on success. |
301 widget->Init(opener_id, RenderWidget::CreateWebWidget(widget.get())); | 293 return widget.get(); |
302 DCHECK(!widget->HasOneRef()); // RenderWidget::Init() adds a reference. | 294 } |
303 return widget.get(); | 295 return NULL; |
304 } | 296 } |
305 | 297 |
306 // static | 298 // static |
307 RenderWidget* RenderWidget::CreateForFrame( | 299 RenderWidget* RenderWidget::CreateForFrame( |
308 int widget_routing_id, | 300 int routing_id, |
309 bool hidden, | 301 bool hidden, |
310 const ScreenInfo& screen_info, | 302 const ScreenInfo& screen_info, |
311 CompositorDependencies* compositor_deps, | 303 CompositorDependencies* compositor_deps, |
312 blink::WebLocalFrame* frame) { | 304 blink::WebLocalFrame* frame) { |
313 CHECK_NE(widget_routing_id, MSG_ROUTING_NONE); | 305 CHECK_NE(routing_id, MSG_ROUTING_NONE); |
314 // TODO(avi): Before RenderViewImpl has-a RenderWidget, the browser passes the | 306 // TODO(avi): Before RenderViewImpl has-a RenderWidget, the browser passes the |
315 // same routing ID for both the view routing ID and the main frame widget | 307 // same routing ID for both the view routing ID and the main frame widget |
316 // routing ID. https://crbug.com/545684 | 308 // routing ID. https://crbug.com/545684 |
317 RenderViewImpl* view = RenderViewImpl::FromRoutingID(widget_routing_id); | 309 RenderViewImpl* view = RenderViewImpl::FromRoutingID(routing_id); |
318 if (view) { | 310 if (view) { |
319 view->AttachWebFrameWidget( | 311 view->AttachWebFrameWidget( |
320 RenderWidget::CreateWebFrameWidget(view->GetWidget(), frame)); | 312 RenderWidget::CreateWebFrameWidget(view->GetWidget(), frame)); |
321 return view->GetWidget(); | 313 return view->GetWidget(); |
322 } | 314 } |
323 scoped_refptr<RenderWidget> widget( | 315 scoped_refptr<RenderWidget> widget( |
324 g_create_render_widget | 316 g_create_render_widget |
325 ? g_create_render_widget(compositor_deps, blink::WebPopupTypeNone, | 317 ? g_create_render_widget(compositor_deps, blink::WebPopupTypeNone, |
326 screen_info, false, hidden, false) | 318 screen_info, false, hidden, false) |
327 : new RenderWidget(compositor_deps, blink::WebPopupTypeNone, | 319 : new RenderWidget(compositor_deps, blink::WebPopupTypeNone, |
328 screen_info, false, hidden, false)); | 320 screen_info, false, hidden, false)); |
| 321 widget->SetRoutingID(routing_id); |
329 widget->for_oopif_ = true; | 322 widget->for_oopif_ = true; |
330 // Init increments the reference count on |widget|, keeping it alive after | 323 // DoInit increments the reference count on |widget|, keeping it alive after |
331 // this function returns. | 324 // this function returns. |
332 widget->InitRoutingID(widget_routing_id); | 325 if (widget->DoInit(MSG_ROUTING_NONE, |
333 widget->Init(MSG_ROUTING_NONE, | 326 RenderWidget::CreateWebFrameWidget(widget.get(), frame), |
334 RenderWidget::CreateWebFrameWidget(widget.get(), frame)); | 327 CreateWidgetCallback())) { |
335 | 328 if (g_render_widget_initialized) |
336 if (g_render_widget_initialized) | 329 g_render_widget_initialized(widget.get()); |
337 g_render_widget_initialized(widget.get()); | 330 return widget.get(); |
338 return widget.get(); | 331 } |
| 332 return nullptr; |
339 } | 333 } |
340 | 334 |
341 // static | 335 // static |
342 blink::WebFrameWidget* RenderWidget::CreateWebFrameWidget( | 336 blink::WebFrameWidget* RenderWidget::CreateWebFrameWidget( |
343 RenderWidget* render_widget, | 337 RenderWidget* render_widget, |
344 blink::WebLocalFrame* frame) { | 338 blink::WebLocalFrame* frame) { |
345 if (!frame->parent()) { | 339 if (!frame->parent()) { |
346 // TODO(dcheng): The main frame widget currently has a special case. | 340 // TODO(dcheng): The main frame widget currently has a special case. |
347 // Eliminate this once WebView is no longer a WebWidget. | 341 // Eliminate this once WebView is no longer a WebWidget. |
348 return blink::WebFrameWidget::create(render_widget, frame->view(), frame); | 342 return blink::WebFrameWidget::create(render_widget, frame->view(), frame); |
(...skipping 11 matching lines...) Expand all Loading... |
360 default: | 354 default: |
361 NOTREACHED(); | 355 NOTREACHED(); |
362 } | 356 } |
363 return NULL; | 357 return NULL; |
364 } | 358 } |
365 | 359 |
366 void RenderWidget::CloseForFrame() { | 360 void RenderWidget::CloseForFrame() { |
367 OnClose(); | 361 OnClose(); |
368 } | 362 } |
369 | 363 |
| 364 void RenderWidget::SetRoutingID(int32_t routing_id) { |
| 365 routing_id_ = routing_id; |
| 366 input_handler_.reset(new RenderWidgetInputHandler( |
| 367 GetRenderWidgetInputHandlerDelegate(this), this)); |
| 368 } |
| 369 |
370 void RenderWidget::SetSwappedOut(bool is_swapped_out) { | 370 void RenderWidget::SetSwappedOut(bool is_swapped_out) { |
371 // We should only toggle between states. | 371 // We should only toggle between states. |
372 DCHECK(is_swapped_out_ != is_swapped_out); | 372 DCHECK(is_swapped_out_ != is_swapped_out); |
373 is_swapped_out_ = is_swapped_out; | 373 is_swapped_out_ = is_swapped_out; |
374 | 374 |
375 // If we are swapping out, we will call ReleaseProcess, allowing the process | 375 // If we are swapping out, we will call ReleaseProcess, allowing the process |
376 // to exit if all of its RenderViews are swapped out. We wait until the | 376 // to exit if all of its RenderViews are swapped out. We wait until the |
377 // WasSwappedOut call to do this, to allow the unload handler to finish. | 377 // WasSwappedOut call to do this, to allow the unload handler to finish. |
378 // If we are swapping in, we call AddRefProcess to prevent the process from | 378 // If we are swapping in, we call AddRefProcess to prevent the process from |
379 // exiting. | 379 // exiting. |
380 if (!is_swapped_out_) | 380 if (!is_swapped_out_) |
381 RenderProcess::current()->AddRefProcess(); | 381 RenderProcess::current()->AddRefProcess(); |
382 } | 382 } |
383 | 383 |
384 void RenderWidget::InitRoutingID(int32_t routing_id) { | 384 bool RenderWidget::CreateWidget(int32_t opener_id, |
385 DCHECK_EQ(routing_id_, MSG_ROUTING_NONE); | 385 blink::WebPopupType popup_type, |
386 routing_id_ = routing_id; | 386 int32_t* routing_id) { |
387 input_handler_.reset(new RenderWidgetInputHandler( | 387 RenderThreadImpl::current_render_message_filter()->CreateNewWidget( |
388 GetRenderWidgetInputHandlerDelegate(this), this)); | 388 opener_id, popup_type, routing_id); |
| 389 return true; |
389 } | 390 } |
390 | 391 |
391 void RenderWidget::Init(int32_t opener_id, WebWidget* web_widget) { | 392 bool RenderWidget::Init(int32_t opener_id) { |
| 393 bool success = DoInit(opener_id, RenderWidget::CreateWebWidget(this), |
| 394 base::Bind(&RenderWidget::CreateWidget, base::Unretained(this), |
| 395 opener_id, popup_type_, &routing_id_)); |
| 396 if (success) { |
| 397 SetRoutingID(routing_id_); |
| 398 return true; |
| 399 } |
| 400 return false; |
| 401 } |
| 402 |
| 403 bool RenderWidget::DoInit(int32_t opener_id, |
| 404 WebWidget* web_widget, |
| 405 CreateWidgetCallback create_widget_callback) { |
392 DCHECK(!webwidget_internal_); | 406 DCHECK(!webwidget_internal_); |
393 DCHECK_NE(routing_id_, MSG_ROUTING_NONE); | |
394 | 407 |
395 if (opener_id != MSG_ROUTING_NONE) | 408 if (opener_id != MSG_ROUTING_NONE) |
396 opener_id_ = opener_id; | 409 opener_id_ = opener_id; |
397 | 410 |
398 webwidget_internal_ = web_widget; | 411 webwidget_internal_ = web_widget; |
399 webwidget_mouse_lock_target_.reset( | 412 webwidget_mouse_lock_target_.reset( |
400 new WebWidgetLockTarget(webwidget_internal_)); | 413 new WebWidgetLockTarget(webwidget_internal_)); |
401 mouse_lock_dispatcher_.reset(new RenderWidgetMouseLockDispatcher(this)); | 414 mouse_lock_dispatcher_.reset(new RenderWidgetMouseLockDispatcher(this)); |
402 | 415 |
403 RenderThread::Get()->AddRoute(routing_id_, this); | 416 bool result = true; |
404 // Take a reference on behalf of the RenderThread. This will be balanced | 417 if (!create_widget_callback.is_null()) |
405 // when we receive ViewMsg_Close. | 418 result = std::move(create_widget_callback).Run(); |
406 AddRef(); | 419 |
407 if (RenderThreadImpl::current()) { | 420 if (result) { |
408 RenderThreadImpl::current()->WidgetCreated(); | 421 RenderThread::Get()->AddRoute(routing_id_, this); |
409 if (is_hidden_) | 422 // Take a reference on behalf of the RenderThread. This will be balanced |
410 RenderThreadImpl::current()->WidgetHidden(); | 423 // when we receive ViewMsg_Close. |
| 424 AddRef(); |
| 425 if (RenderThreadImpl::current()) { |
| 426 RenderThreadImpl::current()->WidgetCreated(); |
| 427 if (is_hidden_) |
| 428 RenderThreadImpl::current()->WidgetHidden(); |
| 429 } |
| 430 |
| 431 return true; |
| 432 } else { |
| 433 // The above Send can fail when the tab is closing. |
| 434 return false; |
411 } | 435 } |
412 } | 436 } |
413 | 437 |
414 void RenderWidget::WasSwappedOut() { | 438 void RenderWidget::WasSwappedOut() { |
415 // If we have been swapped out and no one else is using this process, | 439 // If we have been swapped out and no one else is using this process, |
416 // it's safe to exit now. | 440 // it's safe to exit now. |
417 CHECK(is_swapped_out_); | 441 CHECK(is_swapped_out_); |
418 RenderProcess::current()->ReleaseProcess(); | 442 RenderProcess::current()->ReleaseProcess(); |
419 } | 443 } |
420 | 444 |
(...skipping 1622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2043 bool RenderWidget::isPointerLocked() { | 2067 bool RenderWidget::isPointerLocked() { |
2044 return mouse_lock_dispatcher_->IsMouseLockedTo( | 2068 return mouse_lock_dispatcher_->IsMouseLockedTo( |
2045 webwidget_mouse_lock_target_.get()); | 2069 webwidget_mouse_lock_target_.get()); |
2046 } | 2070 } |
2047 | 2071 |
2048 blink::WebWidget* RenderWidget::GetWebWidget() const { | 2072 blink::WebWidget* RenderWidget::GetWebWidget() const { |
2049 return webwidget_internal_; | 2073 return webwidget_internal_; |
2050 } | 2074 } |
2051 | 2075 |
2052 } // namespace content | 2076 } // namespace content |
OLD | NEW |