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 24 matching lines...) Expand all Loading... | |
35 #include "content/browser/permissions/permission_service_impl.h" | 35 #include "content/browser/permissions/permission_service_impl.h" |
36 #include "content/browser/presentation/presentation_service_impl.h" | 36 #include "content/browser/presentation/presentation_service_impl.h" |
37 #include "content/browser/renderer_host/input/input_router.h" | 37 #include "content/browser/renderer_host/input/input_router.h" |
38 #include "content/browser/renderer_host/input/timeout_monitor.h" | 38 #include "content/browser/renderer_host/input/timeout_monitor.h" |
39 #include "content/browser/renderer_host/render_process_host_impl.h" | 39 #include "content/browser/renderer_host/render_process_host_impl.h" |
40 #include "content/browser/renderer_host/render_view_host_delegate.h" | 40 #include "content/browser/renderer_host/render_view_host_delegate.h" |
41 #include "content/browser/renderer_host/render_view_host_delegate_view.h" | 41 #include "content/browser/renderer_host/render_view_host_delegate_view.h" |
42 #include "content/browser/renderer_host/render_view_host_impl.h" | 42 #include "content/browser/renderer_host/render_view_host_impl.h" |
43 #include "content/browser/renderer_host/render_widget_host_impl.h" | 43 #include "content/browser/renderer_host/render_widget_host_impl.h" |
44 #include "content/browser/renderer_host/render_widget_host_view_base.h" | 44 #include "content/browser/renderer_host/render_widget_host_view_base.h" |
45 #include "content/browser/webui/web_ui_controller_factory_registry.h" | |
45 #include "content/common/accessibility_messages.h" | 46 #include "content/common/accessibility_messages.h" |
46 #include "content/common/frame_messages.h" | 47 #include "content/common/frame_messages.h" |
47 #include "content/common/input_messages.h" | 48 #include "content/common/input_messages.h" |
48 #include "content/common/inter_process_time_ticks_converter.h" | 49 #include "content/common/inter_process_time_ticks_converter.h" |
49 #include "content/common/navigation_params.h" | 50 #include "content/common/navigation_params.h" |
50 #include "content/common/render_frame_setup.mojom.h" | 51 #include "content/common/render_frame_setup.mojom.h" |
51 #include "content/common/site_isolation_policy.h" | 52 #include "content/common/site_isolation_policy.h" |
52 #include "content/common/swapped_out_messages.h" | 53 #include "content/common/swapped_out_messages.h" |
53 #include "content/public/browser/ax_event_notification_details.h" | 54 #include "content/public/browser/ax_event_notification_details.h" |
54 #include "content/public/browser/browser_accessibility_state.h" | 55 #include "content/public/browser/browser_accessibility_state.h" |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 routing_id_(routing_id), | 187 routing_id_(routing_id), |
187 render_frame_created_(false), | 188 render_frame_created_(false), |
188 navigations_suspended_(false), | 189 navigations_suspended_(false), |
189 is_waiting_for_beforeunload_ack_(false), | 190 is_waiting_for_beforeunload_ack_(false), |
190 unload_ack_is_for_navigation_(false), | 191 unload_ack_is_for_navigation_(false), |
191 is_loading_(false), | 192 is_loading_(false), |
192 pending_commit_(false), | 193 pending_commit_(false), |
193 accessibility_reset_token_(0), | 194 accessibility_reset_token_(0), |
194 accessibility_reset_count_(0), | 195 accessibility_reset_count_(0), |
195 no_create_browser_accessibility_manager_for_testing_(false), | 196 no_create_browser_accessibility_manager_for_testing_(false), |
197 web_ui_type_(WebUI::kNoWebUI), | |
198 pending_web_ui_type_(WebUI::kNoWebUI), | |
199 should_reuse_web_ui_(false), | |
196 weak_ptr_factory_(this) { | 200 weak_ptr_factory_(this) { |
197 bool is_swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); | 201 bool is_swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); |
198 bool hidden = !!(flags & CREATE_RF_HIDDEN); | 202 bool hidden = !!(flags & CREATE_RF_HIDDEN); |
199 frame_tree_->AddRenderViewHostRef(render_view_host_); | 203 frame_tree_->AddRenderViewHostRef(render_view_host_); |
200 GetProcess()->AddRoute(routing_id_, this); | 204 GetProcess()->AddRoute(routing_id_, this); |
201 g_routing_id_frame_map.Get().insert(std::make_pair( | 205 g_routing_id_frame_map.Get().insert(std::make_pair( |
202 RenderFrameHostID(GetProcess()->GetID(), routing_id_), | 206 RenderFrameHostID(GetProcess()->GetID(), routing_id_), |
203 this)); | 207 this)); |
204 | 208 |
205 if (is_swapped_out) { | 209 if (is_swapped_out) { |
206 rfh_state_ = STATE_SWAPPED_OUT; | 210 rfh_state_ = STATE_SWAPPED_OUT; |
207 } else { | 211 } else { |
208 rfh_state_ = STATE_DEFAULT; | 212 rfh_state_ = STATE_DEFAULT; |
209 GetSiteInstance()->increment_active_frame_count(); | 213 GetSiteInstance()->increment_active_frame_count(); |
210 } | 214 } |
211 | 215 |
212 SetUpMojoIfNeeded(); | 216 SetUpMojoIfNeeded(); |
213 swapout_event_monitor_timeout_.reset(new TimeoutMonitor(base::Bind( | 217 swapout_event_monitor_timeout_.reset(new TimeoutMonitor(base::Bind( |
214 &RenderFrameHostImpl::OnSwappedOut, weak_ptr_factory_.GetWeakPtr()))); | 218 &RenderFrameHostImpl::OnSwappedOut, weak_ptr_factory_.GetWeakPtr()))); |
215 | 219 |
216 if (widget_routing_id != MSG_ROUTING_NONE) { | 220 if (widget_routing_id != MSG_ROUTING_NONE) { |
217 render_widget_host_ = new RenderWidgetHostImpl(rwh_delegate, GetProcess(), | 221 render_widget_host_ = new RenderWidgetHostImpl(rwh_delegate, GetProcess(), |
218 widget_routing_id, hidden); | 222 widget_routing_id, hidden); |
219 render_widget_host_->set_owned_by_render_frame_host(true); | 223 render_widget_host_->set_owned_by_render_frame_host(true); |
220 } | 224 } |
221 } | 225 } |
222 | 226 |
223 RenderFrameHostImpl::~RenderFrameHostImpl() { | 227 RenderFrameHostImpl::~RenderFrameHostImpl() { |
228 // Release the WebUI before all else as the WebUI accesses the RenderFrameHost | |
229 // during cleanup. | |
230 web_ui_type_ = WebUI::kNoWebUI; | |
231 web_ui_.reset(); | |
232 pending_web_ui_type_ = WebUI::kNoWebUI; | |
233 pending_web_ui_.reset(); | |
234 | |
224 GetProcess()->RemoveRoute(routing_id_); | 235 GetProcess()->RemoveRoute(routing_id_); |
225 g_routing_id_frame_map.Get().erase( | 236 g_routing_id_frame_map.Get().erase( |
226 RenderFrameHostID(GetProcess()->GetID(), routing_id_)); | 237 RenderFrameHostID(GetProcess()->GetID(), routing_id_)); |
227 | 238 |
228 if (delegate_ && render_frame_created_) | 239 if (delegate_ && render_frame_created_) |
229 delegate_->RenderFrameDeleted(this); | 240 delegate_->RenderFrameDeleted(this); |
230 | 241 |
231 // If this was swapped out, it already decremented the active frame count of | 242 // If this was swapped out, it already decremented the active frame count of |
232 // the SiteInstance it belongs to. | 243 // the SiteInstance it belongs to. |
233 if (IsRFHStateActive(rfh_state_)) | 244 if (IsRFHStateActive(rfh_state_)) |
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1019 // gone through this, therefore just return. | 1030 // gone through this, therefore just return. |
1020 if (rfh_state_ != RenderFrameHostImpl::STATE_DEFAULT) { | 1031 if (rfh_state_ != RenderFrameHostImpl::STATE_DEFAULT) { |
1021 NOTREACHED() << "RFH should be in default state when calling SwapOut."; | 1032 NOTREACHED() << "RFH should be in default state when calling SwapOut."; |
1022 return; | 1033 return; |
1023 } | 1034 } |
1024 | 1035 |
1025 SetState(RenderFrameHostImpl::STATE_PENDING_SWAP_OUT); | 1036 SetState(RenderFrameHostImpl::STATE_PENDING_SWAP_OUT); |
1026 swapout_event_monitor_timeout_->Start( | 1037 swapout_event_monitor_timeout_->Start( |
1027 base::TimeDelta::FromMilliseconds(RenderViewHostImpl::kUnloadTimeoutMS)); | 1038 base::TimeDelta::FromMilliseconds(RenderViewHostImpl::kUnloadTimeoutMS)); |
1028 | 1039 |
1040 web_ui_type_ = WebUI::kNoWebUI; | |
Charlie Reis
2015/10/23 06:39:25
Sanity check: Why is this the right time to revoke
carlosk
2015/10/27 14:35:44
Comparing with the previous behavior, RFHI:SwapOut
nasko
2015/11/02 17:00:35
I'm not sure how that makes much of a difference.
carlosk
2015/11/03 09:50:30
OK, I moved the destruction of the WebUI to when t
| |
1041 web_ui_.reset(); | |
1042 pending_web_ui_type_ = WebUI::kNoWebUI; | |
1043 pending_web_ui_.reset(); | |
Charlie Reis
2015/10/23 06:39:25
Can we make these 4 lines into a private helper (R
carlosk
2015/10/27 14:35:44
Done.
| |
1044 | |
1029 // There may be no proxy if there are no active views in the process. | 1045 // There may be no proxy if there are no active views in the process. |
1030 int proxy_routing_id = MSG_ROUTING_NONE; | 1046 int proxy_routing_id = MSG_ROUTING_NONE; |
1031 FrameReplicationState replication_state; | 1047 FrameReplicationState replication_state; |
1032 if (proxy) { | 1048 if (proxy) { |
1033 set_render_frame_proxy_host(proxy); | 1049 set_render_frame_proxy_host(proxy); |
1034 proxy_routing_id = proxy->GetRoutingID(); | 1050 proxy_routing_id = proxy->GetRoutingID(); |
1035 replication_state = proxy->frame_tree_node()->current_replication_state(); | 1051 replication_state = proxy->frame_tree_node()->current_replication_state(); |
1036 } | 1052 } |
1037 | 1053 |
1038 if (IsRenderFrameLive()) { | 1054 if (IsRenderFrameLive()) { |
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1965 bool RenderFrameHostImpl::IsFocused() { | 1981 bool RenderFrameHostImpl::IsFocused() { |
1966 // TODO(mlamouri,kenrb): call GetRenderWidgetHost() directly when it stops | 1982 // TODO(mlamouri,kenrb): call GetRenderWidgetHost() directly when it stops |
1967 // returning nullptr in some cases. See https://crbug.com/455245. | 1983 // returning nullptr in some cases. See https://crbug.com/455245. |
1968 return RenderWidgetHostImpl::From( | 1984 return RenderWidgetHostImpl::From( |
1969 GetView()->GetRenderWidgetHost())->is_focused() && | 1985 GetView()->GetRenderWidgetHost())->is_focused() && |
1970 frame_tree_->GetFocusedFrame() && | 1986 frame_tree_->GetFocusedFrame() && |
1971 (frame_tree_->GetFocusedFrame() == frame_tree_node() || | 1987 (frame_tree_->GetFocusedFrame() == frame_tree_node() || |
1972 frame_tree_->GetFocusedFrame()->IsDescendantOf(frame_tree_node())); | 1988 frame_tree_->GetFocusedFrame()->IsDescendantOf(frame_tree_node())); |
1973 } | 1989 } |
1974 | 1990 |
1991 void RenderFrameHostImpl::UpdatePendingWebUI(const GURL& dest_url, | |
1992 int entry_bindings) { | |
1993 WebUI::TypeID new_web_ui_type = | |
1994 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | |
1995 GetSiteInstance()->GetBrowserContext(), dest_url); | |
1996 | |
1997 // The current WebUI should be reused when dest_url requires a WebUI and its | |
1998 // type matches the current. | |
1999 should_reuse_web_ui_ = false; | |
2000 if (new_web_ui_type != WebUI::kNoWebUI && web_ui_type_ == new_web_ui_type) { | |
2001 DCHECK(web_ui_); | |
2002 should_reuse_web_ui_ = true; | |
2003 | |
2004 // Reset the pending WebUI as the current one will be reused. | |
2005 pending_web_ui_.reset(); | |
2006 pending_web_ui_type_ = WebUI::kNoWebUI; | |
2007 } else if (pending_web_ui_type_ != new_web_ui_type) { | |
2008 // Otherwise create, update or reset the pending one if its type doesn't | |
2009 // match the new type (if new type is kNoWebUI then it will be reset). | |
2010 pending_web_ui_ = | |
2011 CreateWebUI(dest_url, entry_bindings, &pending_web_ui_type_); | |
2012 } | |
2013 | |
2014 DCHECK_EQ(!pending_web_ui_, pending_web_ui_type_ == WebUI::kNoWebUI); | |
2015 } | |
2016 | |
2017 void RenderFrameHostImpl::CommitPendingWebUI() { | |
2018 if (should_reuse_web_ui_) { | |
2019 DCHECK(!pending_web_ui_ && pending_web_ui_type_ == WebUI::kNoWebUI); | |
2020 should_reuse_web_ui_ = false; | |
2021 } else { | |
2022 web_ui_ = pending_web_ui_.Pass(); | |
2023 web_ui_type_ = pending_web_ui_type_; | |
2024 pending_web_ui_type_ = WebUI::kNoWebUI; | |
2025 } | |
2026 } | |
2027 | |
2028 void RenderFrameHostImpl::DiscardPendingWebUI() { | |
2029 pending_web_ui_.reset(); | |
2030 pending_web_ui_type_ = WebUI::kNoWebUI; | |
2031 should_reuse_web_ui_ = false; | |
2032 } | |
2033 | |
1975 const image_downloader::ImageDownloaderPtr& | 2034 const image_downloader::ImageDownloaderPtr& |
1976 RenderFrameHostImpl::GetMojoImageDownloader() { | 2035 RenderFrameHostImpl::GetMojoImageDownloader() { |
1977 if (!mojo_image_downloader_.get() && GetServiceRegistry()) { | 2036 if (!mojo_image_downloader_.get() && GetServiceRegistry()) { |
1978 GetServiceRegistry()->ConnectToRemoteService( | 2037 GetServiceRegistry()->ConnectToRemoteService( |
1979 mojo::GetProxy(&mojo_image_downloader_)); | 2038 mojo::GetProxy(&mojo_image_downloader_)); |
1980 } | 2039 } |
1981 return mojo_image_downloader_; | 2040 return mojo_image_downloader_; |
1982 } | 2041 } |
1983 | 2042 |
1984 bool RenderFrameHostImpl::IsSameSiteInstance( | 2043 bool RenderFrameHostImpl::IsSameSiteInstance( |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2269 ui::AX_ATTR_CHILD_TREE_ID, | 2328 ui::AX_ATTR_CHILD_TREE_ID, |
2270 BrowserPluginInstanceIDToAXTreeID(value))); | 2329 BrowserPluginInstanceIDToAXTreeID(value))); |
2271 break; | 2330 break; |
2272 case AX_CONTENT_INT_ATTRIBUTE_LAST: | 2331 case AX_CONTENT_INT_ATTRIBUTE_LAST: |
2273 NOTREACHED(); | 2332 NOTREACHED(); |
2274 break; | 2333 break; |
2275 } | 2334 } |
2276 } | 2335 } |
2277 } | 2336 } |
2278 | 2337 |
2338 scoped_ptr<WebUIImpl> RenderFrameHostImpl::CreateWebUI( | |
2339 const GURL& dest_url, | |
2340 int entry_bindings, | |
2341 WebUI::TypeID* web_ui_type) { | |
2342 if (!dest_url.is_valid()) { | |
2343 *web_ui_type = WebUI::kNoWebUI; | |
2344 return nullptr; | |
2345 } | |
2346 | |
2347 scoped_ptr<WebUIImpl> web_ui; | |
2348 *web_ui_type = WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | |
2349 GetSiteInstance()->GetBrowserContext(), dest_url); | |
2350 if (*web_ui_type != WebUI::kNoWebUI) { | |
2351 web_ui = delegate_->CreateWebUIForRenderFrameHost(dest_url); | |
2352 DCHECK(web_ui); | |
2353 | |
2354 // If we have assigned (zero or more) bindings to the NavigationEntry in the | |
2355 // past, make sure we're not granting it different bindings than it had | |
2356 // before. If so, note it and don't give it any bindings, to avoid a | |
2357 // potential privilege escalation. | |
2358 if (entry_bindings != NavigationEntryImpl::kInvalidBindings && | |
2359 web_ui->GetBindings() != entry_bindings) { | |
2360 RecordAction(base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM")); | |
2361 *web_ui_type = WebUI::kNoWebUI; | |
2362 return nullptr; | |
2363 } | |
2364 } | |
2365 | |
2366 // Check RenderViewHost for proper bindings. | |
2367 if (web_ui && !render_view_host_->GetProcess()->IsForGuestsOnly()) { | |
2368 // If a WebUI was created for the URL and the RenderView is not in a guest | |
2369 // process, then enable missing bindings with the RenderViewHost. | |
2370 int new_bindings = web_ui->GetBindings(); | |
2371 if ((render_view_host_->GetEnabledBindings() & new_bindings) != | |
2372 new_bindings) { | |
2373 render_view_host_->AllowBindings(new_bindings); | |
2374 } | |
2375 } | |
2376 | |
2377 CHECK_EQ(!web_ui, *web_ui_type == WebUI::kNoWebUI); | |
2378 return web_ui.Pass(); | |
2379 } | |
2380 | |
2279 } // namespace content | 2381 } // namespace content |
OLD | NEW |