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 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_H_ 6 #define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_H_ 7 8 #include <stdint.h> 9 10 #include <map> 11 #include <memory> 12 #include <set> 13 #include <string> 14 #include <unordered_map> 15 #include <vector> 16 17 #include "base/callback_forward.h" 18 #include "base/macros.h" 19 #include "base/scoped_observation.h" 20 #include "build/build_config.h" 21 #include "content/browser/accessibility/accessibility_buildflags.h" 22 #include "content/browser/accessibility/browser_accessibility_position.h" 23 #include "content/common/content_export.h" 24 #include "content/common/render_accessibility.mojom-forward.h" 25 #include "content/public/browser/ax_event_notification_details.h" 26 #include "content/public/browser/web_contents_observer.h" 27 #include "third_party/blink/public/web/web_ax_enums.h" 28 #include "ui/accessibility/ax_action_data.h" 29 #include "ui/accessibility/ax_event_generator.h" 30 #include "ui/accessibility/ax_node.h" 31 #include "ui/accessibility/ax_node_data.h" 32 #include "ui/accessibility/ax_range.h" 33 #include "ui/accessibility/ax_serializable_tree.h" 34 #include "ui/accessibility/ax_tree.h" 35 #include "ui/accessibility/ax_tree_id_registry.h" 36 #include "ui/accessibility/ax_tree_manager.h" 37 #include "ui/accessibility/ax_tree_observer.h" 38 #include "ui/accessibility/ax_tree_update.h" 39 #include "ui/accessibility/platform/ax_platform_node.h" 40 #include "ui/gfx/native_widget_types.h" 41 42 namespace content { 43 class BrowserAccessibility; 44 class BrowserAccessibilityDelegate; 45 class BrowserAccessibilityManager; 46 #if defined(OS_ANDROID) 47 class BrowserAccessibilityManagerAndroid; 48 #elif defined(OS_WIN) 49 class BrowserAccessibilityManagerWin; 50 #elif BUILDFLAG(USE_ATK) 51 class BrowserAccessibilityManagerAuraLinux; 52 #elif defined(OS_MAC) 53 class BrowserAccessibilityManagerMac; 54 #endif 55 56 // To be called when a BrowserAccessibilityManager fires a generated event. 57 // Provides the host, the event fired, and which node id the event was for. 58 typedef base::RepeatingCallback< 59 void(BrowserAccessibilityDelegate*, ui::AXEventGenerator::Event, int)> 60 GeneratedEventCallbackForTesting; 61 62 // For testing. 63 CONTENT_EXPORT ui::AXTreeUpdate MakeAXTreeUpdate( 64 const ui::AXNodeData& node, 65 const ui::AXNodeData& node2 = ui::AXNodeData(), 66 const ui::AXNodeData& node3 = ui::AXNodeData(), 67 const ui::AXNodeData& node4 = ui::AXNodeData(), 68 const ui::AXNodeData& node5 = ui::AXNodeData(), 69 const ui::AXNodeData& node6 = ui::AXNodeData(), 70 const ui::AXNodeData& node7 = ui::AXNodeData(), 71 const ui::AXNodeData& node8 = ui::AXNodeData(), 72 const ui::AXNodeData& node9 = ui::AXNodeData(), 73 const ui::AXNodeData& node10 = ui::AXNodeData(), 74 const ui::AXNodeData& node11 = ui::AXNodeData(), 75 const ui::AXNodeData& node12 = ui::AXNodeData()); 76 77 // Class that can perform actions on behalf of the BrowserAccessibilityManager. 78 // Note: BrowserAccessibilityManager should never cache any of the return 79 // values from any of these interfaces, especially those that return pointers. 80 // They may only be valid within this call stack. That policy eliminates any 81 // concerns about ownership and lifecycle issues; none of these interfaces 82 // transfer ownership and no return values are guaranteed to be valid outside 83 // of the current call stack. 84 class CONTENT_EXPORT BrowserAccessibilityDelegate { 85 public: ~BrowserAccessibilityDelegate()86 virtual ~BrowserAccessibilityDelegate() {} 87 88 virtual void AccessibilityPerformAction(const ui::AXActionData& data) = 0; 89 virtual bool AccessibilityViewHasFocus() = 0; 90 virtual void AccessibilityViewSetFocus() = 0; 91 virtual gfx::Rect AccessibilityGetViewBounds() = 0; 92 virtual float AccessibilityGetDeviceScaleFactor() = 0; 93 virtual void AccessibilityFatalError() = 0; 94 virtual gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget() = 0; 95 virtual gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() = 0; 96 virtual gfx::NativeViewAccessible 97 AccessibilityGetNativeViewAccessibleForWindow() = 0; 98 virtual WebContents* AccessibilityWebContents() = 0; 99 virtual void AccessibilityHitTest( 100 const gfx::Point& point_in_frame_pixels, 101 ax::mojom::Event opt_event_to_fire, 102 int opt_request_id, 103 base::OnceCallback<void(BrowserAccessibilityManager* hit_manager, 104 int hit_node_id)> opt_callback) = 0; 105 106 // Returns true if this delegate represents the main (topmost) frame in a 107 // tree of frames. 108 virtual bool AccessibilityIsMainFrame() = 0; 109 }; 110 111 // This is all of the information about the current find in page result, 112 // so we can activate it if requested. 113 struct BrowserAccessibilityFindInPageInfo { 114 BrowserAccessibilityFindInPageInfo(); 115 116 // This data about find in text results is updated as the user types. 117 int request_id; 118 int match_index; 119 int start_id; 120 int start_offset; 121 int end_id; 122 int end_offset; 123 124 // The active request id indicates that the user committed to a find query, 125 // e.g. by pressing enter or pressing the next or previous buttons. If 126 // |active_request_id| == |request_id|, we fire an accessibility event 127 // to move screen reader focus to that event. 128 int active_request_id; 129 }; 130 131 // Manages a tree of BrowserAccessibility objects. 132 class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeObserver, 133 public ui::AXTreeManager, 134 public WebContentsObserver { 135 protected: 136 using BrowserAccessibilityPositionInstance = 137 BrowserAccessibilityPosition::AXPositionInstance; 138 using BrowserAccessibilityRange = 139 ui::AXRange<BrowserAccessibilityPositionInstance::element_type>; 140 141 public: 142 // Creates the platform-specific BrowserAccessibilityManager, but 143 // with no parent window pointer. Only useful for unit tests. 144 static BrowserAccessibilityManager* Create( 145 const ui::AXTreeUpdate& initial_tree, 146 BrowserAccessibilityDelegate* delegate); 147 148 static BrowserAccessibilityManager* FromID(ui::AXTreeID ax_tree_id); 149 150 ~BrowserAccessibilityManager() override; 151 152 void Initialize(const ui::AXTreeUpdate& initial_tree); 153 154 static ui::AXTreeUpdate GetEmptyDocument(); 155 156 enum RetargetEventType { 157 RetargetEventTypeGenerated = 0, 158 RetargetEventTypeBlinkGeneral, 159 RetargetEventTypeBlinkHover, 160 }; 161 162 // Return |node| by default, but some platforms want to update the target node 163 // based on the event type. 164 virtual BrowserAccessibility* RetargetForEvents(BrowserAccessibility* node, 165 RetargetEventType type) const; 166 167 // Subclasses override these methods to send native event notifications. 168 virtual void FireFocusEvent(BrowserAccessibility* node); FireBlinkEvent(ax::mojom::Event event_type,BrowserAccessibility * node)169 virtual void FireBlinkEvent(ax::mojom::Event event_type, 170 BrowserAccessibility* node) {} 171 virtual void FireGeneratedEvent(ui::AXEventGenerator::Event event_type, 172 BrowserAccessibility* node); 173 174 // Checks whether focus has changed since the last time it was checked, 175 // taking into account whether the window has focus and which frame within 176 // the frame tree has focus. If focus has changed, calls FireFocusEvent. 177 void FireFocusEventsIfNeeded(); 178 179 // Return whether or not we are currently able to fire events. 180 virtual bool CanFireEvents() const; 181 182 // Return a pointer to the root of the tree. 183 BrowserAccessibility* GetRoot() const; 184 185 // Returns a pointer to the BrowserAccessibility object for a given AXNode. 186 BrowserAccessibility* GetFromAXNode(const ui::AXNode* node) const; 187 188 // Return a pointer to the object corresponding to the given id, 189 // does not make a new reference. 190 BrowserAccessibility* GetFromID(int32_t id) const; 191 192 // If this tree has a parent tree, return the parent node in that tree. 193 BrowserAccessibility* GetParentNodeFromParentTree() const; 194 195 // In general, there is only a single node with the role of kRootWebArea, 196 // but if a popup is opened, a second nested "root" is created in the same 197 // tree as the "true" root. This will keep track of the nested root node. 198 BrowserAccessibility* GetPopupRoot() const; 199 200 // Get the AXTreeData for this frame. 201 const ui::AXTreeData& GetTreeData() const; 202 203 // Called to notify the accessibility manager that its associated native 204 // view got focused. 205 virtual void OnWindowFocused(); 206 207 // Called to notify the accessibility manager that its associated native 208 // view lost focus. 209 virtual void OnWindowBlurred(); 210 211 // Notify the accessibility manager about page navigation. 212 // TODO(domfarolino, dmazzoni): Implement WebContentsObserver methods that 213 // correspond to the ones we provide today, so we can stop being manually 214 // notified of navigation events when they happen. 215 void UserIsNavigatingAway(); 216 virtual void UserIsReloading(); 217 void NavigationSucceeded(); 218 void NavigationFailed(); 219 220 // WebContentsObserver overrides 221 void DidStopLoading() override; 222 void DidActivatePortal(WebContents* predecessor_contents, 223 base::TimeTicks activation_time) override; 224 225 // Keep track of if this page is hidden by an interstitial, in which case 226 // we need to suppress all events. set_hidden_by_interstitial_page(bool hidden)227 void set_hidden_by_interstitial_page(bool hidden) { 228 hidden_by_interstitial_page_ = hidden; 229 } hidden_by_interstitial_page()230 bool hidden_by_interstitial_page() const { 231 return hidden_by_interstitial_page_; 232 } 233 234 // Pretend that the given node has focus, for testing only. Doesn't 235 // communicate with the renderer and doesn't fire any events. 236 void SetFocusLocallyForTesting(BrowserAccessibility* node); 237 238 // For testing only, register a function to be called when focus changes 239 // in any BrowserAccessibilityManager. 240 static void SetFocusChangeCallbackForTesting(base::RepeatingClosure callback); 241 242 // For testing only, register a function to be called when 243 // a generated event is fired from this BrowserAccessibilityManager. 244 void SetGeneratedEventCallbackForTesting( 245 const GeneratedEventCallbackForTesting& callback); 246 247 // Normally we avoid firing accessibility focus events when the containing 248 // native window isn't focused, and we also delay some other events like 249 // live region events to improve screen reader compatibility. 250 // However, this can lead to test flakiness, so for testing, simplify 251 // this behavior and just fire all events with no delay as if the window 252 // had focus. 253 static void NeverSuppressOrDelayEventsForTesting(); 254 255 // Accessibility actions. All of these are implemented asynchronously 256 // by sending a message to the renderer to perform the respective action 257 // on the given node. See the definition of |ui::AXActionData| for more 258 // information about each of these actions. 259 void ClearAccessibilityFocus(const BrowserAccessibility& node); 260 void Decrement(const BrowserAccessibility& node); 261 void DoDefaultAction(const BrowserAccessibility& node); 262 void GetImageData(const BrowserAccessibility& node, 263 const gfx::Size& max_size); 264 // Per third_party/blink/renderer/core/layout/hit_test_location.h, Blink 265 // expects hit test points in page coordinates. However, WebAXObject::HitTest 266 // applies the visual viewport offset, so we want to pass that function a 267 // point in frame coordinates. 268 void HitTest(const gfx::Point& frame_point) const; 269 void Increment(const BrowserAccessibility& node); 270 void LoadInlineTextBoxes(const BrowserAccessibility& node); 271 void ScrollToMakeVisible( 272 const BrowserAccessibility& node, 273 gfx::Rect subfocus, 274 ax::mojom::ScrollAlignment horizontal_scroll_alignment = 275 ax::mojom::ScrollAlignment::kScrollAlignmentCenter, 276 ax::mojom::ScrollAlignment vertical_scroll_alignment = 277 ax::mojom::ScrollAlignment::kScrollAlignmentCenter, 278 ax::mojom::ScrollBehavior scroll_behavior = 279 ax::mojom::ScrollBehavior::kDoNotScrollIfVisible); 280 void ScrollToPoint(const BrowserAccessibility& node, gfx::Point point); 281 void SetAccessibilityFocus(const BrowserAccessibility& node); 282 void SetFocus(const BrowserAccessibility& node); 283 void SetSequentialFocusNavigationStartingPoint( 284 const BrowserAccessibility& node); 285 void SetScrollOffset(const BrowserAccessibility& node, gfx::Point offset); 286 void SetValue(const BrowserAccessibility& node, const std::string& value); 287 void SetSelection(const ui::AXActionData& action_data); 288 void SetSelection(const BrowserAccessibilityRange& range); 289 void ShowContextMenu(const BrowserAccessibility& node); 290 void SignalEndOfTest(); 291 292 // Retrieve the bounds of the parent View in screen coordinates. 293 virtual gfx::Rect GetViewBoundsInScreenCoordinates() const; 294 295 // Fire an event telling native assistive technology to move focus to the 296 // given find in page result. 297 void ActivateFindInPageResult(int request_id, int match_index); 298 299 // Called when the renderer process has notified us of tree changes. Returns 300 // false in fatal-error conditions, in which case the caller should destroy 301 // the manager. 302 virtual bool OnAccessibilityEvents(const AXEventNotificationDetails& details) 303 WARN_UNUSED_RESULT; 304 305 // Allows derived classes to do event pre-processing 306 virtual void BeforeAccessibilityEvents(); 307 308 // Allows derived classes to do event post-processing. 309 virtual void FinalizeAccessibilityEvents(); 310 311 // Called when the renderer process updates the location of accessibility 312 // objects. Calls SendLocationChangeEvents(), which can be overridden. 313 void OnLocationChanges(const std::vector<mojom::LocationChangesPtr>& changes); 314 315 // Called when a new find in page result is received. We hold on to this 316 // information and don't activate it until the user requests it. 317 virtual void OnFindInPageResult(int request_id, 318 int match_index, 319 int start_id, 320 int start_offset, 321 int end_id, 322 int end_offset); 323 324 // This is called when the user has committed to a find in page query, 325 // e.g. by pressing enter or tapping on the next / previous result buttons. 326 // If a match has already been received for this request id, 327 // activate the result now by firing an accessibility event. If a match 328 // has not been received, we hold onto this request id and update it 329 // when OnFindInPageResult is called. 330 void ActivateFindInPageResult(int request_id); 331 332 // This is called when the user finishes a find in page query and all 333 // highlighted matches are deactivated. OnFindInPageTermination()334 virtual void OnFindInPageTermination() {} 335 336 #if defined(OS_WIN) 337 BrowserAccessibilityManagerWin* ToBrowserAccessibilityManagerWin(); 338 #endif 339 340 #if defined(OS_ANDROID) 341 BrowserAccessibilityManagerAndroid* ToBrowserAccessibilityManagerAndroid(); 342 #endif 343 344 #if BUILDFLAG(USE_ATK) 345 BrowserAccessibilityManagerAuraLinux* 346 ToBrowserAccessibilityManagerAuraLinux(); 347 #endif 348 349 #if defined(OS_MAC) 350 BrowserAccessibilityManagerMac* ToBrowserAccessibilityManagerMac(); 351 #endif 352 353 // Returns the object that has focus, starting at the top of the frame tree, 354 // or returns nullptr if this manager doesn't have access to the top document. 355 virtual BrowserAccessibility* GetFocus() const; 356 357 // Return the object that has focus, only considering this frame and 358 // descendants. 359 BrowserAccessibility* GetFocusFromThisOrDescendantFrame() const; 360 361 // Given a focused node |focus|, returns a descendant of that node if it 362 // has an active descendant, otherwise returns |focus|. 363 BrowserAccessibility* GetActiveDescendant(BrowserAccessibility* focus) const; 364 365 // Returns true if native focus is anywhere in this WebContents or not. 366 bool NativeViewHasFocus(); 367 368 // True by default, but some platforms want to treat the root 369 // scroll offsets separately. 370 bool UseRootScrollOffsetsWhenComputingBounds(); 371 void SetUseRootScrollOffsetsWhenComputingBoundsForTesting(bool use); 372 373 // Walk the tree using depth-first pre-order traversal. 374 static BrowserAccessibility* NextInTreeOrder( 375 const BrowserAccessibility* object); 376 static BrowserAccessibility* NextNonDescendantInTreeOrder( 377 const BrowserAccessibility* object); 378 static BrowserAccessibility* PreviousInTreeOrder( 379 const BrowserAccessibility* object, 380 bool can_wrap_to_last_element); 381 static BrowserAccessibility* NextTextOnlyObject( 382 const BrowserAccessibility* object); 383 static BrowserAccessibility* PreviousTextOnlyObject( 384 const BrowserAccessibility* object); 385 386 // If the two objects provided have a common ancestor returns both the 387 // common ancestor and the child indices of the two subtrees in which the 388 // objects are located. 389 // Returns false if a common ancestor cannot be found. 390 static bool FindIndicesInCommonParent(const BrowserAccessibility& object1, 391 const BrowserAccessibility& object2, 392 BrowserAccessibility** common_parent, 393 int* child_index1, 394 int* child_index2); 395 396 // Sets |out_is_before| to true if |object1| comes before |object2| 397 // in tree order (pre-order traversal), and false if the objects are the 398 // same or not in the same tree. 399 static ax::mojom::TreeOrder CompareNodes(const BrowserAccessibility& object1, 400 const BrowserAccessibility& object2); 401 402 static std::vector<const BrowserAccessibility*> FindTextOnlyObjectsInRange( 403 const BrowserAccessibility& start_object, 404 const BrowserAccessibility& end_object); 405 406 static base::string16 GetTextForRange( 407 const BrowserAccessibility& start_object, 408 const BrowserAccessibility& end_object); 409 410 // If start and end offsets are greater than the text's length, returns all 411 // the text. 412 static base::string16 GetTextForRange( 413 const BrowserAccessibility& start_object, 414 int start_offset, 415 const BrowserAccessibility& end_object, 416 int end_offset); 417 418 // DEPRECATED: Prefer using AXPlatformNodeDelegate bounds interfaces when 419 // writing new code. 420 static gfx::Rect GetRootFrameInnerTextRangeBoundsRect( 421 const BrowserAccessibility& start_object, 422 int start_offset, 423 const BrowserAccessibility& end_object, 424 int end_offset); 425 426 // Accessors. ax_tree_id()427 ui::AXTreeID ax_tree_id() const { return ax_tree_id_; } device_scale_factor()428 float device_scale_factor() const { return device_scale_factor_; } ax_tree()429 ui::AXTree* ax_tree() const { return tree_.get(); } 430 431 // AXTreeObserver implementation. 432 void OnNodeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override; 433 void OnSubtreeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override; 434 void OnNodeCreated(ui::AXTree* tree, ui::AXNode* node) override; 435 void OnNodeDeleted(ui::AXTree* tree, int32_t node_id) override; 436 void OnNodeReparented(ui::AXTree* tree, ui::AXNode* node) override; 437 void OnRoleChanged(ui::AXTree* tree, 438 ui::AXNode* node, 439 ax::mojom::Role old_role, 440 ax::mojom::Role new_role) override; 441 void OnAtomicUpdateFinished( 442 ui::AXTree* tree, 443 bool root_changed, 444 const std::vector<ui::AXTreeObserver::Change>& changes) override; 445 446 // AXTreeManager overrides. 447 ui::AXNode* GetNodeFromTree(ui::AXTreeID tree_id, 448 ui::AXNode::AXID node_id) const override; 449 ui::AXNode* GetNodeFromTree(ui::AXNode::AXID node_id) const override; 450 void AddObserver(ui::AXTreeObserver* observer) override; 451 void RemoveObserver(ui::AXTreeObserver* observer) override; 452 AXTreeID GetTreeID() const override; 453 AXTreeID GetParentTreeID() const override; 454 ui::AXNode* GetRootAsAXNode() const override; 455 ui::AXNode* GetParentNodeFromParentTreeAsAXNode() const override; 456 delegate()457 BrowserAccessibilityDelegate* delegate() const { return delegate_; } 458 459 // If this BrowserAccessibilityManager is a child frame or guest frame, 460 // returns the BrowserAccessibilityManager from the top document in the frame 461 // tree. If the current frame is not connected to its parent frame yet, or if 462 // it got disconnected after being reparented, return nullptr to indicate that 463 // we don't have access to the root manager yet. 464 BrowserAccessibilityManager* GetRootManager() const; 465 466 // Returns the BrowserAccessibilityDelegate from |GetRootManager| above, or 467 // returns nullptr in case we don't have access to the root manager yet. 468 BrowserAccessibilityDelegate* GetDelegateFromRootManager() const; 469 470 // Returns whether this is the top document. 471 bool IsRootTree() const; 472 473 // Get a snapshot of the current tree as an AXTreeUpdate. 474 ui::AXTreeUpdate SnapshotAXTreeForTesting(); 475 476 // Use a custom device scale factor for testing. 477 void UseCustomDeviceScaleFactorForTesting(float device_scale_factor); 478 479 // Given a point in physical pixel coordinates, trigger an asynchronous hit 480 // test but return the best possible match instantly. 481 BrowserAccessibility* CachingAsyncHitTest( 482 const gfx::Point& physical_pixel_point) const; 483 484 // Called in response to a hover event, caches the result for the next 485 // call to CachingAsyncHitTest(). 486 void CacheHitTestResult(BrowserAccessibility* hit_test_result) const; 487 488 // Updates the page scale factor for this frame. 489 void SetPageScaleFactor(float page_scale_factor); 490 491 // Returns the current page scale factor for this frame. 492 float GetPageScaleFactor() const; 493 494 protected: 495 FRIEND_TEST_ALL_PREFIXES(BrowserAccessibilityManagerTest, 496 TestShouldFireEventForNode); 497 explicit BrowserAccessibilityManager(BrowserAccessibilityDelegate* delegate); 498 499 BrowserAccessibilityManager(const ui::AXTreeUpdate& initial_tree, 500 BrowserAccessibilityDelegate* delegate); 501 502 // Send platform-specific notifications to each of these objects that 503 // their location has changed. This is called by OnLocationChanges 504 // after it's updated the internal data structure. 505 virtual void SendLocationChangeEvents( 506 const std::vector<mojom::LocationChangesPtr>& changes); 507 508 // Given the data from an atomic update, collect the nodes that need updating 509 // assuming that this platform is one where plain text node content is 510 // directly included in parents' hypertext. 511 void CollectChangedNodesAndParentsForAtomicUpdate( 512 ui::AXTree* tree, 513 const std::vector<ui::AXTreeObserver::Change>& changes, 514 std::set<ui::AXPlatformNode*>* nodes_needing_update); 515 516 bool ShouldFireEventForNode(BrowserAccessibility* node) const; 517 518 static void SetLastFocusedNode(BrowserAccessibility* node); 519 static BrowserAccessibility* GetLastFocusedNode(); 520 521 // The object that can perform actions on our behalf. 522 BrowserAccessibilityDelegate* delegate_; 523 524 // A mapping from a node id to its wrapper of type BrowserAccessibility. 525 std::map<int32_t, BrowserAccessibility*> id_wrapper_map_; 526 527 // True if the user has initiated a navigation to another page. 528 bool user_is_navigating_away_; 529 530 // Interstitial page, like an SSL warning. 531 // If so we need to suppress any events. 532 bool hidden_by_interstitial_page_ = false; 533 534 BrowserAccessibilityFindInPageInfo find_in_page_info_; 535 536 // These cache the AX tree ID, node ID, and global screen bounds of the 537 // last object found by an asynchronous hit test. Subsequent hit test 538 // requests that remain within this object's bounds will return the same 539 // object, but will also trigger a new asynchronous hit test request. 540 mutable ui::AXTreeID last_hover_ax_tree_id_; 541 mutable int last_hover_node_id_; 542 mutable gfx::Rect last_hover_bounds_; 543 544 // True if the root's parent is in another accessibility tree and that 545 // parent's child is the root. Ensures that the parent node is notified 546 // once when this subtree is first connected. 547 bool connected_to_parent_tree_node_; 548 549 // The global ID of this accessibility tree. 550 ui::AXTreeID ax_tree_id_; 551 552 // The device scale factor for the view associated with this frame, 553 // cached each time there's any update to the accessibility tree. 554 float device_scale_factor_; 555 556 // The page scale factor for the view associated with this frame, 557 // cached when we get an update via SetPageScaleFactor(). 558 float page_scale_factor_ = 1.0f; 559 560 // For testing only: If true, the manually-set device scale factor will be 561 // used and it won't be updated from the delegate. 562 bool use_custom_device_scale_factor_for_testing_; 563 564 // Whether we should include or exclude the scroll offsets on the root 565 // scroller when computing bounding rectangles. Usually true, but on 566 // some platforms the root scroll offsets are handled separately. 567 bool use_root_scroll_offsets_when_computing_bounds_ = true; 568 569 // For testing only: A function to call when a generated event is fired. 570 GeneratedEventCallbackForTesting generated_event_callback_for_testing_; 571 572 // Keeps track of the nested popup root's id, if it exists. See GetPopupRoot() 573 // for details. 574 std::set<int32_t> popup_root_ids_; 575 576 // Fire all events regardless of focus and with no delay, to avoid test 577 // flakiness. See NeverSuppressOrDelayEventsForTesting() for details. 578 static bool never_suppress_or_delay_events_for_testing_; 579 event_generator()580 const ui::AXEventGenerator& event_generator() const { 581 return event_generator_; 582 } event_generator()583 ui::AXEventGenerator& event_generator() { return event_generator_; } 584 585 // Stores the id of the last focused node across all frames, as well as the id 586 // of the tree that contains it, so that when focus might have changed we can 587 // figure out whether we need to fire a focus event. 588 // 589 // NOTE: Don't use or modify these properties directly, use the 590 // SetLastFocusedNode and GetLastFocusedNode methods instead. 591 static base::Optional<int32_t> last_focused_node_id_; 592 static base::Optional<ui::AXTreeID> last_focused_node_tree_id_; 593 594 // For debug only: True when handling OnAccessibilityEvents. 595 #if DCHECK_IS_ON() 596 bool in_on_accessibility_events_ = false; 597 #endif // DCHECK_IS_ON() 598 599 private: 600 // Helper that calls AXTree::Unserialize(). On failure it populates crash data 601 // with error information. 602 bool Unserialize(const ui::AXTreeUpdate& tree_update); 603 604 // The underlying tree of accessibility objects. 605 std::unique_ptr<ui::AXSerializableTree> tree_; 606 607 ui::AXEventGenerator event_generator_; 608 609 // Automatically stops observing notifications from the AXTree when this class 610 // is destructed. 611 // 612 // This member needs to be destructed before any observed AXTrees. Since 613 // destructors for non-static member fields are called in the reverse order of 614 // declaration, do not move this member above other members. 615 base::ScopedObservation<ui::AXTree, ui::AXTreeObserver> tree_observation_{ 616 this}; 617 618 DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManager); 619 }; 620 621 } // namespace content 622 623 #endif // CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_H_ 624