Flutter Engine
 
Loading...
Searching...
No Matches
accessibility_bridge.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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 FLUTTER_SHELL_PLATFORM_COMMON_ACCESSIBILITY_BRIDGE_H_
6#define FLUTTER_SHELL_PLATFORM_COMMON_ACCESSIBILITY_BRIDGE_H_
7
8#include <unordered_map>
9
10#include "flutter/fml/mapping.h"
12
18
20
21namespace flutter {
22
23//------------------------------------------------------------------------------
24/// Use this class to maintain an accessibility tree. This class consumes
25/// semantics updates from the embedder API and produces an accessibility tree
26/// in the native format.
27///
28/// The bridge creates an AXTree to hold the semantics data that comes from
29/// Flutter semantics updates. The tree holds AXNode[s] which contain the
30/// semantics information for semantics node. The AXTree resemble the Flutter
31/// semantics tree in the Flutter framework. The bridge also uses
32/// FlutterPlatformNodeDelegate to wrap each AXNode in order to provide
33/// an accessibility tree in the native format.
34///
35/// To use this class, one must subclass this class and provide their own
36/// implementation of FlutterPlatformNodeDelegate.
37///
38/// AccessibilityBridge must be created as a shared_ptr, since some methods
39/// acquires its weak_ptr.
41 : public std::enable_shared_from_this<AccessibilityBridge>,
44 private ui::AXTreeObserver {
45 public:
46 //-----------------------------------------------------------------------------
47 /// @brief Creates a new instance of a accessibility bridge.
49 virtual ~AccessibilityBridge();
50
51 //------------------------------------------------------------------------------
52 /// @brief Adds a semantics node update to the pending semantics update.
53 /// Calling this method alone will NOT update the semantics tree.
54 /// To flush the pending updates, call the CommitUpdates().
55 ///
56 /// @param[in] node A reference to the semantics node update.
58
59 //------------------------------------------------------------------------------
60 /// @brief Adds a custom semantics action update to the pending semantics
61 /// update. Calling this method alone will NOT update the
62 /// semantics tree. To flush the pending updates, call the
63 /// CommitUpdates().
64 ///
65 /// @param[in] action A reference to the custom semantics action
66 /// update.
69
70 //------------------------------------------------------------------------------
71 /// @brief Flushes the pending updates and applies them to this
72 /// accessibility bridge. Calling this with no pending updates
73 /// does nothing, and callers should call this method at the end
74 /// of an atomic batch to avoid leaving the tree in a unstable
75 /// state. For example if a node reparents from A to B, callers
76 /// should only call this method when both removal from A and
77 /// addition to B are in the pending updates.
78 void CommitUpdates();
79
80 //------------------------------------------------------------------------------
81 /// @brief Get the flutter platform node delegate with the given id from
82 /// this accessibility bridge. Returns expired weak_ptr if the
83 /// delegate associated with the id does not exist or has been
84 /// removed from the accessibility tree.
85 ///
86 /// @param[in] id The id of the flutter accessibility node you want
87 /// to retrieve.
88 std::weak_ptr<FlutterPlatformNodeDelegate>
90
91 //------------------------------------------------------------------------------
92 /// @brief Get the ax tree data from this accessibility bridge. The tree
93 /// data contains information such as the id of the node that
94 /// has the keyboard focus or the text selection range.
95 const ui::AXTreeData& GetAXTreeData() const;
96
97 //------------------------------------------------------------------------------
98 /// @brief Gets all pending accessibility events generated during
99 /// semantics updates. This is useful when deciding how to handle
100 /// events in AccessibilityBridgeDelegate::OnAccessibilityEvent in
101 /// case one may decide to handle an event differently based on
102 /// all pending events.
103 const std::vector<ui::AXEventGenerator::TargetedEvent> GetPendingEvents()
104 const;
105
106 // |AXTreeManager|
108 const ui::AXNode::AXID node_id) const override;
109
110 // |AXTreeManager|
111 ui::AXNode* GetNodeFromTree(const ui::AXNode::AXID node_id) const override;
112
113 // |AXTreeManager|
114 ui::AXTreeID GetTreeID() const override;
115
116 // |AXTreeManager|
117 ui::AXTreeID GetParentTreeID() const override;
118
119 // |AXTreeManager|
120 ui::AXNode* GetRootAsAXNode() const override;
121
122 // |AXTreeManager|
124
125 // |AXTreeManager|
126 ui::AXTree* GetTree() const override;
127
128 // |AXPlatformTreeManager|
130 const ui::AXNode::AXID node_id) const override;
131
132 // |AXPlatformTreeManager|
134 const ui::AXNode& node) const override;
135
136 // |AXPlatformTreeManager|
138
139 protected:
140 //---------------------------------------------------------------------------
141 /// @brief Handle accessibility events generated due to accessibility
142 /// tree changes. These events are needed to be sent to native
143 /// accessibility system. See ui::AXEventGenerator::Event for
144 /// possible events.
145 ///
146 /// @param[in] targeted_event The object that contains both the
147 /// generated event and the event target.
149 ui::AXEventGenerator::TargetedEvent targeted_event) = 0;
150
151 //---------------------------------------------------------------------------
152 /// @brief Creates a platform specific FlutterPlatformNodeDelegate.
153 /// Ownership passes to the caller. This method will be called
154 /// whenever a new AXNode is created in AXTree. Each platform
155 /// needs to implement this method in order to inject its
156 /// subclass into the accessibility bridge.
157 virtual std::shared_ptr<FlutterPlatformNodeDelegate>
159
160 private:
161 // See FlutterSemanticsNode in embedder.h
162 typedef struct {
163 int32_t id;
166 int32_t text_selection_base;
167 int32_t text_selection_extent;
168 int32_t scroll_child_count;
169 int32_t scroll_index;
170 double scroll_position;
171 double scroll_extent_max;
172 double scroll_extent_min;
173 std::string label;
174 std::string hint;
175 std::string value;
176 std::string increased_value;
177 std::string decreased_value;
178 std::string tooltip;
179 FlutterTextDirection text_direction;
180 FlutterRect rect;
182 std::vector<int32_t> children_in_traversal_order;
183 std::vector<int32_t> custom_accessibility_actions;
184 int32_t heading_level;
185 std::string identifier;
187
188 // See FlutterSemanticsCustomAction in embedder.h
189 typedef struct {
190 int32_t id;
191 FlutterSemanticsAction override_action;
192 std::string label;
193 std::string hint;
194 } SemanticsCustomAction;
195
196 std::unordered_map<AccessibilityNodeId,
197 std::shared_ptr<FlutterPlatformNodeDelegate>>
198 id_wrapper_map_;
199 std::unique_ptr<ui::AXTree> tree_;
200 ui::AXEventGenerator event_generator_;
201 std::unordered_map<int32_t, SemanticsNode> pending_semantics_node_updates_;
202 std::unordered_map<int32_t, SemanticsCustomAction>
203 pending_semantics_custom_action_updates_;
205
206 void InitAXTree(const ui::AXTreeUpdate& initial_state);
207
208 // Create an update that removes any nodes that will be reparented by
209 // pending_semantics_updates_. Returns std::nullopt if none are reparented.
210 std::optional<ui::AXTreeUpdate> CreateRemoveReparentedNodesUpdate();
211
212 void GetSubTreeList(const SemanticsNode& target,
213 std::vector<SemanticsNode>& result);
214 void ConvertFlutterUpdate(const SemanticsNode& node,
215 ui::AXTreeUpdate& tree_update);
216 void SetRoleFromFlutterUpdate(ui::AXNodeData& node_data,
217 const SemanticsNode& node);
218 void SetStateFromFlutterUpdate(ui::AXNodeData& node_data,
219 const SemanticsNode& node);
220 void SetActionsFromFlutterUpdate(ui::AXNodeData& node_data,
221 const SemanticsNode& node);
222 void SetBooleanAttributesFromFlutterUpdate(ui::AXNodeData& node_data,
223 const SemanticsNode& node);
224 void SetIntAttributesFromFlutterUpdate(ui::AXNodeData& node_data,
225 const SemanticsNode& node);
226 void SetIntListAttributesFromFlutterUpdate(ui::AXNodeData& node_data,
227 const SemanticsNode& node);
228 void SetStringListAttributesFromFlutterUpdate(ui::AXNodeData& node_data,
229 const SemanticsNode& node);
230 void SetIdentifierFromFlutterUpdate(ui::AXNodeData& node_data,
231 const SemanticsNode& node);
232 void SetNameFromFlutterUpdate(ui::AXNodeData& node_data,
233 const SemanticsNode& node);
234 void SetValueFromFlutterUpdate(ui::AXNodeData& node_data,
235 const SemanticsNode& node);
236 void SetTooltipFromFlutterUpdate(ui::AXNodeData& node_data,
237 const SemanticsNode& node);
238 void SetTreeData(const SemanticsNode& node, ui::AXTreeUpdate& tree_update);
239 SemanticsNode FromFlutterSemanticsNode(
240 const FlutterSemanticsNode2& flutter_node);
241 SemanticsCustomAction FromFlutterSemanticsCustomAction(
242 const FlutterSemanticsCustomAction2& flutter_custom_action);
243
244 // |AXTreeObserver|
245 void OnNodeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
246
247 // |AXTreeObserver|
248 void OnSubtreeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
249
250 // |AXTreeObserver|
251 void OnNodeCreated(ui::AXTree* tree, ui::AXNode* node) override;
252
253 // |AXTreeObserver|
254 void OnNodeDeleted(ui::AXTree* tree, AccessibilityNodeId node_id) override;
255
256 // |AXTreeObserver|
257 void OnNodeReparented(ui::AXTree* tree, ui::AXNode* node) override;
258
259 // |AXTreeObserver|
260 void OnRoleChanged(ui::AXTree* tree,
261 ui::AXNode* node,
262 ax::mojom::Role old_role,
263 ax::mojom::Role new_role) override;
264
265 // |AXTreeObserver|
266 void OnNodeDataChanged(ui::AXTree* tree,
267 const ui::AXNodeData& old_node_data,
268 const ui::AXNodeData& new_node_data) override;
269
270 // |AXTreeObserver|
271 void OnAtomicUpdateFinished(
272 ui::AXTree* tree,
273 bool root_changed,
274 const std::vector<ui::AXTreeObserver::Change>& changes) override;
275
276 // |FlutterPlatformNodeDelegate::OwnerBridge|
277 void SetLastFocusedId(AccessibilityNodeId node_id) override;
278
279 // |FlutterPlatformNodeDelegate::OwnerBridge|
280 AccessibilityNodeId GetLastFocusedId() override;
281
282 // |FlutterPlatformNodeDelegate::OwnerBridge|
283 gfx::NativeViewAccessible GetNativeAccessibleFromId(
284 AccessibilityNodeId id) override;
285
286 // |FlutterPlatformNodeDelegate::OwnerBridge|
287 gfx::RectF RelativeToGlobalBounds(const ui::AXNode* node,
288 bool& offscreen,
289 bool clip_bounds) override;
290
292};
293
294} // namespace flutter
295
296#endif // FLUTTER_SHELL_PLATFORM_COMMON_ACCESSIBILITY_BRIDGE_H_
ui::AXTree * GetTree() const override
ui::AXPlatformNodeDelegate * RootDelegate() const override
std::weak_ptr< FlutterPlatformNodeDelegate > GetFlutterPlatformNodeDelegateFromID(AccessibilityNodeId id) const
Get the flutter platform node delegate with the given id from this accessibility bridge....
void AddFlutterSemanticsNodeUpdate(const FlutterSemanticsNode2 &node)
Adds a semantics node update to the pending semantics update. Calling this method alone will NOT upda...
virtual std::shared_ptr< FlutterPlatformNodeDelegate > CreateFlutterPlatformNodeDelegate()=0
Creates a platform specific FlutterPlatformNodeDelegate. Ownership passes to the caller....
void AddFlutterSemanticsCustomActionUpdate(const FlutterSemanticsCustomAction2 &action)
Adds a custom semantics action update to the pending semantics update. Calling this method alone will...
ui::AXPlatformNode * GetPlatformNodeFromTree(const ui::AXNode::AXID node_id) const override
const ui::AXTreeData & GetAXTreeData() const
Get the ax tree data from this accessibility bridge. The tree data contains information such as the i...
ui::AXTreeID GetParentTreeID() const override
ui::AXNode * GetRootAsAXNode() const override
ui::AXNode * GetParentNodeFromParentTreeAsAXNode() const override
AccessibilityBridge()
Creates a new instance of a accessibility bridge.
virtual void OnAccessibilityEvent(ui::AXEventGenerator::TargetedEvent targeted_event)=0
Handle accessibility events generated due to accessibility tree changes. These events are needed to b...
ui::AXTreeID GetTreeID() const override
const std::vector< ui::AXEventGenerator::TargetedEvent > GetPendingEvents() const
Gets all pending accessibility events generated during semantics updates. This is useful when decidin...
void CommitUpdates()
Flushes the pending updates and applies them to this accessibility bridge. Calling this with no pendi...
ui::AXNode * GetNodeFromTree(const ui::AXTreeID tree_id, const ui::AXNode::AXID node_id) const override
int32_t AXID
Definition ax_node.h:36
static constexpr AXID kInvalidAXID
Definition ax_node.h:41
int32_t value
FlutterSemanticsAction
Definition embedder.h:115
FlutterTextDirection
Definition embedder.h:359
uint32_t * target
ui::AXNode::AXID AccessibilityNodeId
UnimplementedNativeViewAccessible * NativeViewAccessible
A structure to represent a rectangle.
Definition embedder.h:641
const uintptr_t id
#define BASE_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:8