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

Side by Side Diff: content/browser/accessibility/browser_accessibility_manager.cc

Issue 1925473002: Add verbose logging for native accessibility events. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@load_complete
Patch Set: address all feedback Created 4 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 "content/browser/accessibility/browser_accessibility_manager.h" 5 #include "content/browser/accessibility/browser_accessibility_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 ui::AXTreeUpdate 176 ui::AXTreeUpdate
177 BrowserAccessibilityManager::GetEmptyDocument() { 177 BrowserAccessibilityManager::GetEmptyDocument() {
178 ui::AXNodeData empty_document; 178 ui::AXNodeData empty_document;
179 empty_document.id = 0; 179 empty_document.id = 0;
180 empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA; 180 empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA;
181 ui::AXTreeUpdate update; 181 ui::AXTreeUpdate update;
182 update.nodes.push_back(empty_document); 182 update.nodes.push_back(empty_document);
183 return update; 183 return update;
184 } 184 }
185 185
186 void BrowserAccessibilityManager::FireFocusEventsIfNeeded() { 186 void BrowserAccessibilityManager::NotifyAccessibilityEvent(
187 BrowserAccessibilityEvent::Source source,
188 ui::AXEvent event_type,
189 BrowserAccessibility* node) {
190 BrowserAccessibilityEvent::Create(source, event_type, node)->Fire();
191 }
192
193 void BrowserAccessibilityManager::FireFocusEventsIfNeeded(
194 BrowserAccessibilityEvent::Source source) {
187 BrowserAccessibility* focus = GetFocus(); 195 BrowserAccessibility* focus = GetFocus();
188 196
189 // Don't fire focus events if the window itself doesn't have focus. 197 // Don't fire focus events if the window itself doesn't have focus.
190 // Bypass this check if a global focus listener was set up for testing 198 // Bypass this check if a global focus listener was set up for testing
191 // so that the test passes whether the window is active or not. 199 // so that the test passes whether the window is active or not.
192 if (!g_focus_change_callback_for_testing.Pointer()) { 200 if (!g_focus_change_callback_for_testing.Pointer()) {
193 if (delegate_ && !delegate_->AccessibilityViewHasFocus()) 201 if (delegate_ && !delegate_->AccessibilityViewHasFocus())
194 focus = nullptr; 202 focus = nullptr;
195 203
196 if (!CanFireEvents()) 204 if (!CanFireEvents())
197 focus = nullptr; 205 focus = nullptr;
198 } 206 }
199 207
200 // Don't allow the document to be focused if it has no children and 208 // Don't allow the document to be focused if it has no children and
201 // hasn't finished loading yet. Wait for at least a tiny bit of content, 209 // hasn't finished loading yet. Wait for at least a tiny bit of content,
202 // or for the document to actually finish loading. 210 // or for the document to actually finish loading.
203 if (focus && 211 if (focus &&
204 focus == focus->manager()->GetRoot() && 212 focus == focus->manager()->GetRoot() &&
205 focus->PlatformChildCount() == 0 && 213 focus->PlatformChildCount() == 0 &&
206 !focus->HasState(ui::AX_STATE_BUSY) && 214 !focus->HasState(ui::AX_STATE_BUSY) &&
207 !focus->manager()->GetTreeData().loaded) { 215 !focus->manager()->GetTreeData().loaded) {
208 focus = nullptr; 216 focus = nullptr;
209 } 217 }
210 218
211 if (focus && focus != last_focused_node_) 219 if (focus && focus != last_focused_node_)
212 FireFocusEvent(focus); 220 FireFocusEvent(source, focus);
213 221
214 last_focused_node_ = focus; 222 last_focused_node_ = focus;
215 last_focused_manager_ = focus ? focus->manager() : nullptr; 223 last_focused_manager_ = focus ? focus->manager() : nullptr;
216 } 224 }
217 225
218 bool BrowserAccessibilityManager::CanFireEvents() { 226 bool BrowserAccessibilityManager::CanFireEvents() {
219 return true; 227 return true;
220 } 228 }
221 229
222 void BrowserAccessibilityManager::FireFocusEvent(BrowserAccessibility* node) { 230 void BrowserAccessibilityManager::FireFocusEvent(
223 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, node); 231 BrowserAccessibilityEvent::Source source,
232 BrowserAccessibility* node) {
233 NotifyAccessibilityEvent(source, ui::AX_EVENT_FOCUS, node);
224 234
225 if (!g_focus_change_callback_for_testing.Get().is_null()) 235 if (!g_focus_change_callback_for_testing.Get().is_null())
226 g_focus_change_callback_for_testing.Get().Run(); 236 g_focus_change_callback_for_testing.Get().Run();
227 } 237 }
228 238
229 BrowserAccessibility* BrowserAccessibilityManager::GetRoot() { 239 BrowserAccessibility* BrowserAccessibilityManager::GetRoot() {
230 // tree_ can be null during destruction. 240 // tree_ can be null during destruction.
231 if (!tree_) 241 if (!tree_)
232 return nullptr; 242 return nullptr;
233 243
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 295
286 return nullptr; 296 return nullptr;
287 } 297 }
288 298
289 const ui::AXTreeData& BrowserAccessibilityManager::GetTreeData() { 299 const ui::AXTreeData& BrowserAccessibilityManager::GetTreeData() {
290 return tree_->data(); 300 return tree_->data();
291 } 301 }
292 302
293 void BrowserAccessibilityManager::OnWindowFocused() { 303 void BrowserAccessibilityManager::OnWindowFocused() {
294 if (this == GetRootManager()) 304 if (this == GetRootManager())
295 FireFocusEventsIfNeeded(); 305 FireFocusEventsIfNeeded(BrowserAccessibilityEvent::FromWindowFocusChange);
296 } 306 }
297 307
298 void BrowserAccessibilityManager::OnWindowBlurred() { 308 void BrowserAccessibilityManager::OnWindowBlurred() {
299 if (this == GetRootManager()) { 309 if (this == GetRootManager()) {
300 last_focused_node_ = nullptr; 310 last_focused_node_ = nullptr;
301 last_focused_manager_ = nullptr; 311 last_focused_manager_ = nullptr;
302 } 312 }
303 } 313 }
304 314
305 void BrowserAccessibilityManager::UserIsNavigatingAway() { 315 void BrowserAccessibilityManager::UserIsNavigatingAway() {
306 user_is_navigating_away_ = true; 316 user_is_navigating_away_ = true;
307 } 317 }
308 318
309 void BrowserAccessibilityManager::UserIsReloading() { 319 void BrowserAccessibilityManager::UserIsReloading() {
310 user_is_navigating_away_ = true; 320 user_is_navigating_away_ = true;
311 } 321 }
312 322
313 void BrowserAccessibilityManager::NavigationSucceeded() { 323 void BrowserAccessibilityManager::NavigationSucceeded() {
314 user_is_navigating_away_ = false; 324 user_is_navigating_away_ = false;
315 } 325 }
316 326
317 void BrowserAccessibilityManager::NavigationFailed() { 327 void BrowserAccessibilityManager::NavigationFailed() {
318 user_is_navigating_away_ = false; 328 user_is_navigating_away_ = false;
319 } 329 }
320 330
321 void BrowserAccessibilityManager::GotMouseDown() {
322 BrowserAccessibility* focus = GetFocus();
323 if (!focus)
324 return;
325
326 osk_state_ = OSK_ALLOWED_WITHIN_FOCUSED_OBJECT;
327 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, focus);
328 }
329
330 bool BrowserAccessibilityManager::UseRootScrollOffsetsWhenComputingBounds() { 331 bool BrowserAccessibilityManager::UseRootScrollOffsetsWhenComputingBounds() {
331 return true; 332 return true;
332 } 333 }
333 334
334 void BrowserAccessibilityManager::OnAccessibilityEvents( 335 void BrowserAccessibilityManager::OnAccessibilityEvents(
335 const std::vector<AXEventNotificationDetails>& details) { 336 const std::vector<AXEventNotificationDetails>& details) {
336 // Process all changes to the accessibility tree first. 337 // Process all changes to the accessibility tree first.
337 for (uint32_t index = 0; index < details.size(); ++index) { 338 for (uint32_t index = 0; index < details.size(); ++index) {
338 const AXEventNotificationDetails& detail = details[index]; 339 const AXEventNotificationDetails& detail = details[index];
339 if (!tree_->Unserialize(detail.update)) { 340 if (!tree_->Unserialize(detail.update)) {
340 if (delegate_) { 341 if (delegate_) {
341 LOG(ERROR) << tree_->error(); 342 LOG(ERROR) << tree_->error();
342 delegate_->AccessibilityFatalError(); 343 delegate_->AccessibilityFatalError();
343 } else { 344 } else {
344 CHECK(false) << tree_->error(); 345 CHECK(false) << tree_->error();
345 } 346 }
346 return; 347 return;
347 } 348 }
348 } 349 }
349 350
350 // If the root's parent is in another accessibility tree but it wasn't 351 // If the root's parent is in another accessibility tree but it wasn't
351 // previously connected, post the proper notifications on the parent. 352 // previously connected, post the proper notifications on the parent.
352 BrowserAccessibility* parent = GetParentNodeFromParentTree(); 353 BrowserAccessibility* parent = GetParentNodeFromParentTree();
353 if (parent) { 354 if (parent) {
354 if (!connected_to_parent_tree_node_) { 355 if (!connected_to_parent_tree_node_) {
355 parent->OnDataChanged(); 356 parent->OnDataChanged();
356 parent->UpdatePlatformAttributes(); 357 parent->UpdatePlatformAttributes();
357 parent->manager()->NotifyAccessibilityEvent( 358 NotifyAccessibilityEvent(
358 ui::AX_EVENT_CHILDREN_CHANGED, parent); 359 BrowserAccessibilityEvent::FromChildFrameLoading,
360 ui::AX_EVENT_CHILDREN_CHANGED,
361 parent);
359 connected_to_parent_tree_node_ = true; 362 connected_to_parent_tree_node_ = true;
360 } 363 }
361 } else { 364 } else {
362 connected_to_parent_tree_node_ = false; 365 connected_to_parent_tree_node_ = false;
363 } 366 }
364 367
365 // Based on the changes to the tree, first fire focus events if needed. 368 // Based on the changes to the tree, first fire focus events if needed.
366 // Screen readers might not do the right thing if they're not aware of what 369 // Screen readers might not do the right thing if they're not aware of what
367 // has focus, so always try that first. Nothing will be fired if the window 370 // has focus, so always try that first. Nothing will be fired if the window
368 // itself isn't focused or if focus hasn't changed. 371 // itself isn't focused or if focus hasn't changed.
369 GetRootManager()->FireFocusEventsIfNeeded(); 372 GetRootManager()->FireFocusEventsIfNeeded(
373 BrowserAccessibilityEvent::FromBlink);
370 374
371 // Now iterate over the events again and fire the events other than focus 375 // Now iterate over the events again and fire the events other than focus
372 // events. 376 // events.
373 for (uint32_t index = 0; index < details.size(); index++) { 377 for (uint32_t index = 0; index < details.size(); index++) {
374 const AXEventNotificationDetails& detail = details[index]; 378 const AXEventNotificationDetails& detail = details[index];
375 379
376 // Find the node corresponding to the id that's the target of the 380 // Find the node corresponding to the id that's the target of the
377 // event (which may not be the root of the update tree). 381 // event (which may not be the root of the update tree).
378 ui::AXNode* node = tree_->GetFromId(detail.id); 382 ui::AXNode* node = tree_->GetFromId(detail.id);
379 if (!node) 383 if (!node)
(...skipping 11 matching lines...) Expand all
391 395
392 // Skip all focus events other than ones on menu list options; 396 // Skip all focus events other than ones on menu list options;
393 // we've already handled them, above. Menu list options are a weird 397 // we've already handled them, above. Menu list options are a weird
394 // exception because the menu list itself has focus but we need to fire 398 // exception because the menu list itself has focus but we need to fire
395 // focus events on the individual options. 399 // focus events on the individual options.
396 if (!is_menu_list_option) 400 if (!is_menu_list_option)
397 continue; 401 continue;
398 } 402 }
399 403
400 // Fire the native event. 404 // Fire the native event.
401 NotifyAccessibilityEvent(event_type, GetFromAXNode(node)); 405 BrowserAccessibility* event_target = GetFromAXNode(node);
406 if (event_target) {
407 NotifyAccessibilityEvent(
408 BrowserAccessibilityEvent::FromBlink,
409 event_type,
410 event_target);
411 }
402 } 412 }
403 } 413 }
404 414
405 void BrowserAccessibilityManager::OnLocationChanges( 415 void BrowserAccessibilityManager::OnLocationChanges(
406 const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) { 416 const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) {
407 for (size_t i = 0; i < params.size(); ++i) { 417 for (size_t i = 0; i < params.size(); ++i) {
408 BrowserAccessibility* obj = GetFromID(params[i].id); 418 BrowserAccessibility* obj = GetFromID(params[i].id);
409 if (!obj) 419 if (!obj)
410 continue; 420 continue;
411 ui::AXNode* node = obj->node(); 421 ui::AXNode* node = obj->node();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 // If an ancestor of this node is a leaf node, fire the notification on that. 476 // If an ancestor of this node is a leaf node, fire the notification on that.
467 BrowserAccessibility* ancestor = node->GetParent(); 477 BrowserAccessibility* ancestor = node->GetParent();
468 while (ancestor && ancestor != GetRoot()) { 478 while (ancestor && ancestor != GetRoot()) {
469 if (ancestor->PlatformIsLeaf()) 479 if (ancestor->PlatformIsLeaf())
470 node = ancestor; 480 node = ancestor;
471 ancestor = ancestor->GetParent(); 481 ancestor = ancestor->GetParent();
472 } 482 }
473 483
474 // The "scrolled to anchor" notification is a great way to get a 484 // The "scrolled to anchor" notification is a great way to get a
475 // screen reader to jump directly to a specific location in a document. 485 // screen reader to jump directly to a specific location in a document.
476 NotifyAccessibilityEvent(ui::AX_EVENT_SCROLLED_TO_ANCHOR, node); 486 NotifyAccessibilityEvent(
487 BrowserAccessibilityEvent::FromFindInPageResult,
488 ui::AX_EVENT_SCROLLED_TO_ANCHOR,
489 node);
477 } 490 }
478 491
479 BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendantFocus( 492 BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendantFocus(
480 BrowserAccessibility* focus) { 493 BrowserAccessibility* focus) {
481 if (!focus) 494 if (!focus)
482 return NULL; 495 return NULL;
483 496
484 int active_descendant_id; 497 int active_descendant_id;
485 if (focus->GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, 498 if (focus->GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID,
486 &active_descendant_id)) { 499 &active_descendant_id)) {
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 tree_source(tree_->CreateTreeSource()); 889 tree_source(tree_->CreateTreeSource());
877 ui::AXTreeSerializer<const ui::AXNode*, 890 ui::AXTreeSerializer<const ui::AXNode*,
878 ui::AXNodeData, 891 ui::AXNodeData,
879 ui::AXTreeData> serializer(tree_source.get()); 892 ui::AXTreeData> serializer(tree_source.get());
880 ui::AXTreeUpdate update; 893 ui::AXTreeUpdate update;
881 serializer.SerializeChanges(tree_->root(), &update); 894 serializer.SerializeChanges(tree_->root(), &update);
882 return update; 895 return update;
883 } 896 }
884 897
885 } // namespace content 898 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698