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/content_export.h" 14 #include "third_party/WebKit/public/web/WebAXEnums.h" 15 #include "ui/accessibility/ax_node_data.h" 16 #include "ui/accessibility/ax_tree.h" 17 #include "ui/accessibility/ax_tree_update.h" 18 #include "ui/gfx/native_widget_types.h" 19 20 struct AccessibilityHostMsg_EventParams; 21 struct AccessibilityHostMsg_LocationChangeParams; 22 23 namespace content { 24 class BrowserAccessibility; 25 #if defined(OS_ANDROID) 26 class BrowserAccessibilityManagerAndroid; 27 #endif 28 #if defined(OS_WIN) 29 class BrowserAccessibilityManagerWin; 30 #endif 31 32 // For testing. 33 CONTENT_EXPORT ui::AXTreeUpdate MakeAXTreeUpdate( 34 const ui::AXNodeData& node, 35 const ui::AXNodeData& node2 = ui::AXNodeData(), 36 const ui::AXNodeData& node3 = ui::AXNodeData(), 37 const ui::AXNodeData& node4 = ui::AXNodeData(), 38 const ui::AXNodeData& node5 = ui::AXNodeData(), 39 const ui::AXNodeData& node6 = ui::AXNodeData(), 40 const ui::AXNodeData& node7 = ui::AXNodeData(), 41 const ui::AXNodeData& node8 = ui::AXNodeData(), 42 const ui::AXNodeData& node9 = ui::AXNodeData()); 43 44 // Class that can perform actions on behalf of the BrowserAccessibilityManager. 45 class CONTENT_EXPORT BrowserAccessibilityDelegate { 46 public: ~BrowserAccessibilityDelegate()47 virtual ~BrowserAccessibilityDelegate() {} 48 virtual void AccessibilitySetFocus(int acc_obj_id) = 0; 49 virtual void AccessibilityDoDefaultAction(int acc_obj_id) = 0; 50 virtual void AccessibilityShowMenu(int acc_obj_id) = 0; 51 virtual void AccessibilityScrollToMakeVisible( 52 int acc_obj_id, gfx::Rect subfocus) = 0; 53 virtual void AccessibilityScrollToPoint( 54 int acc_obj_id, gfx::Point point) = 0; 55 virtual void AccessibilitySetTextSelection( 56 int acc_obj_id, int start_offset, int end_offset) = 0; 57 virtual bool AccessibilityViewHasFocus() const = 0; 58 virtual gfx::Rect AccessibilityGetViewBounds() const = 0; 59 virtual gfx::Point AccessibilityOriginInScreen( 60 const gfx::Rect& bounds) const = 0; 61 virtual void AccessibilityHitTest( 62 const gfx::Point& point) = 0; 63 virtual void AccessibilityFatalError() = 0; 64 }; 65 66 class CONTENT_EXPORT BrowserAccessibilityFactory { 67 public: ~BrowserAccessibilityFactory()68 virtual ~BrowserAccessibilityFactory() {} 69 70 // Create an instance of BrowserAccessibility and return a new 71 // reference to it. 72 virtual BrowserAccessibility* Create(); 73 }; 74 75 // Manages a tree of BrowserAccessibility objects. 76 class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate { 77 public: 78 // Creates the platform-specific BrowserAccessibilityManager, but 79 // with no parent window pointer. Only useful for unit tests. 80 static BrowserAccessibilityManager* Create( 81 const ui::AXTreeUpdate& initial_tree, 82 BrowserAccessibilityDelegate* delegate, 83 BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory()); 84 85 virtual ~BrowserAccessibilityManager(); 86 87 void Initialize(const ui::AXTreeUpdate& initial_tree); 88 89 static ui::AXTreeUpdate GetEmptyDocument(); 90 NotifyAccessibilityEvent(ui::AXEvent event_type,BrowserAccessibility * node)91 virtual void NotifyAccessibilityEvent( 92 ui::AXEvent event_type, BrowserAccessibility* node) { } 93 94 // Return a pointer to the root of the tree, does not make a new reference. 95 BrowserAccessibility* GetRoot(); 96 97 // Returns a pointer to the BrowserAccessibility object for a given AXNode. 98 BrowserAccessibility* GetFromAXNode(ui::AXNode* node); 99 100 // Return a pointer to the object corresponding to the given id, 101 // does not make a new reference. 102 BrowserAccessibility* GetFromID(int32 id); 103 104 // Called to notify the accessibility manager that its associated native 105 // view got focused. 106 virtual void OnWindowFocused(); 107 108 // Called to notify the accessibility manager that its associated native 109 // view lost focus. 110 virtual void OnWindowBlurred(); 111 112 // Called to notify the accessibility manager that a mouse down event 113 // occurred in the tab. 114 void GotMouseDown(); 115 116 // Update the focused node to |node|, which may be null. 117 // If |notify| is true, send a message to the renderer to set focus 118 // to this node. 119 void SetFocus(ui::AXNode* node, bool notify); 120 void SetFocus(BrowserAccessibility* node, bool notify); 121 122 // Tell the renderer to do the default action for this node. 123 void DoDefaultAction(const BrowserAccessibility& node); 124 125 // Tell the renderer to scroll to make |node| visible. 126 // In addition, if it's not possible to make the entire object visible, 127 // scroll so that the |subfocus| rect is visible at least. The subfocus 128 // rect is in local coordinates of the object itself. 129 void ScrollToMakeVisible( 130 const BrowserAccessibility& node, gfx::Rect subfocus); 131 132 // Tell the renderer to scroll such that |node| is at |point|, 133 // where |point| is in global coordinates of the WebContents. 134 void ScrollToPoint( 135 const BrowserAccessibility& node, gfx::Point point); 136 137 // Tell the renderer to set the text selection on a node. 138 void SetTextSelection( 139 const BrowserAccessibility& node, int start_offset, int end_offset); 140 141 // Retrieve the bounds of the parent View in screen coordinates. 142 gfx::Rect GetViewBounds(); 143 144 // Called when the renderer process has notified us of about tree changes. 145 void OnAccessibilityEvents( 146 const std::vector<AccessibilityHostMsg_EventParams>& params); 147 148 // Called when the renderer process updates the location of accessibility 149 // objects. 150 void OnLocationChanges( 151 const std::vector<AccessibilityHostMsg_LocationChangeParams>& params); 152 153 #if defined(OS_WIN) 154 BrowserAccessibilityManagerWin* ToBrowserAccessibilityManagerWin(); 155 #endif 156 157 #if defined(OS_ANDROID) 158 BrowserAccessibilityManagerAndroid* ToBrowserAccessibilityManagerAndroid(); 159 #endif 160 161 // Return the object that has focus, if it's a descandant of the 162 // given root (inclusive). Does not make a new reference. 163 virtual BrowserAccessibility* GetFocus(BrowserAccessibility* root); 164 165 // Return the descentant of the given root that has focus, or that object's 166 // active descendant if it has one. 167 BrowserAccessibility* GetActiveDescendantFocus(BrowserAccessibility* root); 168 169 // True by default, but some platforms want to treat the root 170 // scroll offsets separately. 171 virtual bool UseRootScrollOffsetsWhenComputingBounds(); 172 173 // Walk the tree. 174 BrowserAccessibility* NextInTreeOrder(BrowserAccessibility* node); 175 BrowserAccessibility* PreviousInTreeOrder(BrowserAccessibility* node); 176 177 // AXTreeDelegate implementation. 178 virtual void OnNodeWillBeDeleted(ui::AXNode* node) OVERRIDE; 179 virtual void OnNodeCreated(ui::AXNode* node) OVERRIDE; 180 virtual void OnNodeChanged(ui::AXNode* node) OVERRIDE; 181 virtual void OnNodeCreationFinished(ui::AXNode* node) OVERRIDE; 182 virtual void OnNodeChangeFinished(ui::AXNode* node) OVERRIDE; OnRootChanged(ui::AXNode * new_root)183 virtual void OnRootChanged(ui::AXNode* new_root) OVERRIDE {} 184 delegate()185 BrowserAccessibilityDelegate* delegate() const { return delegate_; } 186 187 protected: 188 BrowserAccessibilityManager( 189 BrowserAccessibilityDelegate* delegate, 190 BrowserAccessibilityFactory* factory); 191 192 BrowserAccessibilityManager( 193 const ui::AXTreeUpdate& initial_tree, 194 BrowserAccessibilityDelegate* delegate, 195 BrowserAccessibilityFactory* factory); 196 197 // Called at the end of updating the tree. OnTreeUpdateFinished()198 virtual void OnTreeUpdateFinished() {} 199 200 private: 201 // The following states keep track of whether or not the 202 // on-screen keyboard is allowed to be shown. 203 enum OnScreenKeyboardState { 204 // Never show the on-screen keyboard because this tab is hidden. 205 OSK_DISALLOWED_BECAUSE_TAB_HIDDEN, 206 207 // This tab was just shown, so don't pop-up the on-screen keyboard if a 208 // text field gets focus that wasn't the result of an explicit touch. 209 OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED, 210 211 // A touch event has occurred within the window, but focus has not 212 // explicitly changed. Allow the on-screen keyboard to be shown if the 213 // touch event was within the bounds of the currently focused object. 214 // Otherwise we'll just wait to see if focus changes. 215 OSK_ALLOWED_WITHIN_FOCUSED_OBJECT, 216 217 // Focus has changed within a tab that's already visible. Allow the 218 // on-screen keyboard to show anytime that a touch event leads to an 219 // editable text control getting focus. 220 OSK_ALLOWED 221 }; 222 223 // Update a set of nodes using data received from the renderer 224 // process. 225 bool UpdateNodes(const std::vector<ui::AXNodeData>& nodes); 226 227 // Update one node from the tree using data received from the renderer 228 // process. Returns true on success, false on fatal error. 229 bool UpdateNode(const ui::AXNodeData& src); 230 231 void SetRoot(BrowserAccessibility* root); 232 233 BrowserAccessibility* CreateNode( 234 BrowserAccessibility* parent, 235 int32 id, 236 int32 index_in_parent); 237 238 protected: 239 // The object that can perform actions on our behalf. 240 BrowserAccessibilityDelegate* delegate_; 241 242 // Factory to create BrowserAccessibility objects (for dependency injection). 243 scoped_ptr<BrowserAccessibilityFactory> factory_; 244 245 // The underlying tree of accessibility objects. 246 scoped_ptr<ui::AXTree> tree_; 247 248 // The node that currently has focus. 249 ui::AXNode* focus_; 250 251 // A mapping from a node id to its wrapper of type BrowserAccessibility. 252 base::hash_map<int32, BrowserAccessibility*> id_wrapper_map_; 253 254 // The on-screen keyboard state. 255 OnScreenKeyboardState osk_state_; 256 257 DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManager); 258 }; 259 260 } // namespace content 261 262 #endif // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_H_ 263