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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_ANDROID_H_
#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_ANDROID_H_
#include <utility>
#include "content/common/content_export.h"
#include "third_party/abseil-cpp/absl/container/flat_hash_set.h"
#include "ui/accessibility/platform/browser_accessibility_manager.h"
namespace ui {
class MotionEventAndroid;
class AXPlatformTreeManagerDelegate;
} // namespace ui
namespace content {
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.content.browser.accessibility
enum ScrollDirection { FORWARD, BACKWARD, UP, DOWN, LEFT, RIGHT };
// From android.view.accessibility.AccessibilityNodeInfo in Java:
enum AndroidMovementGranularity {
ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_CHARACTER = 1,
ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_WORD = 2,
ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_LINE = 4
};
// From android.view.accessibility.AccessibilityEvent in Java:
enum {
ANDROID_ACCESSIBILITY_EVENT_CONTENT_CHANGE_TYPE_UNDEFINED = 0,
ANDROID_ACCESSIBILITY_EVENT_CONTENT_CHANGE_TYPE_TEXT = 2,
ANDROID_ACCESSIBILITY_EVENT_CONTENT_CHANGE_TYPE_PANE_TITLE = 8,
ANDROID_ACCESSIBILITY_EVENT_TEXT_CHANGED = 16,
ANDROID_ACCESSIBILITY_EVENT_CONTENT_CHANGE_TYPE_STATE_DESCRIPTION = 64,
ANDROID_ACCESSIBILITY_EVENT_TEXT_SELECTION_CHANGED = 8192,
ANDROID_ACCESSIBILITY_EVENT_CONTENT_CHANGE_TYPE_EXPANDED = 16384,
ANDROID_ACCESSIBILITY_EVENT_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072
};
class BrowserAccessibilityAndroid;
class WebContentsAccessibilityAndroid;
class CONTENT_EXPORT BrowserAccessibilityManagerAndroid
: public ui::BrowserAccessibilityManager {
public:
// Creates the platform-specific BrowserAccessibilityManager.
static BrowserAccessibilityManager* Create(
const ui::AXTreeUpdate& initial_tree,
ui::AXNodeIdDelegate& node_id_delegate,
ui::AXPlatformTreeManagerDelegate* delegate);
static BrowserAccessibilityManager* Create(
ui::AXNodeIdDelegate& node_id_delegate,
ui::AXPlatformTreeManagerDelegate* delegate);
BrowserAccessibilityManagerAndroid(
const ui::AXTreeUpdate& initial_tree,
base::WeakPtr<WebContentsAccessibilityAndroid> web_contents_accessibility,
ui::AXNodeIdDelegate& node_id_delegate,
ui::AXPlatformTreeManagerDelegate* delegate);
BrowserAccessibilityManagerAndroid(
const BrowserAccessibilityManagerAndroid&) = delete;
BrowserAccessibilityManagerAndroid& operator=(
const BrowserAccessibilityManagerAndroid&) = delete;
~BrowserAccessibilityManagerAndroid() override;
static ui::AXTreeUpdate GetEmptyDocument();
void set_allow_image_descriptions_for_testing(bool is_allowed) {
allow_image_descriptions_for_testing_ = is_allowed;
}
const absl::flat_hash_set<int32_t>& nodes_already_cleared_for_test() const {
return nodes_already_cleared_;
}
// By default, the tree is pruned for a better screen reading experience,
// including:
// * If the node has only static text children
// * If the node is focusable and has no focusable children
// * If the node is a heading
// This can be turned off to generate a tree that more accurately reflects
// the DOM and includes style changes within these nodes.
void set_prune_tree_for_screen_reader(bool prune) {
prune_tree_for_screen_reader_ = prune;
}
bool prune_tree_for_screen_reader() { return prune_tree_for_screen_reader_; }
void set_web_contents_accessibility(
base::WeakPtr<WebContentsAccessibilityAndroid> wcax) {
web_contents_accessibility_ = std::move(wcax);
}
void ResetWebContentsAccessibility();
// State properties defined from Java-side code.
bool ShouldAllowImageDescriptions();
// Consume hover event if necessary, and return true if it did.
bool OnHoverEvent(const ui::MotionEventAndroid& event);
// AXTreeManager overrides.
void FireFocusEvent(ui::AXNode* node) override;
// BrowserAccessibilityManager overrides.
ui::BrowserAccessibility* GetFocus() const override;
ui::BrowserAccessibility* GetAccessibilityFocus() const override;
void SendLocationChangeEvents(
const std::vector<ui::AXLocationChange>& changes) override;
ui::AXNode* RetargetForEvents(ui::AXNode* node,
RetargetEventType type) const override;
void FireBlinkEvent(ax::mojom::Event event_type,
ui::BrowserAccessibility* node,
int action_request_id) override;
void FireGeneratedEvent(ui::AXEventGenerator::Event event_type,
const ui::AXNode* node) override;
void FireAriaNotificationEvent(
ui::BrowserAccessibility* node,
const std::string& announcement,
ax::mojom::AriaNotificationPriority priority_property,
ax::mojom::AriaNotificationInterrupt interrupt_property,
const std::string& type) override;
void FireLocationChanged(ui::BrowserAccessibility* node);
// Helper functions to compute the next start and end index when moving
// forwards or backwards by character, word, or line. This part is
// unit-tested; the Java interfaces above are just wrappers. Both of these
// take a single cursor index as input and return the boundaries surrounding
// the next word or line. If moving by character, the output start and
// end index will be the same.
bool NextAtGranularity(int32_t granularity,
int cursor_index,
BrowserAccessibilityAndroid* node,
int32_t* start_index,
int32_t* end_index);
bool PreviousAtGranularity(int32_t granularity,
int cursor_index,
BrowserAccessibilityAndroid* node,
int32_t* start_index,
int32_t* end_index);
// Helper method to clear AccessibilityNodeInfo cache on given node
void ClearNodeInfoCacheForGivenId(int32_t unique_id);
std::u16string GenerateAccessibilityNodeInfoString(int32_t unique_id);
std::vector<std::string> GetMetadataForTree() const;
protected:
std::unique_ptr<ui::BrowserAccessibility> CreateBrowserAccessibility(
ui::AXNode* node) override;
private:
// AXTreeObserver overrides.
void OnAtomicUpdateStarting(
ui::AXTree* tree,
const std::set<ui::AXNodeID>& deleting_nodes,
const std::set<ui::AXNodeID>& reparenting_nodes) override;
void OnAtomicUpdateFinished(
ui::AXTree* tree,
bool root_changed,
const std::vector<ui::AXTreeObserver::Change>& changes) override;
WebContentsAccessibilityAndroid* GetWebContentsAXFromRootManager() const;
// This gives BrowserAccessibilityManager::Create access to the class
// constructor.
friend class ui::BrowserAccessibilityManager;
// Handle a hover event from the renderer process.
void HandleHoverEvent(ui::BrowserAccessibility* node);
// A weak reference to WebContentsAccessibility for reaching Java layer.
// Only the root manager has the reference. Should be accessed through
// |GetWebContentsAXFromRootManager| rather than directly.
base::WeakPtr<WebContentsAccessibilityAndroid> web_contents_accessibility_;
// See docs for set_prune_tree_for_screen_reader, above.
bool prune_tree_for_screen_reader_;
// True if this instance should force enable the image descriptions feature
// for testing. This allows us to mock generated image descriptions and test
// tree dumps for nodes without creating web_contents_accessibility_android.
bool allow_image_descriptions_for_testing_ = false;
// A set of |unique_id| values for nodes cleared from the cache
// with each atomic update to prevent superfluous cache clear calls.
absl::flat_hash_set<int32_t> nodes_already_cleared_;
};
} // namespace content
#endif // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_ANDROID_H_
|