Chromium Code Reviews| 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_view_impl.h" | 5 #include "content/renderer/render_view_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
| 14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 15 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
| 16 #include "base/json/json_writer.h" | 16 #include "base/json/json_writer.h" |
| 17 #include "base/lazy_instance.h" | 17 #include "base/lazy_instance.h" |
| 18 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
| 19 #include "base/path_service.h" | 19 #include "base/path_service.h" |
| 20 #include "base/process_util.h" | 20 #include "base/process_util.h" |
| 21 #include "base/string_number_conversions.h" | 21 #include "base/string_number_conversions.h" |
| 22 #include "base/string_piece.h" | 22 #include "base/string_piece.h" |
| 23 #include "base/string_split.h" | 23 #include "base/string_split.h" |
| 24 #include "base/string_util.h" | 24 #include "base/string_util.h" |
| 25 #include "base/sys_string_conversions.h" | 25 #include "base/sys_string_conversions.h" |
| 26 #include "base/time.h" | 26 #include "base/time.h" |
| 27 #include "base/utf_string_conversions.h" | 27 #include "base/utf_string_conversions.h" |
| 28 #include "content/common/appcache/appcache_dispatcher.h" | 28 #include "content/common/appcache/appcache_dispatcher.h" |
| 29 #include "content/common/child_thread.h" | |
| 29 #include "content/common/clipboard_messages.h" | 30 #include "content/common/clipboard_messages.h" |
| 30 #include "content/common/database_messages.h" | 31 #include "content/common/database_messages.h" |
| 31 #include "content/common/drag_messages.h" | 32 #include "content/common/drag_messages.h" |
| 32 #include "content/common/fileapi/file_system_dispatcher.h" | 33 #include "content/common/fileapi/file_system_dispatcher.h" |
| 33 #include "content/common/fileapi/webfilesystem_callback_dispatcher.h" | 34 #include "content/common/fileapi/webfilesystem_callback_dispatcher.h" |
| 34 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" | 35 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" |
| 35 #include "content/common/intents_messages.h" | 36 #include "content/common/intents_messages.h" |
| 36 #include "content/common/java_bridge_messages.h" | 37 #include "content/common/java_bridge_messages.h" |
| 37 #include "content/common/pepper_messages.h" | 38 #include "content/common/pepper_messages.h" |
| 38 #include "content/common/pepper_plugin_registry.h" | 39 #include "content/common/pepper_plugin_registry.h" |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 RenderViewImpl::RenderViewImpl( | 428 RenderViewImpl::RenderViewImpl( |
| 428 gfx::NativeViewId parent_hwnd, | 429 gfx::NativeViewId parent_hwnd, |
| 429 int32 opener_id, | 430 int32 opener_id, |
| 430 const content::RendererPreferences& renderer_prefs, | 431 const content::RendererPreferences& renderer_prefs, |
| 431 const WebPreferences& webkit_prefs, | 432 const WebPreferences& webkit_prefs, |
| 432 SharedRenderViewCounter* counter, | 433 SharedRenderViewCounter* counter, |
| 433 int32 routing_id, | 434 int32 routing_id, |
| 434 int32 surface_id, | 435 int32 surface_id, |
| 435 int64 session_storage_namespace_id, | 436 int64 session_storage_namespace_id, |
| 436 const string16& frame_name, | 437 const string16& frame_name, |
| 438 bool is_renderer_created, | |
| 439 bool swapped_out, | |
| 437 int32 next_page_id, | 440 int32 next_page_id, |
| 438 const WebKit::WebScreenInfo& screen_info, | 441 const WebKit::WebScreenInfo& screen_info, |
| 439 bool guest, | 442 bool guest, |
| 440 AccessibilityMode accessibility_mode) | 443 AccessibilityMode accessibility_mode) |
| 441 : RenderWidget(WebKit::WebPopupTypeNone, screen_info), | 444 : RenderWidget(WebKit::WebPopupTypeNone, screen_info, swapped_out), |
| 442 webkit_preferences_(webkit_prefs), | 445 webkit_preferences_(webkit_prefs), |
| 443 send_content_state_immediately_(false), | 446 send_content_state_immediately_(false), |
| 444 enabled_bindings_(0), | 447 enabled_bindings_(0), |
| 445 send_preferred_size_changes_(false), | 448 send_preferred_size_changes_(false), |
| 446 is_loading_(false), | 449 is_loading_(false), |
| 447 navigation_gesture_(NavigationGestureUnknown), | 450 navigation_gesture_(NavigationGestureUnknown), |
| 448 opened_by_user_gesture_(true), | 451 opened_by_user_gesture_(true), |
| 449 opener_suppressed_(false), | 452 opener_suppressed_(false), |
| 450 page_id_(-1), | 453 page_id_(-1), |
| 451 last_page_id_sent_to_browser_(-1), | 454 last_page_id_sent_to_browser_(-1), |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 474 session_storage_namespace_id_(session_storage_namespace_id), | 477 session_storage_namespace_id_(session_storage_namespace_id), |
| 475 handling_select_range_(false), | 478 handling_select_range_(false), |
| 476 #if defined(OS_WIN) | 479 #if defined(OS_WIN) |
| 477 focused_plugin_id_(-1), | 480 focused_plugin_id_(-1), |
| 478 #endif | 481 #endif |
| 479 guest_(guest), | 482 guest_(guest), |
| 480 accessibility_mode_(accessibility_mode), | 483 accessibility_mode_(accessibility_mode), |
| 481 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)) { | 484 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)) { |
| 482 routing_id_ = routing_id; | 485 routing_id_ = routing_id; |
| 483 surface_id_ = surface_id; | 486 surface_id_ = surface_id; |
| 484 if (opener_id != MSG_ROUTING_NONE) | 487 if (opener_id != MSG_ROUTING_NONE && is_renderer_created) |
| 485 opener_id_ = opener_id; | 488 opener_id_ = opener_id; |
| 486 | 489 |
| 487 // Ensure we start with a valid next_page_id_ from the browser. | 490 // Ensure we start with a valid next_page_id_ from the browser. |
| 488 DCHECK_GE(next_page_id_, 0); | 491 DCHECK_GE(next_page_id_, 0); |
| 489 | 492 |
| 490 #if defined(ENABLE_NOTIFICATIONS) | 493 #if defined(ENABLE_NOTIFICATIONS) |
| 491 notification_provider_ = new NotificationProvider(this); | 494 notification_provider_ = new NotificationProvider(this); |
| 492 #else | 495 #else |
| 493 notification_provider_ = NULL; | 496 notification_provider_ = NULL; |
| 494 #endif | 497 #endif |
| 495 | 498 |
| 496 webwidget_ = WebView::create(this); | 499 webwidget_ = WebView::create(this); |
| 497 webwidget_mouse_lock_target_.reset(new WebWidgetLockTarget(webwidget_)); | 500 webwidget_mouse_lock_target_.reset(new WebWidgetLockTarget(webwidget_)); |
| 498 | 501 |
| 499 if (counter) { | 502 if (counter) { |
| 500 shared_popup_counter_ = counter; | 503 shared_popup_counter_ = counter; |
| 501 shared_popup_counter_->data++; | 504 // Only count this if it isn't swapped out upon creation. |
| 505 if (!swapped_out) | |
| 506 shared_popup_counter_->data++; | |
| 502 decrement_shared_popup_at_destruction_ = true; | 507 decrement_shared_popup_at_destruction_ = true; |
| 503 } else { | 508 } else { |
| 504 shared_popup_counter_ = new SharedRenderViewCounter(0); | 509 shared_popup_counter_ = new SharedRenderViewCounter(0); |
| 505 decrement_shared_popup_at_destruction_ = false; | 510 decrement_shared_popup_at_destruction_ = false; |
| 506 } | 511 } |
| 507 | 512 |
| 508 RenderThread::Get()->AddRoute(routing_id_, this); | 513 RenderThread::Get()->AddRoute(routing_id_, this); |
| 509 // Take a reference on behalf of the RenderThread. This will be balanced | 514 // Take a reference on behalf of the RenderThread. This will be balanced |
| 510 // when we receive ViewMsg_ClosePage. | 515 // when we receive ViewMsg_ClosePage. |
| 511 AddRef(); | 516 AddRef(); |
| 512 | 517 |
| 513 // If this is a popup, we must wait for the CreatingNew_ACK message before | 518 // If this is a popup, we must wait for the CreatingNew_ACK message before |
| 514 // completing initialization. Otherwise, we can finish it now. | 519 // completing initialization. Otherwise, we can finish it now. |
| 515 if (opener_id == MSG_ROUTING_NONE) { | 520 if (opener_id_ == MSG_ROUTING_NONE) { |
| 516 did_show_ = true; | 521 did_show_ = true; |
| 517 CompleteInit(parent_hwnd); | 522 CompleteInit(parent_hwnd); |
| 518 } | 523 } |
| 519 | 524 |
| 520 g_view_map.Get().insert(std::make_pair(webview(), this)); | 525 g_view_map.Get().insert(std::make_pair(webview(), this)); |
| 521 webkit_preferences_.Apply(webview()); | 526 webkit_preferences_.Apply(webview()); |
| 522 webview()->initializeMainFrame(this); | 527 webview()->initializeMainFrame(this); |
| 523 if (!frame_name.empty()) | 528 if (!frame_name.empty()) |
| 524 webview()->mainFrame()->setName(frame_name); | 529 webview()->mainFrame()->setName(frame_name); |
| 525 webview()->settings()->setMinimumTimerInterval( | 530 webview()->settings()->setMinimumTimerInterval( |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 554 | 559 |
| 555 new IdleUserDetector(this); | 560 new IdleUserDetector(this); |
| 556 | 561 |
| 557 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 562 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 558 if (command_line.HasSwitch(switches::kDomAutomationController)) | 563 if (command_line.HasSwitch(switches::kDomAutomationController)) |
| 559 enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION; | 564 enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION; |
| 560 | 565 |
| 561 ProcessViewLayoutFlags(command_line); | 566 ProcessViewLayoutFlags(command_line); |
| 562 | 567 |
| 563 content::GetContentClient()->renderer()->RenderViewCreated(this); | 568 content::GetContentClient()->renderer()->RenderViewCreated(this); |
| 569 | |
| 570 // If we have an opener_id but we weren't created by a renderer, then | |
| 571 // it's the browser asking us to set our opener to another RenderView. | |
| 572 // TODO(creis): This doesn't yet handle openers that are subframes. | |
| 573 if (opener_id != MSG_ROUTING_NONE && !is_renderer_created) { | |
| 574 RenderViewImpl* opener_view = static_cast<RenderViewImpl*>( | |
| 575 ChildThread::current()->ResolveRoute(opener_id)); | |
| 576 webview()->mainFrame()->setOpener(opener_view->webview()->mainFrame()); | |
| 577 } | |
| 578 | |
| 579 // If we are initially swapped out, navigate to kSwappedOutURL. | |
| 580 // This ensures we are in a unique origin that others cannot script. | |
| 581 if (is_swapped_out_) | |
| 582 NavigateToSwappedOutURL(); | |
| 564 } | 583 } |
| 565 | 584 |
| 566 RenderViewImpl::~RenderViewImpl() { | 585 RenderViewImpl::~RenderViewImpl() { |
| 567 history_page_ids_.clear(); | 586 history_page_ids_.clear(); |
| 568 | 587 |
| 569 if (decrement_shared_popup_at_destruction_) | 588 if (decrement_shared_popup_at_destruction_) |
| 570 shared_popup_counter_->data--; | 589 shared_popup_counter_->data--; |
| 571 | 590 |
| 572 // If file chooser is still waiting for answer, dispatch empty answer. | 591 // If file chooser is still waiting for answer, dispatch empty answer. |
| 573 while (!file_chooser_completions_.empty()) { | 592 while (!file_chooser_completions_.empty()) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 625 RenderViewImpl* RenderViewImpl::Create( | 644 RenderViewImpl* RenderViewImpl::Create( |
| 626 gfx::NativeViewId parent_hwnd, | 645 gfx::NativeViewId parent_hwnd, |
| 627 int32 opener_id, | 646 int32 opener_id, |
| 628 const content::RendererPreferences& renderer_prefs, | 647 const content::RendererPreferences& renderer_prefs, |
| 629 const WebPreferences& webkit_prefs, | 648 const WebPreferences& webkit_prefs, |
| 630 SharedRenderViewCounter* counter, | 649 SharedRenderViewCounter* counter, |
| 631 int32 routing_id, | 650 int32 routing_id, |
| 632 int32 surface_id, | 651 int32 surface_id, |
| 633 int64 session_storage_namespace_id, | 652 int64 session_storage_namespace_id, |
| 634 const string16& frame_name, | 653 const string16& frame_name, |
| 654 bool is_renderer_created, | |
| 655 bool swapped_out, | |
| 635 int32 next_page_id, | 656 int32 next_page_id, |
| 636 const WebKit::WebScreenInfo& screen_info, | 657 const WebKit::WebScreenInfo& screen_info, |
| 637 bool guest, | 658 bool guest, |
| 638 AccessibilityMode accessibility_mode) { | 659 AccessibilityMode accessibility_mode) { |
| 639 DCHECK(routing_id != MSG_ROUTING_NONE); | 660 DCHECK(routing_id != MSG_ROUTING_NONE); |
| 640 return new RenderViewImpl( | 661 return new RenderViewImpl( |
| 641 parent_hwnd, | 662 parent_hwnd, |
| 642 opener_id, | 663 opener_id, |
| 643 renderer_prefs, | 664 renderer_prefs, |
| 644 webkit_prefs, | 665 webkit_prefs, |
| 645 counter, | 666 counter, |
| 646 routing_id, | 667 routing_id, |
| 647 surface_id, | 668 surface_id, |
| 648 session_storage_namespace_id, | 669 session_storage_namespace_id, |
| 649 frame_name, | 670 frame_name, |
| 671 is_renderer_created, | |
| 672 swapped_out, | |
| 650 next_page_id, | 673 next_page_id, |
| 651 screen_info, | 674 screen_info, |
| 652 guest, | 675 guest, |
| 653 accessibility_mode); | 676 accessibility_mode); |
| 654 } | 677 } |
| 655 | 678 |
| 656 WebPeerConnectionHandler* RenderViewImpl::CreatePeerConnectionHandler( | 679 WebPeerConnectionHandler* RenderViewImpl::CreatePeerConnectionHandler( |
| 657 WebPeerConnectionHandlerClient* client) { | 680 WebPeerConnectionHandlerClient* client) { |
| 658 EnsureMediaStreamImpl(); | 681 EnsureMediaStreamImpl(); |
| 659 if (!media_stream_impl_) | 682 if (!media_stream_impl_) |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1505 RenderViewImpl* view = RenderViewImpl::Create( | 1528 RenderViewImpl* view = RenderViewImpl::Create( |
| 1506 0, | 1529 0, |
| 1507 routing_id_, | 1530 routing_id_, |
| 1508 renderer_preferences_, | 1531 renderer_preferences_, |
| 1509 webkit_preferences_, | 1532 webkit_preferences_, |
| 1510 shared_popup_counter_, | 1533 shared_popup_counter_, |
| 1511 routing_id, | 1534 routing_id, |
| 1512 surface_id, | 1535 surface_id, |
| 1513 cloned_session_storage_namespace_id, | 1536 cloned_session_storage_namespace_id, |
| 1514 frame_name, | 1537 frame_name, |
| 1538 true, /* is_renderer_created */ | |
|
jam
2012/05/02 17:42:30
nit: here and in other places, I'm really not a hu
Charlie Reis
2012/05/02 17:52:29
That's fair. We certainly aren't consistent about
| |
| 1539 false, /* swapped_out */ | |
| 1515 1, | 1540 1, |
| 1516 screen_info_, | 1541 screen_info_, |
| 1517 guest_, | 1542 guest_, |
| 1518 accessibility_mode_); | 1543 accessibility_mode_); |
| 1519 view->opened_by_user_gesture_ = params.user_gesture; | 1544 view->opened_by_user_gesture_ = params.user_gesture; |
| 1520 | 1545 |
| 1521 // Record whether the creator frame is trying to suppress the opener field. | 1546 // Record whether the creator frame is trying to suppress the opener field. |
| 1522 view->opener_suppressed_ = params.opener_suppressed; | 1547 view->opener_suppressed_ = params.opener_suppressed; |
| 1523 | 1548 |
| 1524 // Record the security origin of the creator. | 1549 // Record the security origin of the creator. |
| (...skipping 2919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4444 SyncNavigationState(); | 4469 SyncNavigationState(); |
| 4445 | 4470 |
| 4446 // Synchronously run the unload handler before sending the ACK. | 4471 // Synchronously run the unload handler before sending the ACK. |
| 4447 webview()->dispatchUnloadEvent(); | 4472 webview()->dispatchUnloadEvent(); |
| 4448 | 4473 |
| 4449 // Swap out and stop sending any IPC messages that are not ACKs. | 4474 // Swap out and stop sending any IPC messages that are not ACKs. |
| 4450 SetSwappedOut(true); | 4475 SetSwappedOut(true); |
| 4451 | 4476 |
| 4452 // Replace the page with a blank dummy URL. The unload handler will not be | 4477 // Replace the page with a blank dummy URL. The unload handler will not be |
| 4453 // run a second time, thanks to a check in FrameLoader::stopLoading. | 4478 // run a second time, thanks to a check in FrameLoader::stopLoading. |
| 4454 // We use loadRequest instead of loadHTMLString because the former commits | |
| 4455 // synchronously. Otherwise a new navigation can interrupt the navigation | |
| 4456 // to content::kSwappedOutURL. If that happens to be to the page we had been | |
| 4457 // showing, then WebKit will never send a commit and we'll be left spinning. | |
| 4458 // TODO(creis): Need to add a better way to do this that avoids running the | 4479 // TODO(creis): Need to add a better way to do this that avoids running the |
| 4459 // beforeunload handler. For now, we just run it a second time silently. | 4480 // beforeunload handler. For now, we just run it a second time silently. |
| 4460 GURL swappedOutURL(content::kSwappedOutURL); | 4481 NavigateToSwappedOutURL(); |
| 4461 WebURLRequest request(swappedOutURL); | |
| 4462 webview()->mainFrame()->loadRequest(request); | |
| 4463 } | 4482 } |
| 4464 | 4483 |
| 4465 // Just echo back the params in the ACK. | 4484 // Just echo back the params in the ACK. |
| 4466 Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params)); | 4485 Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params)); |
| 4467 } | 4486 } |
| 4468 | 4487 |
| 4488 void RenderViewImpl::NavigateToSwappedOutURL() { | |
| 4489 // We use loadRequest instead of loadHTMLString because the former commits | |
| 4490 // synchronously. Otherwise a new navigation can interrupt the navigation | |
| 4491 // to content::kSwappedOutURL. If that happens to be to the page we had been | |
| 4492 // showing, then WebKit will never send a commit and we'll be left spinning. | |
| 4493 GURL swappedOutURL(content::kSwappedOutURL); | |
| 4494 WebURLRequest request(swappedOutURL); | |
| 4495 webview()->mainFrame()->loadRequest(request); | |
| 4496 } | |
| 4497 | |
| 4469 void RenderViewImpl::OnClosePage() { | 4498 void RenderViewImpl::OnClosePage() { |
| 4470 FOR_EACH_OBSERVER(RenderViewObserver, observers_, ClosePage()); | 4499 FOR_EACH_OBSERVER(RenderViewObserver, observers_, ClosePage()); |
| 4471 // TODO(creis): We'd rather use webview()->Close() here, but that currently | 4500 // TODO(creis): We'd rather use webview()->Close() here, but that currently |
| 4472 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs | 4501 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs |
| 4473 // in the onunload handler from appearing. For now, we're bypassing that and | 4502 // in the onunload handler from appearing. For now, we're bypassing that and |
| 4474 // calling the FrameLoader's CloseURL method directly. This should be | 4503 // calling the FrameLoader's CloseURL method directly. This should be |
| 4475 // revisited to avoid having two ways to close a page. Having a single way | 4504 // revisited to avoid having two ways to close a page. Having a single way |
| 4476 // to close that can run onunload is also useful for fixing | 4505 // to close that can run onunload is also useful for fixing |
| 4477 // http://b/issue?id=753080. | 4506 // http://b/issue?id=753080. |
| 4478 webview()->dispatchUnloadEvent(); | 4507 webview()->dispatchUnloadEvent(); |
| (...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5255 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const { | 5284 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const { |
| 5256 return !!RenderThreadImpl::current()->compositor_thread(); | 5285 return !!RenderThreadImpl::current()->compositor_thread(); |
| 5257 } | 5286 } |
| 5258 | 5287 |
| 5259 void RenderViewImpl::OnJavaBridgeInit() { | 5288 void RenderViewImpl::OnJavaBridgeInit() { |
| 5260 DCHECK(!java_bridge_dispatcher_.get()); | 5289 DCHECK(!java_bridge_dispatcher_.get()); |
| 5261 #if defined(ENABLE_JAVA_BRIDGE) | 5290 #if defined(ENABLE_JAVA_BRIDGE) |
| 5262 java_bridge_dispatcher_.reset(new JavaBridgeDispatcher(this)); | 5291 java_bridge_dispatcher_.reset(new JavaBridgeDispatcher(this)); |
| 5263 #endif | 5292 #endif |
| 5264 } | 5293 } |
| OLD | NEW |