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 #include "content/common/accessibility_node_data.h" 18 19 using base::StringPrintf; 20 21 namespace content { 22 23 namespace { 24 const char* BOOL_ATTRIBUTES[] = { 25 "checkable", 26 "checked", 27 "clickable", 28 "disabled", 29 "editable_text", 30 "focusable", 31 "focused", 32 "invisible", 33 "password", 34 "scrollable", 35 "selected" 36 }; 37 38 const char* STRING_ATTRIBUTES[] = { 39 "name" 40 }; 41 42 const char* INT_ATTRIBUTES[] = { 43 "item_index", 44 "item_count" 45 }; 46 } 47 48 void AccessibilityTreeFormatter::Initialize() { 49 } 50 51 void AccessibilityTreeFormatter::AddProperties( 52 const BrowserAccessibility& node, DictionaryValue* dict) { 53 const BrowserAccessibilityAndroid* android_node = 54 static_cast<const BrowserAccessibilityAndroid*>(&node); 55 56 // Class name. 57 dict->SetString("class", android_node->GetClassName()); 58 59 // Bool attributes. 60 dict->SetBoolean("focusable", android_node->IsFocusable()); 61 dict->SetBoolean("focused", android_node->IsFocused()); 62 dict->SetBoolean("clickable", android_node->IsClickable()); 63 dict->SetBoolean("editable_text", android_node->IsEditableText()); 64 dict->SetBoolean("checkable", android_node->IsCheckable()); 65 dict->SetBoolean("checked", android_node->IsChecked()); 66 dict->SetBoolean("disabled", !android_node->IsEnabled()); 67 dict->SetBoolean("scrollable", android_node->IsScrollable()); 68 dict->SetBoolean("password", android_node->IsPassword()); 69 dict->SetBoolean("selected", android_node->IsSelected()); 70 dict->SetBoolean("invisible", !android_node->IsVisibleToUser()); 71 72 // String attributes. 73 dict->SetString("name", android_node->GetText()); 74 75 // Int attributes. 76 dict->SetInteger("item_index", android_node->GetItemIndex()); 77 dict->SetInteger("item_count", android_node->GetItemCount()); 78 } 79 80 bool AccessibilityTreeFormatter::IncludeChildren( 81 const BrowserAccessibility& node) { 82 const BrowserAccessibilityAndroid* android_node = 83 static_cast<const BrowserAccessibilityAndroid*>(&node); 84 return !android_node->IsLeaf(); 85 } 86 87 string16 AccessibilityTreeFormatter::ToString(const DictionaryValue& dict, 88 const string16& indent) { 89 string16 line; 90 91 string16 class_value; 92 dict.GetString("class", &class_value); 93 WriteAttribute(true, UTF16ToUTF8(class_value), &line); 94 95 for (unsigned i = 0; i < arraysize(BOOL_ATTRIBUTES); i++) { 96 const char* attribute_name = BOOL_ATTRIBUTES[i]; 97 bool value; 98 if (dict.GetBoolean(attribute_name, &value) && value) 99 WriteAttribute(true, attribute_name, &line); 100 } 101 102 for (unsigned i = 0; i < arraysize(STRING_ATTRIBUTES); i++) { 103 const char* attribute_name = STRING_ATTRIBUTES[i]; 104 std::string value; 105 if (!dict.GetString(attribute_name, &value) || value.empty()) 106 continue; 107 WriteAttribute(true, 108 StringPrintf("%s='%s'", attribute_name, value.c_str()), 109 &line); 110 } 111 112 for (unsigned i = 0; i < arraysize(INT_ATTRIBUTES); i++) { 113 const char* attribute_name = INT_ATTRIBUTES[i]; 114 int value; 115 if (!dict.GetInteger(attribute_name, &value) || value == 0) 116 continue; 117 WriteAttribute(true, 118 StringPrintf("%s=%d", attribute_name, value), 119 &line); 120 } 121 122 return indent + line + ASCIIToUTF16("\n"); 123 } 124 125 // static 126 const base::FilePath::StringType 127 AccessibilityTreeFormatter::GetActualFileSuffix() { 128 return FILE_PATH_LITERAL("-actual-android.txt"); 129 } 130 131 // static 132 const base::FilePath::StringType 133 AccessibilityTreeFormatter::GetExpectedFileSuffix() { 134 return FILE_PATH_LITERAL("-expected-android.txt"); 135 } 136 137 // static 138 const std::string AccessibilityTreeFormatter::GetAllowEmptyString() { 139 return "@ANDROID-ALLOW-EMPTY:"; 140 } 141 142 // static 143 const std::string AccessibilityTreeFormatter::GetAllowString() { 144 return "@ANDROID-ALLOW:"; 145 } 146 147 // static 148 const std::string AccessibilityTreeFormatter::GetDenyString() { 149 return "@ANDROID-DENY:"; 150 } 151 152 } // namespace content 153