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

Commit 0148d66

Browse files
committed
Apply dpr transform to fuchsia accessibility bridge
1 parent 876d634 commit 0148d66

File tree

5 files changed

+114
-4
lines changed

5 files changed

+114
-4
lines changed

shell/platform/fuchsia/flutter/accessibility_bridge.cc

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,14 @@ fuchsia::ui::gfx::BoundingBox AccessibilityBridge::GetNodeLocation(
5656

5757
fuchsia::ui::gfx::mat4 AccessibilityBridge::GetNodeTransform(
5858
const flutter::SemanticsNode& node) const {
59+
return ConvertSkiaTransformToMat4(node.transform);
60+
}
61+
62+
fuchsia::ui::gfx::mat4 AccessibilityBridge::ConvertSkiaTransformToMat4(
63+
const SkM44 transform) const {
5964
fuchsia::ui::gfx::mat4 value;
6065
float* m = value.matrix.data();
61-
node.transform.getColMajor(m);
66+
transform.getColMajor(m);
6267
return value;
6368
}
6469

@@ -250,7 +255,7 @@ void AccessibilityBridge::AddSemanticsNodeUpdate(
250255

251256
std::vector<fuchsia::accessibility::semantics::Node> nodes;
252257
size_t current_size = 0;
253-
258+
bool has_root_node_update = false;
254259
// TODO(MI4-2498): Actions, Roles, hit test children, additional
255260
// flags/states/attr
256261

@@ -259,6 +264,14 @@ void AccessibilityBridge::AddSemanticsNodeUpdate(
259264
for (const auto& value : update) {
260265
size_t this_node_size = sizeof(fuchsia::accessibility::semantics::Node);
261266
const auto& flutter_node = value.second;
267+
// We handle root update separately in GetRootNodeUpdate.
268+
// TODO(chunhtai): remove this special case after we remove the inverse
269+
// view pixel ratio transformation in scenic view.
270+
if (flutter_node.id == kRootNodeId) {
271+
root_flutter_semantics_node_ = flutter_node;
272+
has_root_node_update = true;
273+
continue;
274+
}
262275
// Store the nodes for later hit testing.
263276
nodes_[flutter_node.id] = {
264277
.id = flutter_node.id,
@@ -292,7 +305,6 @@ void AccessibilityBridge::AddSemanticsNodeUpdate(
292305
PrintNodeSizeError(flutter_node.id);
293306
return;
294307
}
295-
296308
current_size += this_node_size;
297309

298310
// If we would exceed the max FIDL message size by appending this node,
@@ -309,6 +321,30 @@ void AccessibilityBridge::AddSemanticsNodeUpdate(
309321
PrintNodeSizeError(nodes.back().node_id());
310322
}
311323

324+
// Handles root node update.
325+
float new_view_pixel_ratio = delegate_.GetViewPixelRatio();
326+
if (has_root_node_update ||
327+
last_seen_view_pixel_ratio_ != new_view_pixel_ratio) {
328+
last_seen_view_pixel_ratio_ = new_view_pixel_ratio;
329+
size_t root_node_size;
330+
fuchsia::accessibility::semantics::Node root_update = GetRootNodeUpdate(root_node_size);
331+
// TODO(MI4-2531, FIDL-718): Remove this
332+
// This is defensive. If, despite our best efforts, we ended up with a node
333+
// that is larger than the max fidl size, we send no updates.
334+
if (root_node_size >= kMaxMessageSize) {
335+
PrintNodeSizeError(kRootNodeId);
336+
return;
337+
}
338+
current_size += root_node_size;
339+
// If we would exceed the max FIDL message size by appending this node,
340+
// we should delete/update/commit now.
341+
if (current_size >= kMaxMessageSize) {
342+
tree_ptr_->UpdateSemanticNodes(std::move(nodes));
343+
nodes.clear();
344+
}
345+
nodes.push_back(std::move(root_update));
346+
}
347+
312348
PruneUnreachableNodes();
313349
UpdateScreenRects();
314350

@@ -318,6 +354,46 @@ void AccessibilityBridge::AddSemanticsNodeUpdate(
318354
tree_ptr_->CommitUpdates([]() {});
319355
}
320356

357+
fuchsia::accessibility::semantics::Node
358+
AccessibilityBridge::GetRootNodeUpdate(size_t & node_size) {
359+
fuchsia::accessibility::semantics::Node root_fuchsia_node;
360+
std::vector<uint32_t> child_ids;
361+
node_size = sizeof(fuchsia::accessibility::semantics::Node);
362+
for (int32_t flutter_child_id :
363+
root_flutter_semantics_node_.childrenInTraversalOrder) {
364+
child_ids.push_back(FlutterIdToFuchsiaId(flutter_child_id));
365+
}
366+
// Applies the inverse view pixel ratio transformation to the root node.
367+
float inverse_view_pixel_ratio = 1.f / last_seen_view_pixel_ratio_;
368+
SkM44 inverse_view_pixel_ratio_transform;
369+
inverse_view_pixel_ratio_transform.setScale(inverse_view_pixel_ratio,
370+
inverse_view_pixel_ratio, 1.f);
371+
372+
SkM44 result = root_flutter_semantics_node_.transform *
373+
inverse_view_pixel_ratio_transform;
374+
nodes_[root_flutter_semantics_node_.id] = {
375+
.id = root_flutter_semantics_node_.id,
376+
.flags = root_flutter_semantics_node_.flags,
377+
.rect = root_flutter_semantics_node_.rect,
378+
.transform = result,
379+
.children_in_hit_test_order =
380+
root_flutter_semantics_node_.childrenInHitTestOrder,
381+
};
382+
root_fuchsia_node.set_node_id(root_flutter_semantics_node_.id)
383+
.set_role(GetNodeRole(root_flutter_semantics_node_))
384+
.set_location(GetNodeLocation(root_flutter_semantics_node_))
385+
.set_transform(ConvertSkiaTransformToMat4(result))
386+
.set_attributes(
387+
GetNodeAttributes(root_flutter_semantics_node_, &node_size))
388+
.set_states(GetNodeStates(root_flutter_semantics_node_, &node_size))
389+
.set_actions(
390+
GetNodeActions(root_flutter_semantics_node_, &node_size))
391+
.set_child_ids(child_ids);
392+
node_size +=
393+
kNodeIdSize * root_flutter_semantics_node_.childrenInTraversalOrder.size();
394+
return root_fuchsia_node;
395+
}
396+
321397
void AccessibilityBridge::UpdateScreenRects() {
322398
std::unordered_set<int32_t> visited_nodes;
323399
UpdateScreenRects(kRootNodeId, SkM44{}, &visited_nodes);

shell/platform/fuchsia/flutter/accessibility_bridge.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class AccessibilityBridge
4646
virtual void SetSemanticsEnabled(bool enabled) = 0;
4747
virtual void DispatchSemanticsAction(int32_t node_id,
4848
flutter::SemanticsAction action) = 0;
49+
virtual float GetViewPixelRatio() = 0;
4950
};
5051

5152
// TODO(MI4-2531, FIDL-718): Remove this. We shouldn't be worried about
@@ -115,6 +116,8 @@ class AccessibilityBridge
115116
AccessibilityBridge::Delegate& delegate_;
116117

117118
static constexpr int32_t kRootNodeId = 0;
119+
flutter::SemanticsNode root_flutter_semantics_node_;
120+
float last_seen_view_pixel_ratio_ = 1.f;
118121
fidl::Binding<fuchsia::accessibility::semantics::SemanticListener> binding_;
119122
fuchsia::accessibility::semantics::SemanticsManagerPtr
120123
fuchsia_semantics_manager_;
@@ -124,15 +127,21 @@ class AccessibilityBridge
124127
// Assists with pruning unreachable nodes and hit testing.
125128
std::unordered_map<int32_t, SemanticsNode> nodes_;
126129

130+
fuchsia::accessibility::semantics::Node GetRootNodeUpdate(size_t & node_size);
131+
127132
// Derives the BoundingBox of a Flutter semantics node from its
128133
// rect and elevation.
129134
fuchsia::ui::gfx::BoundingBox GetNodeLocation(
130135
const flutter::SemanticsNode& node) const;
131136

132-
// Converts a Flutter semantics node's transformation to a mat4.
137+
// Gets mat4 transformation from a Flutter semantics node.
133138
fuchsia::ui::gfx::mat4 GetNodeTransform(
134139
const flutter::SemanticsNode& node) const;
135140

141+
// Converts a Flutter semantics node's transformation to a mat4.
142+
fuchsia::ui::gfx::mat4 ConvertSkiaTransformToMat4(
143+
const SkM44 transform) const;
144+
136145
// Derives the attributes for a Fuchsia semantics node from a Flutter
137146
// semantics node.
138147
fuchsia::accessibility::semantics::Attributes GetNodeAttributes(

shell/platform/fuchsia/flutter/accessibility_bridge_unittest.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ namespace flutter_runner_test {
2222
class AccessibilityBridgeTestDelegate
2323
: public flutter_runner::AccessibilityBridge::Delegate {
2424
public:
25+
float view_pixel_ratio = 1.f;
2526
void SetSemanticsEnabled(bool enabled) override { enabled_ = enabled; }
2627
void DispatchSemanticsAction(int32_t node_id,
2728
flutter::SemanticsAction action) override {
2829
actions.push_back(std::make_pair(node_id, action));
2930
}
31+
float GetViewPixelRatio() override { return view_pixel_ratio; }
3032

3133
bool enabled() { return enabled_; }
3234
std::vector<std::pair<int32_t, flutter::SemanticsAction>> actions;
@@ -269,6 +271,21 @@ TEST_F(AccessibilityBridgeTest, PopulatesSelectedState) {
269271
EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
270272
}
271273

274+
TEST_F(AccessibilityBridgeTest, ApplyViewPixelRatioToRoot) {
275+
accessibility_delegate_.view_pixel_ratio = 1.25f;
276+
flutter::SemanticsNode node0;
277+
node0.id = 0;
278+
node0.flags = static_cast<int>(flutter::SemanticsFlags::kIsSelected);
279+
280+
accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}});
281+
RunLoopUntilIdle();
282+
const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
283+
EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
284+
EXPECT_EQ(fuchsia_node.transform().matrix[0], 0.8f);
285+
EXPECT_EQ(fuchsia_node.transform().matrix[5], 0.8f);
286+
EXPECT_EQ(fuchsia_node.transform().matrix[10], 1.f);
287+
}
288+
272289
TEST_F(AccessibilityBridgeTest, PopulatesHiddenState) {
273290
flutter::SemanticsNode node0;
274291
node0.id = 0;

shell/platform/fuchsia/flutter/platform_view.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,12 @@ void PlatformView::DispatchSemanticsAction(int32_t node_id,
570570
flutter::PlatformView::DispatchSemanticsAction(node_id, action, {});
571571
}
572572

573+
// |flutter::PlatformView|
574+
// |flutter_runner::AccessibilityBridge::Delegate|
575+
float PlatformView::GetViewPixelRatio() {
576+
return view_pixel_ratio_;
577+
}
578+
573579
// |flutter::PlatformView|
574580
void PlatformView::UpdateSemantics(
575581
flutter::SemanticsNodeUpdates update,

shell/platform/fuchsia/flutter/platform_view.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ class PlatformView final : public flutter::PlatformView,
7070
// |flutter_runner::AccessibilityBridge::Delegate|
7171
void DispatchSemanticsAction(int32_t node_id,
7272
flutter::SemanticsAction action) override;
73+
// |flutter_runner::AccessibilityBridge::Delegate|
74+
float GetViewPixelRatio() override;
7375

7476
// |PlatformView|
7577
flutter::PointerDataDispatcherMaker GetDispatcherMaker() override;

0 commit comments

Comments
 (0)