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