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.
5 #ifndef CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_
6 #define CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_
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/accessibility/ax_enums.h"
20 template <typename T> struct DefaultSingletonTraits;
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.
30 // Singleton class that adds listeners to many views, then sends an
31 // accessibility notification whenever a relevant event occurs in an
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.
39 // You can use Profile::PauseAccessibilityEvents to prevent a flurry
40 // of accessibility events when a window is being created or initialized.
41 class AccessibilityEventRouterViews : public content::NotificationObserver {
43 // Get the single instance of this class.
44 static AccessibilityEventRouterViews* GetInstance();
46 // Handle an accessibility event generated by a view.
47 void HandleAccessibilityEvent(
48 views::View* view, ui::AXEvent event_type);
50 // Handle a menu item being focused (separate because a menu item is
51 // not necessarily its own view).
52 void HandleMenuItemFocused(const base::string16& menu_name,
53 const base::string16& menu_item_name,
58 // NotificationObserver implementation.
59 void Observe(int type,
60 const content::NotificationSource& source,
61 const content::NotificationDetails& details) override;
64 friend struct DefaultSingletonTraits<AccessibilityEventRouterViews>;
66 FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest,
67 TestFocusNotification);
68 FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest,
69 MenuIndexAndCountForInvisibleMenu);
70 FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest,
71 AccessibilityFocusableView);
73 AccessibilityEventRouterViews();
74 ~AccessibilityEventRouterViews() override;
76 // Call DispatchAccessibilityEvent using a view storage id.
77 static void DispatchEventOnViewStorageId(
81 // Checks the type of the view and calls one of the more specific
82 // Send*Notification methods, below.
83 void DispatchAccessibilityEvent(
87 // Each of these methods constructs an AccessibilityControlInfo object
88 // and sends a notification of a specific accessibility event.
89 static void SendButtonNotification(
93 static void SendStaticTextNotification(
97 static void SendLinkNotification(
101 static void SendMenuNotification(
105 static void SendTabNotification(
109 static void SendMenuItemNotification(
113 static void SendTreeNotification(
117 static void SendTreeItemNotification(
121 static void SendTextfieldNotification(
125 static void SendComboboxNotification(
129 static void SendCheckboxNotification(
133 static void SendWindowNotification(
137 static void SendSliderNotification(
141 static void SendAlertControlNotification(
146 // Return the name of a view.
147 static std::string GetViewName(views::View* view);
149 // Get the context of a view - the name of the enclosing group, toolbar, etc.
150 static std::string GetViewContext(views::View* view);
152 // Return a descendant of this view with a given accessible role, if found.
153 static views::View* FindDescendantWithAccessibleRole(
157 // Recursively explore all menu items of |menu| and return in |count|
158 // the total number of items, and in |index| the 0-based index of
159 // |item|, if found. Initialize |count| to zero before calling this
160 // method. |index| will be unchanged if the item is not found, so
161 // initialize it to -1 to detect this case.
162 static void RecursiveGetMenuItemIndexAndCount(views::View* menu,
167 // Recursively explore the subviews and return the text from the first
168 // subview with a role of STATIC_TEXT.
169 static std::string RecursiveGetStaticText(views::View* view);
171 // Returns the first ancestor of |view| (including |view|) that is
173 static views::View* FindFirstAccessibleAncestor(views::View* view);
175 // The profile associated with the most recent window event - used to
176 // figure out where to route a few events that can't be directly traced
177 // to a window with a profile (like menu events).
178 Profile* most_recent_profile_;
180 // The most recent accessibility focusable view is stored in view storage
181 // and is used to prevent multiple events from being dispatched on a
182 // hoverable view from its multiple children. This is the id for the most
183 // recent view we put in view storage.
184 const int most_recent_view_id_;
186 // Notification registrar so we can clear most_recent_profile_ when a
187 // profile is destroyed.
188 content::NotificationRegistrar registrar_;
190 DISALLOW_COPY_AND_ASSIGN(AccessibilityEventRouterViews);
193 #endif // CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_