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 #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 13 matching lines...) Expand all Loading... |
24 // AXTree. An AXTreeSerializer keeps track of the tree of node ids that its | 24 // AXTree. An AXTreeSerializer keeps track of the tree of node ids that its |
25 // client is aware of so that it will never generate an AXTreeUpdate that | 25 // client is aware of so that it will never generate an AXTreeUpdate that |
26 // results in an invalid tree. | 26 // results in an invalid tree. |
27 // | 27 // |
28 // Every node in the source tree must have an id that's a unique positive | 28 // Every node in the source tree must have an id that's a unique positive |
29 // integer, the same node must not appear twice. | 29 // integer, the same node must not appear twice. |
30 // | 30 // |
31 // Usage: | 31 // Usage: |
32 // | 32 // |
33 // You must call SerializeChanges() every time a node in the tree changes, | 33 // You must call SerializeChanges() every time a node in the tree changes, |
34 // and send the generated AXTreeUpdate to the client. | 34 // and send the generated AXTreeUpdate to the client. Changes to the |
| 35 // AXTreeData, if any, are also automatically included in the AXTreeUpdate. |
35 // | 36 // |
36 // If a node is added, call SerializeChanges on its parent. | 37 // If a node is added, call SerializeChanges on its parent. |
37 // If a node is removed, call SerializeChanges on its parent. | 38 // If a node is removed, call SerializeChanges on its parent. |
38 // If a whole new subtree is added, just call SerializeChanges on its root. | 39 // If a whole new subtree is added, just call SerializeChanges on its root. |
39 // If the root of the tree changes, call SerializeChanges on the new root. | 40 // If the root of the tree changes, call SerializeChanges on the new root. |
40 // | 41 // |
41 // AXTreeSerializer will avoid re-serializing nodes that do not change. | 42 // AXTreeSerializer will avoid re-serializing nodes that do not change. |
42 // For example, if node 1 has children 2, 3, 4, 5 and then child 2 is | 43 // For example, if node 1 has children 2, 3, 4, 5 and then child 2 is |
43 // removed and a new child 6 is added, the AXTreeSerializer will only | 44 // removed and a new child 6 is added, the AXTreeSerializer will only |
44 // update nodes 1 and 6 (and any children of node 6 recursively). It will | 45 // update nodes 1 and 6 (and any children of node 6 recursively). It will |
45 // assume that nodes 3, 4, and 5 are not modified unless you explicitly | 46 // assume that nodes 3, 4, and 5 are not modified unless you explicitly |
46 // call SerializeChanges() on them. | 47 // call SerializeChanges() on them. |
47 // | 48 // |
48 // As long as the source tree has unique ids for every node and no loops, | 49 // As long as the source tree has unique ids for every node and no loops, |
49 // and as long as every update is applied to the client tree, AXTreeSerializer | 50 // and as long as every update is applied to the client tree, AXTreeSerializer |
50 // will continue to work. If the source tree makes a change but fails to | 51 // will continue to work. If the source tree makes a change but fails to |
51 // call SerializeChanges properly, the trees may get out of sync - but | 52 // call SerializeChanges properly, the trees may get out of sync - but |
52 // because AXTreeSerializer always keeps track of what updates it's sent, | 53 // because AXTreeSerializer always keeps track of what updates it's sent, |
53 // it will never send an invalid update and the client tree will not break, | 54 // it will never send an invalid update and the client tree will not break, |
54 // it just may not contain all of the changes. | 55 // it just may not contain all of the changes. |
55 template<typename AXSourceNode, typename AXNodeData> | 56 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
56 class AXTreeSerializer { | 57 class AXTreeSerializer { |
57 public: | 58 public: |
58 explicit AXTreeSerializer(AXTreeSource<AXSourceNode, AXNodeData>* tree); | 59 explicit AXTreeSerializer( |
| 60 AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* tree); |
59 ~AXTreeSerializer(); | 61 ~AXTreeSerializer(); |
60 | 62 |
61 // Throw out the internal state that keeps track of the nodes the client | 63 // Throw out the internal state that keeps track of the nodes the client |
62 // knows about. This has the effect that the next update will send the | 64 // knows about. This has the effect that the next update will send the |
63 // entire tree over because it assumes the client knows nothing. | 65 // entire tree over because it assumes the client knows nothing. |
64 void Reset(); | 66 void Reset(); |
65 | 67 |
66 // Sets the maximum number of nodes that will be serialized, or zero | 68 // Sets the maximum number of nodes that will be serialized, or zero |
67 // for no maximum. This is not a hard maximum - once it hits or | 69 // for no maximum. This is not a hard maximum - once it hits or |
68 // exceeds this maximum it stops walking the children of nodes, but | 70 // exceeds this maximum it stops walking the children of nodes, but |
69 // it may exceed this value a bit in order to create a consistent | 71 // it may exceed this value a bit in order to create a consistent |
70 // tree. | 72 // tree. |
71 void set_max_node_count(size_t max_node_count) { | 73 void set_max_node_count(size_t max_node_count) { |
72 max_node_count_ = max_node_count; | 74 max_node_count_ = max_node_count; |
73 } | 75 } |
74 | 76 |
75 // Serialize all changes to |node| and append them to |out_update|. | 77 // Serialize all changes to |node| and append them to |out_update|. |
76 void SerializeChanges(AXSourceNode node, | 78 void SerializeChanges(AXSourceNode node, |
77 AXTreeUpdate<AXNodeData>* out_update); | 79 AXTreeUpdateBase<AXNodeData, AXTreeData>* out_update); |
78 | 80 |
79 // Delete the client subtree for this node, ensuring that the subtree | 81 // Delete the client subtree for this node, ensuring that the subtree |
80 // is re-serialized. | 82 // is re-serialized. |
81 void DeleteClientSubtree(AXSourceNode node); | 83 void DeleteClientSubtree(AXSourceNode node); |
82 | 84 |
83 // Only for unit testing. Normally this class relies on getting a call | 85 // Only for unit testing. Normally this class relies on getting a call |
84 // to SerializeChanges() every time the source tree changes. For unit | 86 // to SerializeChanges() every time the source tree changes. For unit |
85 // testing, it's convenient to create a static AXTree for the initial | 87 // testing, it's convenient to create a static AXTree for the initial |
86 // state and then call ChangeTreeSourceForTesting and then SerializeChanges | 88 // state and then call ChangeTreeSourceForTesting and then SerializeChanges |
87 // to simulate the changes you'd get if a tree changed from the initial | 89 // to simulate the changes you'd get if a tree changed from the initial |
88 // state to the second tree's state. | 90 // state to the second tree's state. |
89 void ChangeTreeSourceForTesting( | 91 void ChangeTreeSourceForTesting( |
90 AXTreeSource<AXSourceNode, AXNodeData>* new_tree); | 92 AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* new_tree); |
91 | 93 |
92 private: | 94 private: |
93 // Return the least common ancestor of a node in the source tree | 95 // Return the least common ancestor of a node in the source tree |
94 // and a node in the client tree, or NULL if there is no such node. | 96 // and a node in the client tree, or NULL if there is no such node. |
95 // The least common ancestor is the closest ancestor to |node| (which | 97 // The least common ancestor is the closest ancestor to |node| (which |
96 // may be |node| itself) that's in both the source tree and client tree, | 98 // may be |node| itself) that's in both the source tree and client tree, |
97 // and for which both the source and client tree agree on their ancestor | 99 // and for which both the source and client tree agree on their ancestor |
98 // chain up to the root. | 100 // chain up to the root. |
99 // | 101 // |
100 // Example 1: | 102 // Example 1: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 bool AnyDescendantWasReparented(AXSourceNode node, | 140 bool AnyDescendantWasReparented(AXSourceNode node, |
139 AXSourceNode* out_lca); | 141 AXSourceNode* out_lca); |
140 | 142 |
141 ClientTreeNode* ClientTreeNodeById(int32 id); | 143 ClientTreeNode* ClientTreeNodeById(int32 id); |
142 | 144 |
143 // Delete the given client tree node and recursively delete all of its | 145 // Delete the given client tree node and recursively delete all of its |
144 // descendants. | 146 // descendants. |
145 void DeleteClientSubtree(ClientTreeNode* client_node); | 147 void DeleteClientSubtree(ClientTreeNode* client_node); |
146 | 148 |
147 // Helper function, called recursively with each new node to serialize. | 149 // Helper function, called recursively with each new node to serialize. |
148 void SerializeChangedNodes(AXSourceNode node, | 150 void SerializeChangedNodes( |
149 AXTreeUpdate<AXNodeData>* out_update); | 151 AXSourceNode node, |
| 152 AXTreeUpdateBase<AXNodeData, AXTreeData>* out_update); |
150 | 153 |
151 // Visit all of the descendants of |node| once. | 154 // Visit all of the descendants of |node| once. |
152 void WalkAllDescendants(AXSourceNode node); | 155 void WalkAllDescendants(AXSourceNode node); |
153 | 156 |
154 // The tree source. | 157 // The tree source. |
155 AXTreeSource<AXSourceNode, AXNodeData>* tree_; | 158 AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* tree_; |
| 159 |
| 160 // The tree data most recently sent to the client. |
| 161 AXTreeData client_tree_data_; |
156 | 162 |
157 // Our representation of the client tree. | 163 // Our representation of the client tree. |
158 ClientTreeNode* client_root_; | 164 ClientTreeNode* client_root_; |
159 | 165 |
160 // A map from IDs to nodes in the client tree. | 166 // A map from IDs to nodes in the client tree. |
161 base::hash_map<int32, ClientTreeNode*> client_id_map_; | 167 base::hash_map<int32, ClientTreeNode*> client_id_map_; |
162 | 168 |
163 // The maximum number of nodes to serialize in a given call to | 169 // The maximum number of nodes to serialize in a given call to |
164 // SerializeChanges, or 0 if there's no maximum. | 170 // SerializeChanges, or 0 if there's no maximum. |
165 size_t max_node_count_; | 171 size_t max_node_count_; |
166 }; | 172 }; |
167 | 173 |
168 // In order to keep track of what nodes the client knows about, we keep a | 174 // In order to keep track of what nodes the client knows about, we keep a |
169 // representation of the client tree - just IDs and parent/child | 175 // representation of the client tree - just IDs and parent/child |
170 // relationships. | 176 // relationships. |
171 struct AX_EXPORT ClientTreeNode { | 177 struct AX_EXPORT ClientTreeNode { |
172 ClientTreeNode(); | 178 ClientTreeNode(); |
173 virtual ~ClientTreeNode(); | 179 virtual ~ClientTreeNode(); |
174 int32 id; | 180 int32 id; |
175 ClientTreeNode* parent; | 181 ClientTreeNode* parent; |
176 std::vector<ClientTreeNode*> children; | 182 std::vector<ClientTreeNode*> children; |
177 }; | 183 }; |
178 | 184 |
179 template<typename AXSourceNode, typename AXNodeData> | 185 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
180 AXTreeSerializer<AXSourceNode, AXNodeData>::AXTreeSerializer( | 186 AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::AXTreeSerializer( |
181 AXTreeSource<AXSourceNode, AXNodeData>* tree) | 187 AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* tree) |
182 : tree_(tree), | 188 : tree_(tree), client_root_(NULL), max_node_count_(0) {} |
183 client_root_(NULL), | |
184 max_node_count_(0) { | |
185 } | |
186 | 189 |
187 template<typename AXSourceNode, typename AXNodeData> | 190 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
188 AXTreeSerializer<AXSourceNode, AXNodeData>::~AXTreeSerializer() { | 191 AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::~AXTreeSerializer() { |
189 Reset(); | 192 Reset(); |
190 } | 193 } |
191 | 194 |
192 template<typename AXSourceNode, typename AXNodeData> | 195 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
193 void AXTreeSerializer<AXSourceNode, AXNodeData>::Reset() { | 196 void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::Reset() { |
| 197 client_tree_data_ = AXTreeData(); |
194 if (!client_root_) | 198 if (!client_root_) |
195 return; | 199 return; |
196 | 200 |
197 DeleteClientSubtree(client_root_); | 201 DeleteClientSubtree(client_root_); |
198 client_id_map_.erase(client_root_->id); | 202 client_id_map_.erase(client_root_->id); |
199 delete client_root_; | 203 delete client_root_; |
200 client_root_ = NULL; | 204 client_root_ = NULL; |
201 } | 205 } |
202 | 206 |
203 template<typename AXSourceNode, typename AXNodeData> | 207 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
204 void AXTreeSerializer<AXSourceNode, AXNodeData>::ChangeTreeSourceForTesting( | 208 void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>:: |
205 AXTreeSource<AXSourceNode, AXNodeData>* new_tree) { | 209 ChangeTreeSourceForTesting( |
| 210 AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* new_tree) { |
206 tree_ = new_tree; | 211 tree_ = new_tree; |
207 } | 212 } |
208 | 213 |
209 template<typename AXSourceNode, typename AXNodeData> | 214 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
210 AXSourceNode AXTreeSerializer<AXSourceNode, AXNodeData>::LeastCommonAncestor( | 215 AXSourceNode |
211 AXSourceNode node, ClientTreeNode* client_node) { | 216 AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::LeastCommonAncestor( |
| 217 AXSourceNode node, |
| 218 ClientTreeNode* client_node) { |
212 if (!tree_->IsValid(node) || client_node == NULL) | 219 if (!tree_->IsValid(node) || client_node == NULL) |
213 return tree_->GetNull(); | 220 return tree_->GetNull(); |
214 | 221 |
215 std::vector<AXSourceNode> ancestors; | 222 std::vector<AXSourceNode> ancestors; |
216 while (tree_->IsValid(node)) { | 223 while (tree_->IsValid(node)) { |
217 ancestors.push_back(node); | 224 ancestors.push_back(node); |
218 node = tree_->GetParent(node); | 225 node = tree_->GetParent(node); |
219 } | 226 } |
220 | 227 |
221 std::vector<ClientTreeNode*> client_ancestors; | 228 std::vector<ClientTreeNode*> client_ancestors; |
(...skipping 13 matching lines...) Expand all Loading... |
235 client_ancestors[client_index]->id) { | 242 client_ancestors[client_index]->id) { |
236 return lca; | 243 return lca; |
237 } | 244 } |
238 lca = ancestors[source_index]; | 245 lca = ancestors[source_index]; |
239 source_index--; | 246 source_index--; |
240 client_index--; | 247 client_index--; |
241 } | 248 } |
242 return lca; | 249 return lca; |
243 } | 250 } |
244 | 251 |
245 template<typename AXSourceNode, typename AXNodeData> | 252 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
246 AXSourceNode AXTreeSerializer<AXSourceNode, AXNodeData>::LeastCommonAncestor( | 253 AXSourceNode |
| 254 AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::LeastCommonAncestor( |
247 AXSourceNode node) { | 255 AXSourceNode node) { |
248 // Walk up the tree until the source node's id also exists in the | 256 // Walk up the tree until the source node's id also exists in the |
249 // client tree, then call LeastCommonAncestor on those two nodes. | 257 // client tree, then call LeastCommonAncestor on those two nodes. |
250 ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node)); | 258 ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node)); |
251 while (tree_->IsValid(node) && !client_node) { | 259 while (tree_->IsValid(node) && !client_node) { |
252 node = tree_->GetParent(node); | 260 node = tree_->GetParent(node); |
253 if (tree_->IsValid(node)) | 261 if (tree_->IsValid(node)) |
254 client_node = ClientTreeNodeById(tree_->GetId(node)); | 262 client_node = ClientTreeNodeById(tree_->GetId(node)); |
255 } | 263 } |
256 return LeastCommonAncestor(node, client_node); | 264 return LeastCommonAncestor(node, client_node); |
257 } | 265 } |
258 | 266 |
259 template<typename AXSourceNode, typename AXNodeData> | 267 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
260 bool AXTreeSerializer<AXSourceNode, AXNodeData>::AnyDescendantWasReparented( | 268 bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>:: |
261 AXSourceNode node, AXSourceNode* out_lca) { | 269 AnyDescendantWasReparented(AXSourceNode node, AXSourceNode* out_lca) { |
262 bool result = false; | 270 bool result = false; |
263 int id = tree_->GetId(node); | 271 int id = tree_->GetId(node); |
264 std::vector<AXSourceNode> children; | 272 std::vector<AXSourceNode> children; |
265 tree_->GetChildren(node, &children); | 273 tree_->GetChildren(node, &children); |
266 for (size_t i = 0; i < children.size(); ++i) { | 274 for (size_t i = 0; i < children.size(); ++i) { |
267 AXSourceNode& child = children[i]; | 275 AXSourceNode& child = children[i]; |
268 int child_id = tree_->GetId(child); | 276 int child_id = tree_->GetId(child); |
269 ClientTreeNode* client_child = ClientTreeNodeById(child_id); | 277 ClientTreeNode* client_child = ClientTreeNodeById(child_id); |
270 if (client_child) { | 278 if (client_child) { |
271 if (!client_child->parent) { | 279 if (!client_child->parent) { |
(...skipping 14 matching lines...) Expand all Loading... |
286 } | 294 } |
287 } | 295 } |
288 | 296 |
289 // This is a new child or reparented child, check it recursively. | 297 // This is a new child or reparented child, check it recursively. |
290 if (AnyDescendantWasReparented(child, out_lca)) | 298 if (AnyDescendantWasReparented(child, out_lca)) |
291 result = true; | 299 result = true; |
292 } | 300 } |
293 return result; | 301 return result; |
294 } | 302 } |
295 | 303 |
296 template<typename AXSourceNode, typename AXNodeData> | 304 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
297 ClientTreeNode* | 305 ClientTreeNode* |
298 AXTreeSerializer<AXSourceNode, AXNodeData>::ClientTreeNodeById(int32 id) { | 306 AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::ClientTreeNodeById( |
| 307 int32 id) { |
299 base::hash_map<int32, ClientTreeNode*>::iterator iter = | 308 base::hash_map<int32, ClientTreeNode*>::iterator iter = |
300 client_id_map_.find(id); | 309 client_id_map_.find(id); |
301 if (iter != client_id_map_.end()) | 310 if (iter != client_id_map_.end()) |
302 return iter->second; | 311 return iter->second; |
303 else | 312 else |
304 return NULL; | 313 return NULL; |
305 } | 314 } |
306 | 315 |
307 template<typename AXSourceNode, typename AXNodeData> | 316 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
308 void AXTreeSerializer<AXSourceNode, AXNodeData>::SerializeChanges( | 317 void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::SerializeChanges( |
309 AXSourceNode node, | 318 AXSourceNode node, |
310 AXTreeUpdate<AXNodeData>* out_update) { | 319 AXTreeUpdateBase<AXNodeData, AXTreeData>* out_update) { |
| 320 // Send the tree data if it's changed since the last update. |
| 321 AXTreeData new_tree_data = tree_->GetTreeData(); |
| 322 if (new_tree_data != client_tree_data_) { |
| 323 out_update->has_tree_data = true; |
| 324 out_update->tree_data = new_tree_data; |
| 325 client_tree_data_ = new_tree_data; |
| 326 } |
| 327 |
311 // If the node isn't in the client tree, we need to serialize starting | 328 // If the node isn't in the client tree, we need to serialize starting |
312 // with the LCA. | 329 // with the LCA. |
313 AXSourceNode lca = LeastCommonAncestor(node); | 330 AXSourceNode lca = LeastCommonAncestor(node); |
314 | 331 |
315 // This loop computes the least common ancestor that includes the old | 332 // This loop computes the least common ancestor that includes the old |
316 // and new parents of any nodes that have been reparented, and clears the | 333 // and new parents of any nodes that have been reparented, and clears the |
317 // whole client subtree of that LCA if necessary. If we do end up clearing | 334 // whole client subtree of that LCA if necessary. If we do end up clearing |
318 // any client nodes, keep looping because we have to search for more | 335 // any client nodes, keep looping because we have to search for more |
319 // nodes that may have been reparented from this new LCA. | 336 // nodes that may have been reparented from this new LCA. |
320 bool need_delete; | 337 bool need_delete; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 | 369 |
353 // Work around flaky source trees where nodes don't figure out their | 370 // Work around flaky source trees where nodes don't figure out their |
354 // correct parent/child relationships until you walk the whole tree once. | 371 // correct parent/child relationships until you walk the whole tree once. |
355 // Covered by this test in the content_browsertests suite: | 372 // Covered by this test in the content_browsertests suite: |
356 // DumpAccessibilityTreeTest.AccessibilityAriaOwns. | 373 // DumpAccessibilityTreeTest.AccessibilityAriaOwns. |
357 WalkAllDescendants(lca); | 374 WalkAllDescendants(lca); |
358 | 375 |
359 SerializeChangedNodes(lca, out_update); | 376 SerializeChangedNodes(lca, out_update); |
360 } | 377 } |
361 | 378 |
362 template<typename AXSourceNode, typename AXNodeData> | 379 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
363 void AXTreeSerializer<AXSourceNode, AXNodeData>::DeleteClientSubtree( | 380 void AXTreeSerializer<AXSourceNode, |
364 AXSourceNode node) { | 381 AXNodeData, |
| 382 AXTreeData>::DeleteClientSubtree(AXSourceNode node) { |
365 ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node)); | 383 ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node)); |
366 if (client_node) | 384 if (client_node) |
367 DeleteClientSubtree(client_node); | 385 DeleteClientSubtree(client_node); |
368 } | 386 } |
369 | 387 |
370 template<typename AXSourceNode, typename AXNodeData> | 388 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
371 void AXTreeSerializer<AXSourceNode, AXNodeData>::DeleteClientSubtree( | 389 void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>:: |
372 ClientTreeNode* client_node) { | 390 DeleteClientSubtree(ClientTreeNode* client_node) { |
373 for (size_t i = 0; i < client_node->children.size(); ++i) { | 391 for (size_t i = 0; i < client_node->children.size(); ++i) { |
374 client_id_map_.erase(client_node->children[i]->id); | 392 client_id_map_.erase(client_node->children[i]->id); |
375 DeleteClientSubtree(client_node->children[i]); | 393 DeleteClientSubtree(client_node->children[i]); |
376 delete client_node->children[i]; | 394 delete client_node->children[i]; |
377 } | 395 } |
378 client_node->children.clear(); | 396 client_node->children.clear(); |
379 } | 397 } |
380 | 398 |
381 template<typename AXSourceNode, typename AXNodeData> | 399 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
382 void AXTreeSerializer<AXSourceNode, AXNodeData>::SerializeChangedNodes( | 400 void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>:: |
383 AXSourceNode node, | 401 SerializeChangedNodes( |
384 AXTreeUpdate<AXNodeData>* out_update) { | 402 AXSourceNode node, |
| 403 AXTreeUpdateBase<AXNodeData, AXTreeData>* out_update) { |
385 // This method has three responsibilities: | 404 // This method has three responsibilities: |
386 // 1. Serialize |node| into an AXNodeData, and append it to | 405 // 1. Serialize |node| into an AXNodeData, and append it to |
387 // the AXTreeUpdate to be sent to the client. | 406 // the AXTreeUpdate to be sent to the client. |
388 // 2. Determine if |node| has any new children that the client doesn't | 407 // 2. Determine if |node| has any new children that the client doesn't |
389 // know about yet, and call SerializeChangedNodes recursively on those. | 408 // know about yet, and call SerializeChangedNodes recursively on those. |
390 // 3. Update our internal data structure that keeps track of what nodes | 409 // 3. Update our internal data structure that keeps track of what nodes |
391 // the client knows about. | 410 // the client knows about. |
392 | 411 |
393 // First, find the ClientTreeNode for this id in our data structure where | 412 // First, find the ClientTreeNode for this id in our data structure where |
394 // we keep track of what accessibility objects the client already knows | 413 // we keep track of what accessibility objects the client already knows |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 SerializeChangedNodes(child, out_update); | 521 SerializeChangedNodes(child, out_update); |
503 } | 522 } |
504 } | 523 } |
505 | 524 |
506 // Finally, update the child ids of this node to reflect the actual child | 525 // Finally, update the child ids of this node to reflect the actual child |
507 // ids that were valid during serialization. | 526 // ids that were valid during serialization. |
508 out_update->nodes[serialized_node_index].child_ids.swap( | 527 out_update->nodes[serialized_node_index].child_ids.swap( |
509 actual_serialized_node_child_ids); | 528 actual_serialized_node_child_ids); |
510 } | 529 } |
511 | 530 |
512 template<typename AXSourceNode, typename AXNodeData> | 531 template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> |
513 void AXTreeSerializer<AXSourceNode, AXNodeData>::WalkAllDescendants( | 532 void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::WalkAllDescendants( |
514 AXSourceNode node) { | 533 AXSourceNode node) { |
515 std::vector<AXSourceNode> children; | 534 std::vector<AXSourceNode> children; |
516 tree_->GetChildren(node, &children); | 535 tree_->GetChildren(node, &children); |
517 for (size_t i = 0; i < children.size(); ++i) | 536 for (size_t i = 0; i < children.size(); ++i) |
518 WalkAllDescendants(children[i]); | 537 WalkAllDescendants(children[i]); |
519 } | 538 } |
520 | 539 |
521 } // namespace ui | 540 } // namespace ui |
522 | 541 |
523 #endif // UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_ | 542 #endif // UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_ |
OLD | NEW |