Chromium Code Reviews| 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 "ui/views/accessibility/native_view_accessibility_win.h" | 5 #include "ui/views/accessibility/native_view_accessibility_win.h" |
| 6 | 6 |
| 7 #include <oleacc.h> | 7 #include <oleacc.h> |
| 8 #include <UIAutomationClient.h> | 8 #include <UIAutomationClient.h> |
| 9 | 9 |
| 10 #include <set> | 10 #include <set> |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 IID_IAccessible, IID_IAccessible2, | 182 IID_IAccessible, IID_IAccessible2, |
| 183 reinterpret_cast<void**>(iaccessible2.Receive())); | 183 reinterpret_cast<void**>(iaccessible2.Receive())); |
| 184 } | 184 } |
| 185 | 185 |
| 186 } // anonymous namespace | 186 } // anonymous namespace |
| 187 | 187 |
| 188 // static | 188 // static |
| 189 long NativeViewAccessibilityWin::next_unique_id_ = 1; | 189 long NativeViewAccessibilityWin::next_unique_id_ = 1; |
| 190 int NativeViewAccessibilityWin::view_storage_ids_[kMaxViewStorageIds] = {0}; | 190 int NativeViewAccessibilityWin::view_storage_ids_[kMaxViewStorageIds] = {0}; |
| 191 int NativeViewAccessibilityWin::next_view_storage_id_index_ = 0; | 191 int NativeViewAccessibilityWin::next_view_storage_id_index_ = 0; |
| 192 std::vector<int> NativeViewAccessibilityWin::alert_target_view_storage_ids_; | |
| 192 | 193 |
| 193 // static | 194 // static |
| 194 NativeViewAccessibility* NativeViewAccessibility::Create(View* view) { | 195 NativeViewAccessibility* NativeViewAccessibility::Create(View* view) { |
| 195 // Make sure ATL is initialized in this module. | 196 // Make sure ATL is initialized in this module. |
| 196 ui::win::CreateATLModuleIfNeeded(); | 197 ui::win::CreateATLModuleIfNeeded(); |
| 197 | 198 |
| 198 CComObject<NativeViewAccessibilityWin>* instance = NULL; | 199 CComObject<NativeViewAccessibilityWin>* instance = NULL; |
| 199 HRESULT hr = CComObject<NativeViewAccessibilityWin>::CreateInstance( | 200 HRESULT hr = CComObject<NativeViewAccessibilityWin>::CreateInstance( |
| 200 &instance); | 201 &instance); |
| 201 DCHECK(SUCCEEDED(hr)); | 202 DCHECK(SUCCEEDED(hr)); |
| 202 instance->set_view(view); | 203 instance->set_view(view); |
| 203 instance->AddRef(); | 204 instance->AddRef(); |
| 204 return instance; | 205 return instance; |
| 205 } | 206 } |
| 206 | 207 |
| 207 NativeViewAccessibilityWin::NativeViewAccessibilityWin() | 208 NativeViewAccessibilityWin::NativeViewAccessibilityWin() |
| 208 : view_(NULL), | 209 : view_(NULL), |
| 209 unique_id_(next_unique_id_++) { | 210 unique_id_(next_unique_id_++) { |
| 210 } | 211 } |
| 211 | 212 |
| 212 NativeViewAccessibilityWin::~NativeViewAccessibilityWin() { | 213 NativeViewAccessibilityWin::~NativeViewAccessibilityWin() { |
| 214 RemoveAlertTarget(); | |
| 213 } | 215 } |
| 214 | 216 |
| 215 void NativeViewAccessibilityWin::NotifyAccessibilityEvent( | 217 void NativeViewAccessibilityWin::NotifyAccessibilityEvent( |
| 216 ui::AXEvent event_type) { | 218 ui::AXEvent event_type) { |
| 217 if (!view_) | 219 if (!view_) |
| 218 return; | 220 return; |
| 219 | 221 |
| 220 ViewStorage* view_storage = ViewStorage::GetInstance(); | 222 ViewStorage* view_storage = ViewStorage::GetInstance(); |
| 221 HWND hwnd = HWNDForView(view_); | 223 HWND hwnd = HWNDForView(view_); |
| 222 int view_storage_id = view_storage_ids_[next_view_storage_id_index_]; | 224 int view_storage_id = view_storage_ids_[next_view_storage_id_index_]; |
| 223 if (view_storage_id == 0) { | 225 if (view_storage_id == 0) { |
| 224 view_storage_id = view_storage->CreateStorageID(); | 226 view_storage_id = view_storage->CreateStorageID(); |
| 225 view_storage_ids_[next_view_storage_id_index_] = view_storage_id; | 227 view_storage_ids_[next_view_storage_id_index_] = view_storage_id; |
| 226 } else { | 228 } else { |
| 227 view_storage->RemoveView(view_storage_id); | 229 view_storage->RemoveView(view_storage_id); |
| 228 } | 230 } |
| 229 view_storage->StoreView(view_storage_id, view_); | 231 view_storage->StoreView(view_storage_id, view_); |
| 230 | 232 |
| 231 // Positive child ids are used for enumerating direct children, | 233 // Positive child ids are used for enumerating direct children, |
| 232 // negative child ids can be used as unique ids to refer to a specific | 234 // negative child ids can be used as unique ids to refer to a specific |
| 233 // descendants. Make index into view_storage_ids_ into a negative child id. | 235 // descendants. Make index into view_storage_ids_ into a negative child id. |
| 234 int child_id = | 236 int child_id = |
| 235 base::win::kFirstViewsAccessibilityId - next_view_storage_id_index_; | 237 base::win::kFirstViewsAccessibilityId - next_view_storage_id_index_; |
| 236 ::NotifyWinEvent(MSAAEvent(event_type), hwnd, OBJID_CLIENT, child_id); | 238 ::NotifyWinEvent(MSAAEvent(event_type), hwnd, OBJID_CLIENT, child_id); |
| 237 next_view_storage_id_index_ = | 239 next_view_storage_id_index_ = |
| 238 (next_view_storage_id_index_ + 1) % kMaxViewStorageIds; | 240 (next_view_storage_id_index_ + 1) % kMaxViewStorageIds; |
| 241 | |
| 242 // Keep track of views that are a target of an alert event. | |
| 243 if (event_type == ui::AX_EVENT_ALERT) | |
| 244 AddAlertTarget(); | |
| 239 } | 245 } |
| 240 | 246 |
| 241 gfx::NativeViewAccessible NativeViewAccessibilityWin::GetNativeObject() { | 247 gfx::NativeViewAccessible NativeViewAccessibilityWin::GetNativeObject() { |
| 242 return this; | 248 return this; |
| 243 } | 249 } |
| 244 | 250 |
| 245 void NativeViewAccessibilityWin::Destroy() { | 251 void NativeViewAccessibilityWin::Destroy() { |
| 246 view_ = NULL; | 252 view_ = NULL; |
| 247 Release(); | 253 Release(); |
| 248 } | 254 } |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 858 if (!view_) | 864 if (!view_) |
| 859 return E_FAIL; | 865 return E_FAIL; |
| 860 | 866 |
| 861 if (!window_handle) | 867 if (!window_handle) |
| 862 return E_INVALIDARG; | 868 return E_INVALIDARG; |
| 863 | 869 |
| 864 *window_handle = HWNDForView(view_); | 870 *window_handle = HWNDForView(view_); |
| 865 return *window_handle ? S_OK : S_FALSE; | 871 return *window_handle ? S_OK : S_FALSE; |
| 866 } | 872 } |
| 867 | 873 |
| 874 STDMETHODIMP NativeViewAccessibilityWin::get_relationTargetsOfType( | |
| 875 BSTR type_bstr, | |
| 876 long max_targets, | |
| 877 IUnknown ***targets, | |
| 878 long *n_targets) { | |
| 879 if (!view_) | |
| 880 return E_FAIL; | |
| 881 | |
| 882 if (!targets || !n_targets || max_targets <= 0) | |
| 883 return E_INVALIDARG; | |
| 884 | |
| 885 *n_targets = 0; | |
| 886 base::string16 type(type_bstr); | |
| 887 if (type != L"alerts" || view_->parent()) | |
| 888 return S_OK; | |
| 889 | |
| 890 ViewStorage* view_storage = ViewStorage::GetInstance(); | |
| 891 for (size_t i = 0; i < alert_target_view_storage_ids_.size(); ++i) { | |
| 892 int view_storage_id = alert_target_view_storage_ids_[i]; | |
| 893 View* view = view_storage->RetrieveView(view_storage_id); | |
| 894 if (!view || !view_->Contains(view)) | |
| 895 continue; | |
| 896 | |
| 897 (*targets)[*n_targets] = view->GetNativeViewAccessible(); | |
|
aboxhall
2014/05/07 15:26:30
This will put targets in *targets in chronological
dmazzoni
2014/05/07 15:31:41
I hadn't thought about the order. I'm not even sur
| |
| 898 (*targets)[*n_targets]->AddRef(); | |
| 899 ++(*n_targets); | |
| 900 | |
| 901 if (*n_targets == max_targets) | |
| 902 break; | |
| 903 } | |
| 904 return S_OK; | |
| 905 } | |
| 906 | |
| 868 // | 907 // |
| 869 // IAccessibleText | 908 // IAccessibleText |
| 870 // | 909 // |
| 871 | 910 |
| 872 STDMETHODIMP NativeViewAccessibilityWin::get_nCharacters(LONG* n_characters) { | 911 STDMETHODIMP NativeViewAccessibilityWin::get_nCharacters(LONG* n_characters) { |
| 873 if (!view_) | 912 if (!view_) |
| 874 return E_FAIL; | 913 return E_FAIL; |
| 875 | 914 |
| 876 if (!n_characters) | 915 if (!n_characters) |
| 877 return E_INVALIDARG; | 916 return E_INVALIDARG; |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1064 | 1103 |
| 1065 // | 1104 // |
| 1066 // IServiceProvider methods. | 1105 // IServiceProvider methods. |
| 1067 // | 1106 // |
| 1068 | 1107 |
| 1069 STDMETHODIMP NativeViewAccessibilityWin::QueryService( | 1108 STDMETHODIMP NativeViewAccessibilityWin::QueryService( |
| 1070 REFGUID guidService, REFIID riid, void** object) { | 1109 REFGUID guidService, REFIID riid, void** object) { |
| 1071 if (!view_) | 1110 if (!view_) |
| 1072 return E_FAIL; | 1111 return E_FAIL; |
| 1073 | 1112 |
| 1074 if (riid == IID_IAccessible2) | 1113 if (riid == IID_IAccessible2 || riid == IID_IAccessible2_2) |
| 1075 AccessibleWebViewRegistry::GetInstance()->EnableIAccessible2Support(); | 1114 AccessibleWebViewRegistry::GetInstance()->EnableIAccessible2Support(); |
| 1076 | 1115 |
| 1077 if (guidService == IID_IAccessible || | 1116 if (guidService == IID_IAccessible || |
| 1078 guidService == IID_IAccessible2 || | 1117 guidService == IID_IAccessible2 || |
| 1118 guidService == IID_IAccessible2_2 || | |
| 1079 guidService == IID_IAccessibleText) { | 1119 guidService == IID_IAccessibleText) { |
| 1080 return QueryInterface(riid, object); | 1120 return QueryInterface(riid, object); |
| 1081 } | 1121 } |
| 1082 | 1122 |
| 1083 // We only support the IAccessibleEx interface on Windows 8 and above. This | 1123 // We only support the IAccessibleEx interface on Windows 8 and above. This |
| 1084 // is needed for the On screen Keyboard to show up in metro mode, when the | 1124 // is needed for the On screen Keyboard to show up in metro mode, when the |
| 1085 // user taps an editable region in the window. | 1125 // user taps an editable region in the window. |
| 1086 // All methods in the IAccessibleEx interface are unimplemented. | 1126 // All methods in the IAccessibleEx interface are unimplemented. |
| 1087 if (riid == IID_IAccessibleEx && | 1127 if (riid == IID_IAccessibleEx && |
| 1088 base::win::GetVersion() >= base::win::VERSION_WIN8) { | 1128 base::win::GetVersion() >= base::win::VERSION_WIN8) { |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1405 if (!child_widget->IsVisible()) | 1445 if (!child_widget->IsVisible()) |
| 1406 continue; | 1446 continue; |
| 1407 | 1447 |
| 1408 if (widget->GetNativeWindowProperty(kWidgetNativeViewHostKey)) | 1448 if (widget->GetNativeWindowProperty(kWidgetNativeViewHostKey)) |
| 1409 continue; | 1449 continue; |
| 1410 | 1450 |
| 1411 result_child_widgets->push_back(child_widget); | 1451 result_child_widgets->push_back(child_widget); |
| 1412 } | 1452 } |
| 1413 } | 1453 } |
| 1414 | 1454 |
| 1455 void NativeViewAccessibilityWin::AddAlertTarget() { | |
| 1456 ViewStorage* view_storage = ViewStorage::GetInstance(); | |
| 1457 for (size_t i = 0; i < alert_target_view_storage_ids_.size(); ++i) { | |
| 1458 int view_storage_id = alert_target_view_storage_ids_[i]; | |
| 1459 View* view = view_storage->RetrieveView(view_storage_id); | |
| 1460 if (view == view_) | |
|
aboxhall
2014/05/07 15:26:30
Similarly, do we want to bump up this view in the
| |
| 1461 return; | |
| 1462 } | |
| 1463 int view_storage_id = view_storage->CreateStorageID(); | |
| 1464 view_storage->StoreView(view_storage_id, view_); | |
| 1465 alert_target_view_storage_ids_.push_back(view_storage_id); | |
| 1466 } | |
| 1467 | |
| 1468 void NativeViewAccessibilityWin::RemoveAlertTarget() { | |
| 1469 ViewStorage* view_storage = ViewStorage::GetInstance(); | |
| 1470 size_t i = 0; | |
| 1471 while (i < alert_target_view_storage_ids_.size()) { | |
| 1472 int view_storage_id = alert_target_view_storage_ids_[i]; | |
| 1473 View* view = view_storage->RetrieveView(view_storage_id); | |
| 1474 if (view == NULL || view == view_) { | |
| 1475 alert_target_view_storage_ids_.erase( | |
| 1476 alert_target_view_storage_ids_.begin() + i); | |
|
aboxhall
2014/05/07 15:26:30
Why don't we want to increment i in this case?
dmazzoni
2014/05/07 15:31:41
We're erasing the ith element, which should shift
| |
| 1477 } else { | |
| 1478 ++i; | |
| 1479 } | |
| 1480 } | |
| 1481 } | |
| 1482 | |
| 1415 } // namespace views | 1483 } // namespace views |
| OLD | NEW |