blob: adc63d96306a52b566e7088fa4f0862a83bd1f99 [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
Chris Hall34208182019-03-13 02:26:1810#include <memory>
[email protected]d4e273462013-12-04 04:37:5811#include <set>
Takuto Ikutaadf31eb2019-01-05 00:32:4812#include <unordered_map>
[email protected]4b02bbca2013-11-22 08:59:0313
Dominic Mazzoni8549eb682018-12-11 23:48:3214#include "base/observer_list.h"
[email protected]4b02bbca2013-11-22 08:59:0315#include "ui/accessibility/ax_export.h"
Dominic Mazzoniecfb4fd2018-10-23 07:34:2016#include "ui/accessibility/ax_node.h"
dmazzoni329fd012015-10-22 20:05:3517#include "ui/accessibility/ax_node_data.h"
18#include "ui/accessibility/ax_tree_data.h"
[email protected]4b02bbca2013-11-22 08:59:0319#include "ui/accessibility/ax_tree_update.h"
20
21namespace ui {
22
Dominic Mazzoni3d9b5b92018-04-18 21:36:3823class AXTableInfo;
dmazzoni09e75912015-06-02 23:31:5624class AXTree;
Dominic Mazzoni8549eb682018-12-11 23:48:3225class AXTreeObserver;
[email protected]e736e81b2014-02-24 07:15:5826struct AXTreeUpdateState;
Chris Hall697d99b2019-07-09 02:36:1127class AXLanguageDetectionManager;
[email protected]e736e81b2014-02-24 07:15:5828
[email protected]4b02bbca2013-11-22 08:59:0329// AXTree is a live, managed tree of AXNode objects that can receive
30// updates from another AXTreeSource via AXTreeUpdates, and it can be
31// used as a source for sending updates to another client tree.
32// It's designed to be subclassed to implement support for native
33// accessibility APIs on a specific platform.
Dominic Mazzoniecfb4fd2018-10-23 07:34:2034class AX_EXPORT AXTree : public AXNode::OwnerTree {
[email protected]4b02bbca2013-11-22 08:59:0335 public:
David Tsengef6b480d2018-02-19 12:48:4236 typedef std::map<ax::mojom::IntAttribute,
37 std::map<int32_t, std::set<int32_t>>>
38 IntReverseRelationMap;
39 typedef std::map<ax::mojom::IntListAttribute,
40 std::map<int32_t, std::set<int32_t>>>
41 IntListReverseRelationMap;
42
[email protected]4b02bbca2013-11-22 08:59:0343 AXTree();
dmazzoni329fd012015-10-22 20:05:3544 explicit AXTree(const AXTreeUpdate& initial_state);
[email protected]4b02bbca2013-11-22 08:59:0345 virtual ~AXTree();
46
Dominic Mazzoni8549eb682018-12-11 23:48:3247 void AddObserver(AXTreeObserver* observer);
48 bool HasObserver(AXTreeObserver* observer);
49 void RemoveObserver(const AXTreeObserver* observer);
50
51 base::ObserverList<AXTreeObserver>& observers() { return observers_; }
[email protected]e736e81b2014-02-24 07:15:5852
tfarina6b1c1e082015-02-20 23:47:0753 AXNode* root() const { return root_; }
54
dmazzoni329fd012015-10-22 20:05:3555 const AXTreeData& data() const { return data_; }
56
Dominic Mazzoniecfb4fd2018-10-23 07:34:2057 // AXNode::OwnerTree override.
tfarina6b1c1e082015-02-20 23:47:0758 // Returns the AXNode with the given |id| if it is part of this AXTree.
Dominic Mazzoniecfb4fd2018-10-23 07:34:2059 AXNode* GetFromId(int32_t id) const override;
[email protected]4b02bbca2013-11-22 08:59:0360
[email protected]d4e273462013-12-04 04:37:5861 // Returns true on success. If it returns false, it's a fatal error
62 // and this tree should be destroyed, and the source of the tree update
63 // should not be trusted any longer.
dmazzoni329fd012015-10-22 20:05:3564 virtual bool Unserialize(const AXTreeUpdate& update);
65
66 virtual void UpdateData(const AXTreeData& data);
[email protected]4b02bbca2013-11-22 08:59:0367
Dominic Mazzoni2410fc62017-06-09 22:19:1868 // Convert any rectangle from the local coordinate space of one node in
69 // the tree, to bounds in the coordinate space of the tree.
Katie Dektar2c6052d2017-09-27 00:32:3270 // If set, updates |offscreen| boolean to be true if the node is offscreen
71 // relative to its rootWebArea. Callers should initialize |offscreen|
72 // to false: this method may get called multiple times in a row and
73 // |offscreen| will be propagated.
Katie Dektardb71ad942017-11-29 20:07:4874 // If |clip_bounds| is true, result bounds will be clipped.
Dominic Mazzoni2410fc62017-06-09 22:19:1875 gfx::RectF RelativeToTreeBounds(const AXNode* node,
Katie Dektar2c6052d2017-09-27 00:32:3276 gfx::RectF node_bounds,
Katie Dektardb71ad942017-11-29 20:07:4877 bool* offscreen = nullptr,
78 bool clip_bounds = true) const;
Dominic Mazzoni2410fc62017-06-09 22:19:1879
80 // Get the bounds of a node in the coordinate space of the tree.
Katie Dektar2c6052d2017-09-27 00:32:3281 // If set, updates |offscreen| boolean to be true if the node is offscreen
82 // relative to its rootWebArea. Callers should initialize |offscreen|
83 // to false: this method may get called multiple times in a row and
84 // |offscreen| will be propagated.
Katie Dektardb71ad942017-11-29 20:07:4885 // If |clip_bounds| is true, result bounds will be clipped.
86 gfx::RectF GetTreeBounds(const AXNode* node,
87 bool* offscreen = nullptr,
88 bool clip_bounds = true) const;
Dominic Mazzoni2410fc62017-06-09 22:19:1889
Dominic Mazzoni35f2a5252017-09-26 00:56:0490 // Given a node ID attribute (one where IsNodeIdIntAttribute is true),
91 // and a destination node ID, return a set of all source node IDs that
92 // have that relationship attribute between them and the destination.
Dominic Mazzonidcef1b732018-01-26 17:57:0493 std::set<int32_t> GetReverseRelations(ax::mojom::IntAttribute attr,
Dominic Mazzoni94a4da62017-12-22 22:49:3894 int32_t dst_id) const;
Dominic Mazzoni35f2a5252017-09-26 00:56:0495
96 // Given a node ID list attribute (one where
97 // IsNodeIdIntListAttribute is true), and a destination node ID,
98 // return a set of all source node IDs that have that relationship
99 // attribute between them and the destination.
Dominic Mazzonidcef1b732018-01-26 17:57:04100 std::set<int32_t> GetReverseRelations(ax::mojom::IntListAttribute attr,
Dominic Mazzoni94a4da62017-12-22 22:49:38101 int32_t dst_id) const;
Dominic Mazzoni35f2a5252017-09-26 00:56:04102
Dominic Mazzoniaa774822018-08-29 20:33:58103 // Given a child tree ID, return the node IDs of all nodes in the tree who
104 // have a kChildTreeId int attribute with that value.
Dominic Mazzoni336bc0062018-09-23 16:46:43105 std::set<int32_t> GetNodeIdsForChildTreeId(AXTreeID child_tree_id) const;
Dominic Mazzoniaa774822018-08-29 20:33:58106
Dominic Mazzoni748888c2018-11-01 22:34:59107 // Get all of the child tree IDs referenced by any node in this tree.
108 const std::set<AXTreeID> GetAllChildTreeIds() const;
109
David Tsengef6b480d2018-02-19 12:48:42110 // Map from a relation attribute to a map from a target id to source ids.
111 const IntReverseRelationMap& int_reverse_relations() {
112 return int_reverse_relations_;
113 }
114 const IntListReverseRelationMap& intlist_reverse_relations() {
115 return intlist_reverse_relations_;
116 }
Dominic Mazzoni3d9b5b92018-04-18 21:36:38117
[email protected]5eec2f52014-01-06 22:30:54118 // Return a multi-line indented string representation, for logging.
119 std::string ToString() const;
120
[email protected]d4e273462013-12-04 04:37:58121 // A string describing the error from an unsuccessful Unserialize,
122 // for testing and debugging.
tfarinad0bfb4b62015-02-18 17:20:32123 const std::string& error() const { return error_; }
[email protected]d4e273462013-12-04 04:37:58124
dmazzoniee2eaca2015-03-18 18:13:07125 int size() { return static_cast<int>(id_map_.size()); }
126
Dominic Mazzonid42e00a2018-06-27 23:14:23127 // Call this to enable support for extra Mac nodes - for each table,
128 // a table column header and a node for each column.
129 void SetEnableExtraMacNodes(bool enabled);
130 bool enable_extra_mac_nodes() const { return enable_extra_mac_nodes_; }
131
132 // Return a negative number that's suitable to use for a node ID for
133 // internal nodes created automatically by an AXTree, so as not to
134 // conflict with positive-numbered node IDs from tree sources.
135 int32_t GetNextNegativeInternalNodeId();
136
Akihiro Ota886a96d62018-12-18 00:11:48137 // Returns the pos_in_set of node. Looks in ordered_set_info_map_ for cached
138 // value. Calculates pos_in_set and set_size for node (and all other nodes in
Akihiro Ota413ca722018-12-03 23:29:00139 // the same ordered set) if no value is present in the cache.
140 // This function is guaranteed to be only called on nodes that can hold
141 // pos_in_set values, minimizing the size of the cache.
Akihiro Ota886a96d62018-12-18 00:11:48142 int32_t GetPosInSet(const AXNode& node, const AXNode* ordered_set) override;
Akihiro Ota413ca722018-12-03 23:29:00143 // Returns the set_size of node. Looks in ordered_set_info_map_ for cached
144 // value. Calculates pos_inset_set and set_size for node (and all other nodes
145 // in the same ordered set) if no value is present in the cache.
146 // This function is guaranteed to be only called on nodes that can hold
147 // set_size values, minimizing the size of the cache.
Akihiro Ota886a96d62018-12-18 00:11:48148 int32_t GetSetSize(const AXNode& node, const AXNode* ordered_set) override;
Akihiro Ota413ca722018-12-03 23:29:00149
Akihiro Otae3e420e2019-04-17 19:57:40150 bool GetTreeUpdateInProgressState() const override;
151 void SetTreeUpdateInProgressState(bool set_tree_update_value);
152
Chris Hall697d99b2019-07-09 02:36:11153 // Language detection manager, entry point to language detection features.
154 // TODO(chrishall): Should this be stored by pointer or value?
155 // When should we initialize this?
156 std::unique_ptr<AXLanguageDetectionManager> language_detection_manager;
Chris Hall34208182019-03-13 02:26:18157
[email protected]e736e81b2014-02-24 07:15:58158 private:
Dominic Mazzoniecfb4fd2018-10-23 07:34:20159 friend class AXTableInfoTest;
160
161 // AXNode::OwnerTree override.
162 //
163 // Given a node in this accessibility tree that corresponds to a table
164 // or grid, return an object containing information about the
165 // table structure. This object is computed lazily on-demand and
166 // cached until the next time the tree is updated. Clients should
167 // not retain this pointer, they should just request it every time
168 // it's needed.
169 //
170 // Returns nullptr if the node is not a valid table.
171 AXTableInfo* GetTableInfo(const AXNode* table_node) const override;
172
dtseng5a7b3d92016-09-08 06:35:58173 AXNode* CreateNode(AXNode* parent,
174 int32_t id,
Peter Kasting94a07a12019-05-22 19:26:28175 size_t index_in_parent,
dtseng5a7b3d92016-09-08 06:35:58176 AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03177
178 // This is called from within Unserialize(), it returns true on success.
dmazzoni67b4db22016-04-23 00:40:04179 bool UpdateNode(const AXNodeData& src,
180 bool is_new_root,
181 AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03182
David Tseng76429cf62019-01-17 21:11:53183 void CallNodeChangeCallbacks(AXNode* node,
184 const AXNodeData& old_data,
185 const AXNodeData& new_data);
dmazzoni3ab5385c2017-03-13 18:07:03186
Dominic Mazzoni35f2a5252017-09-26 00:56:04187 void UpdateReverseRelations(AXNode* node, const AXNodeData& new_data);
188
[email protected]e736e81b2014-02-24 07:15:58189 void OnRootChanged();
[email protected]4b02bbca2013-11-22 08:59:03190
dmazzonia4b48912015-01-24 00:08:56191 // Notify the delegate that the subtree rooted at |node| will be destroyed,
192 // then call DestroyNodeAndSubtree on it.
dmazzonie3b7faf2015-06-01 17:56:36193 void DestroySubtree(AXNode* node, AXTreeUpdateState* update_state);
dmazzonia4b48912015-01-24 00:08:56194
[email protected]4b02bbca2013-11-22 08:59:03195 // Call Destroy() on |node|, and delete it from the id map, and then
196 // call recursively on all nodes in its subtree.
dmazzonie3b7faf2015-06-01 17:56:36197 void DestroyNodeAndSubtree(AXNode* node, AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03198
199 // Iterate over the children of |node| and for each child, destroy the
200 // child and its subtree if its id is not in |new_child_ids|. Returns
201 // true on success, false on fatal error.
202 bool DeleteOldChildren(AXNode* node,
avi9c81217b2015-12-24 23:40:05203 const std::vector<int32_t>& new_child_ids,
dmazzonie3b7faf2015-06-01 17:56:36204 AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03205
206 // Iterate over |new_child_ids| and populate |new_children| with
207 // pointers to child nodes, reusing existing nodes already in the tree
208 // if they exist, and creating otherwise. Reparenting is disallowed, so
209 // if the id already exists as the child of another node, that's an
[email protected]e736e81b2014-02-24 07:15:58210 // error. Returns true on success, false on fatal error.
[email protected]4b02bbca2013-11-22 08:59:03211 bool CreateNewChildVector(AXNode* node,
avi9c81217b2015-12-24 23:40:05212 const std::vector<int32_t>& new_child_ids,
[email protected]d4e273462013-12-04 04:37:58213 std::vector<AXNode*>* new_children,
[email protected]e736e81b2014-02-24 07:15:58214 AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03215
Dominic Mazzoni8549eb682018-12-11 23:48:32216 base::ObserverList<AXTreeObserver> observers_;
Brett Wilson0feae3a2017-12-06 03:16:56217 AXNode* root_ = nullptr;
Takuto Ikutaadf31eb2019-01-05 00:32:48218 std::unordered_map<int32_t, AXNode*> id_map_;
[email protected]d4e273462013-12-04 04:37:58219 std::string error_;
dmazzoni329fd012015-10-22 20:05:35220 AXTreeData data_;
Dominic Mazzoni35f2a5252017-09-26 00:56:04221
222 // Map from an int attribute (if IsNodeIdIntAttribute is true) to
223 // a reverse mapping from target nodes to source nodes.
David Tsengef6b480d2018-02-19 12:48:42224 IntReverseRelationMap int_reverse_relations_;
Dominic Mazzoni35f2a5252017-09-26 00:56:04225 // Map from an int list attribute (if IsNodeIdIntListAttribute is true) to
226 // a reverse mapping from target nodes to source nodes.
David Tsengef6b480d2018-02-19 12:48:42227 IntListReverseRelationMap intlist_reverse_relations_;
Dominic Mazzoniaa774822018-08-29 20:33:58228 // Map from child tree ID to the set of node IDs that contain that attribute.
Dominic Mazzoni336bc0062018-09-23 16:46:43229 std::map<AXTreeID, std::set<int32_t>> child_tree_id_reverse_map_;
Dominic Mazzoni3d9b5b92018-04-18 21:36:38230
231 // Map from node ID to cached table info, if the given node is a table.
Dominic Mazzonid42e00a2018-06-27 23:14:23232 // Invalidated every time the tree is updated.
Takuto Ikutaadf31eb2019-01-05 00:32:48233 mutable std::unordered_map<int32_t, AXTableInfo*> table_info_map_;
Dominic Mazzonid42e00a2018-06-27 23:14:23234
235 // The next negative node ID to use for internal nodes.
236 int32_t next_negative_internal_node_id_ = -1;
237
238 // Whether we should create extra nodes that
239 // are only useful on macOS. Implemented using this flag to allow
240 // this code to be unit-tested on other platforms (for example, more
241 // code sanitizers run on Linux).
242 bool enable_extra_mac_nodes_ = false;
Akihiro Ota413ca722018-12-03 23:29:00243
244 // Contains pos_in_set and set_size data for an AXNode.
245 struct OrderedSetInfo {
246 int32_t pos_in_set;
247 int32_t set_size;
Alice Boxhallc8ffa6c2019-04-09 02:39:44248 int32_t lowest_hierarchical_level;
Akihiro Ota413ca722018-12-03 23:29:00249 OrderedSetInfo() : pos_in_set(0), set_size(0) {}
250 ~OrderedSetInfo() {}
251 };
252
Akihiro Otab6a8a4d2018-12-04 01:56:39253 // Populates items vector with all items within ordered_set.
Akihiro Ota886a96d62018-12-18 00:11:48254 // Will only add items whose roles match the role of the
255 // ordered_set.
Akihiro Ota413ca722018-12-03 23:29:00256 void PopulateOrderedSetItems(const AXNode* ordered_set,
257 const AXNode* local_parent,
Akihiro Ota886a96d62018-12-18 00:11:48258 std::vector<const AXNode*>& items,
Akihiro Otad659eded2019-02-20 21:44:32259 const AXNode& original_node) const;
Akihiro Ota886a96d62018-12-18 00:11:48260
Akihiro Ota413ca722018-12-03 23:29:00261 // Helper for GetPosInSet and GetSetSize. Computes the pos_in_set and set_size
262 // values of all items in ordered_set and caches those values.
Akihiro Ota886a96d62018-12-18 00:11:48263 void ComputeSetSizePosInSetAndCache(const AXNode& node,
264 const AXNode* ordered_set);
Akihiro Ota413ca722018-12-03 23:29:00265
Akihiro Otab6a8a4d2018-12-04 01:56:39266 // Map from node ID to OrderedSetInfo.
267 // Item-like and ordered-set-like objects will map to populated OrderedSetInfo
268 // objects.
269 // All other objects will map to default-constructed OrderedSetInfo objects.
Akihiro Ota413ca722018-12-03 23:29:00270 // Invalidated every time the tree is updated.
271 mutable std::unordered_map<int32_t, OrderedSetInfo> ordered_set_info_map_;
Chris Hall9b34c2c2018-12-04 01:45:56272
273 // AXTree owns pointers so copying is non-trivial.
274 DISALLOW_COPY_AND_ASSIGN(AXTree);
Akihiro Otae3e420e2019-04-17 19:57:40275
276 // Indicates if the tree is updating.
277 bool tree_update_in_progress_ = false;
[email protected]4b02bbca2013-11-22 08:59:03278};
279
280} // namespace ui
281
282#endif // UI_ACCESSIBILITY_AX_TREE_H_