blob: 8ac63db3ffed999bf57e805045397dd5fd9f387f [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 <lib/syslog/cpp/macros.h>
// This header file has been generated from the strings library fuchsia.intl.l10n.
#include "fuchsia/intl/l10n/cpp/fidl.h"
#include "src/ui/a11y/lib/screen_reader/node_describer.h"
namespace a11y {
namespace {
using fuchsia::accessibility::semantics::Role;
using fuchsia::accessibility::tts::Utterance;
using fuchsia::intl::l10n::MessageIds;
static constexpr zx::duration kDefaultDelay = zx::msec(100);
// Returns a message that describes a node where Role == BUTTON.
NodeDescriber::UtteranceAndContext DescribeButton(a11y::i18n::MessageFormatter* formatter) {
NodeDescriber::UtteranceAndContext utterance;
auto message = formatter->FormatStringById(static_cast<uint64_t>(MessageIds::ROLE_BUTTON));
FX_DCHECK(message);
utterance.utterance.set_message(std::move(*message));
utterance.delay = kDefaultDelay;
return utterance;
}
// Returns a message that describes a node where Role == HEADER.
NodeDescriber::UtteranceAndContext DescribeHeader(a11y::i18n::MessageFormatter* formatter) {
NodeDescriber::UtteranceAndContext utterance;
auto message = formatter->FormatStringById(static_cast<uint64_t>(MessageIds::ROLE_HEADER));
FX_DCHECK(message);
utterance.utterance.set_message(std::move(*message));
utterance.delay = kDefaultDelay;
return utterance;
}
// Returns a message that describes a node where Role == IMAGE.
NodeDescriber::UtteranceAndContext DescribeImage(a11y::i18n::MessageFormatter* formatter) {
NodeDescriber::UtteranceAndContext utterance;
auto message = formatter->FormatStringById(static_cast<uint64_t>(MessageIds::ROLE_IMAGE));
FX_DCHECK(message);
utterance.utterance.set_message(std::move(*message));
utterance.delay = kDefaultDelay;
return utterance;
}
} // namespace
NodeDescriber::NodeDescriber(std::unique_ptr<i18n::MessageFormatter> message_formatter)
: message_formatter_(std::move(message_formatter)) {}
std::vector<NodeDescriber::UtteranceAndContext> NodeDescriber::DescribeNode(
const fuchsia::accessibility::semantics::Node* node) {
std::vector<UtteranceAndContext> description;
{
Utterance utterance;
if (node->has_attributes() && node->attributes().has_label()) {
utterance.set_message(node->attributes().label());
}
// Note that empty descriptions (no labels), are allowed. It is common for developers forget to
// add accessible labels to their UI elements, which causes them to not have one. It is
// desirable still to tell the user what the node is (a button), so the Screen Reader can read
// something like: (pause) button.
description.emplace_back(UtteranceAndContext{.utterance = std::move(utterance)});
}
{
Utterance utterance;
if (node->has_role()) {
if (node->role() == Role::BUTTON) {
description.emplace_back(DescribeButton(message_formatter_.get()));
} else if (node->role() == Role::HEADER) {
description.emplace_back(DescribeHeader(message_formatter_.get()));
} else if (node->role() == Role::IMAGE) {
description.emplace_back(DescribeImage(message_formatter_.get()));
}
}
}
return description;
}
} // namespace a11y