blob: bdf8a464d77adcaeda4e29b3b6d2170587f8f890 [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"
Aaron Leventhalbc649ff2022-08-11 18:53:2317#include "base/debug/crash_logging.h"
Keishi Hattori0e45c022021-11-27 09:25:5218#include "base/memory/raw_ptr.h"
Jacques Newman5846e622021-01-15 02:15:5919#include "base/metrics/histogram_functions.h"
Dominic Mazzoni8549eb682018-12-11 23:48:3220#include "base/observer_list.h"
Nektarios Paisios77c422a2021-10-19 10:37:0021#include "third_party/abseil-cpp/absl/types/optional.h"
James Cook36cab7c2019-10-29 23:26:4022#include "ui/accessibility/ax_enums.mojom-forward.h"
[email protected]4b02bbca2013-11-22 08:59:0323#include "ui/accessibility/ax_export.h"
dmazzoni329fd012015-10-22 20:05:3524#include "ui/accessibility/ax_tree_data.h"
[email protected]4b02bbca2013-11-22 08:59:0325#include "ui/accessibility/ax_tree_update.h"
26
27namespace ui {
28
David Tseng41f13cbd2021-11-06 18:39:0329struct AXEvent;
Alexander Surkov4ab64cf2022-09-01 20:07:4630class AXLanguageDetectionManager;
31class AXNode;
32struct AXNodeData;
Dominic Mazzoni3d9b5b92018-04-18 21:36:3833class AXTableInfo;
Dominic Mazzoni8549eb682018-12-11 23:48:3234class AXTreeObserver;
[email protected]e736e81b2014-02-24 07:15:5835struct AXTreeUpdateState;
Alexander Surkov253235e2022-08-23 01:52:1236class AXSelection;
[email protected]e736e81b2014-02-24 07:15:5837
Jacques Newman5846e622021-01-15 02:15:5938// These values are persisted to logs. Entries should not be renumbered and
39// numeric values should never be reused.
40enum class AXTreeUnserializeError {
41 // Tree has no root.
42 kNoRoot = 0,
43 // Node will not be in the tree and is not the new root.
44 kNotInTree = 1,
45 // Node is already pending for creation, cannot be the new root
46 kCreationPending = 2,
47 // Node has duplicate child.
48 kDuplicateChild = 3,
49 // Node is already pending for creation, cannot be a new child.
50 kCreationPendingForChild = 4,
51 // Node is not marked for destruction, would be reparented.
52 kReparent = 5,
53 // Nodes are left pending by the update.
54 kPendingNodes = 6,
55 // Changes left pending by the update;
56 kPendingChanges = 7,
57 // This must always be the last enum. It's okay for its value to
58 // increase, but none of the other enum values may change.
59 kMaxValue = kPendingChanges
60};
61
62#define ACCESSIBILITY_TREE_UNSERIALIZE_ERROR_HISTOGRAM(enum_value) \
63 base::UmaHistogramEnumeration( \
64 "Accessibility.Reliability.Tree.UnserializeError", enum_value)
65
[email protected]4b02bbca2013-11-22 08:59:0366// AXTree is a live, managed tree of AXNode objects that can receive
67// updates from another AXTreeSource via AXTreeUpdates, and it can be
68// used as a source for sending updates to another client tree.
69// It's designed to be subclassed to implement support for native
70// accessibility APIs on a specific platform.
Alexander Surkov4ab64cf2022-09-01 20:07:4671class AX_EXPORT AXTree {
[email protected]4b02bbca2013-11-22 08:59:0372 public:
Lei Zhanga06144782020-03-13 09:28:4773 using IntReverseRelationMap =
Nektarios Paisios527d33fb52021-02-23 19:23:2874 std::map<ax::mojom::IntAttribute, std::map<AXNodeID, std::set<AXNodeID>>>;
Lei Zhanga06144782020-03-13 09:28:4775 using IntListReverseRelationMap =
76 std::map<ax::mojom::IntListAttribute,
Nektarios Paisios527d33fb52021-02-23 19:23:2877 std::map<AXNodeID, std::set<AXNodeID>>>;
David Tsengef6b480d2018-02-19 12:48:4278
Nektarios Paisios77c422a2021-10-19 10:37:0079 // If called, the focused node in this tree will never be ignored, even if it
80 // has the ignored state set. For now, this boolean will be set to false for
81 // all trees except in test scenarios, in order to thoroughly test the
82 // relevant code without causing any potential regressions. Ultimately, we
83 // want to expose all focused nodes so that a user of an assistive technology
84 // will be able to interact with the application / website, even if there is
85 // an authoring error, e.g. the aria-hidden attribute has been applied to the
86 // focused element.
87 // TODO(nektar): Removed once the feature has been fully tested.
88 static void SetFocusedNodeShouldNeverBeIgnored();
89
90 // Determines the ignored state of a node, given information about the node
91 // and the tree.
92 static bool ComputeNodeIsIgnored(const AXTreeData* optional_tree_data,
93 const AXNodeData& node_data);
94
95 // Determines whether a node has flipped its ignored state, given information
96 // about the previous and current state of the node / tree.
97 static bool ComputeNodeIsIgnoredChanged(
98 const AXTreeData* optional_old_tree_data,
99 const AXNodeData& old_node_data,
100 const AXTreeData* optional_new_tree_data,
101 const AXNodeData& new_node_data);
102
[email protected]4b02bbca2013-11-22 08:59:03103 AXTree();
dmazzoni329fd012015-10-22 20:05:35104 explicit AXTree(const AXTreeUpdate& initial_state);
[email protected]4b02bbca2013-11-22 08:59:03105 virtual ~AXTree();
106
Lei Zhanga06144782020-03-13 09:28:47107 // AXTree owns pointers so copying is non-trivial.
108 AXTree(const AXTree&) = delete;
109 AXTree& operator=(const AXTree&) = delete;
110
Dominic Mazzoni8549eb682018-12-11 23:48:32111 void AddObserver(AXTreeObserver* observer);
112 bool HasObserver(AXTreeObserver* observer);
Nektarios Paisiosdb7b5ee2020-02-18 21:28:11113 void RemoveObserver(AXTreeObserver* observer);
Dominic Mazzoni8549eb682018-12-11 23:48:32114
115 base::ObserverList<AXTreeObserver>& observers() { return observers_; }
[email protected]e736e81b2014-02-24 07:15:58116
tfarina6b1c1e082015-02-20 23:47:07117 AXNode* root() const { return root_; }
118
Alexander Surkov4ab64cf2022-09-01 20:07:46119 const AXTreeData& data() const;
dmazzoni329fd012015-10-22 20:05:35120
Nektarios Paisiosdb7b5ee2020-02-18 21:28:11121 // Destroys the tree and notifies all observers.
122 void Destroy();
123
Adam Ettenberger86af2532019-09-17 20:04:46124 // Returns the globally unique ID of this accessibility tree.
Alexander Surkov4ab64cf2022-09-01 20:07:46125 const AXTreeID& GetAXTreeID() const;
Adam Ettenberger86af2532019-09-17 20:04:46126
Alexander Surkov4ab64cf2022-09-01 20:07:46127 // Given a node in this accessibility tree that corresponds to a table
128 // or grid, return an object containing information about the
129 // table structure. This object is computed lazily on-demand and
130 // cached until the next time the tree is updated. Clients should
131 // not retain this pointer, they should just request it every time
132 // it's needed.
133 //
134 // Returns nullptr if the node is not a valid table.
135 AXTableInfo* GetTableInfo(const AXNode* table_node) const;
136
tfarina6b1c1e082015-02-20 23:47:07137 // Returns the AXNode with the given |id| if it is part of this AXTree.
Alexander Surkov4ab64cf2022-09-01 20:07:46138 AXNode* GetFromId(AXNodeID id) const;
[email protected]4b02bbca2013-11-22 08:59:03139
[email protected]d4e273462013-12-04 04:37:58140 // Returns true on success. If it returns false, it's a fatal error
141 // and this tree should be destroyed, and the source of the tree update
142 // should not be trusted any longer.
dmazzoni329fd012015-10-22 20:05:35143 virtual bool Unserialize(const AXTreeUpdate& update);
144
Nektarios Paisios26ac2b42021-06-02 18:24:19145 // Used by tests to update the tree data without changing any of the nodes in
146 // the tree, notifying all tree observers in the process.
147 virtual void UpdateDataForTesting(const AXTreeData& data);
[email protected]4b02bbca2013-11-22 08:59:03148
Dominic Mazzoni2410fc62017-06-09 22:19:18149 // Convert any rectangle from the local coordinate space of one node in
150 // the tree, to bounds in the coordinate space of the tree.
Katie Dektar2c6052d2017-09-27 00:32:32151 // If set, updates |offscreen| boolean to be true if the node is offscreen
152 // relative to its rootWebArea. Callers should initialize |offscreen|
153 // to false: this method may get called multiple times in a row and
154 // |offscreen| will be propagated.
Katie Dektardb71ad942017-11-29 20:07:48155 // If |clip_bounds| is true, result bounds will be clipped.
Dominic Mazzoni2410fc62017-06-09 22:19:18156 gfx::RectF RelativeToTreeBounds(const AXNode* node,
Katie Dektar2c6052d2017-09-27 00:32:32157 gfx::RectF node_bounds,
Katie Dektar