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