OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ | 5 #ifndef CHROME_BROWSER_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ |
6 #define CHROME_BROWSER_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ | 6 #define CHROME_BROWSER_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 12 #include "base/gtest_prod_util.h" |
12 #include "base/hash_tables.h" | 13 #include "base/hash_tables.h" |
13 #include "base/singleton.h" | 14 #include "base/singleton.h" |
14 #include "base/task.h" | 15 #include "base/task.h" |
15 #include "chrome/browser/accessibility_events.h" | 16 #include "chrome/browser/accessibility_events.h" |
16 #include "views/view.h" | 17 #include "views/view.h" |
17 #include "views/widget/root_view.h" | 18 #include "views/widget/root_view.h" |
18 | 19 |
19 class Profile; | 20 class Profile; |
20 | 21 |
21 // Allows us to use (View*) and (FocusManager*) in a hash_map with gcc. | 22 // Allows us to use (View*) in a hash_map with gcc. |
22 #if defined(COMPILER_GCC) | 23 #if defined(COMPILER_GCC) |
23 namespace __gnu_cxx { | 24 namespace __gnu_cxx { |
24 template<> | 25 template<> |
25 struct hash<views::FocusManager*> { | |
26 size_t operator()(views::FocusManager* focus_manager) const { | |
27 return reinterpret_cast<size_t>(focus_manager); | |
28 } | |
29 }; | |
30 template<> | |
31 struct hash<views::View*> { | 26 struct hash<views::View*> { |
32 size_t operator()(views::View* view) const { | 27 size_t operator()(views::View* view) const { |
33 return reinterpret_cast<size_t>(view); | 28 return reinterpret_cast<size_t>(view); |
34 } | 29 } |
35 }; | 30 }; |
36 } // namespace __gnu_cxx | 31 } // namespace __gnu_cxx |
37 #endif // defined(COMPILER_GCC) | 32 #endif // defined(COMPILER_GCC) |
38 | 33 |
39 // NOTE: This class is part of the Accessibility Extension API, which lets | 34 // NOTE: This class is part of the Accessibility Extension API, which lets |
40 // extensions receive accessibility events. It's distinct from code that | 35 // extensions receive accessibility events. It's distinct from code that |
41 // implements platform accessibility APIs like MSAA or ATK. | 36 // implements platform accessibility APIs like MSAA or ATK. |
42 // | 37 // |
43 // Singleton class that adds listeners to many views, then sends an | 38 // Singleton class that adds listeners to many views, then sends an |
44 // accessibility notification whenever a relevant event occurs in an | 39 // accessibility notification whenever a relevant event occurs in an |
45 // accessible view. | 40 // accessible view. |
46 // | 41 // |
47 // Views are not accessible by default. When you register a root widget, | 42 // Views are not accessible by default. When you register a root widget, |
48 // that widget and all of its descendants will start sending accessibility | 43 // that widget and all of its descendants will start sending accessibility |
49 // event notifications. You can then override the default behavior for | 44 // event notifications. You can then override the default behavior for |
50 // specific descendants using other methods. | 45 // specific descendants using other methods. |
51 // | 46 // |
52 // You can use Profile::PauseAccessibilityEvents to prevent a flurry | 47 // You can use Profile::PauseAccessibilityEvents to prevent a flurry |
53 // of accessibility events when a window is being created or initialized. | 48 // of accessibility events when a window is being created or initialized. |
54 class AccessibilityEventRouterViews | 49 class AccessibilityEventRouterViews { |
55 : public views::FocusChangeListener { | |
56 public: | 50 public: |
57 // Internal information about a particular view to override the | 51 // Internal information about a particular view to override the |
58 // information we get directly from the view. | 52 // information we get directly from the view. |
59 struct ViewInfo { | 53 struct ViewInfo { |
60 ViewInfo() : ignore(false), focus_manager(NULL) {} | 54 ViewInfo() : ignore(false) {} |
61 | 55 |
62 // If nonempty, will use this name instead of the view's label. | 56 // If nonempty, will use this name instead of the view's label. |
63 std::string name; | 57 std::string name; |
64 | 58 |
65 // If true, will ignore this widget and not send accessibility events. | 59 // If true, will ignore this widget and not send accessibility events. |
66 bool ignore; | 60 bool ignore; |
67 | |
68 // The focus manager that this view is part of - saved because | |
69 // GetFocusManager may not succeed while a view is being deleted. | |
70 views::FocusManager* focus_manager; | |
71 }; | 61 }; |
72 | 62 |
73 // Get the single instance of this class. | 63 // Get the single instance of this class. |
74 static AccessibilityEventRouterViews* GetInstance(); | 64 static AccessibilityEventRouterViews* GetInstance(); |
75 | 65 |
76 // Start sending accessibility events for this view and all of its | 66 // Start sending accessibility events for this view and all of its |
77 // descendants. Notifications will go to the specified profile. | 67 // descendants. Notifications will go to the specified profile. |
78 // Returns true on success, false if "view" was already registered. | 68 // Returns true on success, false if "view" was already registered. |
79 // It is the responsibility of the caller to call RemoveViewTree if | 69 // It is the responsibility of the caller to call RemoveViewTree if |
80 // this view is ever deleted; consider using AccessibleViewHelper. | 70 // this view is ever deleted; consider using AccessibleViewHelper. |
81 bool AddViewTree(views::View* view, Profile* profile); | 71 bool AddViewTree(views::View* view, Profile* profile); |
82 | 72 |
83 // Stop sending accessibility events for this view and all of its | 73 // Stop sending accessibility events for this view and all of its |
84 // descendants. | 74 // descendants. |
85 void RemoveViewTree(views::View* view); | 75 void RemoveViewTree(views::View* view); |
86 | 76 |
87 // Don't send any events for this view. | 77 // Don't send any events for this view. |
88 void IgnoreView(views::View* view); | 78 void IgnoreView(views::View* view); |
89 | 79 |
90 // Use the following string as the name of this view, instead of the | 80 // Use the following string as the name of this view, instead of the |
91 // gtk label associated with the view. | 81 // gtk label associated with the view. |
92 void SetViewName(views::View* view, std::string name); | 82 void SetViewName(views::View* view, std::string name); |
93 | 83 |
94 // Forget all information about this view. | 84 // Forget all information about this view. |
95 void RemoveView(views::View* view); | 85 void RemoveView(views::View* view); |
96 | 86 |
97 // Implementation of views::FocusChangeListener: | 87 // Handle an accessibility event generated by a view. |
98 virtual void FocusWillChange( | 88 void HandleAccessibilityEvent( |
99 views::View* focused_before, views::View* focused_now); | 89 views::View* view, AccessibilityTypes::Event event_type); |
100 | 90 |
101 private: | 91 private: |
| 92 AccessibilityEventRouterViews(); |
| 93 virtual ~AccessibilityEventRouterViews(); |
| 94 |
| 95 friend struct DefaultSingletonTraits<AccessibilityEventRouterViews>; |
| 96 FRIEND_TEST_ALL_PREFIXES(AccessibilityEventRouterViewsTest, |
| 97 TestFocusNotification); |
| 98 |
102 // Given a view, determine if it's part of a view tree that's mapped to | 99 // Given a view, determine if it's part of a view tree that's mapped to |
103 // a profile and if so, if it's marked as accessible. | 100 // a profile and if so, if it's marked as accessible. |
104 void FindView(views::View* view, Profile** profile, bool* is_accessible); | 101 void FindView(views::View* view, Profile** profile, bool* is_accessible); |
105 | 102 |
106 // Checks the type of the view and calls one of the more specific | 103 // Checks the type of the view and calls one of the more specific |
107 // Send*Notification methods, below. | 104 // Send*Notification methods, below. |
108 void DispatchAccessibilityNotification( | 105 void DispatchAccessibilityNotification( |
109 views::View* view, NotificationType type); | 106 views::View* view, NotificationType type); |
110 | 107 |
111 // Return the name of a view. | 108 // Return the name of a view. |
112 std::string GetViewName(views::View* view); | 109 std::string GetViewName(views::View* view); |
113 | 110 |
114 // Each of these methods constructs an AccessibilityControlInfo object | 111 // Each of these methods constructs an AccessibilityControlInfo object |
115 // and sends a notification of a specific accessibility event. | 112 // and sends a notification of a specific accessibility event. |
116 void SendButtonNotification( | 113 void SendButtonNotification( |
117 views::View* view, NotificationType type, Profile* profile); | 114 views::View* view, NotificationType type, Profile* profile); |
118 void SendLinkNotification( | 115 void SendLinkNotification( |
119 views::View* view, NotificationType type, Profile* profile); | 116 views::View* view, NotificationType type, Profile* profile); |
120 void SendMenuNotification( | 117 void SendMenuNotification( |
121 views::View* view, NotificationType type, Profile* profile); | 118 views::View* view, NotificationType type, Profile* profile); |
| 119 void SendMenuItemNotification( |
| 120 views::View* view, NotificationType type, Profile* profile); |
122 | 121 |
123 private: | 122 // Return true if it's an event on a menu. |
124 AccessibilityEventRouterViews(); | 123 bool IsMenuEvent(views::View* view, NotificationType type); |
125 virtual ~AccessibilityEventRouterViews(); | |
126 | 124 |
127 friend struct DefaultSingletonTraits<AccessibilityEventRouterViews>; | 125 // Recursively explore all menu items of |menu| and return in |count| |
| 126 // the total number of items, and in |index| the 0-based index of |
| 127 // |item|, if found. Initialize |count| to zero before calling this |
| 128 // method. |index| will be unchanged if the item is not found, so |
| 129 // initialize it to -1 to detect this case. |
| 130 void RecursiveGetMenuItemIndexAndCount( |
| 131 views::View* menu, views::View* item, int* index, int* count); |
128 | 132 |
129 // The set of all view tree roots; only descendants of these will generate | 133 // The set of all view tree roots; only descendants of these will generate |
130 // accessibility notifications. | 134 // accessibility notifications. |
131 base::hash_map<views::View*, Profile*> view_tree_profile_map_; | 135 base::hash_map<views::View*, Profile*> view_tree_profile_map_; |
132 | 136 |
133 // Extra information about specific views. | 137 // Extra information about specific views. |
134 base::hash_map<views::View*, ViewInfo> view_info_map_; | 138 base::hash_map<views::View*, ViewInfo> view_info_map_; |
135 | 139 |
136 // Count of the number of references to each focus manager. | 140 // The profile associated with the most recent window event - used to |
137 base::hash_map<views::FocusManager*, int> focus_manager_ref_count_; | 141 // figure out where to route a few events that can't be directly traced |
| 142 // to a window with a profile (like menu events). |
| 143 Profile* most_recent_profile_; |
138 | 144 |
139 // Used to defer handling of some events until the next time | 145 // Used to defer handling of some events until the next time |
140 // through the event loop. | 146 // through the event loop. |
141 ScopedRunnableMethodFactory<AccessibilityEventRouterViews> method_factory_; | 147 ScopedRunnableMethodFactory<AccessibilityEventRouterViews> method_factory_; |
142 }; | 148 }; |
143 | 149 |
144 #endif // CHROME_BROWSER_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ | 150 #endif // CHROME_BROWSER_VIEWS_ACCESSIBILITY_EVENT_ROUTER_VIEWS_H_ |
OLD | NEW |