blob: 35669c544981b5f8e8c3eda0e3cfa48b78185569 [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:
Wez7a5f5ca2020-08-17 07:41:0841 // |semantics_manager| is used during construction to register the instance.
Sharon Yangfbb9ba4a2019-11-18 23:59:5642 // |web_contents| is required to exist for the duration of |this|.
Sharon Yang23a8135b2019-09-10 21:10:5443 AccessibilityBridge(
Wez7a5f5ca2020-08-17 07:41:0844 fuchsia::accessibility::semantics::SemanticsManager* semantics_manager,
Sharon Yangfbb9ba4a2019-11-18 23:59:5645 fuchsia::ui::views::ViewRef view_ref,
Sharon Yang7919fab2020-07-28 16:46:2046 content::WebContents* web_contents,
Sharon Yang023ea722020-08-05 23:28:1147 base::OnceCallback<void(zx_status_t)> on_error_callback);
Sharon Yang23a8135b2019-09-10 21:10:5448 ~AccessibilityBridge() final;
49
Sharon Yang7919fab2020-07-28 16:46:2050 AccessibilityBridge(const AccessibilityBridge&) = delete;
51 AccessibilityBridge& operator=(const AccessibilityBridge&) = delete;
52
Sharon Yang3231ad92020-08-12 02:22:0853 const ui::AXSerializableTree* ax_tree_for_test() { return &ax_tree_; }
54
55 void set_event_received_callback_for_test(base::OnceClosure callback) {
56 event_received_callback_for_test_ = std::move(callback);
57 }
58
Sharon Yang23a8135b2019-09-10 21:10:5459 private:
Sharon Yangfbb9ba4a2019-11-18 23:59:5660 FRIEND_TEST_ALL_PREFIXES(AccessibilityBridgeTest, OnSemanticsModeChanged);
61
Sharon Yang3231ad92020-08-12 02:22:0862 // A struct used for caching semantic information. This allows for updates
63 // and deletes to be stored in the same vector to preserve all ordering
Sharon Yangca616422019-12-18 23:52:3964 // information.
65 struct SemanticUpdateOrDelete {
66 enum Type { UPDATE, DELETE };
67
68 SemanticUpdateOrDelete(SemanticUpdateOrDelete&& m);
69 SemanticUpdateOrDelete(Type type,
70 fuchsia::accessibility::semantics::Node node,
71 uint32_t id_to_delete);
72 ~SemanticUpdateOrDelete() = default;
73
74 Type type;
75 fuchsia::accessibility::semantics::Node update_node;
76 uint32_t id_to_delete;
77 };
78
79 // Processes pending data and commits it to the Semantic Tree.
Sharon Yangfbb9ba4a2019-11-18 23:59:5680 void TryCommit();
81
Sharon Yangca616422019-12-18 23:52:3982 // Helper function for TryCommit() that sends the contents of |to_send_| to
83 // the Semantic Tree, starting at |start|.
84 void DispatchSemanticsMessages(size_t start, size_t size);
85
Sharon Yangfbb9ba4a2019-11-18 23:59:5686 // Callback for SemanticTree::CommitUpdates.
87 void OnCommitComplete();
88
Sharon Yang3231ad92020-08-12 02:22:0889 // Deletes all nodes in subtree rooted at and including |node|, unless
90 // |node| is the root of the tree. |tree| and |node| are owned by the
91 // accessibility bridge.
92 void DeleteSubtree(ui::AXNode* node);
Sharon Yangca616422019-12-18 23:52:3993
Sharon Yangfbb9ba4a2019-11-18 23:59:5694 // content::WebContentsObserver implementation.
95 void AccessibilityEventReceived(
96 const content::AXEventNotificationDetails& details) override;
97
Sharon Yang23a8135b2019-09-10 21:10:5498 // fuchsia::accessibility::semantics::SemanticListener implementation.
99 void OnAccessibilityActionRequested(
100 uint32_t node_id,
101 fuchsia::accessibility::semantics::Action action,
102 OnAccessibilityActionRequestedCallback callback) final;
103 void HitTest(fuchsia::math::PointF local_point,
104 HitTestCallback callback) final;
105 void OnSemanticsModeChanged(bool updates_enabled,
106 OnSemanticsModeChangedCallback callback) final;
107
Sharon Yangfbb9ba4a2019-11-18 23:59:56108 // ui::AXTreeObserver implementation.
109 void OnNodeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
Sharon Yangca616422019-12-18 23:52:39110 void OnSubtreeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
Sharon Yangfbb9ba4a2019-11-18 23:59:56111 void OnAtomicUpdateFinished(
112 ui::AXTree* tree,
113 bool root_changed,
114 const std::vector<ui::AXTreeObserver::Change>& changes) override;
115
Sharon Yang3231ad92020-08-12 02:22:08116 fuchsia::accessibility::semantics::SemanticTreePtr semantic_tree_;
Sharon Yang23a8135b2019-09-10 21:10:54117 fidl::Binding<fuchsia::accessibility::semantics::SemanticListener> binding_;
Sharon Yangfbb9ba4a2019-11-18 23:59:56118 content::WebContents* web_contents_;
Sharon Yang3231ad92020-08-12 02:22:08119 ui::AXSerializableTree ax_tree_;
Sharon Yangfbb9ba4a2019-11-18 23:59:56120
Sharon Yangca616422019-12-18 23:52:39121 // Cache for pending data to be sent to the Semantic Tree between commits.
122 std::vector<SemanticUpdateOrDelete> to_send_;
Sharon Yangfbb9ba4a2019-11-18 23:59:56123 bool commit_inflight_ = false;
124
Sharon Yang3231ad92020-08-12 02:22:08125 // Maintain a map of callbacks as multiple hit test events can happen at
126 // once. These are keyed by the request_id field of ui::AXActionData.
Sharon Yang1ab5b4c2019-11-21 01:23:27127 base::flat_map<int, HitTestCallback> pending_hit_test_callbacks_;
128
Sharon Yang023ea722020-08-05 23:28:11129 // Run in the case of an internal error that cannot be recovered from. This
130 // will cause the frame |this| is owned by to be torn down.
131 base::OnceCallback<void(zx_status_t)> on_error_callback_;
Sharon Yang5fb4ce22020-02-08 00:45:21132
Sharon Yang3231ad92020-08-12 02:22:08133 // The root id of |ax_tree_|.
Sharon Yangfbb9ba4a2019-11-18 23:59:56134 int32_t root_id_ = 0;
Sharon Yang3231ad92020-08-12 02:22:08135
136 base::OnceClosure event_received_callback_for_test_;
Sharon Yang23a8135b2019-09-10 21:10:54137};
138
139#endif // FUCHSIA_ENGINE_BROWSER_ACCESSIBILITY_BRIDGE_H_