1 // Copyright 2013 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.
5 #include "content/browser/accessibility/accessibility_tree_formatter.h"
9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h"
11 #include "base/files/file_path.h"
12 #include "base/json/json_writer.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "content/browser/accessibility/browser_accessibility_android.h"
19 using base::StringPrintf
;
24 const char* BOOL_ATTRIBUTES
[] = {
47 const char* STRING_ATTRIBUTES
[] = {
51 const char* INT_ATTRIBUTES
[] = {
64 "range_current_value",
65 "text_change_added_count",
66 "text_change_removed_count",
70 void AccessibilityTreeFormatter::Initialize() {
73 void AccessibilityTreeFormatter::AddProperties(
74 const BrowserAccessibility
& node
, base::DictionaryValue
* dict
) {
75 dict
->SetInteger("id", node
.GetId());
77 const BrowserAccessibilityAndroid
* android_node
=
78 static_cast<const BrowserAccessibilityAndroid
*>(&node
);
81 dict
->SetString("class", android_node
->GetClassName());
84 dict
->SetBoolean("checkable", android_node
->IsCheckable());
85 dict
->SetBoolean("checked", android_node
->IsChecked());
86 dict
->SetBoolean("clickable", android_node
->IsClickable());
87 dict
->SetBoolean("collection", android_node
->IsCollection());
88 dict
->SetBoolean("collection_item", android_node
->IsCollectionItem());
89 dict
->SetBoolean("disabled", !android_node
->IsEnabled());
90 dict
->SetBoolean("dismissable", android_node
->IsDismissable());
91 dict
->SetBoolean("editable_text", android_node
->IsEditableText());
92 dict
->SetBoolean("focusable", android_node
->IsFocusable());
93 dict
->SetBoolean("focused", android_node
->IsFocused());
94 dict
->SetBoolean("heading", android_node
->IsHeading());
95 dict
->SetBoolean("hierarchical", android_node
->IsHierarchical());
96 dict
->SetBoolean("invisible", !android_node
->IsVisibleToUser());
97 dict
->SetBoolean("link", android_node
->IsLink());
98 dict
->SetBoolean("multiline", android_node
->IsMultiLine());
99 dict
->SetBoolean("range", android_node
->IsRangeType());
100 dict
->SetBoolean("password", android_node
->IsPassword());
101 dict
->SetBoolean("scrollable", android_node
->IsScrollable());
102 dict
->SetBoolean("selected", android_node
->IsSelected());
104 // String attributes.
105 dict
->SetString("name", android_node
->GetText());
108 dict
->SetInteger("item_index", android_node
->GetItemIndex());
109 dict
->SetInteger("item_count", android_node
->GetItemCount());
110 dict
->SetInteger("row_count", android_node
->RowCount());
111 dict
->SetInteger("column_count", android_node
->ColumnCount());
112 dict
->SetInteger("row_index", android_node
->RowIndex());
113 dict
->SetInteger("row_span", android_node
->RowSpan());
114 dict
->SetInteger("column_index", android_node
->ColumnIndex());
115 dict
->SetInteger("column_span", android_node
->ColumnSpan());
116 dict
->SetInteger("input_type", android_node
->AndroidInputType());
117 dict
->SetInteger("live_region_type", android_node
->AndroidLiveRegionType());
118 dict
->SetInteger("range_min", static_cast<int>(android_node
->RangeMin()));
119 dict
->SetInteger("range_max", static_cast<int>(android_node
->RangeMax()));
120 dict
->SetInteger("range_current_value",
121 static_cast<int>(android_node
->RangeCurrentValue()));
122 dict
->SetInteger("text_change_added_count",
123 android_node
->GetTextChangeAddedCount());
124 dict
->SetInteger("text_change_removed_count",
125 android_node
->GetTextChangeRemovedCount());
128 dict
->SetBoolean("action_scroll_forward", android_node
->CanScrollForward());
129 dict
->SetBoolean("action_scroll_backward", android_node
->CanScrollBackward());
130 dict
->SetBoolean("action_scroll_up", android_node
->CanScrollUp());
131 dict
->SetBoolean("action_scroll_down", android_node
->CanScrollDown());
132 dict
->SetBoolean("action_scroll_left", android_node
->CanScrollLeft());
133 dict
->SetBoolean("action_scroll_right", android_node
->CanScrollRight());
136 base::string16
AccessibilityTreeFormatter::ToString(
137 const base::DictionaryValue
& dict
) {
142 dict
.GetInteger("id", &id_value
);
143 WriteAttribute(true, base::IntToString16(id_value
), &line
);
146 base::string16 class_value
;
147 dict
.GetString("class", &class_value
);
148 WriteAttribute(true, base::UTF16ToUTF8(class_value
), &line
);
150 for (unsigned i
= 0; i
< arraysize(BOOL_ATTRIBUTES
); i
++) {
151 const char* attribute_name
= BOOL_ATTRIBUTES
[i
];
153 if (dict
.GetBoolean(attribute_name
, &value
) && value
)
154 WriteAttribute(true, attribute_name
, &line
);
157 for (unsigned i
= 0; i
< arraysize(STRING_ATTRIBUTES
); i
++) {
158 const char* attribute_name
= STRING_ATTRIBUTES
[i
];
160 if (!dict
.GetString(attribute_name
, &value
) || value
.empty())
163 StringPrintf("%s='%s'", attribute_name
, value
.c_str()),
167 for (unsigned i
= 0; i
< arraysize(INT_ATTRIBUTES
); i
++) {
168 const char* attribute_name
= INT_ATTRIBUTES
[i
];
170 if (!dict
.GetInteger(attribute_name
, &value
) || value
== 0)
173 StringPrintf("%s=%d", attribute_name
, value
),
181 const base::FilePath::StringType
182 AccessibilityTreeFormatter::GetActualFileSuffix() {
183 return FILE_PATH_LITERAL("-actual-android.txt");
187 const base::FilePath::StringType
188 AccessibilityTreeFormatter::GetExpectedFileSuffix() {
189 return FILE_PATH_LITERAL("-expected-android.txt");
193 const std::string
AccessibilityTreeFormatter::GetAllowEmptyString() {
194 return "@ANDROID-ALLOW-EMPTY:";
198 const std::string
AccessibilityTreeFormatter::GetAllowString() {
199 return "@ANDROID-ALLOW:";
203 const std::string
AccessibilityTreeFormatter::GetDenyString() {
204 return "@ANDROID-DENY:";
207 } // namespace content