• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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