| 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" |
| 11 #include "chrome/browser/extensions/extension_accessibility_api.h" | 11 #include "chrome/browser/extensions/extension_accessibility_api.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/profiles/profile_manager.h" | 13 #include "chrome/browser/profiles/profile_manager.h" |
| 14 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" | 14 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" |
| 15 #include "chrome/common/notification_type.h" | 15 #include "chrome/common/notification_type.h" |
| 16 #include "views/accessibility/accessibility_types.h" | 16 #include "views/accessibility/accessibility_types.h" |
| 17 #include "views/controls/button/custom_button.h" | 17 #include "views/controls/button/custom_button.h" |
| 18 #include "views/controls/button/menu_button.h" | 18 #include "views/controls/button/menu_button.h" |
| 19 #include "views/controls/button/native_button.h" | 19 #include "views/controls/button/native_button.h" |
| 20 #include "views/controls/link.h" | 20 #include "views/controls/link.h" |
| 21 #include "views/controls/menu/menu_item_view.h" | 21 #include "views/controls/menu/menu_item_view.h" |
| 22 #include "views/controls/menu/submenu_view.h" | 22 #include "views/controls/menu/submenu_view.h" |
| 23 #include "views/view.h" | 23 #include "views/view.h" |
| 24 #include "views/window/window.h" |
| 24 | 25 |
| 25 #if defined(OS_WIN) | 26 #if defined(OS_WIN) |
| 26 #include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" | 27 #include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" |
| 27 #endif | 28 #endif |
| 28 | 29 |
| 29 using views::FocusManager; | 30 using views::FocusManager; |
| 30 | 31 |
| 31 AccessibilityEventRouterViews::AccessibilityEventRouterViews() | 32 AccessibilityEventRouterViews::AccessibilityEventRouterViews() |
| 32 : most_recent_profile_(NULL), | 33 : most_recent_profile_(NULL), |
| 33 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { | 34 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
| 34 } | 35 } |
| 35 | 36 |
| 36 AccessibilityEventRouterViews::~AccessibilityEventRouterViews() { | 37 AccessibilityEventRouterViews::~AccessibilityEventRouterViews() { |
| 37 } | 38 } |
| 38 | 39 |
| 39 // static | 40 // static |
| 40 AccessibilityEventRouterViews* AccessibilityEventRouterViews::GetInstance() { | 41 AccessibilityEventRouterViews* AccessibilityEventRouterViews::GetInstance() { |
| 41 return Singleton<AccessibilityEventRouterViews>::get(); | 42 return Singleton<AccessibilityEventRouterViews>::get(); |
| 42 } | 43 } |
| 43 | 44 |
| 44 bool AccessibilityEventRouterViews::AddViewTree( | |
| 45 views::View* view, Profile* profile) { | |
| 46 if (view_tree_profile_map_[view] != NULL) | |
| 47 return false; | |
| 48 | |
| 49 view_tree_profile_map_[view] = profile; | |
| 50 return true; | |
| 51 } | |
| 52 | |
| 53 void AccessibilityEventRouterViews::RemoveViewTree(views::View* view) { | |
| 54 DCHECK(view_tree_profile_map_.find(view) != | |
| 55 view_tree_profile_map_.end()); | |
| 56 view_tree_profile_map_.erase(view); | |
| 57 } | |
| 58 | |
| 59 void AccessibilityEventRouterViews::IgnoreView(views::View* view) { | |
| 60 view_info_map_[view].ignore = true; | |
| 61 } | |
| 62 | |
| 63 void AccessibilityEventRouterViews::SetViewName( | |
| 64 views::View* view, std::string name) { | |
| 65 view_info_map_[view].name = name; | |
| 66 } | |
| 67 | |
| 68 void AccessibilityEventRouterViews::RemoveView(views::View* view) { | |
| 69 DCHECK(view_info_map_.find(view) != view_info_map_.end()); | |
| 70 view_info_map_.erase(view); | |
| 71 } | |
| 72 | |
| 73 void AccessibilityEventRouterViews::HandleAccessibilityEvent( | 45 void AccessibilityEventRouterViews::HandleAccessibilityEvent( |
| 74 views::View* view, AccessibilityTypes::Event event_type) { | 46 views::View* view, AccessibilityTypes::Event event_type) { |
| 75 if (!ExtensionAccessibilityEventRouter::GetInstance()-> | 47 if (!ExtensionAccessibilityEventRouter::GetInstance()-> |
| 76 IsAccessibilityEnabled()) { | 48 IsAccessibilityEnabled()) { |
| 77 return; | 49 return; |
| 78 } | 50 } |
| 79 | 51 |
| 80 switch (event_type) { | 52 switch (event_type) { |
| 81 case AccessibilityTypes::EVENT_FOCUS: | 53 case AccessibilityTypes::EVENT_FOCUS: |
| 82 DispatchAccessibilityNotification( | 54 DispatchAccessibilityNotification( |
| (...skipping 25 matching lines...) Expand all Loading... |
| 108 // they'd just be superfluous. | 80 // they'd just be superfluous. |
| 109 NOTIMPLEMENTED(); | 81 NOTIMPLEMENTED(); |
| 110 break; | 82 break; |
| 111 } | 83 } |
| 112 } | 84 } |
| 113 | 85 |
| 114 // | 86 // |
| 115 // Private methods | 87 // Private methods |
| 116 // | 88 // |
| 117 | 89 |
| 118 void AccessibilityEventRouterViews::FindView( | |
| 119 views::View* view, Profile** profile, bool* is_accessible) { | |
| 120 *is_accessible = false; | |
| 121 | |
| 122 // First see if it's a descendant of an accessible view. | |
| 123 for (base::hash_map<views::View*, Profile*>::const_iterator iter = | |
| 124 view_tree_profile_map_.begin(); | |
| 125 iter != view_tree_profile_map_.end(); | |
| 126 ++iter) { | |
| 127 if (iter->first->IsParentOf(view)) { | |
| 128 *is_accessible = true; | |
| 129 if (profile) | |
| 130 *profile = iter->second; | |
| 131 break; | |
| 132 } | |
| 133 } | |
| 134 | |
| 135 if (!*is_accessible) | |
| 136 return; | |
| 137 | |
| 138 // Now make sure it's not marked as a widget to be ignored. | |
| 139 base::hash_map<views::View*, ViewInfo>::const_iterator iter = | |
| 140 view_info_map_.find(view); | |
| 141 if (iter != view_info_map_.end() && iter->second.ignore) | |
| 142 *is_accessible = false; | |
| 143 } | |
| 144 | |
| 145 std::string AccessibilityEventRouterViews::GetViewName(views::View* view) { | 90 std::string AccessibilityEventRouterViews::GetViewName(views::View* view) { |
| 146 std::string name; | 91 string16 wname; |
| 147 | 92 view->GetAccessibleName(&wname); |
| 148 // First see if we have a name registered for this view. | 93 return UTF16ToUTF8(wname); |
| 149 base::hash_map<views::View*, ViewInfo>::const_iterator iter = | |
| 150 view_info_map_.find(view); | |
| 151 if (iter != view_info_map_.end()) | |
| 152 name = iter->second.name; | |
| 153 | |
| 154 // Otherwise ask the view for its accessible name. | |
| 155 if (name.empty()) { | |
| 156 string16 wname; | |
| 157 view->GetAccessibleName(&wname); | |
| 158 name = UTF16ToUTF8(wname); | |
| 159 } | |
| 160 | |
| 161 return name; | |
| 162 } | 94 } |
| 163 | 95 |
| 164 void AccessibilityEventRouterViews::DispatchAccessibilityNotification( | 96 void AccessibilityEventRouterViews::DispatchAccessibilityNotification( |
| 165 views::View* view, NotificationType type) { | 97 views::View* view, NotificationType type) { |
| 98 // Get the profile associated with this view. If it's not found, use |
| 99 // the most recent profile where accessibility events were sent, or |
| 100 // the default profile. |
| 166 Profile* profile = NULL; | 101 Profile* profile = NULL; |
| 167 bool is_accessible; | 102 views::Window* window = view->GetWindow(); |
| 168 FindView(view, &profile, &is_accessible); | 103 if (window) { |
| 169 | 104 profile = reinterpret_cast<Profile*>(window->GetNativeWindowProperty( |
| 170 // Special case: a menu isn't associated with any particular top-level | 105 Profile::kProfileKey)); |
| 171 // window, so menu events get routed to the profile of the most recent | 106 } |
| 172 // event that was associated with a window, which should be the window | 107 if (!profile) |
| 173 // that triggered opening the menu. | |
| 174 bool is_menu_event = IsMenuEvent(view, type); | |
| 175 if (is_menu_event && !profile && most_recent_profile_) { | |
| 176 profile = most_recent_profile_; | 108 profile = most_recent_profile_; |
| 177 is_accessible = true; | 109 if (!profile) |
| 110 profile = g_browser_process->profile_manager()->GetDefaultProfile(); |
| 111 if (!profile) { |
| 112 NOTREACHED(); |
| 113 return; |
| 178 } | 114 } |
| 179 | 115 |
| 180 if (!is_accessible) | |
| 181 return; | |
| 182 | |
| 183 most_recent_profile_ = profile; | 116 most_recent_profile_ = profile; |
| 184 | 117 |
| 185 std::string class_name = view->GetClassName(); | 118 std::string class_name = view->GetClassName(); |
| 186 | |
| 187 if (class_name == views::MenuButton::kViewClassName || | 119 if (class_name == views::MenuButton::kViewClassName || |
| 188 type == NotificationType::ACCESSIBILITY_MENU_OPENED || | 120 type == NotificationType::ACCESSIBILITY_MENU_OPENED || |
| 189 type == NotificationType::ACCESSIBILITY_MENU_CLOSED) { | 121 type == NotificationType::ACCESSIBILITY_MENU_CLOSED) { |
| 190 SendMenuNotification(view, type, profile); | 122 SendMenuNotification(view, type, profile); |
| 191 } else if (is_menu_event) { | 123 } else if (IsMenuEvent(view, type)) { |
| 192 SendMenuItemNotification(view, type, profile); | 124 SendMenuItemNotification(view, type, profile); |
| 193 } else if (class_name == views::CustomButton::kViewClassName || | 125 } else if (class_name == views::CustomButton::kViewClassName || |
| 194 class_name == views::NativeButton::kViewClassName || | 126 class_name == views::NativeButton::kViewClassName || |
| 195 class_name == views::TextButton::kViewClassName) { | 127 class_name == views::TextButton::kViewClassName) { |
| 196 SendButtonNotification(view, type, profile); | 128 SendButtonNotification(view, type, profile); |
| 197 } else if (class_name == views::Link::kViewClassName) { | 129 } else if (class_name == views::Link::kViewClassName) { |
| 198 SendLinkNotification(view, type, profile); | 130 SendLinkNotification(view, type, profile); |
| 199 } else if (class_name == LocationBarView::kViewClassName) { | 131 } else if (class_name == LocationBarView::kViewClassName) { |
| 200 SendLocationBarNotification(view, type, profile); | 132 SendLocationBarNotification(view, type, profile); |
| 201 } else { | |
| 202 class_name += " "; | |
| 203 } | 133 } |
| 204 } | 134 } |
| 205 | 135 |
| 206 void AccessibilityEventRouterViews::SendButtonNotification( | 136 void AccessibilityEventRouterViews::SendButtonNotification( |
| 207 views::View* view, NotificationType type, Profile* profile) { | 137 views::View* view, NotificationType type, Profile* profile) { |
| 208 AccessibilityButtonInfo info(profile, GetViewName(view)); | 138 AccessibilityButtonInfo info(profile, GetViewName(view)); |
| 209 SendAccessibilityNotification(type, &info); | 139 SendAccessibilityNotification(type, &info); |
| 210 } | 140 } |
| 211 | 141 |
| 212 void AccessibilityEventRouterViews::SendLinkNotification( | 142 void AccessibilityEventRouterViews::SendLinkNotification( |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 std::string value = WideToUTF8(location_entry->GetText()); | 226 std::string value = WideToUTF8(location_entry->GetText()); |
| 297 std::wstring::size_type selection_start; | 227 std::wstring::size_type selection_start; |
| 298 std::wstring::size_type selection_end; | 228 std::wstring::size_type selection_end; |
| 299 location_entry->GetSelectionBounds(&selection_start, &selection_end); | 229 location_entry->GetSelectionBounds(&selection_start, &selection_end); |
| 300 | 230 |
| 301 AccessibilityTextBoxInfo info(profile, name, false); | 231 AccessibilityTextBoxInfo info(profile, name, false); |
| 302 info.SetValue(value, selection_start, selection_end); | 232 info.SetValue(value, selection_start, selection_end); |
| 303 SendAccessibilityNotification(type, &info); | 233 SendAccessibilityNotification(type, &info); |
| 304 #endif | 234 #endif |
| 305 } | 235 } |
| OLD | NEW |