Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit c0b3f8f

Browse files
Make AccessibilityBridge a AXPlatformTreeManager (#38610)
* Make Accessibility Bridge a tree manager * Add FlutterPlatformNodeDelegate::GetPlatformNode * Add unit test * Formatting * PR
1 parent 1d2ba73 commit c0b3f8f

7 files changed

+136
-16
lines changed

shell/platform/common/accessibility_bridge.cc

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <functional>
88
#include <utility>
99

10+
#include "flutter/third_party/accessibility/ax/ax_tree_manager_map.h"
1011
#include "flutter/third_party/accessibility/ax/ax_tree_update.h"
1112
#include "flutter/third_party/accessibility/base/logging.h"
1213

@@ -19,14 +20,20 @@ constexpr int kHasScrollingAction =
1920
FlutterSemanticsAction::kFlutterSemanticsActionScrollDown;
2021

2122
// AccessibilityBridge
22-
AccessibilityBridge::AccessibilityBridge() {
23-
event_generator_.SetTree(&tree_);
24-
tree_.AddObserver(static_cast<ui::AXTreeObserver*>(this));
23+
AccessibilityBridge::AccessibilityBridge()
24+
: tree_(std::make_unique<ui::AXTree>()) {
25+
event_generator_.SetTree(tree_.get());
26+
tree_->AddObserver(static_cast<ui::AXTreeObserver*>(this));
27+
ui::AXTreeData data = tree_->data();
28+
data.tree_id = ui::AXTreeID::CreateNewAXTreeID();
29+
tree_->UpdateData(data);
30+
ui::AXTreeManagerMap::GetInstance().AddTreeManager(tree_->GetAXTreeID(),
31+
this);
2532
}
2633

2734
AccessibilityBridge::~AccessibilityBridge() {
2835
event_generator_.ReleaseTree();
29-
tree_.RemoveObserver(static_cast<ui::AXTreeObserver*>(this));
36+
tree_->RemoveObserver(static_cast<ui::AXTreeObserver*>(this));
3037
}
3138

3239
void AccessibilityBridge::AddFlutterSemanticsNodeUpdate(
@@ -51,9 +58,9 @@ void AccessibilityBridge::CommitUpdates() {
5158
std::optional<ui::AXTreeUpdate> remove_reparented =
5259
CreateRemoveReparentedNodesUpdate();
5360
if (remove_reparented.has_value()) {
54-
tree_.Unserialize(remove_reparented.value());
61+
tree_->Unserialize(remove_reparented.value());
5562

56-
std::string error = tree_.error();
63+
std::string error = tree_->error();
5764
if (!error.empty()) {
5865
FML_LOG(ERROR) << "Failed to update ui::AXTree, error: " << error;
5966
assert(false);
@@ -63,7 +70,7 @@ void AccessibilityBridge::CommitUpdates() {
6370

6471
// Second, apply the pending node updates. This also moves reparented nodes to
6572
// their new parents if needed.
66-
ui::AXTreeUpdate update{.tree_data = tree_.data()};
73+
ui::AXTreeUpdate update{.tree_data = tree_->data()};
6774

6875
// Figure out update order, ui::AXTree only accepts update in tree order,
6976
// where parent node must come before the child node in
@@ -88,11 +95,11 @@ void AccessibilityBridge::CommitUpdates() {
8895
}
8996
}
9097

91-
tree_.Unserialize(update);
98+
tree_->Unserialize(update);
9299
pending_semantics_node_updates_.clear();
93100
pending_semantics_custom_action_updates_.clear();
94101

95-
std::string error = tree_.error();
102+
std::string error = tree_->error();
96103
if (!error.empty()) {
97104
FML_LOG(ERROR) << "Failed to update ui::AXTree, error: " << error;
98105
return;
@@ -122,7 +129,7 @@ AccessibilityBridge::GetFlutterPlatformNodeDelegateFromID(
122129
}
123130

124131
const ui::AXTreeData& AccessibilityBridge::GetAXTreeData() const {
125-
return tree_.data();
132+
return tree_->data();
126133
}
127134

128135
const std::vector<ui::AXEventGenerator::TargetedEvent>
@@ -201,7 +208,7 @@ AccessibilityBridge::CreateRemoveReparentedNodesUpdate() {
201208
for (auto node_update : pending_semantics_node_updates_) {
202209
for (int32_t child_id : node_update.second.children_in_traversal_order) {
203210
// Skip nodes that don't exist or have a parent in the current tree.
204-
ui::AXNode* child = tree_.GetFromId(child_id);
211+
ui::AXNode* child = tree_->GetFromId(child_id);
205212
if (!child) {
206213
continue;
207214
}
@@ -222,7 +229,7 @@ AccessibilityBridge::CreateRemoveReparentedNodesUpdate() {
222229
// Create an update to remove the child from its previous parent.
223230
int32_t parent_id = child->parent()->id();
224231
if (updates.find(parent_id) == updates.end()) {
225-
updates[parent_id] = tree_.GetFromId(parent_id)->data();
232+
updates[parent_id] = tree_->GetFromId(parent_id)->data();
226233
}
227234

228235
ui::AXNodeData* parent = &updates[parent_id];
@@ -239,7 +246,7 @@ AccessibilityBridge::CreateRemoveReparentedNodesUpdate() {
239246
}
240247

241248
ui::AXTreeUpdate update{
242-
.tree_data = tree_.data(),
249+
.tree_data = tree_->data(),
243250
.nodes = std::vector<ui::AXNodeData>(),
244251
};
245252

@@ -649,8 +656,60 @@ gfx::NativeViewAccessible AccessibilityBridge::GetNativeAccessibleFromId(
649656
gfx::RectF AccessibilityBridge::RelativeToGlobalBounds(const ui::AXNode* node,
650657
bool& offscreen,
651658
bool clip_bounds) {
652-
return tree_.RelativeToTreeBounds(node, gfx::RectF(), &offscreen,
653-
clip_bounds);
659+
return tree_->RelativeToTreeBounds(node, gfx::RectF(), &offscreen,
660+
clip_bounds);
661+
}
662+
663+
ui::AXNode* AccessibilityBridge::GetNodeFromTree(
664+
ui::AXTreeID tree_id,
665+
ui::AXNode::AXID node_id) const {
666+
return GetNodeFromTree(node_id);
667+
}
668+
669+
ui::AXNode* AccessibilityBridge::GetNodeFromTree(
670+
ui::AXNode::AXID node_id) const {
671+
return tree_->GetFromId(node_id);
672+
}
673+
674+
ui::AXTreeID AccessibilityBridge::GetTreeID() const {
675+
return tree_->GetAXTreeID();
676+
}
677+
678+
ui::AXTreeID AccessibilityBridge::GetParentTreeID() const {
679+
return ui::AXTreeIDUnknown();
680+
}
681+
682+
ui::AXNode* AccessibilityBridge::GetRootAsAXNode() const {
683+
return tree_->root();
684+
}
685+
686+
ui::AXNode* AccessibilityBridge::GetParentNodeFromParentTreeAsAXNode() const {
687+
return nullptr;
688+
}
689+
690+
ui::AXTree* AccessibilityBridge::GetTree() const {
691+
return tree_.get();
692+
}
693+
694+
ui::AXPlatformNode* AccessibilityBridge::GetPlatformNodeFromTree(
695+
const ui::AXNode::AXID node_id) const {
696+
auto platform_delegate_weak = GetFlutterPlatformNodeDelegateFromID(node_id);
697+
auto platform_delegate = platform_delegate_weak.lock();
698+
if (!platform_delegate) {
699+
return nullptr;
700+
}
701+
return platform_delegate->GetPlatformNode();
702+
}
703+
704+
ui::AXPlatformNode* AccessibilityBridge::GetPlatformNodeFromTree(
705+
const ui::AXNode& node) const {
706+
return GetPlatformNodeFromTree(node.id());
707+
}
708+
709+
ui::AXPlatformNodeDelegate* AccessibilityBridge::RootDelegate() const {
710+
return GetFlutterPlatformNodeDelegateFromID(GetRootAsAXNode()->id())
711+
.lock()
712+
.get();
654713
}
655714

656715
} // namespace flutter

shell/platform/common/accessibility_bridge.h

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "flutter/third_party/accessibility/ax/ax_tree.h"
1515
#include "flutter/third_party/accessibility/ax/ax_tree_observer.h"
1616
#include "flutter/third_party/accessibility/ax/platform/ax_platform_node_delegate.h"
17+
#include "flutter/third_party/accessibility/ax/platform/ax_platform_tree_manager.h"
1718

1819
#include "flutter_platform_node_delegate.h"
1920

@@ -39,6 +40,7 @@ namespace flutter {
3940
class AccessibilityBridge
4041
: public std::enable_shared_from_this<AccessibilityBridge>,
4142
public FlutterPlatformNodeDelegate::OwnerBridge,
43+
public ui::AXPlatformTreeManager,
4244
private ui::AXTreeObserver {
4345
public:
4446
//-----------------------------------------------------------------------------
@@ -106,6 +108,39 @@ class AccessibilityBridge
106108
const std::vector<ui::AXEventGenerator::TargetedEvent> GetPendingEvents()
107109
const;
108110

111+
// |AXTreeManager|
112+
ui::AXNode* GetNodeFromTree(const ui::AXTreeID tree_id,
113+
const ui::AXNode::AXID node_id) const override;
114+
115+
// |AXTreeManager|
116+
ui::AXNode* GetNodeFromTree(const ui::AXNode::AXID node_id) const override;
117+
118+
// |AXTreeManager|
119+
ui::AXTreeID GetTreeID() const override;
120+
121+
// |AXTreeManager|
122+
ui::AXTreeID GetParentTreeID() const override;
123+
124+
// |AXTreeManager|
125+
ui::AXNode* GetRootAsAXNode() const override;
126+
127+
// |AXTreeManager|
128+
ui::AXNode* GetParentNodeFromParentTreeAsAXNode() const override;
129+
130+
// |AXTreeManager|
131+
ui::AXTree* GetTree() const override;
132+
133+
// |AXPlatformTreeManager|
134+
ui::AXPlatformNode* GetPlatformNodeFromTree(
135+
const ui::AXNode::AXID node_id) const override;
136+
137+
// |AXPlatformTreeManager|
138+
ui::AXPlatformNode* GetPlatformNodeFromTree(
139+
const ui::AXNode& node) const override;
140+
141+
// |AXPlatformTreeManager|
142+
ui::AXPlatformNodeDelegate* RootDelegate() const override;
143+
109144
protected:
110145
//---------------------------------------------------------------------------
111146
/// @brief Handle accessibility events generated due to accessibility
@@ -176,7 +211,7 @@ class AccessibilityBridge
176211
std::unordered_map<AccessibilityNodeId,
177212
std::shared_ptr<FlutterPlatformNodeDelegate>>
178213
id_wrapper_map_;
179-
ui::AXTree tree_;
214+
std::unique_ptr<ui::AXTree> tree_;
180215
ui::AXEventGenerator event_generator_;
181216
std::unordered_map<int32_t, SemanticsNode> pending_semantics_node_updates_;
182217
std::unordered_map<int32_t, SemanticsCustomAction>

shell/platform/common/accessibility_bridge_unittests.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "gmock/gmock.h"
88
#include "gtest/gtest.h"
99

10+
#include "flutter/third_party/accessibility/ax/ax_tree_manager_map.h"
1011
#include "test_accessibility_bridge.h"
1112

1213
namespace flutter {
@@ -483,5 +484,15 @@ TEST(AccessibilityBridgeTest, CanReparentNodeWithChild) {
483484
Contains(ui::AXEventGenerator::Event::ROLE_CHANGED).Times(1));
484485
}
485486

487+
TEST(AccessibilityBridgeTest, AXTreeManagerTest) {
488+
std::shared_ptr<TestAccessibilityBridge> bridge =
489+
std::make_shared<TestAccessibilityBridge>();
490+
491+
ui::AXTreeID tree_id = bridge->GetTreeID();
492+
ui::AXTreeManager* manager =
493+
ui::AXTreeManagerMap::GetInstance().GetManager(tree_id);
494+
ASSERT_EQ(manager, static_cast<ui::AXTreeManager*>(bridge.get()));
495+
}
496+
486497
} // namespace testing
487498
} // namespace flutter

shell/platform/common/flutter_platform_node_delegate.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,8 @@ FlutterPlatformNodeDelegate::GetOwnerBridge() const {
114114
return bridge_;
115115
}
116116

117+
ui::AXPlatformNode* FlutterPlatformNodeDelegate::GetPlatformNode() const {
118+
return nullptr;
119+
}
120+
117121
} // namespace flutter

shell/platform/common/flutter_platform_node_delegate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ class FlutterPlatformNodeDelegate : public ui::AXPlatformNodeDelegateBase {
144144
/// platform thread.
145145
std::weak_ptr<OwnerBridge> GetOwnerBridge() const;
146146

147+
// Get the platform node represented by this delegate.
148+
virtual ui::AXPlatformNode* GetPlatformNode() const;
149+
147150
private:
148151
ui::AXNode* ax_node_;
149152
std::weak_ptr<OwnerBridge> bridge_;

shell/platform/windows/flutter_platform_node_delegate_windows.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,9 @@ FlutterPlatformNodeDelegateWindows::GetTargetForNativeAccessibilityEvent() {
107107
return view_->GetPlatformWindow();
108108
}
109109

110+
ui::AXPlatformNode* FlutterPlatformNodeDelegateWindows::GetPlatformNode()
111+
const {
112+
return ax_platform_node_;
113+
}
114+
110115
} // namespace flutter

shell/platform/windows/flutter_platform_node_delegate_windows.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ class FlutterPlatformNodeDelegateWindows : public FlutterPlatformNodeDelegate {
5151
// | AXPlatformNodeDelegate |
5252
gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
5353

54+
// | FlutterPlatformNodeDelegate |
55+
ui::AXPlatformNode* GetPlatformNode() const override;
56+
5457
private:
5558
ui::AXPlatformNode* ax_platform_node_;
5659
std::weak_ptr<AccessibilityBridge> bridge_;

0 commit comments

Comments
 (0)