Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1376)

Side by Side Diff: content/renderer/render_view_impl.cc

Issue 10827078: Support frame tree propagation between renderers in the same browsing instance. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moved away from hardcoded strings and no static cast needed for tests. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_reader.h"
16 #include "base/json/json_writer.h" 17 #include "base/json/json_writer.h"
17 #include "base/lazy_instance.h" 18 #include "base/lazy_instance.h"
18 #include "base/message_loop_proxy.h" 19 #include "base/message_loop_proxy.h"
19 #include "base/metrics/histogram.h" 20 #include "base/metrics/histogram.h"
20 #include "base/path_service.h" 21 #include "base/path_service.h"
21 #include "base/process_util.h" 22 #include "base/process_util.h"
22 #include "base/string_number_conversions.h" 23 #include "base/string_number_conversions.h"
23 #include "base/string_piece.h" 24 #include "base/string_piece.h"
24 #include "base/string_split.h" 25 #include "base/string_split.h"
25 #include "base/string_util.h" 26 #include "base/string_util.h"
26 #include "base/sys_string_conversions.h" 27 #include "base/sys_string_conversions.h"
27 #include "base/time.h" 28 #include "base/time.h"
28 #include "base/utf_string_conversions.h" 29 #include "base/utf_string_conversions.h"
29 #include "content/common/appcache/appcache_dispatcher.h" 30 #include "content/common/appcache/appcache_dispatcher.h"
30 #include "content/common/child_thread.h" 31 #include "content/common/child_thread.h"
31 #include "content/common/clipboard_messages.h" 32 #include "content/common/clipboard_messages.h"
32 #include "content/common/database_messages.h" 33 #include "content/common/database_messages.h"
33 #include "content/common/drag_messages.h" 34 #include "content/common/drag_messages.h"
34 #include "content/common/fileapi/file_system_dispatcher.h" 35 #include "content/common/fileapi/file_system_dispatcher.h"
35 #include "content/common/fileapi/webfilesystem_callback_dispatcher.h" 36 #include "content/common/fileapi/webfilesystem_callback_dispatcher.h"
36 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 37 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
37 #include "content/common/intents_messages.h" 38 #include "content/common/intents_messages.h"
38 #include "content/common/java_bridge_messages.h" 39 #include "content/common/java_bridge_messages.h"
39 #include "content/common/old_browser_plugin_messages.h" 40 #include "content/common/old_browser_plugin_messages.h"
40 #include "content/common/pepper_messages.h" 41 #include "content/common/pepper_messages.h"
41 #include "content/common/pepper_plugin_registry.h" 42 #include "content/common/pepper_plugin_registry.h"
42 #include "content/common/quota_dispatcher.h" 43 #include "content/common/quota_dispatcher.h"
43 #include "content/common/request_extra_data.h" 44 #include "content/common/request_extra_data.h"
44 #include "content/common/socket_stream_handle_data.h" 45 #include "content/common/socket_stream_handle_data.h"
46 #include "content/common/string_constants.h"
45 #include "content/common/view_messages.h" 47 #include "content/common/view_messages.h"
46 #include "content/common/webmessageportchannel_impl.h" 48 #include "content/common/webmessageportchannel_impl.h"
47 #include "content/public/common/bindings_policy.h" 49 #include "content/public/common/bindings_policy.h"
48 #include "content/public/common/content_client.h" 50 #include "content/public/common/content_client.h"
49 #include "content/public/common/content_constants.h" 51 #include "content/public/common/content_constants.h"
50 #include "content/public/common/content_switches.h" 52 #include "content/public/common/content_switches.h"
51 #include "content/public/common/context_menu_params.h" 53 #include "content/public/common/context_menu_params.h"
52 #include "content/public/common/file_chooser_params.h" 54 #include "content/public/common/file_chooser_params.h"
53 #include "content/public/common/url_constants.h" 55 #include "content/public/common/url_constants.h"
54 #include "content/public/renderer/content_renderer_client.h" 56 #include "content/public/renderer/content_renderer_client.h"
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 340
339 static const float kScalingIncrement = 0.1f; 341 static const float kScalingIncrement = 0.1f;
340 342
341 static const float kScalingIncrementForGesture = 0.01f; 343 static const float kScalingIncrementForGesture = 0.01f;
342 344
343 static RenderViewImpl* FromRoutingID(int32 routing_id) { 345 static RenderViewImpl* FromRoutingID(int32 routing_id) {
344 return static_cast<RenderViewImpl*>( 346 return static_cast<RenderViewImpl*>(
345 ChildThread::current()->ResolveRoute(routing_id)); 347 ChildThread::current()->ResolveRoute(routing_id));
346 } 348 }
347 349
350 static WebKit::WebFrame* FindFrameByID(WebKit::WebFrame* root, int frame_id) {
351 for (WebFrame* frame = root; frame; frame = frame->traverseNext(false))
352 if (frame->identifier() == frame_id)
353 return frame;
354 return NULL;
355 }
356
348 static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) { 357 static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) {
349 WebVector<WebURL> urls; 358 WebVector<WebURL> urls;
350 ds->redirectChain(urls); 359 ds->redirectChain(urls);
351 result->reserve(urls.size()); 360 result->reserve(urls.size());
352 for (size_t i = 0; i < urls.size(); ++i) 361 for (size_t i = 0; i < urls.size(); ++i)
353 result->push_back(urls[i]); 362 result->push_back(urls[i]);
354 } 363 }
355 364
356 // If |data_source| is non-null and has a DocumentState associated with it, 365 // If |data_source| is non-null and has a DocumentState associated with it,
357 // the AltErrorPageResourceFetcher is reset. 366 // the AltErrorPageResourceFetcher is reset.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 if (!opener) { 451 if (!opener) {
443 return true; 452 return true;
444 } 453 }
445 454
446 if (url.GetOrigin() != GURL(opener->document().url()).GetOrigin()) 455 if (url.GetOrigin() != GURL(opener->document().url()).GetOrigin())
447 return true; 456 return true;
448 } 457 }
449 return false; 458 return false;
450 } 459 }
451 460
461 // The frame tree for a renderer is serialized to JSON, so it can be sent to
462 // the browser process. Each node in the tree is a DictionaryValue with three
463 // properties:
464 // * id - the frame identifier in this renderer
465 // * name - the name of the frame, if one has been assigned
466 // * subtree - a list of DictionaryValue objects for each frame that is
467 // direct child of the current frame. This property can be omitted if
468 // there are no direct child frames, so less data is transferred.
469 static void ConstructFrameTree(WebKit::WebFrame* frame,
470 WebKit::WebFrame* exclude_subtree,
471 base::DictionaryValue* dict) {
472 dict->SetString(content::kFrameTreeNodeNameKey,
473 UTF16ToUTF8(frame->assignedName()).c_str());
474 dict->SetInteger(content::kFrameTreeNodeIdKey, frame->identifier());
475
476 WebFrame* child = frame->firstChild();
477 ListValue* children = new ListValue();
478 for (; child; child = child->nextSibling()) {
479 if (child == exclude_subtree)
480 continue;
481
482 base::DictionaryValue* d = new base::DictionaryValue();
483 ConstructFrameTree(child, exclude_subtree, d);
484 children->Append(d);
485 }
486 if (children->GetSize() > 0) {
487 dict->Set(content::kFrameTreeNodeSubtreeKey, children);
488 }
489 }
490
452 /////////////////////////////////////////////////////////////////////////////// 491 ///////////////////////////////////////////////////////////////////////////////
453 492
454 struct RenderViewImpl::PendingFileChooser { 493 struct RenderViewImpl::PendingFileChooser {
455 PendingFileChooser(const content::FileChooserParams& p, 494 PendingFileChooser(const content::FileChooserParams& p,
456 WebFileChooserCompletion* c) 495 WebFileChooserCompletion* c)
457 : params(p), 496 : params(p),
458 completion(c) { 497 completion(c) {
459 } 498 }
460 content::FileChooserParams params; 499 content::FileChooserParams params;
461 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback. 500 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 java_bridge_dispatcher_(NULL), 590 java_bridge_dispatcher_(NULL),
552 mouse_lock_dispatcher_(NULL), 591 mouse_lock_dispatcher_(NULL),
553 session_storage_namespace_id_(session_storage_namespace_id), 592 session_storage_namespace_id_(session_storage_namespace_id),
554 handling_select_range_(false), 593 handling_select_range_(false),
555 #if defined(OS_WIN) 594 #if defined(OS_WIN)
556 focused_plugin_id_(-1), 595 focused_plugin_id_(-1),
557 #endif 596 #endif
558 guest_to_embedder_channel_(guest_to_embedder_channel), 597 guest_to_embedder_channel_(guest_to_embedder_channel),
559 guest_pp_instance_(0), 598 guest_pp_instance_(0),
560 guest_uninitialized_context_(NULL), 599 guest_uninitialized_context_(NULL),
600 updating_frame_tree_(false),
601 pending_frame_tree_update_(false),
602 target_process_id_(0),
603 target_routing_id_(0),
561 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)) { 604 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)) {
562 set_throttle_input_events(renderer_prefs.throttle_input_events); 605 set_throttle_input_events(renderer_prefs.throttle_input_events);
563 routing_id_ = routing_id; 606 routing_id_ = routing_id;
564 surface_id_ = surface_id; 607 surface_id_ = surface_id;
565 if (opener_id != MSG_ROUTING_NONE && is_renderer_created) 608 if (opener_id != MSG_ROUTING_NONE && is_renderer_created)
566 opener_id_ = opener_id; 609 opener_id_ = opener_id;
567 610
568 // Ensure we start with a valid next_page_id_ from the browser. 611 // Ensure we start with a valid next_page_id_ from the browser.
569 DCHECK_GE(next_page_id_, 0); 612 DCHECK_GE(next_page_id_, 0);
570 613
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 688 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
646 if (command_line.HasSwitch(switches::kDomAutomationController)) 689 if (command_line.HasSwitch(switches::kDomAutomationController))
647 enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION; 690 enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION;
648 691
649 ProcessViewLayoutFlags(command_line); 692 ProcessViewLayoutFlags(command_line);
650 693
651 content::GetContentClient()->renderer()->RenderViewCreated(this); 694 content::GetContentClient()->renderer()->RenderViewCreated(this);
652 695
653 // If we have an opener_id but we weren't created by a renderer, then 696 // If we have an opener_id but we weren't created by a renderer, then
654 // it's the browser asking us to set our opener to another RenderView. 697 // it's the browser asking us to set our opener to another RenderView.
655 // TODO(creis): This doesn't yet handle openers that are subframes.
656 if (opener_id != MSG_ROUTING_NONE && !is_renderer_created) { 698 if (opener_id != MSG_ROUTING_NONE && !is_renderer_created) {
657 RenderViewImpl* opener_view = FromRoutingID(opener_id); 699 RenderViewImpl* opener_view = FromRoutingID(opener_id);
658 if (opener_view) 700 if (opener_view)
659 webview()->mainFrame()->setOpener(opener_view->webview()->mainFrame()); 701 webview()->mainFrame()->setOpener(opener_view->webview()->mainFrame());
660 } 702 }
661 703
662 // If we are initially swapped out, navigate to kSwappedOutURL. 704 // If we are initially swapped out, navigate to kSwappedOutURL.
663 // This ensures we are in a unique origin that others cannot script. 705 // This ensures we are in a unique origin that others cannot script.
664 if (is_swapped_out_) 706 if (is_swapped_out_)
665 NavigateToSwappedOutURL(); 707 NavigateToSwappedOutURL(webview()->mainFrame(), NULL);
666 } 708 }
667 709
668 RenderViewImpl::~RenderViewImpl() { 710 RenderViewImpl::~RenderViewImpl() {
669 history_page_ids_.clear(); 711 history_page_ids_.clear();
670 712
671 if (decrement_shared_popup_at_destruction_) 713 if (decrement_shared_popup_at_destruction_)
672 shared_popup_counter_->data--; 714 shared_popup_counter_->data--;
673 715
674 // If file chooser is still waiting for answer, dispatch empty answer. 716 // If file chooser is still waiting for answer, dispatch empty answer.
675 while (!file_chooser_completions_.empty()) { 717 while (!file_chooser_completions_.empty()) {
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed) 1000 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed)
959 // TODO(viettrungluu): Move to a separate message filter. 1001 // TODO(viettrungluu): Move to a separate message filter.
960 #if defined(OS_MACOSX) 1002 #if defined(OS_MACOSX)
961 IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize) 1003 IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize)
962 #endif 1004 #endif
963 IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune, 1005 IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune,
964 OnSetHistoryLengthAndPrune) 1006 OnSetHistoryLengthAndPrune)
965 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode) 1007 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode)
966 IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit) 1008 IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit)
967 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode) 1009 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode)
1010 IPC_MESSAGE_HANDLER(ViewMsg_UpdateFrameTree, OnUpdatedFrameTree)
968 1011
969 // Have the super handle all other messages. 1012 // Have the super handle all other messages.
970 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message)) 1013 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message))
971 IPC_END_MESSAGE_MAP() 1014 IPC_END_MESSAGE_MAP()
972 1015
973 if (!msg_is_ok) { 1016 if (!msg_is_ok) {
974 // The message had a handler, but its deserialization failed. 1017 // The message had a handler, but its deserialization failed.
975 // Kill the renderer to avoid potential spoofing attacks. 1018 // Kill the renderer to avoid potential spoofing attacks.
976 CHECK(false) << "Unable to deserialize message in RenderViewImpl."; 1019 CHECK(false) << "Unable to deserialize message in RenderViewImpl.";
977 } 1020 }
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after
1861 // NOTE: For now we're doing the safest thing, and sending out notification 1904 // NOTE: For now we're doing the safest thing, and sending out notification
1862 // when done loading. This currently isn't an issue as the favicon is only 1905 // when done loading. This currently isn't an issue as the favicon is only
1863 // displayed when done loading. Ideally we would send notification when 1906 // displayed when done loading. Ideally we would send notification when
1864 // finished parsing the head, but webkit doesn't support that yet. 1907 // finished parsing the head, but webkit doesn't support that yet.
1865 // The feed discovery code would also benefit from access to the head. 1908 // The feed discovery code would also benefit from access to the head.
1866 Send(new ViewHostMsg_DidStopLoading(routing_id_)); 1909 Send(new ViewHostMsg_DidStopLoading(routing_id_));
1867 1910
1868 if (load_progress_tracker_ != NULL) 1911 if (load_progress_tracker_ != NULL)
1869 load_progress_tracker_->DidStopLoading(); 1912 load_progress_tracker_->DidStopLoading();
1870 1913
1914 if (pending_frame_tree_update_) {
1915 pending_frame_tree_update_ = false;
1916 SendUpdatedFrameTree(webview()->mainFrame(), false);
1917 }
1918
1871 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStopLoading()); 1919 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStopLoading());
1872 } 1920 }
1873 1921
1874 void RenderViewImpl::didChangeLoadProgress(WebFrame* frame, 1922 void RenderViewImpl::didChangeLoadProgress(WebFrame* frame,
1875 double load_progress) { 1923 double load_progress) {
1876 if (load_progress_tracker_ != NULL) 1924 if (load_progress_tracker_ != NULL)
1877 load_progress_tracker_->DidChangeLoadProgress(frame, load_progress); 1925 load_progress_tracker_->DidChangeLoadProgress(frame, load_progress);
1878 } 1926 }
1879 1927
1880 bool RenderViewImpl::isSmartInsertDeleteEnabled() { 1928 bool RenderViewImpl::isSmartInsertDeleteEnabled() {
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
2445 return NULL; 2493 return NULL;
2446 return new RendererWebApplicationCacheHostImpl( 2494 return new RendererWebApplicationCacheHostImpl(
2447 FromWebView(frame->view()), client, 2495 FromWebView(frame->view()), client,
2448 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy()); 2496 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy());
2449 } 2497 }
2450 2498
2451 WebCookieJar* RenderViewImpl::cookieJar(WebFrame* frame) { 2499 WebCookieJar* RenderViewImpl::cookieJar(WebFrame* frame) {
2452 return &cookie_jar_; 2500 return &cookie_jar_;
2453 } 2501 }
2454 2502
2503 void RenderViewImpl::didCreateFrame(WebFrame* parent, WebFrame* child) {
2504 if (is_loading_) {
2505 pending_frame_tree_update_ = true;
2506 return;
2507 }
2508 if (!updating_frame_tree_) {
2509 SendUpdatedFrameTree(child, false);
2510 }
2511 }
2512
2455 void RenderViewImpl::frameDetached(WebFrame* frame) { 2513 void RenderViewImpl::frameDetached(WebFrame* frame) {
2514 if (is_loading_) {
2515 pending_frame_tree_update_ = true;
2516 return;
2517 }
2518 if (!updating_frame_tree_) {
2519 SendUpdatedFrameTree(frame, true);
2520 }
2456 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame)); 2521 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame));
2457 } 2522 }
2458 2523
2459 void RenderViewImpl::willClose(WebFrame* frame) { 2524 void RenderViewImpl::willClose(WebFrame* frame) {
2460 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame)); 2525 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame));
2461 } 2526 }
2462 2527
2463 void RenderViewImpl::loadURLExternally( 2528 void RenderViewImpl::loadURLExternally(
2464 WebFrame* frame, const WebURLRequest& request, 2529 WebFrame* frame, const WebURLRequest& request,
2465 WebNavigationPolicy policy) { 2530 WebNavigationPolicy policy) {
(...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after
3598 3663
3599 if (!context->Initialize( 3664 if (!context->Initialize(
3600 attributes, 3665 attributes,
3601 false /* bind generates resources */, 3666 false /* bind generates resources */,
3602 content::CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_ INITIALIZE)) 3667 content::CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_ INITIALIZE))
3603 return NULL; 3668 return NULL;
3604 return context.release(); 3669 return context.release();
3605 } 3670 }
3606 } 3671 }
3607 3672
3673 // The browser process needs to know the shape of the tree, as well as the names
3674 // and ids of all frames. This allows it to properly route JavaScript messages
3675 // across processes and frames.
3676 // This function sends a those updates to the browser and updates the RVH
3677 // corresponding to this object. It must be called on any events that modify
3678 // the tree structure or the names of any frames.
3679 void RenderViewImpl::SendUpdatedFrameTree(
3680 WebKit::WebFrame* frame, bool exclude_subtree) {
3681 std::string json;
3682 WebFrame* f = frame->top();
3683 base::DictionaryValue tree;
3684
3685 ConstructFrameTree(f, exclude_subtree ? frame : NULL, &tree);
3686 base::JSONWriter::Write(&tree, &json);
3687
3688 Send(new ViewHostMsg_FrameTreeUpdated(routing_id_, json));
3689 }
3690
3608 void RenderViewImpl::EnsureMediaStreamImpl() { 3691 void RenderViewImpl::EnsureMediaStreamImpl() {
3609 if (!RenderThreadImpl::current()) // Will be NULL during unit tests. 3692 if (!RenderThreadImpl::current()) // Will be NULL during unit tests.
3610 return; 3693 return;
3611 3694
3612 #if defined(ENABLE_WEBRTC) 3695 #if defined(ENABLE_WEBRTC)
3613 if (!p2p_socket_dispatcher_) 3696 if (!p2p_socket_dispatcher_)
3614 p2p_socket_dispatcher_ = new content::P2PSocketDispatcher(this); 3697 p2p_socket_dispatcher_ = new content::P2PSocketDispatcher(this);
3615 3698
3616 if (!media_stream_dispatcher_) 3699 if (!media_stream_dispatcher_)
3617 media_stream_dispatcher_ = new MediaStreamDispatcher(this); 3700 media_stream_dispatcher_ = new MediaStreamDispatcher(this);
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
3813 } 3896 }
3814 delete channels; 3897 delete channels;
3815 } 3898 }
3816 3899
3817 int id = intents_host_->RegisterWebIntent(intentRequest); 3900 int id = intents_host_->RegisterWebIntent(intentRequest);
3818 Send(new IntentsHostMsg_WebIntentDispatch( 3901 Send(new IntentsHostMsg_WebIntentDispatch(
3819 routing_id_, intent_data, id)); 3902 routing_id_, intent_data, id));
3820 } 3903 }
3821 3904
3822 bool RenderViewImpl::willCheckAndDispatchMessageEvent( 3905 bool RenderViewImpl::willCheckAndDispatchMessageEvent(
3823 WebKit::WebFrame* source, 3906 WebKit::WebFrame* sourceFrame,
3907 WebKit::WebFrame* targetFrame,
3824 WebKit::WebSecurityOrigin target_origin, 3908 WebKit::WebSecurityOrigin target_origin,
3825 WebKit::WebDOMMessageEvent event) { 3909 WebKit::WebDOMMessageEvent event) {
3826 if (!is_swapped_out_) 3910 if (!is_swapped_out_)
3827 return false; 3911 return false;
3828 3912
3829 ViewMsg_PostMessage_Params params; 3913 ViewMsg_PostMessage_Params params;
3830 params.data = event.data().toString(); 3914 params.data = event.data().toString();
3831 params.source_origin = event.origin(); 3915 params.source_origin = event.origin();
3832 if (!target_origin.isNull()) 3916 if (!target_origin.isNull())
3833 params.target_origin = target_origin.toString(); 3917 params.target_origin = target_origin.toString();
3834 3918
3835 // Include the routing ID for the source frame, which the browser process 3919 // Include the routing ID for the source frame, which the browser process
3836 // will translate into the routing ID for the equivalent frame in the target 3920 // will translate into the routing ID for the equivalent frame in the target
3837 // process. 3921 // process.
3838 // TODO(creis): Support source subframes.
3839 params.source_routing_id = MSG_ROUTING_NONE; 3922 params.source_routing_id = MSG_ROUTING_NONE;
3840 RenderViewImpl* source_view = FromWebView(source->view()); 3923 RenderViewImpl* source_view = FromWebView(sourceFrame->view());
3841 if (source_view) 3924 if (source_view)
3842 params.source_routing_id = source_view->routing_id(); 3925 params.source_routing_id = source_view->routing_id();
3926 params.source_frame_id = sourceFrame->identifier();
3927
3928 // Include the process, route, and frame IDs of the target frame. This allows
3929 // the browser to detect races between this message being sent and the target
3930 // frame no longer being valid.
3931 params.target_process_id = target_process_id_;
3932 params.target_routing_id = target_routing_id_;
3933
3934 std::map<int,int>::iterator it = frames_map_.find(targetFrame->identifier());
3935 if (it != frames_map_.end()) {
3936 params.target_frame_id = it->second;
3937 } else {
3938 params.target_frame_id = 0;
3939 }
3843 3940
3844 Send(new ViewHostMsg_RouteMessageEvent(routing_id_, params)); 3941 Send(new ViewHostMsg_RouteMessageEvent(routing_id_, params));
3845 return true; 3942 return true;
3846 } 3943 }
3847 3944
3848 void RenderViewImpl::willOpenSocketStream( 3945 void RenderViewImpl::willOpenSocketStream(
3849 WebSocketStreamHandle* handle) { 3946 WebSocketStreamHandle* handle) {
3850 SocketStreamHandleData::AddToHandle(handle, routing_id_); 3947 SocketStreamHandleData::AddToHandle(handle, routing_id_);
3851 } 3948 }
3852 3949
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
4562 4659
4563 void RenderViewImpl::OnScriptEvalRequest(const string16& frame_xpath, 4660 void RenderViewImpl::OnScriptEvalRequest(const string16& frame_xpath,
4564 const string16& jscript, 4661 const string16& jscript,
4565 int id, 4662 int id,
4566 bool notify_result) { 4663 bool notify_result) {
4567 EvaluateScript(frame_xpath, jscript, id, notify_result); 4664 EvaluateScript(frame_xpath, jscript, id, notify_result);
4568 } 4665 }
4569 4666
4570 void RenderViewImpl::OnPostMessageEvent( 4667 void RenderViewImpl::OnPostMessageEvent(
4571 const ViewMsg_PostMessage_Params& params) { 4668 const ViewMsg_PostMessage_Params& params) {
4572 // TODO(creis): Support sending to subframes. 4669 // Find the frame, which is a target of this message. The source tags the
4573 WebFrame* frame = webview()->mainFrame(); 4670 // message with |remote_frame_id|, so use it to locate the frame.
4671 WebFrame* frame = FindFrameByID(webview()->mainFrame(),
4672 params.target_frame_id);
4673 if (!frame)
4674 return;
4574 4675
4575 // Find the source frame if it exists. 4676 // Find the source frame if it exists.
4576 // TODO(creis): Support source subframes.
4577 WebFrame* source_frame = NULL; 4677 WebFrame* source_frame = NULL;
4578 if (params.source_routing_id != MSG_ROUTING_NONE) { 4678 if (params.source_routing_id != MSG_ROUTING_NONE) {
4579 RenderViewImpl* source_view = FromRoutingID(params.source_routing_id); 4679 RenderViewImpl* source_view = FromRoutingID(params.source_routing_id);
4580 if (source_view) 4680 if (source_view)
4581 source_frame = source_view->webview()->mainFrame(); 4681 source_frame = source_view->GetFrameByRemoteID(params.source_frame_id);
4582 } 4682 }
4583 4683
4584 // Create an event with the message. The final parameter to initMessageEvent 4684 // Create an event with the message. The final parameter to initMessageEvent
4585 // is the last event ID, which is not used with postMessage. 4685 // is the last event ID, which is not used with postMessage.
4586 WebDOMEvent event = frame->document().createEvent("MessageEvent"); 4686 WebDOMEvent event = frame->document().createEvent("MessageEvent");
4587 WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>(); 4687 WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>();
4588 msg_event.initMessageEvent("message", 4688 msg_event.initMessageEvent("message",
4589 // |canBubble| and |cancellable| are always false 4689 // |canBubble| and |cancellable| are always false
4590 false, false, 4690 false, false,
4591 WebSerializedScriptValue::fromString(params.data), 4691 WebSerializedScriptValue::fromString(params.data),
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
4920 // Synchronously run the unload handler before sending the ACK. 5020 // Synchronously run the unload handler before sending the ACK.
4921 webview()->dispatchUnloadEvent(); 5021 webview()->dispatchUnloadEvent();
4922 5022
4923 // Swap out and stop sending any IPC messages that are not ACKs. 5023 // Swap out and stop sending any IPC messages that are not ACKs.
4924 SetSwappedOut(true); 5024 SetSwappedOut(true);
4925 5025
4926 // Replace the page with a blank dummy URL. The unload handler will not be 5026 // Replace the page with a blank dummy URL. The unload handler will not be
4927 // run a second time, thanks to a check in FrameLoader::stopLoading. 5027 // run a second time, thanks to a check in FrameLoader::stopLoading.
4928 // TODO(creis): Need to add a better way to do this that avoids running the 5028 // TODO(creis): Need to add a better way to do this that avoids running the
4929 // beforeunload handler. For now, we just run it a second time silently. 5029 // beforeunload handler. For now, we just run it a second time silently.
4930 NavigateToSwappedOutURL(); 5030 NavigateToSwappedOutURL(webview()->mainFrame(), NULL);
4931 5031
4932 // Let WebKit know that this view is hidden so it can drop resources and 5032 // Let WebKit know that this view is hidden so it can drop resources and
4933 // stop compositing. 5033 // stop compositing.
4934 webview()->setVisibilityState(WebKit::WebPageVisibilityStateHidden, false); 5034 webview()->setVisibilityState(WebKit::WebPageVisibilityStateHidden, false);
4935 } 5035 }
4936 5036
4937 // Just echo back the params in the ACK. 5037 // Just echo back the params in the ACK.
4938 Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params)); 5038 Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params));
4939 } 5039 }
4940 5040
4941 void RenderViewImpl::NavigateToSwappedOutURL() { 5041 void RenderViewImpl::NavigateToSwappedOutURL(
5042 WebKit::WebFrame* frame,
5043 base::DictionaryValue* frame_tree) {
4942 // We use loadRequest instead of loadHTMLString because the former commits 5044 // We use loadRequest instead of loadHTMLString because the former commits
4943 // synchronously. Otherwise a new navigation can interrupt the navigation 5045 // synchronously. Otherwise a new navigation can interrupt the navigation
4944 // to content::kSwappedOutURL. If that happens to be to the page we had been 5046 // to content::kSwappedOutURL. If that happens to be to the page we had been
4945 // showing, then WebKit will never send a commit and we'll be left spinning. 5047 // showing, then WebKit will never send a commit and we'll be left spinning.
4946 GURL swappedOutURL(content::kSwappedOutURL); 5048 GURL swappedOutURL(content::kSwappedOutURL);
4947 WebURLRequest request(swappedOutURL); 5049 WebURLRequest request(swappedOutURL);
4948 webview()->mainFrame()->loadRequest(request); 5050 frame->loadRequest(request);
5051
5052 // If a frame tree is specified, recursively recreate it using the data
5053 // in the current DictionaryValue.
5054 if (frame_tree == NULL)
5055 return;
5056
5057 string16 name;
5058 if (frame_tree->GetString(content::kFrameTreeNodeNameKey, &name) &&
5059 name != string16())
5060 frame->setName(name);
5061
5062 int remote_id;
5063 if (frame_tree->GetInteger(content::kFrameTreeNodeIdKey, &remote_id))
5064 frames_map_.insert(std::pair<int, int>(frame->identifier(), remote_id));
5065
5066 ListValue* children;
5067 if (!frame_tree->GetList(content::kFrameTreeNodeSubtreeKey, &children))
5068 return;
5069
5070 base::DictionaryValue* child;
5071 for (size_t i = 0; i < children->GetSize(); ++i) {
5072 if (!children->GetDictionary(i, &child))
5073 continue;
5074 WebElement element = frame->document().createElement("iframe");
5075 if (frame->document().body().appendChild(element)) {
5076 WebFrame* subframe = WebFrame::fromFrameOwnerElement(element);
5077 if (subframe) {
5078 NavigateToSwappedOutURL(subframe, child);
5079 }
5080 }
5081 }
4949 } 5082 }
4950 5083
4951 void RenderViewImpl::OnClosePage() { 5084 void RenderViewImpl::OnClosePage() {
4952 FOR_EACH_OBSERVER(RenderViewObserver, observers_, ClosePage()); 5085 FOR_EACH_OBSERVER(RenderViewObserver, observers_, ClosePage());
4953 // TODO(creis): We'd rather use webview()->Close() here, but that currently 5086 // TODO(creis): We'd rather use webview()->Close() here, but that currently
4954 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs 5087 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs
4955 // in the onunload handler from appearing. For now, we're bypassing that and 5088 // in the onunload handler from appearing. For now, we're bypassing that and
4956 // calling the FrameLoader's CloseURL method directly. This should be 5089 // calling the FrameLoader's CloseURL method directly. This should be
4957 // revisited to avoid having two ways to close a page. Having a single way 5090 // revisited to avoid having two ways to close a page. Having a single way
4958 // to close that can run onunload is also useful for fixing 5091 // to close that can run onunload is also useful for fixing
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
5798 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const { 5931 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const {
5799 return !!RenderThreadImpl::current()->compositor_thread(); 5932 return !!RenderThreadImpl::current()->compositor_thread();
5800 } 5933 }
5801 5934
5802 void RenderViewImpl::OnJavaBridgeInit() { 5935 void RenderViewImpl::OnJavaBridgeInit() {
5803 DCHECK(!java_bridge_dispatcher_); 5936 DCHECK(!java_bridge_dispatcher_);
5804 #if defined(ENABLE_JAVA_BRIDGE) 5937 #if defined(ENABLE_JAVA_BRIDGE)
5805 java_bridge_dispatcher_ = new JavaBridgeDispatcher(this); 5938 java_bridge_dispatcher_ = new JavaBridgeDispatcher(this);
5806 #endif 5939 #endif
5807 } 5940 }
5941
5942 void RenderViewImpl::OnUpdatedFrameTree(
5943 int process_id,
5944 int route_id,
5945 const std::string& frame_tree) {
5946 base::DictionaryValue* frames = NULL;
5947 scoped_ptr<base::Value> tree(base::JSONReader::Read(frame_tree));
5948 if (tree.get() != NULL && tree->IsType(base::Value::TYPE_DICTIONARY))
5949 tree->GetAsDictionary(&frames);
5950
5951 updating_frame_tree_ = true;
5952 frames_map_.clear();
5953
5954 target_process_id_ = process_id;
5955 target_routing_id_ = route_id;
5956 NavigateToSwappedOutURL(webview()->mainFrame(), frames);
5957
5958 updating_frame_tree_ = false;
5959 }
5960
5961 WebKit::WebFrame* RenderViewImpl::GetFrameByRemoteID(int remote_frame_id) {
5962 WebKit::WebFrame* frame = NULL;
5963
5964 std::map<int, int>::iterator it = frames_map_.find(remote_frame_id);
5965 if (it == frames_map_.end())
5966 return NULL;
5967
5968 for (WebFrame* f = webview()->mainFrame(); f; f = f->traverseNext(false))
5969 if (f->identifier() == it->second)
5970 frame = f;
5971
5972 return frame;
5973 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698