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

Unified Diff: content/browser/speech/speech_recognition_manager_impl.cc

Issue 10933018: Speech JavaScript API: Use the MediaStreamManager to ask for user permission. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address xians's comments Created 8 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/speech/speech_recognition_manager_impl.cc
diff --git a/content/browser/speech/speech_recognition_manager_impl.cc b/content/browser/speech/speech_recognition_manager_impl.cc
index 06b1d8809730482943747757297ee1fd8483cd04..4461d2f68660bbc25a02b4d205de26b7d6737233 100644
--- a/content/browser/speech/speech_recognition_manager_impl.cc
+++ b/content/browser/speech/speech_recognition_manager_impl.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "content/browser/browser_main_loop.h"
+#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/speech/google_one_shot_remote_engine.h"
#include "content/browser/speech/google_streaming_remote_engine.h"
#include "content/browser/speech/speech_recognition_engine.h"
@@ -17,13 +18,13 @@
#include "content/public/browser/speech_recognition_manager_delegate.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 "media/audio/audio_manager.h"
using base::Callback;
using content::BrowserMainLoop;
using content::BrowserThread;
-using content::SpeechRecognitionError;
using content::SpeechRecognitionEventListener;
using content::SpeechRecognitionManager;
using content::SpeechRecognitionResult;
@@ -50,12 +51,89 @@ void ShowAudioInputSettingsOnFileThread() {
namespace speech {
+class SpeechRecognitionManagerImpl::PermissionRequest
+ : public media_stream::MediaStreamRequester {
+ public:
+ PermissionRequest(media_stream::MediaStreamManager* media_stream_manager,
+ int session_id,
+ const base::Callback<void(bool is_allowed)>& callback)
+ : media_stream_manager_(media_stream_manager),
+ session_id_(session_id),
+ callback_(callback),
+ started_(false) {
+ }
+
+ virtual ~PermissionRequest() {
+ if (started_)
+ Abort();
+ }
+
+ void Start(int render_process_id, int render_view_id, const GURL& origin) {
+ started_ = true;
+ media_stream_manager_->GenerateStream(
+ this,
+ render_process_id,
+ render_view_id,
+ media_stream::StreamOptions(/*audio=*/true, /*video=*/false),
+ origin,
+ &label_);
+ }
+
+ void Abort() {
+ started_ = false;
+ media_stream_manager_->CancelGenerateStream(label_);
+ }
+
+ int Session() const { return session_id_; }
+
+ // MediaStreamRequester methods.
+ virtual void StreamGenerated(
+ const std::string& label,
+ const media_stream::StreamDeviceInfoArray& audio_devices,
+ const media_stream::StreamDeviceInfoArray& video_devices) OVERRIDE {
+ // TODO(hans): One day it would be nice to actually use the generated stream
+ // but right now we only use it to request permission, and then we dump it.
+ started_ = false;
+ BrowserThread::PostTask(
wjia(left Chromium) 2012/09/12 22:58:25 StreamGenerated is called on IO thread. Do you nee
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&media_stream::MediaStreamManager::StopGeneratedStream,
+ base::Unretained(media_stream_manager_),
+ label));
+ callback_.Run(true);
+ }
+
+ virtual void StreamGenerationFailed(const std::string& label) OVERRIDE {
+ started_ = false;
+ callback_.Run(false);
+ }
+
+ // The callbacks below are ignored.
+ virtual void AudioDeviceFailed(const std::string& label,
+ int index) OVERRIDE {}
+ virtual void VideoDeviceFailed(const std::string& label,
+ int index) OVERRIDE {}
+ virtual void DevicesEnumerated(
+ const std::string& label,
+ const media_stream::StreamDeviceInfoArray& devices) OVERRIDE {}
+ virtual void DeviceOpened(
+ const std::string& label,
+ const media_stream::StreamDeviceInfo& device_info) OVERRIDE {}
+
+ private:
+ media_stream::MediaStreamManager* media_stream_manager_;
+ int session_id_;
+ base::Callback<void(bool is_allowed)> callback_;
+ std::string label_;
+ bool started_;
+};
+
SpeechRecognitionManagerImpl* SpeechRecognitionManagerImpl::GetInstance() {
return g_speech_recognition_manager_impl;
}
SpeechRecognitionManagerImpl::SpeechRecognitionManagerImpl()
- : session_id_capturing_audio_(kSessionIDInvalid),
+ : primary_session_id_(kSessionIDInvalid),
last_session_id_(kSessionIDInvalid),
is_dispatching_event_(false),
delegate_(content::GetContentClient()->browser()->
@@ -124,28 +202,63 @@ void SpeechRecognitionManagerImpl::StartSession(int session_id) {
return;
// If there is another active session, abort that.
- if (session_id_capturing_audio_ != kSessionIDInvalid &&
- session_id_capturing_audio_ != session_id) {
- AbortSession(session_id_capturing_audio_);
+ if (primary_session_id_ != kSessionIDInvalid &&
+ primary_session_id_ != session_id) {
+ AbortSession(primary_session_id_);
}
- if (delegate_.get())
+ primary_session_id_ = session_id;
+
+ if (delegate_.get()) {
delegate_->CheckRecognitionIsAllowed(
session_id,
base::Bind(&SpeechRecognitionManagerImpl::RecognitionAllowedCallback,
- weak_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr(),
+ session_id));
+ }
}
void SpeechRecognitionManagerImpl::RecognitionAllowedCallback(int session_id,
+ bool ask_user,
bool is_allowed) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK(SessionExists(session_id));
+ if (!SessionExists(session_id))
+ return;
+
+ if (ask_user) {
+ media_stream::MediaStreamManager* media_stream_manager =
+ BrowserMainLoop::GetMediaStreamManager();
+
+ const SpeechRecognitionSessionContext& context =
+ GetSessionContext(session_id);
+
+ permission_request_.reset(new PermissionRequest(
+ media_stream_manager,
+ session_id,
+ base::Bind(&SpeechRecognitionManagerImpl::RecognitionAllowedCallback,
+ weak_factory_.GetWeakPtr(),
+ session_id,
+ false)));
+
+ permission_request_->Start(context.render_process_id,
+ context.render_view_id,
+ GURL(context.context_name));
+
+ return;
+ }
+
+ permission_request_.reset();
+
if (is_allowed) {
MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(&SpeechRecognitionManagerImpl::DispatchEvent,
weak_factory_.GetWeakPtr(), session_id, EVENT_START));
} else {
- sessions_.erase(session_id);
+ OnRecognitionError(session_id, content::SpeechRecognitionError(
+ content::SPEECH_RECOGNITION_ERROR_NOT_ALLOWED));
+ MessageLoop::current()->PostTask(FROM_HERE,
+ base::Bind(&SpeechRecognitionManagerImpl::DispatchEvent,
+ weak_factory_.GetWeakPtr(), session_id, EVENT_ABORT));
}
}
@@ -154,6 +267,12 @@ void SpeechRecognitionManagerImpl::AbortSession(int session_id) {
if (!SessionExists(session_id))
return;
+ if (permission_request_.get() &&
+ permission_request_->Session() == session_id) {
+ DCHECK(permission_request_.get());
+ permission_request_->Abort();
+ }
+
MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(&SpeechRecognitionManagerImpl::DispatchEvent,
weak_factory_.GetWeakPtr(), session_id, EVENT_ABORT));
@@ -164,6 +283,12 @@ void SpeechRecognitionManagerImpl::StopAudioCaptureForSession(int session_id) {
if (!SessionExists(session_id))
return;
+ if (permission_request_.get() &&
+ permission_request_->Session() == session_id) {
+ DCHECK(permission_request_.get());
+ permission_request_->Abort();
+ }
+
MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(&SpeechRecognitionManagerImpl::DispatchEvent,
weak_factory_.GetWeakPtr(), session_id, EVENT_STOP_CAPTURE));
@@ -179,7 +304,7 @@ void SpeechRecognitionManagerImpl::OnRecognitionStart(int session_id) {
if (!SessionExists(session_id))
return;
- DCHECK_EQ(session_id_capturing_audio_, session_id);
+ DCHECK_EQ(primary_session_id_, session_id);
if (SpeechRecognitionEventListener* delegate_listener = GetDelegateListener())
delegate_listener->OnRecognitionStart(session_id);
if (SpeechRecognitionEventListener* listener = GetListener(session_id))
@@ -191,7 +316,7 @@ void SpeechRecognitionManagerImpl::OnAudioStart(int session_id) {
if (!SessionExists(session_id))
return;
- DCHECK_EQ(session_id_capturing_audio_, session_id);
+ DCHECK_EQ(primary_session_id_, session_id);
if (SpeechRecognitionEventListener* delegate_listener = GetDelegateListener())
delegate_listener->OnAudioStart(session_id);
if (SpeechRecognitionEventListener* listener = GetListener(session_id))
@@ -204,7 +329,7 @@ void SpeechRecognitionManagerImpl::OnEnvironmentEstimationComplete(
if (!SessionExists(session_id))
return;
- DCHECK_EQ(session_id_capturing_audio_, session_id);
+ DCHECK_EQ(primary_session_id_, session_id);
if (SpeechRecognitionEventListener* delegate_listener = GetDelegateListener())
delegate_listener->OnEnvironmentEstimationComplete(session_id);
if (SpeechRecognitionEventListener* listener = GetListener(session_id))
@@ -216,7 +341,7 @@ void SpeechRecognitionManagerImpl::OnSoundStart(int session_id) {
if (!SessionExists(session_id))
return;
- DCHECK_EQ(session_id_capturing_audio_, session_id);
+ DCHECK_EQ(primary_session_id_, session_id);
if (SpeechRecognitionEventListener* delegate_listener = GetDelegateListener())
delegate_listener->OnSoundStart(session_id);
if (SpeechRecognitionEventListener* listener = GetListener(session_id))
@@ -396,9 +521,11 @@ void SpeechRecognitionManagerImpl::ExecuteTransitionAndGetNextState(
case EVENT_START:
return SessionStart(session);
case EVENT_ABORT:
+ return SessionAbort(session);
case EVENT_RECOGNITION_ENDED:
return SessionDelete(session);
case EVENT_STOP_CAPTURE:
+ return SessionStopAudioCapture(session);
case EVENT_AUDIO_ENDED:
return;
}
@@ -448,33 +575,33 @@ SpeechRecognitionManagerImpl::GetSessionState(int session_id) const {
// - Are guaranteed to be not reentrant (themselves and each other);
void SpeechRecognitionManagerImpl::SessionStart(const Session& session) {
- session_id_capturing_audio_ = session.id;
+ DCHECK_EQ(primary_session_id_, session.id);
session.recognizer->StartRecognition();
}
void SpeechRecognitionManagerImpl::SessionAbort(const Session& session) {
- if (session_id_capturing_audio_ == session.id)
- session_id_capturing_audio_ = kSessionIDInvalid;
- DCHECK(session.recognizer.get() && session.recognizer->IsActive());
+ if (primary_session_id_ == session.id)
+ primary_session_id_ = kSessionIDInvalid;
+ DCHECK(session.recognizer.get());
session.recognizer->AbortRecognition();
}
void SpeechRecognitionManagerImpl::SessionStopAudioCapture(
const Session& session) {
- DCHECK(session.recognizer.get() && session.recognizer->IsCapturingAudio());
+ DCHECK(session.recognizer.get());
session.recognizer->StopAudioCapture();
}
void SpeechRecognitionManagerImpl::ResetCapturingSessionId(
const Session& session) {
- DCHECK_EQ(session_id_capturing_audio_, session.id);
- session_id_capturing_audio_ = kSessionIDInvalid;
+ DCHECK_EQ(primary_session_id_, session.id);
+ primary_session_id_ = kSessionIDInvalid;
}
void SpeechRecognitionManagerImpl::SessionDelete(const Session& session) {
DCHECK(session.recognizer == NULL || !session.recognizer->IsActive());
- if (session_id_capturing_audio_ == session.id)
- session_id_capturing_audio_ = kSessionIDInvalid;
+ if (primary_session_id_ == session.id)
+ primary_session_id_ = kSessionIDInvalid;
sessions_.erase(session.id);
}
« no previous file with comments | « content/browser/speech/speech_recognition_manager_impl.h ('k') | content/browser/speech/speech_recognizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698