Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
ax_event_generator.h
Go to the documentation of this file.
1// Copyright 2017 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_EVENT_GENERATOR_H_
6#define UI_ACCESSIBILITY_AX_EVENT_GENERATOR_H_
7
8#include <bitset>
9#include <map>
10#include <ostream>
11#include <set>
12#include <vector>
13
14#include "ax_event_intent.h"
15#include "ax_export.h"
16#include "ax_tree.h"
17#include "ax_tree_observer.h"
18
19namespace ui {
20
21// Subclass of AXTreeObserver that automatically generates AXEvents to fire
22// based on changes to an accessibility tree. Every platform
23// tends to want different events, so this class lets each platform
24// handle the events it wants and ignore the others.
26 public:
27 enum class Event : int32_t {
28 ACCESS_KEY_CHANGED,
29 ACTIVE_DESCENDANT_CHANGED,
30 ALERT,
31 // ATK treats alignment, indentation, and other format-related attributes as
32 // text attributes even when they are only applicable to the entire object.
33 // And it lacks an event for object attributes changing.
34 ATK_TEXT_OBJECT_ATTRIBUTE_CHANGED,
35 ATOMIC_CHANGED,
36 AUTO_COMPLETE_CHANGED,
37 BUSY_CHANGED,
38 CHECKED_STATE_CHANGED,
39 CHILDREN_CHANGED,
40 CLASS_NAME_CHANGED,
41 COLLAPSED,
42 CONTROLS_CHANGED,
43 DESCRIBED_BY_CHANGED,
44 DESCRIPTION_CHANGED,
45 DOCUMENT_SELECTION_CHANGED,
46 DOCUMENT_TITLE_CHANGED,
47 DROPEFFECT_CHANGED,
48 ENABLED_CHANGED,
49 EXPANDED,
50 FOCUS_CHANGED,
51 FLOW_FROM_CHANGED,
52 FLOW_TO_CHANGED,
53 GRABBED_CHANGED,
54 HASPOPUP_CHANGED,
55 HIERARCHICAL_LEVEL_CHANGED,
56 IGNORED_CHANGED,
57 IMAGE_ANNOTATION_CHANGED,
58 INVALID_STATUS_CHANGED,
59 KEY_SHORTCUTS_CHANGED,
60 LABELED_BY_CHANGED,
61 LANGUAGE_CHANGED,
62 LAYOUT_INVALIDATED, // Fired when aria-busy goes false
63 LIVE_REGION_CHANGED, // Fired on the root of a live region.
64 LIVE_REGION_CREATED,
65 LIVE_REGION_NODE_CHANGED, // Fired on a node within a live region.
66 LIVE_RELEVANT_CHANGED,
67 LIVE_STATUS_CHANGED,
68 LOAD_COMPLETE,
69 LOAD_START,
70 MENU_ITEM_SELECTED,
71 MULTILINE_STATE_CHANGED,
72 MULTISELECTABLE_STATE_CHANGED,
73 NAME_CHANGED,
74 OBJECT_ATTRIBUTE_CHANGED,
75 OTHER_ATTRIBUTE_CHANGED,
76 PLACEHOLDER_CHANGED,
77 PORTAL_ACTIVATED,
78 POSITION_IN_SET_CHANGED,
79 RELATED_NODE_CHANGED,
80 READONLY_CHANGED,
81 REQUIRED_STATE_CHANGED,
82 ROLE_CHANGED,
83 ROW_COUNT_CHANGED,
84 SCROLL_HORIZONTAL_POSITION_CHANGED,
85 SCROLL_VERTICAL_POSITION_CHANGED,
86 SELECTED_CHANGED,
87 SELECTED_CHILDREN_CHANGED,
88 SET_SIZE_CHANGED,
89 SORT_CHANGED,
90 STATE_CHANGED,
91 SUBTREE_CREATED,
92 TEXT_ATTRIBUTE_CHANGED,
93 VALUE_CHANGED,
94 VALUE_MAX_CHANGED,
95 VALUE_MIN_CHANGED,
96 VALUE_STEP_CHANGED,
97
98 // This event is for the exact set of attributes that affect
99 // the MSAA/IAccessible state on Windows. Not needed on other platforms,
100 // but very natural to compute here.
101 WIN_IACCESSIBLE_STATE_CHANGED,
102 };
103
104 // For distinguishing between show and hide state when a node has
105 // IGNORED_CHANGED event.
106 enum class IgnoredChangedState : uint8_t { kShow, kHide, kCount = 2 };
107
108 struct EventParams {
110 ax::mojom::EventFrom event_from,
111 const std::vector<AXEventIntent>& event_intents);
115 std::vector<AXEventIntent> event_intents;
116
117 bool operator==(const EventParams& rhs);
118 bool operator<(const EventParams& rhs) const;
119 };
120
122 // |node| must not be null
123 TargetedEvent(ui::AXNode* node, const EventParams& event_params);
126 };
127
129 : public std::iterator<std::input_iterator_tag, TargetedEvent> {
130 public:
131 Iterator(
132 const std::map<AXNode*, std::set<EventParams>>& map,
133 const std::map<AXNode*, std::set<EventParams>>::const_iterator& head);
134 Iterator(const Iterator& other);
136
137 bool operator!=(const Iterator& rhs) const;
138 Iterator& operator++();
139 TargetedEvent operator*() const;
140
141 private:
142 const std::map<AXNode*, std::set<EventParams>>& map_;
143 std::map<AXNode*, std::set<EventParams>>::const_iterator map_iter_;
144 std::set<EventParams>::const_iterator set_iter_;
145 };
146
147 // For storing ignored changed states for a particular node. We use bitset as
148 // the underlying data structure to improve memory usage.
149 // We use the index of AXEventGenerator::IgnoredChangedState enum
150 // to access the bitset data.
151 // e.g. AXEventGenerator::IgnoredChangedState::kShow has index 0 in the
152 // IgnoredChangedState enum. If |IgnoredChangedStatesBitset[0]| is set, it
153 // means IgnoredChangedState::kShow is present. Similarly, kHide has index 1
154 // in the enum, and it corresponds to |IgnoredChangedStatesBitset[1]|.
156 std::bitset<static_cast<size_t>(IgnoredChangedState::kCount)>;
160
161 // If you use this constructor, you must call SetTree
162 // before using this class.
164
165 // Automatically registers itself as the observer of |tree| and
166 // clears it on destruction. |tree| must be valid for the lifetime
167 // of this object.
168 explicit AXEventGenerator(AXTree* tree);
169
171
172 // Clears this class as the observer of the previous tree that was
173 // being monitored, if any, and starts monitoring |new_tree|, if not
174 // nullptr. Note that |new_tree| must be valid for the lifetime of
175 // this object or until you call SetTree again.
176 void SetTree(AXTree* new_tree);
177
178 // Null |tree_| without accessing it or destroying it.
179 void ReleaseTree();
180
181 Iterator begin() const {
182 return Iterator(tree_events_, tree_events_.begin());
183 }
184 Iterator end() const { return Iterator(tree_events_, tree_events_.end()); }
185
186 // Clear any previously added events.
187 void ClearEvents();
188
189 // This is called automatically based on changes to the tree observed
190 // by AXTreeObserver, but you can also call it directly to add events
191 // and retrieve them later.
192 //
193 // Note that events are organized by node and then by event id to
194 // efficiently remove duplicates, so events won't be retrieved in the
195 // same order they were added.
196 void AddEvent(ui::AXNode* node, Event event);
197
199 always_fire_load_complete_ = val;
200 }
201
202 protected:
203 // AXTreeObserver overrides.
204 void OnNodeDataChanged(AXTree* tree,
205 const AXNodeData& old_node_data,
206 const AXNodeData& new_node_data) override;
207 void OnRoleChanged(AXTree* tree,
208 AXNode* node,
209 ax::mojom::Role old_role,
210 ax::mojom::Role new_role) override;
211 void OnStateChanged(AXTree* tree,
212 AXNode* node,
214 bool new_value) override;
215 void OnStringAttributeChanged(AXTree* tree,
216 AXNode* node,
218 const std::string& old_value,
219 const std::string& new_value) override;
220 void OnIntAttributeChanged(AXTree* tree,
221 AXNode* node,
223 int32_t old_value,
224 int32_t new_value) override;
225 void OnFloatAttributeChanged(AXTree* tree,
226 AXNode* node,
228 float old_value,
229 float new_value) override;
230 void OnBoolAttributeChanged(AXTree* tree,
231 AXNode* node,
233 bool new_value) override;
234 void OnIntListAttributeChanged(
235 AXTree* tree,
236 AXNode* node,
238 const std::vector<int32_t>& old_value,
239 const std::vector<int32_t>& new_value) override;
240 void OnTreeDataChanged(AXTree* tree,
241 const ui::AXTreeData& old_data,
242 const ui::AXTreeData& new_data) override;
243 void OnNodeWillBeDeleted(AXTree* tree, AXNode* node) override;
244 void OnSubtreeWillBeDeleted(AXTree* tree, AXNode* node) override;
245 void OnNodeWillBeReparented(AXTree* tree, AXNode* node) override;
246 void OnSubtreeWillBeReparented(AXTree* tree, AXNode* node) override;
247 void OnAtomicUpdateFinished(AXTree* tree,
248 bool root_changed,
249 const std::vector<Change>& changes) override;
250
251 private:
252 void FireLiveRegionEvents(AXNode* node);
253 void FireActiveDescendantEvents();
254 void FireRelationSourceEvents(AXTree* tree, AXNode* target_node);
255 bool ShouldFireLoadEvents(AXNode* node);
256 // Remove excessive events for a tree update containing node.
257 // We remove certain events on a node when it flips its IGNORED state to
258 // either show/hide and one of the node's ancestor has also flipped its
259 // IGNORED state in the same way (show/hide) in the tree update.
260 // |ancestor_has_ignored_map| contains if a node's ancestor has changed to
261 // IGNORED state.
262 // Map's key is an AXNode.
263 // Map's value is a std::bitset containing IgnoredChangedStates(kShow/kHide).
264 // - Map's value IgnoredChangedStatesBitset contains kShow if an ancestor
265 // of node removed its IGNORED state.
266 // - Map's value IgnoredChangedStatesBitset contains kHide if an ancestor
267 // of node changed to IGNORED state.
268 // - When IgnoredChangedStatesBitset is not set, it means neither the
269 // node nor its ancestor has IGNORED_CHANGED.
270 void TrimEventsDueToAncestorIgnoredChanged(
271 AXNode* node,
272 std::map<AXNode*, IgnoredChangedStatesBitset>&
273 ancestor_ignored_changed_map);
274 void PostprocessEvents();
275 static void GetRestrictionStates(ax::mojom::Restriction restriction,
276 bool* is_enabled,
277 bool* is_readonly);
278
279 // Returns a vector of values unique to either |lhs| or |rhs|
280 static std::vector<int32_t> ComputeIntListDifference(
281 const std::vector<int32_t>& lhs,
282 const std::vector<int32_t>& rhs);
283
284 AXTree* tree_ = nullptr; // Not owned.
285 std::map<AXNode*, std::set<EventParams>> tree_events_;
286
287 // Valid between the call to OnIntAttributeChanged and the call to
288 // OnAtomicUpdateFinished. List of nodes whose active descendant changed.
289 std::vector<AXNode*> active_descendant_changed_;
290
291 bool always_fire_load_complete_ = false;
292};
293
294AX_EXPORT std::ostream& operator<<(std::ostream& os,
297
298} // namespace ui
299
300#endif // UI_ACCESSIBILITY_AX_EVENT_GENERATOR_H_
static SkSize operator*(SkISize u, SkScalar s)
bool operator!=(const sk_sp< T > &a, const sk_sp< U > &b)
Definition SkRefCnt.h:355
#define AX_EXPORT
Definition ax_export.h:29
Iterator(const Iterator &other)
void set_always_fire_load_complete(bool val)
~AXEventGenerator() override
std::bitset< static_cast< size_t >(IgnoredChangedState::kCount)> IgnoredChangedStatesBitset
static bool operator<(const SkPlainTextEditor::Editor::TextPosition &u, const SkPlainTextEditor::Editor::TextPosition &v)
Definition editor.h:140
bool operator==(const FlutterPoint &a, const FlutterPoint &b)
AtkStateType state
FlKeyEvent * event
const char * ToString(ax::mojom::Event event)
std::ostream & operator<<(std::ostream &os, AXEventGenerator::Event event)
static Target * is_enabled(Benchmark *bench, const Config &config)
std::vector< AXEventIntent > event_intents