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 "content/browser/speech/speech_recognition_manager_impl.h" | 5 #include "content/browser/speech/speech_recognition_manager_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "content/browser/browser_main_loop.h" | 8 #include "content/browser/browser_main_loop.h" |
9 #include "content/browser/renderer_host/render_view_host_impl.h" | 9 #include "content/browser/renderer_host/render_view_host_impl.h" |
10 #include "content/browser/speech/input_tag_speech_dispatcher_host.h" | 10 #include "content/browser/speech/input_tag_speech_dispatcher_host.h" |
11 #include "content/browser/speech/speech_recognizer_impl.h" | |
12 #include "content/public/browser/browser_thread.h" | 11 #include "content/public/browser/browser_thread.h" |
13 #include "content/public/browser/content_browser_client.h" | 12 #include "content/public/browser/content_browser_client.h" |
| 13 #include "content/public/browser/speech_recognizer.h" |
14 #include "content/public/browser/render_view_host_delegate.h" | 14 #include "content/public/browser/render_view_host_delegate.h" |
15 #include "content/public/browser/resource_context.h" | 15 #include "content/public/browser/resource_context.h" |
16 #include "content/public/browser/speech_recognition_manager_delegate.h" | 16 #include "content/public/browser/speech_recognition_manager_delegate.h" |
17 #include "content/public/browser/speech_recognition_preferences.h" | 17 #include "content/public/browser/speech_recognition_preferences.h" |
18 #include "content/public/common/view_type.h" | 18 #include "content/public/common/view_type.h" |
| 19 #include "media/audio/audio_manager.h" |
19 | 20 |
20 using content::BrowserMainLoop; | 21 using content::BrowserMainLoop; |
21 using content::BrowserThread; | 22 using content::BrowserThread; |
22 using content::RenderViewHostImpl; | 23 using content::RenderViewHostImpl; |
23 using content::SpeechRecognitionManager; | 24 using content::SpeechRecognitionManager; |
24 using content::SpeechRecognitionManagerDelegate; | 25 using content::SpeechRecognitionManagerDelegate; |
25 | 26 |
26 SpeechRecognitionManager* SpeechRecognitionManager::GetInstance() { | 27 SpeechRecognitionManager* SpeechRecognitionManager::GetInstance() { |
27 return speech::SpeechRecognitionManagerImpl::GetInstance(); | 28 return speech::SpeechRecognitionManagerImpl::GetInstance(); |
28 } | 29 } |
29 | 30 |
30 namespace speech { | 31 namespace speech { |
31 | 32 |
32 struct SpeechRecognitionManagerImpl::SpeechRecognitionParams { | 33 struct SpeechRecognitionManagerImpl::SpeechRecognitionParams { |
33 SpeechRecognitionParams(InputTagSpeechDispatcherHost* delegate, | 34 SpeechRecognitionParams( |
34 int caller_id, | 35 InputTagSpeechDispatcherHost* delegate, |
35 int render_process_id, | 36 int caller_id, |
36 int render_view_id, | 37 int render_process_id, |
37 const gfx::Rect& element_rect, | 38 int render_view_id, |
38 const std::string& language, | 39 const gfx::Rect& element_rect, |
39 const std::string& grammar, | 40 const std::string& language, |
40 const std::string& origin_url, | 41 const std::string& grammar, |
41 net::URLRequestContextGetter* context_getter, | 42 const std::string& origin_url, |
42 content::SpeechRecognitionPreferences* recognition_prefs) | 43 net::URLRequestContextGetter* context_getter, |
| 44 content::SpeechRecognitionPreferences* recognition_prefs) |
43 : delegate(delegate), | 45 : delegate(delegate), |
44 caller_id(caller_id), | 46 caller_id(caller_id), |
45 render_process_id(render_process_id), | 47 render_process_id(render_process_id), |
46 render_view_id(render_view_id), | 48 render_view_id(render_view_id), |
47 element_rect(element_rect), | 49 element_rect(element_rect), |
48 language(language), | 50 language(language), |
49 grammar(grammar), | 51 grammar(grammar), |
50 origin_url(origin_url), | 52 origin_url(origin_url), |
51 context_getter(context_getter), | 53 context_getter(context_getter), |
52 recognition_prefs(recognition_prefs) { | 54 recognition_prefs(recognition_prefs) { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 | 174 |
173 if (delegate_) { | 175 if (delegate_) { |
174 delegate_->ShowRecognitionRequested( | 176 delegate_->ShowRecognitionRequested( |
175 params.caller_id, params.render_process_id, params.render_view_id, | 177 params.caller_id, params.render_process_id, params.render_view_id, |
176 params.element_rect); | 178 params.element_rect); |
177 delegate_->GetRequestInfo(&can_report_metrics_, &request_info_); | 179 delegate_->GetRequestInfo(&can_report_metrics_, &request_info_); |
178 } | 180 } |
179 | 181 |
180 Request* request = &requests_[params.caller_id]; | 182 Request* request = &requests_[params.caller_id]; |
181 request->delegate = params.delegate; | 183 request->delegate = params.delegate; |
182 request->recognizer = new SpeechRecognizerImpl( | 184 request->recognizer = content::SpeechRecognizer::Create( |
183 this, params.caller_id, params.language, params.grammar, | 185 this, params.caller_id, params.language, params.grammar, |
184 params.context_getter, params.recognition_prefs->FilterProfanities(), | 186 params.context_getter, params.recognition_prefs->FilterProfanities(), |
185 request_info_, can_report_metrics_ ? params.origin_url : ""); | 187 request_info_, can_report_metrics_ ? params.origin_url : ""); |
186 request->is_active = false; | 188 request->is_active = false; |
187 | 189 |
188 StartRecognitionForRequest(params.caller_id); | 190 StartRecognitionForRequest(params.caller_id); |
189 } | 191 } |
190 | 192 |
191 void SpeechRecognitionManagerImpl::StartRecognitionForRequest(int caller_id) { | 193 void SpeechRecognitionManagerImpl::StartRecognitionForRequest(int caller_id) { |
192 SpeechRecognizerMap::iterator request = requests_.find(caller_id); | 194 SpeechRecognizerMap::iterator request = requests_.find(caller_id); |
(...skipping 15 matching lines...) Expand all Loading... |
208 SpeechRecognitionManagerDelegate::MIC_ERROR_NO_DEVICE_AVAILABLE); | 210 SpeechRecognitionManagerDelegate::MIC_ERROR_NO_DEVICE_AVAILABLE); |
209 } | 211 } |
210 } else if (IsCapturingAudio()) { | 212 } else if (IsCapturingAudio()) { |
211 if (delegate_) { | 213 if (delegate_) { |
212 delegate_->ShowMicError( | 214 delegate_->ShowMicError( |
213 caller_id, SpeechRecognitionManagerDelegate::MIC_ERROR_DEVICE_IN_USE); | 215 caller_id, SpeechRecognitionManagerDelegate::MIC_ERROR_DEVICE_IN_USE); |
214 } | 216 } |
215 } else { | 217 } else { |
216 recording_caller_id_ = caller_id; | 218 recording_caller_id_ = caller_id; |
217 requests_[caller_id].is_active = true; | 219 requests_[caller_id].is_active = true; |
218 requests_[caller_id].recognizer->StartRecording(); | 220 requests_[caller_id].recognizer->StartRecognition(); |
219 if (delegate_) | 221 if (delegate_) |
220 delegate_->ShowWarmUp(caller_id); | 222 delegate_->ShowWarmUp(caller_id); |
221 } | 223 } |
222 } | 224 } |
223 | 225 |
224 void SpeechRecognitionManagerImpl::CancelRecognitionForRequest(int caller_id) { | 226 void SpeechRecognitionManagerImpl::CancelRecognitionForRequest(int caller_id) { |
225 // Ignore if the caller id was not in our active recognizers list because the | 227 // Ignore if the caller id was not in our active recognizers list because the |
226 // user might have clicked more than once, or recognition could have been | 228 // user might have clicked more than once, or recognition could have been |
227 // ended due to other reasons before the user click was processed. | 229 // ended due to other reasons before the user click was processed. |
228 if (!HasPendingRequest(caller_id)) | 230 if (!HasPendingRequest(caller_id)) |
(...skipping 11 matching lines...) Expand all Loading... |
240 // to the user, abort it since user has switched focus. Otherwise | 242 // to the user, abort it since user has switched focus. Otherwise |
241 // recognition has started and keep that going so user can start speaking to | 243 // recognition has started and keep that going so user can start speaking to |
242 // another element while this gets the results in parallel. | 244 // another element while this gets the results in parallel. |
243 if (recording_caller_id_ == caller_id || !requests_[caller_id].is_active) | 245 if (recording_caller_id_ == caller_id || !requests_[caller_id].is_active) |
244 CancelRecognitionAndInformDelegate(caller_id); | 246 CancelRecognitionAndInformDelegate(caller_id); |
245 } | 247 } |
246 | 248 |
247 void SpeechRecognitionManagerImpl::CancelRecognition(int caller_id) { | 249 void SpeechRecognitionManagerImpl::CancelRecognition(int caller_id) { |
248 DCHECK(HasPendingRequest(caller_id)); | 250 DCHECK(HasPendingRequest(caller_id)); |
249 if (requests_[caller_id].is_active) | 251 if (requests_[caller_id].is_active) |
250 requests_[caller_id].recognizer->CancelRecognition(); | 252 requests_[caller_id].recognizer->AbortRecognition(); |
251 requests_.erase(caller_id); | 253 requests_.erase(caller_id); |
252 if (recording_caller_id_ == caller_id) | 254 if (recording_caller_id_ == caller_id) |
253 recording_caller_id_ = 0; | 255 recording_caller_id_ = 0; |
254 if (delegate_) | 256 if (delegate_) |
255 delegate_->DoClose(caller_id); | 257 delegate_->DoClose(caller_id); |
256 } | 258 } |
257 | 259 |
258 void SpeechRecognitionManagerImpl::CancelAllRequestsWithDelegate( | 260 void SpeechRecognitionManagerImpl::CancelAllRequestsWithDelegate( |
259 InputTagSpeechDispatcherHost* delegate) { | 261 InputTagSpeechDispatcherHost* delegate) { |
260 SpeechRecognizerMap::iterator it = requests_.begin(); | 262 SpeechRecognizerMap::iterator it = requests_.begin(); |
261 while (it != requests_.end()) { | 263 while (it != requests_.end()) { |
262 if (it->second.delegate == delegate) { | 264 if (it->second.delegate == delegate) { |
263 CancelRecognition(it->first); | 265 CancelRecognition(it->first); |
264 // This map will have very few elements so it is simpler to restart. | 266 // This map will have very few elements so it is simpler to restart. |
265 it = requests_.begin(); | 267 it = requests_.begin(); |
266 } else { | 268 } else { |
267 ++it; | 269 ++it; |
268 } | 270 } |
269 } | 271 } |
270 } | 272 } |
271 | 273 |
272 void SpeechRecognitionManagerImpl::StopRecording(int caller_id) { | 274 void SpeechRecognitionManagerImpl::StopRecording(int caller_id) { |
273 // No pending requests on extension popups. | 275 // No pending requests on extension popups. |
274 if (!HasPendingRequest(caller_id)) | 276 if (!HasPendingRequest(caller_id)) |
275 return; | 277 return; |
276 | 278 |
277 requests_[caller_id].recognizer->StopRecording(); | 279 requests_[caller_id].recognizer->StopAudioCapture(); |
278 } | 280 } |
279 | 281 |
280 void SpeechRecognitionManagerImpl::SetRecognitionResult( | 282 // -------- SpeechRecognitionEventListener interface implementation. --------- |
| 283 |
| 284 void SpeechRecognitionManagerImpl::OnRecognitionResult( |
281 int caller_id, const content::SpeechRecognitionResult& result) { | 285 int caller_id, const content::SpeechRecognitionResult& result) { |
282 DCHECK(HasPendingRequest(caller_id)); | 286 DCHECK(HasPendingRequest(caller_id)); |
283 GetDelegate(caller_id)->SetRecognitionResult(caller_id, result); | 287 GetDelegate(caller_id)->SetRecognitionResult(caller_id, result); |
284 } | 288 } |
285 | 289 |
286 void SpeechRecognitionManagerImpl::DidCompleteRecording(int caller_id) { | 290 void SpeechRecognitionManagerImpl::OnAudioEnd(int caller_id) { |
287 DCHECK(recording_caller_id_ == caller_id); | 291 DCHECK_EQ(recording_caller_id_, caller_id); |
288 DCHECK(HasPendingRequest(caller_id)); | 292 DCHECK(HasPendingRequest(caller_id)); |
289 recording_caller_id_ = 0; | 293 recording_caller_id_ = 0; |
290 GetDelegate(caller_id)->DidCompleteRecording(caller_id); | 294 GetDelegate(caller_id)->DidCompleteRecording(caller_id); |
291 if (delegate_) | 295 if (delegate_) |
292 delegate_->ShowRecognizing(caller_id); | 296 delegate_->ShowRecognizing(caller_id); |
293 } | 297 } |
294 | 298 |
295 void SpeechRecognitionManagerImpl::DidCompleteRecognition(int caller_id) { | 299 void SpeechRecognitionManagerImpl::OnRecognitionEnd(int caller_id) { |
296 GetDelegate(caller_id)->DidCompleteRecognition(caller_id); | 300 GetDelegate(caller_id)->DidCompleteRecognition(caller_id); |
297 requests_.erase(caller_id); | 301 requests_.erase(caller_id); |
298 if (delegate_) | 302 if (delegate_) |
299 delegate_->DoClose(caller_id); | 303 delegate_->DoClose(caller_id); |
300 } | 304 } |
301 | 305 |
302 void SpeechRecognitionManagerImpl::DidStartReceivingSpeech(int caller_id) { | 306 void SpeechRecognitionManagerImpl::OnSoundStart(int caller_id) { |
303 } | 307 } |
304 | 308 |
305 void SpeechRecognitionManagerImpl::DidStopReceivingSpeech(int caller_id) { | 309 void SpeechRecognitionManagerImpl::OnSoundEnd(int caller_id) { |
306 } | 310 } |
307 | 311 |
308 void SpeechRecognitionManagerImpl::OnRecognizerError( | 312 void SpeechRecognitionManagerImpl::OnRecognitionError( |
309 int caller_id, content::SpeechRecognitionErrorCode error) { | 313 int caller_id, const content::SpeechRecognitionErrorCode& error) { |
310 if (caller_id == recording_caller_id_) | 314 if (caller_id == recording_caller_id_) |
311 recording_caller_id_ = 0; | 315 recording_caller_id_ = 0; |
312 requests_[caller_id].is_active = false; | 316 requests_[caller_id].is_active = false; |
313 if (delegate_) | 317 if (delegate_) |
314 delegate_->ShowRecognizerError(caller_id, error); | 318 delegate_->ShowRecognizerError(caller_id, error); |
315 } | 319 } |
316 | 320 |
317 void SpeechRecognitionManagerImpl::DidStartReceivingAudio(int caller_id) { | 321 void SpeechRecognitionManagerImpl::OnAudioStart(int caller_id) { |
318 DCHECK(HasPendingRequest(caller_id)); | 322 DCHECK(HasPendingRequest(caller_id)); |
319 DCHECK(recording_caller_id_ == caller_id); | 323 DCHECK_EQ(recording_caller_id_, caller_id); |
320 if (delegate_) | 324 if (delegate_) |
321 delegate_->ShowRecording(caller_id); | 325 delegate_->ShowRecording(caller_id); |
322 } | 326 } |
323 | 327 |
324 void SpeechRecognitionManagerImpl::DidCompleteEnvironmentEstimation( | 328 void SpeechRecognitionManagerImpl::OnRecognitionStart(int caller_id) { |
| 329 } |
| 330 |
| 331 void SpeechRecognitionManagerImpl::OnEnvironmentEstimationComplete( |
325 int caller_id) { | 332 int caller_id) { |
326 DCHECK(HasPendingRequest(caller_id)); | 333 DCHECK(HasPendingRequest(caller_id)); |
327 DCHECK(recording_caller_id_ == caller_id); | 334 DCHECK_EQ(recording_caller_id_, caller_id); |
328 } | 335 } |
329 | 336 |
330 void SpeechRecognitionManagerImpl::SetInputVolume(int caller_id, float volume, | 337 void SpeechRecognitionManagerImpl::OnAudioLevelsChange( |
331 float noise_volume) { | 338 int caller_id, float volume, float noise_volume) { |
332 DCHECK(HasPendingRequest(caller_id)); | 339 DCHECK(HasPendingRequest(caller_id)); |
333 DCHECK_EQ(recording_caller_id_, caller_id); | 340 DCHECK_EQ(recording_caller_id_, caller_id); |
334 if (delegate_) | 341 if (delegate_) |
335 delegate_->ShowInputVolume(caller_id, volume, noise_volume); | 342 delegate_->ShowInputVolume(caller_id, volume, noise_volume); |
336 } | 343 } |
337 | 344 |
338 void SpeechRecognitionManagerImpl::CancelRecognitionAndInformDelegate( | 345 void SpeechRecognitionManagerImpl::CancelRecognitionAndInformDelegate( |
339 int caller_id) { | 346 int caller_id) { |
340 InputTagSpeechDispatcherHost* cur_delegate = GetDelegate(caller_id); | 347 InputTagSpeechDispatcherHost* cur_delegate = GetDelegate(caller_id); |
341 CancelRecognition(caller_id); | 348 CancelRecognition(caller_id); |
342 cur_delegate->DidCompleteRecording(caller_id); | 349 cur_delegate->DidCompleteRecording(caller_id); |
343 cur_delegate->DidCompleteRecognition(caller_id); | 350 cur_delegate->DidCompleteRecognition(caller_id); |
344 } | 351 } |
345 | 352 |
346 SpeechRecognitionManagerImpl::Request::Request() | 353 SpeechRecognitionManagerImpl::Request::Request() |
347 : delegate(NULL), | 354 : delegate(NULL), |
348 is_active(false) { | 355 is_active(false) { |
349 } | 356 } |
350 | 357 |
351 SpeechRecognitionManagerImpl::Request::~Request() { | 358 SpeechRecognitionManagerImpl::Request::~Request() { |
352 } | 359 } |
353 | 360 |
354 } // namespace speech | 361 } // namespace speech |
OLD | NEW |