1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_H_
#define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_H_
#include <vector>
#include "base/containers/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "third_party/WebKit/public/web/WebAXEnums.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_serializable_tree.h"
#include "ui/accessibility/ax_tree_update.h"
#include "ui/gfx/native_widget_types.h"
struct AccessibilityHostMsg_EventParams;
struct AccessibilityHostMsg_LocationChangeParams;
namespace content {
class BrowserAccessibility;
class BrowserAccessibilityManager;
#if defined(OS_ANDROID)
class BrowserAccessibilityManagerAndroid;
#endif
#if defined(OS_WIN)
class BrowserAccessibilityManagerWin;
#endif
// For testing.
CONTENT_EXPORT ui::AXTreeUpdate MakeAXTreeUpdate(
const ui::AXNodeData& node,
const ui::AXNodeData& node2 = ui::AXNodeData(),
const ui::AXNodeData& node3 = ui::AXNodeData(),
const ui::AXNodeData& node4 = ui::AXNodeData(),
const ui::AXNodeData& node5 = ui::AXNodeData(),
const ui::AXNodeData& node6 = ui::AXNodeData(),
const ui::AXNodeData& node7 = ui::AXNodeData(),
const ui::AXNodeData& node8 = ui::AXNodeData(),
const ui::AXNodeData& node9 = ui::AXNodeData());
// Class that can perform actions on behalf of the BrowserAccessibilityManager.
// Note: BrowserAccessibilityManager should never cache any of the return
// values from any of these interfaces, especially those that return pointers.
// They may only be valid within this call stack. That policy eliminates any
// concerns about ownership and lifecycle issues; none of these interfaces
// transfer ownership and no return values are guaranteed to be valid outside
// of the current call stack.
class CONTENT_EXPORT BrowserAccessibilityDelegate {
public:
virtual ~BrowserAccessibilityDelegate() {}
virtual void AccessibilitySetFocus(int acc_obj_id) = 0;
virtual void AccessibilityDoDefaultAction(int acc_obj_id) = 0;
virtual void AccessibilityShowMenu(const gfx::Point& global_point) = 0;
virtual void AccessibilityScrollToMakeVisible(
int acc_obj_id, const gfx::Rect& subfocus) = 0;
virtual void AccessibilityScrollToPoint(
int acc_obj_id, const gfx::Point& point) = 0;
virtual void AccessibilitySetTextSelection(
int acc_obj_id, int start_offset, int end_offset) = 0;
virtual void AccessibilitySetValue(
int acc_obj_id, const base::string16& value) = 0;
virtual bool AccessibilityViewHasFocus() const = 0;
virtual gfx::Rect AccessibilityGetViewBounds() const = 0;
virtual gfx::Point AccessibilityOriginInScreen(
const gfx::Rect& bounds) const = 0;
virtual void AccessibilityHitTest(
const gfx::Point& point) = 0;
virtual void AccessibilitySetAccessibilityFocus(int acc_obj_id) = 0;
virtual void AccessibilityFatalError() = 0;
virtual gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget() = 0;
virtual gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() = 0;
virtual BrowserAccessibilityManager* AccessibilityGetChildFrame(
int accessibility_node_id) = 0;
virtual void AccessibilityGetAllChildFrames(
std::vector<BrowserAccessibilityManager*>* child_frames) = 0;
virtual BrowserAccessibility* AccessibilityGetParentFrame() = 0;
};
class CONTENT_EXPORT BrowserAccessibilityFactory {
public:
virtual ~BrowserAccessibilityFactory() {}
// Create an instance of BrowserAccessibility and return a new
// reference to it.
virtual BrowserAccessibility* Create();
};
// This is all of the information about the current find in page result,
// so we can activate it if requested.
struct BrowserAccessibilityFindInPageInfo {
BrowserAccessibilityFindInPageInfo();
// This data about find in text results is updated as the user types.
int request_id;
int match_index;
int start_id;
int start_offset;
int end_id;
int end_offset;
// The active request id indicates that the user committed to a find query,
// e.g. by pressing enter or pressing the next or previous buttons. If
// |active_request_id| == |request_id|, we fire an accessibility event
// to move screen reader focus to that event.
int active_request_id;
};
// Manages a tree of BrowserAccessibility objects.
class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
public:
// Creates the platform-specific BrowserAccessibilityManager, but
// with no parent window pointer. Only useful for unit tests.
static BrowserAccessibilityManager* Create(
const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory());
~BrowserAccessibilityManager() override;
void Initialize(const ui::AXTreeUpdate& initial_tree);
static ui::AXTreeUpdate GetEmptyDocument();
virtual void NotifyAccessibilityEvent(
ui::AXEvent event_type, BrowserAccessibility* node) { }
// Return a pointer to the root of the tree, does not make a new reference.
BrowserAccessibility* GetRoot();
// Returns a pointer to the BrowserAccessibility object for a given AXNode.
BrowserAccessibility* GetFromAXNode(ui::AXNode* node);
// Return a pointer to the object corresponding to the given id,
// does not make a new reference.
BrowserAccessibility* GetFromID(int32 id);
// Called to notify the accessibility manager that its associated native
// view got focused.
virtual void OnWindowFocused();
// Called to notify the accessibility manager that its associated native
// view lost focus.
virtual void OnWindowBlurred();
// Called to notify the accessibility manager that a mouse down event
// occurred in the tab.
void GotMouseDown();
// Update the focused node to |node|, which may be null.
// If |notify| is true, send a message to the renderer to set focus
// to this node.
void SetFocus(ui::AXNode* node, bool notify);
void SetFocus(BrowserAccessibility* node, bool notify);
// Tell the renderer to do the default action for this node.
void DoDefaultAction(const BrowserAccessibility& node);
// Tell the renderer to scroll to make |node| visible.
// In addition, if it's not possible to make the entire object visible,
// scroll so that the |subfocus| rect is visible at least. The subfocus
// rect is in local coordinates of the object itself.
void ScrollToMakeVisible(
const BrowserAccessibility& node, gfx::Rect subfocus);
// Tell the renderer to scroll such that |node| is at |point|,
// where |point| is in global coordinates of the WebContents.
void ScrollToPoint(
const BrowserAccessibility& node, gfx::Point point);
// Tell the renderer to set the value of an editable text node.
void SetValue(
const BrowserAccessibility& node, const base::string16& value);
// Tell the renderer to set the text selection on a node.
void SetTextSelection(
const BrowserAccessibility& node, int start_offset, int end_offset);
// Retrieve the bounds of the parent View in screen coordinates.
gfx::Rect GetViewBounds();
// Fire an event telling native assistive technology to move focus to the
// given find in page result.
void ActivateFindInPageResult(int request_id, int match_index);
// Called when the renderer process has notified us of about tree changes.
void OnAccessibilityEvents(
const std::vector<AccessibilityHostMsg_EventParams>& params);
// Called when the renderer process updates the location of accessibility
// objects.
void OnLocationChanges(
const std::vector<AccessibilityHostMsg_LocationChangeParams>& params);
// Called when a new find in page result is received. We hold on to this
// information and don't activate it until the user requests it.
void OnFindInPageResult(
int request_id, int match_index, int start_id, int start_offset,
int end_id, int end_offset);
// This is called when the user has committed to a find in page query,
// e.g. by pressing enter or tapping on the next / previous result buttons.
// If a match has already been received for this request id,
// activate the result now by firing an accessibility event. If a match
// has not been received, we hold onto this request id and update it
// when OnFindInPageResult is called.
void ActivateFindInPageResult(int request_id);
#if defined(OS_WIN)
BrowserAccessibilityManagerWin* ToBrowserAccessibilityManagerWin();
#endif
#if defined(OS_ANDROID)
BrowserAccessibilityManagerAndroid* ToBrowserAccessibilityManagerAndroid();
#endif
// Return the object that has focus, if it's a descandant of the
// given root (inclusive). Does not make a new reference.
virtual BrowserAccessibility* GetFocus(BrowserAccessibility* root);
// Return the descentant of the given root that has focus, or that object's
// active descendant if it has one.
BrowserAccessibility* GetActiveDescendantFocus(BrowserAccessibility* root);
// True by default, but some platforms want to treat the root
// scroll offsets separately.
virtual bool UseRootScrollOffsetsWhenComputingBounds();
// Walk the tree.
BrowserAccessibility* NextInTreeOrder(BrowserAccessibility* node);
BrowserAccessibility* PreviousInTreeOrder(BrowserAccessibility* node);
// AXTreeDelegate implementation.
void OnNodeWillBeDeleted(ui::AXNode* node) override;
void OnNodeCreated(ui::AXNode* node) override;
void OnNodeChanged(ui::AXNode* node) override;
void OnNodeCreationFinished(ui::AXNode* node) override;
void OnNodeChangeFinished(ui::AXNode* node) override;
void OnRootChanged(ui::AXNode* new_root) override {}
BrowserAccessibilityDelegate* delegate() const { return delegate_; }
void set_delegate(BrowserAccessibilityDelegate* delegate) {
delegate_ = delegate;
}
// If this BrowserAccessibilityManager is a child frame or guest frame,
// return the BrowserAccessibilityDelegate from the highest ancestor frame
// in the frame tree.
BrowserAccessibilityDelegate* GetDelegateFromRootManager();
// Get a snapshot of the current tree as an AXTreeUpdate.
ui::AXTreeUpdate SnapshotAXTreeForTesting();
protected:
BrowserAccessibilityManager(
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory);
BrowserAccessibilityManager(
const ui::AXTreeUpdate& initial_tree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory);
// Called at the end of updating the tree.
virtual void OnTreeUpdateFinished() {}
private:
// The following states keep track of whether or not the
// on-screen keyboard is allowed to be shown.
enum OnScreenKeyboardState {
// Never show the on-screen keyboard because this tab is hidden.
OSK_DISALLOWED_BECAUSE_TAB_HIDDEN,
// This tab was just shown, so don't pop-up the on-screen keyboard if a
// text field gets focus that wasn't the result of an explicit touch.
OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED,
// A touch event has occurred within the window, but focus has not
// explicitly changed. Allow the on-screen keyboard to be shown if the
// touch event was within the bounds of the currently focused object.
// Otherwise we'll just wait to see if focus changes.
OSK_ALLOWED_WITHIN_FOCUSED_OBJECT,
// Focus has changed within a tab that's already visible. Allow the
// on-screen keyboard to show anytime that a touch event leads to an
// editable text control getting focus.
OSK_ALLOWED
};
protected:
// The object that can perform actions on our behalf.
BrowserAccessibilityDelegate* delegate_;
// Factory to create BrowserAccessibility objects (for dependency injection).
scoped_ptr<BrowserAccessibilityFactory> factory_;
// The underlying tree of accessibility objects.
scoped_ptr<ui::AXSerializableTree> tree_;
// The node that currently has focus.
ui::AXNode* focus_;
// A mapping from a node id to its wrapper of type BrowserAccessibility.
base::hash_map<int32, BrowserAccessibility*> id_wrapper_map_;
// The on-screen keyboard state.
OnScreenKeyboardState osk_state_;
BrowserAccessibilityFindInPageInfo find_in_page_info_;
DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManager);
};
} // namespace content
#endif // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_H_
|