blob: d03d6d2a92a25d577ae4466d200202ef3441da5e [file] [log] [blame]
// Copyright 2020 The Fuchsia 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 "src/ui/a11y/lib/semantics/tests/mocks/mock_semantics_source.h"
#include <lib/syslog/cpp/macros.h>
#include "src/ui/a11y/lib/util/util.h"
namespace accessibility_test {
void MockSemanticsSource::AddViewRef(fuchsia::ui::views::ViewRef view_ref) {
view_ref_ = std::move(view_ref);
}
bool MockSemanticsSource::ViewHasSemantics(zx_koid_t view_ref_koid) { return view_has_semantics_; }
std::optional<fuchsia::ui::views::ViewRef> MockSemanticsSource::ViewRefClone(
zx_koid_t view_ref_koid) {
if (!ViewHasSemantics(view_ref_koid)) {
return std::nullopt;
}
return a11y::Clone(view_ref_);
}
void MockSemanticsSource::CreateSemanticNode(zx_koid_t koid,
fuchsia::accessibility::semantics::Node node) {
nodes_[koid][node.node_id()] = std::move(node);
}
const fuchsia::accessibility::semantics::Node* MockSemanticsSource::GetSemanticNode(
zx_koid_t koid, uint32_t node_id) const {
const auto it = nodes_.find(koid);
if (it == nodes_.end()) {
return nullptr;
}
const auto& nodes_for_view = it->second;
const auto node_it = nodes_for_view.find(node_id);
if (node_it == nodes_for_view.end()) {
return nullptr;
}
return &node_it->second;
}
const fuchsia::accessibility::semantics::Node* MockSemanticsSource::GetParentNode(
zx_koid_t koid, uint32_t node_id) const {
if (get_parent_node_should_fail_) {
return nullptr;
}
const auto it = nodes_.find(koid);
if (it == nodes_.end()) {
return nullptr;
}
const auto& nodes_for_view = it->second;
for (const auto& node : nodes_for_view) {
if (!node.second.has_child_ids()) {
continue;
}
for (const auto child_id : node.second.child_ids()) {
if (child_id == node_id) {
return &node.second;
}
}
}
return nullptr;
}
const fuchsia::accessibility::semantics::Node* MockSemanticsSource::GetNextNode(
zx_koid_t koid, uint32_t node_id, a11y::NodeFilter filter) const {
if (get_next_node_should_fail_) {
return nullptr;
}
if (nodes_.find(koid) == nodes_.end()) {
return nullptr;
}
const auto& nodes = nodes_.at(koid);
std::map<uint32_t, fuchsia::accessibility::semantics::Node>::const_iterator it =
nodes.find(node_id);
if (it == nodes.end()) {
return nullptr;
}
while (++it != nodes.end() && !filter(&(it->second)))
;
FX_DCHECK(it != nodes.end());
return it == nodes.end() ? nullptr : &(it->second);
}
const fuchsia::accessibility::semantics::Node* MockSemanticsSource::GetNextNode(
zx_koid_t koid, uint32_t node_id, a11y::NodeFilterWithParent filter) const {
FX_CHECK(!get_parent_node_should_fail_) << "Unsupported mock configuration";
return GetNextNode(koid, node_id,
[this, koid, filter = std::move(filter)](
const fuchsia::accessibility::semantics::Node* node) {
return filter(node, GetParentNode(koid, node->node_id()));
});
}
const fuchsia::accessibility::semantics::Node* MockSemanticsSource::GetPreviousNode(
zx_koid_t koid, uint32_t node_id, a11y::NodeFilter filter) const {
if (get_previous_node_should_fail_) {
return nullptr;
}
if (nodes_.find(koid) == nodes_.end()) {
return nullptr;
}
const auto& nodes = nodes_.at(koid);
std::map<uint32_t, fuchsia::accessibility::semantics::Node>::const_iterator it =
nodes.find(node_id);
if (it == nodes.end() || it == nodes.begin()) {
return nullptr;
}
while (it != nodes.begin()) {
it = std::prev(it);
if (filter(&(it->second))) {
return &(it->second);
}
}
return nullptr;
}
const fuchsia::accessibility::semantics::Node* MockSemanticsSource::GetPreviousNode(
zx_koid_t koid, uint32_t node_id, a11y::NodeFilterWithParent filter) const {
FX_CHECK(!get_parent_node_should_fail_) << "Unsupported mock configuration";
return GetPreviousNode(koid, node_id,
[this, koid, filter = std::move(filter)](
const fuchsia::accessibility::semantics::Node* node) {
return filter(node, GetParentNode(koid, node->node_id()));
});
}
void MockSemanticsSource::SetHitTestResult(zx_koid_t koid,
fuchsia::accessibility::semantics::Hit hit_test_result) {
hit_test_results_[koid] = std::move(hit_test_result);
}
void MockSemanticsSource::ExecuteHitTesting(
zx_koid_t koid, fuchsia::math::PointF local_point,
fuchsia::accessibility::semantics::SemanticListener::HitTestCallback callback) {
// NOTE: We don't need to check if we have specified a hit test result for the given koid. If we
// haven't, operator[] will default construct an empty hit test result, which is the desired
// behavior in this case.
callback(std::move(hit_test_results_[koid]));
hit_test_results_.erase(koid);
}
void MockSemanticsSource::SetActionResult(zx_koid_t koid, bool action_result) {
action_results_[koid] = action_result;
}
void MockSemanticsSource::PerformAccessibilityAction(
zx_koid_t koid, uint32_t node_id, fuchsia::accessibility::semantics::Action action,
fuchsia::accessibility::semantics::SemanticListener::OnAccessibilityActionRequestedCallback
callback) {
requested_actions_[koid].emplace_back(node_id, action);
if (custom_action_callback_) {
custom_action_callback_();
}
callback(perform_accessibility_action_callback_value_);
}
const std::vector<std::pair<uint32_t, fuchsia::accessibility::semantics::Action>>&
MockSemanticsSource::GetRequestedActionsForView(zx_koid_t koid) {
return requested_actions_[koid];
}
void MockSemanticsSource::SetNodeToRootTransform(a11y::SemanticTransform semantic_transform) {
transform_to_return_ = std::make_optional<a11y::SemanticTransform>(semantic_transform);
}
std::optional<a11y::SemanticTransform> MockSemanticsSource::GetNodeToRootTransform(
zx_koid_t koid, uint32_t node_id) const {
return transform_to_return_;
}
} // namespace accessibility_test