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 "ui/gfx/native_widget_types.h" 16 17 struct AccessibilityHostMsg_NotificationParams; 18 19 namespace content { 20 class BrowserAccessibility; 21 #if defined(OS_WIN) 22 class BrowserAccessibilityManagerWin; 23 #endif 24 25 // Class that can perform actions on behalf of the BrowserAccessibilityManager. 26 class CONTENT_EXPORT BrowserAccessibilityDelegate { 27 public: 28 virtual ~BrowserAccessibilityDelegate() {} 29 virtual void SetAccessibilityFocus(int acc_obj_id) = 0; 30 virtual void AccessibilityDoDefaultAction(int acc_obj_id) = 0; 31 virtual void AccessibilityScrollToMakeVisible( 32 int acc_obj_id, gfx::Rect subfocus) = 0; 33 virtual void AccessibilityScrollToPoint( 34 int acc_obj_id, gfx::Point point) = 0; 35 virtual void AccessibilitySetTextSelection( 36 int acc_obj_id, int start_offset, int end_offset) = 0; 37 virtual bool HasFocus() const = 0; 38 virtual gfx::Rect GetViewBounds() const = 0; 39 virtual gfx::Point GetLastTouchEventLocation() const = 0; 40 virtual void FatalAccessibilityTreeError() = 0; 41 }; 42 43 class CONTENT_EXPORT BrowserAccessibilityFactory { 44 public: 45 virtual ~BrowserAccessibilityFactory() {} 46 47 // Create an instance of BrowserAccessibility and return a new 48 // reference to it. 49 virtual BrowserAccessibility* Create(); 50 }; 51 52 // Manages a tree of BrowserAccessibility objects. 53 class CONTENT_EXPORT BrowserAccessibilityManager { 54 public: 55 // Creates the platform-specific BrowserAccessibilityManager, but 56 // with no parent window pointer. Only useful for unit tests. 57 static BrowserAccessibilityManager* Create( 58 const AccessibilityNodeData& src, 59 BrowserAccessibilityDelegate* delegate, 60 BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory()); 61 62 virtual ~BrowserAccessibilityManager(); 63 64 void Initialize(const AccessibilityNodeData src); 65 66 static AccessibilityNodeData GetEmptyDocument(); 67 68 // Type is enum AccessibilityNotification. 69 // We pass it as int so that we don't include the message declaration 70 // header here. 71 virtual void NotifyAccessibilityEvent( 72 int type, 73 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 OnAccessibilityNotifications( 130 const std::vector<AccessibilityHostMsg_NotificationParams>& params); 131 132 #if defined(OS_WIN) 133 BrowserAccessibilityManagerWin* ToBrowserAccessibilityManagerWin(); 134 #endif 135 136 // Return the object that has focus, if it's a descandant of the 137 // given root (inclusive). Does not make a new reference. 138 BrowserAccessibility* GetFocus(BrowserAccessibility* root); 139 140 // Is the on-screen keyboard allowed to be shown, in response to a 141 // focus event on a text box? 142 bool IsOSKAllowed(const gfx::Rect& bounds); 143 144 // True by default, but some platforms want to treat the root 145 // scroll offsets separately. 146 virtual bool UseRootScrollOffsetsWhenComputingBounds(); 147 148 // For testing only: update the given nodes as if they were 149 // received from the renderer process in OnAccessibilityNotifications. 150 // Takes up to 7 nodes at once so tests don't need to create a vector 151 // each time. 152 void UpdateNodesForTesting( 153 const AccessibilityNodeData& node, 154 const AccessibilityNodeData& node2 = AccessibilityNodeData(), 155 const AccessibilityNodeData& node3 = AccessibilityNodeData(), 156 const AccessibilityNodeData& node4 = AccessibilityNodeData(), 157 const AccessibilityNodeData& node5 = AccessibilityNodeData(), 158 const AccessibilityNodeData& node6 = AccessibilityNodeData(), 159 const AccessibilityNodeData& node7 = AccessibilityNodeData()); 160 161 protected: 162 BrowserAccessibilityManager( 163 BrowserAccessibilityDelegate* delegate, 164 BrowserAccessibilityFactory* factory); 165 166 BrowserAccessibilityManager( 167 const AccessibilityNodeData& src, 168 BrowserAccessibilityDelegate* delegate, 169 BrowserAccessibilityFactory* factory); 170 171 virtual void AddNodeToMap(BrowserAccessibility* node); 172 173 virtual void NotifyRootChanged() {} 174 175 private: 176 // The following states keep track of whether or not the 177 // on-screen keyboard is allowed to be shown. 178 enum OnScreenKeyboardState { 179 // Never show the on-screen keyboard because this tab is hidden. 180 OSK_DISALLOWED_BECAUSE_TAB_HIDDEN, 181 182 // This tab was just shown, so don't pop-up the on-screen keyboard if a 183 // text field gets focus that wasn't the result of an explicit touch. 184 OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED, 185 186 // A touch event has occurred within the window, but focus has not 187 // explicitly changed. Allow the on-screen keyboard to be shown if the 188 // touch event was within the bounds of the currently focused object. 189 // Otherwise we'll just wait to see if focus changes. 190 OSK_ALLOWED_WITHIN_FOCUSED_OBJECT, 191 192 // Focus has changed within a tab that's already visible. Allow the 193 // on-screen keyboard to show anytime that a touch event leads to an 194 // editable text control getting focus. 195 OSK_ALLOWED 196 }; 197 198 // Update a set of nodes using data received from the renderer 199 // process. 200 bool UpdateNodes(const std::vector<AccessibilityNodeData>& nodes); 201 202 // Update one node from the tree using data received from the renderer 203 // process. Returns true on success, false on fatal error. 204 bool UpdateNode(const AccessibilityNodeData& src); 205 206 void SetRoot(BrowserAccessibility* root); 207 208 BrowserAccessibility* CreateNode( 209 BrowserAccessibility* parent, 210 int32 renderer_id, 211 int32 index_in_parent); 212 213 protected: 214 // The object that can perform actions on our behalf. 215 BrowserAccessibilityDelegate* delegate_; 216 217 // Factory to create BrowserAccessibility objects (for dependency injection). 218 scoped_ptr<BrowserAccessibilityFactory> factory_; 219 220 // The root of the tree of accessible objects and the element that 221 // currently has focus, if any. 222 BrowserAccessibility* root_; 223 BrowserAccessibility* focus_; 224 225 // The on-screen keyboard state. 226 OnScreenKeyboardState osk_state_; 227 228 // A mapping from renderer IDs to BrowserAccessibility objects. 229 base::hash_map<int32, BrowserAccessibility*> renderer_id_map_; 230 231 DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManager); 232 }; 233 234 } // namespace content 235 236 #endif // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_H_ 237