1 // Copyright 2018 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/accessibility_window_info_data_wrapper.h"
6 
7 #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h"
8 #include "chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h"
9 #include "components/exo/wm_helper.h"
10 #include "ui/accessibility/ax_enums.mojom.h"
11 #include "ui/accessibility/ax_node.h"
12 #include "ui/accessibility/platform/ax_android_constants.h"
13 
14 namespace arc {
15 
AccessibilityWindowInfoDataWrapper(AXTreeSourceArc * tree_source,mojom::AccessibilityWindowInfoData * window)16 AccessibilityWindowInfoDataWrapper::AccessibilityWindowInfoDataWrapper(
17     AXTreeSourceArc* tree_source,
18     mojom::AccessibilityWindowInfoData* window)
19     : AccessibilityInfoDataWrapper(tree_source), window_ptr_(window) {}
20 
IsNode() const21 bool AccessibilityWindowInfoDataWrapper::IsNode() const {
22   return false;
23 }
24 
GetNode() const25 mojom::AccessibilityNodeInfoData* AccessibilityWindowInfoDataWrapper::GetNode()
26     const {
27   return nullptr;
28 }
29 
30 mojom::AccessibilityWindowInfoData*
GetWindow() const31 AccessibilityWindowInfoDataWrapper::GetWindow() const {
32   return window_ptr_;
33 }
34 
GetId() const35 int32_t AccessibilityWindowInfoDataWrapper::GetId() const {
36   return window_ptr_->window_id;
37 }
38 
GetBounds() const39 const gfx::Rect AccessibilityWindowInfoDataWrapper::GetBounds() const {
40   return window_ptr_->bounds_in_screen;
41 }
42 
IsVisibleToUser() const43 bool AccessibilityWindowInfoDataWrapper::IsVisibleToUser() const {
44   return true;
45 }
46 
IsVirtualNode() const47 bool AccessibilityWindowInfoDataWrapper::IsVirtualNode() const {
48   return false;
49 }
50 
IsIgnored() const51 bool AccessibilityWindowInfoDataWrapper::IsIgnored() const {
52   return false;
53 }
54 
IsImportantInAndroid() const55 bool AccessibilityWindowInfoDataWrapper::IsImportantInAndroid() const {
56   return true;
57 }
58 
CanBeAccessibilityFocused() const59 bool AccessibilityWindowInfoDataWrapper::CanBeAccessibilityFocused() const {
60   // Windows are too generic to be Accessibility focused in Chrome, although
61   // they can be Accessibility focused in Android by virtue of having
62   // accessibility focus on nodes within themselves.
63   return false;
64 }
65 
IsAccessibilityFocusableContainer() const66 bool AccessibilityWindowInfoDataWrapper::IsAccessibilityFocusableContainer()
67     const {
68   return tree_source_->GetRoot()->GetId() == GetId();
69 }
70 
PopulateAXRole(ui::AXNodeData * out_data) const71 void AccessibilityWindowInfoDataWrapper::PopulateAXRole(
72     ui::AXNodeData* out_data) const {
73   if (tree_source_->is_notification()) {
74     // Notification window doesn't have window type. As the notification window
75     // is a part of notification center UI, use generic container role.
76     out_data->role = ax::mojom::Role::kGenericContainer;
77     return;
78   }
79   switch (window_ptr_->window_type) {
80     case mojom::AccessibilityWindowType::TYPE_ACCESSIBILITY_OVERLAY:
81       out_data->role = ax::mojom::Role::kWindow;
82       return;
83     case mojom::AccessibilityWindowType::TYPE_APPLICATION:
84       out_data->role = ax::mojom::Role::kApplication;
85       return;
86     case mojom::AccessibilityWindowType::TYPE_INPUT_METHOD:
87       out_data->role = ax::mojom::Role::kKeyboard;
88       return;
89     case mojom::AccessibilityWindowType::TYPE_SPLIT_SCREEN_DIVIDER:
90       // A system window used to divide the screen in split-screen mode. This
91       // type of window is present only in split-screen mode.
92       out_data->role = ax::mojom::Role::kSplitter;
93       return;
94     case mojom::AccessibilityWindowType::TYPE_SYSTEM:
95       out_data->role = ax::mojom::Role::kWindow;
96       return;
97   }
98 }
99 
PopulateAXState(ui::AXNodeData * out_data) const100 void AccessibilityWindowInfoDataWrapper::PopulateAXState(
101     ui::AXNodeData* out_data) const {
102   // ARC++ window states are not reflected in ax::mojom::State, and for the
103   // most part aren't needed.
104 }
105 
Serialize(ui::AXNodeData * out_data) const106 void AccessibilityWindowInfoDataWrapper::Serialize(
107     ui::AXNodeData* out_data) const {
108   AccessibilityInfoDataWrapper* root = tree_source_->GetRoot();
109   if (!root)
110     return;
111 
112   AccessibilityInfoDataWrapper::Serialize(out_data);
113 
114   // String properties.
115   const std::string name = ComputeAXName(true);
116   if (!name.empty()) {
117     out_data->SetName(name);
118     out_data->SetNameFrom(ax::mojom::NameFrom::kTitle);
119   }
120 
121   if (root->GetId() == GetId()) {
122     // Make the root window of each ARC task modal unless it's notification.
123     if (!tree_source_->is_notification())
124       out_data->AddBoolAttribute(ax::mojom::BoolAttribute::kModal, true);
125 
126     // Focusable in Android simply means a node within the window is focusable.
127     // The window itself is not focusable in Android, but ChromeVox sets the
128     // focus to the entire window, explicitly specify this.
129     out_data->AddState(ax::mojom::State::kFocusable);
130   }
131 
132   // Not all properties are currently used in Chrome Accessibility.
133 
134   // Boolean properties:
135   // Someday we may want to have a IN_PICTURE_IN_PICTURE_MODE state or a
136   // WINDOW_ACTIVE state, or to map the FOCUSED (i.e. has input focus) or
137   // ACCESSIBILITY_FOCUSED (i.e. some node within this window has accessibility
138   // focus) to new types.
139 
140   // Integer properties:
141   // We could reflect ARC++ window properties like ANCHOR_NODE_ID,
142   // and LAYER_ORDER in ax::mojom::IntAttributes.
143 }
144 
ComputeAXName(bool do_recursive) const145 std::string AccessibilityWindowInfoDataWrapper::ComputeAXName(
146     bool do_recursive) const {
147   std::string title;
148   GetProperty(mojom::AccessibilityWindowStringProperty::TITLE, &title);
149   return title;
150 }
151 
GetChildren(std::vector<AccessibilityInfoDataWrapper * > * children) const152 void AccessibilityWindowInfoDataWrapper::GetChildren(
153     std::vector<AccessibilityInfoDataWrapper*>* children) const {
154   // Populate the children vector by combining the child window IDs with the
155   // root node ID.
156   if (window_ptr_->int_list_properties) {
157     auto it = window_ptr_->int_list_properties->find(
158         mojom::AccessibilityWindowIntListProperty::CHILD_WINDOW_IDS);
159     if (it != window_ptr_->int_list_properties->end()) {
160       for (int32_t id : it->second)
161         children->push_back(tree_source_->GetFromId(id));
162     }
163   }
164 
165   if (window_ptr_->root_node_id)
166     children->push_back(tree_source_->GetFromId(window_ptr_->root_node_id));
167 }
168 
GetProperty(mojom::AccessibilityWindowBooleanProperty prop) const169 bool AccessibilityWindowInfoDataWrapper::GetProperty(
170     mojom::AccessibilityWindowBooleanProperty prop) const {
171   return arc::GetBooleanProperty(window_ptr_, prop);
172 }
173 
GetProperty(mojom::AccessibilityWindowIntProperty prop,int32_t * out_value) const174 bool AccessibilityWindowInfoDataWrapper::GetProperty(
175     mojom::AccessibilityWindowIntProperty prop,
176     int32_t* out_value) const {
177   return arc::GetProperty(window_ptr_->int_properties, prop, out_value);
178 }
179 
HasProperty(mojom::AccessibilityWindowStringProperty prop) const180 bool AccessibilityWindowInfoDataWrapper::HasProperty(
181     mojom::AccessibilityWindowStringProperty prop) const {
182   return arc::HasProperty(window_ptr_->string_properties, prop);
183 }
184 
GetProperty(mojom::AccessibilityWindowStringProperty prop,std::string * out_value) const185 bool AccessibilityWindowInfoDataWrapper::GetProperty(
186     mojom::AccessibilityWindowStringProperty prop,
187     std::string* out_value) const {
188   return arc::GetProperty(window_ptr_->string_properties, prop, out_value);
189 }
190 
GetProperty(mojom::AccessibilityWindowIntListProperty prop,std::vector<int32_t> * out_value) const191 bool AccessibilityWindowInfoDataWrapper::GetProperty(
192     mojom::AccessibilityWindowIntListProperty prop,
193     std::vector<int32_t>* out_value) const {
194   return arc::GetProperty(window_ptr_->int_list_properties, prop, out_value);
195 }
196 
197 }  // namespace arc
198