1 // Copyright (c) 2012 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 "chrome/common/extensions/api/input_ime/input_components_handler.h" 6 7 #include "base/memory/scoped_ptr.h" 8 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_util.h" 10 #include "base/strings/utf_string_conversions.h" 11 #include "base/values.h" 12 #include "chrome/common/extensions/extension.h" 13 #include "chrome/common/extensions/extension_manifest_constants.h" 14 #include "chrome/common/extensions/manifest.h" 15 #include "chrome/common/extensions/manifest_url_handler.h" 16 #include "extensions/common/error_utils.h" 17 18 namespace keys = extension_manifest_keys; 19 namespace errors = extension_manifest_errors; 20 21 namespace extensions { 22 23 InputComponentInfo::InputComponentInfo() 24 : type(INPUT_COMPONENT_TYPE_NONE), 25 shortcut_alt(false), 26 shortcut_ctrl(false), 27 shortcut_shift(false) { 28 } 29 30 InputComponentInfo::~InputComponentInfo() {} 31 32 InputComponents::InputComponents() {} 33 InputComponents::~InputComponents() {} 34 35 // static 36 const std::vector<InputComponentInfo>* InputComponents::GetInputComponents( 37 const Extension* extension) { 38 InputComponents* info = static_cast<InputComponents*>( 39 extension->GetManifestData(keys::kInputComponents)); 40 return info ? &info->input_components : NULL; 41 } 42 43 InputComponentsHandler::InputComponentsHandler() { 44 } 45 46 InputComponentsHandler::~InputComponentsHandler() { 47 } 48 49 bool InputComponentsHandler::Parse(Extension* extension, 50 string16* error) { 51 scoped_ptr<InputComponents> info(new InputComponents); 52 const base::ListValue* list_value = NULL; 53 if (!extension->manifest()->GetList(keys::kInputComponents, &list_value)) { 54 *error = ASCIIToUTF16(errors::kInvalidInputComponents); 55 return false; 56 } 57 for (size_t i = 0; i < list_value->GetSize(); ++i) { 58 const base::DictionaryValue* module_value = NULL; 59 std::string name_str; 60 InputComponentType type; 61 std::string id_str; 62 std::string description_str; 63 std::set<std::string> languages; 64 std::set<std::string> layouts; 65 std::string shortcut_keycode_str; 66 bool shortcut_alt = false; 67 bool shortcut_ctrl = false; 68 bool shortcut_shift = false; 69 70 if (!list_value->GetDictionary(i, &module_value)) { 71 *error = ASCIIToUTF16(errors::kInvalidInputComponents); 72 return false; 73 } 74 75 // Get input_components[i].name. 76 if (!module_value->GetString(keys::kName, &name_str)) { 77 *error = ErrorUtils::FormatErrorMessageUTF16( 78 errors::kInvalidInputComponentName, 79 base::IntToString(i)); 80 return false; 81 } 82 83 // Get input_components[i].type. 84 std::string type_str; 85 if (module_value->GetString(keys::kType, &type_str)) { 86 if (type_str == "ime") { 87 type = INPUT_COMPONENT_TYPE_IME; 88 } else { 89 *error = ErrorUtils::FormatErrorMessageUTF16( 90 errors::kInvalidInputComponentType, 91 base::IntToString(i)); 92 return false; 93 } 94 } else { 95 *error = ErrorUtils::FormatErrorMessageUTF16( 96 errors::kInvalidInputComponentType, 97 base::IntToString(i)); 98 return false; 99 } 100 101 // Get input_components[i].id. 102 if (!module_value->GetString(keys::kId, &id_str)) { 103 id_str = ""; 104 } 105 106 // Get input_components[i].description. 107 if (!module_value->GetString(keys::kDescription, &description_str)) { 108 *error = ErrorUtils::FormatErrorMessageUTF16( 109 errors::kInvalidInputComponentDescription, 110 base::IntToString(i)); 111 return false; 112 } 113 114 // Get input_components[i].language. 115 // Both string and list of string are allowed to be compatibile with old 116 // input_ime manifest specification. 117 const base::Value* language_value = NULL; 118 if (module_value->Get(keys::kLanguage, &language_value)) { 119 if (language_value->GetType() == base::Value::TYPE_STRING) { 120 std::string language_str; 121 language_value->GetAsString(&language_str); 122 languages.insert(language_str); 123 } else if (language_value->GetType() == base::Value::TYPE_LIST) { 124 const base::ListValue* language_list = NULL; 125 language_value->GetAsList(&language_list); 126 for (size_t j = 0; j < language_list->GetSize(); ++j) { 127 std::string language_str; 128 if (language_list->GetString(j, &language_str)) 129 languages.insert(language_str); 130 } 131 } 132 } 133 134 // Get input_components[i].layouts. 135 const base::ListValue* layouts_value = NULL; 136 if (module_value->GetList(keys::kLayouts, &layouts_value)) { 137 for (size_t j = 0; j < layouts_value->GetSize(); ++j) { 138 std::string layout_name_str; 139 if (!layouts_value->GetString(j, &layout_name_str)) { 140 *error = ErrorUtils::FormatErrorMessageUTF16( 141 errors::kInvalidInputComponentLayoutName, 142 base::IntToString(i), base::IntToString(j)); 143 return false; 144 } 145 layouts.insert(layout_name_str); 146 } 147 } 148 149 if (module_value->HasKey(keys::kShortcutKey)) { 150 const DictionaryValue* shortcut_value = NULL; 151 if (!module_value->GetDictionary(keys::kShortcutKey, 152 &shortcut_value)) { 153 *error = ErrorUtils::FormatErrorMessageUTF16( 154 errors::kInvalidInputComponentShortcutKey, 155 base::IntToString(i)); 156 return false; 157 } 158 159 // Get input_components[i].shortcut_keycode. 160 if (!shortcut_value->GetString(keys::kKeycode, &shortcut_keycode_str)) { 161 *error = ErrorUtils::FormatErrorMessageUTF16( 162 errors::kInvalidInputComponentShortcutKeycode, 163 base::IntToString(i)); 164 return false; 165 } 166 167 // Get input_components[i].shortcut_alt. 168 if (!shortcut_value->GetBoolean(keys::kAltKey, &shortcut_alt)) { 169 shortcut_alt = false; 170 } 171 172 // Get input_components[i].shortcut_ctrl. 173 if (!shortcut_value->GetBoolean(keys::kCtrlKey, &shortcut_ctrl)) { 174 shortcut_ctrl = false; 175 } 176 177 // Get input_components[i].shortcut_shift. 178 if (!shortcut_value->GetBoolean(keys::kShiftKey, &shortcut_shift)) { 179 shortcut_shift = false; 180 } 181 } 182 183 info->input_components.push_back(InputComponentInfo()); 184 info->input_components.back().name = name_str; 185 info->input_components.back().type = type; 186 info->input_components.back().id = id_str; 187 info->input_components.back().description = description_str; 188 info->input_components.back().languages = languages; 189 info->input_components.back().layouts.insert(layouts.begin(), 190 layouts.end()); 191 info->input_components.back().shortcut_keycode = shortcut_keycode_str; 192 info->input_components.back().shortcut_alt = shortcut_alt; 193 info->input_components.back().shortcut_ctrl = shortcut_ctrl; 194 info->input_components.back().shortcut_shift = shortcut_shift; 195 info->input_components.back().options_page_url = 196 extensions::ManifestURL::GetOptionsPage(extension); 197 } 198 extension->SetManifestData(keys::kInputComponents, info.release()); 199 return true; 200 } 201 202 const std::vector<std::string> InputComponentsHandler::Keys() const { 203 return SingleKey(keys::kInputComponents); 204 } 205 206 } // namespace extensions 207