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

Side by Side Diff: ui/accessibility/platform/ax_platform_node_win.cc

Issue 1762143002: Use unique IDs for accessibility nodes on Android (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix null obj deref in DCHECK Created 4 years, 9 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 | « ui/accessibility/platform/ax_platform_node_win.h ('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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 <atlbase.h> 5 #include <atlbase.h>
6 #include <atlcom.h> 6 #include <atlcom.h>
7 #include <limits.h> 7 #include <limits.h>
8 #include <oleacc.h> 8 #include <oleacc.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 if (!IsValidId(var_id)) return E_INVALIDARG; \ 71 if (!IsValidId(var_id)) return E_INVALIDARG; \
72 if (!arg1) return E_INVALIDARG; \ 72 if (!arg1) return E_INVALIDARG; \
73 if (!arg2) return E_INVALIDARG; \ 73 if (!arg2) return E_INVALIDARG; \
74 if (!arg3) return E_INVALIDARG; \ 74 if (!arg3) return E_INVALIDARG; \
75 if (!arg4) return E_INVALIDARG 75 if (!arg4) return E_INVALIDARG
76 76
77 namespace ui { 77 namespace ui {
78 78
79 namespace { 79 namespace {
80 80
81 typedef base::hash_map<LONG, AXPlatformNodeWin*> UniqueIdWinMap;
82 // Map from each AXPlatformNodeWin's unique id to its instance.
83 base::LazyInstance<UniqueIdWinMap> g_unique_id_win_map =
84 LAZY_INSTANCE_INITIALIZER;
85
86 typedef base::hash_set<AXPlatformNodeWin*> AXPlatformNodeWinSet; 81 typedef base::hash_set<AXPlatformNodeWin*> AXPlatformNodeWinSet;
87 // Set of all AXPlatformNodeWin objects that were the target of an 82 // Set of all AXPlatformNodeWin objects that were the target of an
88 // alert event. 83 // alert event.
89 base::LazyInstance<AXPlatformNodeWinSet> g_alert_targets = 84 base::LazyInstance<AXPlatformNodeWinSet> g_alert_targets =
90 LAZY_INSTANCE_INITIALIZER; 85 LAZY_INSTANCE_INITIALIZER;
91 86
92 LONG GetNextNegativeUniqueIdForWinAccessibility(AXPlatformNodeWin* obj) {
93 static LONG next_unique_id = -1;
94 LONG unique_id = next_unique_id;
95 if (next_unique_id == LONG_MIN)
96 next_unique_id = -1;
97 else
98 next_unique_id--;
99
100 g_unique_id_win_map.Get().insert(std::make_pair(unique_id, obj));
101
102 return unique_id;
103 }
104
105 void UnregisterNegativeUniqueId(LONG unique_id) {
106 g_unique_id_win_map.Get().erase(unique_id);
107 }
108
109 base::LazyInstance<base::ObserverList<IAccessible2UsageObserver>> 87 base::LazyInstance<base::ObserverList<IAccessible2UsageObserver>>
110 g_iaccessible2_usage_observer_list = LAZY_INSTANCE_INITIALIZER; 88 g_iaccessible2_usage_observer_list = LAZY_INSTANCE_INITIALIZER;
111 89
112 } // namespace 90 } // namespace
113 91
114 // 92 //
115 // IAccessible2UsageObserver 93 // IAccessible2UsageObserver
116 // 94 //
117 95
118 IAccessible2UsageObserver::IAccessible2UsageObserver() { 96 IAccessible2UsageObserver::IAccessible2UsageObserver() {
(...skipping 30 matching lines...) Expand all
149 gfx::NativeViewAccessible accessible) { 127 gfx::NativeViewAccessible accessible) {
150 base::win::ScopedComPtr<AXPlatformNodeWin> ax_platform_node; 128 base::win::ScopedComPtr<AXPlatformNodeWin> ax_platform_node;
151 accessible->QueryInterface(ax_platform_node.Receive()); 129 accessible->QueryInterface(ax_platform_node.Receive());
152 return ax_platform_node.get(); 130 return ax_platform_node.get();
153 } 131 }
154 132
155 // 133 //
156 // AXPlatformNodeWin 134 // AXPlatformNodeWin
157 // 135 //
158 136
159 AXPlatformNodeWin::AXPlatformNodeWin() 137 AXPlatformNodeWin::AXPlatformNodeWin() {
160 : unique_id_win_(GetNextNegativeUniqueIdForWinAccessibility(this)) {
161 } 138 }
162 139
163 AXPlatformNodeWin::~AXPlatformNodeWin() { 140 AXPlatformNodeWin::~AXPlatformNodeWin() {
164 CHECK(!delegate_); 141 CHECK(!delegate_);
165 } 142 }
166 143
167 // 144 //
168 // AXPlatformNode implementation. 145 // AXPlatformNode implementation.
169 // 146 //
170 147
171 void AXPlatformNodeWin::Destroy() { 148 void AXPlatformNodeWin::Destroy() {
172 delegate_ = nullptr; 149 delegate_ = nullptr;
173 UnregisterNegativeUniqueId(unique_id_win_);
174 RemoveAlertTarget(); 150 RemoveAlertTarget();
175 Release(); 151 Release();
176 } 152 }
177 153
178 gfx::NativeViewAccessible AXPlatformNodeWin::GetNativeViewAccessible() { 154 gfx::NativeViewAccessible AXPlatformNodeWin::GetNativeViewAccessible() {
179 return this; 155 return this;
180 } 156 }
181 157
182 void AXPlatformNodeWin::NotifyAccessibilityEvent(ui::AXEvent event_type) { 158 void AXPlatformNodeWin::NotifyAccessibilityEvent(ui::AXEvent event_type) {
183 HWND hwnd = delegate_->GetTargetForNativeAccessibilityEvent(); 159 HWND hwnd = delegate_->GetTargetForNativeAccessibilityEvent();
184 if (!hwnd) 160 if (!hwnd)
185 return; 161 return;
186 162
187 // Menu items fire selection events but Windows screen readers work reliably 163 // Menu items fire selection events but Windows screen readers work reliably
188 // with focus events. Remap here. 164 // with focus events. Remap here.
189 if (event_type == ui::AX_EVENT_SELECTION && 165 if (event_type == ui::AX_EVENT_SELECTION &&
190 GetData().role == ui::AX_ROLE_MENU_ITEM) 166 GetData().role == ui::AX_ROLE_MENU_ITEM)
191 event_type = ui::AX_EVENT_FOCUS; 167 event_type = ui::AX_EVENT_FOCUS;
192 168
193 int native_event = MSAAEvent(event_type); 169 int native_event = MSAAEvent(event_type);
194 if (native_event < EVENT_MIN) 170 if (native_event < EVENT_MIN)
195 return; 171 return;
196 172
197 ::NotifyWinEvent(native_event, hwnd, OBJID_CLIENT, unique_id_win_); 173 ::NotifyWinEvent(native_event, hwnd, OBJID_CLIENT, -unique_id_);
198 174
199 // Keep track of objects that are a target of an alert event. 175 // Keep track of objects that are a target of an alert event.
200 if (event_type == ui::AX_EVENT_ALERT) 176 if (event_type == ui::AX_EVENT_ALERT)
201 AddAlertTarget(); 177 AddAlertTarget();
202 } 178 }
203 179
204 int AXPlatformNodeWin::GetIndexInParent() { 180 int AXPlatformNodeWin::GetIndexInParent() {
205 base::win::ScopedComPtr<IDispatch> parent_dispatch; 181 base::win::ScopedComPtr<IDispatch> parent_dispatch;
206 base::win::ScopedComPtr<IAccessible> parent_accessible; 182 base::win::ScopedComPtr<IAccessible> parent_accessible;
207 if (S_OK != get_accParent(parent_dispatch.Receive())) 183 if (S_OK != get_accParent(parent_dispatch.Receive()))
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 if (!(*disp_child)) 335 if (!(*disp_child))
360 return E_FAIL; 336 return E_FAIL;
361 (*disp_child)->AddRef(); 337 (*disp_child)->AddRef();
362 return S_OK; 338 return S_OK;
363 } 339 }
364 340
365 if (child_id >= 0) 341 if (child_id >= 0)
366 return E_FAIL; 342 return E_FAIL;
367 343
368 // Negative child ids can be used to map to any descendant. 344 // Negative child ids can be used to map to any descendant.
369 UniqueIdWinMap* unique_ids = g_unique_id_win_map.Pointer(); 345 AXPlatformNodeWin* child = static_cast<AXPlatformNodeWin*>(
370 auto iter = unique_ids->find(child_id); 346 GetFromUniqueId(-child_id));
371 if (iter != unique_ids->end()) { 347 if (child) {
372 *disp_child = iter->second; 348 *disp_child = child;
373 (*disp_child)->AddRef(); 349 (*disp_child)->AddRef();
374 return S_OK; 350 return S_OK;
375 } 351 }
376 352
377 *disp_child = nullptr; 353 *disp_child = nullptr;
378 return E_FAIL; 354 return E_FAIL;
379 } 355 }
380 356
381 STDMETHODIMP AXPlatformNodeWin::get_accChildCount(LONG* child_count) { 357 STDMETHODIMP AXPlatformNodeWin::get_accChildCount(LONG* child_count) {
382 COM_OBJECT_VALIDATE_1_ARG(child_count); 358 COM_OBJECT_VALIDATE_1_ARG(child_count);
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 // add a helper function like MSAAState. 500 // add a helper function like MSAAState.
525 *states = IA2_STATE_OPAQUE; 501 *states = IA2_STATE_OPAQUE;
526 if (GetData().state & (1 << ui::AX_STATE_EDITABLE)) 502 if (GetData().state & (1 << ui::AX_STATE_EDITABLE))
527 *states |= IA2_STATE_EDITABLE; 503 *states |= IA2_STATE_EDITABLE;
528 504
529 return S_OK; 505 return S_OK;
530 } 506 }
531 507
532 STDMETHODIMP AXPlatformNodeWin::get_uniqueID(LONG* unique_id) { 508 STDMETHODIMP AXPlatformNodeWin::get_uniqueID(LONG* unique_id) {
533 COM_OBJECT_VALIDATE_1_ARG(unique_id); 509 COM_OBJECT_VALIDATE_1_ARG(unique_id);
534 *unique_id = unique_id_win_; 510 *unique_id = -unique_id_;
535 return S_OK; 511 return S_OK;
536 } 512 }
537 513
538 STDMETHODIMP AXPlatformNodeWin::get_windowHandle(HWND* window_handle) { 514 STDMETHODIMP AXPlatformNodeWin::get_windowHandle(HWND* window_handle) {
539 COM_OBJECT_VALIDATE_1_ARG(window_handle); 515 COM_OBJECT_VALIDATE_1_ARG(window_handle);
540 *window_handle = delegate_->GetTargetForNativeAccessibilityEvent(); 516 *window_handle = delegate_->GetTargetForNativeAccessibilityEvent();
541 return *window_handle ? S_OK : S_FALSE; 517 return *window_handle ? S_OK : S_FALSE;
542 } 518 }
543 519
544 STDMETHODIMP AXPlatformNodeWin::get_relationTargetsOfType( 520 STDMETHODIMP AXPlatformNodeWin::get_relationTargetsOfType(
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
1151 LONG start_offset, 1127 LONG start_offset,
1152 ui::TextBoundaryDirection direction) { 1128 ui::TextBoundaryDirection direction) {
1153 HandleSpecialTextOffset(text, &start_offset); 1129 HandleSpecialTextOffset(text, &start_offset);
1154 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary); 1130 ui::TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary);
1155 std::vector<int32_t> line_breaks; 1131 std::vector<int32_t> line_breaks;
1156 return static_cast<LONG>(ui::FindAccessibleTextBoundary( 1132 return static_cast<LONG>(ui::FindAccessibleTextBoundary(
1157 text, line_breaks, boundary, start_offset, direction)); 1133 text, line_breaks, boundary, start_offset, direction));
1158 } 1134 }
1159 1135
1160 } // namespace ui 1136 } // namespace ui
OLDNEW
« no previous file with comments | « ui/accessibility/platform/ax_platform_node_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698