Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/speech/extension_api/tts_engine_extension_api.h" | 5 #include "chrome/browser/speech/extension_api/tts_engine_extension_api.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| 11 #include "chrome/browser/extensions/extension_event_router.h" | 11 #include "chrome/browser/extensions/extension_event_router.h" |
| 12 #include "chrome/browser/extensions/extension_service.h" | 12 #include "chrome/browser/extensions/extension_service.h" |
| 13 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/browser/speech/extension_api/tts_extension_api_constants.h" | 14 #include "chrome/browser/speech/extension_api/tts_extension_api_constants.h" |
| 15 #include "chrome/browser/speech/extension_api/tts_extension_api_controller.h" | 15 #include "chrome/browser/speech/extension_api/tts_extension_api_controller.h" |
| 16 #include "chrome/common/extensions/extension.h" | 16 #include "chrome/common/extensions/extension.h" |
| 17 | 17 |
| 18 using extensions::Extension; | 18 using extensions::Extension; |
| 19 | 19 |
| 20 namespace constants = tts_extension_api_constants; | 20 namespace constants = tts_extension_api_constants; |
| 21 | 21 |
| 22 namespace events { | 22 namespace events { |
| 23 const char kOnSpeak[] = "ttsEngine.onSpeak"; | 23 const char kOnSpeak[] = "ttsEngine.onSpeak"; |
| 24 const char kOnStop[] = "ttsEngine.onStop"; | 24 const char kOnStop[] = "ttsEngine.onStop"; |
| 25 }; // namespace events | 25 }; // namespace events |
| 26 | 26 |
| 27 namespace { | |
| 28 // Given a language/region code of the form 'fr-FR', returns just the basic | |
| 29 // language portion, e.g. 'fr'. | |
| 30 std::string TrimLanguageCode(std::string lang) { | |
| 31 if (lang.size() >= 5 && lang[2] == '-') | |
| 32 return lang.substr(0, 2); | |
| 33 else | |
| 34 return lang; | |
| 35 } | |
| 36 } | |
| 37 | |
| 27 void GetExtensionVoices(Profile* profile, ListValue* result_voices) { | 38 void GetExtensionVoices(Profile* profile, ListValue* result_voices) { |
| 28 ExtensionService* service = profile->GetExtensionService(); | 39 ExtensionService* service = profile->GetExtensionService(); |
| 29 DCHECK(service); | 40 DCHECK(service); |
| 30 ExtensionEventRouter* event_router = profile->GetExtensionEventRouter(); | 41 ExtensionEventRouter* event_router = profile->GetExtensionEventRouter(); |
| 31 DCHECK(event_router); | 42 DCHECK(event_router); |
| 32 | 43 |
| 33 const ExtensionSet* extensions = service->extensions(); | 44 const ExtensionSet* extensions = service->extensions(); |
| 34 ExtensionSet::const_iterator iter; | 45 ExtensionSet::const_iterator iter; |
| 35 for (iter = extensions->begin(); iter != extensions->end(); ++iter) { | 46 for (iter = extensions->begin(); iter != extensions->end(); ++iter) { |
| 36 const Extension* extension = *iter; | 47 const Extension* extension = *iter; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 90 ExtensionService* service = utterance->profile()->GetExtensionService(); | 101 ExtensionService* service = utterance->profile()->GetExtensionService(); |
| 91 DCHECK(service); | 102 DCHECK(service); |
| 92 ExtensionEventRouter* event_router = | 103 ExtensionEventRouter* event_router = |
| 93 utterance->profile()->GetExtensionEventRouter(); | 104 utterance->profile()->GetExtensionEventRouter(); |
| 94 DCHECK(event_router); | 105 DCHECK(event_router); |
| 95 | 106 |
| 96 *matching_extension = NULL; | 107 *matching_extension = NULL; |
| 97 *voice_index = -1; | 108 *voice_index = -1; |
| 98 const ExtensionSet* extensions = service->extensions(); | 109 const ExtensionSet* extensions = service->extensions(); |
| 99 ExtensionSet::const_iterator iter; | 110 ExtensionSet::const_iterator iter; |
| 100 for (iter = extensions->begin(); iter != extensions->end(); ++iter) { | |
| 101 const Extension* extension = *iter; | |
| 102 | 111 |
| 103 if (!event_router->ExtensionHasEventListener( | 112 // Make two passes: the first time, do strict language matching |
| 104 extension->id(), events::kOnSpeak) || | 113 // ('fr-FR' does not match 'fr-CA'). The second time, do prefix |
| 105 !event_router->ExtensionHasEventListener( | 114 // language matching ('fr-FR' matches 'fr' and 'fr-CA') |
| 106 extension->id(), events::kOnStop)) { | 115 for (int pass = 0; pass < 2; ++pass) { |
| 107 continue; | 116 for (iter = extensions->begin(); iter != extensions->end(); ++iter) { |
| 108 } | 117 const Extension* extension = *iter; |
| 109 | 118 |
| 110 if (!utterance->extension_id().empty() && | 119 if (!event_router->ExtensionHasEventListener( |
| 111 utterance->extension_id() != extension->id()) { | 120 extension->id(), events::kOnSpeak) || |
| 112 continue; | 121 !event_router->ExtensionHasEventListener( |
| 113 } | 122 extension->id(), events::kOnStop)) { |
| 114 | |
| 115 const std::vector<Extension::TtsVoice>& tts_voices = | |
| 116 extension->tts_voices(); | |
| 117 for (size_t i = 0; i < tts_voices.size(); ++i) { | |
| 118 const Extension::TtsVoice& voice = tts_voices[i]; | |
| 119 if (!voice.voice_name.empty() && | |
| 120 !utterance->voice_name().empty() && | |
| 121 voice.voice_name != utterance->voice_name()) { | |
| 122 continue; | 123 continue; |
| 123 } | 124 } |
| 124 if (!voice.lang.empty() && | 125 |
| 125 !utterance->lang().empty() && | 126 if (!utterance->extension_id().empty() && |
| 126 voice.lang != utterance->lang()) { | 127 utterance->extension_id() != extension->id()) { |
| 127 continue; | 128 continue; |
| 128 } | 129 } |
| 129 if (!voice.gender.empty() && | 130 |
| 130 !utterance->gender().empty() && | 131 const std::vector<Extension::TtsVoice>& tts_voices = |
| 131 voice.gender != utterance->gender()) { | 132 extension->tts_voices(); |
| 132 continue; | 133 for (size_t i = 0; i < tts_voices.size(); ++i) { |
|
David Tseng
2012/06/20 17:18:30
Use a const iterator here.
dmazzoni
2012/06/20 22:51:12
We're using *i* below - we need to return the voic
David Tseng
2012/06/20 23:38:41
On 2012/06/20 22:51:12, Dominic Mazzoni wrote:
st
| |
| 134 const Extension::TtsVoice& voice = tts_voices[i]; | |
| 135 if (!voice.voice_name.empty() && | |
| 136 !utterance->voice_name().empty() && | |
| 137 voice.voice_name != utterance->voice_name()) { | |
| 138 continue; | |
| 139 } | |
| 140 if (!voice.lang.empty() && !utterance->lang().empty()) { | |
|
David Tseng
2012/06/20 17:18:30
Can you only make two passes to resolve the lang c
dmazzoni
2012/06/20 22:51:12
I think it's necessary to iterate over all extensi
David Tseng
2012/06/20 23:38:41
On 2012/06/20 22:51:12, Dominic Mazzoni wrote:
We
| |
| 141 std::string voice_lang = voice.lang; | |
| 142 std::string utterance_lang = utterance->lang(); | |
| 143 if (pass == 1) { | |
| 144 voice_lang = TrimLanguageCode(voice_lang); | |
| 145 utterance_lang = TrimLanguageCode(utterance_lang); | |
| 146 } | |
| 147 if (voice_lang != utterance_lang) | |
| 148 continue; | |
| 149 } | |
| 150 if (!voice.gender.empty() && | |
| 151 !utterance->gender().empty() && | |
| 152 voice.gender != utterance->gender()) { | |
| 153 continue; | |
| 154 } | |
| 155 if (utterance->required_event_types().size() > 0) { | |
| 156 bool has_all_required_event_types = true; | |
| 157 for (std::set<std::string>::const_iterator iter = | |
| 158 utterance->required_event_types().begin(); | |
| 159 iter != utterance->required_event_types().end(); | |
| 160 ++iter) { | |
| 161 if (voice.event_types.find(*iter) == voice.event_types.end()) { | |
| 162 has_all_required_event_types = false; | |
| 163 break; | |
| 164 } | |
| 165 } | |
| 166 if (!has_all_required_event_types) | |
| 167 continue; | |
| 168 } | |
| 169 | |
| 170 *matching_extension = extension; | |
| 171 *voice_index = i; | |
| 172 return true; | |
| 133 } | 173 } |
| 134 if (utterance->required_event_types().size() > 0) { | |
| 135 bool has_all_required_event_types = true; | |
| 136 for (std::set<std::string>::const_iterator iter = | |
| 137 utterance->required_event_types().begin(); | |
| 138 iter != utterance->required_event_types().end(); | |
| 139 ++iter) { | |
| 140 if (voice.event_types.find(*iter) == voice.event_types.end()) { | |
| 141 has_all_required_event_types = false; | |
| 142 break; | |
| 143 } | |
| 144 } | |
| 145 if (!has_all_required_event_types) | |
| 146 continue; | |
| 147 } | |
| 148 | |
| 149 *matching_extension = extension; | |
| 150 *voice_index = i; | |
| 151 return true; | |
| 152 } | 174 } |
| 153 } | 175 } |
| 154 | 176 |
| 155 return false; | 177 return false; |
| 156 } | 178 } |
| 157 | 179 |
| 158 void ExtensionTtsEngineSpeak(Utterance* utterance, | 180 void ExtensionTtsEngineSpeak(Utterance* utterance, |
| 159 const Extension* extension, | 181 const Extension* extension, |
| 160 size_t voice_index) { | 182 size_t voice_index) { |
| 161 // See if the engine supports the "end" event; if so, we can keep the | 183 // See if the engine supports the "end" event; if so, we can keep the |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 std::string error_message; | 283 std::string error_message; |
| 262 event->GetString(constants::kErrorMessageKey, &error_message); | 284 event->GetString(constants::kErrorMessageKey, &error_message); |
| 263 controller->OnTtsEvent( | 285 controller->OnTtsEvent( |
| 264 utterance_id, TTS_EVENT_ERROR, char_index, error_message); | 286 utterance_id, TTS_EVENT_ERROR, char_index, error_message); |
| 265 } else { | 287 } else { |
| 266 EXTENSION_FUNCTION_VALIDATE(false); | 288 EXTENSION_FUNCTION_VALIDATE(false); |
| 267 } | 289 } |
| 268 | 290 |
| 269 return true; | 291 return true; |
| 270 } | 292 } |
| OLD | NEW |