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

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

Issue 1761633002: One accessibility tree per frame. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix is-richly-editable test 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
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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 user_is_navigating_away_(false), 126 user_is_navigating_away_(false),
127 osk_state_(OSK_ALLOWED), 127 osk_state_(OSK_ALLOWED),
128 last_focused_node_(nullptr),
129 last_focused_manager_(nullptr),
128 ax_tree_id_(AXTreeIDRegistry::kNoAXTreeID), 130 ax_tree_id_(AXTreeIDRegistry::kNoAXTreeID),
129 parent_node_id_from_parent_tree_(0) { 131 parent_node_id_from_parent_tree_(0) {
130 tree_->SetDelegate(this); 132 tree_->SetDelegate(this);
131 } 133 }
132 134
133 BrowserAccessibilityManager::BrowserAccessibilityManager( 135 BrowserAccessibilityManager::BrowserAccessibilityManager(
134 const ui::AXTreeUpdate& initial_tree, 136 const ui::AXTreeUpdate& initial_tree,
135 BrowserAccessibilityDelegate* delegate, 137 BrowserAccessibilityDelegate* delegate,
136 BrowserAccessibilityFactory* factory) 138 BrowserAccessibilityFactory* factory)
137 : delegate_(delegate), 139 : delegate_(delegate),
(...skipping 28 matching lines...) Expand all
166 ui::AXTreeUpdate 168 ui::AXTreeUpdate
167 BrowserAccessibilityManager::GetEmptyDocument() { 169 BrowserAccessibilityManager::GetEmptyDocument() {
168 ui::AXNodeData empty_document; 170 ui::AXNodeData empty_document;
169 empty_document.id = 0; 171 empty_document.id = 0;
170 empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA; 172 empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA;
171 ui::AXTreeUpdate update; 173 ui::AXTreeUpdate update;
172 update.nodes.push_back(empty_document); 174 update.nodes.push_back(empty_document);
173 return update; 175 return update;
174 } 176 }
175 177
178 void BrowserAccessibilityManager::FireFocusEventsIfNeeded() {
179 BrowserAccessibility* focus = GetFocus();
180 if (delegate_ && !delegate_->AccessibilityViewHasFocus())
181 focus = nullptr;
182
183 if (!CanFireEvents())
184 focus = nullptr;
185
186 // Don't allow the document to be focused if it has no children and
187 // hasn't finished loading yet. Wait for at least a tiny bit of content,
188 // or for the document to actually finish loading.
189 if (focus &&
190 focus == focus->manager()->GetRoot() &&
191 focus->PlatformChildCount() == 0 &&
192 !focus->HasState(ui::AX_STATE_BUSY) &&
193 !focus->manager()->GetTreeData().loaded) {
194 focus = nullptr;
195 }
196
197 if (focus && focus != last_focused_node_)
198 FireFocusEvent(focus);
199
200 last_focused_node_ = focus;
201 last_focused_manager_ = focus ? focus->manager() : nullptr;
202 }
203
204 bool BrowserAccessibilityManager::CanFireEvents() {
205 return true;
206 }
207
208 void BrowserAccessibilityManager::FireFocusEvent(BrowserAccessibility* node) {
209 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, node);
210 }
211
176 BrowserAccessibility* BrowserAccessibilityManager::GetRoot() { 212 BrowserAccessibility* BrowserAccessibilityManager::GetRoot() {
177 // tree_ can be null during destruction. 213 // tree_ can be null during destruction.
178 if (!tree_) 214 if (!tree_)
179 return nullptr; 215 return nullptr;
180 216
181 // tree_->root() can be null during AXTreeDelegate callbacks. 217 // tree_->root() can be null during AXTreeDelegate callbacks.
182 ui::AXNode* root = tree_->root(); 218 ui::AXNode* root = tree_->root();
183 return root ? GetFromAXNode(root) : nullptr; 219 return root ? GetFromAXNode(root) : nullptr;
184 } 220 }
185 221
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 } 267 }
232 268
233 return nullptr; 269 return nullptr;
234 } 270 }
235 271
236 const ui::AXTreeData& BrowserAccessibilityManager::GetTreeData() { 272 const ui::AXTreeData& BrowserAccessibilityManager::GetTreeData() {
237 return tree_->data(); 273 return tree_->data();
238 } 274 }
239 275
240 void BrowserAccessibilityManager::OnWindowFocused() { 276 void BrowserAccessibilityManager::OnWindowFocused() {
241 BrowserAccessibility* focus = GetFocus(); 277 if (this == GetRootManager())
242 if (focus) 278 FireFocusEventsIfNeeded();
243 NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, focus);
244 } 279 }
245 280
246 void BrowserAccessibilityManager::OnWindowBlurred() { 281 void BrowserAccessibilityManager::OnWindowBlurred() {
247 BrowserAccessibility* focus = GetFocus(); 282 if (this == GetRootManager()) {
248 if (focus) 283 last_focused_node_ = nullptr;
249 NotifyAccessibilityEvent(ui::AX_EVENT_BLUR, focus); 284 last_focused_manager_ = nullptr;
285 }
250 } 286 }
251 287
252 void BrowserAccessibilityManager::UserIsNavigatingAway() { 288 void BrowserAccessibilityManager::UserIsNavigatingAway() {
253 user_is_navigating_away_ = true; 289 user_is_navigating_away_ = true;
254 } 290 }
255 291
256 void BrowserAccessibilityManager::UserIsReloading() { 292 void BrowserAccessibilityManager::UserIsReloading() {
257 user_is_navigating_away_ = true; 293 user_is_navigating_away_ = true;
258 } 294 }
259 295
(...skipping 27 matching lines...) Expand all
287 if (delegate_) { 323 if (delegate_) {
288 LOG(ERROR) << tree_->error(); 324 LOG(ERROR) << tree_->error();
289 delegate_->AccessibilityFatalError(); 325 delegate_->AccessibilityFatalError();
290 } else { 326 } else {
291 CHECK(false) << tree_->error(); 327 CHECK(false) << tree_->error();
292 } 328 }
293 return; 329 return;
294 } 330 }
295 } 331 }
296 332
297 // Now iterate over the events again and fire the events. 333 // Based on the changes to the tree, first fire focus events if needed.
334 // Screen readers might not do the right thing if they're not aware of what
335 // has focus, so always try that first. Nothing will be fired if the window
336 // itself isn't focused or if focus hasn't changed.
337 GetRootManager()->FireFocusEventsIfNeeded();
338
339 // Now iterate over the events again and fire the events other than focus
340 // events.
298 for (uint32_t index = 0; index < details.size(); index++) { 341 for (uint32_t index = 0; index < details.size(); index++) {
299 const AXEventNotificationDetails& detail = details[index]; 342 const AXEventNotificationDetails& detail = details[index];
300 343
301 // Find the node corresponding to the id that's the target of the 344 // 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). 345 // event (which may not be the root of the update tree).
303 ui::AXNode* node = tree_->GetFromId(detail.id); 346 ui::AXNode* node = tree_->GetFromId(detail.id);
304 if (!node) 347 if (!node)
305 continue; 348 continue;
306 349
307 ui::AXEvent event_type = detail.event_type; 350 ui::AXEvent event_type = detail.event_type;
308 if (event_type == ui::AX_EVENT_FOCUS || 351 if (event_type == ui::AX_EVENT_FOCUS ||
309 event_type == ui::AX_EVENT_BLUR) { 352 event_type == ui::AX_EVENT_BLUR) {
310 if (osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_HIDDEN && 353 if (osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_HIDDEN &&
311 osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED) 354 osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED)
312 osk_state_ = OSK_ALLOWED; 355 osk_state_ = OSK_ALLOWED;
313 356
314 // Don't send a native focus event if the window itself doesn't 357 bool is_menu_list_option =
315 // have focus. 358 node->data().role == ui::AX_ROLE_MENU_LIST_OPTION;
316 if (!NativeViewHasFocus()) 359
360 // Skip all focus events other than ones on menu list options;
361 // we've already handled them, above. Menu list options are a weird
362 // exception because the menu list itself has focus but we need to fire
363 // focus events on the individual options.
364 if (!is_menu_list_option)
317 continue; 365 continue;
318 } 366 }
319 367
320 // Send the event event to the operating system. 368 // Fire the native event.
321 NotifyAccessibilityEvent(event_type, GetFromAXNode(node)); 369 NotifyAccessibilityEvent(event_type, GetFromAXNode(node));
322 } 370 }
323 } 371 }
324 372
325 void BrowserAccessibilityManager::OnLocationChanges( 373 void BrowserAccessibilityManager::OnLocationChanges(
326 const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) { 374 const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) {
327 for (size_t i = 0; i < params.size(); ++i) { 375 for (size_t i = 0; i < params.size(); ++i) {
328 BrowserAccessibility* obj = GetFromID(params[i].id); 376 BrowserAccessibility* obj = GetFromID(params[i].id);
329 if (!obj) 377 if (!obj)
330 continue; 378 continue;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 } 436 }
389 437
390 bool BrowserAccessibilityManager::NativeViewHasFocus() { 438 bool BrowserAccessibilityManager::NativeViewHasFocus() {
391 BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager(); 439 BrowserAccessibilityDelegate* delegate = GetDelegateFromRootManager();
392 if (delegate) 440 if (delegate)
393 return delegate->AccessibilityViewHasFocus(); 441 return delegate->AccessibilityViewHasFocus();
394 return false; 442 return false;
395 } 443 }
396 444
397 BrowserAccessibility* BrowserAccessibilityManager::GetFocus() { 445 BrowserAccessibility* BrowserAccessibilityManager::GetFocus() {
398 int32_t focus_id = GetTreeData().focus_id; 446 BrowserAccessibilityManager* root_manager = GetRootManager();
399 BrowserAccessibility* obj = GetFromID(focus_id); 447 if (!root_manager)
448 root_manager = this;
449 int32_t focused_tree_id = root_manager->GetTreeData().focused_tree_id;
450
451 BrowserAccessibilityManager* focused_manager = nullptr;
452 if (focused_tree_id)
453 focused_manager =BrowserAccessibilityManager::FromID(focused_tree_id);
454 if (!focused_manager)
455 focused_manager = root_manager;
456
457 int32_t focus_id = focused_manager->GetTreeData().focus_id;
458 BrowserAccessibility* obj = focused_manager->GetFromID(focus_id);
400 if (!obj) 459 if (!obj)
401 return GetRoot(); 460 return focused_manager->GetRoot();
402 461
403 if (obj->HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) { 462 if (obj->HasIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)) {
404 BrowserAccessibilityManager* child_manager = 463 BrowserAccessibilityManager* child_manager =
405 BrowserAccessibilityManager::FromID( 464 BrowserAccessibilityManager::FromID(
406 obj->GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID)); 465 obj->GetIntAttribute(ui::AX_ATTR_CHILD_TREE_ID));
407 if (child_manager) 466 if (child_manager)
408 return child_manager->GetFocus(); 467 return child_manager->GetFocus();
409 } 468 }
410 469
411 return obj; 470 return obj;
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 tree_->CreateTreeSource()); 808 tree_->CreateTreeSource());
750 ui::AXTreeSerializer<const ui::AXNode*, 809 ui::AXTreeSerializer<const ui::AXNode*,
751 ui::AXNodeData, 810 ui::AXNodeData,
752 ui::AXTreeData> serializer(tree_source.get()); 811 ui::AXTreeData> serializer(tree_source.get());
753 ui::AXTreeUpdate update; 812 ui::AXTreeUpdate update;
754 serializer.SerializeChanges(tree_->root(), &update); 813 serializer.SerializeChanges(tree_->root(), &update);
755 return update; 814 return update;
756 } 815 }
757 816
758 } // namespace content 817 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698