blob: 9f0870ccc87d8093251ed086d3f4190685674d48 [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
Lei Zhanga06144782020-03-13 09:28:4710#include <map>
Chris Hall34208182019-03-13 02:26:1811#include <memory>
[email protected]d4e273462013-12-04 04:37:5812#include <set>
Lei Zhanga06144782020-03-13 09:28:4713#include <string>
Lei Zhanga06144782020-03-13 09:28:4714#include <vector>
[email protected]4b02bbca2013-11-22 08:59:0315
Jacob Francis78735e32022-06-30 22:02:5216#include "base/containers/flat_map.h"
Keishi Hattori0e45c022021-11-27 09:25:5217#include "base/memory/raw_ptr.h"
Jacques Newman5846e622021-01-15 02:15:5918#include "base/metrics/histogram_functions.h"
Dominic Mazzoni8549eb682018-12-11 23:48:3219#include "base/observer_list.h"
Nektarios Paisios77c422a2021-10-19 10:37:0020#include "third_party/abseil-cpp/absl/types/optional.h"
James Cook36cab7c2019-10-29 23:26:4021#include "ui/accessibility/ax_enums.mojom-forward.h"
[email protected]4b02bbca2013-11-22 08:59:0322#include "ui/accessibility/ax_export.h"
Dominic Mazzoniecfb4fd2018-10-23 07:34:2023#include "ui/accessibility/ax_node.h"
dmazzoni329fd012015-10-22 20:05:3524#include "ui/accessibility/ax_node_data.h"
25#include "ui/accessibility/ax_tree_data.h"
[email protected]4b02bbca2013-11-22 08:59:0326#include "ui/accessibility/ax_tree_update.h"
27
28namespace ui {
29
David Tseng41f13cbd2021-11-06 18:39:0330struct AXEvent;
Dominic Mazzoni3d9b5b92018-04-18 21:36:3831class AXTableInfo;
Dominic Mazzoni8549eb682018-12-11 23:48:3232class AXTreeObserver;
[email protected]e736e81b2014-02-24 07:15:5833struct AXTreeUpdateState;
Chris Hall697d99b2019-07-09 02:36:1134class AXLanguageDetectionManager;
[email protected]e736e81b2014-02-24 07:15:5835
Jacques Newman5846e622021-01-15 02:15:5936// These values are persisted to logs. Entries should not be renumbered and
37// numeric values should never be reused.
38enum class AXTreeUnserializeError {
39 // Tree has no root.
40 kNoRoot = 0,
41 // Node will not be in the tree and is not the new root.
42 kNotInTree = 1,
43 // Node is already pending for creation, cannot be the new root
44 kCreationPending = 2,
45 // Node has duplicate child.
46 kDuplicateChild = 3,
47 // Node is already pending for creation, cannot be a new child.
48 kCreationPendingForChild = 4,
49 // Node is not marked for destruction, would be reparented.
50 kReparent = 5,
51 // Nodes are left pending by the update.
52 kPendingNodes = 6,
53 // Changes left pending by the update;
54 kPendingChanges = 7,
55 // This must always be the last enum. It's okay for its value to
56 // increase, but none of the other enum values may change.
57 kMaxValue = kPendingChanges
58};
59
60#define ACCESSIBILITY_TREE_UNSERIALIZE_ERROR_HISTOGRAM(enum_value) \
61 base::UmaHistogramEnumeration( \
62 "Accessibility.Reliability.Tree.UnserializeError", enum_value)
63
[email protected]4b02bbca2013-11-22 08:59:0364// AXTree is a live, managed tree of AXNode objects that can receive
65// updates from another AXTreeSource via AXTreeUpdates, and it can be
66// used as a source for sending updates to another client tree.
67// It's designed to be subclassed to implement support for native
68// accessibility APIs on a specific platform.
Dominic Mazzoniecfb4fd2018-10-23 07:34:2069class AX_EXPORT AXTree : public AXNode::OwnerTree {
[email protected]4b02bbca2013-11-22 08:59:0370 public:
Lei Zhanga06144782020-03-13 09:28:4771 using IntReverseRelationMap =
Nektarios Paisios527d33fb52021-02-23 19:23:2872 std::map<ax::mojom::IntAttribute, std::map<AXNodeID, std::set<AXNodeID>>>;
Lei Zhanga06144782020-03-13 09:28:4773 using IntListReverseRelationMap =
74 std::map<ax::mojom::IntListAttribute,
Nektarios Paisios527d33fb52021-02-23 19:23:2875 std::map<AXNodeID, std::set<AXNodeID>>>;
David Tsengef6b480d2018-02-19 12:48:4276
Nektarios Paisios77c422a2021-10-19 10:37:0077 // If called, the focused node in this tree will never be ignored, even if it
78 // has the ignored state set. For now, this boolean will be set to false for
79 // all trees except in test scenarios, in order to thoroughly test the
80 // relevant code without causing any potential regressions. Ultimately, we
81 // want to expose all focused nodes so that a user of an assistive technology
82 // will be able to interact with the application / website, even if there is
83 // an authoring error, e.g. the aria-hidden attribute has been applied to the
84 // focused element.
85 // TODO(nektar): Removed once the feature has been fully tested.
86 static void SetFocusedNodeShouldNeverBeIgnored();
87
88 // Determines the ignored state of a node, given information about the node
89 // and the tree.
90 static bool ComputeNodeIsIgnored(const AXTreeData* optional_tree_data,
91 const AXNodeData& node_data);
92
93 // Determines whether a node has flipped its ignored state, given information
94 // about the previous and current state of the node / tree.
95 static bool ComputeNodeIsIgnoredChanged(
96 const AXTreeData* optional_old_tree_data,
97 const AXNodeData& old_node_data,
98 const AXTreeData* optional_new_tree_data,
99 const AXNodeData& new_node_data);
100
[email protected]4b02bbca2013-11-22 08:59:03101 AXTree();
dmazzoni329fd012015-10-22 20:05:35102 explicit AXTree(const AXTreeUpdate& initial_state);
[email protected]4b02bbca2013-11-22 08:59:03103 virtual ~AXTree();
104
Lei Zhanga06144782020-03-13 09:28:47105 // AXTree owns pointers so copying is non-trivial.
106 AXTree(const AXTree&) = delete;
107 AXTree& operator=(const AXTree&) = delete;
108
Dominic Mazzoni8549eb682018-12-11 23:48:32109 void AddObserver(AXTreeObserver* observer);
110 bool HasObserver(AXTreeObserver* observer);
Nektarios Paisiosdb7b5ee2020-02-18 21:28:11111 void RemoveObserver(AXTreeObserver* observer);
Dominic Mazzoni8549eb682018-12-11 23:48:32112
113 base::ObserverList<AXTreeObserver>& observers() { return observers_; }
[email protected]e736e81b2014-02-24 07:15:58114
tfarina6b1c1e082015-02-20 23:47:07115 AXNode* root() const { return root_; }
116
Joanmarie Diggs58b67c982020-11-13 15:33:28117 const AXTreeData& data() const override;
dmazzoni329fd012015-10-22 20:05:35118
Nektarios Paisiosdb7b5ee2020-02-18 21:28:11119 // Destroys the tree and notifies all observers.
120 void Destroy();
121
Dominic Mazzoniecfb4fd2018-10-23 07:34:20122 // AXNode::OwnerTree override.
Adam Ettenberger86af2532019-09-17 20:04:46123 // Returns the globally unique ID of this accessibility tree.
Nektarios Paisios50e579f12022-05-19 19:22:39124 const AXTreeID& GetAXTreeID() const override;
Adam Ettenberger86af2532019-09-17 20:04:46125
126 // AXNode::OwnerTree override.
tfarina6b1c1e082015-02-20 23:47:07127 // Returns the AXNode with the given |id| if it is part of this AXTree.
Nektarios Paisios527d33fb52021-02-23 19:23:28128 AXNode* GetFromId(AXNodeID id) const override;
[email protected]4b02bbca2013-11-22 08:59:03129
[email protected]d4e273462013-12-04 04:37:58130 // Returns true on success. If it returns false, it's a fatal error
131 // and this tree should be destroyed, and the source of the tree update
132 // should not be trusted any longer.
dmazzoni329fd012015-10-22 20:05:35133 virtual bool Unserialize(const AXTreeUpdate& update);
134
Nektarios Paisios26ac2b42021-06-02 18:24:19135 // Used by tests to update the tree data without changing any of the nodes in
136 // the tree, notifying all tree observers in the process.
137 virtual void UpdateDataForTesting(const AXTreeData& data);
[email protected]4b02bbca2013-11-22 08:59:03138
Dominic Mazzoni2410fc62017-06-09 22:19:18139 // Convert any rectangle from the local coordinate space of one node in
140 // the tree, to bounds in the coordinate space of the tree.
Katie Dektar2c6052d2017-09-27 00:32:32141 // If set, updates |offscreen| boolean to be true if the node is offscreen
142 // relative to its rootWebArea. Callers should initialize |offscreen|
143 // to false: this method may get called multiple times in a row and
144 // |offscreen| will be propagated.
Katie Dektardb71ad942017-11-29 20:07:48145 // If |clip_bounds| is true, result bounds will be clipped.
Dominic Mazzoni2410fc62017-06-09 22:19:18146 gfx::RectF RelativeToTreeBounds(const AXNode* node,
Katie Dektar2c6052d2017-09-27 00:32:32147 gfx::RectF node_bounds,
Katie Dektardb71ad942017-11-29 20:07:48148 bool* offscreen = nullptr,
David Tseng7bf30c3c2022-07-22 15:13:37149 bool clip_bounds = true,
150 bool skip_container_offset = false) const;
Dominic Mazzoni2410fc62017-06-09 22:19:18151
152 // Get the bounds of a node in the coordinate space of the tree.
Katie Dektar2c6052d2017-09-27 00:32:32153 // If set, updates |offscreen| boolean to be true if the node is offscreen
154 // relative to its rootWebArea. Callers should initialize |offscreen|
155 // to false: this method may get called multiple times in a row and
156 // |offscreen| will be propagated.
Katie Dektardb71ad942017-11-29 20:07:48157 // If |clip_bounds| is true, result bounds will be clipped.
158 gfx::RectF GetTreeBounds(const AXNode* node,
159 bool* offscreen = nullptr,
160 bool clip_bounds = true) const;
Dominic Mazzoni2410fc62017-06-09 22:19:18161
Dominic Mazzoni35f2a5252017-09-26 00:56:04162 // Given a node ID attribute (one where IsNodeIdIntAttribute is true),
163 // and a destination node ID, return a set of all source node IDs that
164 // have that relationship attribute between them and the destination.
Nektarios Paisios527d33fb52021-02-23 19:23:28165 std::set<AXNodeID> GetReverseRelations(ax::mojom::IntAttribute attr,
166 AXNodeID dst_id) const;
Dominic Mazzoni35f2a5252017-09-26 00:56:04167
168 // Given a node ID list attribute (one where
169 // IsNodeIdIntListAttribute is true), and a destination node ID,
170 // return a set of all source node IDs that have that relationship
171 // attribute between them and the destination.
Nektarios Paisios527d33fb52021-02-23 19:23:28172 std::set<AXNodeID> GetReverseRelations(ax::mojom::IntListAttribute attr,
173 AXNodeID dst_id) const;
Dominic Mazzoni35f2a5252017-09-26 00:56:04174
Dominic Mazzoniaa774822018-08-29 20:33:58175 // Given a child tree ID, return the node IDs of all nodes in the tree who
176 // have a kChildTreeId int attribute with that value.
Nektarios Paisios50e579f12022-05-19 19:22:39177 //
178 // TODO(accessibility): There should really be only one host node per child
179 // tree, so the return value should not be a set but a single node ID or
180 // `kInvalidAXNodeID`.
Nektarios Paisios527d33fb52021-02-23 19:23:28181 std::set<AXNodeID> GetNodeIdsForChildTreeId(AXTreeID child_tree_id) const;
Dominic Mazzoniaa774822018-08-29 20:33:58182
Dominic Mazzoni748888c2018-11-01 22:34:59183 // Get all of the child tree IDs referenced by any node in this tree.
184 const std::set<AXTreeID> GetAllChildTreeIds() const;
185
David Tsengef6b480d2018-02-19 12:48:42186 // Map from a relation attribute to a map from a target id to source ids.
187 const IntReverseRelationMap& int_reverse_relations() {
188 return int_reverse_relations_;
189 }
190 const IntListReverseRelationMap& intlist_reverse_relations() {
191 return intlist_reverse_relations_;
192 }
Dominic Mazzoni3d9b5b92018-04-18 21:36:38193
[email protected]5eec2f52014-01-06 22:30:54194 // Return a multi-line indented string representation, for logging.
195 std::string ToString() const;
196
[email protected]d4e273462013-12-04 04:37:58197 // A string describing the error from an unsuccessful Unserialize,
198 // for testing and debugging.
tfarinad0bfb4b62015-02-18 17:20:32199 const std::string& error() const { return error_; }
[email protected]d4e273462013-12-04 04:37:58200
dmazzoniee2eaca2015-03-18 18:13:07201 int size() { return static_cast<int>(id_map_.size()); }
202
Dominic Mazzonid42e00a2018-06-27 23:14:23203 // Return a negative number that's suitable to use for a node ID for
204 // internal nodes created automatically by an AXTree, so as not to
205 // conflict with positive-numbered node IDs from tree sources.
Nektarios Paisios527d33fb52021-02-23 19:23:28206 AXNodeID GetNextNegativeInternalNodeId();
Dominic Mazzonid42e00a2018-06-27 23:14:23207
Akihiro Otaf42a7d02020-06-12 19:07:56208 // Returns the PosInSet of |node|. Looks in node_set_size_pos_in_set_info_map_
209 // for cached value. Calls |ComputeSetSizePosInSetAndCache|if no value is
210 // present in the cache.
Anton Bikineeveed0b26b2021-05-16 03:16:48211 absl::optional<int> GetPosInSet(const AXNode& node) override;
Akihiro Otaf42a7d02020-06-12 19:07:56212 // Returns the SetSize of |node|. Looks in node_set_size_pos_in_set_info_map_
213 // for cached value. Calls |ComputeSetSizePosInSetAndCache|if no value is
214 // present in the cache.
Anton Bikineeveed0b26b2021-05-16 03:16:48215 absl::optional<int> GetSetSize(const AXNode& node) override;
Akihiro Ota413ca722018-12-03 23:29:00216
Jacques Newman339afc62019-08-14 00:49:22217 Selection GetUnignoredSelection() const override;
218
Akihiro Otae3e420e2019-04-17 19:57:40219 bool GetTreeUpdateInProgressState() const override;
Akihiro Otae3e420e2019-04-17 19:57:40220
Kurt Catti-Schmidtc8445a12019-08-07 18:52:58221 // AXNode::OwnerTree override.
222 // Returns true if the tree represents a paginated document
223 bool HasPaginationSupport() const override;
224
Chris Hall697d99b2019-07-09 02:36:11225 // Language detection manager, entry point to language detection features.
226 // TODO(chrishall): Should this be stored by pointer or value?
227 // When should we initialize this?
228 std::unique_ptr<AXLanguageDetectionManager> language_detection_manager;
Chris Hall34208182019-03-13 02:26:18229
David Tseng41f13cbd2021-11-06 18:39:03230 // Event metadata while applying a tree update during unserialization.
231 AXEvent* event_data() const { return event_data_.get(); }
David Tsengb0d43662020-05-20 20:47:28232
Benjamin Beaudrye8f23a22020-12-17 20:08:02233 // Notify the delegate that the tree manager for |previous_tree_id| will be
234 // removed from the AXTreeManagerMap. Because we sometimes remove the tree
235 // manager after the tree's id has been modified, we need to pass the (old)
236 // tree id associated with the manager we are removing even though it is the
237 // same tree.
238 void NotifyTreeManagerWillBeRemoved(AXTreeID previous_tree_id);
239
[email protected]e736e81b2014-02-24 07:15:58240 private:
Nektarios Paisios8eb31fc2022-02-18 16:37:58241 friend class ScopedTreeUpdateInProgressStateSetter;
Dominic Mazzoniecfb4fd2018-10-23 07:34:20242 friend class AXTableInfoTest;
243
Nektarios Paisios77c422a2021-10-19 10:37:00244 // Indicates if the node with the focus should never be ignored, (see
245 // `SetFocusedNodeShouldNeverBeIgnored` above).
246 static bool is_focused_node_always_unignored_;
247
Aaron Leventhala674d632020-09-30 07:05:36248 // Accumulate errors as there can be more than one before Chrome is crashed
249 // via AccessibilityFatalError();
250 void RecordError(std::string new_error);
251
Dominic Mazzoniecfb4fd2018-10-23 07:34:20252 // AXNode::OwnerTree override.
253 //
254 // Given a node in this accessibility tree that corresponds to a table
255 // or grid, return an object containing information about the
256 // table structure. This object is computed lazily on-demand and
257 // cached until the next time the tree is updated. Clients should
258 // not retain this pointer, they should just request it every time
259 // it's needed.
260 //
261 // Returns nullptr if the node is not a valid table.
262 AXTableInfo* GetTableInfo(const AXNode* table_node) const override;
263
dtseng5a7b3d92016-09-08 06:35:58264 AXNode* CreateNode(AXNode* parent,
Dominic Mazzoni9ccdedb22021-01-30 17:59:42265 AXNodeID id,
Peter Kasting94a07a12019-05-22 19:26:28266 size_t index_in_parent,
dtseng5a7b3d92016-09-08 06:35:58267 AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03268
Adam Ettenbergerd9d8d58a2019-08-06 16:54:08269 // Accumulates the work that will be required to update the AXTree.
270 // This allows us to notify observers of structure changes when the
271 // tree is still in a stable and unchanged state.
272 bool ComputePendingChanges(const AXTreeUpdate& update,
Lei Zhanga06144782020-03-13 09:28:47273 AXTreeUpdateState* update_state);
Adam Ettenbergerd9d8d58a2019-08-06 16:54:08274
275 // Populates |update_state| with information about actions that will
276 // be performed on the tree during the update, such as adding or
277 // removing nodes in the tree. Returns true on success.
278 // Nothing within this call should modify tree structure or node data.
279 bool ComputePendingChangesToNode(const AXNodeData& new_data,
280 bool is_new_root,
281 AXTreeUpdateState* update_state);
282
[email protected]4b02bbca2013-11-22 08:59:03283 // This is called from within Unserialize(), it returns true on success.
dmazzoni67b4db22016-04-23 00:40:04284 bool UpdateNode(const AXNodeData& src,
285 bool is_new_root,
286 AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03287
Adam Ettenbergerd9d8d58a2019-08-06 16:54:08288 // Notify the delegate that the subtree rooted at |node| will be
289 // destroyed or reparented.
290 void NotifySubtreeWillBeReparentedOrDeleted(
291 AXNode* node,
292 const AXTreeUpdateState* update_state);
293
294 // Notify the delegate that |node| will be destroyed or reparented.
295 void NotifyNodeWillBeReparentedOrDeleted(
296 AXNode* node,
297 const AXTreeUpdateState* update_state);
298
299 // Notify the delegate that |node| and all of its descendants will be
Victor Feie3cce4c2019-11-14 18:35:41300 // destroyed. This function is called during AXTree teardown.
301 void RecursivelyNotifyNodeDeletedForTreeTeardown(AXNode* node);
302
303 // Notify the delegate that the node marked by |node_id| has been deleted.
304 // We are passing the node id instead of ax node is because by the time this
305 // function is called, the ax node in the tree will already have been
Adam Ettenbergerd9d8d58a2019-08-06 16:54:08306 // destroyed.
Dominic Mazzoni9ccdedb22021-01-30 17:59:42307 void NotifyNodeHasBeenDeleted(AXNodeID node_id);
Adam Ettenbergerd9d8d58a2019-08-06 16:54:08308
309 // Notify the delegate that |node| has been created or reparented.
310 void NotifyNodeHasBeenReparentedOrCreated(
311 AXNode* node,
312 const AXTreeUpdateState* update_state);
313
Nektarios Paisios77c422a2021-10-19 10:37:00314 // Notify the delegate that `node` will change its data attributes, including
315 // its ignored state.
316 void NotifyNodeAttributesWillChange(AXNode* node,
317 const AXTreeData* optional_old_tree_data,
318 const AXNodeData& old_data,
319 const AXTreeData* new_tree_data,
320 const AXNodeData& new_data);
Adam Ettenberger05afcec2019-08-06 17:11:29321
Nektarios Paisios77c422a2021-10-19 10:37:00322 // Notify the delegate that `node` has changed its data attributes, including
323 // its ignored state.
324 void NotifyNodeAttributesHaveBeenChanged(
325 AXNode* node,
326 const AXTreeData* optional_old_tree_data,
327 const AXNodeData& old_data,
328 const AXTreeData* new_tree_data,
329 const AXNodeData& new_data);
dmazzoni3ab5385c2017-03-13 18:07:03330
Dominic Mazzoni35f2a5252017-09-26 00:56:04331 void UpdateReverseRelations(AXNode* node, const AXNodeData& new_data);
332
Nektarios Paisios8eb31fc2022-02-18 16:37:58333 // Sets a flag indicating whether the tree is currently being updated or not.
334 // If the tree is being updated, then its internal pointers might be invalid
335 // and the tree should not be traversed.
336 void SetTreeUpdateInProgressState(bool set_tree_update_value);
337
Adam Ettenbergerd9d8d58a2019-08-06 16:54:08338 // Returns true if all pending changes in the |update_state| have been
339 // handled. If this returns false, the |error_| message will be populated.
340 // It's a fatal error to have pending changes after exhausting
341 // the AXTreeUpdate.
342 bool ValidatePendingChangesComplete(const AXTreeUpdateState& update_state);
[email protected]4b02bbca2013-11-22 08:59:03343
Adam Ettenbergerd9d8d58a2019-08-06 16:54:08344 // Modifies |update_state| so that it knows what subtree and nodes are
345 // going to be destroyed for the subtree rooted at |node|.
Dominic Mazzoni9ccdedb22021-01-30 17:59:42346 void MarkSubtreeForDestruction(AXNodeID node_id,
Adam Ettenbergerd9d8d58a2019-08-06 16:54:08347 AXTreeUpdateState* update_state);
348
349 // Modifies |update_state| so that it knows what nodes are
350 // going to be destroyed for the subtree rooted at |node|.
Dominic Mazzoni9ccdedb22021-01-30 17:59:42351 void MarkNodesForDestructionRecursive(AXNodeID node_id,
Adam Ettenbergerd9d8d58a2019-08-06 16:54:08352 AXTreeUpdateState* update_state);
353
354 // Validates that destroying the subtree rooted at |node| has required
355 // information in |update_state|, then calls DestroyNodeAndSubtree on it.
dmazzonie3b7faf2015-06-01 17:56:36356 void DestroySubtree(AXNode* node, AXTreeUpdateState* update_state);
dmazzonia4b48912015-01-24 00:08:56357
[email protected]4b02bbca2013-11-22 08:59:03358 // Call Destroy() on |node|, and delete it from the id map, and then
359 // call recursively on all nodes in its subtree.
dmazzonie3b7faf2015-06-01 17:56:36360 void DestroyNodeAndSubtree(AXNode* node, AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03361
362 // Iterate over the children of |node| and for each child, destroy the
Adam Ettenbergerd9d8d58a2019-08-06 16:54:08363 // child and its subtree if its id is not in |new_child_ids|.
364 void DeleteOldChildren(AXNode* node,
Nektarios Paisios527d33fb52021-02-23 19:23:28365 const std::vector<AXNodeID>& new_child_ids,
dmazzonie3b7faf2015-06-01 17:56:36366 AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03367
368 // Iterate over |new_child_ids| and populate |new_children| with
369 // pointers to child nodes, reusing existing nodes already in the tree
370 // if they exist, and creating otherwise. Reparenting is disallowed, so
371 // if the id already exists as the child of another node, that's an
[email protected]e736e81b2014-02-24 07:15:58372 // error. Returns true on success, false on fatal error.
[email protected]4b02bbca2013-11-22 08:59:03373 bool CreateNewChildVector(AXNode* node,
Nektarios Paisios527d33fb52021-02-23 19:23:28374 const std::vector<AXNodeID>& new_child_ids,
[email protected]d4e273462013-12-04 04:37:58375 std::vector<AXNode*>* new_children,
[email protected]e736e81b2014-02-24 07:15:58376 AXTreeUpdateState* update_state);
[email protected]4b02bbca2013-11-22 08:59:03377
Nektarios Paisios77c422a2021-10-19 10:37:00378 // Returns the lowest unignored ancestor of the node with the given ID. If the
379 // node is not ignored, it returns the node.
380 AXNode* GetUnignoredAncestorFromId(AXNodeID node_id) const;
381
Dominic Mazzonia1bb0d122019-09-26 20:19:59382 // Internal implementation of RelativeToTreeBounds. It calls itself
383 // recursively but ensures that it can only do so exactly once!
384 gfx::RectF RelativeToTreeBoundsInternal(const AXNode* node,
385 gfx::RectF node_bounds,
386 bool* offscreen,
387 bool clip_bounds,
David Tseng7bf30c3c2022-07-22 15:13:37388 bool skip_container_offset,
Dominic Mazzonia1bb0d122019-09-26 20:19:59389 bool allow_recursion) const;
390
Dominic Mazzoni8549eb682018-12-11 23:48:32391 base::ObserverList<AXTreeObserver> observers_;
Arthur Sonzogni4c9cdac2022-06-13 17:22:56392 raw_ptr<AXNode, DanglingUntriaged> root_ = nullptr;
[email protected]d4e273462013-12-04 04:37:58393 std::string error_;
dmazzoni329fd012015-10-22 20:05:35394 AXTreeData data_;
Jacob Francis78735e32022-06-30 22:02:52395 base::flat_map<AXNodeID, std::unique_ptr<AXNode>> id_map_;
Dominic Mazzoni35f2a5252017-09-26 00:56:04396
397 // Map from an int attribute (if IsNodeIdIntAttribute is true) to
398 // a reverse mapping from target nodes to source nodes.
David Tsengef6b480d2018-02-19 12:48:42399 IntReverseRelationMap int_reverse_relations_;
Dominic Mazzoni35f2a5252017-09-26 00:56:04400 // Map from an int list attribute (if IsNodeIdIntListAttribute is true) to
401 // a reverse mapping from target nodes to source nodes.
David Tsengef6b480d2018-02-19 12:48:42402 IntListReverseRelationMap intlist_reverse_relations_;
Dominic Mazzoniaa774822018-08-29 20:33:58403 // Map from child tree ID to the set of node IDs that contain that attribute.
Nektarios Paisios527d33fb52021-02-23 19:23:28404 std::map<AXTreeID, std::set<AXNodeID>> child_tree_id_reverse_map_;
Dominic Mazzoni3d9b5b92018-04-18 21:36:38405
406 // Map from node ID to cached table info, if the given node is a table.
Dominic Mazzonid42e00a2018-06-27 23:14:23407 // Invalidated every time the tree is updated.
Jacob Francis78735e32022-06-30 22:02:52408 mutable base::flat_map<AXNodeID, std::unique_ptr<AXTableInfo>>
Aaron Leventhal80797182020-02-25 18:50:31409 table_info_map_;
Dominic Mazzonid42e00a2018-06-27 23:14:23410
411 // The next negative node ID to use for internal nodes.
Nektarios Paisios527d33fb52021-02-23 19:23:28412 AXNodeID next_negative_internal_node_id_ = -1;
Dominic Mazzonid42e00a2018-06-27 23:14:23413
Akihiro Ota413ca722018-12-03 23:29:00414 // Contains pos_in_set and set_size data for an AXNode.
Stephan Hartmannaeef6882020-04-20 18:21:43415 struct NodeSetSizePosInSetInfo {
416 NodeSetSizePosInSetInfo();
417 ~NodeSetSizePosInSetInfo();
418
Anton Bikineeveed0b26b2021-05-16 03:16:48419 absl::optional<int> pos_in_set;
420 absl::optional<int> set_size;
421 absl::optional<int> lowest_hierarchical_level;
Stephan Hartmannaeef6882020-04-20 18:21:43422 };
Akihiro Ota413ca722018-12-03 23:29:00423
Victor Fei5eea952e2020-02-28 01:43:09424 // Represents the content of an ordered set which includes the ordered set
425 // items and the ordered set container if it exists.
426 struct OrderedSetContent;
427
428 // Maps a particular hierarchical level to a list of OrderedSetContents.
429 // Represents all ordered set items/container on a particular hierarchical
430 // level.
431 struct OrderedSetItemsMap;
432
433 // Populates |items_map_to_be_populated| with all items associated with
Victor Feid95130c2020-02-03 21:42:54434 // |original_node| and within |ordered_set|. Only items whose roles match the
435 // role of the |ordered_set| will be added.
Victor Fei5eea952e2020-02-28 01:43:09436 void PopulateOrderedSetItemsMap(
Victor Feid95130c2020-02-03 21:42:54437 const AXNode& original_node,
438 const AXNode* ordered_set,
Lei Zhanga06144782020-03-13 09:28:47439 OrderedSetItemsMap* items_map_to_be_populated) const;
Victor Feid95130c2020-02-03 21:42:54440
Victor Fei5eea952e2020-02-28 01:43:09441 // Helper function for recursively populating ordered sets items map with
Victor Feid95130c2020-02-03 21:42:54442 // all items associated with |original_node| and |ordered_set|. |local_parent|
443 // tracks the recursively passed in child nodes of |ordered_set|.
Victor Fei5eea952e2020-02-28 01:43:09444 void RecursivelyPopulateOrderedSetItemsMap(
Victor Feid95130c2020-02-03 21:42:54445 const AXNode& original_node,
446 const AXNode* ordered_set,
447 const AXNode* local_parent,
Anton Bikineeveed0b26b2021-05-16 03:16:48448 absl::optional<int> ordered_set_min_level,
449 absl::optional<int> prev_level,
Lei Zhanga06144782020-03-13 09:28:47450 OrderedSetItemsMap* items_map_to_be_populated) const;
Akihiro Ota886a96d62018-12-18 00:11:48451
Victor Fei5eea952e2020-02-28 01:43:09452 // Computes the pos_in_set and set_size values of all items in ordered_set and
453 // caches those values. Called by GetPosInSet and GetSetSize.
Akihiro Ota886a96d62018-12-18 00:11:48454 void ComputeSetSizePosInSetAndCache(const AXNode& node,
455 const AXNode* ordered_set);
Akihiro Ota413ca722018-12-03 23:29:00456
Victor Fei5eea952e2020-02-28 01:43:09457 // Helper for ComputeSetSizePosInSetAndCache. Computes and caches the
458 // pos_in_set and set_size values for a given OrderedSetContent.
459 void ComputeSetSizePosInSetAndCacheHelper(
460 const OrderedSetContent& ordered_set_content);
461
Akihiro Otab6a8a4d2018-12-04 01:56:39462 // Map from node ID to OrderedSetInfo.
463 // Item-like and ordered-set-like objects will map to populated OrderedSetInfo
464 // objects.
465 // All other objects will map to default-constructed OrderedSetInfo objects.
Akihiro Ota413ca722018-12-03 23:29:00466 // Invalidated every time the tree is updated.
Jacob Francis78735e32022-06-30 22:02:52467 mutable base::flat_map<AXNodeID, NodeSetSizePosInSetInfo>
Victor Fei5eea952e2020-02-28 01:43:09468 node_set_size_pos_in_set_info_map_;
Chris Hall9b34c2c2018-12-04 01:45:56469
Akihiro Otae3e420e2019-04-17 19:57:40470 // Indicates if the tree is updating.
471 bool tree_update_in_progress_ = false;
Kurt Catti-Schmidtc8445a12019-08-07 18:52:58472
473 // Indicates if the tree represents a paginated document
474 bool has_pagination_support_ = false;
David Tsengb0d43662020-05-20 20:47:28475
David Tseng41f13cbd2021-11-06 18:39:03476 std::unique_ptr<AXEvent> event_data_;
[email protected]4b02bbca2013-11-22 08:59:03477};
478
Nektarios Paisios8eb31fc2022-02-18 16:37:58479// Sets the flag that indicates whether the accessibility tree is currently
480// being updated, and ensures that it is reset to its previous value when the
481// instance is destructed. An accessibility tree that is being updated is
482// unstable and should not be traversed.
483class AX_EXPORT ScopedTreeUpdateInProgressStateSetter {
484 public:
485 explicit ScopedTreeUpdateInProgressStateSetter(AXTree& tree)
486 : tree_(&tree),
487 last_tree_update_in_progress_(tree.GetTreeUpdateInProgressState()) {
488 tree_->SetTreeUpdateInProgressState(true);
489 }
490
491 ~ScopedTreeUpdateInProgressStateSetter() {
492 tree_->SetTreeUpdateInProgressState(last_tree_update_in_progress_);
493 }
494
495 ScopedTreeUpdateInProgressStateSetter(
496 const ScopedTreeUpdateInProgressStateSetter&) = delete;
497 ScopedTreeUpdateInProgressStateSetter& operator=(
498 const ScopedTreeUpdateInProgressStateSetter&) = delete;
499
500 private:
Keishi Hattorie175ac52022-06-07 06:24:57501 const raw_ptr<AXTree> tree_;
Nektarios Paisios8eb31fc2022-02-18 16:37:58502 bool last_tree_update_in_progress_;
503};
504
[email protected]4b02bbca2013-11-22 08:59:03505} // namespace ui
506
507#endif // UI_ACCESSIBILITY_AX_TREE_H_