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/frame_tree.h" | 5 #include "content/browser/frame_host/frame_tree.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <queue> | 9 #include <queue> |
10 #include <utility> | 10 #include <utility> |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "content/common/site_isolation_policy.h" | 24 #include "content/common/site_isolation_policy.h" |
25 #include "third_party/WebKit/public/web/WebSandboxFlags.h" | 25 #include "third_party/WebKit/public/web/WebSandboxFlags.h" |
26 | 26 |
27 namespace content { | 27 namespace content { |
28 | 28 |
29 namespace { | 29 namespace { |
30 | 30 |
31 // Helper function to collect SiteInstances involved in rendering a single | 31 // Helper function to collect SiteInstances involved in rendering a single |
32 // FrameTree (which is a subset of SiteInstances in main frame's proxy_hosts_ | 32 // FrameTree (which is a subset of SiteInstances in main frame's proxy_hosts_ |
33 // because of openers). | 33 // because of openers). |
34 std::set<SiteInstance*> CollectSiteInstances(FrameTree* tree) { | 34 std::set<SiteInstanceImpl*> CollectSiteInstances(FrameTree* tree) { |
35 std::set<SiteInstance*> instances; | 35 std::set<SiteInstanceImpl*> instances; |
36 for (FrameTreeNode* node : tree->Nodes()) | 36 for (FrameTreeNode* node : tree->Nodes()) |
37 instances.insert(node->current_frame_host()->GetSiteInstance()); | 37 instances.insert(node->current_frame_host()->GetSiteInstance()); |
38 return instances; | 38 return instances; |
39 } | 39 } |
40 | 40 |
41 } // namespace | 41 } // namespace |
42 | 42 |
43 FrameTree::NodeIterator::NodeIterator(const NodeIterator& other) = default; | 43 FrameTree::NodeIterator::NodeIterator(const NodeIterator& other) = default; |
44 | 44 |
45 FrameTree::NodeIterator::~NodeIterator() {} | 45 FrameTree::NodeIterator::~NodeIterator() {} |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 void FrameTree::RemoveFrame(FrameTreeNode* child) { | 205 void FrameTree::RemoveFrame(FrameTreeNode* child) { |
206 FrameTreeNode* parent = child->parent(); | 206 FrameTreeNode* parent = child->parent(); |
207 if (!parent) { | 207 if (!parent) { |
208 NOTREACHED() << "Unexpected RemoveFrame call for main frame."; | 208 NOTREACHED() << "Unexpected RemoveFrame call for main frame."; |
209 return; | 209 return; |
210 } | 210 } |
211 | 211 |
212 parent->RemoveChild(child); | 212 parent->RemoveChild(child); |
213 } | 213 } |
214 | 214 |
215 void FrameTree::CreateProxiesForSiteInstance( | 215 void FrameTree::CreateProxiesForSiteInstance(FrameTreeNode* source, |
216 FrameTreeNode* source, | 216 SiteInstanceImpl* site_instance) { |
217 SiteInstance* site_instance) { | |
218 // Create the RenderFrameProxyHost for the new SiteInstance. | 217 // Create the RenderFrameProxyHost for the new SiteInstance. |
219 if (!source || !source->IsMainFrame()) { | 218 if (!source || !source->IsMainFrame()) { |
220 RenderViewHostImpl* render_view_host = GetRenderViewHost(site_instance); | 219 RenderViewHostImpl* render_view_host = GetRenderViewHost(site_instance); |
221 if (!render_view_host) { | 220 if (!render_view_host) { |
222 root()->render_manager()->CreateRenderFrameProxy(site_instance); | 221 root()->render_manager()->CreateRenderFrameProxy(site_instance); |
223 } else { | 222 } else { |
224 root()->render_manager()->EnsureRenderViewInitialized(render_view_host, | 223 root()->render_manager()->EnsureRenderViewInitialized(render_view_host, |
225 site_instance); | 224 site_instance); |
226 } | 225 } |
227 } | 226 } |
228 | 227 |
229 // Proxies are created in the FrameTree in response to a node navigating to a | 228 // Proxies are created in the FrameTree in response to a node navigating to a |
230 // new SiteInstance. Since |source|'s navigation will replace the currently | 229 // new SiteInstance. Since |source|'s navigation will replace the currently |
231 // loaded document, the entire subtree under |source| will be removed. | 230 // loaded document, the entire subtree under |source| will be removed. |
232 for (FrameTreeNode* node : NodesExcept(source)) { | 231 for (FrameTreeNode* node : NodesExcept(source)) { |
233 // If a new frame is created in the current SiteInstance, other frames in | 232 // If a new frame is created in the current SiteInstance, other frames in |
234 // that SiteInstance don't need a proxy for the new frame. | 233 // that SiteInstance don't need a proxy for the new frame. |
235 SiteInstance* current_instance = | 234 SiteInstanceImpl* current_instance = |
236 node->render_manager()->current_frame_host()->GetSiteInstance(); | 235 node->render_manager()->current_frame_host()->GetSiteInstance(); |
237 if (current_instance != site_instance) | 236 if (current_instance != site_instance) |
238 node->render_manager()->CreateRenderFrameProxy(site_instance); | 237 node->render_manager()->CreateRenderFrameProxy(site_instance); |
239 } | 238 } |
240 } | 239 } |
241 | 240 |
242 RenderFrameHostImpl* FrameTree::GetMainFrame() const { | 241 RenderFrameHostImpl* FrameTree::GetMainFrame() const { |
243 return root_->current_frame_host(); | 242 return root_->current_frame_host(); |
244 } | 243 } |
245 | 244 |
246 FrameTreeNode* FrameTree::GetFocusedFrame() { | 245 FrameTreeNode* FrameTree::GetFocusedFrame() { |
247 return FindByID(focused_frame_tree_node_id_); | 246 return FindByID(focused_frame_tree_node_id_); |
248 } | 247 } |
249 | 248 |
250 void FrameTree::SetFocusedFrame(FrameTreeNode* node, SiteInstance* source) { | 249 void FrameTree::SetFocusedFrame(FrameTreeNode* node, SiteInstanceImpl* source) { |
251 if (node == GetFocusedFrame()) | 250 if (node == GetFocusedFrame()) |
252 return; | 251 return; |
253 | 252 |
254 std::set<SiteInstance*> frame_tree_site_instances = | 253 std::set<SiteInstanceImpl*> frame_tree_site_instances = |
255 CollectSiteInstances(this); | 254 CollectSiteInstances(this); |
256 | 255 |
257 SiteInstance* current_instance = | 256 SiteInstanceImpl* current_instance = |
258 node->current_frame_host()->GetSiteInstance(); | 257 node->current_frame_host()->GetSiteInstance(); |
259 | 258 |
260 // Update the focused frame in all other SiteInstances. If focus changes to | 259 // Update the focused frame in all other SiteInstances. If focus changes to |
261 // a cross-process frame, this allows the old focused frame's renderer | 260 // a cross-process frame, this allows the old focused frame's renderer |
262 // process to clear focus from that frame and fire blur events. It also | 261 // process to clear focus from that frame and fire blur events. It also |
263 // ensures that the latest focused frame is available in all renderers to | 262 // ensures that the latest focused frame is available in all renderers to |
264 // compute document.activeElement. | 263 // compute document.activeElement. |
265 // | 264 // |
266 // We do not notify the |source| SiteInstance because it already knows the | 265 // We do not notify the |source| SiteInstance because it already knows the |
267 // new focused frame (since it initiated the focus change), and we notify the | 266 // new focused frame (since it initiated the focus change), and we notify the |
(...skipping 21 matching lines...) Expand all Loading... |
289 // focused frame changes. | 288 // focused frame changes. |
290 root()->current_frame_host()->UpdateAXTreeData(); | 289 root()->current_frame_host()->UpdateAXTreeData(); |
291 } | 290 } |
292 | 291 |
293 void FrameTree::SetFrameRemoveListener( | 292 void FrameTree::SetFrameRemoveListener( |
294 const base::Callback<void(RenderFrameHost*)>& on_frame_removed) { | 293 const base::Callback<void(RenderFrameHost*)>& on_frame_removed) { |
295 on_frame_removed_ = on_frame_removed; | 294 on_frame_removed_ = on_frame_removed; |
296 } | 295 } |
297 | 296 |
298 RenderViewHostImpl* FrameTree::CreateRenderViewHost( | 297 RenderViewHostImpl* FrameTree::CreateRenderViewHost( |
299 SiteInstance* site_instance, | 298 SiteInstanceImpl* site_instance, |
300 int32_t routing_id, | 299 int32_t routing_id, |
301 int32_t main_frame_routing_id, | 300 int32_t main_frame_routing_id, |
302 bool swapped_out, | 301 bool swapped_out, |
303 bool hidden) { | 302 bool hidden) { |
304 RenderViewHostMap::iterator iter = | 303 RenderViewHostMap::iterator iter = |
305 render_view_host_map_.find(site_instance->GetId()); | 304 render_view_host_map_.find(site_instance->GetId()); |
306 if (iter != render_view_host_map_.end()) { | 305 if (iter != render_view_host_map_.end()) { |
307 // If a RenderViewHost is pending deletion for this |site_instance|, it | 306 // If a RenderViewHost is pending deletion for this |site_instance|, it |
308 // shouldn't be reused, so put it in the map of RenderViewHosts pending | 307 // shouldn't be reused, so put it in the map of RenderViewHosts pending |
309 // shutdown. Otherwise, return the existing RenderViewHost for the | 308 // shutdown. Otherwise, return the existing RenderViewHost for the |
(...skipping 10 matching lines...) Expand all Loading... |
320 } | 319 } |
321 RenderViewHostImpl* rvh = | 320 RenderViewHostImpl* rvh = |
322 static_cast<RenderViewHostImpl*>(RenderViewHostFactory::Create( | 321 static_cast<RenderViewHostImpl*>(RenderViewHostFactory::Create( |
323 site_instance, render_view_delegate_, render_widget_delegate_, | 322 site_instance, render_view_delegate_, render_widget_delegate_, |
324 routing_id, main_frame_routing_id, swapped_out, hidden)); | 323 routing_id, main_frame_routing_id, swapped_out, hidden)); |
325 | 324 |
326 render_view_host_map_[site_instance->GetId()] = rvh; | 325 render_view_host_map_[site_instance->GetId()] = rvh; |
327 return rvh; | 326 return rvh; |
328 } | 327 } |
329 | 328 |
330 RenderViewHostImpl* FrameTree::GetRenderViewHost(SiteInstance* site_instance) { | 329 RenderViewHostImpl* FrameTree::GetRenderViewHost( |
| 330 SiteInstanceImpl* site_instance) { |
331 RenderViewHostMap::iterator iter = | 331 RenderViewHostMap::iterator iter = |
332 render_view_host_map_.find(site_instance->GetId()); | 332 render_view_host_map_.find(site_instance->GetId()); |
333 // Don't return the RVH if it is pending deletion. | 333 // Don't return the RVH if it is pending deletion. |
334 if (iter != render_view_host_map_.end() && | 334 if (iter != render_view_host_map_.end() && |
335 !root_->render_manager()->IsViewPendingDeletion(iter->second)) { | 335 !root_->render_manager()->IsViewPendingDeletion(iter->second)) { |
336 return iter->second; | 336 return iter->second; |
337 } | 337 } |
338 return nullptr; | 338 return nullptr; |
339 } | 339 } |
340 | 340 |
341 void FrameTree::AddRenderViewHostRef(RenderViewHostImpl* render_view_host) { | 341 void FrameTree::AddRenderViewHostRef(RenderViewHostImpl* render_view_host) { |
342 SiteInstance* site_instance = render_view_host->GetSiteInstance(); | 342 SiteInstanceImpl* site_instance = render_view_host->GetSiteInstance(); |
343 RenderViewHostMap::iterator iter = | 343 RenderViewHostMap::iterator iter = |
344 render_view_host_map_.find(site_instance->GetId()); | 344 render_view_host_map_.find(site_instance->GetId()); |
345 CHECK(iter != render_view_host_map_.end()); | 345 CHECK(iter != render_view_host_map_.end()); |
346 CHECK(iter->second == render_view_host); | 346 CHECK(iter->second == render_view_host); |
347 | 347 |
348 iter->second->increment_ref_count(); | 348 iter->second->increment_ref_count(); |
349 } | 349 } |
350 | 350 |
351 void FrameTree::ReleaseRenderViewHostRef(RenderViewHostImpl* render_view_host) { | 351 void FrameTree::ReleaseRenderViewHostRef(RenderViewHostImpl* render_view_host) { |
352 SiteInstance* site_instance = render_view_host->GetSiteInstance(); | 352 SiteInstanceImpl* site_instance = render_view_host->GetSiteInstance(); |
353 int32_t site_instance_id = site_instance->GetId(); | 353 int32_t site_instance_id = site_instance->GetId(); |
354 RenderViewHostMap::iterator iter = | 354 RenderViewHostMap::iterator iter = |
355 render_view_host_map_.find(site_instance_id); | 355 render_view_host_map_.find(site_instance_id); |
356 if (iter != render_view_host_map_.end() && iter->second == render_view_host) { | 356 if (iter != render_view_host_map_.end() && iter->second == render_view_host) { |
357 // Decrement the refcount and shutdown the RenderViewHost if no one else is | 357 // Decrement the refcount and shutdown the RenderViewHost if no one else is |
358 // using it. | 358 // using it. |
359 CHECK_GT(iter->second->ref_count(), 0); | 359 CHECK_GT(iter->second->ref_count(), 0); |
360 iter->second->decrement_ref_count(); | 360 iter->second->decrement_ref_count(); |
361 if (iter->second->ref_count() == 0) { | 361 if (iter->second->ref_count() == 0) { |
362 iter->second->ShutdownAndDestroy(); | 362 iter->second->ShutdownAndDestroy(); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 | 437 |
438 bool FrameTree::IsLoading() const { | 438 bool FrameTree::IsLoading() const { |
439 for (const FrameTreeNode* node : const_cast<FrameTree*>(this)->Nodes()) { | 439 for (const FrameTreeNode* node : const_cast<FrameTree*>(this)->Nodes()) { |
440 if (node->IsLoading()) | 440 if (node->IsLoading()) |
441 return true; | 441 return true; |
442 } | 442 } |
443 return false; | 443 return false; |
444 } | 444 } |
445 | 445 |
446 void FrameTree::ReplicatePageFocus(bool is_focused) { | 446 void FrameTree::ReplicatePageFocus(bool is_focused) { |
447 std::set<SiteInstance*> frame_tree_site_instances = | 447 std::set<SiteInstanceImpl*> frame_tree_site_instances = |
448 CollectSiteInstances(this); | 448 CollectSiteInstances(this); |
449 | 449 |
450 // Send the focus update to main frame's proxies in all SiteInstances of | 450 // Send the focus update to main frame's proxies in all SiteInstances of |
451 // other frames in this FrameTree. Note that the main frame might also know | 451 // other frames in this FrameTree. Note that the main frame might also know |
452 // about proxies in SiteInstances for frames in a different FrameTree (e.g., | 452 // about proxies in SiteInstances for frames in a different FrameTree (e.g., |
453 // for window.open), so we can't just iterate over its proxy_hosts_ in | 453 // for window.open), so we can't just iterate over its proxy_hosts_ in |
454 // RenderFrameHostManager. | 454 // RenderFrameHostManager. |
455 for (const auto& instance : frame_tree_site_instances) | 455 for (const auto& instance : frame_tree_site_instances) |
456 SetPageFocus(instance, is_focused); | 456 SetPageFocus(instance, is_focused); |
457 } | 457 } |
458 | 458 |
459 void FrameTree::SetPageFocus(SiteInstance* instance, bool is_focused) { | 459 void FrameTree::SetPageFocus(SiteInstanceImpl* instance, bool is_focused) { |
460 RenderFrameHostManager* root_manager = root_->render_manager(); | 460 RenderFrameHostManager* root_manager = root_->render_manager(); |
461 | 461 |
462 // This is only used to set page-level focus in cross-process subframes, and | 462 // This is only used to set page-level focus in cross-process subframes, and |
463 // requests to set focus in main frame's SiteInstance are ignored. | 463 // requests to set focus in main frame's SiteInstance are ignored. |
464 if (instance != root_manager->current_frame_host()->GetSiteInstance()) { | 464 if (instance != root_manager->current_frame_host()->GetSiteInstance()) { |
465 RenderFrameProxyHost* proxy = | 465 RenderFrameProxyHost* proxy = |
466 root_manager->GetRenderFrameProxyHost(instance); | 466 root_manager->GetRenderFrameProxyHost(instance); |
467 proxy->Send(new InputMsg_SetFocus(proxy->GetRoutingID(), is_focused)); | 467 proxy->Send(new InputMsg_SetFocus(proxy->GetRoutingID(), is_focused)); |
468 } | 468 } |
469 } | 469 } |
470 | 470 |
471 } // namespace content | 471 } // namespace content |
OLD | NEW |