// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ #define CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ #pragma once #include <string> #include "base/basictypes.h" #include "base/gtest_prod_util.h" #include "base/memory/singleton.h" #include "base/task.h" #include "chrome/browser/accessibility_events.h" #include "ui/base/accessibility/accessibility_types.h" class Profile; namespace views { class View; } // NOTE: This class is part of the Accessibility Extension API, which lets // extensions receive accessibility events. It's distinct from code that // implements platform accessibility APIs like MSAA or ATK. // // Singleton class that adds listeners to many views, then sends an // accessibility notification whenever a relevant event occurs in an // accessible view. // // Views are not accessible by default. When you register a root widget, // that widget and all of its descendants will start sending accessibility // event notifications. You can then override the default behavior for // specific descendants using other methods. // // You can use Profile::PauseAccessibilityEvents to prevent a flurry // of accessibility events when a window is being created or initialized. class AccessibilityEventRouterViews { public: // Internal information about a particular view to override the // information we get directly from the view. struct ViewInfo { ViewInfo() : ignore(false) {} // If nonempty, will use this name instead of the view's label. std::string name; // If true, will ignore this widget and not send accessibility events. bool ignore; }; // Get the single instance of this class. static AccessibilityEventRouterViews* GetInstance(); // Handle an accessibility event generated by a view. void HandleAccessibilityEvent( views::View* view, ui::AccessibilityTypes::Event event_type); // Handle a menu item being focused (separate because a menu item is // not necessarily its own view). void HandleMenuItemFocused( const std::wstring& menu_name, const std::wstring& menu_item_name, int item_index, int item_count, bool has_submenu); private: AccessibilityEventRouterViews(); virtual ~AccessibilityEventRouterViews(); friend struct DefaultSingletonTraits<AccessibilityEventRouterViews>; FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest, TestFocusNotification); // Checks the type of the view and calls one of the more specific // Send*Notification methods, below. void DispatchAccessibilityNotification( views::View* view, NotificationType type); // Return the name of a view. std::string GetViewName(views::View* view); // Each of these methods constructs an AccessibilityControlInfo object // and sends a notification of a specific accessibility event. void SendButtonNotification( views::View* view, NotificationType type, Profile* profile); void SendLinkNotification( views::View* view, NotificationType type, Profile* profile); void SendMenuNotification( views::View* view, NotificationType type, Profile* profile); void SendMenuItemNotification( views::View* view, NotificationType type, Profile* profile); void SendLocationBarNotification( views::View* view, NotificationType type, Profile* profile); void SendTextfieldNotification( views::View* view, NotificationType type, Profile* profile); void SendComboboxNotification( views::View* view, NotificationType type, Profile* profile); void SendCheckboxNotification( views::View* view, NotificationType type, Profile* profile); // Return true if it's an event on a menu. bool IsMenuEvent(views::View* view, NotificationType type); // Recursively explore all menu items of |menu| and return in |count| // the total number of items, and in |index| the 0-based index of // |item|, if found. Initialize |count| to zero before calling this // method. |index| will be unchanged if the item is not found, so // initialize it to -1 to detect this case. void RecursiveGetMenuItemIndexAndCount( views::View* menu, views::View* item, int* index, int* count); // The profile associated with the most recent window event - used to // figure out where to route a few events that can't be directly traced // to a window with a profile (like menu events). Profile* most_recent_profile_; // Used to defer handling of some events until the next time // through the event loop. ScopedRunnableMethodFactory<AccessibilityEventRouterViews> method_factory_; }; #endif // CHROME_BROWSER_UI_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_