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

Unified Diff: content/renderer/speech_recognition_dispatcher.cc

Issue 10273006: Introduced SpeechRecognitionDispatcher(Host) classes, handling dispatch of IPC messages for continu… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 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/renderer/speech_recognition_dispatcher.cc
diff --git a/content/renderer/speech_recognition_dispatcher.cc b/content/renderer/speech_recognition_dispatcher.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d65748788df9caa9420de8e5f0ddc87415d7e979
--- /dev/null
+++ b/content/renderer/speech_recognition_dispatcher.cc
@@ -0,0 +1,189 @@
+// 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/WebSpeechRecognizer.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),
+ event_proxy_(NULL),
+ last_mapping_id_(0) {
+}
+
+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* event_proxy) {
+ //TODO(primiano) What to do if a start is issued to an already started object?
+ DCHECK(!event_proxy_ || event_proxy_ == event_proxy);
+ event_proxy_ = event_proxy;
+
+ SpeechRecognitionHostMsg_StartRequest_Params msg_params;
+ for (size_t i=0; i < params.grammars().size(); ++i) {
hans 2012/05/11 16:56:32 spaces around the =
Primiano Tucci (use gerrit) 2012/05/14 12:58:22 Done.
+ 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.
hans 2012/05/11 16:56:32 i don't think we normally put space between TODO a
Primiano Tucci (use gerrit) 2012/05/14 12:58:22 Uh, right. The space was misplaced.
+ msg_params.render_view_id = routing_id();
+ msg_params.js_handle_id = GetIDForHandle(handle);
+ Send(new SpeechRecognitionHostMsg_StartRequest(msg_params));
+}
+
+void SpeechRecognitionDispatcher::stop(const WebSpeechRecognitionHandle& handle,
+ WebSpeechRecognizerClient* event_proxy) {
+ DCHECK(event_proxy_ == event_proxy);
+ Send(new SpeechRecognitionHostMsg_StopCaptureRequest(routing_id(),
+ GetIDForHandle(handle)));
+}
+
+void SpeechRecognitionDispatcher::abort(
+ const WebSpeechRecognitionHandle& handle,
+ WebSpeechRecognizerClient* event_proxy) {
+ Send(new SpeechRecognitionHostMsg_AbortRequest(routing_id(),
+ GetIDForHandle(handle)));
+}
+
+void SpeechRecognitionDispatcher::OnRecognitionStarted(int js_handle_id) {
+ if (!event_proxy_)
hans 2012/05/11 16:56:32 can this happen?
Primiano Tucci (use gerrit) 2012/05/14 12:58:22 Hmm, agree. A DCHECK is more suitable.
+ return;
+ event_proxy_->didStart(GetHandleFromID(js_handle_id));
+}
+
+void SpeechRecognitionDispatcher::OnAudioStarted(int js_handle_id) {
+ if (!event_proxy_)
+ return;
+ event_proxy_->didStartAudio(GetHandleFromID(js_handle_id));
+}
+
+void SpeechRecognitionDispatcher::OnSoundStarted(int js_handle_id) {
+ if (!event_proxy_)
+ return;
+ event_proxy_->didStartSound(GetHandleFromID(js_handle_id));
+}
+
+void SpeechRecognitionDispatcher::OnSoundEnded(int js_handle_id) {
+ if (!event_proxy_)
+ return;
+ event_proxy_->didEndSound(GetHandleFromID(js_handle_id));
+}
+
+void SpeechRecognitionDispatcher::OnAudioEnded(int js_handle_id) {
+ if (!event_proxy_)
+ return;
+ event_proxy_->didEndAudio(GetHandleFromID(js_handle_id));
+}
+
+void SpeechRecognitionDispatcher::OnErrorOccurred(
+ int js_handle_id, const SpeechRecognitionError& error) {
+ if (!event_proxy_)
+ return;
+ if (error.code == content::SPEECH_RECOGNITION_ERROR_NO_MATCH) {
+ event_proxy_->didReceiveNoMatch(GetHandleFromID(js_handle_id),
+ WebSpeechRecognitionResult());
+ } else {
+ event_proxy_->didReceiveError(GetHandleFromID(js_handle_id),
+ WebString(), // TODO(primiano) error message?
hans 2012/05/11 16:56:32 hmm, i guess we should look at the error.details a
Primiano Tucci (use gerrit) 2012/05/14 12:58:22 Right.
+ error.code);
+ }
+}
+
+void SpeechRecognitionDispatcher::OnRecognitionEnded(int js_handle_id) {
+ if (!event_proxy_)
+ return;
+ event_proxy_->didEnd(GetHandleFromID(js_handle_id));
+ handle_mappings_.erase(js_handle_id);
+}
+
+void SpeechRecognitionDispatcher::OnResultRetrieved(
+ int js_handle_id, const SpeechRecognitionResult& result) {
+ if (!event_proxy_)
+ return;
+
+ 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) {
hans 2012/05/11 16:56:32 spaces around =
Primiano Tucci (use gerrit) 2012/05/14 12:58:22 Done.
+ 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;
+ event_proxy_->didReceiveResult(GetHandleFromID(js_handle_id),
+ webkit_result,
+ 0, // result_index
hans 2012/05/11 16:56:32 maybe do "const int result_index = 0;" and pass in
Primiano Tucci (use gerrit) 2012/05/14 12:58:22 I really agree with the pattern, but in a similar
hans 2012/05/14 14:04:52 OK. Satish can comment if he has opinions here :)
+ empty_history);
+}
+
+int SpeechRecognitionDispatcher::GetIDForHandle(
+ const WebSpeechRecognitionHandle& handle) {
+ // Search first for an existing mapping.
+ for(HandleMap::iterator iter = handle_mappings_.begin();
hans 2012/05/11 16:56:32 space between for and (
Primiano Tucci (use gerrit) 2012/05/14 12:58:22 Done.
+ iter != handle_mappings_.end();
+ ++iter) {
+ if (iter->second.equals(handle))
+ return iter->first;
+ }
+ // If no existing mapping found, create a new one.
+ for (++last_mapping_id_;
+ handle_mappings_.find(last_mapping_id_) != handle_mappings_.end();
+ ++last_mapping_id_) {}
hans 2012/05/11 16:56:32 why do we need this loop? why not just handle_map
Primiano Tucci (use gerrit) 2012/05/14 12:58:22 Just me being extremely paranoid about holes after
+ handle_mappings_[last_mapping_id_] = handle;
+ return last_mapping_id_;
+}
+
+const WebSpeechRecognitionHandle& SpeechRecognitionDispatcher::GetHandleFromID(
+ int js_handle_id) {
+ HandleMap::iterator iter = handle_mappings_.find(js_handle_id);
+ DCHECK(iter != handle_mappings_.end());
+ return iter->second;
+}

Powered by Google App Engine
This is Rietveld 408576698