OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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_event_router_views.h" | 5 #include "chrome/browser/ui/views/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/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 if (!ExtensionAccessibilityEventRouter::GetInstance()-> | 84 if (!ExtensionAccessibilityEventRouter::GetInstance()-> |
85 IsAccessibilityEnabled()) { | 85 IsAccessibilityEnabled()) { |
86 return; | 86 return; |
87 } | 87 } |
88 | 88 |
89 if (!most_recent_profile_) | 89 if (!most_recent_profile_) |
90 return; | 90 return; |
91 | 91 |
92 AccessibilityMenuItemInfo info(most_recent_profile_, | 92 AccessibilityMenuItemInfo info(most_recent_profile_, |
93 UTF16ToUTF8(menu_item_name), | 93 UTF16ToUTF8(menu_item_name), |
| 94 UTF16ToUTF8(menu_name), |
94 has_submenu, | 95 has_submenu, |
95 item_index, | 96 item_index, |
96 item_count); | 97 item_count); |
97 SendAccessibilityNotification( | 98 SendAccessibilityNotification( |
98 chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED, &info); | 99 chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED, &info); |
99 } | 100 } |
100 | 101 |
101 // | 102 // |
102 // Private methods | 103 // Private methods |
103 // | 104 // |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 break; | 164 break; |
164 case ui::AccessibilityTypes::ROLE_RADIOBUTTON: | 165 case ui::AccessibilityTypes::ROLE_RADIOBUTTON: |
165 // Not used anymore? | 166 // Not used anymore? |
166 default: | 167 default: |
167 // If this is encountered, please file a bug with the role that wasn't | 168 // If this is encountered, please file a bug with the role that wasn't |
168 // caught so we can add accessibility extension API support. | 169 // caught so we can add accessibility extension API support. |
169 NOTREACHED(); | 170 NOTREACHED(); |
170 } | 171 } |
171 } | 172 } |
172 | 173 |
| 174 // static |
173 void AccessibilityEventRouterViews::SendButtonNotification( | 175 void AccessibilityEventRouterViews::SendButtonNotification( |
174 views::View* view, | 176 views::View* view, |
175 int type, | 177 int type, |
176 Profile* profile) { | 178 Profile* profile) { |
177 AccessibilityButtonInfo info(profile, GetViewName(view)); | 179 AccessibilityButtonInfo info( |
| 180 profile, GetViewName(view), GetViewContext(view)); |
178 SendAccessibilityNotification(type, &info); | 181 SendAccessibilityNotification(type, &info); |
179 } | 182 } |
180 | 183 |
| 184 // static |
181 void AccessibilityEventRouterViews::SendLinkNotification( | 185 void AccessibilityEventRouterViews::SendLinkNotification( |
182 views::View* view, | 186 views::View* view, |
183 int type, | 187 int type, |
184 Profile* profile) { | 188 Profile* profile) { |
185 AccessibilityLinkInfo info(profile, GetViewName(view)); | 189 AccessibilityLinkInfo info(profile, GetViewName(view), GetViewContext(view)); |
186 SendAccessibilityNotification(type, &info); | 190 SendAccessibilityNotification(type, &info); |
187 } | 191 } |
188 | 192 |
| 193 // static |
189 void AccessibilityEventRouterViews::SendMenuNotification( | 194 void AccessibilityEventRouterViews::SendMenuNotification( |
190 views::View* view, | 195 views::View* view, |
191 int type, | 196 int type, |
192 Profile* profile) { | 197 Profile* profile) { |
193 AccessibilityMenuInfo info(profile, GetViewName(view)); | 198 AccessibilityMenuInfo info(profile, GetViewName(view)); |
194 SendAccessibilityNotification(type, &info); | 199 SendAccessibilityNotification(type, &info); |
195 } | 200 } |
196 | 201 |
| 202 // static |
197 void AccessibilityEventRouterViews::SendMenuItemNotification( | 203 void AccessibilityEventRouterViews::SendMenuItemNotification( |
198 views::View* view, | 204 views::View* view, |
199 int type, | 205 int type, |
200 Profile* profile) { | 206 Profile* profile) { |
201 std::string name = GetViewName(view); | 207 std::string name = GetViewName(view); |
| 208 std::string context = GetViewContext(view); |
202 | 209 |
203 bool has_submenu = false; | 210 bool has_submenu = false; |
204 int index = -1; | 211 int index = -1; |
205 int count = -1; | 212 int count = -1; |
206 | 213 |
207 if (view->GetClassName() == views::MenuItemView::kViewClassName) | 214 if (view->GetClassName() == views::MenuItemView::kViewClassName) |
208 has_submenu = static_cast<views::MenuItemView*>(view)->HasSubmenu(); | 215 has_submenu = static_cast<views::MenuItemView*>(view)->HasSubmenu(); |
209 | 216 |
210 views::View* parent_menu = view->parent(); | 217 views::View* parent_menu = view->parent(); |
211 while (parent_menu != NULL && parent_menu->GetClassName() != | 218 while (parent_menu != NULL && parent_menu->GetClassName() != |
212 views::SubmenuView::kViewClassName) { | 219 views::SubmenuView::kViewClassName) { |
213 parent_menu = parent_menu->parent(); | 220 parent_menu = parent_menu->parent(); |
214 } | 221 } |
215 if (parent_menu) { | 222 if (parent_menu) { |
216 count = 0; | 223 count = 0; |
217 RecursiveGetMenuItemIndexAndCount(parent_menu, view, &index, &count); | 224 RecursiveGetMenuItemIndexAndCount(parent_menu, view, &index, &count); |
218 } | 225 } |
219 | 226 |
220 AccessibilityMenuItemInfo info(profile, name, has_submenu, index, count); | 227 AccessibilityMenuItemInfo info( |
| 228 profile, name, context, has_submenu, index, count); |
221 SendAccessibilityNotification(type, &info); | 229 SendAccessibilityNotification(type, &info); |
222 } | 230 } |
223 | 231 |
| 232 // static |
224 void AccessibilityEventRouterViews::SendTextfieldNotification( | 233 void AccessibilityEventRouterViews::SendTextfieldNotification( |
225 views::View* view, | 234 views::View* view, |
226 int type, | 235 int type, |
227 Profile* profile) { | 236 Profile* profile) { |
228 ui::AccessibleViewState state; | 237 ui::AccessibleViewState state; |
229 view->GetAccessibleState(&state); | 238 view->GetAccessibleState(&state); |
230 std::string name = UTF16ToUTF8(state.name); | 239 std::string name = UTF16ToUTF8(state.name); |
| 240 std::string context = GetViewContext(view); |
231 bool password = | 241 bool password = |
232 (state.state & ui::AccessibilityTypes::STATE_PROTECTED) != 0; | 242 (state.state & ui::AccessibilityTypes::STATE_PROTECTED) != 0; |
233 AccessibilityTextBoxInfo info(profile, name, password); | 243 AccessibilityTextBoxInfo info(profile, name, context, password); |
234 std::string value = UTF16ToUTF8(state.value); | 244 std::string value = UTF16ToUTF8(state.value); |
235 info.SetValue(value, state.selection_start, state.selection_end); | 245 info.SetValue(value, state.selection_start, state.selection_end); |
236 SendAccessibilityNotification(type, &info); | 246 SendAccessibilityNotification(type, &info); |
237 } | 247 } |
238 | 248 |
| 249 // static |
239 void AccessibilityEventRouterViews::SendComboboxNotification( | 250 void AccessibilityEventRouterViews::SendComboboxNotification( |
240 views::View* view, | 251 views::View* view, |
241 int type, | 252 int type, |
242 Profile* profile) { | 253 Profile* profile) { |
243 ui::AccessibleViewState state; | 254 ui::AccessibleViewState state; |
244 view->GetAccessibleState(&state); | 255 view->GetAccessibleState(&state); |
245 std::string name = UTF16ToUTF8(state.name); | 256 std::string name = UTF16ToUTF8(state.name); |
246 std::string value = UTF16ToUTF8(state.value); | 257 std::string value = UTF16ToUTF8(state.value); |
| 258 std::string context = GetViewContext(view); |
247 AccessibilityComboBoxInfo info( | 259 AccessibilityComboBoxInfo info( |
248 profile, name, value, state.index, state.count); | 260 profile, name, context, value, state.index, state.count); |
249 SendAccessibilityNotification(type, &info); | 261 SendAccessibilityNotification(type, &info); |
250 } | 262 } |
251 | 263 |
| 264 // static |
252 void AccessibilityEventRouterViews::SendCheckboxNotification( | 265 void AccessibilityEventRouterViews::SendCheckboxNotification( |
253 views::View* view, | 266 views::View* view, |
254 int type, | 267 int type, |
255 Profile* profile) { | 268 Profile* profile) { |
256 ui::AccessibleViewState state; | 269 ui::AccessibleViewState state; |
257 view->GetAccessibleState(&state); | 270 view->GetAccessibleState(&state); |
258 std::string name = UTF16ToUTF8(state.name); | 271 std::string name = UTF16ToUTF8(state.name); |
259 std::string value = UTF16ToUTF8(state.value); | 272 std::string value = UTF16ToUTF8(state.value); |
| 273 std::string context = GetViewContext(view); |
260 AccessibilityCheckboxInfo info( | 274 AccessibilityCheckboxInfo info( |
261 profile, name, state.state == ui::AccessibilityTypes::STATE_CHECKED); | 275 profile, |
| 276 name, |
| 277 context, |
| 278 state.state == ui::AccessibilityTypes::STATE_CHECKED); |
262 SendAccessibilityNotification(type, &info); | 279 SendAccessibilityNotification(type, &info); |
263 } | 280 } |
264 | 281 |
| 282 // static |
265 void AccessibilityEventRouterViews::SendWindowNotification( | 283 void AccessibilityEventRouterViews::SendWindowNotification( |
266 views::View* view, | 284 views::View* view, |
267 int type, | 285 int type, |
268 Profile* profile) { | 286 Profile* profile) { |
269 ui::AccessibleViewState state; | 287 ui::AccessibleViewState state; |
270 view->GetAccessibleState(&state); | 288 view->GetAccessibleState(&state); |
271 std::string window_text; | 289 std::string window_text; |
272 | 290 |
273 // If it's an alert, try to get the text from the contents of the | 291 // If it's an alert, try to get the text from the contents of the |
274 // static text, not the window title. | 292 // static text, not the window title. |
275 if (state.role == ui::AccessibilityTypes::ROLE_ALERT) | 293 if (state.role == ui::AccessibilityTypes::ROLE_ALERT) |
276 window_text = RecursiveGetStaticText(view); | 294 window_text = RecursiveGetStaticText(view); |
277 | 295 |
278 // Otherwise get it from the window's accessible name. | 296 // Otherwise get it from the window's accessible name. |
279 if (window_text.empty()) | 297 if (window_text.empty()) |
280 window_text = UTF16ToUTF8(state.name); | 298 window_text = UTF16ToUTF8(state.name); |
281 | 299 |
282 AccessibilityWindowInfo info(profile, window_text); | 300 AccessibilityWindowInfo info(profile, window_text); |
283 SendAccessibilityNotification(type, &info); | 301 SendAccessibilityNotification(type, &info); |
284 } | 302 } |
285 | 303 |
| 304 // static |
286 std::string AccessibilityEventRouterViews::GetViewName(views::View* view) { | 305 std::string AccessibilityEventRouterViews::GetViewName(views::View* view) { |
287 ui::AccessibleViewState state; | 306 ui::AccessibleViewState state; |
288 view->GetAccessibleState(&state); | 307 view->GetAccessibleState(&state); |
289 return UTF16ToUTF8(state.name); | 308 return UTF16ToUTF8(state.name); |
290 } | 309 } |
291 | 310 |
| 311 // static |
| 312 std::string AccessibilityEventRouterViews::GetViewContext(views::View* view) { |
| 313 for (views::View* parent = view->parent(); |
| 314 parent; |
| 315 parent = parent->parent()) { |
| 316 ui::AccessibleViewState state; |
| 317 parent->GetAccessibleState(&state); |
| 318 |
| 319 // Two cases are handled right now. More could be added in the future |
| 320 // depending on how the UI evolves. |
| 321 |
| 322 // A control in a toolbar should use the toolbar's accessible name |
| 323 // as the context. |
| 324 if (state.role == ui::AccessibilityTypes::ROLE_TOOLBAR && |
| 325 !state.name.empty()) { |
| 326 return UTF16ToUTF8(state.name); |
| 327 } |
| 328 |
| 329 // A control inside of an alert (like an infobar) should grab the |
| 330 // first static text descendant as the context; that's the prompt. |
| 331 if (state.role == ui::AccessibilityTypes::ROLE_ALERT) { |
| 332 views::View* static_text_child = FindDescendantWithAccessibleRole( |
| 333 parent, ui::AccessibilityTypes::ROLE_STATICTEXT); |
| 334 if (static_text_child) { |
| 335 ui::AccessibleViewState state; |
| 336 static_text_child->GetAccessibleState(&state); |
| 337 if (!state.name.empty()) |
| 338 return UTF16ToUTF8(state.name); |
| 339 } |
| 340 return std::string(); |
| 341 } |
| 342 } |
| 343 |
| 344 return std::string(); |
| 345 } |
| 346 |
| 347 // static |
| 348 views::View* AccessibilityEventRouterViews::FindDescendantWithAccessibleRole( |
| 349 views::View* view, ui::AccessibilityTypes::Role role) { |
| 350 ui::AccessibleViewState state; |
| 351 view->GetAccessibleState(&state); |
| 352 if (state.role == role) |
| 353 return view; |
| 354 |
| 355 for (int i = 0; i < view->child_count(); i++) { |
| 356 views::View* child = view->child_at(i); |
| 357 views::View* result = FindDescendantWithAccessibleRole(child, role); |
| 358 if (result) |
| 359 return result; |
| 360 } |
| 361 |
| 362 return NULL; |
| 363 } |
| 364 |
| 365 // static |
292 bool AccessibilityEventRouterViews::IsMenuEvent( | 366 bool AccessibilityEventRouterViews::IsMenuEvent( |
293 views::View* view, | 367 views::View* view, |
294 int type) { | 368 int type) { |
295 if (type == chrome::NOTIFICATION_ACCESSIBILITY_MENU_OPENED || | 369 if (type == chrome::NOTIFICATION_ACCESSIBILITY_MENU_OPENED || |
296 type == chrome::NOTIFICATION_ACCESSIBILITY_MENU_CLOSED) | 370 type == chrome::NOTIFICATION_ACCESSIBILITY_MENU_CLOSED) |
297 return true; | 371 return true; |
298 | 372 |
299 while (view) { | 373 while (view) { |
300 ui::AccessibleViewState state; | 374 ui::AccessibleViewState state; |
301 view->GetAccessibleState(&state); | 375 view->GetAccessibleState(&state); |
302 ui::AccessibilityTypes::Role role = state.role; | 376 ui::AccessibilityTypes::Role role = state.role; |
303 if (role == ui::AccessibilityTypes::ROLE_MENUITEM || | 377 if (role == ui::AccessibilityTypes::ROLE_MENUITEM || |
304 role == ui::AccessibilityTypes::ROLE_MENUPOPUP) { | 378 role == ui::AccessibilityTypes::ROLE_MENUPOPUP) { |
305 return true; | 379 return true; |
306 } | 380 } |
307 view = view->parent(); | 381 view = view->parent(); |
308 } | 382 } |
309 | 383 |
310 return false; | 384 return false; |
311 } | 385 } |
312 | 386 |
| 387 // static |
313 void AccessibilityEventRouterViews::RecursiveGetMenuItemIndexAndCount( | 388 void AccessibilityEventRouterViews::RecursiveGetMenuItemIndexAndCount( |
314 views::View* menu, | 389 views::View* menu, |
315 views::View* item, | 390 views::View* item, |
316 int* index, | 391 int* index, |
317 int* count) { | 392 int* count) { |
318 for (int i = 0; i < menu->child_count(); ++i) { | 393 for (int i = 0; i < menu->child_count(); ++i) { |
319 views::View* child = menu->child_at(i); | 394 views::View* child = menu->child_at(i); |
320 int previous_count = *count; | 395 int previous_count = *count; |
321 RecursiveGetMenuItemIndexAndCount(child, item, index, count); | 396 RecursiveGetMenuItemIndexAndCount(child, item, index, count); |
322 if (child->GetClassName() == views::MenuItemView::kViewClassName && | 397 if (child->GetClassName() == views::MenuItemView::kViewClassName && |
323 *count == previous_count) { | 398 *count == previous_count) { |
324 if (item == child) | 399 if (item == child) |
325 *index = *count; | 400 *index = *count; |
326 (*count)++; | 401 (*count)++; |
327 } else if (child->GetClassName() == views::TextButton::kViewClassName) { | 402 } else if (child->GetClassName() == views::TextButton::kViewClassName) { |
328 if (item == child) | 403 if (item == child) |
329 *index = *count; | 404 *index = *count; |
330 (*count)++; | 405 (*count)++; |
331 } | 406 } |
332 } | 407 } |
333 } | 408 } |
334 | 409 |
| 410 // static |
335 std::string AccessibilityEventRouterViews::RecursiveGetStaticText( | 411 std::string AccessibilityEventRouterViews::RecursiveGetStaticText( |
336 views::View* view) { | 412 views::View* view) { |
337 ui::AccessibleViewState state; | 413 ui::AccessibleViewState state; |
338 view->GetAccessibleState(&state); | 414 view->GetAccessibleState(&state); |
339 if (state.role == ui::AccessibilityTypes::ROLE_STATICTEXT) | 415 if (state.role == ui::AccessibilityTypes::ROLE_STATICTEXT) |
340 return UTF16ToUTF8(state.name); | 416 return UTF16ToUTF8(state.name); |
341 | 417 |
342 for (int i = 0; i < view->child_count(); ++i) { | 418 for (int i = 0; i < view->child_count(); ++i) { |
343 views::View* child = view->child_at(i); | 419 views::View* child = view->child_at(i); |
344 std::string result = RecursiveGetStaticText(child); | 420 std::string result = RecursiveGetStaticText(child); |
345 if (!result.empty()) | 421 if (!result.empty()) |
346 return result; | 422 return result; |
347 } | 423 } |
348 return std::string(); | 424 return std::string(); |
349 } | 425 } |
OLD | NEW |