Chromium Code Reviews| 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 DCHECK_EQ(child_node->frame_tree(), | |
| 115 parent_frame_host->frame_tree_node()->frame_tree()); | |
| 116 if (child_node->frame_tree() != | |
| 117 parent_frame_host->frame_tree_node()->frame_tree()) { | |
| 118 return NULL; | |
|
Charlie Reis
2014/09/12 21:01:58
nit: You can put a NOTREACHED before the return NU
dmazzoni
2014/09/15 17:55:23
Done.
| |
| 119 } | |
| 120 | |
| 121 return child_node->current_frame_host(); | |
| 122 } | |
| 123 | |
| 124 if (iter->browser_plugin_instance_id) { | |
| 125 RenderFrameHost* guest = | |
| 126 parent_frame_host->delegate()->GetGuestByInstanceID( | |
| 127 iter->browser_plugin_instance_id); | |
| 128 if (guest) | |
| 129 return static_cast<RenderFrameHostImpl*>(guest); | |
| 130 } | |
| 131 } | |
| 132 | |
| 133 return NULL; | |
| 134 } | |
| 135 | |
| 136 bool FrameAccessibility::GetParent( | |
| 137 RenderFrameHostImpl* child_frame_host, | |
| 138 RenderFrameHostImpl** out_parent_frame_host, | |
| 139 int* out_accessibility_node_id) { | |
| 140 for (std::vector<ChildFrameMapping>::iterator iter = mappings_.begin(); | |
| 141 iter != mappings_.end(); | |
| 142 ++iter) { | |
| 143 if (iter->child_frame_tree_node_id) { | |
| 144 FrameTreeNode* child_node = | |
| 145 FrameTree::GloballyFindByID(iter->child_frame_tree_node_id); | |
| 146 if (child_node && | |
| 147 child_node->current_frame_host() == child_frame_host) { | |
| 148 // We should have gotten a node in the same frame tree. | |
| 149 DCHECK_EQ(child_node->frame_tree(), | |
| 150 iter->parent_frame_host->frame_tree_node()->frame_tree()); | |
| 151 if (child_node->frame_tree() != | |
| 152 iter->parent_frame_host->frame_tree_node()->frame_tree()) { | |
| 153 return false; | |
|
Charlie Reis
2014/09/12 21:01:58
NOTREACHED rather than DCHECK with duplicate compa
dmazzoni
2014/09/15 17:55:23
Done.
| |
| 154 } | |
| 155 | |
| 156 if (out_parent_frame_host) | |
| 157 *out_parent_frame_host = iter->parent_frame_host; | |
| 158 if (out_accessibility_node_id) | |
| 159 *out_accessibility_node_id = iter->accessibility_node_id; | |
| 160 return true; | |
| 161 } | |
| 162 } | |
| 163 | |
| 164 if (iter->browser_plugin_instance_id) { | |
| 165 RenderFrameHost* guest = | |
| 166 iter->parent_frame_host->delegate()->GetGuestByInstanceID( | |
| 167 iter->browser_plugin_instance_id); | |
| 168 if (guest == child_frame_host) { | |
| 169 if (out_parent_frame_host) | |
| 170 *out_parent_frame_host = iter->parent_frame_host; | |
| 171 if (out_accessibility_node_id) | |
| 172 *out_accessibility_node_id = iter->accessibility_node_id; | |
| 173 return true; | |
| 174 } | |
| 175 } | |
| 176 } | |
| 177 | |
| 178 return false; | |
| 179 } | |
| 180 | |
| 181 } // namespace content | |
| OLD | NEW |