1 // Copyright 2017 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 EXTENSIONS_RENDERER_API_AUTOMATION_AUTOMATION_AX_TREE_WRAPPER_H_
6 #define EXTENSIONS_RENDERER_API_AUTOMATION_AUTOMATION_AX_TREE_WRAPPER_H_
7 
8 #include "extensions/common/api/automation.h"
9 #include "ui/accessibility/ax_event_generator.h"
10 #include "ui/accessibility/ax_node.h"
11 #include "ui/accessibility/ax_tree.h"
12 #include "ui/accessibility/ax_tree_manager.h"
13 
14 struct ExtensionMsg_AccessibilityEventBundleParams;
15 
16 namespace extensions {
17 
18 class AutomationInternalCustomBindings;
19 
20 // A class that wraps one AXTree and all of the additional state
21 // and helper methods needed to use it for the automation API.
22 class AutomationAXTreeWrapper : public ui::AXTreeObserver,
23                                 public ui::AXTreeManager {
24  public:
25   AutomationAXTreeWrapper(ui::AXTreeID tree_id,
26                           AutomationInternalCustomBindings* owner);
27   ~AutomationAXTreeWrapper() override;
28 
29   // Returns the AutomationAXTreeWrapper that lists |tree_id| as one of its
30   // child trees, if any.
31   static AutomationAXTreeWrapper* GetParentOfTreeId(ui::AXTreeID tree_id);
32 
33   static std::map<ui::AXTreeID, AutomationAXTreeWrapper*>&
34   GetChildTreeIDReverseMap();
35 
tree()36   ui::AXTree* tree() { return &tree_; }
owner()37   AutomationInternalCustomBindings* owner() { return owner_; }
38 
39   // Called by AutomationInternalCustomBindings::OnAccessibilityEvents on
40   // the AutomationAXTreeWrapper instance for the correct tree corresponding
41   // to this event. Unserializes the tree update and calls back to
42   // AutomationInternalCustomBindings to fire any automation events needed.
43   bool OnAccessibilityEvents(
44       const ExtensionMsg_AccessibilityEventBundleParams& events,
45       bool is_active_profile);
46 
47   // Returns true if this is the desktop tree.
48   bool IsDesktopTree() const;
49 
50   // Returns whether |node_id| is the focused node in this tree. Accounts for
51   // cases where this tree itself is not focused. Behaves similarly to
52   // document.activeElement (within the DOM).
53   bool IsInFocusChain(int32_t node_id);
54 
55   ui::AXTree::Selection GetUnignoredSelection();
56 
57   // Returns an AXNode from the underlying tree if it both exists and is not
58   // ignored.
59   ui::AXNode* GetUnignoredNodeFromId(int32_t id);
60 
61   // Accessibility focus is globally set via automation API from js.
62   void SetAccessibilityFocus(int32_t node_id);
63   ui::AXNode* GetAccessibilityFocusedNode();
64 
accessibility_focused_id()65   int32_t accessibility_focused_id() { return accessibility_focused_id_; }
66 
67   // Updates or gets this wrapper with the latest state of listeners in js.
68   void EventListenerAdded(api::automation::EventType event_type,
69                           ui::AXNode* node);
70   void EventListenerRemoved(api::automation::EventType event_type,
71                             ui::AXNode* node);
72   bool HasEventListener(api::automation::EventType event_type,
73                         ui::AXNode* node);
74 
75   // AXTreeManager overrides.
76   ui::AXNode* GetNodeFromTree(const ui::AXTreeID tree_id,
77                               const ui::AXNode::AXID node_id) const override;
78   ui::AXNode* GetNodeFromTree(const ui::AXNode::AXID node_id) const override;
79   ui::AXTreeID GetTreeID() const override;
80   ui::AXTreeID GetParentTreeID() const override;
81   ui::AXNode* GetRootAsAXNode() const override;
82   ui::AXNode* GetParentNodeFromParentTreeAsAXNode() const override;
83 
84  private:
85   // AXTreeObserver overrides.
86   void OnNodeDataChanged(ui::AXTree* tree,
87                          const ui::AXNodeData& old_node_data,
88                          const ui::AXNodeData& new_node_data) override;
89   void OnNodeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override;
90   void OnAtomicUpdateFinished(ui::AXTree* tree,
91                               bool root_changed,
92                               const std::vector<Change>& changes) override;
93 
94   ui::AXTreeID tree_id_;
95   ui::AXTree tree_;
96   AutomationInternalCustomBindings* owner_;
97   std::vector<int> deleted_node_ids_;
98   std::vector<int> text_changed_node_ids_;
99   ui::AXEventGenerator event_generator_;
100 
101   int32_t accessibility_focused_id_ = ui::AXNode::kInvalidAXID;
102 
103   // Tracks whether a tree change event was sent during unserialization. Tree
104   // changes outside of unserialization do not get reflected here. The value is
105   // reset after unserialization.
106   bool did_send_tree_change_during_unserialization_ = false;
107 
108   // Maps a node to a set containing events for which the node has listeners.
109   std::map<int32_t, std::set<api::automation::EventType>> node_id_to_events_;
110 
111   DISALLOW_COPY_AND_ASSIGN(AutomationAXTreeWrapper);
112 };
113 
114 }  // namespace extensions
115 
116 #endif  // EXTENSIONS_RENDERER_API_AUTOMATION_AUTOMATION_AX_TREE_WRAPPER_H_
117