• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "content/browser/accessibility/accessibility_tree_formatter.h"
6 
7 #include <string>
8 
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_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "content/browser/accessibility/browser_accessibility_android.h"
17 
18 using base::StringPrintf;
19 
20 namespace content {
21 
22 namespace {
23 const char* BOOL_ATTRIBUTES[] = {
24   "checkable",
25   "checked",
26   "clickable",
27   "collection",
28   "collection_item",
29   "content_invalid",
30   "disabled",
31   "dismissable",
32   "editable_text",
33   "focusable",
34   "focused",
35   "heading",
36   "hierarchical",
37   "invisible",
38   "multiline",
39   "password",
40   "range",
41   "scrollable",
42   "selected"
43 };
44 
45 const char* STRING_ATTRIBUTES[] = {
46   "name"
47 };
48 
49 const char* INT_ATTRIBUTES[] = {
50   "item_index",
51   "item_count",
52   "row_count",
53   "column_count",
54   "row_index",
55   "row_span",
56   "column_index",
57   "column_span",
58   "input_type",
59   "live_region_type",
60   "range_min",
61   "range_max",
62   "range_current_value",
63 };
64 }
65 
Initialize()66 void AccessibilityTreeFormatter::Initialize() {
67 }
68 
AddProperties(const BrowserAccessibility & node,base::DictionaryValue * dict)69 void AccessibilityTreeFormatter::AddProperties(
70     const BrowserAccessibility& node, base::DictionaryValue* dict) {
71   const BrowserAccessibilityAndroid* android_node =
72       static_cast<const BrowserAccessibilityAndroid*>(&node);
73 
74   // Class name.
75   dict->SetString("class", android_node->GetClassName());
76 
77   // Bool attributes.
78   dict->SetBoolean("checkable", android_node->IsCheckable());
79   dict->SetBoolean("checked", android_node->IsChecked());
80   dict->SetBoolean("clickable", android_node->IsClickable());
81   dict->SetBoolean("collection", android_node->IsCollection());
82   dict->SetBoolean("collection_item", android_node->IsCollectionItem());
83   dict->SetBoolean("disabled", !android_node->IsEnabled());
84   dict->SetBoolean("dismissable", android_node->IsDismissable());
85   dict->SetBoolean("editable_text", android_node->IsEditableText());
86   dict->SetBoolean("focusable", android_node->IsFocusable());
87   dict->SetBoolean("focused", android_node->IsFocused());
88   dict->SetBoolean("heading", android_node->IsHeading());
89   dict->SetBoolean("hierarchical", android_node->IsHierarchical());
90   dict->SetBoolean("invisible", !android_node->IsVisibleToUser());
91   dict->SetBoolean("multiline", android_node->IsMultiLine());
92   dict->SetBoolean("range", android_node->IsRangeType());
93   dict->SetBoolean("password", android_node->IsPassword());
94   dict->SetBoolean("scrollable", android_node->IsScrollable());
95   dict->SetBoolean("selected", android_node->IsSelected());
96 
97   // String attributes.
98   dict->SetString("name", android_node->GetText());
99 
100   // Int attributes.
101   dict->SetInteger("item_index", android_node->GetItemIndex());
102   dict->SetInteger("item_count", android_node->GetItemCount());
103   dict->SetInteger("row_count", android_node->RowCount());
104   dict->SetInteger("column_count", android_node->ColumnCount());
105   dict->SetInteger("row_index", android_node->RowIndex());
106   dict->SetInteger("row_span", android_node->RowSpan());
107   dict->SetInteger("column_index", android_node->ColumnIndex());
108   dict->SetInteger("column_span", android_node->ColumnSpan());
109   dict->SetInteger("input_type", android_node->AndroidInputType());
110   dict->SetInteger("live_region_type", android_node->AndroidLiveRegionType());
111   dict->SetInteger("range_min", static_cast<int>(android_node->RangeMin()));
112   dict->SetInteger("range_max", static_cast<int>(android_node->RangeMax()));
113   dict->SetInteger("range_current_value",
114                    static_cast<int>(android_node->RangeCurrentValue()));
115 }
116 
ToString(const base::DictionaryValue & dict,const base::string16 & indent)117 base::string16 AccessibilityTreeFormatter::ToString(
118     const base::DictionaryValue& dict,
119     const base::string16& indent) {
120   base::string16 line;
121 
122   base::string16 class_value;
123   dict.GetString("class", &class_value);
124   WriteAttribute(true, base::UTF16ToUTF8(class_value), &line);
125 
126   for (unsigned i = 0; i < arraysize(BOOL_ATTRIBUTES); i++) {
127     const char* attribute_name = BOOL_ATTRIBUTES[i];
128     bool value;
129     if (dict.GetBoolean(attribute_name, &value) && value)
130       WriteAttribute(true, attribute_name, &line);
131   }
132 
133   for (unsigned i = 0; i < arraysize(STRING_ATTRIBUTES); i++) {
134     const char* attribute_name = STRING_ATTRIBUTES[i];
135     std::string value;
136     if (!dict.GetString(attribute_name, &value) || value.empty())
137       continue;
138     WriteAttribute(true,
139                    StringPrintf("%s='%s'", attribute_name, value.c_str()),
140                    &line);
141   }
142 
143   for (unsigned i = 0; i < arraysize(INT_ATTRIBUTES); i++) {
144     const char* attribute_name = INT_ATTRIBUTES[i];
145     int value;
146     if (!dict.GetInteger(attribute_name, &value) || value == 0)
147       continue;
148     WriteAttribute(true,
149                    StringPrintf("%s=%d", attribute_name, value),
150                    &line);
151   }
152 
153   return indent + line + base::ASCIIToUTF16("\n");
154 }
155 
156 // static
157 const base::FilePath::StringType
GetActualFileSuffix()158 AccessibilityTreeFormatter::GetActualFileSuffix() {
159   return FILE_PATH_LITERAL("-actual-android.txt");
160 }
161 
162 // static
163 const base::FilePath::StringType
GetExpectedFileSuffix()164 AccessibilityTreeFormatter::GetExpectedFileSuffix() {
165   return FILE_PATH_LITERAL("-expected-android.txt");
166 }
167 
168 // static
GetAllowEmptyString()169 const std::string AccessibilityTreeFormatter::GetAllowEmptyString() {
170   return "@ANDROID-ALLOW-EMPTY:";
171 }
172 
173 // static
GetAllowString()174 const std::string AccessibilityTreeFormatter::GetAllowString() {
175   return "@ANDROID-ALLOW:";
176 }
177 
178 // static
GetDenyString()179 const std::string AccessibilityTreeFormatter::GetDenyString() {
180   return "@ANDROID-DENY:";
181 }
182 
183 }  // namespace content
184