@@ -56,9 +56,14 @@ fuchsia::ui::gfx::BoundingBox AccessibilityBridge::GetNodeLocation(
5656
5757fuchsia::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
@@ -248,7 +253,8 @@ static void PrintNodeSizeError(uint32_t node_id) {
248253}
249254
250255void AccessibilityBridge::AddSemanticsNodeUpdate (
251- const flutter::SemanticsNodeUpdates update) {
256+ const flutter::SemanticsNodeUpdates update,
257+ float view_pixel_ratio) {
252258 if (update.empty ()) {
253259 return ;
254260 }
@@ -259,7 +265,7 @@ void AccessibilityBridge::AddSemanticsNodeUpdate(
259265
260266 std::vector<fuchsia::accessibility::semantics::Node> nodes;
261267 size_t current_size = 0 ;
262-
268+ bool has_root_node_update = false ;
263269 // TODO(MI4-2498): Actions, Roles, hit test children, additional
264270 // flags/states/attr
265271
@@ -268,6 +274,14 @@ void AccessibilityBridge::AddSemanticsNodeUpdate(
268274 for (const auto & value : update) {
269275 size_t this_node_size = sizeof (fuchsia::accessibility::semantics::Node);
270276 const auto & flutter_node = value.second ;
277+ // We handle root update separately in GetRootNodeUpdate.
278+ // TODO(chunhtai): remove this special case after we remove the inverse
279+ // view pixel ratio transformation in scenic view.
280+ if (flutter_node.id == kRootNodeId ) {
281+ root_flutter_semantics_node_ = flutter_node;
282+ has_root_node_update = true ;
283+ continue ;
284+ }
271285 // Store the nodes for later hit testing.
272286 nodes_[flutter_node.id ] = {
273287 .id = flutter_node.id ,
@@ -302,7 +316,6 @@ void AccessibilityBridge::AddSemanticsNodeUpdate(
302316 PrintNodeSizeError (flutter_node.id );
303317 return ;
304318 }
305-
306319 current_size += this_node_size;
307320
308321 // If we would exceed the max FIDL message size by appending this node,
@@ -319,6 +332,29 @@ void AccessibilityBridge::AddSemanticsNodeUpdate(
319332 PrintNodeSizeError (nodes.back ().node_id ());
320333 }
321334
335+ // Handles root node update.
336+ if (has_root_node_update || last_seen_view_pixel_ratio_ != view_pixel_ratio) {
337+ last_seen_view_pixel_ratio_ = view_pixel_ratio;
338+ size_t root_node_size;
339+ fuchsia::accessibility::semantics::Node root_update =
340+ GetRootNodeUpdate (root_node_size);
341+ // TODO(MI4-2531, FIDL-718): Remove this
342+ // This is defensive. If, despite our best efforts, we ended up with a node
343+ // that is larger than the max fidl size, we send no updates.
344+ if (root_node_size >= kMaxMessageSize ) {
345+ PrintNodeSizeError (kRootNodeId );
346+ return ;
347+ }
348+ current_size += root_node_size;
349+ // If we would exceed the max FIDL message size by appending this node,
350+ // we should delete/update/commit now.
351+ if (current_size >= kMaxMessageSize ) {
352+ tree_ptr_->UpdateSemanticNodes (std::move (nodes));
353+ nodes.clear ();
354+ }
355+ nodes.push_back (std::move (root_update));
356+ }
357+
322358 PruneUnreachableNodes ();
323359 UpdateScreenRects ();
324360
@@ -328,6 +364,45 @@ void AccessibilityBridge::AddSemanticsNodeUpdate(
328364 tree_ptr_->CommitUpdates ([]() {});
329365}
330366
367+ fuchsia::accessibility::semantics::Node AccessibilityBridge::GetRootNodeUpdate (
368+ size_t & node_size) {
369+ fuchsia::accessibility::semantics::Node root_fuchsia_node;
370+ std::vector<uint32_t > child_ids;
371+ node_size = sizeof (fuchsia::accessibility::semantics::Node);
372+ for (int32_t flutter_child_id :
373+ root_flutter_semantics_node_.childrenInTraversalOrder ) {
374+ child_ids.push_back (FlutterIdToFuchsiaId (flutter_child_id));
375+ }
376+ // Applies the inverse view pixel ratio transformation to the root node.
377+ float inverse_view_pixel_ratio = 1 .f / last_seen_view_pixel_ratio_;
378+ SkM44 inverse_view_pixel_ratio_transform;
379+ inverse_view_pixel_ratio_transform.setScale (inverse_view_pixel_ratio,
380+ inverse_view_pixel_ratio, 1 .f );
381+
382+ SkM44 result = root_flutter_semantics_node_.transform *
383+ inverse_view_pixel_ratio_transform;
384+ nodes_[root_flutter_semantics_node_.id ] = {
385+ .id = root_flutter_semantics_node_.id ,
386+ .flags = root_flutter_semantics_node_.flags ,
387+ .rect = root_flutter_semantics_node_.rect ,
388+ .transform = result,
389+ .children_in_hit_test_order =
390+ root_flutter_semantics_node_.childrenInHitTestOrder ,
391+ };
392+ root_fuchsia_node.set_node_id (root_flutter_semantics_node_.id )
393+ .set_role (GetNodeRole (root_flutter_semantics_node_))
394+ .set_location (GetNodeLocation (root_flutter_semantics_node_))
395+ .set_transform (ConvertSkiaTransformToMat4 (result))
396+ .set_attributes (
397+ GetNodeAttributes (root_flutter_semantics_node_, &node_size))
398+ .set_states (GetNodeStates (root_flutter_semantics_node_, &node_size))
399+ .set_actions (GetNodeActions (root_flutter_semantics_node_, &node_size))
400+ .set_child_ids (child_ids);
401+ node_size += kNodeIdSize *
402+ root_flutter_semantics_node_.childrenInTraversalOrder .size ();
403+ return root_fuchsia_node;
404+ }
405+
331406void AccessibilityBridge::UpdateScreenRects () {
332407 std::unordered_set<int32_t > visited_nodes;
333408 UpdateScreenRects (kRootNodeId , SkM44{}, &visited_nodes);
0 commit comments