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

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

Issue 23531055: Use IAccessible2 to detect screen reader in Win Aura (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 3 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
« no previous file with comments | « content/browser/accessibility/browser_accessibility_win.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <UIAutomationClient.h> 7 #include <UIAutomationClient.h>
8 #include <oleacc.h> 8 #include <oleacc.h>
9 9
10 #include <set> 10 #include <set>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/memory/singleton.h" 13 #include "base/memory/singleton.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "base/win/scoped_comptr.h"
15 #include "base/win/windows_version.h" 16 #include "base/win/windows_version.h"
16 #include "third_party/iaccessible2/ia2_api_all.h" 17 #include "third_party/iaccessible2/ia2_api_all.h"
17 #include "ui/base/accessibility/accessible_text_utils.h" 18 #include "ui/base/accessibility/accessible_text_utils.h"
18 #include "ui/base/accessibility/accessible_view_state.h" 19 #include "ui/base/accessibility/accessible_view_state.h"
19 #include "ui/base/win/accessibility_ids_win.h" 20 #include "ui/base/win/accessibility_ids_win.h"
20 #include "ui/base/win/accessibility_misc_utils.h" 21 #include "ui/base/win/accessibility_misc_utils.h"
21 #include "ui/base/win/atl_module.h" 22 #include "ui/base/win/atl_module.h"
22 #include "ui/views/controls/button/custom_button.h" 23 #include "ui/views/controls/button/custom_button.h"
23 #include "ui/views/focus/focus_manager.h" 24 #include "ui/views/focus/focus_manager.h"
24 #include "ui/views/focus/view_storage.h" 25 #include "ui/views/focus/view_storage.h"
(...skipping 12 matching lines...) Expand all
37 void RegisterWebView(View* web_view); 38 void RegisterWebView(View* web_view);
38 39
39 void UnregisterWebView(View* web_view); 40 void UnregisterWebView(View* web_view);
40 41
41 // Given the view that received the request for the accessible 42 // Given the view that received the request for the accessible
42 // id in |top_view|, and the child id requested, return the native 43 // id in |top_view|, and the child id requested, return the native
43 // accessible object with that child id from one of the WebViews in 44 // accessible object with that child id from one of the WebViews in
44 // |top_view|'s view hierarchy, if any. 45 // |top_view|'s view hierarchy, if any.
45 IAccessible* GetAccessibleFromWebView(View* top_view, long child_id); 46 IAccessible* GetAccessibleFromWebView(View* top_view, long child_id);
46 47
48 // The system uses IAccessible APIs for many purposes, but only
49 // assistive technology like screen readers uses IAccessible2.
50 // Call this method to note that the IAccessible2 interface was queried and
51 // that WebViews should be proactively notified that this interface will be
52 // used. If this is enabled for the first time, this will explicitly call
53 // QueryService with an argument of IAccessible2 on all WebViews, otherwise
54 // it will just do it from now on.
55 void EnableIAccessible2Support();
56
47 private: 57 private:
48 friend struct DefaultSingletonTraits<AccessibleWebViewRegistry>; 58 friend struct DefaultSingletonTraits<AccessibleWebViewRegistry>;
49 AccessibleWebViewRegistry(); 59 AccessibleWebViewRegistry();
50 ~AccessibleWebViewRegistry() {} 60 ~AccessibleWebViewRegistry() {}
51 61
52 IAccessible* AccessibleObjectFromChildId(View* web_view, long child_id); 62 IAccessible* AccessibleObjectFromChildId(View* web_view, long child_id);
53 63
64 void QueryIAccessible2Interface(View* web_view);
65
54 // Set of all web views. We check whether each one is contained in a 66 // Set of all web views. We check whether each one is contained in a
55 // top view dynamically rather than keeping track of a map. 67 // top view dynamically rather than keeping track of a map.
56 std::set<View*> web_views_; 68 std::set<View*> web_views_;
57 69
58 // The most recent top view used in a call to GetAccessibleFromWebView. 70 // The most recent top view used in a call to GetAccessibleFromWebView.
59 View* last_top_view_; 71 View* last_top_view_;
60 72
61 // The most recent web view where an accessible object was found, 73 // The most recent web view where an accessible object was found,
62 // corresponding to |last_top_view_|. 74 // corresponding to |last_top_view_|.
63 View* last_web_view_; 75 View* last_web_view_;
64 76
77 // If IAccessible2 support is enabled, we query the IAccessible2 interface
78 // of WebViews proactively when they're registered, so that they are
79 // aware that they need to support this interface.
80 bool iaccessible2_support_enabled_;
81
65 DISALLOW_COPY_AND_ASSIGN(AccessibleWebViewRegistry); 82 DISALLOW_COPY_AND_ASSIGN(AccessibleWebViewRegistry);
66 }; 83 };
67 84
68 AccessibleWebViewRegistry::AccessibleWebViewRegistry() 85 AccessibleWebViewRegistry::AccessibleWebViewRegistry()
69 : last_top_view_(NULL), 86 : last_top_view_(NULL),
70 last_web_view_(NULL) { 87 last_web_view_(NULL),
88 iaccessible2_support_enabled_(false) {
71 } 89 }
72 90
73 AccessibleWebViewRegistry* AccessibleWebViewRegistry::GetInstance() { 91 AccessibleWebViewRegistry* AccessibleWebViewRegistry::GetInstance() {
74 return Singleton<AccessibleWebViewRegistry>::get(); 92 return Singleton<AccessibleWebViewRegistry>::get();
75 } 93 }
76 94
77 void AccessibleWebViewRegistry::RegisterWebView(View* web_view) { 95 void AccessibleWebViewRegistry::RegisterWebView(View* web_view) {
78 DCHECK(web_views_.find(web_view) == web_views_.end()); 96 DCHECK(web_views_.find(web_view) == web_views_.end());
79 web_views_.insert(web_view); 97 web_views_.insert(web_view);
98
99 if (iaccessible2_support_enabled_)
100 QueryIAccessible2Interface(web_view);
80 } 101 }
81 102
82 void AccessibleWebViewRegistry::UnregisterWebView(View* web_view) { 103 void AccessibleWebViewRegistry::UnregisterWebView(View* web_view) {
83 DCHECK(web_views_.find(web_view) != web_views_.end()); 104 DCHECK(web_views_.find(web_view) != web_views_.end());
84 web_views_.erase(web_view); 105 web_views_.erase(web_view);
85 if (last_web_view_ == web_view) { 106 if (last_web_view_ == web_view) {
86 last_top_view_ = NULL; 107 last_top_view_ = NULL;
87 last_web_view_ = NULL; 108 last_web_view_ = NULL;
88 } 109 }
89 } 110 }
(...skipping 23 matching lines...) Expand all
113 if (accessible) { 134 if (accessible) {
114 last_top_view_ = top_view; 135 last_top_view_ = top_view;
115 last_web_view_ = web_view; 136 last_web_view_ = web_view;
116 return accessible; 137 return accessible;
117 } 138 }
118 } 139 }
119 140
120 return NULL; 141 return NULL;
121 } 142 }
122 143
144 void AccessibleWebViewRegistry::EnableIAccessible2Support() {
145 if (iaccessible2_support_enabled_)
146 return;
147 iaccessible2_support_enabled_ = true;
148 for (std::set<View*>::iterator iter = web_views_.begin();
149 iter != web_views_.end(); ++iter) {
150 QueryIAccessible2Interface(*iter);
151 }
152 }
153
123 IAccessible* AccessibleWebViewRegistry::AccessibleObjectFromChildId( 154 IAccessible* AccessibleWebViewRegistry::AccessibleObjectFromChildId(
124 View* web_view, 155 View* web_view,
125 long child_id) { 156 long child_id) {
126 IAccessible* web_view_accessible = web_view->GetNativeViewAccessible(); 157 IAccessible* web_view_accessible = web_view->GetNativeViewAccessible();
127 if (web_view_accessible == NULL) 158 if (web_view_accessible == NULL)
128 return NULL; 159 return NULL;
129 160
130 VARIANT var_child; 161 VARIANT var_child;
131 var_child.vt = VT_I4; 162 var_child.vt = VT_I4;
132 var_child.lVal = child_id; 163 var_child.lVal = child_id;
133 IAccessible* result = NULL; 164 IAccessible* result = NULL;
134 if (S_OK == web_view_accessible->get_accChild( 165 if (S_OK == web_view_accessible->get_accChild(
135 var_child, reinterpret_cast<IDispatch**>(&result))) { 166 var_child, reinterpret_cast<IDispatch**>(&result))) {
136 return result; 167 return result;
137 } 168 }
138 169
139 return NULL; 170 return NULL;
140 } 171 }
141 172
173 void AccessibleWebViewRegistry::QueryIAccessible2Interface(View* web_view) {
174 IAccessible* web_view_accessible = web_view->GetNativeViewAccessible();
175 if (!web_view_accessible)
176 return;
177
178 base::win::ScopedComPtr<IServiceProvider> service_provider;
179 if (S_OK != web_view_accessible->QueryInterface(service_provider.Receive()))
180 return;
181 base::win::ScopedComPtr<IAccessible2> iaccessible2;
182 service_provider->QueryService(
183 IID_IAccessible, IID_IAccessible2,
184 reinterpret_cast<void**>(iaccessible2.Receive()));
185 }
186
142 } // anonymous namespace 187 } // anonymous namespace
143 188
144 // static 189 // static
145 long NativeViewAccessibilityWin::next_unique_id_ = 1; 190 long NativeViewAccessibilityWin::next_unique_id_ = 1;
146 int NativeViewAccessibilityWin::view_storage_ids_[kMaxViewStorageIds] = {0}; 191 int NativeViewAccessibilityWin::view_storage_ids_[kMaxViewStorageIds] = {0};
147 int NativeViewAccessibilityWin::next_view_storage_id_index_ = 0; 192 int NativeViewAccessibilityWin::next_view_storage_id_index_ = 0;
148 193
149 // static 194 // static
150 NativeViewAccessibility* NativeViewAccessibility::Create(View* view) { 195 NativeViewAccessibility* NativeViewAccessibility::Create(View* view) {
151 // Make sure ATL is initialized in this module. 196 // Make sure ATL is initialized in this module.
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 1064
1020 // 1065 //
1021 // IServiceProvider methods. 1066 // IServiceProvider methods.
1022 // 1067 //
1023 1068
1024 STDMETHODIMP NativeViewAccessibilityWin::QueryService( 1069 STDMETHODIMP NativeViewAccessibilityWin::QueryService(
1025 REFGUID guidService, REFIID riid, void** object) { 1070 REFGUID guidService, REFIID riid, void** object) {
1026 if (!view_) 1071 if (!view_)
1027 return E_FAIL; 1072 return E_FAIL;
1028 1073
1074 if (riid == IID_IAccessible2)
1075 AccessibleWebViewRegistry::GetInstance()->EnableIAccessible2Support();
1076
1029 if (guidService == IID_IAccessible || 1077 if (guidService == IID_IAccessible ||
1030 guidService == IID_IAccessible2 || 1078 guidService == IID_IAccessible2 ||
1031 guidService == IID_IAccessibleText) { 1079 guidService == IID_IAccessibleText) {
1032 return QueryInterface(riid, object); 1080 return QueryInterface(riid, object);
1033 } 1081 }
1034 1082
1035 // We only support the IAccessibleEx interface on Windows 8 and above. This 1083 // We only support the IAccessibleEx interface on Windows 8 and above. This
1036 // is needed for the On screen Keyboard to show up in metro mode, when the 1084 // is needed for the On screen Keyboard to show up in metro mode, when the
1037 // user taps an editable region in the window. 1085 // user taps an editable region in the window.
1038 // All methods in the IAccessibleEx interface are unimplemented. 1086 // All methods in the IAccessibleEx interface are unimplemented.
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 continue; 1405 continue;
1358 1406
1359 if (widget->GetNativeWindowProperty(kWidgetNativeViewHostKey)) 1407 if (widget->GetNativeWindowProperty(kWidgetNativeViewHostKey))
1360 continue; 1408 continue;
1361 1409
1362 result_child_widgets->push_back(child_widget); 1410 result_child_widgets->push_back(child_widget);
1363 } 1411 }
1364 } 1412 }
1365 1413
1366 } // namespace views 1414 } // namespace views
OLDNEW
« no previous file with comments | « content/browser/accessibility/browser_accessibility_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698