Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: ui/views/accessibility/native_view_accessibility_win.cc

Issue 266963002: Expose an accessible relation between the main window and active alert. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ia2_1-3
Patch Set: Address feedback Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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)
883 return E_INVALIDARG;
884
885 *n_targets = 0;
886 *targets = NULL;
887
888 // Only respond to requests for relations of type "alerts" on the
889 // root view.
890 base::string16 type(type_bstr);
891 if (type != L"alerts" || view_->parent())
892 return S_FALSE;
893
894 // Collect all of the alert views that are still valid.
895 std::vector<View*> alert_views;
896 ViewStorage* view_storage = ViewStorage::GetInstance();
897 for (size_t i = 0; i < alert_target_view_storage_ids_.size(); ++i) {
898 int view_storage_id = alert_target_view_storage_ids_[i];
899 View* view = view_storage->RetrieveView(view_storage_id);
900 if (!view || !view_->Contains(view))
901 continue;
902 alert_views.push_back(view);
903 }
904
905 long count = alert_views.size();
906 if (count == 0)
907 return S_FALSE;
908
909 // Don't return more targets than max_targets - but note that the caller
910 // is allowed to specify max_targets=0 to mean no limit.
911 if (max_targets > 0 && count > max_targets)
912 count = max_targets;
913
914 // Return the number of targets.
915 *n_targets = count;
916
917 // Allocate COM memory for the result array and populate it.
918 *targets = static_cast<IUnknown**>(
919 CoTaskMemAlloc(count * sizeof(IUnknown*)));
920 for (long i = 0; i < count; ++i) {
921 (*targets)[i] = alert_views[i]->GetNativeViewAccessible();
922 (*targets)[i]->AddRef();
923 }
924 return S_OK;
925 }
926
868 // 927 //
869 // IAccessibleText 928 // IAccessibleText
870 // 929 //
871 930
872 STDMETHODIMP NativeViewAccessibilityWin::get_nCharacters(LONG* n_characters) { 931 STDMETHODIMP NativeViewAccessibilityWin::get_nCharacters(LONG* n_characters) {
873 if (!view_) 932 if (!view_)
874 return E_FAIL; 933 return E_FAIL;
875 934
876 if (!n_characters) 935 if (!n_characters)
877 return E_INVALIDARG; 936 return E_INVALIDARG;
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 1123
1065 // 1124 //
1066 // IServiceProvider methods. 1125 // IServiceProvider methods.
1067 // 1126 //
1068 1127
1069 STDMETHODIMP NativeViewAccessibilityWin::QueryService( 1128 STDMETHODIMP NativeViewAccessibilityWin::QueryService(
1070 REFGUID guidService, REFIID riid, void** object) { 1129 REFGUID guidService, REFIID riid, void** object) {
1071 if (!view_) 1130 if (!view_)
1072 return E_FAIL; 1131 return E_FAIL;
1073 1132
1074 if (riid == IID_IAccessible2) 1133 if (riid == IID_IAccessible2 || riid == IID_IAccessible2_2)
1075 AccessibleWebViewRegistry::GetInstance()->EnableIAccessible2Support(); 1134 AccessibleWebViewRegistry::GetInstance()->EnableIAccessible2Support();
1076 1135
1077 if (guidService == IID_IAccessible || 1136 if (guidService == IID_IAccessible ||
1078 guidService == IID_IAccessible2 || 1137 guidService == IID_IAccessible2 ||
1138 guidService == IID_IAccessible2_2 ||
1079 guidService == IID_IAccessibleText) { 1139 guidService == IID_IAccessibleText) {
1080 return QueryInterface(riid, object); 1140 return QueryInterface(riid, object);
1081 } 1141 }
1082 1142
1083 // We only support the IAccessibleEx interface on Windows 8 and above. This 1143 // 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 1144 // is needed for the On screen Keyboard to show up in metro mode, when the
1085 // user taps an editable region in the window. 1145 // user taps an editable region in the window.
1086 // All methods in the IAccessibleEx interface are unimplemented. 1146 // All methods in the IAccessibleEx interface are unimplemented.
1087 if (riid == IID_IAccessibleEx && 1147 if (riid == IID_IAccessibleEx &&
1088 base::win::GetVersion() >= base::win::VERSION_WIN8) { 1148 base::win::GetVersion() >= base::win::VERSION_WIN8) {
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 if (!child_widget->IsVisible()) 1465 if (!child_widget->IsVisible())
1406 continue; 1466 continue;
1407 1467
1408 if (widget->GetNativeWindowProperty(kWidgetNativeViewHostKey)) 1468 if (widget->GetNativeWindowProperty(kWidgetNativeViewHostKey))
1409 continue; 1469 continue;
1410 1470
1411 result_child_widgets->push_back(child_widget); 1471 result_child_widgets->push_back(child_widget);
1412 } 1472 }
1413 } 1473 }
1414 1474
1475 void NativeViewAccessibilityWin::AddAlertTarget() {
1476 ViewStorage* view_storage = ViewStorage::GetInstance();
1477 for (size_t i = 0; i < alert_target_view_storage_ids_.size(); ++i) {
1478 int view_storage_id = alert_target_view_storage_ids_[i];
1479 View* view = view_storage->RetrieveView(view_storage_id);
1480 if (view == view_)
1481 return;
1482 }
1483 int view_storage_id = view_storage->CreateStorageID();
1484 view_storage->StoreView(view_storage_id, view_);
1485 alert_target_view_storage_ids_.push_back(view_storage_id);
1486 }
1487
1488 void NativeViewAccessibilityWin::RemoveAlertTarget() {
1489 ViewStorage* view_storage = ViewStorage::GetInstance();
1490 size_t i = 0;
1491 while (i < alert_target_view_storage_ids_.size()) {
1492 int view_storage_id = alert_target_view_storage_ids_[i];
1493 View* view = view_storage->RetrieveView(view_storage_id);
1494 if (view == NULL || view == view_) {
1495 alert_target_view_storage_ids_.erase(
1496 alert_target_view_storage_ids_.begin() + i);
1497 } else {
1498 ++i;
1499 }
1500 }
1501 }
1502
1415 } // namespace views 1503 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698