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

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

Powered by Google App Engine
This is Rietveld 408576698