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