blob: bc31fc190eca54ab8160894533f55452fd97a2d6 [file] [log] [blame]
// Copyright 2018 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.
#ifndef GARNET_BIN_A11Y_A11Y_MANAGER_SEMANTIC_TREE_H_
#define GARNET_BIN_A11Y_A11Y_MANAGER_SEMANTIC_TREE_H_
#include <unordered_map>
#include <fuchsia/accessibility/cpp/fidl.h>
#include "garnet/lib/ui/gfx/util/unwrap.h"
#include "lib/fidl/cpp/binding_set.h"
#include "lib/fxl/logging.h"
#include "lib/fxl/macros.h"
namespace a11y_manager {
// Represents an aggregate semantics tree of all front-ends. Each front-end
// semantics tree is associated with a Scenic view id.
// To query a specific node from a particular front-end, we need to provide
// a Scenic view id to figure out which front-end semantics tree to query,
// and a node id to get the specific node from the tree.
class SemanticTree : public fuchsia::accessibility::SemanticsRoot {
public:
explicit SemanticTree() = default;
~SemanticTree() = default;
// Allows the SemanticTree to handle client connection requests to its
// SemanticRoot interface.
void AddBinding(
fidl::InterfaceRequest<fuchsia::accessibility::SemanticsRoot> request);
// Provides the a11y manager with a way to perform hit-testing for a
// front-end node when it has the view id and the local view hit
// coordinates from Scenic. Currently, this only supports 2D hit-tests
// using bounding boxes.
fuchsia::accessibility::NodePtr GetHitAccessibilityNode(
zx_koid_t view_id, fuchsia::math::PointF point);
// Provides the manager a way to query a node if it already knows
// what view id and node id it wants to query for. This method returns
// a copy of the queried node. It may return a nullptr if no node is found.
fuchsia::accessibility::NodePtr GetAccessibilityNode(zx_koid_t view_id,
int32_t node_id);
// Since the SemanticsTree holds the references to the front-end semantics
// providers, it must be the one to perform actions.
void PerformAccessibilityAction(zx_koid_t view_id, int32_t node_id,
fuchsia::accessibility::Action action);
private:
// |fuchsia::accessibility::SemanticRoot|:
// We tie the lifetime of the view id to the lifetime of the
// SemanticsProvider connection. Upon SemanticsProvider connection error,
// we remove the associated view id semantics tree in the mappings.
// Providers should re-register upon connection error to send more data.
void RegisterSemanticsProvider(
zx_koid_t view_id,
fidl::InterfaceHandle<fuchsia::accessibility::SemanticsProvider> handle)
override;
void UpdateSemanticNodes(
zx_koid_t view_id,
std::vector<fuchsia::accessibility::Node> nodes) override;
void DeleteSemanticNodes(zx_koid_t view_id,
std::vector<int32_t> node_ids) override;
void Commit(zx_koid_t view_id) override;
// Internal recursive hit-test function using the cached tree. Returns a
// null pointer if no hit nodes were found. Public functions that query
// nodes from the tree should always return a copy of the node to avoid
// unintentional modification of the tree.
// NOTE: This is a 2D hit test and only operates on bounding boxes of
// semantics nodes.
fuchsia::accessibility::Node* HitTest(
std::unordered_map<int32_t, fuchsia::accessibility::Node>& nodes,
int32_t node_id, escher::vec4 coordinates);
fidl::BindingSet<fuchsia::accessibility::SemanticsRoot> bindings_;
// When a front-end registers itself to the SemanticsRoot using
// RegisterSemanticProvider, we create an entry in the following four
// maps keyed to the front-end's view id. We follow a simple commit system
// to provide a way for front-ends to send atomic updates to the
// SemanticsRoot.
// Maps view ids to the committed, cached trees for each front-end. For
// each front-end, we represent its semantics tree as a map of local
// node ids to the actual node objects. All query operations should
// use the node information from these trees.
std::unordered_map<
zx_koid_t /*view_id*/,
std::unordered_map<int32_t /*node_id*/, fuchsia::accessibility::Node>>
nodes_;
// Maps view ids to the list of nodes that should be updated or added to the
// tree on the next commit.
std::unordered_map<zx_koid_t /*view_id*/,
std::vector<fuchsia::accessibility::Node>>
uncommitted_nodes_;
// Maps view ids to the list of local node ids that should be removed from
// the next commit.
std::unordered_map<zx_koid_t /*view_id*/, std::vector<int32_t> /*node_ids*/>
uncommitted_deletes_;
// Maps view ids to SemanticsProvider pointers that the SemanticTree
// can use to ask front-ends to perform accessibility actions.
std::unordered_map<zx_koid_t /*view_id*/,
fuchsia::accessibility::SemanticsProviderPtr>
providers_;
FXL_DISALLOW_COPY_AND_ASSIGN(SemanticTree);
};
} // namespace a11y_manager
#endif // GARNET_BIN_A11Y_A11Y_MANAGER_SEMANTIC_TREE_H_