Chromium Code Reviews| Index: content/browser/frame_host/frame_accessibility.cc |
| diff --git a/content/browser/frame_host/frame_accessibility.cc b/content/browser/frame_host/frame_accessibility.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..3b99a0512decad7382608fe9ab143838ed272d0b |
| --- /dev/null |
| +++ b/content/browser/frame_host/frame_accessibility.cc |
| @@ -0,0 +1,174 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "content/browser/frame_host/frame_accessibility.h" |
| + |
| +#include "content/browser/frame_host/frame_tree.h" |
| +#include "content/browser/frame_host/frame_tree_node.h" |
| +#include "content/browser/frame_host/render_frame_host_delegate.h" |
| +#include "content/browser/frame_host/render_frame_host_impl.h" |
| +#include "content/public/browser/browser_context.h" |
| +#include "content/public/browser/browser_plugin_guest_manager.h" |
| +#include "content/public/browser/web_contents.h" |
|
dmazzoni
2014/09/12 07:34:34
Currently this inclusion is not allowed.
Should I
Fady Samuel
2014/09/12 16:05:11
I can look into changing GetGuestByInstanceID to t
|
| + |
| +namespace content { |
| + |
| +// static |
| +FrameAccessibility* FrameAccessibility::GetInstance() { |
| + return Singleton<FrameAccessibility>::get(); |
| +} |
| + |
| +FrameAccessibility::ChildFrameMapping::ChildFrameMapping() |
| + : parent_frame_host(NULL), |
| + accessibility_node_id(0), |
| + child_frame_tree_node_id(0), |
| + browser_plugin_instance_id(0) {} |
| + |
| +FrameAccessibility::FrameAccessibility() {} |
| + |
| +FrameAccessibility::~FrameAccessibility() {} |
| + |
| +void FrameAccessibility::AddChildFrame( |
| + RenderFrameHostImpl* parent_frame_host, |
| + int accessibility_node_id, |
| + int64 child_frame_tree_node_id) { |
| + for (std::vector<ChildFrameMapping>::iterator iter = mappings_.begin(); |
| + iter != mappings_.end(); |
| + ++iter) { |
| + if (iter->parent_frame_host == parent_frame_host && |
| + (iter->accessibility_node_id == accessibility_node_id || |
| + iter->child_frame_tree_node_id == child_frame_tree_node_id)) { |
| + iter->accessibility_node_id = accessibility_node_id; |
|
Charlie Reis
2014/09/11 21:46:21
What cases require us to update an existing record
dmazzoni
2014/09/12 07:34:34
There are several cases where both could change: i
Charlie Reis
2014/09/12 21:01:58
The frame routing ID might change during navigatio
|
| + iter->child_frame_tree_node_id = child_frame_tree_node_id; |
| + return; |
| + } |
| + } |
| + |
| + ChildFrameMapping new_mapping; |
| + new_mapping.parent_frame_host = parent_frame_host; |
| + new_mapping.accessibility_node_id = accessibility_node_id; |
| + new_mapping.child_frame_tree_node_id = child_frame_tree_node_id; |
| + mappings_.push_back(new_mapping); |
| +} |
| + |
| +void FrameAccessibility::AddGuestWebContents( |
| + RenderFrameHostImpl* parent_frame_host, |
| + int accessibility_node_id, |
| + int browser_plugin_instance_id) { |
| + for (std::vector<ChildFrameMapping>::iterator iter = mappings_.begin(); |
| + iter != mappings_.end(); |
| + ++iter) { |
| + if (iter->parent_frame_host == parent_frame_host && |
| + (iter->accessibility_node_id == accessibility_node_id || |
| + iter->browser_plugin_instance_id == browser_plugin_instance_id)) { |
| + iter->accessibility_node_id = accessibility_node_id; |
| + iter->browser_plugin_instance_id = browser_plugin_instance_id; |
| + return; |
| + } |
| + } |
| + |
| + ChildFrameMapping new_mapping; |
| + new_mapping.parent_frame_host = parent_frame_host; |
| + new_mapping.accessibility_node_id = accessibility_node_id; |
| + new_mapping.browser_plugin_instance_id = browser_plugin_instance_id; |
| + mappings_.push_back(new_mapping); |
| +} |
| + |
| +void FrameAccessibility::OnRenderFrameHostDestroyed( |
| + RenderFrameHostImpl* render_frame_host) { |
| + // Since the order doesn't matter, the fastest way to remove all items |
| + // with this render_frame_host is to iterate over the vector backwards, |
| + // swapping each one with the back element if we need to delete it. |
| + int initial_len = static_cast<int>(mappings_.size()); |
| + for (int i = initial_len - 1; i >= 0; i--) { |
| + if (mappings_[i].parent_frame_host == render_frame_host) { |
| + mappings_[i] = mappings_.back(); |
| + mappings_.pop_back(); |
| + } |
| + } |
| +} |
| + |
| +RenderFrameHostImpl* FrameAccessibility::GetChild( |
| + RenderFrameHostImpl* parent_frame_host, |
| + int accessibility_node_id) { |
| + for (std::vector<ChildFrameMapping>::iterator iter = mappings_.begin(); |
| + iter != mappings_.end(); |
| + ++iter) { |
| + if (iter->parent_frame_host != parent_frame_host || |
| + iter->accessibility_node_id != accessibility_node_id) { |
| + continue; |
| + } |
| + |
| + if (iter->child_frame_tree_node_id) { |
| + FrameTreeNode* child_node = |
| + FrameTree::GloballyFindByID(iter->child_frame_tree_node_id); |
| + if (!child_node) |
| + return NULL; |
| + |
| + // We should have gotten a node in the same frame tree. |
| + CHECK_EQ(child_node->frame_tree(), |
| + parent_frame_host->frame_tree_node()->frame_tree()); |
| + |
| + return child_node->current_frame_host(); |
| + } |
| + |
| + if (iter->browser_plugin_instance_id) { |
| + WebContents* web_contents = |
| + parent_frame_host->delegate()->GetAsWebContents(); |
| + if (!web_contents) |
| + continue; |
| + BrowserPluginGuestManager* guest_manager = |
| + web_contents->GetBrowserContext()->GetGuestManager(); |
| + WebContents* guest = guest_manager->GetGuestByInstanceID( |
| + web_contents, iter->browser_plugin_instance_id); |
| + return static_cast<RenderFrameHostImpl*>(guest->GetMainFrame()); |
| + } |
| + } |
| + |
| + return NULL; |
| +} |
| + |
| +bool FrameAccessibility::GetParent( |
| + RenderFrameHostImpl* child_frame_host, |
| + RenderFrameHostImpl** out_parent_frame_host, |
| + int* out_accessibility_node_id) { |
| + for (std::vector<ChildFrameMapping>::iterator iter = mappings_.begin(); |
| + iter != mappings_.end(); |
| + ++iter) { |
| + if (iter->child_frame_tree_node_id) { |
| + FrameTreeNode* child_node = |
| + FrameTree::GloballyFindByID(iter->child_frame_tree_node_id); |
| + if (child_node && |
| + child_node->current_frame_host() == child_frame_host) { |
| + if (out_parent_frame_host) |
| + *out_parent_frame_host = iter->parent_frame_host; |
| + if (out_accessibility_node_id) |
| + *out_accessibility_node_id = iter->accessibility_node_id; |
| + return true; |
| + } |
| + } |
| + |
| + if (iter->browser_plugin_instance_id) { |
| + WebContents* web_contents = |
| + iter->parent_frame_host->delegate()->GetAsWebContents(); |
| + if (web_contents) { |
| + BrowserPluginGuestManager* guest_manager = |
| + web_contents->GetBrowserContext()->GetGuestManager(); |
| + WebContents* guest = guest_manager->GetGuestByInstanceID( |
| + web_contents, iter->browser_plugin_instance_id); |
| + if (guest->GetMainFrame() == child_frame_host) { |
| + if (out_parent_frame_host) |
| + *out_parent_frame_host = iter->parent_frame_host; |
| + if (out_accessibility_node_id) |
| + *out_accessibility_node_id = iter->accessibility_node_id; |
| + return true; |
| + } |
| + } |
| + } |
| + } |
| + |
| + return false; |
| +} |
| + |
| +} // namespace content |