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/speech/tts_engine_manifest_handler.h" 6 7 #include "base/memory/scoped_ptr.h" 8 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "base/values.h" 11 #include "extensions/common/error_utils.h" 12 #include "extensions/common/manifest.h" 13 #include "extensions/common/manifest_constants.h" 14 #include "ui/base/l10n/l10n_util.h" 15 16 namespace extensions { 17 18 namespace keys = manifest_keys; 19 namespace errors = manifest_errors; 20 21 namespace { 22 23 struct TtsVoices : public Extension::ManifestData { 24 TtsVoices() {} 25 virtual ~TtsVoices() {} 26 27 std::vector<extensions::TtsVoice> voices; 28 }; 29 30 } // namespace 31 32 TtsVoice::TtsVoice() : remote(false) {} 33 34 TtsVoice::~TtsVoice() {} 35 36 // static 37 const std::vector<TtsVoice>* TtsVoice::GetTtsVoices( 38 const Extension* extension) { 39 TtsVoices* info = static_cast<TtsVoices*>( 40 extension->GetManifestData(keys::kTtsVoices)); 41 return info ? &info->voices : NULL; 42 } 43 44 TtsEngineManifestHandler::TtsEngineManifestHandler() { 45 } 46 47 TtsEngineManifestHandler::~TtsEngineManifestHandler() { 48 } 49 50 bool TtsEngineManifestHandler::Parse(Extension* extension, 51 base::string16* error) { 52 scoped_ptr<TtsVoices> info(new TtsVoices); 53 const base::DictionaryValue* tts_dict = NULL; 54 if (!extension->manifest()->GetDictionary(keys::kTtsEngine, &tts_dict)) { 55 *error = ASCIIToUTF16(errors::kInvalidTts); 56 return false; 57 } 58 59 if (!tts_dict->HasKey(keys::kTtsVoices)) 60 return true; 61 62 const base::ListValue* tts_voices = NULL; 63 if (!tts_dict->GetList(keys::kTtsVoices, &tts_voices)) { 64 *error = ASCIIToUTF16(errors::kInvalidTtsVoices); 65 return false; 66 } 67 68 for (size_t i = 0; i < tts_voices->GetSize(); i++) { 69 const base::DictionaryValue* one_tts_voice = NULL; 70 if (!tts_voices->GetDictionary(i, &one_tts_voice)) { 71 *error = ASCIIToUTF16(errors::kInvalidTtsVoices); 72 return false; 73 } 74 75 TtsVoice voice_data; 76 if (one_tts_voice->HasKey(keys::kTtsVoicesVoiceName)) { 77 if (!one_tts_voice->GetString( 78 keys::kTtsVoicesVoiceName, &voice_data.voice_name)) { 79 *error = ASCIIToUTF16(errors::kInvalidTtsVoicesVoiceName); 80 return false; 81 } 82 } 83 if (one_tts_voice->HasKey(keys::kTtsVoicesLang)) { 84 if (!one_tts_voice->GetString( 85 keys::kTtsVoicesLang, &voice_data.lang) || 86 !l10n_util::IsValidLocaleSyntax(voice_data.lang)) { 87 *error = ASCIIToUTF16(errors::kInvalidTtsVoicesLang); 88 return false; 89 } 90 } 91 if (one_tts_voice->HasKey(keys::kTtsVoicesGender)) { 92 if (!one_tts_voice->GetString( 93 keys::kTtsVoicesGender, &voice_data.gender) || 94 (voice_data.gender != keys::kTtsGenderMale && 95 voice_data.gender != keys::kTtsGenderFemale)) { 96 *error = ASCIIToUTF16(errors::kInvalidTtsVoicesGender); 97 return false; 98 } 99 } 100 if (one_tts_voice->HasKey(keys::kTtsVoicesRemote)) { 101 if (!one_tts_voice->GetBoolean( 102 keys::kTtsVoicesRemote, &voice_data.remote)) { 103 *error = ASCIIToUTF16(errors::kInvalidTtsVoicesRemote); 104 return false; 105 } 106 } 107 if (one_tts_voice->HasKey(keys::kTtsVoicesEventTypes)) { 108 const base::ListValue* event_types_list; 109 if (!one_tts_voice->GetList( 110 keys::kTtsVoicesEventTypes, 111 &event_types_list)) { 112 *error = ASCIIToUTF16( 113 errors::kInvalidTtsVoicesEventTypes); 114 return false; 115 } 116 for (size_t i = 0; i < event_types_list->GetSize(); i++) { 117 std::string event_type; 118 if (!event_types_list->GetString(i, &event_type)) { 119 *error = ASCIIToUTF16(errors::kInvalidTtsVoicesEventTypes); 120 return false; 121 } 122 if (event_type != keys::kTtsVoicesEventTypeEnd && 123 event_type != keys::kTtsVoicesEventTypeError && 124 event_type != keys::kTtsVoicesEventTypeMarker && 125 event_type != keys::kTtsVoicesEventTypeSentence && 126 event_type != keys::kTtsVoicesEventTypeStart && 127 event_type != keys::kTtsVoicesEventTypeWord) { 128 *error = ASCIIToUTF16(errors::kInvalidTtsVoicesEventTypes); 129 return false; 130 } 131 if (voice_data.event_types.find(event_type) != 132 voice_data.event_types.end()) { 133 *error = ASCIIToUTF16(errors::kInvalidTtsVoicesEventTypes); 134 return false; 135 } 136 voice_data.event_types.insert(event_type); 137 } 138 } 139 140 info->voices.push_back(voice_data); 141 } 142 143 extension->SetManifestData(keys::kTtsVoices, info.release()); 144 return true; 145 } 146 147 const std::vector<std::string> TtsEngineManifestHandler::Keys() const { 148 return SingleKey(keys::kTtsEngine); 149 } 150 151 } // namespace extensions 152