blob: 9fc88b45476f18ee26961b55af2a9fcdb3844cb5 [file] [log] [blame]
[email protected]4b02bbca2013-11-22 08:59:031// 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.
4
5#ifndef UI_ACCESSIBILITY_AX_TREE_H_
6#define UI_ACCESSIBILITY_AX_TREE_H_
7
avi9c81217b2015-12-24 23:40:058#include <stdint.h>
9
[email protected]d4e273462013-12-04 04:37:5810#include <set>
[email protected]4b02bbca2013-11-22 08:59:0311
[email protected]d4e273462013-12-04 04:37:5812#include "base/containers/hash_tables.h"
[email protected]4b02bbca2013-11-22 08:59:0313#include "ui/accessibility/ax_export.h"
dmazzoni329fd012015-10-22 20:05:3514#include "ui/accessibility/ax_node_data.h"
15#include "ui/accessibility/ax_tree_data.h"
[email protected]4b02bbca2013-11-22 08:59:0316#include "ui/accessibility/ax_tree_update.h"
17
18namespace ui {
19
20class AXNode;
dmazzoni09e75912015-06-02 23:31:5621class AXTree;
[email protected]e736e81b2014-02-24 07:15:5822struct AXTreeUpdateState;
23
24// Used when you want to be notified when changes happen to the tree.
[email protected]d96f3842014-04-21 18:07:2925//
26// Some of the notifications are called in the middle of an update operation.
27// Be careful, as the tree may be in an inconsistent state at this time;
28// don't walk the parents and children at this time:
29// OnNodeWillBeDeleted
dmazzonia4b48912015-01-24 00:08:5630// OnSubtreeWillBeDeleted
dtseng5a7b3d92016-09-08 06:35:5831// OnNodeWillBeReparented
32// OnSubtreeWillBeReparented
[email protected]d96f3842014-04-21 18:07:2933// OnNodeCreated
dtseng5a7b3d92016-09-08 06:35:5834// OnNodeReparented
[email protected]d96f3842014-04-21 18:07:2935// OnNodeChanged
36//
dmazzonia4b48912015-01-24 00:08:5637// In addition, one additional notification is fired at the end of an
38// atomic update, and it provides a vector of nodes that were added or
39// changed, for final postprocessing:
40// OnAtomicUpdateFinished
41//
[email protected]e736e81b2014-02-24 07:15:5842class AX_EXPORT AXTreeDelegate {
43 public:
44 AXTreeDelegate();
45 virtual ~AXTreeDelegate();
46
dtsengf5424b32016-02-23 03:21:5547 // Called before a node's data gets updated.
48 virtual void OnNodeDataWillChange(AXTree* tree,
49 const AXNodeData& old_node_data,
50 const AXNodeData& new_node_data) = 0;
51
dmazzoni3ab5385c2017-03-13 18:07:0352 // Individual callbacks for every attribute of AXNodeData that can change.
53 virtual void OnRoleChanged(AXTree* tree,
54 AXNode* node,
55 AXRole old_role,
56 AXRole new_role) {}
57 virtual void OnStateChanged(AXTree* tree,
58 AXNode* node,
59 AXState state,
60 bool new_value) {}
61 virtual void OnStringAttributeChanged(AXTree* tree,
62 AXNode* node,
63 AXStringAttribute attr,
64 const std::string& old_value,
65 const std::string& new_value) {}
66 virtual void OnIntAttributeChanged(AXTree* tree,
67 AXNode* node,
68 AXIntAttribute attr,
69 int32_t old_value,
70 int32_t new_value) {}
71 virtual void OnFloatAttributeChanged(AXTree* tree,
72 AXNode* node,
73 AXFloatAttribute attr,
74 float old_value,
75 float new_value) {}
76 virtual void OnBoolAttributeChanged(AXTree* tree,
77 AXNode* node,
78 AXBoolAttribute attr,
79 bool new_value) {}
80 virtual void OnIntListAttributeChanged(
81 AXTree* tree,
82 AXNode* node,
83 AXIntListAttribute attr,
84 const std::vector<int32_t>& old_value,
85 const std::vector<int32_t>& new_value) {}
yawanob87aed42017-06-26 02:55:2986 virtual void OnStringListAttributeChanged(
87 AXTree* tree,
88 AXNode* node,
89 AXStringListAttribute attr,
90 const std::vector<std::string>& old_value,
91 const std::vector<std::string>& new_value) {}
dmazzoni3ab5385c2017-03-13 18:07:0392
dmazzoni329fd012015-10-22 20:05:3593 // Called when tree data changes.
dmazzoni5e3acae92017-06-08 04:39:5294 virtual void OnTreeDataChanged(AXTree* tree,
95 const ui::AXTreeData& old_data,
96 const ui::AXTreeData& new_data) = 0;
[email protected]e736e81b2014-02-24 07:15:5897 // Called just before a node is deleted. Its id and data will be valid,
98 // but its links to parents and children are invalid. This is called
99 // in the middle of an update, the tree may be in an invalid state!
dmazzoni09e75912015-06-02 23:31:56100 virtual void OnNodeWillBeDeleted(AXTree* tree, AXNode* node) = 0;
[email protected]e736e81b2014-02-24 07:15:58101
dmazzonia4b48912015-01-24 00:08:56102 // Same as OnNodeWillBeDeleted, but only called once for an entire subtree.
103 // This is called in the middle of an update, the tree may be in an
104 // invalid state!
dmazzoni09e75912015-06-02 23:31:56105 virtual void OnSubtreeWillBeDeleted(AXTree* tree, AXNode* node) = 0;
dmazzonia4b48912015-01-24 00:08:56106
dtseng5a7b3d92016-09-08 06:35:58107 // Called just before a node is deleted for reparenting. See
108 // |OnNodeWillBeDeleted| for additional information.
109 virtual void OnNodeWillBeReparented(AXTree* tree, AXNode* node) = 0;
110
111 // Called just before a subtree is deleted for reparenting. See
112 // |OnSubtreeWillBeDeleted| for additional information.
113 virtual void OnSubtreeWillBeReparented(AXTree* tree, AXNode* node) = 0;
114
[email protected]d96f3842014-04-21 18:07:29115 // Called immediately after a new node is created. The tree may be in
116 // the middle of an update, don't walk the parents and children now.
dmazzoni09e75912015-06-02 23:31:56117 virtual void OnNodeCreated(AXTree* tree, AXNode* node) = 0;
[email protected]e736e81b2014-02-24 07:15:58118
dtseng5a7b3d92016-09-08 06:35:58119 // Called immediately after a node is reparented. The tree may be in the
120 // middle of an update, don't walk the parents and children now.
121 virtual void OnNodeReparented(AXTree* tree, AXNode* node) = 0;
122
[email protected]d96f3842014-04-21 18:07:29123 // Called when a node changes its data or children. The tree may be in
124 // the middle of an update, don't walk the parents and children now.
dmazzoni09e75912015-06-02 23:31:56125 virtual void OnNodeChanged(AXTree* tree, AXNode* node) = 0;
[email protected]e736e81b2014-02-24 07:15:58126
dmazzonia4b48912015-01-24 00:08:56127 enum ChangeType {
128 NODE_CREATED,
129 SUBTREE_CREATED,
dtseng54e74742016-05-17 23:20:29130 NODE_CHANGED,
131 NODE_REPARENTED,
132 SUBTREE_REPARENTED
dmazzonia4b48912015-01-24 00:08:56133 };
[email protected]d96f3842014-04-21 18:07:29134
dmazzonia4b48912015-01-24 00:08:56135 struct Change {
136 Change(AXNode* node, ChangeType type) {
137 this->node = node;
138 this->type = type;
139 }
tfarinad0bfb4b62015-02-18 17:20:32140 AXNode* node;
dmazzonia4b48912015-01-24 00:08:56141 ChangeType type;
142 };
[email protected]d96f3842014-04-21 18:07:29143
dmazzonia4b48912015-01-24 00:08:56144 // Called at the end of the update operation. Every node that was added
145 // or changed will be included in |changes|, along with an enum indicating
146 // the type of change - either (1) a node was created, (2) a node was created
147 // and it's the root of a new subtree, or (3) a node was changed. Finally,
148 // a bool indicates if the root of the tree was changed or not.
dmazzoni09e75912015-06-02 23:31:56149 virtual void OnAtomicUpdateFinished(AXTree* tree,
150 bool root_changed,
dmazzonia4b48912015-01-24 00:08:56151 const std::vector<Change>& changes) = 0;
[email protected]e736e81b2014-02-24 07:15:58152};
[email protected]4b02bbca2013-11-22 08:59:03153
154// AXTree is a live, managed tree of AXNode objects that can receive
155// updates from another AXTreeSource via AXTreeUpdates, and it can be
156// used as a source for sending updates to another client tree.
157// It's designed to be subclassed to implement support for native
158// accessibility APIs on a specific platform.
159class AX_EXPORT AXTree {
160 public:
161 AXTree();
dmazzoni329fd012015-10-22 20:05:35162 explicit AXTree(const AXTreeUpdate& initial_state);
[email protected]4b02bbca2013-11-22 08:59:03163 virtual ~AXTree();
164
[email protected]e736e81b2014-02-24 07:15:58165 virtual void SetDelegate(AXTreeDelegate* delegate);
Dominic Mazzoni4d523f722017-08-31 22:29:06166 AXTreeDelegate* delegate() const { return delegate_; }
[email protected]e736e81b2014-02-24 07:15:58167
tfarina6b1c1e082015-02-20 23:47:07168 AXNode* root() const { return root_; }
169
dmazzoni329fd012015-10-22 20:05:35170 const AXTreeData& data() const { return data_; }
171
tfarina6b1c1e082015-02-20 23:47:07172 // Returns the AXNode with the given |id| if it is part of this AXTree.
avi9c81217b2015-12-24 23:40:05173 AXNode* GetFromId(int32_t id) const;
[email protected]4b02bbca2013-11-22 08:59:03174
[email protected]d4e273462013-12-04 04:37:58175 // Returns true on success. If it returns false, it's a fatal error
176 // and this tree should be destroyed, and the source of the tree update
177 // should not be trusted any longer.
dmazzoni329fd012015-10-22 20:05:35178 virtual bool Unserialize(const AXTreeUpdate& update);
179
180 virtual void UpdateData(const AXTreeData& data);
[email protected]4b02bbca2013-11-22 08:59:03181
Dominic Mazzoni2410fc62017-06-09 22:19:18182 // Convert any rectangle from the local coordinate space of one node in
183 // the tree, to bounds in the coordinate space of the tree.
Katie Dektar2c6052d2017-09-27 00:32:32184 // If set, updates |offscreen| boolean to be true if the node is offscreen
185 // relative to its rootWebArea. Callers should initialize |offscreen|
186 // to false: this method may get called multiple times in a row and
187 // |offscreen| will be propagated.
Katie Dektardb71ad942017-11-29 20:07:48188 // If |clip_bounds| is true, result bounds will be clipped.
Dominic Mazzoni2410fc62017-06-09 22:19:18189 gfx::RectF RelativeToTreeBounds(const AXNode* node,
Katie Dektar2c6052d2017-09-27 00:32:32190 gfx::RectF node_bounds,
Katie Dektardb71ad942017-11-29 20:07:48191 bool* offscreen = nullptr,
192 bool clip_bounds = true) const;
Dominic Mazzoni2410fc62017-06-09 22:19:18193
194 // Get the bounds of a node in the coordinate space of the tree.
Katie Dektar2c6052d2017-09-27 00:32:32195 // If set, updates |offscreen| boolean to be true if the node is offscreen
196 // relative to its rootWebArea. Callers should initialize |offscreen|
197 // to false: this method may get called multiple times in a row and
198 // |offscreen| will be propagated.
Katie Dektardb71ad942017-11-29 20:07:48199 // If |clip_bounds| is true, result bounds will be clipped.
200 gfx::RectF GetTreeBounds(const AXNode* node,
201 bool* offscreen = nullptr,
202 bool clip_bounds = true) const;
Dominic Mazzoni2410fc62017-06-09 22:19:18203
Dominic Mazzoni35f2a5252017-09-26 00:56:04204 // Given a node ID attribute (one where IsNodeIdIntAttribute is true),
205 // and a destination node ID, return a set of all source node IDs that
206 // have that relationship attribute between them and the destination.
207 std::set<int32_t> GetReverseRelations(AXIntAttribute attr, int32_t dst_id);
208
209 // Given a node ID list attribute (one where
210 // IsNodeIdIntListAttribute is true), and a destination node ID,
211 // return a set of all source node IDs that have that relationship
212 // attribute between them and the destination.
213 std::set<int32_t> GetReverseRelations(AXIntListAttribute attr,
214 int32_t dst_id);
215
[email protected]5eec2f52014-01-06 22:30:54216 // Return a multi-line indented string representation, for logging.
217 std::string ToString() const;
218
[email protected]d4e273462013-12-04 04:37:58219 // A string describing the error from an unsuccessful Unserialize,
220 // for testing and debugging.
tfarinad0bfb4b62015-02-18 17:20:32221 const std::string& error() const { return error_; }
[email protected]d4e273462013-12-04 04:37:58222
dmazzoniee2eaca2015-03-18 18:13:07223 int size() { return static_cast<int>(id_map_.size()); }
224
[email protected]e736e81b2014-02-24 07:15:58225 private:
dtseng5a7b3d92016-09-08 06:35:58226 AXNode* CreateNode(AXNode* parent,
227 int32_t id,
228 int32_t index_in_parent,
229 AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03230
231 // This is called from within Unserialize(), it returns true on success.
dmazzoni67b4db22016-04-23 00:40:04232 bool UpdateNode(const AXNodeData& src,
233 bool is_new_root,
234 AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03235
dmazzoni3ab5385c2017-03-13 18:07:03236 void CallNodeChangeCallbacks(AXNode* node, const AXNodeData& new_data);
237
Dominic Mazzoni35f2a5252017-09-26 00:56:04238 void UpdateReverseRelations(AXNode* node, const AXNodeData& new_data);
239
[email protected]e736e81b2014-02-24 07:15:58240 void OnRootChanged();
[email protected]4b02bbca2013-11-22 08:59:03241
dmazzonia4b48912015-01-24 00:08:56242 // Notify the delegate that the subtree rooted at |node| will be destroyed,
243 // then call DestroyNodeAndSubtree on it.
dmazzonie3b7faf2015-06-01 17:56:36244 void DestroySubtree(AXNode* node, AXTreeUpdateState* update_state);
dmazzonia4b48912015-01-24 00:08:56245
[email protected]4b02bbca2013-11-22 08:59:03246 // Call Destroy() on |node|, and delete it from the id map, and then
247 // call recursively on all nodes in its subtree.
dmazzonie3b7faf2015-06-01 17:56:36248 void DestroyNodeAndSubtree(AXNode* node, AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03249
250 // Iterate over the children of |node| and for each child, destroy the
251 // child and its subtree if its id is not in |new_child_ids|. Returns
252 // true on success, false on fatal error.
253 bool DeleteOldChildren(AXNode* node,
avi9c81217b2015-12-24 23:40:05254 const std::vector<int32_t>& new_child_ids,
dmazzonie3b7faf2015-06-01 17:56:36255 AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03256
257 // Iterate over |new_child_ids| and populate |new_children| with
258 // pointers to child nodes, reusing existing nodes already in the tree
259 // if they exist, and creating otherwise. Reparenting is disallowed, so
260 // if the id already exists as the child of another node, that's an
[email protected]e736e81b2014-02-24 07:15:58261 // error. Returns true on success, false on fatal error.
[email protected]4b02bbca2013-11-22 08:59:03262 bool CreateNewChildVector(AXNode* node,
avi9c81217b2015-12-24 23:40:05263 const std::vector<int32_t>& new_child_ids,
[email protected]d4e273462013-12-04 04:37:58264 std::vector<AXNode*>* new_children,
[email protected]e736e81b2014-02-24 07:15:58265 AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03266
[email protected]e736e81b2014-02-24 07:15:58267 AXTreeDelegate* delegate_;
[email protected]4b02bbca2013-11-22 08:59:03268 AXNode* root_;
avi9c81217b2015-12-24 23:40:05269 base::hash_map<int32_t, AXNode*> id_map_;
[email protected]d4e273462013-12-04 04:37:58270 std::string error_;
dmazzoni329fd012015-10-22 20:05:35271 AXTreeData data_;
Dominic Mazzoni35f2a5252017-09-26 00:56:04272
273 // Map from an int attribute (if IsNodeIdIntAttribute is true) to
274 // a reverse mapping from target nodes to source nodes.
275 std::map<AXIntAttribute, std::map<int32_t, std::set<int32_t>>>
276 int_reverse_relations_;
277 // Map from an int list attribute (if IsNodeIdIntListAttribute is true) to
278 // a reverse mapping from target nodes to source nodes.
279 std::map<AXIntListAttribute, std::map<int32_t, std::set<int32_t>>>
280 intlist_reverse_relations_;
[email protected]4b02bbca2013-11-22 08:59:03281};
282
283} // namespace ui
284
285#endif // UI_ACCESSIBILITY_AX_TREE_H_