Index: chrome/browser/speech/speech_input_extension_manager.cc |
diff --git a/chrome/browser/speech/speech_input_extension_manager.cc b/chrome/browser/speech/speech_input_extension_manager.cc |
index 67ab90ce1a7fb4e0c9147a5f60caefd583f36d55..7f5da6b6ab6ac17f83a137954a68438a5de18175 100644 |
--- a/chrome/browser/speech/speech_input_extension_manager.cc |
+++ b/chrome/browser/speech/speech_input_extension_manager.cc |
@@ -15,7 +15,6 @@ |
#include "chrome/browser/profiles/profile_dependency_manager.h" |
#include "chrome/browser/profiles/profile_keyed_service.h" |
#include "chrome/browser/profiles/profile_keyed_service_factory.h" |
-#include "chrome/browser/speech/speech_recognition_tray_icon_controller.h" |
#include "chrome/common/chrome_notification_types.h" |
#include "chrome/common/extensions/extension.h" |
#include "chrome/common/pref_names.h" |
@@ -23,9 +22,11 @@ |
#include "content/public/browser/notification_registrar.h" |
#include "content/public/browser/notification_service.h" |
#include "content/public/browser/speech_recognition_manager.h" |
-#include "content/public/browser/speech_recognizer.h" |
+#include "content/public/browser/speech_recognition_session_config.h" |
+#include "content/public/browser/speech_recognition_session_context.h" |
#include "content/public/common/speech_recognition_error.h" |
#include "content/public/common/speech_recognition_result.h" |
+#include "net/url_request/url_request_context_getter.h" |
using content::BrowserThread; |
using content::SpeechRecognitionHypothesis; |
@@ -55,12 +56,6 @@ const char kOnResultEvent[] = "experimental.speechInput.onResult"; |
const char kOnSoundStartEvent[] = "experimental.speechInput.onSoundStart"; |
const char kOnSoundEndEvent[] = "experimental.speechInput.onSoundEnd"; |
-// Session id provided to the speech recognizer. Since only one extension can |
-// be recording on the same time a constant value is enough as id. |
-// TODO(primiano) this will not be valid anymore once speech input extension |
-// will use the SpeechRecognitionManager and not the SpeechRecognizer directly. |
-static const int kSpeechInputSessionId = 1; |
- |
// Wrap an SpeechInputExtensionManager using scoped_refptr to avoid |
// assertion failures on destruction because of not using release(). |
class SpeechInputExtensionManagerWrapper : public ProfileKeyedService { |
@@ -157,7 +152,10 @@ SpeechInputExtensionManager::SpeechInputExtensionManager(Profile* profile) |
: profile_(profile), |
state_(kIdle), |
registrar_(new content::NotificationRegistrar), |
- speech_interface_(NULL) { |
+ speech_interface_(NULL), |
+ is_recognition_in_progress_(false), |
+ speech_recognition_session_id_( |
+ SpeechRecognitionManager::kSessionIDInvalid) { |
registrar_->Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
content::Source<Profile>(profile_)); |
} |
@@ -193,11 +191,14 @@ void SpeechInputExtensionManager::ShutdownOnUIThread() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
VLOG(1) << "Profile shutting down."; |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
+ base::Bind(&SpeechRecognitionManager::AbortAllSessionsForListener, |
+ base::Unretained(SpeechRecognitionManager::GetInstance()), |
+ base::Unretained(this))); |
+ |
base::AutoLock auto_lock(state_lock_); |
DCHECK(state_ != kShutdown); |
if (state_ != kIdle) { |
- DCHECK(notification_.get()); |
- notification_->Hide(); |
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
base::Bind(&SpeechInputExtensionManager::ForceStopOnIOThread, this)); |
} |
@@ -244,7 +245,7 @@ void SpeechInputExtensionManager::OnRecognitionResult( |
int session_id, |
const content::SpeechRecognitionResult& result) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- DCHECK_EQ(session_id, kSpeechInputSessionId); |
+ DCHECK_EQ(session_id, speech_recognition_session_id_); |
// Stopping will start the disassociation with the extension. |
// Make a copy to report the results to the proper one. |
@@ -287,13 +288,13 @@ void SpeechInputExtensionManager::SetRecognitionResultOnUIThread( |
} |
void SpeechInputExtensionManager::OnRecognitionStart(int session_id) { |
- DCHECK_EQ(session_id, kSpeechInputSessionId); |
+ DCHECK_EQ(session_id, speech_recognition_session_id_); |
} |
void SpeechInputExtensionManager::OnAudioStart(int session_id) { |
VLOG(1) << "OnAudioStart"; |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- DCHECK_EQ(session_id, kSpeechInputSessionId); |
+ DCHECK_EQ(session_id, speech_recognition_session_id_); |
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
base::Bind(&SpeechInputExtensionManager::DidStartReceivingAudioOnUIThread, |
@@ -301,11 +302,16 @@ void SpeechInputExtensionManager::OnAudioStart(int session_id) { |
} |
void SpeechInputExtensionManager::OnAudioEnd(int session_id) { |
- DCHECK_EQ(session_id, kSpeechInputSessionId); |
} |
void SpeechInputExtensionManager::OnRecognitionEnd(int session_id) { |
- DCHECK_EQ(session_id, kSpeechInputSessionId); |
+ // In the very exceptional case in which we requested a new recognition before |
+ // the previous one ended, don't clobber the speech_recognition_session_id_. |
+ if (speech_recognition_session_id_ == session_id) { |
+ is_recognition_in_progress_ = false; |
+ speech_recognition_session_id_ = |
+ SpeechRecognitionManager::kSessionIDInvalid; |
+ } |
} |
void SpeechInputExtensionManager::DidStartReceivingAudioOnUIThread() { |
@@ -319,21 +325,9 @@ void SpeechInputExtensionManager::DidStartReceivingAudioOnUIThread() { |
VLOG(1) << "State changed to recording"; |
state_ = kRecording; |
- const Extension* extension = profile_->GetExtensionService()-> |
- GetExtensionById(extension_id_in_use_, true); |
- DCHECK(extension); |
- |
- bool show_notification = !profile_->GetPrefs()->GetBoolean( |
- prefs::kSpeechInputTrayNotificationShown); |
- |
- if (!notification_.get()) |
- notification_ = new SpeechRecognitionTrayIconController(); |
- notification_->Show(UTF8ToUTF16(extension->name()), show_notification); |
- |
- if (show_notification) { |
- profile_->GetPrefs()->SetBoolean( |
- prefs::kSpeechInputTrayNotificationShown, true); |
- } |
+ DCHECK(profile_); |
+ profile_->GetPrefs()->SetBoolean( |
+ prefs::kSpeechInputTrayNotificationShown, true); |
hans
2012/05/15 13:35:17
this looks like a simplification of the old code..
Primiano Tucci (use gerrit)
2012/05/16 10:16:00
The previous code was doing 3 things:
(a) checkin
|
VLOG(1) << "Sending start notification"; |
content::NotificationService::current()->Notify( |
@@ -345,13 +339,13 @@ void SpeechInputExtensionManager::DidStartReceivingAudioOnUIThread() { |
void SpeechInputExtensionManager::OnRecognitionError( |
int session_id, const content::SpeechRecognitionError& error) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- DCHECK_EQ(session_id, kSpeechInputSessionId); |
// Simply return in case of an ERROR_ABORTED, since it is not contemplated |
// in the speech input extensions architecture. |
if (error.code == content::SPEECH_RECOGNITION_ERROR_ABORTED) |
return; |
+ DCHECK_EQ(session_id, speech_recognition_session_id_); |
VLOG(1) << "OnRecognitionError: " << error.code; |
base::AutoLock auto_lock(state_lock_); |
@@ -410,12 +404,12 @@ void SpeechInputExtensionManager::OnRecognitionError( |
void SpeechInputExtensionManager::OnEnvironmentEstimationComplete( |
int session_id) { |
- DCHECK_EQ(session_id, kSpeechInputSessionId); |
+ DCHECK_EQ(session_id, speech_recognition_session_id_); |
} |
void SpeechInputExtensionManager::OnSoundStart(int session_id) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- DCHECK_EQ(session_id, kSpeechInputSessionId); |
+ DCHECK_EQ(session_id, speech_recognition_session_id_); |
VLOG(1) << "OnSoundStart"; |
std::string json_args; |
@@ -427,7 +421,6 @@ void SpeechInputExtensionManager::OnSoundStart(int session_id) { |
void SpeechInputExtensionManager::OnSoundEnd(int session_id) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- DCHECK_EQ(session_id, kSpeechInputSessionId); |
VLOG(1) << "OnSoundEnd"; |
std::string json_args; |
@@ -470,11 +463,6 @@ void SpeechInputExtensionManager::DispatchError( |
if (state_ == kShutdown) |
return; |
- if (state_ == kRecording) { |
- DCHECK(notification_.get()); |
- notification_->Hide(); |
- } |
- |
extension_id = extension_id_in_use_; |
ResetToIdleState(); |
@@ -530,23 +518,37 @@ bool SpeechInputExtensionManager::Start( |
NOTREACHED(); |
} |
+ const Extension* extension = profile_->GetExtensionService()-> |
+ GetExtensionById(extension_id, true); |
+ DCHECK(extension); |
+ const string16& extension_name = UTF8ToUTF16(extension->name()); |
+ |
extension_id_in_use_ = extension_id; |
VLOG(1) << "State changed to starting"; |
state_ = kStarting; |
+ // Checks if the security notification balloon has been already shown (only |
+ // once for a profile). It is reset on DidStartReceivingAudioOnUIThread. |
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = |
+ profile_->GetRequestContext(); |
+ const bool show_notification = !profile_->GetPrefs()->GetBoolean( |
+ prefs::kSpeechInputTrayNotificationShown); |
+ |
BrowserThread::PostTask( |
BrowserThread::IO, FROM_HERE, |
base::Bind(&SpeechInputExtensionManager::StartOnIOThread, this, |
- profile_->GetRequestContext(), language, grammar, |
- filter_profanities)); |
+ url_request_context_getter, extension_name, language, grammar, |
+ filter_profanities, show_notification)); |
return true; |
} |
void SpeechInputExtensionManager::StartOnIOThread( |
- net::URLRequestContextGetter* context_getter, |
+ scoped_refptr<net::URLRequestContextGetter> context_getter, |
+ const string16& extension_name, |
const std::string& language, |
const std::string& grammar, |
- bool filter_profanities) { |
+ bool filter_profanities, |
+ bool show_notification) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
VLOG(1) << "Requesting start (IO thread)"; |
@@ -572,9 +574,13 @@ void SpeechInputExtensionManager::StartOnIOThread( |
return; |
} |
- GetSpeechInputExtensionInterface()->StartRecording( |
- this, context_getter, kSpeechInputSessionId, language, grammar, |
- filter_profanities); |
+ GetSpeechInputExtensionInterface()->StartRecording(this, |
+ context_getter, |
+ extension_name, |
+ language, |
+ grammar, |
+ filter_profanities, |
+ show_notification); |
} |
bool SpeechInputExtensionManager::HasAudioInputDevices() { |
@@ -617,20 +623,41 @@ void SpeechInputExtensionManager::IsRecordingOnUIThread( |
void SpeechInputExtensionManager::StartRecording( |
content::SpeechRecognitionEventListener* listener, |
net::URLRequestContextGetter* context_getter, |
- int session_id, |
+ const string16& extension_name, |
const std::string& language, |
const std::string& grammar, |
- bool filter_profanities) { |
+ bool filter_profanities, |
+ bool show_notification) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- DCHECK(!recognizer_); |
- recognizer_ = content::SpeechRecognizer::Create( |
- listener, session_id, language, grammar, context_getter, |
- filter_profanities, "", ""); |
- recognizer_->StartRecognition(); |
+ |
+ content::SpeechRecognitionSessionContext context; |
+ context.use_bubble_on_element = false; |
+ context.show_security_balloon = show_notification; |
+ context.context_name = extension_name; |
+ |
+ content::SpeechRecognitionSessionConfig config; |
+ // config.is_one_shot = true; // TODO(primiano) Uncomment when CL2.0 lands. |
+ config.language = language; |
+ config.grammar = grammar; |
+ config.initial_context = context; |
+ config.url_request_context_getter = context_getter; |
+ config.filter_profanities = filter_profanities; |
+ config.event_listener = listener; |
+ |
+ DCHECK(!is_recognition_in_progress_); |
+ SpeechRecognitionManager& manager = *SpeechRecognitionManager::GetInstance(); |
+ speech_recognition_session_id_ = |
+ manager.CreateSession(config); |
+ DCHECK_NE(speech_recognition_session_id_, |
+ SpeechRecognitionManager::kSessionIDInvalid); |
+ is_recognition_in_progress_ = true; |
+ manager.StartSession(speech_recognition_session_id_); |
} |
bool SpeechInputExtensionManager::HasValidRecognizer() { |
- return !!recognizer_; |
+ if (!is_recognition_in_progress_) |
+ return false; |
+ return SpeechRecognitionManager::GetInstance()->IsCapturingAudio(); |
} |
bool SpeechInputExtensionManager::Stop(const std::string& extension_id, |
@@ -691,13 +718,13 @@ void SpeechInputExtensionManager::ForceStopOnIOThread() { |
} |
void SpeechInputExtensionManager::StopRecording(bool recognition_failed) { |
- if (recognizer_) { |
- // Recognition is already cancelled in case of failure. |
- // Double-cancelling leads to assertion failures. |
- if (!recognition_failed) |
- recognizer_->AbortRecognition(); |
- recognizer_.release(); |
- } |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ if (!is_recognition_in_progress_) |
+ return; |
+ DCHECK_NE(speech_recognition_session_id_, |
+ SpeechRecognitionManager::kSessionIDInvalid); |
+ SpeechRecognitionManager::GetInstance()->AbortSession( |
+ speech_recognition_session_id_); |
} |
void SpeechInputExtensionManager::StopSucceededOnUIThread() { |
@@ -711,9 +738,6 @@ void SpeechInputExtensionManager::StopSucceededOnUIThread() { |
std::string extension_id = extension_id_in_use_; |
ResetToIdleState(); |
- DCHECK(notification_.get()); |
- notification_->Hide(); |
- |
content::NotificationService::current()->Notify( |
chrome::NOTIFICATION_EXTENSION_SPEECH_INPUT_RECORDING_STOPPED, |
// Guarded by the state_ == kShutdown check. |
@@ -722,18 +746,5 @@ void SpeechInputExtensionManager::StopSucceededOnUIThread() { |
} |
void SpeechInputExtensionManager::OnAudioLevelsChange(int session_id, |
- float volume, |
- float noise_volume) { |
- DCHECK_EQ(session_id, kSpeechInputSessionId); |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
- base::Bind(&SpeechInputExtensionManager::SetInputVolumeOnUIThread, |
- this, volume)); |
-} |
- |
-void SpeechInputExtensionManager::SetInputVolumeOnUIThread( |
- float volume) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DCHECK(notification_.get()); |
- notification_->SetVUMeterVolume(volume); |
-} |
+ float volume, |
+ float noise_volume) {} |