1 // Copyright (c) 2011 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_EVENT_ROUTER_VIEWS_H_ 6 #define CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ 7 #pragma once 8 9 #include <string> 10 11 #include "base/basictypes.h" 12 #include "base/gtest_prod_util.h" 13 #include "base/memory/singleton.h" 14 #include "base/task.h" 15 #include "chrome/browser/accessibility_events.h" 16 #include "ui/base/accessibility/accessibility_types.h" 17 18 class Profile; 19 namespace views { 20 class View; 21 } 22 23 // NOTE: This class is part of the Accessibility Extension API, which lets 24 // extensions receive accessibility events. It's distinct from code that 25 // implements platform accessibility APIs like MSAA or ATK. 26 // 27 // Singleton class that adds listeners to many views, then sends an 28 // accessibility notification whenever a relevant event occurs in an 29 // accessible view. 30 // 31 // Views are not accessible by default. When you register a root widget, 32 // that widget and all of its descendants will start sending accessibility 33 // event notifications. You can then override the default behavior for 34 // specific descendants using other methods. 35 // 36 // You can use Profile::PauseAccessibilityEvents to prevent a flurry 37 // of accessibility events when a window is being created or initialized. 38 class AccessibilityEventRouterViews { 39 public: 40 // Internal information about a particular view to override the 41 // information we get directly from the view. 42 struct ViewInfo { ViewInfoViewInfo43 ViewInfo() : ignore(false) {} 44 45 // If nonempty, will use this name instead of the view's label. 46 std::string name; 47 48 // If true, will ignore this widget and not send accessibility events. 49 bool ignore; 50 }; 51 52 // Get the single instance of this class. 53 static AccessibilityEventRouterViews* GetInstance(); 54 55 // Handle an accessibility event generated by a view. 56 void HandleAccessibilityEvent( 57 views::View* view, ui::AccessibilityTypes::Event event_type); 58 59 // Handle a menu item being focused (separate because a menu item is 60 // not necessarily its own view). 61 void HandleMenuItemFocused( 62 const std::wstring& menu_name, 63 const std::wstring& menu_item_name, 64 int item_index, 65 int item_count, 66 bool has_submenu); 67 68 private: 69 AccessibilityEventRouterViews(); 70 virtual ~AccessibilityEventRouterViews(); 71 72 friend struct DefaultSingletonTraits<AccessibilityEventRouterViews>; 73 FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest, 74 TestFocusNotification); 75 76 // Checks the type of the view and calls one of the more specific 77 // Send*Notification methods, below. 78 void DispatchAccessibilityNotification( 79 views::View* view, NotificationType type); 80 81 // Return the name of a view. 82 std::string GetViewName(views::View* view); 83 84 // Each of these methods constructs an AccessibilityControlInfo object 85 // and sends a notification of a specific accessibility event. 86 void SendButtonNotification( 87 views::View* view, NotificationType type, Profile* profile); 88 void SendLinkNotification( 89 views::View* view, NotificationType type, Profile* profile); 90 void SendMenuNotification( 91 views::View* view, NotificationType type, Profile* profile); 92 void SendMenuItemNotification( 93 views::View* view, NotificationType type, Profile* profile); 94 void SendLocationBarNotification( 95 views::View* view, NotificationType type, Profile* profile); 96 void SendTextfieldNotification( 97 views::View* view, NotificationType type, Profile* profile); 98 void SendComboboxNotification( 99 views::View* view, NotificationType type, Profile* profile); 100 void SendCheckboxNotification( 101 views::View* view, NotificationType type, Profile* profile); 102 103 // Return true if it's an event on a menu. 104 bool IsMenuEvent(views::View* view, NotificationType type); 105 106 // Recursively explore all menu items of |menu| and return in |count| 107 // the total number of items, and in |index| the 0-based index of 108 // |item|, if found. Initialize |count| to zero before calling this 109 // method. |index| will be unchanged if the item is not found, so 110 // initialize it to -1 to detect this case. 111 void RecursiveGetMenuItemIndexAndCount( 112 views::View* menu, views::View* item, int* index, int* count); 113 114 // The profile associated with the most recent window event - used to 115 // figure out where to route a few events that can't be directly traced 116 // to a window with a profile (like menu events). 117 Profile* most_recent_profile_; 118 119 // Used to defer handling of some events until the next time 120 // through the event loop. 121 ScopedRunnableMethodFactory<AccessibilityEventRouterViews> method_factory_; 122 }; 123 124 #endif // CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ 125