accessibility_event_router_views.h revision 3551c9c881056c480085172ff9840cab31610854
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 CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_
6#define CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/gtest_prod_util.h"
12#include "base/strings/string16.h"
13#include "chrome/browser/accessibility/accessibility_events.h"
14#include "content/public/browser/notification_observer.h"
15#include "content/public/browser/notification_registrar.h"
16#include "ui/base/accessibility/accessibility_types.h"
17
18class Profile;
19
20template <typename T> struct DefaultSingletonTraits;
21
22namespace views {
23class View;
24}
25
26// NOTE: This class is part of the Accessibility Extension API, which lets
27// extensions receive accessibility events. It's distinct from code that
28// implements platform accessibility APIs like MSAA or ATK.
29//
30// Singleton class that adds listeners to many views, then sends an
31// accessibility notification whenever a relevant event occurs in an
32// accessible view.
33//
34// Views are not accessible by default. When you register a root widget,
35// that widget and all of its descendants will start sending accessibility
36// event notifications. You can then override the default behavior for
37// specific descendants using other methods.
38//
39// You can use Profile::PauseAccessibilityEvents to prevent a flurry
40// of accessibility events when a window is being created or initialized.
41class AccessibilityEventRouterViews : public content::NotificationObserver {
42 public:
43  // Get the single instance of this class.
44  static AccessibilityEventRouterViews* GetInstance();
45
46  // Handle an accessibility event generated by a view.
47  void HandleAccessibilityEvent(
48      views::View* view, ui::AccessibilityTypes::Event event_type);
49
50  // Handle a menu item being focused (separate because a menu item is
51  // not necessarily its own view).
52  void HandleMenuItemFocused(const string16& menu_name,
53                             const string16& menu_item_name,
54                             int item_index,
55                             int item_count,
56                             bool has_submenu);
57
58  // NotificationObserver implementation.
59  virtual void Observe(int type,
60                       const content::NotificationSource& source,
61                       const content::NotificationDetails& details) OVERRIDE;
62
63 private:
64  friend struct DefaultSingletonTraits<AccessibilityEventRouterViews>;
65
66  FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest,
67                           TestFocusNotification);
68
69  AccessibilityEventRouterViews();
70  virtual ~AccessibilityEventRouterViews();
71
72  // Call DispatchAccessibilityEvent using a view storage id.
73  static void DispatchEventOnViewStorageId(
74      int view_storage_id,
75      ui::AccessibilityTypes::Event event);
76
77  // Checks the type of the view and calls one of the more specific
78  // Send*Notification methods, below.
79  void DispatchAccessibilityEvent(
80      views::View* view,
81      ui::AccessibilityTypes::Event event);
82
83  // Each of these methods constructs an AccessibilityControlInfo object
84  // and sends a notification of a specific accessibility event.
85  static void SendButtonNotification(
86      views::View* view,
87      ui::AccessibilityTypes::Event event,
88      Profile* profile);
89  static void SendLinkNotification(
90      views::View* view,
91      ui::AccessibilityTypes::Event event,
92      Profile* profile);
93  static void SendMenuNotification(
94      views::View* view,
95      ui::AccessibilityTypes::Event event,
96      Profile* profile);
97  static void SendMenuItemNotification(
98      views::View* view,
99      ui::AccessibilityTypes::Event event,
100      Profile* profile);
101  static void SendTextfieldNotification(
102      views::View* view,
103      ui::AccessibilityTypes::Event event,
104      Profile* profile);
105  static void SendComboboxNotification(
106      views::View* view,
107      ui::AccessibilityTypes::Event event,
108      Profile* profile);
109  static void SendCheckboxNotification(
110      views::View* view,
111      ui::AccessibilityTypes::Event event,
112      Profile* profile);
113  static void SendWindowNotification(
114      views::View* view,
115      ui::AccessibilityTypes::Event event,
116      Profile* profile);
117  static void SendSliderNotification(
118      views::View* view,
119      ui::AccessibilityTypes::Event event,
120      Profile* profile);
121
122  // Return the name of a view.
123  static std::string GetViewName(views::View* view);
124
125  // Get the context of a view - the name of the enclosing group, toolbar, etc.
126  static std::string GetViewContext(views::View* view);
127
128  // Return a descendant of this view with a given accessible role, if found.
129  static views::View* FindDescendantWithAccessibleRole(
130      views::View* view,
131      ui::AccessibilityTypes::Role role);
132
133  // Recursively explore all menu items of |menu| and return in |count|
134  // the total number of items, and in |index| the 0-based index of
135  // |item|, if found. Initialize |count| to zero before calling this
136  // method. |index| will be unchanged if the item is not found, so
137  // initialize it to -1 to detect this case.
138  static void RecursiveGetMenuItemIndexAndCount(views::View* menu,
139                                                views::View* item,
140                                                int* index,
141                                                int* count);
142
143  // Recursively explore the subviews and return the text from the first
144  // subview with a role of STATIC_TEXT.
145  static std::string RecursiveGetStaticText(views::View* view);
146
147  // The profile associated with the most recent window event  - used to
148  // figure out where to route a few events that can't be directly traced
149  // to a window with a profile (like menu events).
150  Profile* most_recent_profile_;
151
152  // Notification registrar so we can clear most_recent_profile_ when a
153  // profile is destroyed.
154  content::NotificationRegistrar registrar_;
155
156  DISALLOW_COPY_AND_ASSIGN(AccessibilityEventRouterViews);
157};
158
159#endif  // CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_
160