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