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/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 OnTextSurroundingSelectionResponse) | 400 OnTextSurroundingSelectionResponse) |
401 IPC_MESSAGE_HANDLER(AccessibilityHostMsg_Events, OnAccessibilityEvents) | 401 IPC_MESSAGE_HANDLER(AccessibilityHostMsg_Events, OnAccessibilityEvents) |
402 IPC_MESSAGE_HANDLER(AccessibilityHostMsg_LocationChanges, | 402 IPC_MESSAGE_HANDLER(AccessibilityHostMsg_LocationChanges, |
403 OnAccessibilityLocationChanges) | 403 OnAccessibilityLocationChanges) |
404 #if defined(OS_MACOSX) || defined(OS_ANDROID) | 404 #if defined(OS_MACOSX) || defined(OS_ANDROID) |
405 IPC_MESSAGE_HANDLER(FrameHostMsg_ShowPopup, OnShowPopup) | 405 IPC_MESSAGE_HANDLER(FrameHostMsg_ShowPopup, OnShowPopup) |
406 IPC_MESSAGE_HANDLER(FrameHostMsg_HidePopup, OnHidePopup) | 406 IPC_MESSAGE_HANDLER(FrameHostMsg_HidePopup, OnHidePopup) |
407 #endif | 407 #endif |
408 IPC_END_MESSAGE_MAP() | 408 IPC_END_MESSAGE_MAP() |
409 | 409 |
| 410 // No further actions here, since we may have been deleted. |
410 return handled; | 411 return handled; |
411 } | 412 } |
412 | 413 |
413 void RenderFrameHostImpl::AccessibilitySetFocus(int object_id) { | 414 void RenderFrameHostImpl::AccessibilitySetFocus(int object_id) { |
414 Send(new AccessibilityMsg_SetFocus(routing_id_, object_id)); | 415 Send(new AccessibilityMsg_SetFocus(routing_id_, object_id)); |
415 } | 416 } |
416 | 417 |
417 void RenderFrameHostImpl::AccessibilityDoDefaultAction(int object_id) { | 418 void RenderFrameHostImpl::AccessibilityDoDefaultAction(int object_id) { |
418 Send(new AccessibilityMsg_DoDefaultAction(routing_id_, object_id)); | 419 Send(new AccessibilityMsg_DoDefaultAction(routing_id_, object_id)); |
419 } | 420 } |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 | 779 |
779 void RenderFrameHostImpl::SwapOut(RenderFrameProxyHost* proxy) { | 780 void RenderFrameHostImpl::SwapOut(RenderFrameProxyHost* proxy) { |
780 // The end of this event is in OnSwapOutACK when the RenderFrame has completed | 781 // The end of this event is in OnSwapOutACK when the RenderFrame has completed |
781 // the operation and sends back an IPC message. | 782 // the operation and sends back an IPC message. |
782 // The trace event may not end properly if the ACK times out. We expect this | 783 // The trace event may not end properly if the ACK times out. We expect this |
783 // to be fixed when RenderViewHostImpl::OnSwapOut moves to RenderFrameHost. | 784 // to be fixed when RenderViewHostImpl::OnSwapOut moves to RenderFrameHost. |
784 TRACE_EVENT_ASYNC_BEGIN0("navigation", "RenderFrameHostImpl::SwapOut", this); | 785 TRACE_EVENT_ASYNC_BEGIN0("navigation", "RenderFrameHostImpl::SwapOut", this); |
785 | 786 |
786 // If this RenderFrameHost is not in the default state, it must have already | 787 // If this RenderFrameHost is not in the default state, it must have already |
787 // gone through this, therefore just return. | 788 // gone through this, therefore just return. |
788 if (rfh_state_ != RenderFrameHostImpl::STATE_DEFAULT) | 789 if (rfh_state_ != RenderFrameHostImpl::STATE_DEFAULT) { |
| 790 NOTREACHED() << "RFH should be in default state when calling SwapOut."; |
789 return; | 791 return; |
| 792 } |
790 | 793 |
791 SetState(RenderFrameHostImpl::STATE_PENDING_SWAP_OUT); | 794 SetState(RenderFrameHostImpl::STATE_PENDING_SWAP_OUT); |
792 swapout_event_monitor_timeout_->Start( | 795 swapout_event_monitor_timeout_->Start( |
793 base::TimeDelta::FromMilliseconds(RenderViewHostImpl::kUnloadTimeoutMS)); | 796 base::TimeDelta::FromMilliseconds(RenderViewHostImpl::kUnloadTimeoutMS)); |
794 | 797 |
795 set_render_frame_proxy_host(proxy); | 798 // There may be no proxy if there are no active views in the process. |
| 799 int proxy_routing_id = MSG_ROUTING_NONE; |
| 800 if (proxy) { |
| 801 set_render_frame_proxy_host(proxy); |
| 802 proxy_routing_id = proxy->GetRoutingID(); |
| 803 } |
796 | 804 |
797 if (IsRenderFrameLive()) | 805 if (IsRenderFrameLive()) |
798 Send(new FrameMsg_SwapOut(routing_id_, proxy->GetRoutingID())); | 806 Send(new FrameMsg_SwapOut(routing_id_, proxy_routing_id)); |
799 | 807 |
800 if (!GetParent()) | 808 if (!GetParent()) |
801 delegate_->SwappedOut(this); | 809 delegate_->SwappedOut(this); |
802 } | 810 } |
803 | 811 |
804 void RenderFrameHostImpl::OnBeforeUnloadACK( | 812 void RenderFrameHostImpl::OnBeforeUnloadACK( |
805 bool proceed, | 813 bool proceed, |
806 const base::TimeTicks& renderer_before_unload_start_time, | 814 const base::TimeTicks& renderer_before_unload_start_time, |
807 const base::TimeTicks& renderer_before_unload_end_time) { | 815 const base::TimeTicks& renderer_before_unload_end_time) { |
808 TRACE_EVENT_ASYNC_END0( | 816 TRACE_EVENT_ASYNC_END0( |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 unload_ack_is_for_cross_site_transition_, proceed, | 880 unload_ack_is_for_cross_site_transition_, proceed, |
873 before_unload_end_time); | 881 before_unload_end_time); |
874 | 882 |
875 // If canceled, notify the delegate to cancel its pending navigation entry. | 883 // If canceled, notify the delegate to cancel its pending navigation entry. |
876 if (!proceed) | 884 if (!proceed) |
877 render_view_host_->GetDelegate()->DidCancelLoading(); | 885 render_view_host_->GetDelegate()->DidCancelLoading(); |
878 } | 886 } |
879 | 887 |
880 bool RenderFrameHostImpl::IsWaitingForUnloadACK() const { | 888 bool RenderFrameHostImpl::IsWaitingForUnloadACK() const { |
881 return render_view_host_->is_waiting_for_close_ack_ || | 889 return render_view_host_->is_waiting_for_close_ack_ || |
882 rfh_state_ == STATE_PENDING_SHUTDOWN || | |
883 rfh_state_ == STATE_PENDING_SWAP_OUT; | 890 rfh_state_ == STATE_PENDING_SWAP_OUT; |
884 } | 891 } |
885 | 892 |
886 void RenderFrameHostImpl::OnSwapOutACK() { | 893 void RenderFrameHostImpl::OnSwapOutACK() { |
887 OnSwappedOut(); | 894 OnSwappedOut(); |
888 } | 895 } |
889 | 896 |
890 void RenderFrameHostImpl::OnSwappedOut() { | 897 void RenderFrameHostImpl::OnSwappedOut() { |
891 // Ignore spurious swap out ack. | 898 // Ignore spurious swap out ack. |
892 if (rfh_state_ != STATE_PENDING_SWAP_OUT && | 899 if (rfh_state_ != STATE_PENDING_SWAP_OUT) |
893 rfh_state_ != STATE_PENDING_SHUTDOWN) | |
894 return; | 900 return; |
895 | 901 |
896 TRACE_EVENT_ASYNC_END0("navigation", "RenderFrameHostImpl::SwapOut", this); | 902 TRACE_EVENT_ASYNC_END0("navigation", "RenderFrameHostImpl::SwapOut", this); |
897 swapout_event_monitor_timeout_->Stop(); | 903 swapout_event_monitor_timeout_->Stop(); |
898 | 904 |
899 switch (rfh_state_) { | 905 if (frame_tree_node_->render_manager()->DeleteFromPendingList(this)) { |
900 case STATE_PENDING_SWAP_OUT: | 906 // We are now deleted. |
901 SetState(STATE_SWAPPED_OUT); | 907 return; |
902 break; | |
903 case STATE_PENDING_SHUTDOWN: | |
904 DCHECK(!pending_shutdown_on_swap_out_.is_null()); | |
905 pending_shutdown_on_swap_out_.Run(); | |
906 break; | |
907 default: | |
908 NOTREACHED(); | |
909 } | 908 } |
| 909 |
| 910 // If this RFH wasn't pending deletion, then it is now swapped out. |
| 911 SetState(RenderFrameHostImpl::STATE_SWAPPED_OUT); |
910 } | 912 } |
911 | 913 |
912 void RenderFrameHostImpl::OnContextMenu(const ContextMenuParams& params) { | 914 void RenderFrameHostImpl::OnContextMenu(const ContextMenuParams& params) { |
913 // Validate the URLs in |params|. If the renderer can't request the URLs | 915 // Validate the URLs in |params|. If the renderer can't request the URLs |
914 // directly, don't show them in the context menu. | 916 // directly, don't show them in the context menu. |
915 ContextMenuParams validated_params(params); | 917 ContextMenuParams validated_params(params); |
916 RenderProcessHost* process = GetProcess(); | 918 RenderProcessHost* process = GetProcess(); |
917 | 919 |
918 // We don't validate |unfiltered_link_url| so that this field can be used | 920 // We don't validate |unfiltered_link_url| so that this field can be used |
919 // when users want to copy the original link URL. | 921 // when users want to copy the original link URL. |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1172 | 1174 |
1173 void RenderFrameHostImpl::OnHidePopup() { | 1175 void RenderFrameHostImpl::OnHidePopup() { |
1174 RenderViewHostDelegateView* view = | 1176 RenderViewHostDelegateView* view = |
1175 render_view_host_->delegate_->GetDelegateView(); | 1177 render_view_host_->delegate_->GetDelegateView(); |
1176 if (view) | 1178 if (view) |
1177 view->HidePopupMenu(); | 1179 view->HidePopupMenu(); |
1178 } | 1180 } |
1179 #endif | 1181 #endif |
1180 | 1182 |
1181 void RenderFrameHostImpl::SetState(RenderFrameHostImplState rfh_state) { | 1183 void RenderFrameHostImpl::SetState(RenderFrameHostImplState rfh_state) { |
| 1184 // Only main frames should be swapped out and retained inside a proxy host. |
| 1185 if (rfh_state == STATE_SWAPPED_OUT) |
| 1186 CHECK(!GetParent()); |
| 1187 |
1182 // We update the number of RenderFrameHosts in a SiteInstance when the swapped | 1188 // We update the number of RenderFrameHosts in a SiteInstance when the swapped |
1183 // out status of a RenderFrameHost gets flipped to/from active. | 1189 // out status of a RenderFrameHost gets flipped to/from active. |
1184 if (!IsRFHStateActive(rfh_state_) && IsRFHStateActive(rfh_state)) | 1190 if (!IsRFHStateActive(rfh_state_) && IsRFHStateActive(rfh_state)) |
1185 GetSiteInstance()->increment_active_frame_count(); | 1191 GetSiteInstance()->increment_active_frame_count(); |
1186 else if (IsRFHStateActive(rfh_state_) && !IsRFHStateActive(rfh_state)) | 1192 else if (IsRFHStateActive(rfh_state_) && !IsRFHStateActive(rfh_state)) |
1187 GetSiteInstance()->decrement_active_frame_count(); | 1193 GetSiteInstance()->decrement_active_frame_count(); |
1188 | 1194 |
1189 // The active and swapped out state of the RVH is determined by its main | 1195 // The active and swapped out state of the RVH is determined by its main |
1190 // frame, since subframes should have their own widgets. | 1196 // frame, since subframes should have their own widgets. |
1191 if (frame_tree_node_->IsMainFrame()) { | 1197 if (frame_tree_node_->IsMainFrame()) { |
1192 render_view_host_->set_is_active(IsRFHStateActive(rfh_state)); | 1198 render_view_host_->set_is_active(IsRFHStateActive(rfh_state)); |
1193 render_view_host_->set_is_swapped_out(rfh_state == STATE_SWAPPED_OUT); | 1199 render_view_host_->set_is_swapped_out(rfh_state == STATE_SWAPPED_OUT); |
1194 } | 1200 } |
1195 | 1201 |
1196 // Whenever we change the RFH state to and from active or swapped out state, | 1202 // Whenever we change the RFH state to and from active or swapped out state, |
1197 // we should not be waiting for beforeunload or close acks. We clear them | 1203 // we should not be waiting for beforeunload or close acks. We clear them |
1198 // here to be safe, since they can cause navigations to be ignored in | 1204 // here to be safe, since they can cause navigations to be ignored in |
1199 // OnDidCommitProvisionalLoad. | 1205 // OnDidCommitProvisionalLoad. |
1200 // TODO(creis): Move is_waiting_for_beforeunload_ack_ into the state machine. | 1206 // TODO(creis): Move is_waiting_for_beforeunload_ack_ into the state machine. |
1201 if (rfh_state == STATE_DEFAULT || | 1207 if (rfh_state == STATE_DEFAULT || |
1202 rfh_state == STATE_SWAPPED_OUT || | 1208 rfh_state == STATE_SWAPPED_OUT || |
1203 rfh_state_ == STATE_DEFAULT || | 1209 rfh_state_ == STATE_DEFAULT || |
1204 rfh_state_ == STATE_SWAPPED_OUT) { | 1210 rfh_state_ == STATE_SWAPPED_OUT) { |
1205 is_waiting_for_beforeunload_ack_ = false; | 1211 is_waiting_for_beforeunload_ack_ = false; |
1206 render_view_host_->is_waiting_for_close_ack_ = false; | 1212 render_view_host_->is_waiting_for_close_ack_ = false; |
1207 } | 1213 } |
1208 rfh_state_ = rfh_state; | 1214 rfh_state_ = rfh_state; |
1209 } | 1215 } |
1210 | 1216 |
1211 void RenderFrameHostImpl::SetPendingShutdown(const base::Closure& on_swap_out) { | |
1212 pending_shutdown_on_swap_out_ = on_swap_out; | |
1213 SetState(STATE_PENDING_SHUTDOWN); | |
1214 } | |
1215 | |
1216 bool RenderFrameHostImpl::CanCommitURL(const GURL& url) { | 1217 bool RenderFrameHostImpl::CanCommitURL(const GURL& url) { |
1217 // TODO(creis): We should also check for WebUI pages here. Also, when the | 1218 // TODO(creis): We should also check for WebUI pages here. Also, when the |
1218 // out-of-process iframes implementation is ready, we should check for | 1219 // out-of-process iframes implementation is ready, we should check for |
1219 // cross-site URLs that are not allowed to commit in this process. | 1220 // cross-site URLs that are not allowed to commit in this process. |
1220 | 1221 |
1221 // Give the client a chance to disallow URLs from committing. | 1222 // Give the client a chance to disallow URLs from committing. |
1222 return GetContentClient()->browser()->CanCommitURL(GetProcess(), url); | 1223 return GetContentClient()->browser()->CanCommitURL(GetProcess(), url); |
1223 } | 1224 } |
1224 | 1225 |
1225 void RenderFrameHostImpl::Navigate(const FrameMsg_Navigate_Params& params) { | 1226 void RenderFrameHostImpl::Navigate(const FrameMsg_Navigate_Params& params) { |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1540 // Clear any state if a pending navigation is canceled or preempted. | 1541 // Clear any state if a pending navigation is canceled or preempted. |
1541 if (suspended_nav_params_) | 1542 if (suspended_nav_params_) |
1542 suspended_nav_params_.reset(); | 1543 suspended_nav_params_.reset(); |
1543 | 1544 |
1544 TRACE_EVENT_ASYNC_END0("navigation", | 1545 TRACE_EVENT_ASYNC_END0("navigation", |
1545 "RenderFrameHostImpl navigation suspended", this); | 1546 "RenderFrameHostImpl navigation suspended", this); |
1546 navigations_suspended_ = false; | 1547 navigations_suspended_ = false; |
1547 } | 1548 } |
1548 | 1549 |
1549 } // namespace content | 1550 } // namespace content |
OLD | NEW |