summaryrefslogtreecommitdiffstats
path: root/content/browser
diff options
context:
space:
mode:
authorallanwoj@chromium.org <allanwoj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-21 16:45:06 +0000
committerallanwoj@chromium.org <allanwoj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-21 16:45:06 +0000
commit0944a72912b25707d953edcf029ab8c96594d825 (patch)
tree90854b8166be197413cfa11bb357e572d2ea5dc8 /content/browser
parentf35a9d1b289827e2f21a23fdafadf5c3c6a21a2d (diff)
downloadchromium_src-0944a72912b25707d953edcf029ab8c96594d825.zip
chromium_src-0944a72912b25707d953edcf029ab8c96594d825.tar.gz
chromium_src-0944a72912b25707d953edcf029ab8c96594d825.tar.bz2
Refactor SpeechInputManager between chrome/ and content/.
Moved requests_ (and related code) to SpeechInputManager. Added some pure virtual methods in SpeechInputManager that are implemented by ChromeSpeechInputManager. BUG=95792 TEST=None Review URL: http://codereview.chromium.org/7838028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102117 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser')
-rw-r--r--content/browser/speech/speech_input_browsertest.cc18
-rw-r--r--content/browser/speech/speech_input_manager.cc156
-rw-r--r--content/browser/speech/speech_input_manager.h92
3 files changed, 259 insertions, 7 deletions
diff --git a/content/browser/speech/speech_input_browsertest.cc b/content/browser/speech/speech_input_browsertest.cc
index 0da6e47..4909a31 100644
--- a/content/browser/speech/speech_input_browsertest.cc
+++ b/content/browser/speech/speech_input_browsertest.cc
@@ -92,6 +92,24 @@ class FakeSpeechInputManager : public SpeechInputManager {
did_cancel_all_ = true;
}
+ protected:
+ virtual void GetRequestInfo(bool* can_report_metrics,
+ std::string* request_info) {}
+ virtual void ShowRecognitionRequested(int caller_id,
+ int render_process_id,
+ int render_view_id,
+ const gfx::Rect& element_rect) {}
+ virtual void ShowWarmUp(int caller_id) {}
+ virtual void ShowRecognizing(int caller_id) {}
+ virtual void ShowRecording(int caller_id) {}
+ virtual void ShowInputVolume(int caller_id,
+ float volume,
+ float noise_volume) {}
+ virtual void ShowNoMicError(int caller_id) {}
+ virtual void ShowRecognizerError(int caller_id,
+ SpeechRecognizer::ErrorCode error) {}
+ virtual void DoClose(int caller_id) {}
+
private:
void SetFakeRecognitionResult() {
if (caller_id_) { // Do a check in case we were cancelled..
diff --git a/content/browser/speech/speech_input_manager.cc b/content/browser/speech/speech_input_manager.cc
index 104d7e8..d115c89 100644
--- a/content/browser/speech/speech_input_manager.cc
+++ b/content/browser/speech/speech_input_manager.cc
@@ -9,10 +9,24 @@
namespace speech_input {
-SpeechInputManager::SpeechInputManager() : censor_results_(true) {
+SpeechInputManager::SpeechInputManager()
+ : can_report_metrics_(false),
+ censor_results_(true),
+ recording_caller_id_(0) {
}
SpeechInputManager::~SpeechInputManager() {
+ while (requests_.begin() != requests_.end())
+ CancelRecognition(requests_.begin()->first);
+}
+
+bool SpeechInputManager::HasPendingRequest(int caller_id) const {
+ return requests_.find(caller_id) != requests_.end();
+}
+
+SpeechInputManagerDelegate* SpeechInputManager::GetDelegate(
+ int caller_id) const {
+ return requests_.find(caller_id)->second.delegate;
}
void SpeechInputManager::ShowAudioInputSettings() {
@@ -30,4 +44,144 @@ void SpeechInputManager::ShowAudioInputSettings() {
AudioManager::GetAudioManager()->ShowAudioInputSettings();
}
+void SpeechInputManager::StartRecognition(
+ SpeechInputManagerDelegate* delegate,
+ int caller_id,
+ int render_process_id,
+ int render_view_id,
+ const gfx::Rect& element_rect,
+ const std::string& language,
+ const std::string& grammar,
+ const std::string& origin_url) {
+ DCHECK(!HasPendingRequest(caller_id));
+
+ ShowRecognitionRequested(
+ caller_id, render_process_id, render_view_id, element_rect);
+ GetRequestInfo(&can_report_metrics_, &request_info_);
+
+ SpeechInputRequest* request = &requests_[caller_id];
+ request->delegate = delegate;
+ request->recognizer = new SpeechRecognizer(
+ this, caller_id, language, grammar, censor_results(),
+ request_info_, can_report_metrics_ ? origin_url : "");
+ request->is_active = false;
+
+ StartRecognitionForRequest(caller_id);
+}
+
+void SpeechInputManager::StartRecognitionForRequest(int caller_id) {
+ DCHECK(HasPendingRequest(caller_id));
+
+ // If we are currently recording audio for another caller, abort that cleanly.
+ if (recording_caller_id_)
+ CancelRecognitionAndInformDelegate(recording_caller_id_);
+
+ if (!AudioManager::GetAudioManager()->HasAudioInputDevices()) {
+ ShowNoMicError(caller_id);
+ } else {
+ recording_caller_id_ = caller_id;
+ requests_[caller_id].is_active = true;
+ requests_[caller_id].recognizer->StartRecording();
+ ShowWarmUp(caller_id);
+ }
+}
+
+void SpeechInputManager::CancelRecognition(int caller_id) {
+ DCHECK(HasPendingRequest(caller_id));
+ if (requests_[caller_id].is_active)
+ requests_[caller_id].recognizer->CancelRecognition();
+ requests_.erase(caller_id);
+ if (recording_caller_id_ == caller_id)
+ recording_caller_id_ = 0;
+ DoClose(caller_id);
+}
+
+void SpeechInputManager::CancelAllRequestsWithDelegate(
+ SpeechInputManagerDelegate* delegate) {
+ SpeechRecognizerMap::iterator it = requests_.begin();
+ while (it != requests_.end()) {
+ if (it->second.delegate == delegate) {
+ CancelRecognition(it->first);
+ // This map will have very few elements so it is simpler to restart.
+ it = requests_.begin();
+ } else {
+ ++it;
+ }
+ }
+}
+
+void SpeechInputManager::StopRecording(int caller_id) {
+ DCHECK(HasPendingRequest(caller_id));
+ requests_[caller_id].recognizer->StopRecording();
+}
+
+void SpeechInputManager::SetRecognitionResult(
+ int caller_id, bool error, const SpeechInputResultArray& result) {
+ DCHECK(HasPendingRequest(caller_id));
+ GetDelegate(caller_id)->SetRecognitionResult(caller_id, result);
+}
+
+void SpeechInputManager::DidCompleteRecording(int caller_id) {
+ DCHECK(recording_caller_id_ == caller_id);
+ DCHECK(HasPendingRequest(caller_id));
+ recording_caller_id_ = 0;
+ GetDelegate(caller_id)->DidCompleteRecording(caller_id);
+ ShowRecognizing(caller_id);
+}
+
+void SpeechInputManager::DidCompleteRecognition(int caller_id) {
+ GetDelegate(caller_id)->DidCompleteRecognition(caller_id);
+ requests_.erase(caller_id);
+ DoClose(caller_id);
+}
+
+void SpeechInputManager::OnRecognizerError(
+ int caller_id, SpeechRecognizer::ErrorCode error) {
+ if (caller_id == recording_caller_id_)
+ recording_caller_id_ = 0;
+ requests_[caller_id].is_active = false;
+ ShowRecognizerError(caller_id, error);
+}
+
+void SpeechInputManager::DidStartReceivingAudio(int caller_id) {
+ DCHECK(HasPendingRequest(caller_id));
+ DCHECK(recording_caller_id_ == caller_id);
+ ShowRecording(caller_id);
+}
+
+void SpeechInputManager::DidCompleteEnvironmentEstimation(int caller_id) {
+ DCHECK(HasPendingRequest(caller_id));
+ DCHECK(recording_caller_id_ == caller_id);
+}
+
+void SpeechInputManager::SetInputVolume(int caller_id, float volume,
+ float noise_volume) {
+ DCHECK(HasPendingRequest(caller_id));
+ DCHECK_EQ(recording_caller_id_, caller_id);
+ ShowInputVolume(caller_id, volume, noise_volume);
+}
+
+void SpeechInputManager::CancelRecognitionAndInformDelegate(
+ int caller_id) {
+ SpeechInputManagerDelegate* cur_delegate = GetDelegate(caller_id);
+ CancelRecognition(caller_id);
+ cur_delegate->DidCompleteRecording(caller_id);
+ cur_delegate->DidCompleteRecognition(caller_id);
+}
+
+void SpeechInputManager::OnFocusChanged(int caller_id) {
+ // Ignore if the caller id was not in our active recognizers list because the
+ // user might have clicked more than once, or recognition could have been
+ // ended due to other reasons before the user click was processed.
+ if (HasPendingRequest(caller_id)) {
+ // If this is an ongoing recording or if we were displaying an error message
+ // to the user, abort it since user has switched focus. Otherwise
+ // recognition has started and keep that going so user can start speaking to
+ // another element while this gets the results in parallel.
+ if (recording_caller_id_ == caller_id || !requests_[caller_id].is_active) {
+ CancelRecognitionAndInformDelegate(caller_id);
+ }
+ }
+}
+
} // namespace speech_input
diff --git a/content/browser/speech/speech_input_manager.h b/content/browser/speech/speech_input_manager.h
index a68e790..afac442 100644
--- a/content/browser/speech/speech_input_manager.h
+++ b/content/browser/speech/speech_input_manager.h
@@ -5,7 +5,11 @@
#ifndef CONTENT_BROWSER_SPEECH_SPEECH_INPUT_MANAGER_H_
#define CONTENT_BROWSER_SPEECH_SPEECH_INPUT_MANAGER_H_
+#include <map>
+#include <string>
+
#include "base/basictypes.h"
+#include "content/browser/speech/speech_recognizer.h"
#include "content/common/content_export.h"
#include "content/common/speech_input_result.h"
#include "ui/gfx/rect.h"
@@ -16,7 +20,7 @@ namespace speech_input {
// handles requests received from various render views and makes sure only one
// of them can use speech recognition at a time. It also sends recognition
// results and status events to the render views when required.
-class SpeechInputManager {
+class SpeechInputManager : public SpeechRecognizerDelegate {
public:
// Implemented by the dispatcher host to relay events to the render views.
class Delegate {
@@ -54,18 +58,94 @@ class SpeechInputManager {
const gfx::Rect& element_rect,
const std::string& language,
const std::string& grammar,
- const std::string& origin_url) = 0;
- virtual void CancelRecognition(int caller_id) = 0;
- virtual void StopRecording(int caller_id) = 0;
-
- virtual void CancelAllRequestsWithDelegate(Delegate* delegate) = 0;
+ const std::string& origin_url);
+ virtual void CancelRecognition(int caller_id);
+ virtual void CancelAllRequestsWithDelegate(Delegate* delegate);
+ virtual void StopRecording(int caller_id);
+
+ // SpeechRecognizer::Delegate methods.
+ virtual void DidStartReceivingAudio(int caller_id);
+ virtual void SetRecognitionResult(int caller_id,
+ bool error,
+ const SpeechInputResultArray& result);
+ virtual void DidCompleteRecording(int caller_id);
+ virtual void DidCompleteRecognition(int caller_id);
+ virtual void OnRecognizerError(int caller_id,
+ SpeechRecognizer::ErrorCode error);
+ virtual void DidCompleteEnvironmentEstimation(int caller_id);
+ virtual void SetInputVolume(int caller_id, float volume, float noise_volume);
void set_censor_results(bool censor) { censor_results_ = censor; }
bool censor_results() { return censor_results_; }
+ protected:
+ // The pure virtual methods are used for displaying the current state of
+ // recognition and for fetching optional request information.
+
+ // Get the optional request information if available.
+ virtual void GetRequestInfo(bool* can_report_metrics,
+ std::string* request_info) = 0;
+
+ // Called when recognition has been requested from point |element_rect_| on
+ // the view port for the given caller.
+ virtual void ShowRecognitionRequested(int caller_id,
+ int render_process_id,
+ int render_view_id,
+ const gfx::Rect& element_rect) = 0;
+
+ // Called when recognition is starting up.
+ virtual void ShowWarmUp(int caller_id) = 0;
+
+ // Called when recognition has started.
+ virtual void ShowRecognizing(int caller_id) = 0;
+
+ // Called when recording has started.
+ virtual void ShowRecording(int caller_id) = 0;
+
+ // Continuously updated with the current input volume.
+ virtual void ShowInputVolume(int caller_id,
+ float volume,
+ float noise_volume) = 0;
+
+ // Called when no microphone has been found.
+ virtual void ShowNoMicError(int caller_id) = 0;
+
+ // Called when there has been a error with the recognition.
+ virtual void ShowRecognizerError(int caller_id,
+ SpeechRecognizer::ErrorCode error) = 0;
+
+ // Called when recognition has ended or has been canceled.
+ virtual void DoClose(int caller_id) = 0;
+
+ // Cancels recognition for the specified caller if it is active.
+ void OnFocusChanged(int caller_id);
+
+ bool HasPendingRequest(int caller_id) const;
+
+ // Starts/restarts recognition for an existing request.
+ void StartRecognitionForRequest(int caller_id);
+
+ void CancelRecognitionAndInformDelegate(int caller_id);
+
private:
+ struct SpeechInputRequest {
+ SpeechInputRequest();
+ ~SpeechInputRequest();
+
+ Delegate* delegate;
+ scoped_refptr<SpeechRecognizer> recognizer;
+ bool is_active; // Set to true when recording or recognition is going on.
+ };
+
+ Delegate* GetDelegate(int caller_id) const;
+
+ typedef std::map<int, SpeechInputRequest> SpeechRecognizerMap;
+ SpeechRecognizerMap requests_;
+ std::string request_info_;
+ bool can_report_metrics_;
bool censor_results_;
+ int recording_caller_id_;
};
// This typedef is to workaround the issue with certain versions of