blob: f082eff5c03410a96e59070df121b504635870b6 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fuchsia/engine/browser/ax_tree_converter.h"
#include <fuchsia/math/cpp/fidl.h>
#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/ui/scenic/cpp/commands.h>
#include <vector>
#include "base/bit_cast.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_tree_id.h"
#include "ui/gfx/geometry/rect_f.h"
namespace {
fuchsia::accessibility::semantics::Role ConvertRole(ax::mojom::Role role) {
if (role == ax::mojom::Role::kUnknown)
return fuchsia::accessibility::semantics::Role::UNKNOWN;
// TODO(crbug.com/973095): Currently Fuchsia only has one Role option. Add
// more and update tests as they become supported.
return fuchsia::accessibility::semantics::Role::UNKNOWN;
}
fuchsia::accessibility::semantics::Attributes SetAttributes(std::string name) {
fuchsia::accessibility::semantics::Attributes attributes;
attributes.set_label(name);
return attributes;
}
std::vector<fuchsia::accessibility::semantics::Action> ConvertActions(
uint32_t actions) {
std::vector<fuchsia::accessibility::semantics::Action> fuchsia_actions;
ax::mojom::Action action_enum = static_cast<ax::mojom::Action>(actions);
switch (action_enum) {
case ax::mojom::Action::kDoDefault:
fuchsia_actions.push_back(
fuchsia::accessibility::semantics::Action::DEFAULT);
break;
case ax::mojom::Action::kNone:
case ax::mojom::Action::kAnnotatePageImages:
case ax::mojom::Action::kBlur:
case ax::mojom::Action::kClearAccessibilityFocus:
case ax::mojom::Action::kCustomAction:
case ax::mojom::Action::kDecrement:
case ax::mojom::Action::kFocus:
case ax::mojom::Action::kGetImageData:
case ax::mojom::Action::kGetTextLocation:
case ax::mojom::Action::kHideTooltip:
case ax::mojom::Action::kHitTest:
case ax::mojom::Action::kIncrement:
case ax::mojom::Action::kInternalInvalidateTree:
case ax::mojom::Action::kLoadInlineTextBoxes:
case ax::mojom::Action::kReplaceSelectedText:
case ax::mojom::Action::kScrollBackward:
case ax::mojom::Action::kScrollDown:
case ax::mojom::Action::kScrollForward:
case ax::mojom::Action::kScrollLeft:
case ax::mojom::Action::kScrollRight:
case ax::mojom::Action::kScrollUp:
case ax::mojom::Action::kScrollToMakeVisible:
case ax::mojom::Action::kScrollToPoint:
case ax::mojom::Action::kSetAccessibilityFocus:
case ax::mojom::Action::kSetScrollOffset:
case ax::mojom::Action::kSetSelection:
case ax::mojom::Action::kSetSequentialFocusNavigationStartingPoint:
case ax::mojom::Action::kSetValue:
case ax::mojom::Action::kShowContextMenu:
case ax::mojom::Action::kSignalEndOfTest:
case ax::mojom::Action::kShowTooltip:
DVLOG(2) << "Action: " << action_enum;
break;
}
return fuchsia_actions;
}
std::vector<uint32_t> ConvertChildIds(std::vector<int32_t> ids) {
std::vector<uint32_t> child_ids;
child_ids.reserve(ids.size());
for (auto i : ids) {
child_ids.push_back(bit_cast<uint32_t>(i));
}
return child_ids;
}
fuchsia::ui::gfx::BoundingBox ConvertBoundingBox(gfx::RectF bounds) {
fuchsia::ui::gfx::BoundingBox box;
float min[3] = {bounds.bottom_left().x(), bounds.bottom_left().y(), 0.0f};
float max[3] = {bounds.top_right().x(), bounds.top_right().y(), 0.0f};
box.min = scenic::NewVector3(min);
box.max = scenic::NewVector3(max);
return box;
}
// The Semantics Manager applies this matrix to position the node and its
// subtree as an optimization to handle resizing or repositioning. This requires
// only one node to be updated on such an event.
fuchsia::ui::gfx::mat4 ConvertTransform(gfx::Transform* transform) {
float mat[16] = {};
transform->matrix().asColMajorf(mat);
fuchsia::ui::gfx::Matrix4Value fuchsia_transform =
scenic::NewMatrix4Value(mat);
return fuchsia_transform.value;
}
} // namespace
fuchsia::accessibility::semantics::Node AXNodeDataToSemanticNode(
const ui::AXNodeData& node) {
fuchsia::accessibility::semantics::Node fuchsia_node;
fuchsia_node.set_node_id(bit_cast<uint32_t>(node.id));
fuchsia_node.set_role(ConvertRole(node.role));
// TODO(fxb/18796): Handle node state conversions once available.
if (node.HasStringAttribute(ax::mojom::StringAttribute::kName)) {
fuchsia_node.set_attributes(SetAttributes(
node.GetStringAttribute(ax::mojom::StringAttribute::kName)));
}
fuchsia_node.set_actions(ConvertActions(node.actions));
fuchsia_node.set_child_ids(ConvertChildIds(node.child_ids));
fuchsia_node.set_location(ConvertBoundingBox(node.relative_bounds.bounds));
if (node.relative_bounds.transform) {
fuchsia_node.set_transform(
ConvertTransform(node.relative_bounds.transform.get()));
}
return fuchsia_node;
}