• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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_H_
6 #define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_H_
7 
8 #include <vector>
9 
10 #include "base/containers/hash_tables.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "build/build_config.h"
13 #include "content/common/accessibility_node_data.h"
14 #include "content/common/content_export.h"
15 #include "third_party/WebKit/public/web/WebAXEnums.h"
16 #include "ui/gfx/native_widget_types.h"
17 
18 struct AccessibilityHostMsg_EventParams;
19 
20 namespace content {
21 class BrowserAccessibility;
22 #if defined(OS_ANDROID)
23 class BrowserAccessibilityManagerAndroid;
24 #endif
25 #if defined(OS_WIN)
26 class BrowserAccessibilityManagerWin;
27 #endif
28 
29 // Class that can perform actions on behalf of the BrowserAccessibilityManager.
30 class CONTENT_EXPORT BrowserAccessibilityDelegate {
31  public:
~BrowserAccessibilityDelegate()32   virtual ~BrowserAccessibilityDelegate() {}
33   virtual void SetAccessibilityFocus(int acc_obj_id) = 0;
34   virtual void AccessibilityDoDefaultAction(int acc_obj_id) = 0;
35   virtual void AccessibilityScrollToMakeVisible(
36       int acc_obj_id, gfx::Rect subfocus) = 0;
37   virtual void AccessibilityScrollToPoint(
38       int acc_obj_id, gfx::Point point) = 0;
39   virtual void AccessibilitySetTextSelection(
40       int acc_obj_id, int start_offset, int end_offset) = 0;
41   virtual bool HasFocus() const = 0;
42   virtual gfx::Rect GetViewBounds() const = 0;
43   virtual gfx::Point GetLastTouchEventLocation() const = 0;
44   virtual void FatalAccessibilityTreeError() = 0;
45 };
46 
47 class CONTENT_EXPORT BrowserAccessibilityFactory {
48  public:
~BrowserAccessibilityFactory()49   virtual ~BrowserAccessibilityFactory() {}
50 
51   // Create an instance of BrowserAccessibility and return a new
52   // reference to it.
53   virtual BrowserAccessibility* Create();
54 };
55 
56 // Manages a tree of BrowserAccessibility objects.
57 class CONTENT_EXPORT BrowserAccessibilityManager {
58  public:
59   // Creates the platform-specific BrowserAccessibilityManager, but
60   // with no parent window pointer. Only useful for unit tests.
61   static BrowserAccessibilityManager* Create(
62       const AccessibilityNodeData& src,
63       BrowserAccessibilityDelegate* delegate,
64       BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory());
65 
66   virtual ~BrowserAccessibilityManager();
67 
68   void Initialize(const AccessibilityNodeData src);
69 
70   static AccessibilityNodeData GetEmptyDocument();
71 
NotifyAccessibilityEvent(blink::WebAXEvent event_type,BrowserAccessibility * node)72   virtual void NotifyAccessibilityEvent(
73       blink::WebAXEvent event_type, BrowserAccessibility* node) { }
74 
75   // Return a pointer to the root of the tree, does not make a new reference.
76   BrowserAccessibility* GetRoot();
77 
78   // Removes a node from the manager.
79   virtual void RemoveNode(BrowserAccessibility* node);
80 
81   // Return a pointer to the object corresponding to the given renderer_id,
82   // does not make a new reference.
83   BrowserAccessibility* GetFromRendererID(int32 renderer_id);
84 
85   // Called to notify the accessibility manager that its associated native
86   // view got focused. This implies that it is shown (opposite of WasHidden,
87   // below).
88   // The touch_event_context parameter indicates that we were called in the
89   // context of a touch event.
90   void GotFocus(bool touch_event_context);
91 
92   // Called to notify the accessibility manager that its associated native
93   // view was hidden. When it's no longer hidden, GotFocus will be called.
94   void WasHidden();
95 
96   // Called to notify the accessibility manager that a mouse down event
97   // occurred in the tab.
98   void GotMouseDown();
99 
100   // Update the focused node to |node|, which may be null.
101   // If |notify| is true, send a message to the renderer to set focus
102   // to this node.
103   void SetFocus(BrowserAccessibility* node, bool notify);
104 
105   // Tell the renderer to do the default action for this node.
106   void DoDefaultAction(const BrowserAccessibility& node);
107 
108   // Tell the renderer to scroll to make |node| visible.
109   // In addition, if it's not possible to make the entire object visible,
110   // scroll so that the |subfocus| rect is visible at least. The subfocus
111   // rect is in local coordinates of the object itself.
112   void ScrollToMakeVisible(
113       const BrowserAccessibility& node, gfx::Rect subfocus);
114 
115   // Tell the renderer to scroll such that |node| is at |point|,
116   // where |point| is in global coordinates of the WebContents.
117   void ScrollToPoint(
118       const BrowserAccessibility& node, gfx::Point point);
119 
120   // Tell the renderer to set the text selection on a node.
121   void SetTextSelection(
122       const BrowserAccessibility& node, int start_offset, int end_offset);
123 
124   // Retrieve the bounds of the parent View in screen coordinates.
125   gfx::Rect GetViewBounds();
126 
127   // Called when the renderer process has notified us of about tree changes.
128   // Send a notification to MSAA clients of the change.
129   void OnAccessibilityEvents(
130       const std::vector<AccessibilityHostMsg_EventParams>& params);
131 
132 #if defined(OS_WIN)
133   BrowserAccessibilityManagerWin* ToBrowserAccessibilityManagerWin();
134 #endif
135 
136 #if defined(OS_ANDROID)
137   BrowserAccessibilityManagerAndroid* ToBrowserAccessibilityManagerAndroid();
138 #endif
139 
140   // Return the object that has focus, if it's a descandant of the
141   // given root (inclusive). Does not make a new reference.
142   BrowserAccessibility* GetFocus(BrowserAccessibility* root);
143 
144   // Is the on-screen keyboard allowed to be shown, in response to a
145   // focus event on a text box?
146   bool IsOSKAllowed(const gfx::Rect& bounds);
147 
148   // True by default, but some platforms want to treat the root
149   // scroll offsets separately.
150   virtual bool UseRootScrollOffsetsWhenComputingBounds();
151 
152   // For testing only: update the given nodes as if they were
153   // received from the renderer process in OnAccessibilityEvents.
154   // Takes up to 7 nodes at once so tests don't need to create a vector
155   // each time.
156   void UpdateNodesForTesting(
157       const AccessibilityNodeData& node,
158       const AccessibilityNodeData& node2 = AccessibilityNodeData(),
159       const AccessibilityNodeData& node3 = AccessibilityNodeData(),
160       const AccessibilityNodeData& node4 = AccessibilityNodeData(),
161       const AccessibilityNodeData& node5 = AccessibilityNodeData(),
162       const AccessibilityNodeData& node6 = AccessibilityNodeData(),
163       const AccessibilityNodeData& node7 = AccessibilityNodeData());
164 
165  protected:
166   BrowserAccessibilityManager(
167       BrowserAccessibilityDelegate* delegate,
168       BrowserAccessibilityFactory* factory);
169 
170   BrowserAccessibilityManager(
171       const AccessibilityNodeData& src,
172       BrowserAccessibilityDelegate* delegate,
173       BrowserAccessibilityFactory* factory);
174 
175   virtual void AddNodeToMap(BrowserAccessibility* node);
176 
NotifyRootChanged()177   virtual void NotifyRootChanged() {}
178 
179  private:
180   // The following states keep track of whether or not the
181   // on-screen keyboard is allowed to be shown.
182   enum OnScreenKeyboardState {
183     // Never show the on-screen keyboard because this tab is hidden.
184     OSK_DISALLOWED_BECAUSE_TAB_HIDDEN,
185 
186     // This tab was just shown, so don't pop-up the on-screen keyboard if a
187     // text field gets focus that wasn't the result of an explicit touch.
188     OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED,
189 
190     // A touch event has occurred within the window, but focus has not
191     // explicitly changed. Allow the on-screen keyboard to be shown if the
192     // touch event was within the bounds of the currently focused object.
193     // Otherwise we'll just wait to see if focus changes.
194     OSK_ALLOWED_WITHIN_FOCUSED_OBJECT,
195 
196     // Focus has changed within a tab that's already visible. Allow the
197     // on-screen keyboard to show anytime that a touch event leads to an
198     // editable text control getting focus.
199     OSK_ALLOWED
200   };
201 
202   // Update a set of nodes using data received from the renderer
203   // process.
204   bool UpdateNodes(const std::vector<AccessibilityNodeData>& nodes);
205 
206   // Update one node from the tree using data received from the renderer
207   // process. Returns true on success, false on fatal error.
208   bool UpdateNode(const AccessibilityNodeData& src);
209 
210   void SetRoot(BrowserAccessibility* root);
211 
212   BrowserAccessibility* CreateNode(
213       BrowserAccessibility* parent,
214       int32 renderer_id,
215       int32 index_in_parent);
216 
217  protected:
218   // The object that can perform actions on our behalf.
219   BrowserAccessibilityDelegate* delegate_;
220 
221   // Factory to create BrowserAccessibility objects (for dependency injection).
222   scoped_ptr<BrowserAccessibilityFactory> factory_;
223 
224   // The root of the tree of accessible objects and the element that
225   // currently has focus, if any.
226   BrowserAccessibility* root_;
227   BrowserAccessibility* focus_;
228 
229   // The on-screen keyboard state.
230   OnScreenKeyboardState osk_state_;
231 
232   // A mapping from renderer IDs to BrowserAccessibility objects.
233   base::hash_map<int32, BrowserAccessibility*> renderer_id_map_;
234 
235   DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManager);
236 };
237 
238 }  // namespace content
239 
240 #endif  // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_H_
241