1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
// 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.
#ifndef FUCHSIA_ENGINE_BROWSER_ACCESSIBILITY_BRIDGE_H_
#define FUCHSIA_ENGINE_BROWSER_ACCESSIBILITY_BRIDGE_H_
#include <fuchsia/accessibility/semantics/cpp/fidl.h>
#include <fuchsia/math/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include "base/callback.h"
#include "base/macros.h"
#include "content/public/browser/ax_event_notification_details.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "fuchsia/engine/web_engine_export.h"
#include "ui/accessibility/ax_serializable_tree.h"
#include "ui/accessibility/ax_tree_id.h"
#include "ui/accessibility/ax_tree_observer.h"
namespace content {
class WebContents;
} // namespace content
// This class is the intermediate for accessibility between Chrome and Fuchsia.
// It handles registration to the Fuchsia Semantics Manager, translating events
// and data structures between the two services, and forwarding actions and
// events.
// The lifetime of an instance of AccessibilityBridge is the same as that of a
// View created by FrameImpl. This class refers to the View via the
// caller-supplied ViewRef.
class WEB_ENGINE_EXPORT AccessibilityBridge
: public content::WebContentsObserver,
public fuchsia::accessibility::semantics::SemanticListener,
public ui::AXTreeObserver {
public:
// |web_contents| is required to exist for the duration of |this|.
AccessibilityBridge(
fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager,
fuchsia::ui::views::ViewRef view_ref,
content::WebContents* web_contents);
~AccessibilityBridge() final;
void set_handle_actions_for_test(bool handle) {
handle_actions_for_test_ = handle;
}
private:
FRIEND_TEST_ALL_PREFIXES(AccessibilityBridgeTest, OnSemanticsModeChanged);
// A struct used for caching semantic information. This allows for updates and
// deletes to be stored in the same vector to preserve all ordering
// information.
struct SemanticUpdateOrDelete {
enum Type { UPDATE, DELETE };
SemanticUpdateOrDelete(SemanticUpdateOrDelete&& m);
SemanticUpdateOrDelete(Type type,
fuchsia::accessibility::semantics::Node node,
uint32_t id_to_delete);
~SemanticUpdateOrDelete() = default;
Type type;
fuchsia::accessibility::semantics::Node update_node;
uint32_t id_to_delete;
};
// Processes pending data and commits it to the Semantic Tree.
void TryCommit();
// Helper function for TryCommit() that sends the contents of |to_send_| to
// the Semantic Tree, starting at |start|.
void DispatchSemanticsMessages(size_t start, size_t size);
// Callback for SemanticTree::CommitUpdates.
void OnCommitComplete();
// Converts AXNode ids to Semantic Node ids, and handles special casing of the
// root.
uint32_t ConvertToFuchsiaNodeId(int32_t ax_node_id);
// Deletes all nodes in subtree rooted at and including |node|, unless |node|
// is the root of the tree.
// |tree| and |node| are owned by the accessibility bridge.
void DeleteSubtree(ui::AXTree* tree, ui::AXNode* node);
// content::WebContentsObserver implementation.
void AccessibilityEventReceived(
const content::AXEventNotificationDetails& details) override;
// fuchsia::accessibility::semantics::SemanticListener implementation.
void OnAccessibilityActionRequested(
uint32_t node_id,
fuchsia::accessibility::semantics::Action action,
OnAccessibilityActionRequestedCallback callback) final;
void HitTest(fuchsia::math::PointF local_point,
HitTestCallback callback) final;
void OnSemanticsModeChanged(bool updates_enabled,
OnSemanticsModeChangedCallback callback) final;
// ui::AXTreeObserver implementation.
void OnNodeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
void OnSubtreeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
void OnAtomicUpdateFinished(
ui::AXTree* tree,
bool root_changed,
const std::vector<ui::AXTreeObserver::Change>& changes) override;
fuchsia::accessibility::semantics::SemanticTreePtr tree_ptr_;
fidl::Binding<fuchsia::accessibility::semantics::SemanticListener> binding_;
content::WebContents* web_contents_;
ui::AXSerializableTree tree_;
// Cache for pending data to be sent to the Semantic Tree between commits.
std::vector<SemanticUpdateOrDelete> to_send_;
bool commit_inflight_ = false;
// Maintain a map of callbacks as multiple hit test events can happen at once.
// These are keyed by the request_id field of ui::AXActionData.
base::flat_map<int, HitTestCallback> pending_hit_test_callbacks_;
// Maintain a map of callbacks for accessibility actions. Entries are keyed by
// node id the action is performed on.
base::flat_map<int, OnAccessibilityActionRequestedCallback>
pending_accessibility_action_callbacks_;
// The root id of |tree_|.
int32_t root_id_ = 0;
bool handle_actions_for_test_ = true;
DISALLOW_COPY_AND_ASSIGN(AccessibilityBridge);
};
#endif // FUCHSIA_ENGINE_BROWSER_ACCESSIBILITY_BRIDGE_H_
|