| 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/speech_input_extension_manager.h" | 5 #include "chrome/browser/speech/speech_input_extension_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 277 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 278 base::Bind(&SpeechInputExtensionManager::SetRecognitionResultOnUIThread, | 278 base::Bind(&SpeechInputExtensionManager::SetRecognitionResultOnUIThread, |
| 279 this, result, extension_id)); | 279 this, result, extension_id)); |
| 280 } | 280 } |
| 281 | 281 |
| 282 void SpeechInputExtensionManager::SetRecognitionResultOnUIThread( | 282 void SpeechInputExtensionManager::SetRecognitionResultOnUIThread( |
| 283 const content::SpeechRecognitionResult& result, | 283 const content::SpeechRecognitionResult& result, |
| 284 const std::string& extension_id) { | 284 const std::string& extension_id) { |
| 285 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 285 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 286 | 286 |
| 287 ListValue args; | 287 scoped_ptr<ListValue> args(new ListValue()); |
| 288 DictionaryValue* js_event = new DictionaryValue(); | 288 DictionaryValue* js_event = new DictionaryValue(); |
| 289 args.Append(js_event); | 289 args->Append(js_event); |
| 290 | 290 |
| 291 ListValue* js_hypothesis_array = new ListValue(); | 291 ListValue* js_hypothesis_array = new ListValue(); |
| 292 js_event->Set(kHypothesesKey, js_hypothesis_array); | 292 js_event->Set(kHypothesesKey, js_hypothesis_array); |
| 293 | 293 |
| 294 for (size_t i = 0; i < result.hypotheses.size(); ++i) { | 294 for (size_t i = 0; i < result.hypotheses.size(); ++i) { |
| 295 const SpeechRecognitionHypothesis& hypothesis = result.hypotheses[i]; | 295 const SpeechRecognitionHypothesis& hypothesis = result.hypotheses[i]; |
| 296 | 296 |
| 297 DictionaryValue* js_hypothesis_object = new DictionaryValue(); | 297 DictionaryValue* js_hypothesis_object = new DictionaryValue(); |
| 298 js_hypothesis_array->Append(js_hypothesis_object); | 298 js_hypothesis_array->Append(js_hypothesis_object); |
| 299 | 299 |
| 300 js_hypothesis_object->SetString(kUtteranceKey, | 300 js_hypothesis_object->SetString(kUtteranceKey, |
| 301 UTF16ToUTF8(hypothesis.utterance)); | 301 UTF16ToUTF8(hypothesis.utterance)); |
| 302 js_hypothesis_object->SetDouble(kConfidenceKey, | 302 js_hypothesis_object->SetDouble(kConfidenceKey, |
| 303 hypothesis.confidence); | 303 hypothesis.confidence); |
| 304 } | 304 } |
| 305 | 305 |
| 306 std::string json_args; | 306 DispatchEventToExtension(extension_id, kOnResultEvent, args.Pass()); |
| 307 base::JSONWriter::Write(&args, &json_args); | |
| 308 VLOG(1) << "Results: " << json_args; | |
| 309 DispatchEventToExtension(extension_id, kOnResultEvent, json_args); | |
| 310 } | 307 } |
| 311 | 308 |
| 312 void SpeechInputExtensionManager::OnRecognitionStart(int session_id) { | 309 void SpeechInputExtensionManager::OnRecognitionStart(int session_id) { |
| 313 DCHECK_EQ(session_id, speech_recognition_session_id_); | 310 DCHECK_EQ(session_id, speech_recognition_session_id_); |
| 314 } | 311 } |
| 315 | 312 |
| 316 void SpeechInputExtensionManager::OnAudioStart(int session_id) { | 313 void SpeechInputExtensionManager::OnAudioStart(int session_id) { |
| 317 VLOG(1) << "OnAudioStart"; | 314 VLOG(1) << "OnAudioStart"; |
| 318 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 319 DCHECK_EQ(session_id, speech_recognition_session_id_); | 316 DCHECK_EQ(session_id, speech_recognition_session_id_); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 void SpeechInputExtensionManager::OnEnvironmentEstimationComplete( | 424 void SpeechInputExtensionManager::OnEnvironmentEstimationComplete( |
| 428 int session_id) { | 425 int session_id) { |
| 429 DCHECK_EQ(session_id, speech_recognition_session_id_); | 426 DCHECK_EQ(session_id, speech_recognition_session_id_); |
| 430 } | 427 } |
| 431 | 428 |
| 432 void SpeechInputExtensionManager::OnSoundStart(int session_id) { | 429 void SpeechInputExtensionManager::OnSoundStart(int session_id) { |
| 433 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 430 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 434 DCHECK_EQ(session_id, speech_recognition_session_id_); | 431 DCHECK_EQ(session_id, speech_recognition_session_id_); |
| 435 VLOG(1) << "OnSoundStart"; | 432 VLOG(1) << "OnSoundStart"; |
| 436 | 433 |
| 437 std::string json_args; | |
| 438 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 434 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 439 base::Bind(&SpeechInputExtensionManager::DispatchEventToExtension, | 435 base::Bind(&SpeechInputExtensionManager::DispatchEventToExtension, |
| 440 this, extension_id_in_use_, std::string(kOnSoundStartEvent), | 436 this, extension_id_in_use_, std::string(kOnSoundStartEvent), |
| 441 json_args)); | 437 Passed(scoped_ptr<ListValue>(new ListValue())))); |
| 442 } | 438 } |
| 443 | 439 |
| 444 void SpeechInputExtensionManager::OnSoundEnd(int session_id) { | 440 void SpeechInputExtensionManager::OnSoundEnd(int session_id) { |
| 445 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 441 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 446 VLOG(1) << "OnSoundEnd"; | 442 VLOG(1) << "OnSoundEnd"; |
| 447 | 443 |
| 448 std::string json_args; | |
| 449 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 444 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 450 base::Bind(&SpeechInputExtensionManager::DispatchEventToExtension, | 445 base::Bind(&SpeechInputExtensionManager::DispatchEventToExtension, |
| 451 this, extension_id_in_use_, std::string(kOnSoundEndEvent), | 446 this, extension_id_in_use_, std::string(kOnSoundEndEvent), |
| 452 json_args)); | 447 Passed(scoped_ptr<ListValue>(new ListValue())))); |
| 453 } | 448 } |
| 454 | 449 |
| 455 void SpeechInputExtensionManager::DispatchEventToExtension( | 450 void SpeechInputExtensionManager::DispatchEventToExtension( |
| 456 const std::string& extension_id, const std::string& event, | 451 const std::string& extension_id, const std::string& event, |
| 457 const std::string& json_args) { | 452 scoped_ptr<ListValue> event_args) { |
| 458 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 453 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 459 | 454 |
| 460 base::AutoLock auto_lock(state_lock_); | 455 base::AutoLock auto_lock(state_lock_); |
| 461 if (state_ == kShutdown) | 456 if (state_ == kShutdown) |
| 462 return; | 457 return; |
| 463 | 458 |
| 464 if (profile_ && profile_->GetExtensionEventRouter()) { | 459 if (profile_ && profile_->GetExtensionEventRouter()) { |
| 465 std::string final_args; | |
| 466 if (json_args.empty()) { | |
| 467 ListValue args; | |
| 468 base::JSONWriter::Write(&args, &final_args); | |
| 469 } else { | |
| 470 final_args = json_args; | |
| 471 } | |
| 472 | |
| 473 profile_->GetExtensionEventRouter()->DispatchEventToExtension( | 460 profile_->GetExtensionEventRouter()->DispatchEventToExtension( |
| 474 extension_id, event, final_args, profile_, GURL()); | 461 extension_id, event, event_args.Pass(), profile_, GURL()); |
| 475 } | 462 } |
| 476 } | 463 } |
| 477 | 464 |
| 478 void SpeechInputExtensionManager::DispatchError( | 465 void SpeechInputExtensionManager::DispatchError( |
| 479 const std::string& error, bool dispatch_event) { | 466 const std::string& error, bool dispatch_event) { |
| 480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 481 | 468 |
| 482 std::string extension_id; | 469 std::string extension_id; |
| 483 { | 470 { |
| 484 base::AutoLock auto_lock(state_lock_); | 471 base::AutoLock auto_lock(state_lock_); |
| 485 if (state_ == kShutdown) | 472 if (state_ == kShutdown) |
| 486 return; | 473 return; |
| 487 | 474 |
| 488 extension_id = extension_id_in_use_; | 475 extension_id = extension_id_in_use_; |
| 489 ResetToIdleState(); | 476 ResetToIdleState(); |
| 490 | 477 |
| 491 // Will set the error property in the ongoing extension function calls. | 478 // Will set the error property in the ongoing extension function calls. |
| 492 ExtensionError details(extension_id, error); | 479 ExtensionError details(extension_id, error); |
| 493 content::NotificationService::current()->Notify( | 480 content::NotificationService::current()->Notify( |
| 494 chrome::NOTIFICATION_EXTENSION_SPEECH_INPUT_FAILED, | 481 chrome::NOTIFICATION_EXTENSION_SPEECH_INPUT_FAILED, |
| 495 content::Source<Profile>(profile_), | 482 content::Source<Profile>(profile_), |
| 496 content::Details<ExtensionError>(&details)); | 483 content::Details<ExtensionError>(&details)); |
| 497 } | 484 } |
| 498 | 485 |
| 499 // Used for errors that are also reported via the onError event. | 486 // Used for errors that are also reported via the onError event. |
| 500 if (dispatch_event) { | 487 if (dispatch_event) { |
| 501 ListValue args; | 488 scoped_ptr<ListValue> args(new ListValue()); |
| 502 DictionaryValue* js_error = new DictionaryValue(); | 489 DictionaryValue* js_error = new DictionaryValue(); |
| 503 args.Append(js_error); | 490 args->Append(js_error); |
| 504 js_error->SetString(kErrorCodeKey, error); | 491 js_error->SetString(kErrorCodeKey, error); |
| 505 std::string json_args; | 492 DispatchEventToExtension(extension_id, kOnErrorEvent, args.Pass()); |
| 506 base::JSONWriter::Write(&args, &json_args); | |
| 507 DispatchEventToExtension(extension_id, | |
| 508 kOnErrorEvent, json_args); | |
| 509 } | 493 } |
| 510 } | 494 } |
| 511 | 495 |
| 512 bool SpeechInputExtensionManager::Start( | 496 bool SpeechInputExtensionManager::Start( |
| 513 const std::string& extension_id, const std::string& language, | 497 const std::string& extension_id, const std::string& language, |
| 514 const std::string& grammar, bool filter_profanities, std::string* error) { | 498 const std::string& grammar, bool filter_profanities, std::string* error) { |
| 515 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 499 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 516 DCHECK(error); | 500 DCHECK(error); |
| 517 VLOG(1) << "Requesting start (UI thread)"; | 501 VLOG(1) << "Requesting start (UI thread)"; |
| 518 | 502 |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 content::NotificationService::current()->Notify( | 750 content::NotificationService::current()->Notify( |
| 767 chrome::NOTIFICATION_EXTENSION_SPEECH_INPUT_RECORDING_STOPPED, | 751 chrome::NOTIFICATION_EXTENSION_SPEECH_INPUT_RECORDING_STOPPED, |
| 768 // Guarded by the state_ == kShutdown check. | 752 // Guarded by the state_ == kShutdown check. |
| 769 content::Source<Profile>(profile_), | 753 content::Source<Profile>(profile_), |
| 770 content::Details<std::string>(&extension_id)); | 754 content::Details<std::string>(&extension_id)); |
| 771 } | 755 } |
| 772 | 756 |
| 773 void SpeechInputExtensionManager::OnAudioLevelsChange(int session_id, | 757 void SpeechInputExtensionManager::OnAudioLevelsChange(int session_id, |
| 774 float volume, | 758 float volume, |
| 775 float noise_volume) {} | 759 float noise_volume) {} |
| OLD | NEW |