blob: 1528651ec9d0a524253b9884c99c41cdff46eaaa [file] [log] [blame]
Sharon Yang23a8135b2019-09-10 21:10:541// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef FUCHSIA_ENGINE_BROWSER_ACCESSIBILITY_BRIDGE_H_
6#define FUCHSIA_ENGINE_BROWSER_ACCESSIBILITY_BRIDGE_H_
7
8#include <fuchsia/accessibility/semantics/cpp/fidl.h>
9#include <fuchsia/math/cpp/fidl.h>
10#include <fuchsia/ui/views/cpp/fidl.h>
11#include <lib/fidl/cpp/binding.h>
12
Sharon Yangfbb9ba4a2019-11-18 23:59:5613#include "base/callback.h"
Sharon Yang23a8135b2019-09-10 21:10:5414#include "base/macros.h"
Sharon Yangfbb9ba4a2019-11-18 23:59:5615#include "content/public/browser/ax_event_notification_details.h"
16#include "content/public/browser/web_contents_delegate.h"
17#include "content/public/browser/web_contents_observer.h"
Sharon Yang23a8135b2019-09-10 21:10:5418#include "fuchsia/engine/web_engine_export.h"
Sharon Yangfbb9ba4a2019-11-18 23:59:5619#include "ui/accessibility/ax_serializable_tree.h"
20#include "ui/accessibility/ax_tree_id.h"
21#include "ui/accessibility/ax_tree_observer.h"
22
23namespace content {
24class WebContents;
25} // namespace content
Sharon Yang23a8135b2019-09-10 21:10:5426
27// This class is the intermediate for accessibility between Chrome and Fuchsia.
28// It handles registration to the Fuchsia Semantics Manager, translating events
29// and data structures between the two services, and forwarding actions and
30// events.
31// The lifetime of an instance of AccessibilityBridge is the same as that of a
32// View created by FrameImpl. This class refers to the View via the
33// caller-supplied ViewRef.
Sharon Yang3231ad92020-08-12 02:22:0834// If |semantic_tree_| gets disconnected, it will cause the FrameImpl that owns
Sharon Yang7919fab2020-07-28 16:46:2035// |this| to close, which will also destroy |this|.
Sharon Yang23a8135b2019-09-10 21:10:5436class WEB_ENGINE_EXPORT AccessibilityBridge
Sharon Yangfbb9ba4a2019-11-18 23:59:5637 : public content::WebContentsObserver,
38 public fuchsia::accessibility::semantics::SemanticListener,
39 public ui::AXTreeObserver {
Sharon Yang23a8135b2019-09-10 21:10:5440 public:
Sharon Yangfbb9ba4a2019-11-18 23:59:5641 // |web_contents| is required to exist for the duration of |this|.
Sharon Yang23a8135b2019-09-10 21:10:5442 AccessibilityBridge(
43 fuchsia::accessibility::semantics::SemanticsManagerPtr semantics_manager,
Sharon Yangfbb9ba4a2019-11-18 23:59:5644 fuchsia::ui::views::ViewRef view_ref,
Sharon Yang7919fab2020-07-28 16:46:2045 content::WebContents* web_contents,
Sharon Yang023ea722020-08-05 23:28:1146 base::OnceCallback<void(zx_status_t)> on_error_callback);
Sharon Yang23a8135b2019-09-10 21:10:5447 ~AccessibilityBridge() final;
48
Sharon Yang7919fab2020-07-28 16:46:2049 AccessibilityBridge(const AccessibilityBridge&) = delete;
50 AccessibilityBridge& operator=(const AccessibilityBridge&) = delete;
51
Sharon Yang3231ad92020-08-12 02:22:0852 const ui::AXSerializableTree* ax_tree_for_test() { return &ax_tree_; }
53
54 void set_event_received_callback_for_test(base::OnceClosure callback) {
55 event_received_callback_for_test_ = std::move(callback);
56 }
57
Sharon Yang23a8135b2019-09-10 21:10:5458 private:
Sharon Yangfbb9ba4a2019-11-18 23:59:5659 FRIEND_TEST_ALL_PREFIXES(AccessibilityBridgeTest, OnSemanticsModeChanged);
60
Sharon Yang3231ad92020-08-12 02:22:0861 // A struct used for caching semantic information. This allows for updates
62 // and deletes to be stored in the same vector to preserve all ordering
Sharon Yangca616422019-12-18 23:52:3963 // information.
64 struct SemanticUpdateOrDelete {
65 enum Type { UPDATE, DELETE };
66
67 SemanticUpdateOrDelete(SemanticUpdateOrDelete&& m);
68 SemanticUpdateOrDelete(Type type,
69 fuchsia::accessibility::semantics::Node node,
70 uint32_t id_to_delete);
71 ~SemanticUpdateOrDelete() = default;
72
73 Type type;
74 fuchsia::accessibility::semantics::Node update_node;
75 uint32_t id_to_delete;
76 };
77
78 // Processes pending data and commits it to the Semantic Tree.
Sharon Yangfbb9ba4a2019-11-18 23:59:5679 void TryCommit();
80
Sharon Yangca616422019-12-18 23:52:3981 // Helper function for TryCommit() that sends the contents of |to_send_| to
82 // the Semantic Tree, starting at |start|.
83 void DispatchSemanticsMessages(size_t start, size_t size);
84
Sharon Yangfbb9ba4a2019-11-18 23:59:5685 // Callback for SemanticTree::CommitUpdates.
86 void OnCommitComplete();
87
Sharon Yang3231ad92020-08-12 02:22:0888 // Converts AXNode ids to Semantic Node ids, and handles special casing of
89 // the root.
Sharon Yangfbb9ba4a2019-11-18 23:59:5690 uint32_t ConvertToFuchsiaNodeId(int32_t ax_node_id);
91
Sharon Yang3231ad92020-08-12 02:22:0892 // Deletes all nodes in subtree rooted at and including |node|, unless
93 // |node| is the root of the tree. |tree| and |node| are owned by the
94 // accessibility bridge.
95 void DeleteSubtree(ui::AXNode* node);
Sharon Yangca616422019-12-18 23:52:3996
Sharon Yangfbb9ba4a2019-11-18 23:59:5697 // content::WebContentsObserver implementation.
98 void AccessibilityEventReceived(
99 const content::AXEventNotificationDetails& details) override;
100
Sharon Yang23a8135b2019-09-10 21:10:54101 // fuchsia::accessibility::semantics::SemanticListener implementation.
102 void OnAccessibilityActionRequested(
103 uint32_t node_id,
104 fuchsia::accessibility::semantics::Action action,
105 OnAccessibilityActionRequestedCallback callback) final;
106 void HitTest(fuchsia::math::PointF local_point,
107 HitTestCallback callback) final;
108 void OnSemanticsModeChanged(bool updates_enabled,
109 OnSemanticsModeChangedCallback callback) final;
110
Sharon Yangfbb9ba4a2019-11-18 23:59:56111 // ui::AXTreeObserver implementation.
112 void OnNodeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
Sharon Yangca616422019-12-18 23:52:39113 void OnSubtreeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
Sharon Yangfbb9ba4a2019-11-18 23:59:56114 void OnAtomicUpdateFinished(
115 ui::AXTree* tree,
116 bool root_changed,
117 const std::vector<ui::AXTreeObserver::Change>& changes) override;
118
Sharon Yang3231ad92020-08-12 02:22:08119 fuchsia::accessibility::semantics::SemanticTreePtr semantic_tree_;
Sharon Yang23a8135b2019-09-10 21:10:54120 fidl::Binding<fuchsia::accessibility::semantics::SemanticListener> binding_;
Sharon Yangfbb9ba4a2019-11-18 23:59:56121 content::WebContents* web_contents_;
Sharon Yang3231ad92020-08-12 02:22:08122 ui::AXSerializableTree ax_tree_;
Sharon Yangfbb9ba4a2019-11-18 23:59:56123
Sharon Yangca616422019-12-18 23:52:39124 // Cache for pending data to be sent to the Semantic Tree between commits.
125 std::vector<SemanticUpdateOrDelete> to_send_;
Sharon Yangfbb9ba4a2019-11-18 23:59:56126 bool commit_inflight_ = false;
127
Sharon Yang3231ad92020-08-12 02:22:08128 // Maintain a map of callbacks as multiple hit test events can happen at
129 // once. These are keyed by the request_id field of ui::AXActionData.
Sharon Yang1ab5b4c2019-11-21 01:23:27130 base::flat_map<int, HitTestCallback> pending_hit_test_callbacks_;
131
Sharon Yang023ea722020-08-05 23:28:11132 // Run in the case of an internal error that cannot be recovered from. This
133 // will cause the frame |this| is owned by to be torn down.
134 base::OnceCallback<void(zx_status_t)> on_error_callback_;
Sharon Yang5fb4ce22020-02-08 00:45:21135
Sharon Yang3231ad92020-08-12 02:22:08136 // The root id of |ax_tree_|.
Sharon Yangfbb9ba4a2019-11-18 23:59:56137 int32_t root_id_ = 0;
Sharon Yang3231ad92020-08-12 02:22:08138
139 base::OnceClosure event_received_callback_for_test_;
Sharon Yang23a8135b2019-09-10 21:10:54140};
141
142#endif // FUCHSIA_ENGINE_BROWSER_ACCESSIBILITY_BRIDGE_H_