Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(363)

Side by Side Diff: ui/accessibility/ax_tree_serializer.h

Issue 125783002: Add AXTreeDelegate and refactor other AXTree classes slightly. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed const issue Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/accessibility/ax_tree.cc ('k') | ui/accessibility/ax_tree_serializer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #ifndef UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_ 5 #ifndef UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_
6 #define UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_ 6 #define UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_
7 7
8 #include <set> 8 #include <set>
9 9
10 #include "base/containers/hash_tables.h" 10 #include "base/containers/hash_tables.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 // assume that nodes 3, 4, and 5 are not modified unless you explicitly 44 // assume that nodes 3, 4, and 5 are not modified unless you explicitly
45 // call SerializeChanges() on them. 45 // call SerializeChanges() on them.
46 // 46 //
47 // As long as the source tree has unique ids for every node and no loops, 47 // As long as the source tree has unique ids for every node and no loops,
48 // and as long as every update is applied to the client tree, AXTreeSerializer 48 // and as long as every update is applied to the client tree, AXTreeSerializer
49 // will continue to work. If the source tree makes a change but fails to 49 // will continue to work. If the source tree makes a change but fails to
50 // call SerializeChanges properly, the trees may get out of sync - but 50 // call SerializeChanges properly, the trees may get out of sync - but
51 // because AXTreeSerializer always keeps track of what updates it's sent, 51 // because AXTreeSerializer always keeps track of what updates it's sent,
52 // it will never send an invalid update and the client tree will not break, 52 // it will never send an invalid update and the client tree will not break,
53 // it just may not contain all of the changes. 53 // it just may not contain all of the changes.
54 template<class AXSourceNode> 54 template<typename AXSourceNode>
55 class AXTreeSerializer { 55 class AXTreeSerializer {
56 public: 56 public:
57 explicit AXTreeSerializer(AXTreeSource<AXSourceNode>* tree); 57 explicit AXTreeSerializer(AXTreeSource<AXSourceNode>* tree);
58 ~AXTreeSerializer(); 58 ~AXTreeSerializer();
59 59
60 // Throw out the internal state that keeps track of the nodes the client 60 // Throw out the internal state that keeps track of the nodes the client
61 // knows about. This has the effect that the next update will send the 61 // knows about. This has the effect that the next update will send the
62 // entire tree over because it assumes the client knows nothing. 62 // entire tree over because it assumes the client knows nothing.
63 void Reset(); 63 void Reset();
64 64
65 // Serialize all changes to |node| and append them to |out_update|. 65 // Serialize all changes to |node| and append them to |out_update|.
66 void SerializeChanges(const AXSourceNode* node, 66 void SerializeChanges(AXSourceNode node,
67 AXTreeUpdate* out_update); 67 AXTreeUpdate* out_update);
68 68
69 // Delete the client subtree for this node, ensuring that the subtree
70 // is re-serialized.
71 void DeleteClientSubtree(AXSourceNode node);
72
69 // Only for unit testing. Normally this class relies on getting a call 73 // Only for unit testing. Normally this class relies on getting a call
70 // to SerializeChanges() every time the source tree changes. For unit 74 // to SerializeChanges() every time the source tree changes. For unit
71 // testing, it's convenient to create a static AXTree for the initial 75 // testing, it's convenient to create a static AXTree for the initial
72 // state and then call ChangeTreeSourceForTesting and then SerializeChanges 76 // state and then call ChangeTreeSourceForTesting and then SerializeChanges
73 // to simulate the changes you'd get if a tree changed from the initial 77 // to simulate the changes you'd get if a tree changed from the initial
74 // state to the second tree's state. 78 // state to the second tree's state.
75 void ChangeTreeSourceForTesting(AXTreeSource<AXSourceNode>* new_tree); 79 void ChangeTreeSourceForTesting(AXTreeSource<AXSourceNode>* new_tree);
76 80
77 private: 81 private:
78 // Return the least common ancestor of a node in the source tree 82 // Return the least common ancestor of a node in the source tree
(...skipping 21 matching lines...) Expand all
100 // 2 3 2 3 | 104 // 2 3 2 3 |
101 // / \ / / | 105 // / \ / / |
102 // 4 7 8 4 | 106 // 4 7 8 4 |
103 // / \ / \ | 107 // / \ / \ |
104 // 5 6 5 6 | 108 // 5 6 5 6 |
105 // 109 //
106 // LCA(source node 8, client node 7) is node 2. 110 // LCA(source node 8, client node 7) is node 2.
107 // LCA(source node 5, client node 5) is node 1. 111 // LCA(source node 5, client node 5) is node 1.
108 // It's not node 5, because the two trees disagree on the parent of 112 // It's not node 5, because the two trees disagree on the parent of
109 // node 4, so the LCA is the first ancestor both trees agree on. 113 // node 4, so the LCA is the first ancestor both trees agree on.
110 const AXSourceNode* LeastCommonAncestor(const AXSourceNode* node, 114 AXSourceNode LeastCommonAncestor(AXSourceNode node,
111 ClientTreeNode* client_node); 115 ClientTreeNode* client_node);
112 116
113 // Return the least common ancestor of |node| that's in the client tree. 117 // Return the least common ancestor of |node| that's in the client tree.
114 // This just walks up the ancestors of |node| until it finds a node that's 118 // This just walks up the ancestors of |node| until it finds a node that's
115 // also in the client tree, and then calls LeastCommonAncestor on the 119 // also in the client tree, and then calls LeastCommonAncestor on the
116 // source node and client node. 120 // source node and client node.
117 const AXSourceNode* LeastCommonAncestor(const AXSourceNode* node); 121 AXSourceNode LeastCommonAncestor(AXSourceNode node);
118 122
119 // Walk the subtree rooted at |node| and return true if any nodes that 123 // Walk the subtree rooted at |node| and return true if any nodes that
120 // would be updated are being reparented. If so, update |lca| to point 124 // would be updated are being reparented. If so, update |out_lca| to point
121 // to the least common ancestor of the previous LCA and the previous 125 // to the least common ancestor of the previous LCA and the previous
122 // parent of the node being reparented. 126 // parent of the node being reparented.
123 bool AnyDescendantWasReparented(const AXSourceNode* node, 127 bool AnyDescendantWasReparented(AXSourceNode node,
124 const AXSourceNode** lca); 128 AXSourceNode* out_lca);
125 129
126 ClientTreeNode* ClientTreeNodeById(int32 id); 130 ClientTreeNode* ClientTreeNodeById(int32 id);
127 131
128 // Delete the given client tree node and recursively delete all of its 132 // Delete the given client tree node and recursively delete all of its
129 // descendants. 133 // descendants.
130 void DeleteClientSubtree(ClientTreeNode* client_node); 134 void DeleteClientSubtree(ClientTreeNode* client_node);
131 135
132 // Helper function, called recursively with each new node to serialize. 136 // Helper function, called recursively with each new node to serialize.
133 void SerializeChangedNodes(const AXSourceNode* node, 137 void SerializeChangedNodes(AXSourceNode node,
134 AXTreeUpdate* out_update); 138 AXTreeUpdate* out_update);
135 139
136 // The tree source. 140 // The tree source.
137 AXTreeSource<AXSourceNode>* tree_; 141 AXTreeSource<AXSourceNode>* tree_;
138 142
139 // Our representation of the client tree. 143 // Our representation of the client tree.
140 ClientTreeNode* client_root_; 144 ClientTreeNode* client_root_;
141 145
142 // A map from IDs to nodes in the client tree. 146 // A map from IDs to nodes in the client tree.
143 base::hash_map<int32, ClientTreeNode*> client_id_map_; 147 base::hash_map<int32, ClientTreeNode*> client_id_map_;
144 }; 148 };
145 149
146 // In order to keep track of what nodes the client knows about, we keep a 150 // In order to keep track of what nodes the client knows about, we keep a
147 // representation of the client tree - just IDs and parent/child 151 // representation of the client tree - just IDs and parent/child
148 // relationships. 152 // relationships.
149 struct AX_EXPORT ClientTreeNode { 153 struct AX_EXPORT ClientTreeNode {
150 ClientTreeNode(); 154 ClientTreeNode();
151 virtual ~ClientTreeNode(); 155 virtual ~ClientTreeNode();
152 int32 id; 156 int32 id;
153 ClientTreeNode* parent; 157 ClientTreeNode* parent;
154 std::vector<ClientTreeNode*> children; 158 std::vector<ClientTreeNode*> children;
155 }; 159 };
156 160
157 template<class AXSourceNode> 161 template<typename AXSourceNode>
158 AXTreeSerializer<AXSourceNode>::AXTreeSerializer( 162 AXTreeSerializer<AXSourceNode>::AXTreeSerializer(
159 AXTreeSource<AXSourceNode>* tree) 163 AXTreeSource<AXSourceNode>* tree)
160 : tree_(tree), 164 : tree_(tree),
161 client_root_(NULL) { 165 client_root_(NULL) {
162 } 166 }
163 167
164 template<class AXSourceNode> 168 template<typename AXSourceNode>
165 AXTreeSerializer<AXSourceNode>::~AXTreeSerializer() { 169 AXTreeSerializer<AXSourceNode>::~AXTreeSerializer() {
166 Reset(); 170 Reset();
167 } 171 }
168 172
169 template<class AXSourceNode> 173 template<typename AXSourceNode>
170 void AXTreeSerializer<AXSourceNode>::Reset() { 174 void AXTreeSerializer<AXSourceNode>::Reset() {
171 if (client_root_) { 175 if (client_root_) {
172 DeleteClientSubtree(client_root_); 176 DeleteClientSubtree(client_root_);
173 client_root_ = NULL; 177 client_root_ = NULL;
174 } 178 }
175 } 179 }
176 180
177 template<class AXSourceNode> 181 template<typename AXSourceNode>
178 void AXTreeSerializer<AXSourceNode>::ChangeTreeSourceForTesting( 182 void AXTreeSerializer<AXSourceNode>::ChangeTreeSourceForTesting(
179 AXTreeSource<AXSourceNode>* new_tree) { 183 AXTreeSource<AXSourceNode>* new_tree) {
180 tree_ = new_tree; 184 tree_ = new_tree;
181 } 185 }
182 186
183 template<class AXSourceNode> 187 template<typename AXSourceNode>
184 const AXSourceNode* AXTreeSerializer<AXSourceNode>::LeastCommonAncestor( 188 AXSourceNode AXTreeSerializer<AXSourceNode>::LeastCommonAncestor(
185 const AXSourceNode* node, ClientTreeNode* client_node) { 189 AXSourceNode node, ClientTreeNode* client_node) {
186 if (node == NULL || client_node == NULL) 190 if (!tree_->IsValid(node) || client_node == NULL)
187 return NULL; 191 return tree_->GetNull();
188 192
189 std::vector<const AXSourceNode*> ancestors; 193 std::vector<AXSourceNode> ancestors;
190 while (node) { 194 while (tree_->IsValid(node)) {
191 ancestors.push_back(node); 195 ancestors.push_back(node);
192 node = tree_->GetParent(node); 196 node = tree_->GetParent(node);
193 } 197 }
194 198
195 std::vector<ClientTreeNode*> client_ancestors; 199 std::vector<ClientTreeNode*> client_ancestors;
196 while (client_node) { 200 while (client_node) {
197 client_ancestors.push_back(client_node); 201 client_ancestors.push_back(client_node);
198 client_node = client_node->parent; 202 client_node = client_node->parent;
199 } 203 }
200 204
201 // Start at the root. Keep going until the source ancestor chain and 205 // Start at the root. Keep going until the source ancestor chain and
202 // client ancestor chain disagree. The last node before they disagree 206 // client ancestor chain disagree. The last node before they disagree
203 // is the LCA. 207 // is the LCA.
204 const AXSourceNode* lca = NULL; 208 AXSourceNode lca = tree_->GetNull();
205 int source_index = static_cast<int>(ancestors.size() - 1); 209 int source_index = static_cast<int>(ancestors.size() - 1);
206 int client_index = static_cast<int>(client_ancestors.size() - 1); 210 int client_index = static_cast<int>(client_ancestors.size() - 1);
207 while (source_index >= 0 && client_index >= 0) { 211 while (source_index >= 0 && client_index >= 0) {
208 if (tree_->GetId(ancestors[source_index]) != 212 if (tree_->GetId(ancestors[source_index]) !=
209 client_ancestors[client_index]->id) { 213 client_ancestors[client_index]->id) {
210 return lca; 214 return lca;
211 } 215 }
212 lca = ancestors[source_index]; 216 lca = ancestors[source_index];
213 source_index--; 217 source_index--;
214 client_index--; 218 client_index--;
215 } 219 }
216 return lca; 220 return lca;
217 } 221 }
218 222
219 template<class AXSourceNode> 223 template<typename AXSourceNode>
220 const AXSourceNode* AXTreeSerializer<AXSourceNode>::LeastCommonAncestor( 224 AXSourceNode AXTreeSerializer<AXSourceNode>::LeastCommonAncestor(
221 const AXSourceNode* node) { 225 AXSourceNode node) {
222 // Walk up the tree until the source node's id also exists in the 226 // Walk up the tree until the source node's id also exists in the
223 // client tree, then call LeastCommonAncestor on those two nodes. 227 // client tree, then call LeastCommonAncestor on those two nodes.
224 ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node)); 228 ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node));
225 while (node && !client_node) { 229 while (tree_->IsValid(node) && !client_node) {
226 node = tree_->GetParent(node); 230 node = tree_->GetParent(node);
227 if (node) 231 if (tree_->IsValid(node))
228 client_node = ClientTreeNodeById(tree_->GetId(node)); 232 client_node = ClientTreeNodeById(tree_->GetId(node));
229 } 233 }
230 return LeastCommonAncestor(node, client_node); 234 return LeastCommonAncestor(node, client_node);
231 } 235 }
232 236
233 template<class AXSourceNode> 237 template<typename AXSourceNode>
234 bool AXTreeSerializer<AXSourceNode>::AnyDescendantWasReparented( 238 bool AXTreeSerializer<AXSourceNode>::AnyDescendantWasReparented(
235 const AXSourceNode* node, const AXSourceNode** lca) { 239 AXSourceNode node, AXSourceNode* out_lca) {
236 bool result = false; 240 bool result = false;
237 int id = tree_->GetId(node); 241 int id = tree_->GetId(node);
238 int child_count = tree_->GetChildCount(node); 242 std::vector<AXSourceNode> children;
239 for (int i = 0; i < child_count; ++i) { 243 tree_->GetChildren(node, &children);
240 const AXSourceNode* child = tree_->GetChildAtIndex(node, i); 244 for (size_t i = 0; i < children.size(); ++i) {
245 AXSourceNode& child = children[i];
241 int child_id = tree_->GetId(child); 246 int child_id = tree_->GetId(child);
242 ClientTreeNode* client_child = ClientTreeNodeById(child_id); 247 ClientTreeNode* client_child = ClientTreeNodeById(child_id);
243 if (client_child) { 248 if (client_child) {
244 if (!client_child->parent) { 249 if (!client_child->parent) {
245 // If the client child has no parent, it must have been the 250 // If the client child has no parent, it must have been the
246 // previous root node, so there is no LCA and we can exit early. 251 // previous root node, so there is no LCA and we can exit early.
247 *lca = NULL; 252 *out_lca = tree_->GetNull();
248 return true; 253 return true;
249 } else if (client_child->parent->id != id) { 254 } else if (client_child->parent->id != id) {
250 // If the client child's parent is not this node, update the LCA 255 // If the client child's parent is not this node, update the LCA
251 // and return true (reparenting was found). 256 // and return true (reparenting was found).
252 *lca = LeastCommonAncestor(*lca, client_child); 257 *out_lca = LeastCommonAncestor(*out_lca, client_child);
253 result = true; 258 result = true;
254 } else { 259 } else {
255 // This child is already in the client tree, we won't 260 // This child is already in the client tree, we won't
256 // recursively serialize it so we don't need to check this 261 // recursively serialize it so we don't need to check this
257 // subtree recursively for reparenting. 262 // subtree recursively for reparenting.
258 continue; 263 continue;
259 } 264 }
260 } 265 }
261 266
262 // This is a new child or reparented child, check it recursively. 267 // This is a new child or reparented child, check it recursively.
263 if (AnyDescendantWasReparented(child, lca)) 268 if (AnyDescendantWasReparented(child, out_lca))
264 result = true; 269 result = true;
265 } 270 }
266 return result; 271 return result;
267 } 272 }
268 273
269 template<class AXSourceNode> 274 template<typename AXSourceNode>
270 ClientTreeNode* AXTreeSerializer<AXSourceNode>::ClientTreeNodeById(int32 id) { 275 ClientTreeNode* AXTreeSerializer<AXSourceNode>::ClientTreeNodeById(int32 id) {
271 base::hash_map<int32, ClientTreeNode*>::iterator iter = 276 base::hash_map<int32, ClientTreeNode*>::iterator iter =
272 client_id_map_.find(id); 277 client_id_map_.find(id);
273 if (iter != client_id_map_.end()) 278 if (iter != client_id_map_.end())
274 return iter->second; 279 return iter->second;
275 else 280 else
276 return NULL; 281 return NULL;
277 } 282 }
278 283
279 template<class AXSourceNode> 284 template<typename AXSourceNode>
280 void AXTreeSerializer<AXSourceNode>::SerializeChanges( 285 void AXTreeSerializer<AXSourceNode>::SerializeChanges(
281 const AXSourceNode* node, 286 AXSourceNode node,
282 AXTreeUpdate* out_update) { 287 AXTreeUpdate* out_update) {
283 // If the node isn't in the client tree, we need to serialize starting 288 // If the node isn't in the client tree, we need to serialize starting
284 // with the LCA. 289 // with the LCA.
285 const AXSourceNode* lca = LeastCommonAncestor(node); 290 AXSourceNode lca = LeastCommonAncestor(node);
286 291
287 if (client_root_) { 292 if (client_root_) {
288 // If the LCA is anything other than the node itself, tell the 293 // If the LCA is anything other than the node itself, tell the
289 // client to first delete the subtree rooted at the LCA. 294 // client to first delete the subtree rooted at the LCA.
290 bool need_delete = (lca != node); 295 bool need_delete = !tree_->IsEqual(lca, node);
291 if (lca) { 296 if (tree_->IsValid(lca)) {
292 // Check for any reparenting within this subtree - if there is 297 // Check for any reparenting within this subtree - if there is
293 // any, we need to delete and reserialize the whole subtree 298 // any, we need to delete and reserialize the whole subtree
294 // that contains the old and new parents of the reparented node. 299 // that contains the old and new parents of the reparented node.
295 if (AnyDescendantWasReparented(lca, &lca)) 300 if (AnyDescendantWasReparented(lca, &lca))
296 need_delete = true; 301 need_delete = true;
297 } 302 }
298 303
299 if (lca == NULL) { 304 if (!tree_->IsValid(lca)) {
300 // If there's no LCA, just tell the client to destroy the whole 305 // If there's no LCA, just tell the client to destroy the whole
301 // tree and then we'll serialize everything from the new root. 306 // tree and then we'll serialize everything from the new root.
302 out_update->node_id_to_clear = client_root_->id; 307 out_update->node_id_to_clear = client_root_->id;
303 DeleteClientSubtree(client_root_); 308 DeleteClientSubtree(client_root_);
304 client_id_map_.erase(client_root_->id); 309 client_id_map_.erase(client_root_->id);
305 client_root_ = NULL; 310 client_root_ = NULL;
306 } else if (need_delete) { 311 } else if (need_delete) {
307 // Otherwise, if we need to reserialize a subtree, first we need 312 // Otherwise, if we need to reserialize a subtree, first we need
308 // to delete those nodes in our client tree so that 313 // to delete those nodes in our client tree so that
309 // SerializeChangedNodes() will be sure to send them again. 314 // SerializeChangedNodes() will be sure to send them again.
310 out_update->node_id_to_clear = tree_->GetId(lca); 315 out_update->node_id_to_clear = tree_->GetId(lca);
311 ClientTreeNode* client_lca = ClientTreeNodeById(tree_->GetId(lca)); 316 ClientTreeNode* client_lca = ClientTreeNodeById(tree_->GetId(lca));
312 CHECK(client_lca); 317 CHECK(client_lca);
313 for (size_t i = 0; i < client_lca->children.size(); ++i) { 318 for (size_t i = 0; i < client_lca->children.size(); ++i) {
314 client_id_map_.erase(client_lca->children[i]->id); 319 client_id_map_.erase(client_lca->children[i]->id);
315 DeleteClientSubtree(client_lca->children[i]); 320 DeleteClientSubtree(client_lca->children[i]);
316 } 321 }
317 client_lca->children.clear(); 322 client_lca->children.clear();
318 } 323 }
319 } 324 }
320 325
321 // Serialize from the LCA, or from the root if there isn't one. 326 // Serialize from the LCA, or from the root if there isn't one.
322 if (!lca) 327 if (!tree_->IsValid(lca))
323 lca = tree_->GetRoot(); 328 lca = tree_->GetRoot();
324 SerializeChangedNodes(lca, out_update); 329 SerializeChangedNodes(lca, out_update);
325 } 330 }
326 331
327 template<class AXSourceNode> 332 template<typename AXSourceNode>
333 void AXTreeSerializer<AXSourceNode>::DeleteClientSubtree(AXSourceNode node) {
334 ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node));
335 if (client_node)
336 DeleteClientSubtree(client_node);
337 }
338
339 template<typename AXSourceNode>
328 void AXTreeSerializer<AXSourceNode>::DeleteClientSubtree( 340 void AXTreeSerializer<AXSourceNode>::DeleteClientSubtree(
329 ClientTreeNode* client_node) { 341 ClientTreeNode* client_node) {
330 for (size_t i = 0; i < client_node->children.size(); ++i) { 342 for (size_t i = 0; i < client_node->children.size(); ++i) {
331 client_id_map_.erase(client_node->children[i]->id); 343 client_id_map_.erase(client_node->children[i]->id);
332 DeleteClientSubtree(client_node->children[i]); 344 DeleteClientSubtree(client_node->children[i]);
333 } 345 }
334 client_node->children.clear(); 346 client_node->children.clear();
335 } 347 }
336 348
337 template<class AXSourceNode> 349 template<typename AXSourceNode>
338 void AXTreeSerializer<AXSourceNode>::SerializeChangedNodes( 350 void AXTreeSerializer<AXSourceNode>::SerializeChangedNodes(
339 const AXSourceNode* node, 351 AXSourceNode node,
340 AXTreeUpdate* out_update) { 352 AXTreeUpdate* out_update) {
341 // This method has three responsibilities: 353 // This method has three responsibilities:
342 // 1. Serialize |node| into an AXNodeData, and append it to 354 // 1. Serialize |node| into an AXNodeData, and append it to
343 // the AXTreeUpdate to be sent to the client. 355 // the AXTreeUpdate to be sent to the client.
344 // 2. Determine if |node| has any new children that the client doesn't 356 // 2. Determine if |node| has any new children that the client doesn't
345 // know about yet, and call SerializeChangedNodes recursively on those. 357 // know about yet, and call SerializeChangedNodes recursively on those.
346 // 3. Update our internal data structure that keeps track of what nodes 358 // 3. Update our internal data structure that keeps track of what nodes
347 // the client knows about. 359 // the client knows about.
348 360
349 // First, find the ClientTreeNode for this id in our data structure where 361 // First, find the ClientTreeNode for this id in our data structure where
(...skipping 11 matching lines...) Expand all
361 client_node = client_root_; 373 client_node = client_root_;
362 client_node->id = id; 374 client_node->id = id;
363 client_node->parent = NULL; 375 client_node->parent = NULL;
364 client_id_map_[client_node->id] = client_node; 376 client_id_map_[client_node->id] = client_node;
365 } 377 }
366 378
367 // Iterate over the ids of the children of |node|. 379 // Iterate over the ids of the children of |node|.
368 // Create a set of the child ids so we can quickly look 380 // Create a set of the child ids so we can quickly look
369 // up which children are new and which ones were there before. 381 // up which children are new and which ones were there before.
370 base::hash_set<int32> new_child_ids; 382 base::hash_set<int32> new_child_ids;
371 int child_count = tree_->GetChildCount(node); 383 std::vector<AXSourceNode> children;
372 for (int i = 0; i < child_count; ++i) { 384 tree_->GetChildren(node, &children);
373 AXSourceNode* child = tree_->GetChildAtIndex(node, i); 385 for (size_t i = 0; i < children.size(); ++i) {
386 AXSourceNode& child = children[i];
374 int new_child_id = tree_->GetId(child); 387 int new_child_id = tree_->GetId(child);
375 new_child_ids.insert(new_child_id); 388 new_child_ids.insert(new_child_id);
376 389
377 // This is a sanity check - there shouldn't be any reparenting 390 // This is a sanity check - there shouldn't be any reparenting
378 // because we've already handled it above. 391 // because we've already handled it above.
379 ClientTreeNode* client_child = client_id_map_[new_child_id]; 392 ClientTreeNode* client_child = client_id_map_[new_child_id];
380 CHECK(!client_child || client_child->parent == client_node); 393 CHECK(!client_child || client_child->parent == client_node);
381 } 394 }
382 395
383 // Go through the old children and delete subtrees for child 396 // Go through the old children and delete subtrees for child
(...skipping 21 matching lines...) Expand all
405 out_update->nodes.push_back(AXNodeData()); 418 out_update->nodes.push_back(AXNodeData());
406 AXNodeData* serialized_node = &out_update->nodes.back(); 419 AXNodeData* serialized_node = &out_update->nodes.back();
407 tree_->SerializeNode(node, serialized_node); 420 tree_->SerializeNode(node, serialized_node);
408 if (serialized_node->id == client_root_->id) 421 if (serialized_node->id == client_root_->id)
409 serialized_node->role = AX_ROLE_ROOT_WEB_AREA; 422 serialized_node->role = AX_ROLE_ROOT_WEB_AREA;
410 serialized_node->child_ids.clear(); 423 serialized_node->child_ids.clear();
411 424
412 // Iterate over the children, make note of the ones that are new 425 // Iterate over the children, make note of the ones that are new
413 // and need to be serialized, and update the ClientTreeNode 426 // and need to be serialized, and update the ClientTreeNode
414 // data structure to reflect the new tree. 427 // data structure to reflect the new tree.
415 std::vector<AXSourceNode*> children_to_serialize; 428 std::vector<AXSourceNode> children_to_serialize;
416 client_node->children.reserve(child_count); 429 client_node->children.reserve(children.size());
417 for (int i = 0; i < child_count; ++i) { 430 for (size_t i = 0; i < children.size(); ++i) {
418 AXSourceNode* child = tree_->GetChildAtIndex(node, i); 431 AXSourceNode& child = children[i];
419 int child_id = tree_->GetId(child); 432 int child_id = tree_->GetId(child);
420 433
421 // No need to do anything more with children that aren't new; 434 // No need to do anything more with children that aren't new;
422 // the client will reuse its existing object. 435 // the client will reuse its existing object.
423 if (new_child_ids.find(child_id) == new_child_ids.end()) 436 if (new_child_ids.find(child_id) == new_child_ids.end())
424 continue; 437 continue;
425 438
426 new_child_ids.erase(child_id); 439 new_child_ids.erase(child_id);
427 serialized_node->child_ids.push_back(child_id); 440 serialized_node->child_ids.push_back(child_id);
428 if (client_child_id_map.find(child_id) != client_child_id_map.end()) { 441 if (client_child_id_map.find(child_id) != client_child_id_map.end()) {
(...skipping 10 matching lines...) Expand all
439 } 452 }
440 453
441 // Serialize all of the new children, recursively. 454 // Serialize all of the new children, recursively.
442 for (size_t i = 0; i < children_to_serialize.size(); ++i) 455 for (size_t i = 0; i < children_to_serialize.size(); ++i)
443 SerializeChangedNodes(children_to_serialize[i], out_update); 456 SerializeChangedNodes(children_to_serialize[i], out_update);
444 } 457 }
445 458
446 } // namespace ui 459 } // namespace ui
447 460
448 #endif // UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_ 461 #endif // UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_
OLDNEW
« no previous file with comments | « ui/accessibility/ax_tree.cc ('k') | ui/accessibility/ax_tree_serializer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698