Home | History | Annotate | Download | only in accessibility
      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