Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/browser/frame_host/render_frame_host_impl.h" | 5 #include "content/browser/frame_host/render_frame_host_impl.h" |
| 6 | 6 |
| 7 #include "base/containers/hash_tables.h" | 7 #include "base/containers/hash_tables.h" |
| 8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
| 9 #include "base/metrics/user_metrics_action.h" | 9 #include "base/metrics/user_metrics_action.h" |
| 10 #include "content/browser/child_process_security_policy_impl.h" | 10 #include "content/browser/child_process_security_policy_impl.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 62 FrameTree* frame_tree, | 62 FrameTree* frame_tree, |
| 63 FrameTreeNode* frame_tree_node, | 63 FrameTreeNode* frame_tree_node, |
| 64 int routing_id, | 64 int routing_id, |
| 65 bool is_swapped_out) | 65 bool is_swapped_out) |
| 66 : render_view_host_(render_view_host), | 66 : render_view_host_(render_view_host), |
| 67 delegate_(delegate), | 67 delegate_(delegate), |
| 68 cross_process_frame_connector_(NULL), | 68 cross_process_frame_connector_(NULL), |
| 69 frame_tree_(frame_tree), | 69 frame_tree_(frame_tree), |
| 70 frame_tree_node_(frame_tree_node), | 70 frame_tree_node_(frame_tree_node), |
| 71 routing_id_(routing_id), | 71 routing_id_(routing_id), |
| 72 is_swapped_out_(is_swapped_out) { | 72 is_swapped_out_(is_swapped_out), |
| 73 are_javascript_messages_suppressed_(false) { | |
| 73 frame_tree_->RegisterRenderFrameHost(this); | 74 frame_tree_->RegisterRenderFrameHost(this); |
| 74 GetProcess()->AddRoute(routing_id_, this); | 75 GetProcess()->AddRoute(routing_id_, this); |
| 75 g_routing_id_frame_map.Get().insert(std::make_pair( | 76 g_routing_id_frame_map.Get().insert(std::make_pair( |
| 76 RenderFrameHostID(GetProcess()->GetID(), routing_id_), | 77 RenderFrameHostID(GetProcess()->GetID(), routing_id_), |
| 77 this)); | 78 this)); |
| 78 } | 79 } |
| 79 | 80 |
| 80 RenderFrameHostImpl::~RenderFrameHostImpl() { | 81 RenderFrameHostImpl::~RenderFrameHostImpl() { |
| 81 GetProcess()->RemoveRoute(routing_id_); | 82 GetProcess()->RemoveRoute(routing_id_); |
| 82 g_routing_id_frame_map.Get().erase( | 83 g_routing_id_frame_map.Get().erase( |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 319 IPC_MESSAGE_HANDLER_GENERIC(FrameHostMsg_DidCommitProvisionalLoad, | 320 IPC_MESSAGE_HANDLER_GENERIC(FrameHostMsg_DidCommitProvisionalLoad, |
| 320 OnNavigate(msg)) | 321 OnNavigate(msg)) |
| 321 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartLoading, OnDidStartLoading) | 322 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartLoading, OnDidStartLoading) |
| 322 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading) | 323 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading) |
| 323 IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL) | 324 IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL) |
| 324 IPC_MESSAGE_HANDLER(FrameHostMsg_BeforeUnload_ACK, OnBeforeUnloadACK) | 325 IPC_MESSAGE_HANDLER(FrameHostMsg_BeforeUnload_ACK, OnBeforeUnloadACK) |
| 325 IPC_MESSAGE_HANDLER(FrameHostMsg_SwapOut_ACK, OnSwapOutACK) | 326 IPC_MESSAGE_HANDLER(FrameHostMsg_SwapOut_ACK, OnSwapOutACK) |
| 326 IPC_MESSAGE_HANDLER(FrameHostMsg_ContextMenu, OnContextMenu) | 327 IPC_MESSAGE_HANDLER(FrameHostMsg_ContextMenu, OnContextMenu) |
| 327 IPC_MESSAGE_HANDLER(FrameHostMsg_JavaScriptExecuteResponse, | 328 IPC_MESSAGE_HANDLER(FrameHostMsg_JavaScriptExecuteResponse, |
| 328 OnJavaScriptExecuteResponse) | 329 OnJavaScriptExecuteResponse) |
| 330 IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_RunJavaScriptMessage, | |
| 331 OnRunJavaScriptMessage) | |
| 332 IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_RunBeforeUnloadConfirm, | |
| 333 OnRunBeforeUnloadConfirm) | |
| 329 IPC_END_MESSAGE_MAP_EX() | 334 IPC_END_MESSAGE_MAP_EX() |
| 330 | 335 |
| 331 if (!msg_is_ok) { | 336 if (!msg_is_ok) { |
| 332 // The message had a handler, but its de-serialization failed. | 337 // The message had a handler, but its de-serialization failed. |
| 333 // Kill the renderer. | 338 // Kill the renderer. |
| 334 RecordAction(base::UserMetricsAction("BadMessageTerminate_RFH")); | 339 RecordAction(base::UserMetricsAction("BadMessageTerminate_RFH")); |
| 335 GetProcess()->ReceivedBadMessage(); | 340 GetProcess()->ReceivedBadMessage(); |
| 336 } | 341 } |
| 337 | 342 |
| 338 return handled; | 343 return handled; |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 640 std::map<int, JavaScriptResultCallback>::iterator it = | 645 std::map<int, JavaScriptResultCallback>::iterator it = |
| 641 javascript_callbacks_.find(id); | 646 javascript_callbacks_.find(id); |
| 642 if (it != javascript_callbacks_.end()) { | 647 if (it != javascript_callbacks_.end()) { |
| 643 it->second.Run(result_value); | 648 it->second.Run(result_value); |
| 644 javascript_callbacks_.erase(it); | 649 javascript_callbacks_.erase(it); |
| 645 } else { | 650 } else { |
| 646 NOTREACHED() << "Received script response for unknown request"; | 651 NOTREACHED() << "Received script response for unknown request"; |
| 647 } | 652 } |
| 648 } | 653 } |
| 649 | 654 |
| 655 void RenderFrameHostImpl::OnRunJavaScriptMessage( | |
| 656 const base::string16& message, | |
| 657 const base::string16& default_prompt, | |
| 658 const GURL& frame_url, | |
| 659 JavaScriptMessageType type, | |
| 660 IPC::Message* reply_msg) { | |
| 661 // While a JS message dialog is showing, tabs in the same process shouldn't | |
| 662 // process input events. | |
| 663 GetProcess()->SetIgnoreInputEvents(true); | |
| 664 render_view_host_->StopHangMonitorTimeout(); | |
| 665 delegate_->RunJavaScriptMessage(this, message, default_prompt, | |
| 666 frame_url, type, reply_msg, | |
| 667 AreJavaScriptMessagesSuppressed()); | |
| 668 } | |
| 669 | |
| 670 void RenderFrameHostImpl::OnRunBeforeUnloadConfirm( | |
| 671 const GURL& frame_url, | |
| 672 const base::string16& message, | |
| 673 bool is_reload, | |
| 674 IPC::Message* reply_msg) { | |
| 675 // While a JS before unload dialog is showing, tabs in the same process | |
| 676 // shouldn't process input events. | |
| 677 GetProcess()->SetIgnoreInputEvents(true); | |
| 678 render_view_host_->StopHangMonitorTimeout(); | |
| 679 delegate_->RunBeforeUnloadConfirm(this, message, is_reload, reply_msg); | |
| 680 } | |
| 681 | |
| 650 void RenderFrameHostImpl::SetPendingShutdown(const base::Closure& on_swap_out) { | 682 void RenderFrameHostImpl::SetPendingShutdown(const base::Closure& on_swap_out) { |
| 651 render_view_host_->SetPendingShutdown(on_swap_out); | 683 render_view_host_->SetPendingShutdown(on_swap_out); |
| 652 } | 684 } |
| 653 | 685 |
| 654 bool RenderFrameHostImpl::CanCommitURL(const GURL& url) { | 686 bool RenderFrameHostImpl::CanCommitURL(const GURL& url) { |
| 655 // TODO(creis): We should also check for WebUI pages here. Also, when the | 687 // TODO(creis): We should also check for WebUI pages here. Also, when the |
| 656 // out-of-process iframes implementation is ready, we should check for | 688 // out-of-process iframes implementation is ready, we should check for |
| 657 // cross-site URLs that are not allowed to commit in this process. | 689 // cross-site URLs that are not allowed to commit in this process. |
| 658 | 690 |
| 659 // Give the client a chance to disallow URLs from committing. | 691 // Give the client a chance to disallow URLs from committing. |
| 660 return GetContentClient()->browser()->CanCommitURL(GetProcess(), url); | 692 return GetContentClient()->browser()->CanCommitURL(GetProcess(), url); |
| 661 } | 693 } |
| 662 | 694 |
| 695 bool* RenderFrameHostImpl::AreJavaScriptMessagesSuppressed() { | |
| 696 RenderFrameHostImpl* main_frame = frame_tree_->GetMainFrame(); | |
| 697 return &main_frame->are_javascript_messages_suppressed_; | |
|
jam
2014/04/05 00:21:38
why keep this in RFH at all instead of in the dele
Avi (use Gerrit)
2014/04/07 18:03:46
This was added in https://codereview.chromium.org/
jam
2014/04/07 18:11:36
What I meant is why keep state on a main RFH, inst
Avi (use Gerrit)
2014/04/07 19:53:55
Gotcha.
| |
| 698 } | |
| 699 | |
| 663 void RenderFrameHostImpl::Navigate(const FrameMsg_Navigate_Params& params) { | 700 void RenderFrameHostImpl::Navigate(const FrameMsg_Navigate_Params& params) { |
| 664 TRACE_EVENT0("frame_host", "RenderFrameHostImpl::Navigate"); | 701 TRACE_EVENT0("frame_host", "RenderFrameHostImpl::Navigate"); |
| 665 // Browser plugin guests are not allowed to navigate outside web-safe schemes, | 702 // Browser plugin guests are not allowed to navigate outside web-safe schemes, |
| 666 // so do not grant them the ability to request additional URLs. | 703 // so do not grant them the ability to request additional URLs. |
| 667 if (!GetProcess()->IsGuest()) { | 704 if (!GetProcess()->IsGuest()) { |
| 668 ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL( | 705 ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL( |
| 669 GetProcess()->GetID(), params.url); | 706 GetProcess()->GetID(), params.url); |
| 670 if (params.url.SchemeIs(kDataScheme) && | 707 if (params.url.SchemeIs(kDataScheme) && |
| 671 params.base_url_for_data_url.SchemeIs(kFileScheme)) { | 708 params.base_url_for_data_url.SchemeIs(kFileScheme)) { |
| 672 // If 'data:' is used, and we have a 'file:' base url, grant access to | 709 // If 'data:' is used, and we have a 'file:' base url, grant access to |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 724 void RenderFrameHostImpl::SelectRange(const gfx::Point& start, | 761 void RenderFrameHostImpl::SelectRange(const gfx::Point& start, |
| 725 const gfx::Point& end) { | 762 const gfx::Point& end) { |
| 726 Send(new InputMsg_SelectRange(routing_id_, start, end)); | 763 Send(new InputMsg_SelectRange(routing_id_, start, end)); |
| 727 } | 764 } |
| 728 | 765 |
| 729 void RenderFrameHostImpl::ExtendSelectionAndDelete(size_t before, | 766 void RenderFrameHostImpl::ExtendSelectionAndDelete(size_t before, |
| 730 size_t after) { | 767 size_t after) { |
| 731 Send(new FrameMsg_ExtendSelectionAndDelete(routing_id_, before, after)); | 768 Send(new FrameMsg_ExtendSelectionAndDelete(routing_id_, before, after)); |
| 732 } | 769 } |
| 733 | 770 |
| 771 void RenderFrameHostImpl::JavaScriptDialogClosed( | |
| 772 IPC::Message* reply_msg, | |
| 773 bool success, | |
| 774 const base::string16& user_input) { | |
| 775 GetProcess()->SetIgnoreInputEvents(false); | |
| 776 bool is_waiting = render_view_host_->is_waiting_for_beforeunload_ack() || | |
| 777 render_view_host_->IsWaitingForUnloadACK(); | |
| 778 | |
| 779 // If we are executing as part of (before)unload event handling, we don't | |
| 780 // want to use the regular hung_renderer_delay_ms_ if the user has agreed to | |
| 781 // leave the current page. In this case, use the regular timeout value used | |
| 782 // during the (before)unload handling. | |
| 783 if (is_waiting) { | |
| 784 render_view_host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds( | |
| 785 success ? RenderViewHostImpl::kUnloadTimeoutMS | |
| 786 : render_view_host_->hung_renderer_delay_ms_)); | |
| 787 } | |
| 788 | |
| 789 FrameHostMsg_RunJavaScriptMessage::WriteReplyParams(reply_msg, | |
| 790 success, user_input); | |
| 791 Send(reply_msg); | |
| 792 | |
| 793 // If we are waiting for an unload or beforeunload ack and the user has | |
| 794 // suppressed messages, kill the tab immediately; a page that's spamming | |
| 795 // alerts in onbeforeunload is presumably malicious, so there's no point in | |
| 796 // continuing to run its script and dragging out the process. | |
| 797 // This must be done after sending the reply since RenderView can't close | |
| 798 // correctly while waiting for a response. | |
| 799 if (is_waiting && *AreJavaScriptMessagesSuppressed()) | |
| 800 render_view_host_->delegate_->RendererUnresponsive( | |
| 801 render_view_host_, | |
| 802 render_view_host_->is_waiting_for_beforeunload_ack(), | |
| 803 render_view_host_->IsWaitingForUnloadACK()); | |
| 804 } | |
| 805 | |
| 734 } // namespace content | 806 } // namespace content |
| OLD | NEW |