1 // Copyright 2013 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 CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_ANDROID_H_
6 #define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_ANDROID_H_
7 
8 #include <utility>
9 
10 #include "content/browser/accessibility/browser_accessibility_manager.h"
11 #include "content/common/render_accessibility.mojom-forward.h"
12 
13 namespace ui {
14 class MotionEventAndroid;
15 }
16 
17 namespace content {
18 
19 // A Java counterpart will be generated for this enum.
20 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.content.browser.accessibility
21 enum ScrollDirection { FORWARD, BACKWARD, UP, DOWN, LEFT, RIGHT };
22 
23 // From android.view.accessibility.AccessibilityNodeInfo in Java:
24 enum AndroidMovementGranularity {
25   ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_CHARACTER = 1,
26   ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_WORD = 2,
27   ANDROID_ACCESSIBILITY_NODE_INFO_MOVEMENT_GRANULARITY_LINE = 4
28 };
29 
30 // From android.view.accessibility.AccessibilityEvent in Java:
31 enum {
32   ANDROID_ACCESSIBILITY_EVENT_TEXT_CHANGED = 16,
33   ANDROID_ACCESSIBILITY_EVENT_TEXT_SELECTION_CHANGED = 8192,
34   ANDROID_ACCESSIBILITY_EVENT_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072
35 };
36 
37 class BrowserAccessibilityAndroid;
38 class WebContentsAccessibilityAndroid;
39 
40 class CONTENT_EXPORT BrowserAccessibilityManagerAndroid
41     : public BrowserAccessibilityManager {
42  public:
43   BrowserAccessibilityManagerAndroid(
44       const ui::AXTreeUpdate& initial_tree,
45       base::WeakPtr<WebContentsAccessibilityAndroid> web_contents_accessibility,
46       BrowserAccessibilityDelegate* delegate);
47 
48   ~BrowserAccessibilityManagerAndroid() override;
49 
50   static ui::AXTreeUpdate GetEmptyDocument();
51 
52   // By default, the tree is pruned for a better screen reading experience,
53   // including:
54   //   * If the node has only static text children
55   //   * If the node is focusable and has no focusable children
56   //   * If the node is a heading
57   // This can be turned off to generate a tree that more accurately reflects
58   // the DOM and includes style changes within these nodes.
set_prune_tree_for_screen_reader(bool prune)59   void set_prune_tree_for_screen_reader(bool prune) {
60     prune_tree_for_screen_reader_ = prune;
61   }
prune_tree_for_screen_reader()62   bool prune_tree_for_screen_reader() { return prune_tree_for_screen_reader_; }
63 
set_web_contents_accessibility(base::WeakPtr<WebContentsAccessibilityAndroid> wcax)64   void set_web_contents_accessibility(
65       base::WeakPtr<WebContentsAccessibilityAndroid> wcax) {
66     web_contents_accessibility_ = std::move(wcax);
67   }
68 
69   bool ShouldRespectDisplayedPasswordText();
70   bool ShouldExposePasswordText();
71 
72   // Consume hover event if necessary, and return true if it did.
73   bool OnHoverEvent(const ui::MotionEventAndroid& event);
74 
75   // BrowserAccessibilityManager overrides.
76   BrowserAccessibility* GetFocus() const override;
77   void SendLocationChangeEvents(
78       const std::vector<mojom::LocationChangesPtr>& changes) override;
79   BrowserAccessibility* RetargetForEvents(
80       BrowserAccessibility* node,
81       RetargetEventType type) const override;
82   void FireFocusEvent(BrowserAccessibility* node) override;
83   void FireBlinkEvent(ax::mojom::Event event_type,
84                       BrowserAccessibility* node) override;
85   void FireGeneratedEvent(ui::AXEventGenerator::Event event_type,
86                           BrowserAccessibility* node) override;
87   gfx::Rect GetViewBoundsInScreenCoordinates() const override;
88 
89   void FireLocationChanged(BrowserAccessibility* node);
90 
91   // Helper functions to compute the next start and end index when moving
92   // forwards or backwards by character, word, or line. This part is
93   // unit-tested; the Java interfaces above are just wrappers. Both of these
94   // take a single cursor index as input and return the boundaries surrounding
95   // the next word or line. If moving by character, the output start and
96   // end index will be the same.
97   bool NextAtGranularity(int32_t granularity,
98                          int cursor_index,
99                          BrowserAccessibilityAndroid* node,
100                          int32_t* start_index,
101                          int32_t* end_index);
102   bool PreviousAtGranularity(int32_t granularity,
103                              int cursor_index,
104                              BrowserAccessibilityAndroid* node,
105                              int32_t* start_index,
106                              int32_t* end_index);
107 
108   // Helper method to clear AccessibilityNodeInfo cache on given node
109   void ClearNodeInfoCacheForGivenId(int32_t unique_id);
110 
111  private:
112   // AXTreeObserver overrides.
113   void OnAtomicUpdateFinished(
114       ui::AXTree* tree,
115       bool root_changed,
116       const std::vector<ui::AXTreeObserver::Change>& changes) override;
117 
118   void OnNodeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
119 
120   WebContentsAccessibilityAndroid* GetWebContentsAXFromRootManager();
121 
122   // This gives BrowserAccessibilityManager::Create access to the class
123   // constructor.
124   friend class BrowserAccessibilityManager;
125 
126   // Handle a hover event from the renderer process.
127   void HandleHoverEvent(BrowserAccessibility* node);
128 
129   // A weak reference to WebContentsAccessibility for reaching Java layer.
130   // Only the root manager has the reference. Should be accessed through
131   // |GetWebContentsAXFromRootManager| rather than directly.
132   base::WeakPtr<WebContentsAccessibilityAndroid> web_contents_accessibility_;
133 
134   // See docs for set_prune_tree_for_screen_reader, above.
135   bool prune_tree_for_screen_reader_;
136 
137   // A count of the number of TYPE_WINDOW_CONTENT_CHANGED events we've
138   // fired during a single atomic update.
139   int content_changed_events_ = 0;
140 
141   DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManagerAndroid);
142 };
143 
144 }  // namespace content
145 
146 #endif  // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_ANDROID_H_
147