| 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_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" |
| 33 #include "content/common/content_constants_internal.h" |
| 32 #include "content/common/database_messages.h" | 34 #include "content/common/database_messages.h" |
| 33 #include "content/common/drag_messages.h" | 35 #include "content/common/drag_messages.h" |
| 34 #include "content/common/fileapi/file_system_dispatcher.h" | 36 #include "content/common/fileapi/file_system_dispatcher.h" |
| 35 #include "content/common/fileapi/webfilesystem_callback_dispatcher.h" | 37 #include "content/common/fileapi/webfilesystem_callback_dispatcher.h" |
| 36 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" | 38 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" |
| 37 #include "content/common/intents_messages.h" | 39 #include "content/common/intents_messages.h" |
| 38 #include "content/common/java_bridge_messages.h" | 40 #include "content/common/java_bridge_messages.h" |
| 39 #include "content/common/old_browser_plugin_messages.h" | 41 #include "content/common/old_browser_plugin_messages.h" |
| 40 #include "content/common/pepper_messages.h" | 42 #include "content/common/pepper_messages.h" |
| 41 #include "content/common/pepper_plugin_registry.h" | 43 #include "content/common/pepper_plugin_registry.h" |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 // Delay between tapping in content and launching the associated android intent. | 361 // Delay between tapping in content and launching the associated android intent. |
| 360 // Used to allow users see what has been recognized as content. | 362 // Used to allow users see what has been recognized as content. |
| 361 static const size_t kContentIntentDelayMilliseconds = 700; | 363 static const size_t kContentIntentDelayMilliseconds = 700; |
| 362 #endif | 364 #endif |
| 363 | 365 |
| 364 static RenderViewImpl* FromRoutingID(int32 routing_id) { | 366 static RenderViewImpl* FromRoutingID(int32 routing_id) { |
| 365 return static_cast<RenderViewImpl*>( | 367 return static_cast<RenderViewImpl*>( |
| 366 ChildThread::current()->ResolveRoute(routing_id)); | 368 ChildThread::current()->ResolveRoute(routing_id)); |
| 367 } | 369 } |
| 368 | 370 |
| 371 static WebKit::WebFrame* FindFrameByID(WebKit::WebFrame* root, int frame_id) { |
| 372 for (WebFrame* frame = root; frame; frame = frame->traverseNext(false)) { |
| 373 if (frame->identifier() == frame_id) |
| 374 return frame; |
| 375 } |
| 376 return NULL; |
| 377 } |
| 378 |
| 369 static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) { | 379 static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) { |
| 370 WebVector<WebURL> urls; | 380 WebVector<WebURL> urls; |
| 371 ds->redirectChain(urls); | 381 ds->redirectChain(urls); |
| 372 result->reserve(urls.size()); | 382 result->reserve(urls.size()); |
| 373 for (size_t i = 0; i < urls.size(); ++i) | 383 for (size_t i = 0; i < urls.size(); ++i) |
| 374 result->push_back(urls[i]); | 384 result->push_back(urls[i]); |
| 375 } | 385 } |
| 376 | 386 |
| 377 // If |data_source| is non-null and has a DocumentState associated with it, | 387 // If |data_source| is non-null and has a DocumentState associated with it, |
| 378 // the AltErrorPageResourceFetcher is reset. | 388 // the AltErrorPageResourceFetcher is reset. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 if (!opener) { | 473 if (!opener) { |
| 464 return true; | 474 return true; |
| 465 } | 475 } |
| 466 | 476 |
| 467 if (url.GetOrigin() != GURL(opener->document().url()).GetOrigin()) | 477 if (url.GetOrigin() != GURL(opener->document().url()).GetOrigin()) |
| 468 return true; | 478 return true; |
| 469 } | 479 } |
| 470 return false; | 480 return false; |
| 471 } | 481 } |
| 472 | 482 |
| 483 // Recursively walks the frame tree and serializes it to JSON as described in |
| 484 // the comment for ViewMsg_UpdateFrameTree. If |exclude_frame_subtree| is not |
| 485 // NULL, the subtree for the frame is not included in the serialized form. |
| 486 // This is used when a frame is going to be removed from the tree. |
| 487 static void ConstructFrameTree(WebKit::WebFrame* frame, |
| 488 WebKit::WebFrame* exclude_frame_subtree, |
| 489 base::DictionaryValue* dict) { |
| 490 dict->SetString(content::kFrameTreeNodeNameKey, |
| 491 UTF16ToUTF8(frame->assignedName()).c_str()); |
| 492 dict->SetInteger(content::kFrameTreeNodeIdKey, frame->identifier()); |
| 493 |
| 494 WebFrame* child = frame->firstChild(); |
| 495 ListValue* children = new ListValue(); |
| 496 for (; child; child = child->nextSibling()) { |
| 497 if (child == exclude_frame_subtree) |
| 498 continue; |
| 499 |
| 500 base::DictionaryValue* d = new base::DictionaryValue(); |
| 501 ConstructFrameTree(child, exclude_frame_subtree, d); |
| 502 children->Append(d); |
| 503 } |
| 504 if (children->GetSize() > 0) |
| 505 dict->Set(content::kFrameTreeNodeSubtreeKey, children); |
| 506 } |
| 507 |
| 473 /////////////////////////////////////////////////////////////////////////////// | 508 /////////////////////////////////////////////////////////////////////////////// |
| 474 | 509 |
| 475 struct RenderViewImpl::PendingFileChooser { | 510 struct RenderViewImpl::PendingFileChooser { |
| 476 PendingFileChooser(const content::FileChooserParams& p, | 511 PendingFileChooser(const content::FileChooserParams& p, |
| 477 WebFileChooserCompletion* c) | 512 WebFileChooserCompletion* c) |
| 478 : params(p), | 513 : params(p), |
| 479 completion(c) { | 514 completion(c) { |
| 480 } | 515 } |
| 481 content::FileChooserParams params; | 516 content::FileChooserParams params; |
| 482 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback. | 517 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback. |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 expected_content_intent_id_(0), | 610 expected_content_intent_id_(0), |
| 576 #endif | 611 #endif |
| 577 session_storage_namespace_id_(session_storage_namespace_id), | 612 session_storage_namespace_id_(session_storage_namespace_id), |
| 578 handling_select_range_(false), | 613 handling_select_range_(false), |
| 579 #if defined(OS_WIN) | 614 #if defined(OS_WIN) |
| 580 focused_plugin_id_(-1), | 615 focused_plugin_id_(-1), |
| 581 #endif | 616 #endif |
| 582 guest_to_embedder_channel_(guest_to_embedder_channel), | 617 guest_to_embedder_channel_(guest_to_embedder_channel), |
| 583 guest_pp_instance_(0), | 618 guest_pp_instance_(0), |
| 584 guest_uninitialized_context_(NULL), | 619 guest_uninitialized_context_(NULL), |
| 620 updating_frame_tree_(false), |
| 621 pending_frame_tree_update_(false), |
| 622 target_process_id_(0), |
| 623 target_routing_id_(0), |
| 585 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)) { | 624 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)) { |
| 586 set_throttle_input_events(renderer_prefs.throttle_input_events); | 625 set_throttle_input_events(renderer_prefs.throttle_input_events); |
| 587 routing_id_ = routing_id; | 626 routing_id_ = routing_id; |
| 588 surface_id_ = surface_id; | 627 surface_id_ = surface_id; |
| 589 if (opener_id != MSG_ROUTING_NONE && is_renderer_created) | 628 if (opener_id != MSG_ROUTING_NONE && is_renderer_created) |
| 590 opener_id_ = opener_id; | 629 opener_id_ = opener_id; |
| 591 | 630 |
| 592 // Ensure we start with a valid next_page_id_ from the browser. | 631 // Ensure we start with a valid next_page_id_ from the browser. |
| 593 DCHECK_GE(next_page_id_, 0); | 632 DCHECK_GE(next_page_id_, 0); |
| 594 | 633 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 | 724 |
| 686 if (command_line.HasSwitch(switches::kDomAutomationController)) | 725 if (command_line.HasSwitch(switches::kDomAutomationController)) |
| 687 enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION; | 726 enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION; |
| 688 | 727 |
| 689 ProcessViewLayoutFlags(command_line); | 728 ProcessViewLayoutFlags(command_line); |
| 690 | 729 |
| 691 content::GetContentClient()->renderer()->RenderViewCreated(this); | 730 content::GetContentClient()->renderer()->RenderViewCreated(this); |
| 692 | 731 |
| 693 // If we have an opener_id but we weren't created by a renderer, then | 732 // If we have an opener_id but we weren't created by a renderer, then |
| 694 // it's the browser asking us to set our opener to another RenderView. | 733 // it's the browser asking us to set our opener to another RenderView. |
| 695 // TODO(creis): This doesn't yet handle openers that are subframes. | |
| 696 if (opener_id != MSG_ROUTING_NONE && !is_renderer_created) { | 734 if (opener_id != MSG_ROUTING_NONE && !is_renderer_created) { |
| 697 RenderViewImpl* opener_view = FromRoutingID(opener_id); | 735 RenderViewImpl* opener_view = FromRoutingID(opener_id); |
| 698 if (opener_view) | 736 if (opener_view) |
| 699 webview()->mainFrame()->setOpener(opener_view->webview()->mainFrame()); | 737 webview()->mainFrame()->setOpener(opener_view->webview()->mainFrame()); |
| 700 } | 738 } |
| 701 | 739 |
| 702 // If we are initially swapped out, navigate to kSwappedOutURL. | 740 // If we are initially swapped out, navigate to kSwappedOutURL. |
| 703 // This ensures we are in a unique origin that others cannot script. | 741 // This ensures we are in a unique origin that others cannot script. |
| 704 if (is_swapped_out_) | 742 if (is_swapped_out_) |
| 705 NavigateToSwappedOutURL(); | 743 NavigateToSwappedOutURL(webview()->mainFrame()); |
| 706 } | 744 } |
| 707 | 745 |
| 708 RenderViewImpl::~RenderViewImpl() { | 746 RenderViewImpl::~RenderViewImpl() { |
| 709 history_page_ids_.clear(); | 747 history_page_ids_.clear(); |
| 710 | 748 |
| 711 if (decrement_shared_popup_at_destruction_) | 749 if (decrement_shared_popup_at_destruction_) |
| 712 shared_popup_counter_->data--; | 750 shared_popup_counter_->data--; |
| 713 | 751 |
| 714 // If file chooser is still waiting for answer, dispatch empty answer. | 752 // If file chooser is still waiting for answer, dispatch empty answer. |
| 715 while (!file_chooser_completions_.empty()) { | 753 while (!file_chooser_completions_.empty()) { |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed) | 1038 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed) |
| 1001 // TODO(viettrungluu): Move to a separate message filter. | 1039 // TODO(viettrungluu): Move to a separate message filter. |
| 1002 #if defined(OS_MACOSX) | 1040 #if defined(OS_MACOSX) |
| 1003 IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize) | 1041 IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize) |
| 1004 #endif | 1042 #endif |
| 1005 IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune, | 1043 IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune, |
| 1006 OnSetHistoryLengthAndPrune) | 1044 OnSetHistoryLengthAndPrune) |
| 1007 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode) | 1045 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode) |
| 1008 IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit) | 1046 IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit) |
| 1009 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode) | 1047 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode) |
| 1048 IPC_MESSAGE_HANDLER(ViewMsg_UpdateFrameTree, OnUpdatedFrameTree) |
| 1010 | 1049 |
| 1011 // Have the super handle all other messages. | 1050 // Have the super handle all other messages. |
| 1012 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message)) | 1051 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message)) |
| 1013 IPC_END_MESSAGE_MAP() | 1052 IPC_END_MESSAGE_MAP() |
| 1014 | 1053 |
| 1015 if (!msg_is_ok) { | 1054 if (!msg_is_ok) { |
| 1016 // The message had a handler, but its deserialization failed. | 1055 // The message had a handler, but its deserialization failed. |
| 1017 // Kill the renderer to avoid potential spoofing attacks. | 1056 // Kill the renderer to avoid potential spoofing attacks. |
| 1018 CHECK(false) << "Unable to deserialize message in RenderViewImpl."; | 1057 CHECK(false) << "Unable to deserialize message in RenderViewImpl."; |
| 1019 } | 1058 } |
| (...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1893 } | 1932 } |
| 1894 | 1933 |
| 1895 void RenderViewImpl::didStopLoading() { | 1934 void RenderViewImpl::didStopLoading() { |
| 1896 if (!is_loading_) { | 1935 if (!is_loading_) { |
| 1897 DVLOG(1) << "DidStopLoading called while not loading"; | 1936 DVLOG(1) << "DidStopLoading called while not loading"; |
| 1898 return; | 1937 return; |
| 1899 } | 1938 } |
| 1900 | 1939 |
| 1901 is_loading_ = false; | 1940 is_loading_ = false; |
| 1902 | 1941 |
| 1942 if (pending_frame_tree_update_) { |
| 1943 pending_frame_tree_update_ = false; |
| 1944 SendUpdatedFrameTree(NULL); |
| 1945 } |
| 1946 |
| 1903 // NOTE: For now we're doing the safest thing, and sending out notification | 1947 // NOTE: For now we're doing the safest thing, and sending out notification |
| 1904 // when done loading. This currently isn't an issue as the favicon is only | 1948 // when done loading. This currently isn't an issue as the favicon is only |
| 1905 // displayed when done loading. Ideally we would send notification when | 1949 // displayed when done loading. Ideally we would send notification when |
| 1906 // finished parsing the head, but webkit doesn't support that yet. | 1950 // finished parsing the head, but webkit doesn't support that yet. |
| 1907 // The feed discovery code would also benefit from access to the head. | 1951 // The feed discovery code would also benefit from access to the head. |
| 1908 Send(new ViewHostMsg_DidStopLoading(routing_id_)); | 1952 Send(new ViewHostMsg_DidStopLoading(routing_id_)); |
| 1909 | 1953 |
| 1910 if (load_progress_tracker_ != NULL) | 1954 if (load_progress_tracker_ != NULL) |
| 1911 load_progress_tracker_->DidStopLoading(); | 1955 load_progress_tracker_->DidStopLoading(); |
| 1912 | 1956 |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2487 return NULL; | 2531 return NULL; |
| 2488 return new RendererWebApplicationCacheHostImpl( | 2532 return new RendererWebApplicationCacheHostImpl( |
| 2489 FromWebView(frame->view()), client, | 2533 FromWebView(frame->view()), client, |
| 2490 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy()); | 2534 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy()); |
| 2491 } | 2535 } |
| 2492 | 2536 |
| 2493 WebCookieJar* RenderViewImpl::cookieJar(WebFrame* frame) { | 2537 WebCookieJar* RenderViewImpl::cookieJar(WebFrame* frame) { |
| 2494 return &cookie_jar_; | 2538 return &cookie_jar_; |
| 2495 } | 2539 } |
| 2496 | 2540 |
| 2541 void RenderViewImpl::didCreateFrame(WebFrame* parent, WebFrame* child) { |
| 2542 if (is_loading_) { |
| 2543 pending_frame_tree_update_ = true; |
| 2544 return; |
| 2545 } |
| 2546 if (!updating_frame_tree_) |
| 2547 SendUpdatedFrameTree(NULL); |
| 2548 } |
| 2549 |
| 2497 void RenderViewImpl::frameDetached(WebFrame* frame) { | 2550 void RenderViewImpl::frameDetached(WebFrame* frame) { |
| 2551 if (is_loading_) { |
| 2552 pending_frame_tree_update_ = true; |
| 2553 // Make sure observers are notified, even if we return right away. |
| 2554 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame)); |
| 2555 return; |
| 2556 } |
| 2557 if (!updating_frame_tree_) |
| 2558 SendUpdatedFrameTree(frame); |
| 2559 |
| 2498 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame)); | 2560 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame)); |
| 2499 } | 2561 } |
| 2500 | 2562 |
| 2501 void RenderViewImpl::willClose(WebFrame* frame) { | 2563 void RenderViewImpl::willClose(WebFrame* frame) { |
| 2502 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame)); | 2564 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame)); |
| 2503 } | 2565 } |
| 2504 | 2566 |
| 2505 void RenderViewImpl::loadURLExternally( | 2567 void RenderViewImpl::loadURLExternally( |
| 2506 WebFrame* frame, const WebURLRequest& request, | 2568 WebFrame* frame, const WebURLRequest& request, |
| 2507 WebNavigationPolicy policy) { | 2569 WebNavigationPolicy policy) { |
| (...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3640 | 3702 |
| 3641 if (!context->Initialize( | 3703 if (!context->Initialize( |
| 3642 attributes, | 3704 attributes, |
| 3643 false /* bind generates resources */, | 3705 false /* bind generates resources */, |
| 3644 content::CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_
INITIALIZE)) | 3706 content::CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_
INITIALIZE)) |
| 3645 return NULL; | 3707 return NULL; |
| 3646 return context.release(); | 3708 return context.release(); |
| 3647 } | 3709 } |
| 3648 } | 3710 } |
| 3649 | 3711 |
| 3712 // The browser process needs to know the shape of the tree, as well as the names |
| 3713 // and ids of all frames. This allows it to properly route JavaScript messages |
| 3714 // across processes and frames. The serialization format is described in the |
| 3715 // comments of the ViewMsg_FrameTreeUpdated message. |
| 3716 // This function sends those updates to the browser and updates the RVH |
| 3717 // corresponding to this object. It must be called on any events that modify |
| 3718 // the tree structure or the names of any frames. |
| 3719 void RenderViewImpl::SendUpdatedFrameTree( |
| 3720 WebKit::WebFrame* exclude_frame_subtree) { |
| 3721 std::string json; |
| 3722 base::DictionaryValue tree; |
| 3723 |
| 3724 ConstructFrameTree(webview()->mainFrame(), exclude_frame_subtree, &tree); |
| 3725 base::JSONWriter::Write(&tree, &json); |
| 3726 |
| 3727 Send(new ViewHostMsg_FrameTreeUpdated(routing_id_, json)); |
| 3728 } |
| 3729 |
| 3730 void RenderViewImpl::CreateFrameTree(WebKit::WebFrame* frame, |
| 3731 DictionaryValue* frame_tree) { |
| 3732 NavigateToSwappedOutURL(frame); |
| 3733 |
| 3734 string16 name; |
| 3735 if (frame_tree->GetString(content::kFrameTreeNodeNameKey, &name) && |
| 3736 name != string16()) { |
| 3737 frame->setName(name); |
| 3738 } |
| 3739 |
| 3740 int remote_id; |
| 3741 if (frame_tree->GetInteger(content::kFrameTreeNodeIdKey, &remote_id)) |
| 3742 active_frame_id_map_.insert(std::pair<int, int>(frame->identifier(), |
| 3743 remote_id)); |
| 3744 |
| 3745 ListValue* children; |
| 3746 if (!frame_tree->GetList(content::kFrameTreeNodeSubtreeKey, &children)) |
| 3747 return; |
| 3748 |
| 3749 base::DictionaryValue* child; |
| 3750 for (size_t i = 0; i < children->GetSize(); ++i) { |
| 3751 if (!children->GetDictionary(i, &child)) |
| 3752 continue; |
| 3753 WebElement element = frame->document().createElement("iframe"); |
| 3754 if (frame->document().body().appendChild(element)) { |
| 3755 WebFrame* subframe = WebFrame::fromFrameOwnerElement(element); |
| 3756 if (subframe) |
| 3757 CreateFrameTree(subframe, child); |
| 3758 } else { |
| 3759 LOG(ERROR) << "Failed to append created iframe element."; |
| 3760 } |
| 3761 } |
| 3762 } |
| 3763 |
| 3764 WebKit::WebFrame* RenderViewImpl::GetFrameByMappedID(int frame_id) { |
| 3765 std::map<int, int>::iterator it = active_frame_id_map_.find(frame_id); |
| 3766 if (it == active_frame_id_map_.end()) |
| 3767 return NULL; |
| 3768 |
| 3769 return FindFrameByID(webview()->mainFrame(), it->second); |
| 3770 } |
| 3771 |
| 3650 void RenderViewImpl::EnsureMediaStreamImpl() { | 3772 void RenderViewImpl::EnsureMediaStreamImpl() { |
| 3651 if (!RenderThreadImpl::current()) // Will be NULL during unit tests. | 3773 if (!RenderThreadImpl::current()) // Will be NULL during unit tests. |
| 3652 return; | 3774 return; |
| 3653 | 3775 |
| 3654 #if defined(ENABLE_WEBRTC) | 3776 #if defined(ENABLE_WEBRTC) |
| 3655 if (!p2p_socket_dispatcher_) | 3777 if (!p2p_socket_dispatcher_) |
| 3656 p2p_socket_dispatcher_ = new content::P2PSocketDispatcher(this); | 3778 p2p_socket_dispatcher_ = new content::P2PSocketDispatcher(this); |
| 3657 | 3779 |
| 3658 if (!media_stream_dispatcher_) | 3780 if (!media_stream_dispatcher_) |
| 3659 media_stream_dispatcher_ = new MediaStreamDispatcher(this); | 3781 media_stream_dispatcher_ = new MediaStreamDispatcher(this); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3855 } | 3977 } |
| 3856 delete channels; | 3978 delete channels; |
| 3857 } | 3979 } |
| 3858 | 3980 |
| 3859 int id = intents_host_->RegisterWebIntent(intentRequest); | 3981 int id = intents_host_->RegisterWebIntent(intentRequest); |
| 3860 Send(new IntentsHostMsg_WebIntentDispatch( | 3982 Send(new IntentsHostMsg_WebIntentDispatch( |
| 3861 routing_id_, intent_data, id)); | 3983 routing_id_, intent_data, id)); |
| 3862 } | 3984 } |
| 3863 | 3985 |
| 3864 bool RenderViewImpl::willCheckAndDispatchMessageEvent( | 3986 bool RenderViewImpl::willCheckAndDispatchMessageEvent( |
| 3865 WebKit::WebFrame* source, | 3987 WebKit::WebFrame* sourceFrame, |
| 3988 WebKit::WebFrame* targetFrame, |
| 3866 WebKit::WebSecurityOrigin target_origin, | 3989 WebKit::WebSecurityOrigin target_origin, |
| 3867 WebKit::WebDOMMessageEvent event) { | 3990 WebKit::WebDOMMessageEvent event) { |
| 3868 if (!is_swapped_out_) | 3991 if (!is_swapped_out_) |
| 3869 return false; | 3992 return false; |
| 3870 | 3993 |
| 3871 ViewMsg_PostMessage_Params params; | 3994 ViewMsg_PostMessage_Params params; |
| 3872 params.data = event.data().toString(); | 3995 params.data = event.data().toString(); |
| 3873 params.source_origin = event.origin(); | 3996 params.source_origin = event.origin(); |
| 3874 if (!target_origin.isNull()) | 3997 if (!target_origin.isNull()) |
| 3875 params.target_origin = target_origin.toString(); | 3998 params.target_origin = target_origin.toString(); |
| 3876 | 3999 |
| 3877 // Include the routing ID for the source frame, which the browser process | 4000 // Include the routing ID for the source frame, which the browser process |
| 3878 // will translate into the routing ID for the equivalent frame in the target | 4001 // will translate into the routing ID for the equivalent frame in the target |
| 3879 // process. | 4002 // process. |
| 3880 // TODO(creis): Support source subframes. | |
| 3881 params.source_routing_id = MSG_ROUTING_NONE; | 4003 params.source_routing_id = MSG_ROUTING_NONE; |
| 3882 RenderViewImpl* source_view = FromWebView(source->view()); | 4004 RenderViewImpl* source_view = FromWebView(sourceFrame->view()); |
| 3883 if (source_view) | 4005 if (source_view) |
| 3884 params.source_routing_id = source_view->routing_id(); | 4006 params.source_routing_id = source_view->routing_id(); |
| 4007 params.source_frame_id = sourceFrame->identifier(); |
| 4008 |
| 4009 // Include the process, route, and frame IDs of the target frame. This allows |
| 4010 // the browser to detect races between this message being sent and the target |
| 4011 // frame no longer being valid. |
| 4012 params.target_process_id = target_process_id_; |
| 4013 params.target_routing_id = target_routing_id_; |
| 4014 |
| 4015 std::map<int,int>::iterator it = active_frame_id_map_.find( |
| 4016 targetFrame->identifier()); |
| 4017 if (it != active_frame_id_map_.end()) { |
| 4018 params.target_frame_id = it->second; |
| 4019 } else { |
| 4020 params.target_frame_id = 0; |
| 4021 } |
| 3885 | 4022 |
| 3886 Send(new ViewHostMsg_RouteMessageEvent(routing_id_, params)); | 4023 Send(new ViewHostMsg_RouteMessageEvent(routing_id_, params)); |
| 3887 return true; | 4024 return true; |
| 3888 } | 4025 } |
| 3889 | 4026 |
| 3890 void RenderViewImpl::willOpenSocketStream( | 4027 void RenderViewImpl::willOpenSocketStream( |
| 3891 WebSocketStreamHandle* handle) { | 4028 WebSocketStreamHandle* handle) { |
| 3892 SocketStreamHandleData::AddToHandle(handle, routing_id_); | 4029 SocketStreamHandleData::AddToHandle(handle, routing_id_); |
| 3893 } | 4030 } |
| 3894 | 4031 |
| (...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4604 | 4741 |
| 4605 void RenderViewImpl::OnScriptEvalRequest(const string16& frame_xpath, | 4742 void RenderViewImpl::OnScriptEvalRequest(const string16& frame_xpath, |
| 4606 const string16& jscript, | 4743 const string16& jscript, |
| 4607 int id, | 4744 int id, |
| 4608 bool notify_result) { | 4745 bool notify_result) { |
| 4609 EvaluateScript(frame_xpath, jscript, id, notify_result); | 4746 EvaluateScript(frame_xpath, jscript, id, notify_result); |
| 4610 } | 4747 } |
| 4611 | 4748 |
| 4612 void RenderViewImpl::OnPostMessageEvent( | 4749 void RenderViewImpl::OnPostMessageEvent( |
| 4613 const ViewMsg_PostMessage_Params& params) { | 4750 const ViewMsg_PostMessage_Params& params) { |
| 4614 // TODO(creis): Support sending to subframes. | 4751 // Find the target frame of this message. The source tags the message with |
| 4615 WebFrame* frame = webview()->mainFrame(); | 4752 // |target_frame_id|, so use it to locate the frame. |
| 4753 WebFrame* frame = FindFrameByID(webview()->mainFrame(), |
| 4754 params.target_frame_id); |
| 4755 if (!frame) |
| 4756 return; |
| 4616 | 4757 |
| 4617 // Find the source frame if it exists. | 4758 // Find the source frame if it exists. |
| 4618 // TODO(creis): Support source subframes. | |
| 4619 WebFrame* source_frame = NULL; | 4759 WebFrame* source_frame = NULL; |
| 4620 if (params.source_routing_id != MSG_ROUTING_NONE) { | 4760 if (params.source_routing_id != MSG_ROUTING_NONE) { |
| 4621 RenderViewImpl* source_view = FromRoutingID(params.source_routing_id); | 4761 RenderViewImpl* source_view = FromRoutingID(params.source_routing_id); |
| 4622 if (source_view) | 4762 if (source_view) |
| 4623 source_frame = source_view->webview()->mainFrame(); | 4763 source_frame = source_view->GetFrameByMappedID(params.source_frame_id); |
| 4624 } | 4764 } |
| 4625 | 4765 |
| 4626 // Create an event with the message. The final parameter to initMessageEvent | 4766 // Create an event with the message. The final parameter to initMessageEvent |
| 4627 // is the last event ID, which is not used with postMessage. | 4767 // is the last event ID, which is not used with postMessage. |
| 4628 WebDOMEvent event = frame->document().createEvent("MessageEvent"); | 4768 WebDOMEvent event = frame->document().createEvent("MessageEvent"); |
| 4629 WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>(); | 4769 WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>(); |
| 4630 msg_event.initMessageEvent("message", | 4770 msg_event.initMessageEvent("message", |
| 4631 // |canBubble| and |cancellable| are always false | 4771 // |canBubble| and |cancellable| are always false |
| 4632 false, false, | 4772 false, false, |
| 4633 WebSerializedScriptValue::fromString(params.data), | 4773 WebSerializedScriptValue::fromString(params.data), |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4962 // Synchronously run the unload handler before sending the ACK. | 5102 // Synchronously run the unload handler before sending the ACK. |
| 4963 webview()->dispatchUnloadEvent(); | 5103 webview()->dispatchUnloadEvent(); |
| 4964 | 5104 |
| 4965 // Swap out and stop sending any IPC messages that are not ACKs. | 5105 // Swap out and stop sending any IPC messages that are not ACKs. |
| 4966 SetSwappedOut(true); | 5106 SetSwappedOut(true); |
| 4967 | 5107 |
| 4968 // Replace the page with a blank dummy URL. The unload handler will not be | 5108 // Replace the page with a blank dummy URL. The unload handler will not be |
| 4969 // run a second time, thanks to a check in FrameLoader::stopLoading. | 5109 // run a second time, thanks to a check in FrameLoader::stopLoading. |
| 4970 // TODO(creis): Need to add a better way to do this that avoids running the | 5110 // TODO(creis): Need to add a better way to do this that avoids running the |
| 4971 // beforeunload handler. For now, we just run it a second time silently. | 5111 // beforeunload handler. For now, we just run it a second time silently. |
| 4972 NavigateToSwappedOutURL(); | 5112 NavigateToSwappedOutURL(webview()->mainFrame()); |
| 4973 | 5113 |
| 4974 // Let WebKit know that this view is hidden so it can drop resources and | 5114 // Let WebKit know that this view is hidden so it can drop resources and |
| 4975 // stop compositing. | 5115 // stop compositing. |
| 4976 webview()->setVisibilityState(WebKit::WebPageVisibilityStateHidden, false); | 5116 webview()->setVisibilityState(WebKit::WebPageVisibilityStateHidden, false); |
| 4977 } | 5117 } |
| 4978 | 5118 |
| 4979 // Just echo back the params in the ACK. | 5119 // Just echo back the params in the ACK. |
| 4980 Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params)); | 5120 Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params)); |
| 4981 } | 5121 } |
| 4982 | 5122 |
| 4983 void RenderViewImpl::NavigateToSwappedOutURL() { | 5123 void RenderViewImpl::NavigateToSwappedOutURL(WebKit::WebFrame* frame) { |
| 4984 // We use loadRequest instead of loadHTMLString because the former commits | 5124 // We use loadRequest instead of loadHTMLString because the former commits |
| 4985 // synchronously. Otherwise a new navigation can interrupt the navigation | 5125 // synchronously. Otherwise a new navigation can interrupt the navigation |
| 4986 // to content::kSwappedOutURL. If that happens to be to the page we had been | 5126 // to content::kSwappedOutURL. If that happens to be to the page we had been |
| 4987 // showing, then WebKit will never send a commit and we'll be left spinning. | 5127 // showing, then WebKit will never send a commit and we'll be left spinning. |
| 4988 GURL swappedOutURL(content::kSwappedOutURL); | 5128 GURL swappedOutURL(content::kSwappedOutURL); |
| 4989 WebURLRequest request(swappedOutURL); | 5129 WebURLRequest request(swappedOutURL); |
| 4990 webview()->mainFrame()->loadRequest(request); | 5130 frame->loadRequest(request); |
| 4991 } | 5131 } |
| 4992 | 5132 |
| 4993 void RenderViewImpl::OnClosePage() { | 5133 void RenderViewImpl::OnClosePage() { |
| 4994 FOR_EACH_OBSERVER(RenderViewObserver, observers_, ClosePage()); | 5134 FOR_EACH_OBSERVER(RenderViewObserver, observers_, ClosePage()); |
| 4995 // TODO(creis): We'd rather use webview()->Close() here, but that currently | 5135 // TODO(creis): We'd rather use webview()->Close() here, but that currently |
| 4996 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs | 5136 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs |
| 4997 // in the onunload handler from appearing. For now, we're bypassing that and | 5137 // in the onunload handler from appearing. For now, we're bypassing that and |
| 4998 // calling the FrameLoader's CloseURL method directly. This should be | 5138 // calling the FrameLoader's CloseURL method directly. This should be |
| 4999 // revisited to avoid having two ways to close a page. Having a single way | 5139 // revisited to avoid having two ways to close a page. Having a single way |
| 5000 // to close that can run onunload is also useful for fixing | 5140 // to close that can run onunload is also useful for fixing |
| (...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5892 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const { | 6032 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const { |
| 5893 return !!RenderThreadImpl::current()->compositor_thread(); | 6033 return !!RenderThreadImpl::current()->compositor_thread(); |
| 5894 } | 6034 } |
| 5895 | 6035 |
| 5896 void RenderViewImpl::OnJavaBridgeInit() { | 6036 void RenderViewImpl::OnJavaBridgeInit() { |
| 5897 DCHECK(!java_bridge_dispatcher_); | 6037 DCHECK(!java_bridge_dispatcher_); |
| 5898 #if defined(ENABLE_JAVA_BRIDGE) | 6038 #if defined(ENABLE_JAVA_BRIDGE) |
| 5899 java_bridge_dispatcher_ = new JavaBridgeDispatcher(this); | 6039 java_bridge_dispatcher_ = new JavaBridgeDispatcher(this); |
| 5900 #endif | 6040 #endif |
| 5901 } | 6041 } |
| 6042 |
| 6043 void RenderViewImpl::OnUpdatedFrameTree( |
| 6044 int process_id, |
| 6045 int route_id, |
| 6046 const std::string& frame_tree) { |
| 6047 base::DictionaryValue* frames = NULL; |
| 6048 scoped_ptr<base::Value> tree(base::JSONReader::Read(frame_tree)); |
| 6049 if (tree.get() && tree->IsType(base::Value::TYPE_DICTIONARY)) |
| 6050 tree->GetAsDictionary(&frames); |
| 6051 |
| 6052 updating_frame_tree_ = true; |
| 6053 active_frame_id_map_.clear(); |
| 6054 |
| 6055 target_process_id_ = process_id; |
| 6056 target_routing_id_ = route_id; |
| 6057 CreateFrameTree(webview()->mainFrame(), frames); |
| 6058 |
| 6059 updating_frame_tree_ = false; |
| 6060 } |
| OLD | NEW |