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 
     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 
     66 void AccessibilityTreeFormatter::Initialize() {
     67 }
     68 
     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 
    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
    158 AccessibilityTreeFormatter::GetActualFileSuffix() {
    159   return FILE_PATH_LITERAL("-actual-android.txt");
    160 }
    161 
    162 // static
    163 const base::FilePath::StringType
    164 AccessibilityTreeFormatter::GetExpectedFileSuffix() {
    165   return FILE_PATH_LITERAL("-expected-android.txt");
    166 }
    167 
    168 // static
    169 const std::string AccessibilityTreeFormatter::GetAllowEmptyString() {
    170   return "@ANDROID-ALLOW-EMPTY:";
    171 }
    172 
    173 // static
    174 const std::string AccessibilityTreeFormatter::GetAllowString() {
    175   return "@ANDROID-ALLOW:";
    176 }
    177 
    178 // static
    179 const std::string AccessibilityTreeFormatter::GetDenyString() {
    180   return "@ANDROID-DENY:";
    181 }
    182 
    183 }  // namespace content
    184