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 |