OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/browser/frame_host/frame_accessibility.h" |
| 6 |
| 7 #include "content/browser/frame_host/frame_tree.h" |
| 8 #include "content/browser/frame_host/frame_tree_node.h" |
| 9 #include "content/browser/frame_host/render_frame_host_delegate.h" |
| 10 #include "content/browser/frame_host/render_frame_host_impl.h" |
| 11 #include "content/public/browser/browser_context.h" |
| 12 |
| 13 namespace content { |
| 14 |
| 15 // static |
| 16 FrameAccessibility* FrameAccessibility::GetInstance() { |
| 17 return Singleton<FrameAccessibility>::get(); |
| 18 } |
| 19 |
| 20 FrameAccessibility::ChildFrameMapping::ChildFrameMapping() |
| 21 : parent_frame_host(NULL), |
| 22 accessibility_node_id(0), |
| 23 child_frame_tree_node_id(0), |
| 24 browser_plugin_instance_id(0) {} |
| 25 |
| 26 FrameAccessibility::FrameAccessibility() {} |
| 27 |
| 28 FrameAccessibility::~FrameAccessibility() {} |
| 29 |
| 30 void FrameAccessibility::AddChildFrame( |
| 31 RenderFrameHostImpl* parent_frame_host, |
| 32 int accessibility_node_id, |
| 33 int64 child_frame_tree_node_id) { |
| 34 for (std::vector<ChildFrameMapping>::iterator iter = mappings_.begin(); |
| 35 iter != mappings_.end(); |
| 36 ++iter) { |
| 37 // TODO(dmazzoni): the renderer should keep track of these mappings |
| 38 // and clear an existing mapping before setting a new one, that would |
| 39 // be safer than just updating existing mappings. http://crbug.com/413464 |
| 40 if (iter->parent_frame_host == parent_frame_host && |
| 41 (iter->accessibility_node_id == accessibility_node_id || |
| 42 iter->child_frame_tree_node_id == child_frame_tree_node_id)) { |
| 43 iter->accessibility_node_id = accessibility_node_id; |
| 44 iter->child_frame_tree_node_id = child_frame_tree_node_id; |
| 45 return; |
| 46 } |
| 47 } |
| 48 |
| 49 ChildFrameMapping new_mapping; |
| 50 new_mapping.parent_frame_host = parent_frame_host; |
| 51 new_mapping.accessibility_node_id = accessibility_node_id; |
| 52 new_mapping.child_frame_tree_node_id = child_frame_tree_node_id; |
| 53 mappings_.push_back(new_mapping); |
| 54 } |
| 55 |
| 56 void FrameAccessibility::AddGuestWebContents( |
| 57 RenderFrameHostImpl* parent_frame_host, |
| 58 int accessibility_node_id, |
| 59 int browser_plugin_instance_id) { |
| 60 for (std::vector<ChildFrameMapping>::iterator iter = mappings_.begin(); |
| 61 iter != mappings_.end(); |
| 62 ++iter) { |
| 63 // TODO(dmazzoni): the renderer should keep track of these mappings |
| 64 // and clear an existing mapping before setting a new one, that would |
| 65 // be safer than just updating existing mappings. http://crbug.com/413464 |
| 66 if (iter->parent_frame_host == parent_frame_host && |
| 67 (iter->accessibility_node_id == accessibility_node_id || |
| 68 iter->browser_plugin_instance_id == browser_plugin_instance_id)) { |
| 69 iter->accessibility_node_id = accessibility_node_id; |
| 70 iter->browser_plugin_instance_id = browser_plugin_instance_id; |
| 71 return; |
| 72 } |
| 73 } |
| 74 |
| 75 ChildFrameMapping new_mapping; |
| 76 new_mapping.parent_frame_host = parent_frame_host; |
| 77 new_mapping.accessibility_node_id = accessibility_node_id; |
| 78 new_mapping.browser_plugin_instance_id = browser_plugin_instance_id; |
| 79 mappings_.push_back(new_mapping); |
| 80 } |
| 81 |
| 82 void FrameAccessibility::OnRenderFrameHostDestroyed( |
| 83 RenderFrameHostImpl* render_frame_host) { |
| 84 // Since the order doesn't matter, the fastest way to remove all items |
| 85 // with this render_frame_host is to iterate over the vector backwards, |
| 86 // swapping each one with the back element if we need to delete it. |
| 87 int initial_len = static_cast<int>(mappings_.size()); |
| 88 for (int i = initial_len - 1; i >= 0; i--) { |
| 89 if (mappings_[i].parent_frame_host == render_frame_host) { |
| 90 mappings_[i] = mappings_.back(); |
| 91 mappings_.pop_back(); |
| 92 } |
| 93 } |
| 94 } |
| 95 |
| 96 RenderFrameHostImpl* FrameAccessibility::GetChild( |
| 97 RenderFrameHostImpl* parent_frame_host, |
| 98 int accessibility_node_id) { |
| 99 for (std::vector<ChildFrameMapping>::iterator iter = mappings_.begin(); |
| 100 iter != mappings_.end(); |
| 101 ++iter) { |
| 102 if (iter->parent_frame_host != parent_frame_host || |
| 103 iter->accessibility_node_id != accessibility_node_id) { |
| 104 continue; |
| 105 } |
| 106 |
| 107 if (iter->child_frame_tree_node_id) { |
| 108 FrameTreeNode* child_node = |
| 109 FrameTree::GloballyFindByID(iter->child_frame_tree_node_id); |
| 110 if (!child_node) |
| 111 return NULL; |
| 112 |
| 113 // We should have gotten a node in the same frame tree. |
| 114 if (child_node->frame_tree() != |
| 115 parent_frame_host->frame_tree_node()->frame_tree()) { |
| 116 NOTREACHED(); |
| 117 return NULL; |
| 118 } |
| 119 |
| 120 return child_node->current_frame_host(); |
| 121 } |
| 122 |
| 123 if (iter->browser_plugin_instance_id) { |
| 124 RenderFrameHost* guest = |
| 125 parent_frame_host->delegate()->GetGuestByInstanceID( |
| 126 iter->browser_plugin_instance_id); |
| 127 if (guest) |
| 128 return static_cast<RenderFrameHostImpl*>(guest); |
| 129 } |
| 130 } |
| 131 |
| 132 return NULL; |
| 133 } |
| 134 |
| 135 bool FrameAccessibility::GetParent( |
| 136 RenderFrameHostImpl* child_frame_host, |
| 137 RenderFrameHostImpl** out_parent_frame_host, |
| 138 int* out_accessibility_node_id) { |
| 139 for (std::vector<ChildFrameMapping>::iterator iter = mappings_.begin(); |
| 140 iter != mappings_.end(); |
| 141 ++iter) { |
| 142 if (iter->child_frame_tree_node_id) { |
| 143 FrameTreeNode* child_node = |
| 144 FrameTree::GloballyFindByID(iter->child_frame_tree_node_id); |
| 145 if (child_node && |
| 146 child_node->current_frame_host() == child_frame_host) { |
| 147 // We should have gotten a node in the same frame tree. |
| 148 if (child_node->frame_tree() != |
| 149 iter->parent_frame_host->frame_tree_node()->frame_tree()) { |
| 150 NOTREACHED(); |
| 151 return false; |
| 152 } |
| 153 |
| 154 if (out_parent_frame_host) |
| 155 *out_parent_frame_host = iter->parent_frame_host; |
| 156 if (out_accessibility_node_id) |
| 157 *out_accessibility_node_id = iter->accessibility_node_id; |
| 158 return true; |
| 159 } |
| 160 } |
| 161 |
| 162 if (iter->browser_plugin_instance_id) { |
| 163 RenderFrameHost* guest = |
| 164 iter->parent_frame_host->delegate()->GetGuestByInstanceID( |
| 165 iter->browser_plugin_instance_id); |
| 166 if (guest == child_frame_host) { |
| 167 if (out_parent_frame_host) |
| 168 *out_parent_frame_host = iter->parent_frame_host; |
| 169 if (out_accessibility_node_id) |
| 170 *out_accessibility_node_id = iter->accessibility_node_id; |
| 171 return true; |
| 172 } |
| 173 } |
| 174 } |
| 175 |
| 176 return false; |
| 177 } |
| 178 |
| 179 } // namespace content |
OLD | NEW |