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

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

Issue 1706353002: Added the selected text marker range to the dictionary for the selection change notification (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merged with dmazzoni's change to GetFocus. Created 4 years, 10 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 auto iter = ax_tree_id_map->find(ax_tree_id); 116 auto iter = ax_tree_id_map->find(ax_tree_id);
117 return iter == ax_tree_id_map->end() ? nullptr : iter->second; 117 return iter == ax_tree_id_map->end() ? nullptr : iter->second;
118 } 118 }
119 119
120 BrowserAccessibilityManager::BrowserAccessibilityManager( 120 BrowserAccessibilityManager::BrowserAccessibilityManager(
121 BrowserAccessibilityDelegate* delegate, 121 BrowserAccessibilityDelegate* delegate,
122 BrowserAccessibilityFactory* factory) 122 BrowserAccessibilityFactory* factory)
123 : delegate_(delegate), 123 : delegate_(delegate),
124 factory_(factory), 124 factory_(factory),
125 tree_(new ui::AXSerializableTree()), 125 tree_(new ui::AXSerializableTree()),
126 focus_(NULL),
126 user_is_navigating_away_(false), 127 user_is_navigating_away_(false),
127 osk_state_(OSK_ALLOWED), 128 osk_state_(OSK_ALLOWED),
128 ax_tree_id_(AXTreeIDRegistry::kNoAXTreeID), 129 ax_tree_id_(AXTreeIDRegistry::kNoAXTreeID),
129 parent_node_id_from_parent_tree_(0) { 130 parent_node_id_from_parent_tree_(0) {
130 tree_->SetDelegate(this); 131 tree_->SetDelegate(this);
131 } 132 }
132 133
133 BrowserAccessibilityManager::BrowserAccessibilityManager( 134 BrowserAccessibilityManager::BrowserAccessibilityManager(
134 const ui::AXTreeUpdate& initial_tree, 135 const ui::AXTreeUpdate& initial_tree,
135 BrowserAccessibilityDelegate* delegate, 136 BrowserAccessibilityDelegate* delegate,
136 BrowserAccessibilityFactory* factory) 137 BrowserAccessibilityFactory* factory)
137 : delegate_(delegate), 138 : delegate_(delegate),
138 factory_(factory), 139 factory_(factory),
139 tree_(new ui::AXSerializableTree()), 140 tree_(new ui::AXSerializableTree()),
141 focus_(NULL),
140 user_is_navigating_away_(false), 142 user_is_navigating_away_(false),
141 osk_state_(OSK_ALLOWED), 143 osk_state_(OSK_ALLOWED),
142 ax_tree_id_(AXTreeIDRegistry::kNoAXTreeID), 144 ax_tree_id_(AXTreeIDRegistry::kNoAXTreeID),
143 parent_node_id_from_parent_tree_(0) { 145 parent_node_id_from_parent_tree_(0) {
144 tree_->SetDelegate(this); 146 tree_->SetDelegate(this);
145 Initialize(initial_tree); 147 Initialize(initial_tree);
146 } 148 }
147 149
148 BrowserAccessibilityManager::~BrowserAccessibilityManager() { 150 BrowserAccessibilityManager::~BrowserAccessibilityManager() {
149 tree_.reset(NULL); 151 tree_.reset(NULL);
150 g_ax_tree_id_map.Get().erase(ax_tree_id_); 152 g_ax_tree_id_map.Get().erase(ax_tree_id_);
151 } 153 }
152 154
153 void BrowserAccessibilityManager::Initialize( 155 void BrowserAccessibilityManager::Initialize(
154 const ui::AXTreeUpdate& initial_tree) { 156 const ui::AXTreeUpdate& initial_tree) {
155 if (!tree_->Unserialize(initial_tree)) { 157 if (!tree_->Unserialize(initial_tree)) {
156 if (delegate_) { 158 if (delegate_) {
157 LOG(ERROR) << tree_->error(); 159 LOG(ERROR) << tree_->error();
158 delegate_->AccessibilityFatalError(); 160 delegate_->AccessibilityFatalError();
159 } else { 161 } else {
160 LOG(FATAL) << tree_->error(); 162 LOG(FATAL) << tree_->error();
161 } 163 }
162 } 164 }
165
166 if (!focus_)
167 SetFocus(tree_->root(), false);
163 } 168 }
164 169
165 // static 170 // static
166 ui::AXTreeUpdate 171 ui::AXTreeUpdate
167 BrowserAccessibilityManager::GetEmptyDocument() { 172 BrowserAccessibilityManager::GetEmptyDocument() {
168 ui::AXNodeData empty_document; 173 ui::AXNodeData empty_document;
169 empty_document.id = 0; 174 empty_document.id = 0;
170 empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA; 175 empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA;
171 ui::AXTreeUpdate update; 176 ui::AXTreeUpdate update;
172 update.nodes.push_back(empty_document); 177 update.nodes.push_back(empty_document);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 } 236 }
232 237
233 return nullptr; 238 return nullptr;
234 } 239 }
235 240
236 const ui::AXTreeData& BrowserAccessibilityManager::GetTreeData() { 241 const ui::AXTreeData& BrowserAccessibilityManager::GetTreeData() {
237 return tree_->data(); 242 return tree_->data();
238 } 243 }
239 244
240 void BrowserAccessibilityManager::OnWindowFocused() { 245 void BrowserAccessibilityManager::OnWindowFocused() {
241 BrowserAccessibility* focus = GetFocus(); 246 if (focus_)
242 if (focus) 247 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetFromAXNode(focus_));
243 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, focus);
244 } 248 }
245 249
246 void BrowserAccessibilityManager::OnWindowBlurred() { 250 void BrowserAccessibilityManager::OnWindowBlurred() {
247 BrowserAccessibility* focus = GetFocus(); 251 if (focus_)
248 if (focus) 252 NotifyAccessibilityEvent(ui::AX_EVENT_BLUR, GetFromAXNode(focus_));
249 NotifyAccessibilityEvent(ui::AX_EVENT_BLUR, focus);
250 } 253 }
251 254
252 void BrowserAccessibilityManager::UserIsNavigatingAway() { 255 void BrowserAccessibilityManager::UserIsNavigatingAway() {
253 user_is_navigating_away_ = true; 256 user_is_navigating_away_ = true;
254 } 257 }
255 258
256 void BrowserAccessibilityManager::UserIsReloading() { 259 void BrowserAccessibilityManager::UserIsReloading() {
257 user_is_navigating_away_ = true; 260 user_is_navigating_away_ = true;
258 } 261 }
259 262
260 void BrowserAccessibilityManager::NavigationSucceeded() { 263 void BrowserAccessibilityManager::NavigationSucceeded() {
261 user_is_navigating_away_ = false; 264 user_is_navigating_away_ = false;
262 } 265 }
263 266
264 void BrowserAccessibilityManager::NavigationFailed() { 267 void BrowserAccessibilityManager::NavigationFailed() {
265 user_is_navigating_away_ = false; 268 user_is_navigating_away_ = false;
266 } 269 }
267 270
268 void BrowserAccessibilityManager::GotMouseDown() { 271 void BrowserAccessibilityManager::GotMouseDown() {
269 BrowserAccessibility* focus = GetFocus(); 272 if (!focus_)
270 if (!focus)
271 return; 273 return;
272 274
273 osk_state_ = OSK_ALLOWED_WITHIN_FOCUSED_OBJECT; 275 osk_state_ = OSK_ALLOWED_WITHIN_FOCUSED_OBJECT;
274 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, focus); 276 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetFromAXNode(focus_));
275 } 277 }
276 278
277 bool BrowserAccessibilityManager::UseRootScrollOffsetsWhenComputingBounds() { 279 bool BrowserAccessibilityManager::UseRootScrollOffsetsWhenComputingBounds() {
278 return true; 280 return true;
279 } 281 }
280 282
281 void BrowserAccessibilityManager::OnAccessibilityEvents( 283 void BrowserAccessibilityManager::OnAccessibilityEvents(
282 const std::vector<AXEventNotificationDetails>& details) { 284 const std::vector<AXEventNotificationDetails>& details) {
285 bool should_send_initial_focus = false;
286
283 // Process all changes to the accessibility tree first. 287 // Process all changes to the accessibility tree first.
284 for (uint32_t index = 0; index < details.size(); ++index) { 288 for (uint32_t index = 0; index < details.size(); ++index) {
285 const AXEventNotificationDetails& detail = details[index]; 289 const AXEventNotificationDetails& detail = details[index];
286 if (!tree_->Unserialize(detail.update)) { 290 if (!tree_->Unserialize(detail.update)) {
287 if (delegate_) { 291 if (delegate_) {
288 LOG(ERROR) << tree_->error(); 292 LOG(ERROR) << tree_->error();
289 delegate_->AccessibilityFatalError(); 293 delegate_->AccessibilityFatalError();
290 } else { 294 } else {
291 CHECK(false) << tree_->error(); 295 CHECK(false) << tree_->error();
292 } 296 }
293 return; 297 return;
294 } 298 }
299
300 // Set focus to the root if it's not anywhere else.
301 if (!focus_) {
302 SetFocus(tree_->root(), false);
303 should_send_initial_focus = true;
304 }
295 } 305 }
296 306
307 if (should_send_initial_focus && NativeViewHasFocus())
308 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetFromAXNode(focus_));
309
297 // Now iterate over the events again and fire the events. 310 // Now iterate over the events again and fire the events.
298 for (uint32_t index = 0; index < details.size(); index++) { 311 for (uint32_t index = 0; index < details.size(); index++) {
299 const AXEventNotificationDetails& detail = details[index]; 312 const AXEventNotificationDetails& detail = details[index];
300 313
301 // Find the node corresponding to the id that's the target of the 314 // Find the node corresponding to the id that's the target of the
302 // event (which may not be the root of the update tree). 315 // event (which may not be the root of the update tree).
303 ui::AXNode* node = tree_->GetFromId(detail.id); 316 ui::AXNode* node = tree_->GetFromId(detail.id);
304 if (!node) 317 if (!node)
305 continue; 318 continue;
306 319
307 ui::AXEvent event_type = detail.event_type; 320 ui::AXEvent event_type = detail.event_type;
308 if (event_type == ui::AX_EVENT_FOCUS || 321 if (event_type == ui::AX_EVENT_FOCUS ||
309 event_type == ui::AX_EVENT_BLUR) { 322 event_type == ui::AX_EVENT_BLUR) {
323 SetFocus(node, false);
324
310 if (osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_HIDDEN && 325 if (osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_HIDDEN &&
311 osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED) 326 osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED)
312 osk_state_ = OSK_ALLOWED; 327 osk_state_ = OSK_ALLOWED;
313 328
314 // Don't send a native focus event if the window itself doesn't 329 // Don't send a native focus event if the window itself doesn't
315 // have focus. 330 // have focus.
316 if (!NativeViewHasFocus()) 331 if (!NativeViewHasFocus())
317 continue; 332 continue;
318 } 333 }
319 334
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 node = ancestor; 380 node = ancestor;
366 ancestor = ancestor->GetParent(); 381 ancestor = ancestor->GetParent();
367 } 382 }
368 383
369 // The "scrolled to anchor" notification is a great way to get a 384 // The "scrolled to anchor" notification is a great way to get a
370 // screen reader to jump directly to a specific location in a document. 385 // screen reader to jump directly to a specific location in a document.
371 NotifyAccessibilityEvent(ui::AX_EVENT_SCROLLED_TO_ANCHOR, node); 386 NotifyAccessibilityEvent(ui::AX_EVENT_SCROLLED_TO_ANCHOR, node);
372 } 387 }
373 388
374 BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendantFocus( 389 BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendantFocus(
375 BrowserAccessibility* focus) { 390 BrowserAccessibility* root) {
376 if (!focus) 391 BrowserAccessibility* node = BrowserAccessibilityManager::GetFocus(root);
392 if (!node)
377 return NULL; 393 return NULL;
378 394
379 int active_descendant_id; 395 int active_descendant_id;
380 if (focus->GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, 396 if (node->GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID,
381 &active_descendant_id)) { 397 &active_descendant_id)) {
382 BrowserAccessibility* active_descendant = 398 BrowserAccessibility* active_descendant =
383 focus->manager()->GetFromID(active_descendant_id); 399 node->manager()->GetFromID(active_descendant_id);
384 if (active_descendant) 400 if (active_descendant)
385 return active_descendant; 401 return active_descendant;
386 } 402 }
387 return focus; 403 return node;
388 } 404 }
389 405
390 bool BrowserAccessibilityManager::NativeViewHasFocus() { 406 bool BrowserAccessibilityManager::NativeViewHasFocus() {
391 BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager(); 407 BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager();
392 if (delegate) 408 if (delegate)
393 return delegate->AccessibilityViewHasFocus(); 409 return delegate->AccessibilityViewHasFocus();
394 return false; 410 return false;
395 } 411 }
396 412
397 BrowserAccessibility* BrowserAccessibilityManager::GetFocus() { 413 BrowserAccessibility* BrowserAccessibilityManager::GetFocus(
398 int32_t focus_id = GetTreeData().focus_id; 414 BrowserAccessibility* root) {
399 BrowserAccessibility* obj = GetFromID(focus_id); 415 if (!focus_)
400 if (!obj) 416 return nullptr;
401 return GetRoot();
402 417
418 if (root && !focus_->IsDescendantOf(root->node()))
419 return nullptr;
420
421 BrowserAccessibility* obj = GetFromAXNode(focus_);
422 DCHECK(obj);
403 if (obj->HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) { 423 if (obj->HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) {
404 BrowserAccessibilityManager* child_manager = 424 BrowserAccessibilityManager* child_manager =
405 BrowserAccessibilityManager::FromID( 425 BrowserAccessibilityManager::FromID(
406 obj->GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)); 426 obj->GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID));
407 if (child_manager) 427 if (child_manager)
408 return child_manager->GetFocus(); 428 return child_manager->GetFocus(child_manager->GetRoot());
409 } 429 }
410 430
411 return obj; 431 return obj;
412 } 432 }
413 433
414 void BrowserAccessibilityManager::SetFocus(const BrowserAccessibility& node) { 434 void BrowserAccessibilityManager::SetFocus(ui::AXNode* node, bool notify) {
415 if (delegate_) 435 if (focus_ != node)
416 delegate_->AccessibilitySetFocus(node.GetId()); 436 focus_ = node;
437
438 if (notify && node && delegate_)
439 delegate_->AccessibilitySetFocus(node->id());
417 } 440 }
418 441
419 void BrowserAccessibilityManager::SetFocusLocallyForTesting( 442 void BrowserAccessibilityManager::SetFocus(BrowserAccessibility* obj,
420 BrowserAccessibility* node) { 443 bool notify) {
421 ui::AXTreeData data = GetTreeData(); 444 if (obj->node())
422 data.focus_id = node->GetId(); 445 SetFocus(obj->node(), notify);
423 tree_->UpdateData(data);
424 } 446 }
425 447
426 void BrowserAccessibilityManager::DoDefaultAction( 448 void BrowserAccessibilityManager::DoDefaultAction(
427 const BrowserAccessibility& node) { 449 const BrowserAccessibility& node) {
428 if (delegate_) 450 if (delegate_)
429 delegate_->AccessibilityDoDefaultAction(node.GetId()); 451 delegate_->AccessibilityDoDefaultAction(node.GetId());
430 } 452 }
431 453
432 void BrowserAccessibilityManager::ScrollToMakeVisible( 454 void BrowserAccessibilityManager::ScrollToMakeVisible(
433 const BrowserAccessibility& node, gfx::Rect subfocus) { 455 const BrowserAccessibility& node, gfx::Rect subfocus) {
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 671
650 return text; 672 return text;
651 } 673 }
652 674
653 void BrowserAccessibilityManager::OnTreeDataChanged(ui::AXTree* tree) { 675 void BrowserAccessibilityManager::OnTreeDataChanged(ui::AXTree* tree) {
654 } 676 }
655 677
656 void BrowserAccessibilityManager::OnNodeWillBeDeleted(ui::AXTree* tree, 678 void BrowserAccessibilityManager::OnNodeWillBeDeleted(ui::AXTree* tree,
657 ui::AXNode* node) { 679 ui::AXNode* node) {
658 DCHECK(node); 680 DCHECK(node);
681 if (node == focus_ && tree_) {
682 if (node != tree_->root())
683 SetFocus(tree_->root(), false);
684 else
685 focus_ = NULL;
686 }
659 if (id_wrapper_map_.find(node->id()) == id_wrapper_map_.end()) 687 if (id_wrapper_map_.find(node->id()) == id_wrapper_map_.end())
660 return; 688 return;
661 GetFromAXNode(node)->Destroy(); 689 GetFromAXNode(node)->Destroy();
662 id_wrapper_map_.erase(node->id()); 690 id_wrapper_map_.erase(node->id());
663 } 691 }
664 692
665 void BrowserAccessibilityManager::OnSubtreeWillBeDeleted(ui::AXTree* tree, 693 void BrowserAccessibilityManager::OnSubtreeWillBeDeleted(ui::AXTree* tree,
666 ui::AXNode* node) { 694 ui::AXNode* node) {
667 DCHECK(node); 695 DCHECK(node);
668 BrowserAccessibility* obj = GetFromAXNode(node); 696 BrowserAccessibility* obj = GetFromAXNode(node);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 tree_->CreateTreeSource()); 761 tree_->CreateTreeSource());
734 ui::AXTreeSerializer<const ui::AXNode*, 762 ui::AXTreeSerializer<const ui::AXNode*,
735 ui::AXNodeData, 763 ui::AXNodeData,
736 ui::AXTreeData> serializer(tree_source.get()); 764 ui::AXTreeData> serializer(tree_source.get());
737 ui::AXTreeUpdate update; 765 ui::AXTreeUpdate update;
738 serializer.SerializeChanges(tree_->root(), &update); 766 serializer.SerializeChanges(tree_->root(), &update);
739 return update; 767 return update;
740 } 768 }
741 769
742 } // namespace content 770 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698