Home | History | Annotate | Download | only in accessibility
      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:
     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:
     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 
     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 
    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