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

Side by Side Diff: chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc

Issue 2640123004: Initial support for native accessibility in ARC (Closed)
Patch Set: |window| can be nullptr Created 3 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
(Empty)
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 #include "chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h"
6
7 #include "chrome/browser/extensions/api/automation_internal/automation_event_rou ter.h"
8 #include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h"
9 #include "chrome/common/extensions/chrome_extension_messages.h"
10 #include "components/exo/wm_helper.h"
11 #include "ui/accessibility/ax_tree_id_registry.h"
12 #include "ui/aura/window.h"
13
14 namespace {
15
16 ui::AXEvent ToAXEvent(arc::mojom::AccessibilityEventType arc_event_type) {
17 switch (arc_event_type) {
18 case arc::mojom::AccessibilityEventType::VIEW_FOCUSED:
19 case arc::mojom::AccessibilityEventType::VIEW_ACCESSIBILITY_FOCUSED:
20 return ui::AX_EVENT_FOCUS;
21 case arc::mojom::AccessibilityEventType::VIEW_ACCESSIBILITY_FOCUS_CLEARED:
22 return ui::AX_EVENT_BLUR;
23 case arc::mojom::AccessibilityEventType::VIEW_CLICKED:
24 case arc::mojom::AccessibilityEventType::VIEW_LONG_CLICKED:
25 return ui::AX_EVENT_CLICKED;
26 case arc::mojom::AccessibilityEventType::VIEW_TEXT_CHANGED:
27 return ui::AX_EVENT_TEXT_CHANGED;
28 case arc::mojom::AccessibilityEventType::VIEW_TEXT_SELECTION_CHANGED:
29 return ui::AX_EVENT_TEXT_SELECTION_CHANGED;
30 case arc::mojom::AccessibilityEventType::WINDOW_STATE_CHANGED:
31 case arc::mojom::AccessibilityEventType::NOTIFICATION_STATE_CHANGED:
32 case arc::mojom::AccessibilityEventType::WINDOW_CONTENT_CHANGED:
33 case arc::mojom::AccessibilityEventType::WINDOWS_CHANGED:
34 return ui::AX_EVENT_LAYOUT_COMPLETE;
35 case arc::mojom::AccessibilityEventType::VIEW_HOVER_ENTER:
36 return ui::AX_EVENT_FOCUS;
37 case arc::mojom::AccessibilityEventType::ANNOUNCEMENT:
38 return ui::AX_EVENT_ALERT;
39 case arc::mojom::AccessibilityEventType::VIEW_SELECTED:
40 case arc::mojom::AccessibilityEventType::VIEW_HOVER_EXIT:
41 case arc::mojom::AccessibilityEventType::TOUCH_EXPLORATION_GESTURE_START:
42 case arc::mojom::AccessibilityEventType::TOUCH_EXPLORATION_GESTURE_END:
43 case arc::mojom::AccessibilityEventType::VIEW_SCROLLED:
44 case arc::mojom::AccessibilityEventType::
45 VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY:
46 case arc::mojom::AccessibilityEventType::GESTURE_DETECTION_START:
47 case arc::mojom::AccessibilityEventType::GESTURE_DETECTION_END:
48 case arc::mojom::AccessibilityEventType::TOUCH_INTERACTION_START:
49 case arc::mojom::AccessibilityEventType::TOUCH_INTERACTION_END:
50 case arc::mojom::AccessibilityEventType::VIEW_CONTEXT_CLICKED:
51 case arc::mojom::AccessibilityEventType::ASSIST_READING_CONTEXT:
52 return ui::AX_EVENT_CHILDREN_CHANGED;
53 default:
54 return ui::AX_EVENT_CHILDREN_CHANGED;
55 }
56 return ui::AX_EVENT_CHILDREN_CHANGED;
57 }
58
59 } // namespace
60
61 namespace arc {
62
63 AXTreeSourceArc::AXTreeSourceArc()
64 : id_(ui::AXTreeIDRegistry::GetInstance()->CreateID()),
65 current_tree_serializer_(new AXTreeArcSerializer(this)),
66 root_id_(-1),
67 focused_node_id_(-1) {
68 set_owned_by_client();
69 SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
70 }
71
72 AXTreeSourceArc::~AXTreeSourceArc() {
73 Reset();
74 }
75
76 void AXTreeSourceArc::NotifyAccessibilityEvent(
77 mojom::AccessibilityEventData* event_data) {
78 tree_map_.clear();
79 parent_map_.clear();
80 for (size_t i = 0; i < event_data->nodeData.size(); ++i) {
81 for (size_t j = 0; j < event_data->nodeData[i]->childIds.size(); ++j)
82 parent_map_[event_data->nodeData[i]->childIds[j]] =
83 event_data->nodeData[i]->id;
84 }
85
86 for (size_t i = 0; i < event_data->nodeData.size(); ++i) {
87 int32_t id = event_data->nodeData[i]->id;
88 tree_map_[id] = event_data->nodeData[i].get();
89 if (parent_map_.find(id) == parent_map_.end())
90 root_id_ = id;
dmazzoni 2017/02/09 01:18:09 Any other clue that we have the root? Maybe asser
yawano 2017/02/09 10:55:29 Can we simply force that the first element in the
91 }
92
93 ExtensionMsg_AccessibilityEventParams params;
94 current_tree_serializer_->SerializeChanges(GetFromId(event_data->sourceId),
95 &params.update);
96 params.tree_id = id_;
97 params.id = event_data->sourceId;
98 params.event_type = ToAXEvent(event_data->eventType);
99 if (params.event_type == ui::AX_EVENT_FOCUS)
100 focused_node_id_ = params.id;
101
102 extensions::AutomationEventRouter* router =
103 extensions::AutomationEventRouter::GetInstance();
104 router->DispatchAccessibilityEvent(params);
105 }
106
107 bool AXTreeSourceArc::GetTreeData(ui::AXTreeData* data) const {
108 data->tree_id = id_;
109 if (focused_node_id_ >= 0)
110 data->focus_id = focused_node_id_;
111 return true;
112 }
113
114 mojom::AccessibilityNodeInfoData* AXTreeSourceArc::GetRoot() const {
115 mojom::AccessibilityNodeInfoData* root = GetFromId(root_id_);
116 return root;
117 }
118
119 mojom::AccessibilityNodeInfoData* AXTreeSourceArc::GetFromId(int32_t id) const {
120 auto it = tree_map_.find(id);
121 if (it == tree_map_.end())
122 return nullptr;
123 return it->second;
124 }
125
126 int32_t AXTreeSourceArc::GetId(mojom::AccessibilityNodeInfoData* node) const {
127 if (!node)
128 return -1;
129 return node->id;
130 }
131
132 void AXTreeSourceArc::GetChildren(
133 mojom::AccessibilityNodeInfoData* node,
134 std::vector<mojom::AccessibilityNodeInfoData*>* out_children) const {
135 if (!node)
136 return;
137 for (size_t i = 0; i < node->childIds.size(); ++i) {
138 out_children->push_back(GetFromId(node->childIds[i]));
139 }
140 }
141
142 mojom::AccessibilityNodeInfoData* AXTreeSourceArc::GetParent(
143 mojom::AccessibilityNodeInfoData* node) const {
144 if (!node)
145 return nullptr;
146 auto it = parent_map_.find(node->id);
147 if (it != parent_map_.end())
148 return GetFromId(it->second);
149 return nullptr;
150 }
151
152 bool AXTreeSourceArc::IsValid(mojom::AccessibilityNodeInfoData* node) const {
153 return node;
154 }
155
156 bool AXTreeSourceArc::IsEqual(mojom::AccessibilityNodeInfoData* node1,
157 mojom::AccessibilityNodeInfoData* node2) const {
158 if (!node1 || !node2)
159 return false;
160 return node1->id == node2->id;
161 }
162
163 mojom::AccessibilityNodeInfoData* AXTreeSourceArc::GetNull() const {
164 return nullptr;
165 }
166
167 void AXTreeSourceArc::SerializeNode(mojom::AccessibilityNodeInfoData* node,
168 ui::AXNodeData* out_data) const {
169 if (!node)
170 return;
171 out_data->id = node->id;
172 out_data->state = 0;
173 if (!node->text.empty())
174 out_data->SetName(node->text);
175 else if (!node->contentDescription.empty())
176 out_data->SetName(node->contentDescription);
177
178 int32_t id = node->id;
179 if (id == root_id_)
180 out_data->role = ui::AX_ROLE_ROOT_WEB_AREA;
181 else if (!node->text.empty())
182 out_data->role = ui::AX_ROLE_STATIC_TEXT;
183 else
184 out_data->role = ui::AX_ROLE_DIV;
185
186 exo::WMHelper* wmHelper = exo::WMHelper::GetInstance();
187 aura::Window* focused_window = wmHelper->GetFocusedWindow();
dmazzoni 2017/02/09 01:18:09 Maybe try to refactor this out and not call it on
188 gfx::Rect bounds_in_screen = node->boundsInScreen;
189 if (focused_window) {
190 aura::Window* toplevel_window = focused_window->GetToplevelWindow();
191 bounds_in_screen = gfx::ScaleToEnclosingRect(
192 bounds_in_screen,
193 1.0f / toplevel_window->layer()->device_scale_factor());
194 }
195 out_data->location.SetRect(bounds_in_screen.x(), bounds_in_screen.y(),
196 bounds_in_screen.width(),
197 bounds_in_screen.height());
198 }
199
200 void AXTreeSourceArc::GetAccessibleNodeData(ui::AXNodeData* node_data) {
201 node_data->AddIntAttribute(ui::AX_ATTR_CHILD_TREE_ID, id_);
202 node_data->SetName("ExoShell");
203 }
204
205 void AXTreeSourceArc::Reset() {
206 tree_map_.clear();
207 parent_map_.clear();
208 current_tree_serializer_.reset(new AXTreeArcSerializer(this));
209 extensions::AutomationEventRouter* router =
210 extensions::AutomationEventRouter::GetInstance();
211 router->DispatchTreeDestroyedEvent(id_, nullptr);
212 }
213
214 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698