@@ -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
@@ -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+
321397void AccessibilityBridge::UpdateScreenRects () {
322398 std::unordered_set<int32_t > visited_nodes;
323399 UpdateScreenRects (kRootNodeId , SkM44{}, &visited_nodes);
0 commit comments