OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "chrome/browser/ui/views/accessibility/accessibility_event_router_views
.h" | 5 #include "chrome/browser/ui/views/accessibility/accessibility_event_router_views
.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/memory/singleton.h" | 9 #include "base/memory/singleton.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
12 #include "chrome/browser/accessibility/accessibility_extension_api.h" | 12 #include "chrome/browser/accessibility/accessibility_extension_api.h" |
13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
14 #include "chrome/browser/chrome_notification_types.h" | 14 #include "chrome/browser/chrome_notification_types.h" |
15 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/profiles/profile_manager.h" | 16 #include "chrome/browser/profiles/profile_manager.h" |
17 #include "content/public/browser/notification_service.h" | 17 #include "content/public/browser/notification_service.h" |
18 #include "ui/accessibility/ax_view_state.h" | 18 #include "ui/accessibility/ax_view_state.h" |
19 #include "ui/views/controls/menu/menu_item_view.h" | 19 #include "ui/views/controls/menu/menu_item_view.h" |
20 #include "ui/views/controls/menu/submenu_view.h" | 20 #include "ui/views/controls/menu/submenu_view.h" |
21 #include "ui/views/controls/tree/tree_view.h" | 21 #include "ui/views/controls/tree/tree_view.h" |
22 #include "ui/views/focus/view_storage.h" | 22 #include "ui/views/focus/view_storage.h" |
23 #include "ui/views/view.h" | 23 #include "ui/views/view.h" |
24 #include "ui/views/widget/widget.h" | 24 #include "ui/views/widget/widget.h" |
25 | 25 |
26 using views::FocusManager; | 26 using views::FocusManager; |
| 27 using views::ViewStorage; |
27 | 28 |
28 AccessibilityEventRouterViews::AccessibilityEventRouterViews() | 29 AccessibilityEventRouterViews::AccessibilityEventRouterViews() |
29 : most_recent_profile_(NULL) { | 30 : most_recent_profile_(NULL), |
| 31 most_recent_view_id_( |
| 32 ViewStorage::GetInstance()->CreateStorageID()) { |
30 // Register for notification when profile is destroyed to ensure that all | 33 // Register for notification when profile is destroyed to ensure that all |
31 // observers are detatched at that time. | 34 // observers are detatched at that time. |
32 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, | 35 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
33 content::NotificationService::AllSources()); | 36 content::NotificationService::AllSources()); |
34 } | 37 } |
35 | 38 |
36 AccessibilityEventRouterViews::~AccessibilityEventRouterViews() { | 39 AccessibilityEventRouterViews::~AccessibilityEventRouterViews() { |
37 } | 40 } |
38 | 41 |
39 // static | 42 // static |
(...skipping 21 matching lines...) Expand all Loading... |
61 // we pass more information along to the listener such as focused state. | 64 // we pass more information along to the listener such as focused state. |
62 if (!view->GetFocusManager() || | 65 if (!view->GetFocusManager() || |
63 view->GetFocusManager()->GetFocusedView() != view) | 66 view->GetFocusManager()->GetFocusedView() != view) |
64 return; | 67 return; |
65 } | 68 } |
66 | 69 |
67 // Don't dispatch the accessibility event until the next time through the | 70 // Don't dispatch the accessibility event until the next time through the |
68 // event loop, to handle cases where the view's state changes after | 71 // event loop, to handle cases where the view's state changes after |
69 // the call to post the event. It's safe to use base::Unretained(this) | 72 // the call to post the event. It's safe to use base::Unretained(this) |
70 // because AccessibilityEventRouterViews is a singleton. | 73 // because AccessibilityEventRouterViews is a singleton. |
71 views::ViewStorage* view_storage = views::ViewStorage::GetInstance(); | 74 ViewStorage* view_storage = ViewStorage::GetInstance(); |
72 int view_storage_id = view_storage->CreateStorageID(); | 75 int view_storage_id = view_storage->CreateStorageID(); |
73 view_storage->StoreView(view_storage_id, view); | 76 view_storage->StoreView(view_storage_id, view); |
74 base::MessageLoop::current()->PostTask( | 77 base::MessageLoop::current()->PostTask( |
75 FROM_HERE, | 78 FROM_HERE, |
76 base::Bind( | 79 base::Bind( |
77 &AccessibilityEventRouterViews::DispatchEventOnViewStorageId, | 80 &AccessibilityEventRouterViews::DispatchEventOnViewStorageId, |
78 view_storage_id, | 81 view_storage_id, |
79 event_type)); | 82 event_type)); |
80 } | 83 } |
81 | 84 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 most_recent_profile_ = NULL; | 116 most_recent_profile_ = NULL; |
114 } | 117 } |
115 | 118 |
116 // | 119 // |
117 // Private methods | 120 // Private methods |
118 // | 121 // |
119 | 122 |
120 void AccessibilityEventRouterViews::DispatchEventOnViewStorageId( | 123 void AccessibilityEventRouterViews::DispatchEventOnViewStorageId( |
121 int view_storage_id, | 124 int view_storage_id, |
122 ui::AXEvent type) { | 125 ui::AXEvent type) { |
123 views::ViewStorage* view_storage = views::ViewStorage::GetInstance(); | 126 ViewStorage* view_storage = ViewStorage::GetInstance(); |
124 views::View* view = view_storage->RetrieveView(view_storage_id); | 127 views::View* view = view_storage->RetrieveView(view_storage_id); |
125 view_storage->RemoveView(view_storage_id); | 128 view_storage->RemoveView(view_storage_id); |
126 if (!view) | 129 if (!view) |
127 return; | 130 return; |
128 | 131 |
129 AccessibilityEventRouterViews* instance = | 132 AccessibilityEventRouterViews* instance = |
130 AccessibilityEventRouterViews::GetInstance(); | 133 AccessibilityEventRouterViews::GetInstance(); |
131 instance->DispatchAccessibilityEvent(view, type); | 134 instance->DispatchAccessibilityEvent(view, type); |
132 } | 135 } |
133 | 136 |
(...skipping 22 matching lines...) Expand all Loading... |
156 most_recent_profile_ = profile; | 159 most_recent_profile_ = profile; |
157 | 160 |
158 if (type == ui::AX_EVENT_MENU_START || | 161 if (type == ui::AX_EVENT_MENU_START || |
159 type == ui::AX_EVENT_MENU_POPUP_START || | 162 type == ui::AX_EVENT_MENU_POPUP_START || |
160 type == ui::AX_EVENT_MENU_END || | 163 type == ui::AX_EVENT_MENU_END || |
161 type == ui::AX_EVENT_MENU_POPUP_END) { | 164 type == ui::AX_EVENT_MENU_POPUP_END) { |
162 SendMenuNotification(view, type, profile); | 165 SendMenuNotification(view, type, profile); |
163 return; | 166 return; |
164 } | 167 } |
165 | 168 |
| 169 view = FindFirstAccessibleAncestor(view); |
| 170 |
| 171 // Since multiple items could share a highest focusable view, these items |
| 172 // could all dispatch the same accessibility hover events, which isn't |
| 173 // necessary. |
| 174 if (type == ui::AX_EVENT_HOVER && |
| 175 ViewStorage::GetInstance()->RetrieveView(most_recent_view_id_) == view) { |
| 176 return; |
| 177 } |
| 178 // If there was already a view stored here from before, it must be removed |
| 179 // before storing a new view. |
| 180 ViewStorage::GetInstance()->RemoveView(most_recent_view_id_); |
| 181 ViewStorage::GetInstance()->StoreView(most_recent_view_id_, view); |
| 182 |
166 ui::AXViewState state; | 183 ui::AXViewState state; |
167 view->GetAccessibleState(&state); | 184 view->GetAccessibleState(&state); |
168 | 185 |
169 if (type == ui::AX_EVENT_ALERT && | 186 if (type == ui::AX_EVENT_ALERT && |
170 !(state.role == ui::AX_ROLE_ALERT || | 187 !(state.role == ui::AX_ROLE_ALERT || |
171 state.role == ui::AX_ROLE_WINDOW)) { | 188 state.role == ui::AX_ROLE_WINDOW)) { |
172 SendAlertControlNotification(view, type, profile); | 189 SendAlertControlNotification(view, type, profile); |
173 return; | 190 return; |
174 } | 191 } |
175 | 192 |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 return base::UTF16ToUTF8(state.name); | 562 return base::UTF16ToUTF8(state.name); |
546 | 563 |
547 for (int i = 0; i < view->child_count(); ++i) { | 564 for (int i = 0; i < view->child_count(); ++i) { |
548 views::View* child = view->child_at(i); | 565 views::View* child = view->child_at(i); |
549 std::string result = RecursiveGetStaticText(child); | 566 std::string result = RecursiveGetStaticText(child); |
550 if (!result.empty()) | 567 if (!result.empty()) |
551 return result; | 568 return result; |
552 } | 569 } |
553 return std::string(); | 570 return std::string(); |
554 } | 571 } |
| 572 |
| 573 // static |
| 574 views::View* AccessibilityEventRouterViews::FindFirstAccessibleAncestor( |
| 575 views::View* view) { |
| 576 while (view->parent() && !view->IsAccessibilityFocusable()) { |
| 577 view = view->parent(); |
| 578 } |
| 579 return view; |
| 580 } |
OLD | NEW |