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

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

Issue 125763003: Refactor content/renderer/accessibility to use AXTreeSerializer (re-land). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix memory leaks Created 6 years, 8 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
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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 client_root_(NULL) { 165 client_root_(NULL) {
166 } 166 }
167 167
168 template<typename AXSourceNode> 168 template<typename AXSourceNode>
169 AXTreeSerializer<AXSourceNode>::~AXTreeSerializer() { 169 AXTreeSerializer<AXSourceNode>::~AXTreeSerializer() {
170 Reset(); 170 Reset();
171 } 171 }
172 172
173 template<typename AXSourceNode> 173 template<typename AXSourceNode>
174 void AXTreeSerializer<AXSourceNode>::Reset() { 174 void AXTreeSerializer<AXSourceNode>::Reset() {
175 if (client_root_) { 175 if (!client_root_)
176 DeleteClientSubtree(client_root_); 176 return;
177 client_root_ = NULL; 177
178 } 178 DeleteClientSubtree(client_root_);
179 client_id_map_.erase(client_root_->id);
180 delete client_root_;
181 client_root_ = NULL;
179 } 182 }
180 183
181 template<typename AXSourceNode> 184 template<typename AXSourceNode>
182 void AXTreeSerializer<AXSourceNode>::ChangeTreeSourceForTesting( 185 void AXTreeSerializer<AXSourceNode>::ChangeTreeSourceForTesting(
183 AXTreeSource<AXSourceNode>* new_tree) { 186 AXTreeSource<AXSourceNode>* new_tree) {
184 tree_ = new_tree; 187 tree_ = new_tree;
185 } 188 }
186 189
187 template<typename AXSourceNode> 190 template<typename AXSourceNode>
188 AXSourceNode AXTreeSerializer<AXSourceNode>::LeastCommonAncestor( 191 AXSourceNode AXTreeSerializer<AXSourceNode>::LeastCommonAncestor(
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 // any, we need to delete and reserialize the whole subtree 301 // any, we need to delete and reserialize the whole subtree
299 // that contains the old and new parents of the reparented node. 302 // that contains the old and new parents of the reparented node.
300 if (AnyDescendantWasReparented(lca, &lca)) 303 if (AnyDescendantWasReparented(lca, &lca))
301 need_delete = true; 304 need_delete = true;
302 } 305 }
303 306
304 if (!tree_->IsValid(lca)) { 307 if (!tree_->IsValid(lca)) {
305 // If there's no LCA, just tell the client to destroy the whole 308 // If there's no LCA, just tell the client to destroy the whole
306 // tree and then we'll serialize everything from the new root. 309 // tree and then we'll serialize everything from the new root.
307 out_update->node_id_to_clear = client_root_->id; 310 out_update->node_id_to_clear = client_root_->id;
308 DeleteClientSubtree(client_root_); 311 Reset();
309 client_id_map_.erase(client_root_->id);
310 client_root_ = NULL;
311 } else if (need_delete) { 312 } else if (need_delete) {
312 // Otherwise, if we need to reserialize a subtree, first we need 313 // Otherwise, if we need to reserialize a subtree, first we need
313 // to delete those nodes in our client tree so that 314 // to delete those nodes in our client tree so that
314 // SerializeChangedNodes() will be sure to send them again. 315 // SerializeChangedNodes() will be sure to send them again.
315 out_update->node_id_to_clear = tree_->GetId(lca); 316 out_update->node_id_to_clear = tree_->GetId(lca);
316 ClientTreeNode* client_lca = ClientTreeNodeById(tree_->GetId(lca)); 317 ClientTreeNode* client_lca = ClientTreeNodeById(tree_->GetId(lca));
317 CHECK(client_lca); 318 CHECK(client_lca);
318 for (size_t i = 0; i < client_lca->children.size(); ++i) { 319 for (size_t i = 0; i < client_lca->children.size(); ++i) {
319 client_id_map_.erase(client_lca->children[i]->id); 320 client_id_map_.erase(client_lca->children[i]->id);
320 DeleteClientSubtree(client_lca->children[i]); 321 DeleteClientSubtree(client_lca->children[i]);
322 delete client_lca->children[i];
321 } 323 }
322 client_lca->children.clear(); 324 client_lca->children.clear();
323 } 325 }
324 } 326 }
325 327
326 // Serialize from the LCA, or from the root if there isn't one. 328 // Serialize from the LCA, or from the root if there isn't one.
327 if (!tree_->IsValid(lca)) 329 if (!tree_->IsValid(lca))
328 lca = tree_->GetRoot(); 330 lca = tree_->GetRoot();
329 SerializeChangedNodes(lca, out_update); 331 SerializeChangedNodes(lca, out_update);
330 } 332 }
331 333
332 template<typename AXSourceNode> 334 template<typename AXSourceNode>
333 void AXTreeSerializer<AXSourceNode>::DeleteClientSubtree(AXSourceNode node) { 335 void AXTreeSerializer<AXSourceNode>::DeleteClientSubtree(AXSourceNode node) {
334 ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node)); 336 ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node));
335 if (client_node) 337 if (client_node)
336 DeleteClientSubtree(client_node); 338 DeleteClientSubtree(client_node);
337 } 339 }
338 340
339 template<typename AXSourceNode> 341 template<typename AXSourceNode>
340 void AXTreeSerializer<AXSourceNode>::DeleteClientSubtree( 342 void AXTreeSerializer<AXSourceNode>::DeleteClientSubtree(
341 ClientTreeNode* client_node) { 343 ClientTreeNode* client_node) {
342 for (size_t i = 0; i < client_node->children.size(); ++i) { 344 for (size_t i = 0; i < client_node->children.size(); ++i) {
343 client_id_map_.erase(client_node->children[i]->id); 345 client_id_map_.erase(client_node->children[i]->id);
344 DeleteClientSubtree(client_node->children[i]); 346 DeleteClientSubtree(client_node->children[i]);
347 delete client_node->children[i];
345 } 348 }
346 client_node->children.clear(); 349 client_node->children.clear();
347 } 350 }
348 351
349 template<typename AXSourceNode> 352 template<typename AXSourceNode>
350 void AXTreeSerializer<AXSourceNode>::SerializeChangedNodes( 353 void AXTreeSerializer<AXSourceNode>::SerializeChangedNodes(
351 AXSourceNode node, 354 AXSourceNode node,
352 AXTreeUpdate* out_update) { 355 AXTreeUpdate* out_update) {
353 // This method has three responsibilities: 356 // This method has three responsibilities:
354 // 1. Serialize |node| into an AXNodeData, and append it to 357 // 1. Serialize |node| into an AXNodeData, and append it to
355 // the AXTreeUpdate to be sent to the client. 358 // the AXTreeUpdate to be sent to the client.
356 // 2. Determine if |node| has any new children that the client doesn't 359 // 2. Determine if |node| has any new children that the client doesn't
357 // know about yet, and call SerializeChangedNodes recursively on those. 360 // know about yet, and call SerializeChangedNodes recursively on those.
358 // 3. Update our internal data structure that keeps track of what nodes 361 // 3. Update our internal data structure that keeps track of what nodes
359 // the client knows about. 362 // the client knows about.
360 363
361 // First, find the ClientTreeNode for this id in our data structure where 364 // First, find the ClientTreeNode for this id in our data structure where
362 // we keep track of what accessibility objects the client already knows 365 // we keep track of what accessibility objects the client already knows
363 // about. If we don't find it, then this must be the new root of the 366 // about. If we don't find it, then this must be the new root of the
364 // accessibility tree. 367 // accessibility tree.
365 int id = tree_->GetId(node); 368 int id = tree_->GetId(node);
366 ClientTreeNode* client_node = ClientTreeNodeById(id); 369 ClientTreeNode* client_node = ClientTreeNodeById(id);
367 if (!client_node) { 370 if (!client_node) {
368 if (client_root_) { 371 Reset();
369 client_id_map_.erase(client_root_->id);
370 DeleteClientSubtree(client_root_);
371 }
372 client_root_ = new ClientTreeNode(); 372 client_root_ = new ClientTreeNode();
373 client_node = client_root_; 373 client_node = client_root_;
374 client_node->id = id; 374 client_node->id = id;
375 client_node->parent = NULL; 375 client_node->parent = NULL;
376 client_id_map_[client_node->id] = client_node; 376 client_id_map_[client_node->id] = client_node;
377 } 377 }
378 378
379 // Iterate over the ids of the children of |node|. 379 // Iterate over the ids of the children of |node|.
380 // 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
381 // up which children are new and which ones were there before. 381 // up which children are new and which ones were there before.
(...skipping 19 matching lines...) Expand all
401 // of an update, which can lead to a double-free. 401 // of an update, which can lead to a double-free.
402 base::hash_map<int32, ClientTreeNode*> client_child_id_map; 402 base::hash_map<int32, ClientTreeNode*> client_child_id_map;
403 std::vector<ClientTreeNode*> old_children; 403 std::vector<ClientTreeNode*> old_children;
404 old_children.swap(client_node->children); 404 old_children.swap(client_node->children);
405 for (size_t i = 0; i < old_children.size(); ++i) { 405 for (size_t i = 0; i < old_children.size(); ++i) {
406 ClientTreeNode* old_child = old_children[i]; 406 ClientTreeNode* old_child = old_children[i];
407 int old_child_id = old_child->id; 407 int old_child_id = old_child->id;
408 if (new_child_ids.find(old_child_id) == new_child_ids.end()) { 408 if (new_child_ids.find(old_child_id) == new_child_ids.end()) {
409 client_id_map_.erase(old_child_id); 409 client_id_map_.erase(old_child_id);
410 DeleteClientSubtree(old_child); 410 DeleteClientSubtree(old_child);
411 delete old_child;
411 } else { 412 } else {
412 client_child_id_map[old_child_id] = old_child; 413 client_child_id_map[old_child_id] = old_child;
413 } 414 }
414 } 415 }
415 416
416 // Serialize this node. This fills in all of the fields in 417 // Serialize this node. This fills in all of the fields in
417 // AXNodeData except child_ids, which we handle below. 418 // AXNodeData except child_ids, which we handle below.
418 out_update->nodes.push_back(AXNodeData()); 419 out_update->nodes.push_back(AXNodeData());
419 AXNodeData* serialized_node = &out_update->nodes.back(); 420 AXNodeData* serialized_node = &out_update->nodes.back();
420 tree_->SerializeNode(node, serialized_node); 421 tree_->SerializeNode(node, serialized_node);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 } 453 }
453 454
454 // Serialize all of the new children, recursively. 455 // Serialize all of the new children, recursively.
455 for (size_t i = 0; i < children_to_serialize.size(); ++i) 456 for (size_t i = 0; i < children_to_serialize.size(); ++i)
456 SerializeChangedNodes(children_to_serialize[i], out_update); 457 SerializeChangedNodes(children_to_serialize[i], out_update);
457 } 458 }
458 459
459 } // namespace ui 460 } // namespace ui
460 461
461 #endif // UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_ 462 #endif // UI_ACCESSIBILITY_AX_TREE_SERIALIZER_H_
OLDNEW
« no previous file with comments | « content/renderer/accessibility/renderer_accessibility_focus_only.cc ('k') | ui/accessibility/ax_tree_source.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698