accessibility_event_router_views.h revision f2477e01787aa58f445919b809d89e252beef54f
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  FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest,
69                           MenuIndexAndCountForInvisibleMenu);
70
71  AccessibilityEventRouterViews();
72  virtual ~AccessibilityEventRouterViews();
73
74  // Call DispatchAccessibilityEvent using a view storage id.
75  static void DispatchEventOnViewStorageId(
76      int view_storage_id,
77      ui::AccessibilityTypes::Event event);
78
79  // Checks the type of the view and calls one of the more specific
80  // Send*Notification methods, below.
81  void DispatchAccessibilityEvent(
82      views::View* view,
83      ui::AccessibilityTypes::Event event);
84
85  // Each of these methods constructs an AccessibilityControlInfo object
86  // and sends a notification of a specific accessibility event.
87  static void SendButtonNotification(
88      views::View* view,
89      ui::AccessibilityTypes::Event event,
90      Profile* profile);
91  static void SendLinkNotification(
92      views::View* view,
93      ui::AccessibilityTypes::Event event,
94      Profile* profile);
95  static void SendMenuNotification(
96      views::View* view,
97      ui::AccessibilityTypes::Event event,
98      Profile* profile);
99  static void SendMenuItemNotification(
100      views::View* view,
101      ui::AccessibilityTypes::Event event,
102      Profile* profile);
103  static void SendTextfieldNotification(
104      views::View* view,
105      ui::AccessibilityTypes::Event event,
106      Profile* profile);
107  static void SendComboboxNotification(
108      views::View* view,
109      ui::AccessibilityTypes::Event event,
110      Profile* profile);
111  static void SendCheckboxNotification(
112      views::View* view,
113      ui::AccessibilityTypes::Event event,
114      Profile* profile);
115  static void SendWindowNotification(
116      views::View* view,
117      ui::AccessibilityTypes::Event event,
118      Profile* profile);
119  static void SendSliderNotification(
120      views::View* view,
121      ui::AccessibilityTypes::Event event,
122      Profile* profile);
123  static void SendAlertControlNotification(
124      views::View* view,
125      ui::AccessibilityTypes::Event event,
126      Profile* profile);
127
128  // Return the name of a view.
129  static std::string GetViewName(views::View* view);
130
131  // Get the context of a view - the name of the enclosing group, toolbar, etc.
132  static std::string GetViewContext(views::View* view);
133
134  // Return a descendant of this view with a given accessible role, if found.
135  static views::View* FindDescendantWithAccessibleRole(
136      views::View* view,
137      ui::AccessibilityTypes::Role role);
138
139  // Recursively explore all menu items of |menu| and return in |count|
140  // the total number of items, and in |index| the 0-based index of
141  // |item|, if found. Initialize |count| to zero before calling this
142  // method. |index| will be unchanged if the item is not found, so
143  // initialize it to -1 to detect this case.
144  static void RecursiveGetMenuItemIndexAndCount(views::View* menu,
145                                                views::View* item,
146                                                int* index,
147                                                int* count);
148
149  // Recursively explore the subviews and return the text from the first
150  // subview with a role of STATIC_TEXT.
151  static std::string RecursiveGetStaticText(views::View* view);
152
153  // The profile associated with the most recent window event  - used to
154  // figure out where to route a few events that can't be directly traced
155  // to a window with a profile (like menu events).
156  Profile* most_recent_profile_;
157
158  // Notification registrar so we can clear most_recent_profile_ when a
159  // profile is destroyed.
160  content::NotificationRegistrar registrar_;
161
162  DISALLOW_COPY_AND_ASSIGN(AccessibilityEventRouterViews);
163};
164
165#endif  // CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_
166