accessibility_event_router_views.h revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#ifndef CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <string> 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/basictypes.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/gtest_prod_util.h" 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string16.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/accessibility/accessibility_events.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/notification_observer.h" 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/notification_registrar.h" 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/base/accessibility/accessibility_types.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class Profile; 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename T> struct DefaultSingletonTraits; 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace views { 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class View; 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// NOTE: This class is part of the Accessibility Extension API, which lets 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// extensions receive accessibility events. It's distinct from code that 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// implements platform accessibility APIs like MSAA or ATK. 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Singleton class that adds listeners to many views, then sends an 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// accessibility notification whenever a relevant event occurs in an 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// accessible view. 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Views are not accessible by default. When you register a root widget, 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// that widget and all of its descendants will start sending accessibility 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// event notifications. You can then override the default behavior for 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// specific descendants using other methods. 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// You can use Profile::PauseAccessibilityEvents to prevent a flurry 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// of accessibility events when a window is being created or initialized. 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class AccessibilityEventRouterViews : public content::NotificationObserver { 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Get the single instance of this class. 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static AccessibilityEventRouterViews* GetInstance(); 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Handle an accessibility event generated by a view. 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void HandleAccessibilityEvent( 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* view, ui::AccessibilityTypes::Event event_type); 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Handle a menu item being focused (separate because a menu item is 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // not necessarily its own view). 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void HandleMenuItemFocused(const string16& menu_name, 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const string16& menu_item_name, 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int item_index, 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int item_count, 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool has_submenu); 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // NotificationObserver implementation. 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void Observe(int type, 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const content::NotificationSource& source, 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const content::NotificationDetails& details) OVERRIDE; 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) friend struct DefaultSingletonTraits<AccessibilityEventRouterViews>; 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest, 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TestFocusNotification); 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AccessibilityEventRouterViews(); 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~AccessibilityEventRouterViews(); 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Call DispatchAccessibilityNotification using a view storage id. 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static void DispatchNotificationOnViewStorageId( 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int view_storage_id, 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome::NotificationType type); 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Checks the type of the view and calls one of the more specific 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Send*Notification methods, below. 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void DispatchAccessibilityNotification( 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* view, 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome::NotificationType type); 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Each of these methods constructs an AccessibilityControlInfo object 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // and sends a notification of a specific accessibility event. 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static void SendButtonNotification( 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* view, 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int type, 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* profile); 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static void SendLinkNotification( 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* view, 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int type, 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* profile); 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static void SendMenuNotification( 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* view, 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int type, 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* profile); 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static void SendMenuItemNotification( 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* view, 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int type, 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* profile); 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static void SendTextfieldNotification( 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* view, 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int type, 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* profile); 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static void SendComboboxNotification( 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* view, 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int type, 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* profile); 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static void SendCheckboxNotification( 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* view, 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int type, 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* profile); 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static void SendWindowNotification( 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* view, 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int type, 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* profile); 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static void SendSliderNotification( 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* view, 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int type, 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* profile); 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Return the name of a view. 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static std::string GetViewName(views::View* view); 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Get the context of a view - the name of the enclosing group, toolbar, etc. 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static std::string GetViewContext(views::View* view); 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Return a descendant of this view with a given accessible role, if found. 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static views::View* FindDescendantWithAccessibleRole( 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* view, 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::AccessibilityTypes::Role role); 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Return true if it's an event on a menu. 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static bool IsMenuEvent(views::View* view, 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int type); 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Recursively explore all menu items of |menu| and return in |count| 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the total number of items, and in |index| the 0-based index of 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |item|, if found. Initialize |count| to zero before calling this 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // method. |index| will be unchanged if the item is not found, so 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // initialize it to -1 to detect this case. 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static void RecursiveGetMenuItemIndexAndCount(views::View* menu, 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::View* item, 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int* index, 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int* count); 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Recursively explore the subviews and return the text from the first 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // subview with a role of STATIC_TEXT. 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static std::string RecursiveGetStaticText(views::View* view); 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The profile associated with the most recent window event - used to 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // figure out where to route a few events that can't be directly traced 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // to a window with a profile (like menu events). 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* most_recent_profile_; 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Notification registrar so we can clear most_recent_profile_ when a 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // profile is destroyed. 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::NotificationRegistrar registrar_; 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AccessibilityEventRouterViews); 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif // CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)