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
3 // found in the LICENSE file.
5 #ifndef UI_ACCESSIBILITY_AX_TREE_H_
6 #define UI_ACCESSIBILITY_AX_TREE_H_
10 #include "base/containers/hash_tables.h"
11 #include "ui/accessibility/ax_export.h"
12 #include "ui/accessibility/ax_tree_update.h"
18 struct AXTreeUpdateState
;
20 // Used when you want to be notified when changes happen to the tree.
22 // Some of the notifications are called in the middle of an update operation.
23 // Be careful, as the tree may be in an inconsistent state at this time;
24 // don't walk the parents and children at this time:
25 // OnNodeWillBeDeleted
26 // OnSubtreeWillBeDeleted
30 // In addition, one additional notification is fired at the end of an
31 // atomic update, and it provides a vector of nodes that were added or
32 // changed, for final postprocessing:
33 // OnAtomicUpdateFinished
35 class AX_EXPORT AXTreeDelegate
{
38 virtual ~AXTreeDelegate();
40 // Called just before a node is deleted. Its id and data will be valid,
41 // but its links to parents and children are invalid. This is called
42 // in the middle of an update, the tree may be in an invalid state!
43 virtual void OnNodeWillBeDeleted(AXTree
* tree
, AXNode
* node
) = 0;
45 // Same as OnNodeWillBeDeleted, but only called once for an entire subtree.
46 // This is called in the middle of an update, the tree may be in an
48 virtual void OnSubtreeWillBeDeleted(AXTree
* tree
, AXNode
* node
) = 0;
50 // Called immediately after a new node is created. The tree may be in
51 // the middle of an update, don't walk the parents and children now.
52 virtual void OnNodeCreated(AXTree
* tree
, AXNode
* node
) = 0;
54 // Called when a node changes its data or children. The tree may be in
55 // the middle of an update, don't walk the parents and children now.
56 virtual void OnNodeChanged(AXTree
* tree
, AXNode
* node
) = 0;
65 Change(AXNode
* node
, ChangeType type
) {
73 // Called at the end of the update operation. Every node that was added
74 // or changed will be included in |changes|, along with an enum indicating
75 // the type of change - either (1) a node was created, (2) a node was created
76 // and it's the root of a new subtree, or (3) a node was changed. Finally,
77 // a bool indicates if the root of the tree was changed or not.
78 virtual void OnAtomicUpdateFinished(AXTree
* tree
,
80 const std::vector
<Change
>& changes
) = 0;
83 // AXTree is a live, managed tree of AXNode objects that can receive
84 // updates from another AXTreeSource via AXTreeUpdates, and it can be
85 // used as a source for sending updates to another client tree.
86 // It's designed to be subclassed to implement support for native
87 // accessibility APIs on a specific platform.
88 class AX_EXPORT AXTree
{
91 explicit AXTree(const AXTreeUpdate
& initial_state
);
94 virtual void SetDelegate(AXTreeDelegate
* delegate
);
96 AXNode
* root() const { return root_
; }
98 // Returns the AXNode with the given |id| if it is part of this AXTree.
99 AXNode
* GetFromId(int32 id
) const;
101 // Returns true on success. If it returns false, it's a fatal error
102 // and this tree should be destroyed, and the source of the tree update
103 // should not be trusted any longer.
104 virtual bool Unserialize(const AXTreeUpdate
& update
);
106 // Return a multi-line indented string representation, for logging.
107 std::string
ToString() const;
109 // A string describing the error from an unsuccessful Unserialize,
110 // for testing and debugging.
111 const std::string
& error() const { return error_
; }
113 int size() { return static_cast<int>(id_map_
.size()); }
116 AXNode
* CreateNode(AXNode
* parent
, int32 id
, int32 index_in_parent
);
118 // This is called from within Unserialize(), it returns true on success.
119 bool UpdateNode(const AXNodeData
& src
, AXTreeUpdateState
* update_state
);
121 void OnRootChanged();
123 // Notify the delegate that the subtree rooted at |node| will be destroyed,
124 // then call DestroyNodeAndSubtree on it.
125 void DestroySubtree(AXNode
* node
, AXTreeUpdateState
* update_state
);
127 // Call Destroy() on |node|, and delete it from the id map, and then
128 // call recursively on all nodes in its subtree.
129 void DestroyNodeAndSubtree(AXNode
* node
, AXTreeUpdateState
* update_state
);
131 // Iterate over the children of |node| and for each child, destroy the
132 // child and its subtree if its id is not in |new_child_ids|. Returns
133 // true on success, false on fatal error.
134 bool DeleteOldChildren(AXNode
* node
,
135 const std::vector
<int32
>& new_child_ids
,
136 AXTreeUpdateState
* update_state
);
138 // Iterate over |new_child_ids| and populate |new_children| with
139 // pointers to child nodes, reusing existing nodes already in the tree
140 // if they exist, and creating otherwise. Reparenting is disallowed, so
141 // if the id already exists as the child of another node, that's an
142 // error. Returns true on success, false on fatal error.
143 bool CreateNewChildVector(AXNode
* node
,
144 const std::vector
<int32
>& new_child_ids
,
145 std::vector
<AXNode
*>* new_children
,
146 AXTreeUpdateState
* update_state
);
148 AXTreeDelegate
* delegate_
;
150 base::hash_map
<int32
, AXNode
*> id_map_
;
156 #endif // UI_ACCESSIBILITY_AX_TREE_H_