| 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 |