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 UI_VIEWS_ACCESSIBILITY_NATIVE_VIEW_ACCESSIBILITY_WIN_H_
      6 #define UI_VIEWS_ACCESSIBILITY_NATIVE_VIEW_ACCESSIBILITY_WIN_H_
      7 
      8 #include <atlbase.h>
      9 #include <atlcom.h>
     10 #include <oleacc.h>
     11 
     12 #include <UIAutomationCore.h>
     13 
     14 #include <set>
     15 
     16 #include "third_party/iaccessible2/ia2_api_all.h"
     17 #include "ui/base/accessibility/accessible_view_state.h"
     18 #include "ui/views/accessibility/native_view_accessibility.h"
     19 #include "ui/views/controls/native/native_view_host.h"
     20 #include "ui/views/view.h"
     21 
     22 namespace ui {
     23 enum TextBoundaryDirection;
     24 enum TextBoundaryType;
     25 }
     26 
     27 namespace views {
     28 
     29 ////////////////////////////////////////////////////////////////////////////////
     30 //
     31 // NativeViewAccessibilityWin
     32 //
     33 // Class implementing the MSAA IAccessible COM interface for a generic View,
     34 // providing accessibility to be used by screen readers and other assistive
     35 // technology (AT).
     36 //
     37 ////////////////////////////////////////////////////////////////////////////////
     38 class __declspec(uuid("26f5641a-246d-457b-a96d-07f3fae6acf2"))
     39 NativeViewAccessibilityWin
     40   : public CComObjectRootEx<CComMultiThreadModel>,
     41     public IDispatchImpl<IAccessible2, &IID_IAccessible2,
     42                            &LIBID_IAccessible2Lib>,
     43     public IAccessibleText,
     44     public IServiceProvider,
     45     public IAccessibleEx,
     46     public IRawElementProviderSimple,
     47     public NativeViewAccessibility {
     48  public:
     49   BEGIN_COM_MAP(NativeViewAccessibilityWin)
     50     COM_INTERFACE_ENTRY2(IDispatch, IAccessible2)
     51     COM_INTERFACE_ENTRY2(IAccessible, IAccessible2)
     52     COM_INTERFACE_ENTRY(IAccessible2)
     53     COM_INTERFACE_ENTRY(IAccessibleText)
     54     COM_INTERFACE_ENTRY(IServiceProvider)
     55     COM_INTERFACE_ENTRY(IAccessibleEx)
     56     COM_INTERFACE_ENTRY(IRawElementProviderSimple)
     57   END_COM_MAP()
     58 
     59   virtual ~NativeViewAccessibilityWin();
     60 
     61   // NativeViewAccessibility.
     62   virtual void NotifyAccessibilityEvent(
     63       ui::AccessibilityTypes::Event event_type) OVERRIDE;
     64   virtual gfx::NativeViewAccessible GetNativeObject() OVERRIDE;
     65   virtual void Destroy() OVERRIDE;
     66 
     67   void set_view(views::View* view) { view_ = view; }
     68 
     69   // Supported IAccessible methods.
     70 
     71   // Retrieves the child element or child object at a given point on the screen.
     72   virtual STDMETHODIMP accHitTest(LONG x_left, LONG y_top, VARIANT* child);
     73 
     74   // Performs the object's default action.
     75   STDMETHODIMP accDoDefaultAction(VARIANT var_id);
     76 
     77   // Retrieves the specified object's current screen location.
     78   STDMETHODIMP accLocation(LONG* x_left,
     79                            LONG* y_top,
     80                            LONG* width,
     81                            LONG* height,
     82                            VARIANT var_id);
     83 
     84   // Traverses to another UI element and retrieves the object.
     85   STDMETHODIMP accNavigate(LONG nav_dir, VARIANT start, VARIANT* end);
     86 
     87   // Retrieves an IDispatch interface pointer for the specified child.
     88   virtual STDMETHODIMP get_accChild(VARIANT var_child, IDispatch** disp_child);
     89 
     90   // Retrieves the number of accessible children.
     91   virtual STDMETHODIMP get_accChildCount(LONG* child_count);
     92 
     93   // Retrieves a string that describes the object's default action.
     94   STDMETHODIMP get_accDefaultAction(VARIANT var_id, BSTR* default_action);
     95 
     96   // Retrieves the tooltip description.
     97   STDMETHODIMP get_accDescription(VARIANT var_id, BSTR* desc);
     98 
     99   // Retrieves the object that has the keyboard focus.
    100   STDMETHODIMP get_accFocus(VARIANT* focus_child);
    101 
    102   // Retrieves the specified object's shortcut.
    103   STDMETHODIMP get_accKeyboardShortcut(VARIANT var_id, BSTR* access_key);
    104 
    105   // Retrieves the name of the specified object.
    106   STDMETHODIMP get_accName(VARIANT var_id, BSTR* name);
    107 
    108   // Retrieves the IDispatch interface of the object's parent.
    109   STDMETHODIMP get_accParent(IDispatch** disp_parent);
    110 
    111   // Retrieves information describing the role of the specified object.
    112   STDMETHODIMP get_accRole(VARIANT var_id, VARIANT* role);
    113 
    114   // Retrieves the current state of the specified object.
    115   STDMETHODIMP get_accState(VARIANT var_id, VARIANT* state);
    116 
    117   // Retrieve or set the string value associated with the specified object.
    118   // Setting the value is not typically used by screen readers, but it's
    119   // used frequently by automation software.
    120   STDMETHODIMP get_accValue(VARIANT var_id, BSTR* value);
    121   STDMETHODIMP put_accValue(VARIANT var_id, BSTR new_value);
    122 
    123   // Selections not applicable to views.
    124   STDMETHODIMP get_accSelection(VARIANT* selected);
    125   STDMETHODIMP accSelect(LONG flags_sel, VARIANT var_id);
    126 
    127   // Help functions not supported.
    128   STDMETHODIMP get_accHelp(VARIANT var_id, BSTR* help);
    129   STDMETHODIMP get_accHelpTopic(BSTR* help_file,
    130                                 VARIANT var_id,
    131                                 LONG* topic_id);
    132 
    133   // Deprecated functions, not implemented here.
    134   STDMETHODIMP put_accName(VARIANT var_id, BSTR put_name);
    135 
    136   //
    137   // IAccessible2
    138   //
    139 
    140   STDMETHODIMP role(LONG* role);
    141 
    142   STDMETHODIMP get_states(AccessibleStates* states);
    143 
    144   STDMETHODIMP get_uniqueID(LONG* unique_id);
    145 
    146   STDMETHODIMP get_windowHandle(HWND* window_handle);
    147 
    148   //
    149   // IAccessible2 methods not implemented.
    150   //
    151 
    152   STDMETHODIMP get_attributes(BSTR* attributes) {
    153     return E_NOTIMPL;
    154   }
    155   STDMETHODIMP get_indexInParent(LONG* index_in_parent) {
    156     return E_NOTIMPL;
    157   }
    158   STDMETHODIMP get_extendedRole(BSTR* extended_role) {
    159     return E_NOTIMPL;
    160   }
    161   STDMETHODIMP get_nRelations(LONG* n_relations) {
    162     return E_NOTIMPL;
    163   }
    164   STDMETHODIMP get_relation(LONG relation_index,
    165                             IAccessibleRelation** relation) {
    166     return E_NOTIMPL;
    167   }
    168   STDMETHODIMP get_relations(LONG max_relations,
    169       IAccessibleRelation** relations,
    170       LONG* n_relations) {
    171     return E_NOTIMPL;
    172   }
    173   STDMETHODIMP scrollTo(enum IA2ScrollType scroll_type) {
    174     return E_NOTIMPL;
    175   }
    176   STDMETHODIMP scrollToPoint(
    177       enum IA2CoordinateType coordinate_type,
    178       LONG x,
    179       LONG y) {
    180     return E_NOTIMPL;
    181   }
    182   STDMETHODIMP get_groupPosition(LONG* group_level,
    183                                  LONG* similar_items_in_group,
    184                                  LONG* position_in_group) {
    185     return E_NOTIMPL;
    186   }
    187   STDMETHODIMP get_localizedExtendedRole(
    188       BSTR* localized_extended_role) {
    189     return E_NOTIMPL;
    190   }
    191   STDMETHODIMP get_nExtendedStates(LONG* n_extended_states) {
    192     return E_NOTIMPL;
    193   }
    194   STDMETHODIMP get_extendedStates(LONG max_extended_states,
    195                                   BSTR** extended_states,
    196                                   LONG* n_extended_states) {
    197     return E_NOTIMPL;
    198   }
    199   STDMETHODIMP get_localizedExtendedStates(
    200       LONG max_localized_extended_states,
    201       BSTR** localized_extended_states,
    202       LONG* n_localized_extended_states) {
    203     return E_NOTIMPL;
    204   }
    205   STDMETHODIMP get_locale(IA2Locale* locale) {
    206     return E_NOTIMPL;
    207   }
    208 
    209   //
    210   // IAccessibleText methods.
    211   //
    212 
    213   STDMETHODIMP get_nCharacters(LONG* n_characters);
    214 
    215   STDMETHODIMP get_caretOffset(LONG* offset);
    216 
    217   STDMETHODIMP get_nSelections(LONG* n_selections);
    218 
    219   STDMETHODIMP get_selection(LONG selection_index,
    220                              LONG* start_offset,
    221                              LONG* end_offset);
    222 
    223   STDMETHODIMP get_text(LONG start_offset, LONG end_offset, BSTR* text);
    224 
    225   STDMETHODIMP get_textAtOffset(LONG offset,
    226                                 enum IA2TextBoundaryType boundary_type,
    227                                 LONG* start_offset, LONG* end_offset,
    228                                 BSTR* text);
    229 
    230   STDMETHODIMP get_textBeforeOffset(LONG offset,
    231                                     enum IA2TextBoundaryType boundary_type,
    232                                     LONG* start_offset, LONG* end_offset,
    233                                     BSTR* text);
    234 
    235   STDMETHODIMP get_textAfterOffset(LONG offset,
    236                                    enum IA2TextBoundaryType boundary_type,
    237                                    LONG* start_offset, LONG* end_offset,
    238                                    BSTR* text);
    239 
    240   STDMETHODIMP get_offsetAtPoint(LONG x, LONG y,
    241       enum IA2CoordinateType coord_type,
    242       LONG* offset);
    243 
    244   //
    245   // IAccessibleText methods not implemented.
    246   //
    247 
    248   STDMETHODIMP get_newText(IA2TextSegment* new_text) {
    249     return E_NOTIMPL;
    250   }
    251   STDMETHODIMP get_oldText(IA2TextSegment* old_text) {
    252     return E_NOTIMPL;
    253   }
    254   STDMETHODIMP addSelection(LONG start_offset, LONG end_offset) {
    255     return E_NOTIMPL;
    256   }
    257   STDMETHODIMP get_attributes(LONG offset,
    258                               LONG* start_offset,
    259                               LONG* end_offset,
    260                               BSTR* text_attributes) {
    261     return E_NOTIMPL;
    262   }
    263   STDMETHODIMP get_characterExtents(LONG offset,
    264       enum IA2CoordinateType coord_type,
    265       LONG* x, LONG* y,
    266       LONG* width, LONG* height) {
    267     return E_NOTIMPL;
    268   }
    269   STDMETHODIMP removeSelection(LONG selection_index) {
    270     return E_NOTIMPL;
    271   }
    272   STDMETHODIMP setCaretOffset(LONG offset) {
    273     return E_NOTIMPL;
    274   }
    275   STDMETHODIMP setSelection(LONG selection_index,
    276                             LONG start_offset,
    277                             LONG end_offset) {
    278     return E_NOTIMPL;
    279   }
    280   STDMETHODIMP scrollSubstringTo(LONG start_index,
    281                                  LONG end_index,
    282                                  enum IA2ScrollType scroll_type) {
    283     return E_NOTIMPL;
    284   }
    285   STDMETHODIMP scrollSubstringToPoint(LONG start_index,
    286       LONG end_index,
    287       enum IA2CoordinateType coordinate_type,
    288       LONG x, LONG y) {
    289     return E_NOTIMPL;
    290   }
    291 
    292   //
    293   // IServiceProvider methods.
    294   //
    295 
    296   STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void** object);
    297 
    298   //
    299   // IAccessibleEx methods not implemented.
    300   //
    301   STDMETHODIMP GetObjectForChild(long child_id, IAccessibleEx** ret) {
    302     return E_NOTIMPL;
    303   }
    304 
    305   STDMETHODIMP GetIAccessiblePair(IAccessible** acc, long* child_id) {
    306     return E_NOTIMPL;
    307   }
    308 
    309   STDMETHODIMP GetRuntimeId(SAFEARRAY** runtime_id) {
    310     return E_NOTIMPL;
    311   }
    312 
    313   STDMETHODIMP ConvertReturnedElement(IRawElementProviderSimple* element,
    314                                       IAccessibleEx** acc) {
    315     return E_NOTIMPL;
    316   }
    317 
    318   //
    319   // IRawElementProviderSimple methods.
    320   //
    321   // The GetPatternProvider/GetPropertyValue methods need to be implemented for
    322   // the on-screen keyboard to show up in Windows 8 metro.
    323   STDMETHODIMP GetPatternProvider(PATTERNID id, IUnknown** provider);
    324   STDMETHODIMP GetPropertyValue(PROPERTYID id, VARIANT* ret);
    325 
    326   //
    327   // IRawElementProviderSimple methods not implemented.
    328   //
    329   STDMETHODIMP get_ProviderOptions(enum ProviderOptions* ret) {
    330     return E_NOTIMPL;
    331   }
    332 
    333   STDMETHODIMP get_HostRawElementProvider(
    334       IRawElementProviderSimple** provider) {
    335     return E_NOTIMPL;
    336   }
    337 
    338   // Static methods
    339 
    340   // Returns a conversion from the event (as defined in accessibility_types.h)
    341   // to an MSAA event.
    342   static int32 MSAAEvent(ui::AccessibilityTypes::Event event);
    343 
    344   // Returns a conversion from the Role (as defined in accessibility_types.h)
    345   // to an MSAA role.
    346   static int32 MSAARole(ui::AccessibilityTypes::Role role);
    347 
    348   // Returns a conversion from the State (as defined in accessibility_types.h)
    349   // to MSAA states set.
    350   static int32 MSAAState(ui::AccessibilityTypes::State state);
    351 
    352  protected:
    353   NativeViewAccessibilityWin();
    354 
    355   const View* view() const { return view_; }
    356 
    357  private:
    358   // Determines navigation direction for accNavigate, based on left, up and
    359   // previous being mapped all to previous and right, down, next being mapped
    360   // to next. Returns true if navigation direction is next, false otherwise.
    361   bool IsNavDirNext(int nav_dir) const;
    362 
    363   // Determines if the navigation target is within the allowed bounds. Returns
    364   // true if it is, false otherwise.
    365   bool IsValidNav(int nav_dir,
    366                   int start_id,
    367                   int lower_bound,
    368                   int upper_bound) const;
    369 
    370   // Determines if the child id variant is valid.
    371   bool IsValidId(const VARIANT& child) const;
    372 
    373   // Helper function which sets applicable states of view.
    374   void SetState(VARIANT* msaa_state, View* view);
    375 
    376   // Return the text to use for IAccessibleText.
    377   string16 TextForIAccessibleText();
    378 
    379   // If offset is a member of IA2TextSpecialOffsets this function updates the
    380   // value of offset and returns, otherwise offset remains unchanged.
    381   void HandleSpecialTextOffset(const string16& text, LONG* offset);
    382 
    383   // Convert from a IA2TextBoundaryType to a ui::TextBoundaryType.
    384   ui::TextBoundaryType IA2TextBoundaryToTextBoundary(IA2TextBoundaryType type);
    385 
    386   // Search forwards (direction == 1) or backwards (direction == -1)
    387   // from the given offset until the given boundary is found, and
    388   // return the offset of that boundary.
    389   LONG FindBoundary(const string16& text,
    390                     IA2TextBoundaryType ia2_boundary,
    391                     LONG start_offset,
    392                     ui::TextBoundaryDirection direction);
    393 
    394   // Populates the given vector with all widgets that are either a child
    395   // or are owned by this view's widget, and who are not contained in a
    396   // NativeViewHost.
    397   void PopulateChildWidgetVector(std::vector<Widget*>* child_widgets);
    398 
    399   // Give CComObject access to the class constructor.
    400   template <class Base> friend class CComObject;
    401 
    402   // Member View needed for view-specific calls.
    403   View* view_;
    404 
    405   // A unique id for each object, needed for IAccessible2.
    406   long unique_id_;
    407 
    408   // Next unique id to assign.
    409   static long next_unique_id_;
    410 
    411   // Circular queue size.
    412   static const int kMaxViewStorageIds = 20;
    413 
    414   // Circular queue of view storage ids corresponding to child ids
    415   // used to post notifications using NotifyWinEvent.
    416   static int view_storage_ids_[kMaxViewStorageIds];
    417 
    418   // Next index into |view_storage_ids_| to use.
    419   static int next_view_storage_id_index_;
    420 
    421   DISALLOW_COPY_AND_ASSIGN(NativeViewAccessibilityWin);
    422 };
    423 
    424 }  // namespace views
    425 
    426 #endif  // UI_VIEWS_ACCESSIBILITY_NATIVE_VIEW_ACCESSIBILITY_WIN_H_
    427