summaryrefslogtreecommitdiffstats
path: root/content/renderer
diff options
context:
space:
mode:
authorhans@chromium.org <hans@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-25 10:10:34 +0000
committerhans@chromium.org <hans@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-25 10:10:34 +0000
commit64d09224049a393ad66c565299001beab3616c1e (patch)
treed7bb1d841856eaf297087711c6269e2f998057c3 /content/renderer
parentc4205b9ed7bd1096500828e2893036c0f38a51df (diff)
downloadchromium_src-64d09224049a393ad66c565299001beab3616c1e.zip
chromium_src-64d09224049a393ad66c565299001beab3616c1e.tar.gz
chromium_src-64d09224049a393ad66c565299001beab3616c1e.tar.bz2
Introduced SpeechRecognitionDispatcher(Host) classes, handling dispatch of IPC messages for continuous speech recognition. (Speech CL2.1)
BUG=116954 TEST=none Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=138801 Review URL: https://chromiumcodereview.appspot.com/10273006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139015 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer')
-rw-r--r--content/renderer/input_tag_speech_dispatcher.cc2
-rw-r--r--content/renderer/render_view_impl.cc10
-rw-r--r--content/renderer/render_view_impl.h7
-rw-r--r--content/renderer/speech_recognition_dispatcher.cc193
-rw-r--r--content/renderer/speech_recognition_dispatcher.h70
5 files changed, 281 insertions, 1 deletions
diff --git a/content/renderer/input_tag_speech_dispatcher.cc b/content/renderer/input_tag_speech_dispatcher.cc
index 7aa6d9f..41f3dd7 100644
--- a/content/renderer/input_tag_speech_dispatcher.cc
+++ b/content/renderer/input_tag_speech_dispatcher.cc
@@ -81,7 +81,7 @@ void InputTagSpeechDispatcher::cancelRecognition(int request_id) {
void InputTagSpeechDispatcher::stopRecording(int request_id) {
VLOG(1) << "InputTagSpeechDispatcher::stopRecording enter";
Send(new InputTagSpeechHostMsg_StopRecording(routing_id(),
- request_id));
+ request_id));
VLOG(1) << "InputTagSpeechDispatcher::stopRecording exit";
}
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 271c3e7..7cc7ebe 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -89,6 +89,7 @@
#include "content/renderer/renderer_accessibility.h"
#include "content/renderer/renderer_webapplicationcachehost_impl.h"
#include "content/renderer/renderer_webcolorchooser_impl.h"
+#include "content/renderer/speech_recognition_dispatcher.h"
#include "content/renderer/text_input_client_observer.h"
#include "content/renderer/v8_value_converter_impl.h"
#include "content/renderer/web_intents_host.h"
@@ -527,6 +528,7 @@ RenderViewImpl::RenderViewImpl(
ALLOW_THIS_IN_INITIALIZER_LIST(cookie_jar_(this)),
geolocation_dispatcher_(NULL),
input_tag_speech_dispatcher_(NULL),
+ speech_recognition_dispatcher_(NULL),
device_orientation_dispatcher_(NULL),
media_stream_dispatcher_(NULL),
media_stream_impl_(NULL),
@@ -5386,6 +5388,14 @@ WebKit::WebSpeechInputController* RenderViewImpl::speechInputController(
return input_tag_speech_dispatcher_;
}
+WebKit::WebSpeechRecognizer* RenderViewImpl::speechRecognizer() {
+#if defined(ENABLE_INPUT_SPEECH)
+ if (!speech_recognition_dispatcher_)
+ speech_recognition_dispatcher_ = new SpeechRecognitionDispatcher(this);
+#endif
+ return speech_recognition_dispatcher_;
+}
+
WebKit::WebDeviceOrientationClient* RenderViewImpl::deviceOrientationClient() {
if (!device_orientation_dispatcher_)
device_orientation_dispatcher_ = new DeviceOrientationDispatcher(this);
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index 6345287..119ddad 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -81,6 +81,7 @@ class RendererAccessibility;
class RendererWebColorChooserImpl;
class SkBitmap;
class InputTagSpeechDispatcher;
+class SpeechRecognitionDispatcher;
struct ViewMsg_Navigate_Params;
struct ViewMsg_PostMessage_Params;
struct ViewMsg_StopFinding_Params;
@@ -140,6 +141,7 @@ class WebPeerConnectionHandlerClient;
class WebSocketStreamHandle;
class WebSpeechInputController;
class WebSpeechInputListener;
+class WebSpeechRecognizer;
class WebStorageNamespace;
class WebTouchEvent;
class WebURLLoader;
@@ -466,6 +468,7 @@ class RenderViewImpl : public RenderWidget,
virtual WebKit::WebGeolocationClient* geolocationClient();
virtual WebKit::WebSpeechInputController* speechInputController(
WebKit::WebSpeechInputListener* listener);
+ virtual WebKit::WebSpeechRecognizer* speechRecognizer();
virtual WebKit::WebDeviceOrientationClient* deviceOrientationClient();
virtual void zoomLimitsChanged(double minimum_level, double maximum_level);
virtual void zoomLevelChanged();
@@ -1269,6 +1272,10 @@ class RenderViewImpl : public RenderWidget,
// The speech dispatcher attached to this view, lazily initialized.
InputTagSpeechDispatcher* input_tag_speech_dispatcher_;
+ // The speech recognition dispatcher attached to this view, lazily
+ // initialized.
+ SpeechRecognitionDispatcher* speech_recognition_dispatcher_;
+
// Device orientation dispatcher attached to this view; lazily initialized.
DeviceOrientationDispatcher* device_orientation_dispatcher_;
diff --git a/content/renderer/speech_recognition_dispatcher.cc b/content/renderer/speech_recognition_dispatcher.cc
new file mode 100644
index 0000000..90123dd
--- /dev/null
+++ b/content/renderer/speech_recognition_dispatcher.cc
@@ -0,0 +1,193 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/speech_recognition_dispatcher.h"
+
+#include "base/basictypes.h"
+#include "base/utf_string_conversions.h"
+#include "content/common/speech_recognition_messages.h"
+#include "content/renderer/render_view_impl.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSpeechGrammar.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSpeechRecognitionParams.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSpeechRecognitionResult.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSpeechRecognizerClient.h"
+
+using content::SpeechRecognitionError;
+using content::SpeechRecognitionResult;
+using WebKit::WebVector;
+using WebKit::WebString;
+using WebKit::WebSpeechGrammar;
+using WebKit::WebSpeechRecognitionHandle;
+using WebKit::WebSpeechRecognitionResult;
+using WebKit::WebSpeechRecognitionParams;
+using WebKit::WebSpeechRecognizerClient;
+
+SpeechRecognitionDispatcher::SpeechRecognitionDispatcher(
+ RenderViewImpl* render_view)
+ : content::RenderViewObserver(render_view),
+ recognizer_client_(NULL),
+ next_id_(1) {
+}
+
+SpeechRecognitionDispatcher::~SpeechRecognitionDispatcher() {
+}
+
+bool SpeechRecognitionDispatcher::OnMessageReceived(
+ const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(SpeechRecognitionDispatcher, message)
+ IPC_MESSAGE_HANDLER(SpeechRecognitionMsg_Started, OnRecognitionStarted)
+ IPC_MESSAGE_HANDLER(SpeechRecognitionMsg_AudioStarted, OnAudioStarted)
+ IPC_MESSAGE_HANDLER(SpeechRecognitionMsg_SoundStarted, OnSoundStarted)
+ IPC_MESSAGE_HANDLER(SpeechRecognitionMsg_SoundEnded, OnSoundEnded)
+ IPC_MESSAGE_HANDLER(SpeechRecognitionMsg_AudioEnded, OnAudioEnded)
+ IPC_MESSAGE_HANDLER(SpeechRecognitionMsg_ErrorOccurred, OnErrorOccurred)
+ IPC_MESSAGE_HANDLER(SpeechRecognitionMsg_Ended, OnRecognitionEnded)
+ IPC_MESSAGE_HANDLER(SpeechRecognitionMsg_ResultRetrieved, OnResultRetrieved)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void SpeechRecognitionDispatcher::start(
+ const WebSpeechRecognitionHandle& handle,
+ const WebSpeechRecognitionParams& params,
+ WebSpeechRecognizerClient* recognizer_client) {
+ //TODO(primiano) What to do if a start is issued to an already started object?
+ DCHECK(!recognizer_client_ || recognizer_client_ == recognizer_client);
+ recognizer_client_ = recognizer_client;
+
+ SpeechRecognitionHostMsg_StartRequest_Params msg_params;
+ for (size_t i = 0; i < params.grammars().size(); ++i) {
+ const WebSpeechGrammar& grammar = params.grammars()[i];
+ msg_params.grammars.push_back(
+ content::SpeechRecognitionGrammar(grammar.src().spec(),
+ grammar.weight()));
+ }
+ msg_params.language = UTF16ToUTF8(params.language());
+ msg_params.is_one_shot = !params.continuous();
+ msg_params.origin_url = ""; // TODO(primiano) we need an origin from WebKit.
+ msg_params.render_view_id = routing_id();
+ msg_params.request_id = GetIDForHandle(handle);
+ Send(new SpeechRecognitionHostMsg_StartRequest(msg_params));
+}
+
+void SpeechRecognitionDispatcher::stop(
+ const WebSpeechRecognitionHandle& handle,
+ WebSpeechRecognizerClient* recognizer_client) {
+ DCHECK(recognizer_client_ == recognizer_client);
+ Send(new SpeechRecognitionHostMsg_StopCaptureRequest(routing_id(),
+ GetIDForHandle(handle)));
+}
+
+void SpeechRecognitionDispatcher::abort(
+ const WebSpeechRecognitionHandle& handle,
+ WebSpeechRecognizerClient* recognizer_client) {
+ Send(new SpeechRecognitionHostMsg_AbortRequest(routing_id(),
+ GetIDForHandle(handle)));
+}
+
+void SpeechRecognitionDispatcher::OnRecognitionStarted(int request_id) {
+ recognizer_client_->didStart(GetHandleFromID(request_id));
+}
+
+void SpeechRecognitionDispatcher::OnAudioStarted(int request_id) {
+ recognizer_client_->didStartAudio(GetHandleFromID(request_id));
+}
+
+void SpeechRecognitionDispatcher::OnSoundStarted(int request_id) {
+ recognizer_client_->didStartSound(GetHandleFromID(request_id));
+}
+
+void SpeechRecognitionDispatcher::OnSoundEnded(int request_id) {
+ recognizer_client_->didEndSound(GetHandleFromID(request_id));
+}
+
+void SpeechRecognitionDispatcher::OnAudioEnded(int request_id) {
+ recognizer_client_->didEndAudio(GetHandleFromID(request_id));
+}
+
+void SpeechRecognitionDispatcher::OnErrorOccurred(
+ int request_id, const SpeechRecognitionError& error) {
+ if (error.code == content::SPEECH_RECOGNITION_ERROR_NO_MATCH) {
+ recognizer_client_->didReceiveNoMatch(GetHandleFromID(request_id),
+ WebSpeechRecognitionResult());
+ } else {
+ // TODO(primiano) speech_recognition_error.h must be updated with the new
+ // API specs soon.
+ WebSpeechRecognizerClient::ErrorCode wk_error_code;
+ switch (error.code) {
+ case content::SPEECH_RECOGNITION_ERROR_ABORTED:
+ wk_error_code = WebSpeechRecognizerClient::AbortedError;
+ break;
+ case content::SPEECH_RECOGNITION_ERROR_AUDIO:
+ wk_error_code = WebSpeechRecognizerClient::AudioCaptureError;
+ break;
+ case content::SPEECH_RECOGNITION_ERROR_NETWORK:
+ wk_error_code = WebSpeechRecognizerClient::NetworkError;
+ break;
+ case content::SPEECH_RECOGNITION_ERROR_NO_SPEECH:
+ wk_error_code = WebSpeechRecognizerClient::NoSpeechError;
+ break;
+ case content::SPEECH_RECOGNITION_ERROR_BAD_GRAMMAR:
+ wk_error_code = WebSpeechRecognizerClient::BadGrammarError;
+ break;
+ default:
+ NOTREACHED();
+ wk_error_code = WebSpeechRecognizerClient::OtherError;
+ }
+ recognizer_client_->didReceiveError(GetHandleFromID(request_id),
+ WebString(), // TODO(primiano) message?
+ wk_error_code);
+ }
+}
+
+void SpeechRecognitionDispatcher::OnRecognitionEnded(int request_id) {
+ recognizer_client_->didEnd(GetHandleFromID(request_id));
+ handle_map_.erase(request_id);
+}
+
+void SpeechRecognitionDispatcher::OnResultRetrieved(
+ int request_id, const SpeechRecognitionResult& result) {
+ const size_t num_hypotheses = result.hypotheses.size();
+ WebSpeechRecognitionResult webkit_result;
+ WebVector<WebString> transcripts(num_hypotheses);
+ WebVector<float> confidences(num_hypotheses);
+ for (size_t i = 0; i < num_hypotheses; ++i) {
+ transcripts[i] = result.hypotheses[i].utterance;
+ confidences[i] = static_cast<float>(result.hypotheses[i].confidence);
+ }
+ webkit_result.assign(transcripts, confidences, !result.provisional);
+ // TODO(primiano) Handle history, currently empty.
+ WebVector<WebSpeechRecognitionResult> empty_history;
+ recognizer_client_->didReceiveResult(GetHandleFromID(request_id),
+ webkit_result,
+ 0, // result_index
+ empty_history);
+}
+
+int SpeechRecognitionDispatcher::GetIDForHandle(
+ const WebSpeechRecognitionHandle& handle) {
+ // Search first for an existing mapping.
+ for (HandleMap::iterator iter = handle_map_.begin();
+ iter != handle_map_.end();
+ ++iter) {
+ if (iter->second.equals(handle))
+ return iter->first;
+ }
+ // If no existing mapping found, create a new one.
+ const int new_id = next_id_;
+ handle_map_[new_id] = handle;
+ ++next_id_;
+ return new_id;
+}
+
+const WebSpeechRecognitionHandle& SpeechRecognitionDispatcher::GetHandleFromID(
+ int request_id) {
+ HandleMap::iterator iter = handle_map_.find(request_id);
+ DCHECK(iter != handle_map_.end());
+ return iter->second;
+}
diff --git a/content/renderer/speech_recognition_dispatcher.h b/content/renderer/speech_recognition_dispatcher.h
new file mode 100644
index 0000000..3e3b141
--- /dev/null
+++ b/content/renderer/speech_recognition_dispatcher.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_SPEECH_RECOGNITION_DISPATCHER_H_
+#define CONTENT_RENDERER_SPEECH_RECOGNITION_DISPATCHER_H_
+#pragma once
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "content/public/renderer/render_view_observer.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSpeechRecognitionHandle.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSpeechRecognizer.h"
+
+class RenderViewImpl;
+
+namespace content {
+struct SpeechRecognitionError;
+struct SpeechRecognitionResult;
+}
+
+// SpeechRecognitionDispatcher is a delegate for methods used by WebKit for
+// scripted JS speech APIs. It's the complement of
+// SpeechRecognitionDispatcherHost (owned by RenderViewHost).
+class SpeechRecognitionDispatcher : public content::RenderViewObserver,
+ public WebKit::WebSpeechRecognizer {
+ public:
+ explicit SpeechRecognitionDispatcher(RenderViewImpl* render_view);
+ virtual ~SpeechRecognitionDispatcher();
+
+ private:
+ // RenderViewObserver implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+
+ // WebKit::WebSpeechRecognizer implementation.
+ virtual void start(const WebKit::WebSpeechRecognitionHandle&,
+ const WebKit::WebSpeechRecognitionParams&,
+ WebKit::WebSpeechRecognizerClient*) OVERRIDE;
+ virtual void stop(const WebKit::WebSpeechRecognitionHandle&,
+ WebKit::WebSpeechRecognizerClient*) OVERRIDE;
+ virtual void abort(const WebKit::WebSpeechRecognitionHandle&,
+ WebKit::WebSpeechRecognizerClient*) OVERRIDE;
+
+ void OnRecognitionStarted(int request_id);
+ void OnAudioStarted(int request_id);
+ void OnSoundStarted(int request_id);
+ void OnSoundEnded(int request_id);
+ void OnAudioEnded(int request_id);
+ void OnErrorOccurred(int request_id,
+ const content::SpeechRecognitionError& error);
+ void OnRecognitionEnded(int request_id);
+ void OnResultRetrieved(int request_id,
+ const content::SpeechRecognitionResult& result);
+
+ int GetIDForHandle(const WebKit::WebSpeechRecognitionHandle& handle);
+ const WebKit::WebSpeechRecognitionHandle& GetHandleFromID(int handle_id);
+
+ // The WebKit client class that we use to send events back to the JS world.
+ WebKit::WebSpeechRecognizerClient* recognizer_client_;
+
+ typedef std::map<int, WebKit::WebSpeechRecognitionHandle> HandleMap;
+ HandleMap handle_map_;
+ int next_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(SpeechRecognitionDispatcher);
+};
+
+#endif // CONTENT_RENDERER_SPEECH_RECOGNITION_DISPATCHER_H_