Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1260)

Side by Side Diff: chrome/browser/speech/extension_api/tts_engine_extension_api.cc

Issue 10581011: Fix TTS extension API language matching. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/speech/extension_api/tts_extension_apitest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/speech/extension_api/tts_extension_apitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698