Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/render_view_impl.h" | 5 #include "content/renderer/render_view_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
| 14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 15 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
| 16 #include "base/json/json_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 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 } | |
| 355 return NULL; | |
| 356 } | |
| 357 | |
| 348 static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) { | 358 static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) { |
| 349 WebVector<WebURL> urls; | 359 WebVector<WebURL> urls; |
| 350 ds->redirectChain(urls); | 360 ds->redirectChain(urls); |
| 351 result->reserve(urls.size()); | 361 result->reserve(urls.size()); |
| 352 for (size_t i = 0; i < urls.size(); ++i) | 362 for (size_t i = 0; i < urls.size(); ++i) |
| 353 result->push_back(urls[i]); | 363 result->push_back(urls[i]); |
| 354 } | 364 } |
| 355 | 365 |
| 356 // If |data_source| is non-null and has a DocumentState associated with it, | 366 // If |data_source| is non-null and has a DocumentState associated with it, |
| 357 // the AltErrorPageResourceFetcher is reset. | 367 // the AltErrorPageResourceFetcher is reset. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 442 if (!opener) { | 452 if (!opener) { |
| 443 return true; | 453 return true; |
| 444 } | 454 } |
| 445 | 455 |
| 446 if (url.GetOrigin() != GURL(opener->document().url()).GetOrigin()) | 456 if (url.GetOrigin() != GURL(opener->document().url()).GetOrigin()) |
| 447 return true; | 457 return true; |
| 448 } | 458 } |
| 449 return false; | 459 return false; |
| 450 } | 460 } |
| 451 | 461 |
| 462 // Recursively walks the frame tree and serializes it to JSON as described in | |
| 463 // the comment for ViewMsg_UpdateFrameTree. If |exclude_subtree| is set to | |
| 464 // true, the subtree for the |frame| is not included in the serialized form. | |
| 465 // This is used when a frame is going to be removed from the tree. | |
| 466 static void ConstructFrameTree(WebKit::WebFrame* frame, | |
| 467 WebKit::WebFrame* exclude_subtree, | |
| 468 base::DictionaryValue* dict) { | |
| 469 dict->SetString(content::kFrameTreeNodeNameKey, | |
| 470 UTF16ToUTF8(frame->assignedName()).c_str()); | |
| 471 dict->SetInteger(content::kFrameTreeNodeIdKey, frame->identifier()); | |
| 472 | |
| 473 WebFrame* child = frame->firstChild(); | |
| 474 ListValue* children = new ListValue(); | |
| 475 for (; child; child = child->nextSibling()) { | |
| 476 if (child == exclude_subtree) | |
| 477 continue; | |
| 478 | |
| 479 base::DictionaryValue* d = new base::DictionaryValue(); | |
| 480 ConstructFrameTree(child, exclude_subtree, d); | |
| 481 children->Append(d); | |
| 482 } | |
| 483 if (children->GetSize() > 0) | |
| 484 dict->Set(content::kFrameTreeNodeSubtreeKey, children); | |
| 485 } | |
| 486 | |
| 452 /////////////////////////////////////////////////////////////////////////////// | 487 /////////////////////////////////////////////////////////////////////////////// |
| 453 | 488 |
| 454 struct RenderViewImpl::PendingFileChooser { | 489 struct RenderViewImpl::PendingFileChooser { |
| 455 PendingFileChooser(const content::FileChooserParams& p, | 490 PendingFileChooser(const content::FileChooserParams& p, |
| 456 WebFileChooserCompletion* c) | 491 WebFileChooserCompletion* c) |
| 457 : params(p), | 492 : params(p), |
| 458 completion(c) { | 493 completion(c) { |
| 459 } | 494 } |
| 460 content::FileChooserParams params; | 495 content::FileChooserParams params; |
| 461 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback. | 496 WebFileChooserCompletion* completion; // MAY BE NULL to skip callback. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 551 java_bridge_dispatcher_(NULL), | 586 java_bridge_dispatcher_(NULL), |
| 552 mouse_lock_dispatcher_(NULL), | 587 mouse_lock_dispatcher_(NULL), |
| 553 session_storage_namespace_id_(session_storage_namespace_id), | 588 session_storage_namespace_id_(session_storage_namespace_id), |
| 554 handling_select_range_(false), | 589 handling_select_range_(false), |
| 555 #if defined(OS_WIN) | 590 #if defined(OS_WIN) |
| 556 focused_plugin_id_(-1), | 591 focused_plugin_id_(-1), |
| 557 #endif | 592 #endif |
| 558 guest_to_embedder_channel_(guest_to_embedder_channel), | 593 guest_to_embedder_channel_(guest_to_embedder_channel), |
| 559 guest_pp_instance_(0), | 594 guest_pp_instance_(0), |
| 560 guest_uninitialized_context_(NULL), | 595 guest_uninitialized_context_(NULL), |
| 596 updating_frame_tree_(false), | |
| 597 pending_frame_tree_update_(false), | |
| 598 target_process_id_(0), | |
| 599 target_routing_id_(0), | |
| 561 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)) { | 600 ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)) { |
| 562 set_throttle_input_events(renderer_prefs.throttle_input_events); | 601 set_throttle_input_events(renderer_prefs.throttle_input_events); |
| 563 routing_id_ = routing_id; | 602 routing_id_ = routing_id; |
| 564 surface_id_ = surface_id; | 603 surface_id_ = surface_id; |
| 565 if (opener_id != MSG_ROUTING_NONE && is_renderer_created) | 604 if (opener_id != MSG_ROUTING_NONE && is_renderer_created) |
| 566 opener_id_ = opener_id; | 605 opener_id_ = opener_id; |
| 567 | 606 |
| 568 // Ensure we start with a valid next_page_id_ from the browser. | 607 // Ensure we start with a valid next_page_id_ from the browser. |
| 569 DCHECK_GE(next_page_id_, 0); | 608 DCHECK_GE(next_page_id_, 0); |
| 570 | 609 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 645 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 684 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 646 if (command_line.HasSwitch(switches::kDomAutomationController)) | 685 if (command_line.HasSwitch(switches::kDomAutomationController)) |
| 647 enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION; | 686 enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION; |
| 648 | 687 |
| 649 ProcessViewLayoutFlags(command_line); | 688 ProcessViewLayoutFlags(command_line); |
| 650 | 689 |
| 651 content::GetContentClient()->renderer()->RenderViewCreated(this); | 690 content::GetContentClient()->renderer()->RenderViewCreated(this); |
| 652 | 691 |
| 653 // If we have an opener_id but we weren't created by a renderer, then | 692 // 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. | 693 // 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) { | 694 if (opener_id != MSG_ROUTING_NONE && !is_renderer_created) { |
| 657 RenderViewImpl* opener_view = FromRoutingID(opener_id); | 695 RenderViewImpl* opener_view = FromRoutingID(opener_id); |
| 658 if (opener_view) | 696 if (opener_view) |
| 659 webview()->mainFrame()->setOpener(opener_view->webview()->mainFrame()); | 697 webview()->mainFrame()->setOpener(opener_view->webview()->mainFrame()); |
| 660 } | 698 } |
| 661 | 699 |
| 662 // If we are initially swapped out, navigate to kSwappedOutURL. | 700 // If we are initially swapped out, navigate to kSwappedOutURL. |
| 663 // This ensures we are in a unique origin that others cannot script. | 701 // This ensures we are in a unique origin that others cannot script. |
| 664 if (is_swapped_out_) | 702 if (is_swapped_out_) |
| 665 NavigateToSwappedOutURL(); | 703 NavigateToSwappedOutURL(webview()->mainFrame()); |
| 666 } | 704 } |
| 667 | 705 |
| 668 RenderViewImpl::~RenderViewImpl() { | 706 RenderViewImpl::~RenderViewImpl() { |
| 669 history_page_ids_.clear(); | 707 history_page_ids_.clear(); |
| 670 | 708 |
| 671 if (decrement_shared_popup_at_destruction_) | 709 if (decrement_shared_popup_at_destruction_) |
| 672 shared_popup_counter_->data--; | 710 shared_popup_counter_->data--; |
| 673 | 711 |
| 674 // If file chooser is still waiting for answer, dispatch empty answer. | 712 // If file chooser is still waiting for answer, dispatch empty answer. |
| 675 while (!file_chooser_completions_.empty()) { | 713 while (!file_chooser_completions_.empty()) { |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 958 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed) | 996 IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed) |
| 959 // TODO(viettrungluu): Move to a separate message filter. | 997 // TODO(viettrungluu): Move to a separate message filter. |
| 960 #if defined(OS_MACOSX) | 998 #if defined(OS_MACOSX) |
| 961 IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize) | 999 IPC_MESSAGE_HANDLER(ViewMsg_SetInLiveResize, OnSetInLiveResize) |
| 962 #endif | 1000 #endif |
| 963 IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune, | 1001 IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune, |
| 964 OnSetHistoryLengthAndPrune) | 1002 OnSetHistoryLengthAndPrune) |
| 965 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode) | 1003 IPC_MESSAGE_HANDLER(ViewMsg_EnableViewSourceMode, OnEnableViewSourceMode) |
| 966 IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit) | 1004 IPC_MESSAGE_HANDLER(JavaBridgeMsg_Init, OnJavaBridgeInit) |
| 967 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode) | 1005 IPC_MESSAGE_HANDLER(ViewMsg_SetAccessibilityMode, OnSetAccessibilityMode) |
| 1006 IPC_MESSAGE_HANDLER(ViewMsg_UpdateFrameTree, OnUpdatedFrameTree) | |
| 968 | 1007 |
| 969 // Have the super handle all other messages. | 1008 // Have the super handle all other messages. |
| 970 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message)) | 1009 IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message)) |
| 971 IPC_END_MESSAGE_MAP() | 1010 IPC_END_MESSAGE_MAP() |
| 972 | 1011 |
| 973 if (!msg_is_ok) { | 1012 if (!msg_is_ok) { |
| 974 // The message had a handler, but its deserialization failed. | 1013 // The message had a handler, but its deserialization failed. |
| 975 // Kill the renderer to avoid potential spoofing attacks. | 1014 // Kill the renderer to avoid potential spoofing attacks. |
| 976 CHECK(false) << "Unable to deserialize message in RenderViewImpl."; | 1015 CHECK(false) << "Unable to deserialize message in RenderViewImpl."; |
| 977 } | 1016 } |
| (...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1861 // NOTE: For now we're doing the safest thing, and sending out notification | 1900 // 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 | 1901 // 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 | 1902 // displayed when done loading. Ideally we would send notification when |
| 1864 // finished parsing the head, but webkit doesn't support that yet. | 1903 // finished parsing the head, but webkit doesn't support that yet. |
| 1865 // The feed discovery code would also benefit from access to the head. | 1904 // The feed discovery code would also benefit from access to the head. |
| 1866 Send(new ViewHostMsg_DidStopLoading(routing_id_)); | 1905 Send(new ViewHostMsg_DidStopLoading(routing_id_)); |
| 1867 | 1906 |
| 1868 if (load_progress_tracker_ != NULL) | 1907 if (load_progress_tracker_ != NULL) |
| 1869 load_progress_tracker_->DidStopLoading(); | 1908 load_progress_tracker_->DidStopLoading(); |
| 1870 | 1909 |
| 1910 if (pending_frame_tree_update_) { | |
| 1911 pending_frame_tree_update_ = false; | |
| 1912 SendUpdatedFrameTree(webview()->mainFrame(), false); | |
| 1913 } | |
| 1914 | |
| 1871 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStopLoading()); | 1915 FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStopLoading()); |
| 1872 } | 1916 } |
| 1873 | 1917 |
| 1874 void RenderViewImpl::didChangeLoadProgress(WebFrame* frame, | 1918 void RenderViewImpl::didChangeLoadProgress(WebFrame* frame, |
| 1875 double load_progress) { | 1919 double load_progress) { |
| 1876 if (load_progress_tracker_ != NULL) | 1920 if (load_progress_tracker_ != NULL) |
| 1877 load_progress_tracker_->DidChangeLoadProgress(frame, load_progress); | 1921 load_progress_tracker_->DidChangeLoadProgress(frame, load_progress); |
| 1878 } | 1922 } |
| 1879 | 1923 |
| 1880 bool RenderViewImpl::isSmartInsertDeleteEnabled() { | 1924 bool RenderViewImpl::isSmartInsertDeleteEnabled() { |
| (...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2445 return NULL; | 2489 return NULL; |
| 2446 return new RendererWebApplicationCacheHostImpl( | 2490 return new RendererWebApplicationCacheHostImpl( |
| 2447 FromWebView(frame->view()), client, | 2491 FromWebView(frame->view()), client, |
| 2448 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy()); | 2492 RenderThreadImpl::current()->appcache_dispatcher()->backend_proxy()); |
| 2449 } | 2493 } |
| 2450 | 2494 |
| 2451 WebCookieJar* RenderViewImpl::cookieJar(WebFrame* frame) { | 2495 WebCookieJar* RenderViewImpl::cookieJar(WebFrame* frame) { |
| 2452 return &cookie_jar_; | 2496 return &cookie_jar_; |
| 2453 } | 2497 } |
| 2454 | 2498 |
| 2499 void RenderViewImpl::didCreateFrame(WebFrame* parent, WebFrame* child) { | |
| 2500 if (is_loading_) { | |
| 2501 pending_frame_tree_update_ = true; | |
| 2502 return; | |
| 2503 } | |
| 2504 if (!updating_frame_tree_) | |
| 2505 SendUpdatedFrameTree(child, false); | |
| 2506 } | |
| 2507 | |
| 2455 void RenderViewImpl::frameDetached(WebFrame* frame) { | 2508 void RenderViewImpl::frameDetached(WebFrame* frame) { |
| 2509 if (is_loading_) { | |
| 2510 pending_frame_tree_update_ = true; | |
| 2511 return; | |
| 2512 } | |
| 2513 if (!updating_frame_tree_) | |
| 2514 SendUpdatedFrameTree(frame, true); | |
| 2515 | |
| 2456 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame)); | 2516 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameDetached(frame)); |
| 2457 } | 2517 } |
| 2458 | 2518 |
| 2459 void RenderViewImpl::willClose(WebFrame* frame) { | 2519 void RenderViewImpl::willClose(WebFrame* frame) { |
| 2460 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame)); | 2520 FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameWillClose(frame)); |
| 2461 } | 2521 } |
| 2462 | 2522 |
| 2463 void RenderViewImpl::loadURLExternally( | 2523 void RenderViewImpl::loadURLExternally( |
| 2464 WebFrame* frame, const WebURLRequest& request, | 2524 WebFrame* frame, const WebURLRequest& request, |
| 2465 WebNavigationPolicy policy) { | 2525 WebNavigationPolicy policy) { |
| (...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3598 | 3658 |
| 3599 if (!context->Initialize( | 3659 if (!context->Initialize( |
| 3600 attributes, | 3660 attributes, |
| 3601 false /* bind generates resources */, | 3661 false /* bind generates resources */, |
| 3602 content::CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_ INITIALIZE)) | 3662 content::CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_ INITIALIZE)) |
| 3603 return NULL; | 3663 return NULL; |
| 3604 return context.release(); | 3664 return context.release(); |
| 3605 } | 3665 } |
| 3606 } | 3666 } |
| 3607 | 3667 |
| 3668 // The browser process needs to know the shape of the tree, as well as the names | |
| 3669 // and ids of all frames. This allows it to properly route JavaScript messages | |
| 3670 // across processes and frames. The serialization format is described in the | |
| 3671 // comments of the ViewMsg_FrameTreeUpdated message. | |
| 3672 // This function sends those updates to the browser and updates the RVH | |
| 3673 // corresponding to this object. It must be called on any events that modify | |
| 3674 // the tree structure or the names of any frames. | |
| 3675 void RenderViewImpl::SendUpdatedFrameTree( | |
| 3676 WebKit::WebFrame* frame, bool exclude_subtree) { | |
|
Charlie Reis
2012/08/24 23:26:07
Hmm, "frame" makes it sound like we're sending the
nasko
2012/08/27 18:53:37
Done.
| |
| 3677 std::string json; | |
| 3678 WebFrame* f = frame->top(); | |
| 3679 base::DictionaryValue tree; | |
| 3680 | |
| 3681 ConstructFrameTree(f, exclude_subtree ? frame : NULL, &tree); | |
| 3682 base::JSONWriter::Write(&tree, &json); | |
| 3683 | |
| 3684 Send(new ViewHostMsg_FrameTreeUpdated(routing_id_, json)); | |
| 3685 } | |
| 3686 | |
| 3687 void RenderViewImpl::CreateFrameTree(WebKit::WebFrame* frame, | |
| 3688 DictionaryValue* frame_tree) { | |
| 3689 NavigateToSwappedOutURL(frame); | |
| 3690 | |
| 3691 string16 name; | |
| 3692 if (frame_tree->GetString(content::kFrameTreeNodeNameKey, &name) && | |
| 3693 name != string16()) { | |
| 3694 frame->setName(name); | |
| 3695 } | |
| 3696 | |
| 3697 int remote_id; | |
| 3698 if (frame_tree->GetInteger(content::kFrameTreeNodeIdKey, &remote_id)) | |
| 3699 active_frame_id_map_.insert(std::pair<int, int>(frame->identifier(), | |
| 3700 remote_id)); | |
| 3701 | |
| 3702 ListValue* children; | |
| 3703 if (!frame_tree->GetList(content::kFrameTreeNodeSubtreeKey, &children)) | |
| 3704 return; | |
| 3705 | |
| 3706 base::DictionaryValue* child; | |
| 3707 for (size_t i = 0; i < children->GetSize(); ++i) { | |
| 3708 if (!children->GetDictionary(i, &child)) | |
| 3709 continue; | |
| 3710 WebElement element = frame->document().createElement("iframe"); | |
| 3711 if (frame->document().body().appendChild(element)) { | |
|
Charlie Reis
2012/08/24 23:26:07
I wonder if we should do something if this fails?
nasko
2012/08/27 18:53:37
Done.
| |
| 3712 WebFrame* subframe = WebFrame::fromFrameOwnerElement(element); | |
| 3713 if (subframe) | |
| 3714 CreateFrameTree(subframe, child); | |
| 3715 } | |
| 3716 } | |
| 3717 } | |
| 3718 | |
| 3719 WebKit::WebFrame* RenderViewImpl::GetFrameByMappedID(int frame_id) { | |
| 3720 std::map<int, int>::iterator it = active_frame_id_map_.find(frame_id); | |
| 3721 if (it == active_frame_id_map_.end()) | |
| 3722 return NULL; | |
| 3723 | |
| 3724 return FindFrameByID(webview()->mainFrame(), it->second); | |
| 3725 } | |
| 3726 | |
| 3608 void RenderViewImpl::EnsureMediaStreamImpl() { | 3727 void RenderViewImpl::EnsureMediaStreamImpl() { |
| 3609 if (!RenderThreadImpl::current()) // Will be NULL during unit tests. | 3728 if (!RenderThreadImpl::current()) // Will be NULL during unit tests. |
| 3610 return; | 3729 return; |
| 3611 | 3730 |
| 3612 #if defined(ENABLE_WEBRTC) | 3731 #if defined(ENABLE_WEBRTC) |
| 3613 if (!p2p_socket_dispatcher_) | 3732 if (!p2p_socket_dispatcher_) |
| 3614 p2p_socket_dispatcher_ = new content::P2PSocketDispatcher(this); | 3733 p2p_socket_dispatcher_ = new content::P2PSocketDispatcher(this); |
| 3615 | 3734 |
| 3616 if (!media_stream_dispatcher_) | 3735 if (!media_stream_dispatcher_) |
| 3617 media_stream_dispatcher_ = new MediaStreamDispatcher(this); | 3736 media_stream_dispatcher_ = new MediaStreamDispatcher(this); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3813 } | 3932 } |
| 3814 delete channels; | 3933 delete channels; |
| 3815 } | 3934 } |
| 3816 | 3935 |
| 3817 int id = intents_host_->RegisterWebIntent(intentRequest); | 3936 int id = intents_host_->RegisterWebIntent(intentRequest); |
| 3818 Send(new IntentsHostMsg_WebIntentDispatch( | 3937 Send(new IntentsHostMsg_WebIntentDispatch( |
| 3819 routing_id_, intent_data, id)); | 3938 routing_id_, intent_data, id)); |
| 3820 } | 3939 } |
| 3821 | 3940 |
| 3822 bool RenderViewImpl::willCheckAndDispatchMessageEvent( | 3941 bool RenderViewImpl::willCheckAndDispatchMessageEvent( |
| 3823 WebKit::WebFrame* source, | 3942 WebKit::WebFrame* sourceFrame, |
| 3943 WebKit::WebFrame* targetFrame, | |
| 3824 WebKit::WebSecurityOrigin target_origin, | 3944 WebKit::WebSecurityOrigin target_origin, |
| 3825 WebKit::WebDOMMessageEvent event) { | 3945 WebKit::WebDOMMessageEvent event) { |
| 3826 if (!is_swapped_out_) | 3946 if (!is_swapped_out_) |
| 3827 return false; | 3947 return false; |
| 3828 | 3948 |
| 3829 ViewMsg_PostMessage_Params params; | 3949 ViewMsg_PostMessage_Params params; |
| 3830 params.data = event.data().toString(); | 3950 params.data = event.data().toString(); |
| 3831 params.source_origin = event.origin(); | 3951 params.source_origin = event.origin(); |
| 3832 if (!target_origin.isNull()) | 3952 if (!target_origin.isNull()) |
| 3833 params.target_origin = target_origin.toString(); | 3953 params.target_origin = target_origin.toString(); |
| 3834 | 3954 |
| 3835 // Include the routing ID for the source frame, which the browser process | 3955 // 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 | 3956 // will translate into the routing ID for the equivalent frame in the target |
| 3837 // process. | 3957 // process. |
| 3838 // TODO(creis): Support source subframes. | |
| 3839 params.source_routing_id = MSG_ROUTING_NONE; | 3958 params.source_routing_id = MSG_ROUTING_NONE; |
| 3840 RenderViewImpl* source_view = FromWebView(source->view()); | 3959 RenderViewImpl* source_view = FromWebView(sourceFrame->view()); |
| 3841 if (source_view) | 3960 if (source_view) |
| 3842 params.source_routing_id = source_view->routing_id(); | 3961 params.source_routing_id = source_view->routing_id(); |
| 3962 params.source_frame_id = sourceFrame->identifier(); | |
| 3963 | |
| 3964 // Include the process, route, and frame IDs of the target frame. This allows | |
| 3965 // the browser to detect races between this message being sent and the target | |
| 3966 // frame no longer being valid. | |
| 3967 params.target_process_id = target_process_id_; | |
| 3968 params.target_routing_id = target_routing_id_; | |
| 3969 | |
| 3970 std::map<int,int>::iterator it = active_frame_id_map_.find( | |
| 3971 targetFrame->identifier()); | |
| 3972 if (it != active_frame_id_map_.end()) { | |
| 3973 params.target_frame_id = it->second; | |
| 3974 } else { | |
| 3975 params.target_frame_id = 0; | |
| 3976 } | |
| 3843 | 3977 |
| 3844 Send(new ViewHostMsg_RouteMessageEvent(routing_id_, params)); | 3978 Send(new ViewHostMsg_RouteMessageEvent(routing_id_, params)); |
| 3845 return true; | 3979 return true; |
| 3846 } | 3980 } |
| 3847 | 3981 |
| 3848 void RenderViewImpl::willOpenSocketStream( | 3982 void RenderViewImpl::willOpenSocketStream( |
| 3849 WebSocketStreamHandle* handle) { | 3983 WebSocketStreamHandle* handle) { |
| 3850 SocketStreamHandleData::AddToHandle(handle, routing_id_); | 3984 SocketStreamHandleData::AddToHandle(handle, routing_id_); |
| 3851 } | 3985 } |
| 3852 | 3986 |
| (...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4562 | 4696 |
| 4563 void RenderViewImpl::OnScriptEvalRequest(const string16& frame_xpath, | 4697 void RenderViewImpl::OnScriptEvalRequest(const string16& frame_xpath, |
| 4564 const string16& jscript, | 4698 const string16& jscript, |
| 4565 int id, | 4699 int id, |
| 4566 bool notify_result) { | 4700 bool notify_result) { |
| 4567 EvaluateScript(frame_xpath, jscript, id, notify_result); | 4701 EvaluateScript(frame_xpath, jscript, id, notify_result); |
| 4568 } | 4702 } |
| 4569 | 4703 |
| 4570 void RenderViewImpl::OnPostMessageEvent( | 4704 void RenderViewImpl::OnPostMessageEvent( |
| 4571 const ViewMsg_PostMessage_Params& params) { | 4705 const ViewMsg_PostMessage_Params& params) { |
| 4572 // TODO(creis): Support sending to subframes. | 4706 // Find the target frame of this message. The source tags the message with |
| 4573 WebFrame* frame = webview()->mainFrame(); | 4707 // |target_frame_id|, so use it to locate the frame. |
| 4708 WebFrame* frame = FindFrameByID(webview()->mainFrame(), | |
| 4709 params.target_frame_id); | |
| 4710 if (!frame) | |
| 4711 return; | |
| 4574 | 4712 |
| 4575 // Find the source frame if it exists. | 4713 // Find the source frame if it exists. |
| 4576 // TODO(creis): Support source subframes. | |
| 4577 WebFrame* source_frame = NULL; | 4714 WebFrame* source_frame = NULL; |
| 4578 if (params.source_routing_id != MSG_ROUTING_NONE) { | 4715 if (params.source_routing_id != MSG_ROUTING_NONE) { |
| 4579 RenderViewImpl* source_view = FromRoutingID(params.source_routing_id); | 4716 RenderViewImpl* source_view = FromRoutingID(params.source_routing_id); |
| 4580 if (source_view) | 4717 if (source_view) |
| 4581 source_frame = source_view->webview()->mainFrame(); | 4718 source_frame = source_view->GetFrameByMappedID(params.source_frame_id); |
| 4582 } | 4719 } |
| 4583 | 4720 |
| 4584 // Create an event with the message. The final parameter to initMessageEvent | 4721 // Create an event with the message. The final parameter to initMessageEvent |
| 4585 // is the last event ID, which is not used with postMessage. | 4722 // is the last event ID, which is not used with postMessage. |
| 4586 WebDOMEvent event = frame->document().createEvent("MessageEvent"); | 4723 WebDOMEvent event = frame->document().createEvent("MessageEvent"); |
| 4587 WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>(); | 4724 WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>(); |
| 4588 msg_event.initMessageEvent("message", | 4725 msg_event.initMessageEvent("message", |
| 4589 // |canBubble| and |cancellable| are always false | 4726 // |canBubble| and |cancellable| are always false |
| 4590 false, false, | 4727 false, false, |
| 4591 WebSerializedScriptValue::fromString(params.data), | 4728 WebSerializedScriptValue::fromString(params.data), |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4920 // Synchronously run the unload handler before sending the ACK. | 5057 // Synchronously run the unload handler before sending the ACK. |
| 4921 webview()->dispatchUnloadEvent(); | 5058 webview()->dispatchUnloadEvent(); |
| 4922 | 5059 |
| 4923 // Swap out and stop sending any IPC messages that are not ACKs. | 5060 // Swap out and stop sending any IPC messages that are not ACKs. |
| 4924 SetSwappedOut(true); | 5061 SetSwappedOut(true); |
| 4925 | 5062 |
| 4926 // Replace the page with a blank dummy URL. The unload handler will not be | 5063 // 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. | 5064 // 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 | 5065 // 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. | 5066 // beforeunload handler. For now, we just run it a second time silently. |
| 4930 NavigateToSwappedOutURL(); | 5067 NavigateToSwappedOutURL(webview()->mainFrame()); |
| 4931 | 5068 |
| 4932 // Let WebKit know that this view is hidden so it can drop resources and | 5069 // Let WebKit know that this view is hidden so it can drop resources and |
| 4933 // stop compositing. | 5070 // stop compositing. |
| 4934 webview()->setVisibilityState(WebKit::WebPageVisibilityStateHidden, false); | 5071 webview()->setVisibilityState(WebKit::WebPageVisibilityStateHidden, false); |
| 4935 } | 5072 } |
| 4936 | 5073 |
| 4937 // Just echo back the params in the ACK. | 5074 // Just echo back the params in the ACK. |
| 4938 Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params)); | 5075 Send(new ViewHostMsg_SwapOut_ACK(routing_id_, params)); |
| 4939 } | 5076 } |
| 4940 | 5077 |
| 4941 void RenderViewImpl::NavigateToSwappedOutURL() { | 5078 void RenderViewImpl::NavigateToSwappedOutURL(WebKit::WebFrame* frame) { |
| 4942 // We use loadRequest instead of loadHTMLString because the former commits | 5079 // We use loadRequest instead of loadHTMLString because the former commits |
| 4943 // synchronously. Otherwise a new navigation can interrupt the navigation | 5080 // synchronously. Otherwise a new navigation can interrupt the navigation |
| 4944 // to content::kSwappedOutURL. If that happens to be to the page we had been | 5081 // 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. | 5082 // showing, then WebKit will never send a commit and we'll be left spinning. |
| 4946 GURL swappedOutURL(content::kSwappedOutURL); | 5083 GURL swappedOutURL(content::kSwappedOutURL); |
| 4947 WebURLRequest request(swappedOutURL); | 5084 WebURLRequest request(swappedOutURL); |
| 4948 webview()->mainFrame()->loadRequest(request); | 5085 frame->loadRequest(request); |
| 4949 } | 5086 } |
| 4950 | 5087 |
| 4951 void RenderViewImpl::OnClosePage() { | 5088 void RenderViewImpl::OnClosePage() { |
| 4952 FOR_EACH_OBSERVER(RenderViewObserver, observers_, ClosePage()); | 5089 FOR_EACH_OBSERVER(RenderViewObserver, observers_, ClosePage()); |
| 4953 // TODO(creis): We'd rather use webview()->Close() here, but that currently | 5090 // TODO(creis): We'd rather use webview()->Close() here, but that currently |
| 4954 // sets the WebView's delegate_ to NULL, preventing any JavaScript dialogs | 5091 // 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 | 5092 // in the onunload handler from appearing. For now, we're bypassing that and |
| 4956 // calling the FrameLoader's CloseURL method directly. This should be | 5093 // 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 | 5094 // 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 | 5095 // to close that can run onunload is also useful for fixing |
| (...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5798 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const { | 5935 bool RenderViewImpl::WebWidgetHandlesCompositorScheduling() const { |
| 5799 return !!RenderThreadImpl::current()->compositor_thread(); | 5936 return !!RenderThreadImpl::current()->compositor_thread(); |
| 5800 } | 5937 } |
| 5801 | 5938 |
| 5802 void RenderViewImpl::OnJavaBridgeInit() { | 5939 void RenderViewImpl::OnJavaBridgeInit() { |
| 5803 DCHECK(!java_bridge_dispatcher_); | 5940 DCHECK(!java_bridge_dispatcher_); |
| 5804 #if defined(ENABLE_JAVA_BRIDGE) | 5941 #if defined(ENABLE_JAVA_BRIDGE) |
| 5805 java_bridge_dispatcher_ = new JavaBridgeDispatcher(this); | 5942 java_bridge_dispatcher_ = new JavaBridgeDispatcher(this); |
| 5806 #endif | 5943 #endif |
| 5807 } | 5944 } |
| 5945 | |
| 5946 void RenderViewImpl::OnUpdatedFrameTree( | |
| 5947 int process_id, | |
| 5948 int route_id, | |
| 5949 const std::string& frame_tree) { | |
| 5950 base::DictionaryValue* frames = NULL; | |
| 5951 scoped_ptr<base::Value> tree(base::JSONReader::Read(frame_tree)); | |
| 5952 if (tree.get() && tree->IsType(base::Value::TYPE_DICTIONARY)) | |
| 5953 tree->GetAsDictionary(&frames); | |
| 5954 | |
| 5955 updating_frame_tree_ = true; | |
| 5956 active_frame_id_map_.clear(); | |
| 5957 | |
| 5958 target_process_id_ = process_id; | |
| 5959 target_routing_id_ = route_id; | |
| 5960 CreateFrameTree(webview()->mainFrame(), frames); | |
| 5961 | |
| 5962 updating_frame_tree_ = false; | |
| 5963 } | |
| OLD | NEW |