Home | History | Annotate | Download | only in speech
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/speech/speech_recognition_dispatcher_host.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/command_line.h"
      9 #include "base/lazy_instance.h"
     10 #include "content/browser/speech/speech_recognition_manager_impl.h"
     11 #include "content/common/speech_recognition_messages.h"
     12 #include "content/public/browser/speech_recognition_manager_delegate.h"
     13 #include "content/public/browser/speech_recognition_session_config.h"
     14 #include "content/public/browser/speech_recognition_session_context.h"
     15 #include "content/public/common/content_switches.h"
     16 
     17 namespace content {
     18 
     19 SpeechRecognitionDispatcherHost::SpeechRecognitionDispatcherHost(
     20     int render_process_id,
     21     net::URLRequestContextGetter* context_getter)
     22     : render_process_id_(render_process_id),
     23       context_getter_(context_getter) {
     24   // Do not add any non-trivial initialization here, instead do it lazily when
     25   // required (e.g. see the method |SpeechRecognitionManager::GetInstance()|) or
     26   // add an Init() method.
     27 }
     28 
     29 SpeechRecognitionDispatcherHost::~SpeechRecognitionDispatcherHost() {
     30   SpeechRecognitionManager::GetInstance()->AbortAllSessionsForListener(this);
     31 }
     32 
     33 bool SpeechRecognitionDispatcherHost::OnMessageReceived(
     34     const IPC::Message& message, bool* message_was_ok) {
     35   bool handled = true;
     36   IPC_BEGIN_MESSAGE_MAP_EX(SpeechRecognitionDispatcherHost, message,
     37                            *message_was_ok)
     38     IPC_MESSAGE_HANDLER(SpeechRecognitionHostMsg_StartRequest,
     39                         OnStartRequest)
     40     IPC_MESSAGE_HANDLER(SpeechRecognitionHostMsg_AbortRequest,
     41                         OnAbortRequest)
     42     IPC_MESSAGE_HANDLER(SpeechRecognitionHostMsg_StopCaptureRequest,
     43                         OnStopCaptureRequest)
     44     IPC_MESSAGE_UNHANDLED(handled = false)
     45   IPC_END_MESSAGE_MAP()
     46   return handled;
     47 }
     48 
     49 void SpeechRecognitionDispatcherHost::OverrideThreadForMessage(
     50     const IPC::Message& message,
     51     BrowserThread::ID* thread) {
     52   if (message.type() == SpeechRecognitionHostMsg_StartRequest::ID)
     53     *thread = BrowserThread::UI;
     54 }
     55 
     56 void SpeechRecognitionDispatcherHost::OnStartRequest(
     57     const SpeechRecognitionHostMsg_StartRequest_Params& params) {
     58   bool filter_profanities =
     59       SpeechRecognitionManagerImpl::GetInstance() &&
     60       SpeechRecognitionManagerImpl::GetInstance()->delegate() &&
     61       SpeechRecognitionManagerImpl::GetInstance()->delegate()->
     62           FilterProfanities(render_process_id_);
     63 
     64   BrowserThread::PostTask(
     65       BrowserThread::IO,
     66       FROM_HERE,
     67       base::Bind(&SpeechRecognitionDispatcherHost::OnStartRequestOnIO,
     68                  this, params, filter_profanities));
     69 }
     70 
     71 void SpeechRecognitionDispatcherHost::OnStartRequestOnIO(
     72     const SpeechRecognitionHostMsg_StartRequest_Params& params,
     73     bool filter_profanities) {
     74   SpeechRecognitionSessionContext context;
     75   context.context_name = params.origin_url;
     76   context.render_process_id = render_process_id_;
     77   context.render_view_id = params.render_view_id;
     78   context.request_id = params.request_id;
     79   context.requested_by_page_element = false;
     80 
     81   SpeechRecognitionSessionConfig config;
     82   config.is_legacy_api = false;
     83   config.language = params.language;
     84   config.grammars = params.grammars;
     85   config.max_hypotheses = params.max_hypotheses;
     86   config.origin_url = params.origin_url;
     87   config.initial_context = context;
     88   config.url_request_context_getter = context_getter_.get();
     89   config.filter_profanities = filter_profanities;
     90   config.continuous = params.continuous;
     91   config.interim_results = params.interim_results;
     92   config.event_listener = this;
     93 
     94   int session_id = SpeechRecognitionManager::GetInstance()->CreateSession(
     95       config);
     96   DCHECK_NE(session_id, SpeechRecognitionManager::kSessionIDInvalid);
     97   SpeechRecognitionManager::GetInstance()->StartSession(session_id);
     98 }
     99 
    100 void SpeechRecognitionDispatcherHost::OnAbortRequest(int render_view_id,
    101                                                      int request_id) {
    102   int session_id = SpeechRecognitionManager::GetInstance()->GetSession(
    103       render_process_id_, render_view_id, request_id);
    104 
    105   // The renderer might provide an invalid |request_id| if the session was not
    106   // started as expected, e.g., due to unsatisfied security requirements.
    107   if (session_id != SpeechRecognitionManager::kSessionIDInvalid)
    108     SpeechRecognitionManager::GetInstance()->AbortSession(session_id);
    109 }
    110 
    111 void SpeechRecognitionDispatcherHost::OnStopCaptureRequest(
    112     int render_view_id, int request_id) {
    113   int session_id = SpeechRecognitionManager::GetInstance()->GetSession(
    114       render_process_id_, render_view_id, request_id);
    115 
    116   // The renderer might provide an invalid |request_id| if the session was not
    117   // started as expected, e.g., due to unsatisfied security requirements.
    118   if (session_id != SpeechRecognitionManager::kSessionIDInvalid) {
    119     SpeechRecognitionManager::GetInstance()->StopAudioCaptureForSession(
    120         session_id);
    121   }
    122 }
    123 
    124 // -------- SpeechRecognitionEventListener interface implementation -----------
    125 
    126 void SpeechRecognitionDispatcherHost::OnRecognitionStart(int session_id) {
    127   const SpeechRecognitionSessionContext& context =
    128       SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
    129   Send(new SpeechRecognitionMsg_Started(context.render_view_id,
    130                                         context.request_id));
    131 }
    132 
    133 void SpeechRecognitionDispatcherHost::OnAudioStart(int session_id) {
    134   const SpeechRecognitionSessionContext& context =
    135       SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
    136   Send(new SpeechRecognitionMsg_AudioStarted(context.render_view_id,
    137                                              context.request_id));
    138 }
    139 
    140 void SpeechRecognitionDispatcherHost::OnSoundStart(int session_id) {
    141   const SpeechRecognitionSessionContext& context =
    142       SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
    143   Send(new SpeechRecognitionMsg_SoundStarted(context.render_view_id,
    144                                              context.request_id));
    145 }
    146 
    147 void SpeechRecognitionDispatcherHost::OnSoundEnd(int session_id) {
    148   const SpeechRecognitionSessionContext& context =
    149       SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
    150   Send(new SpeechRecognitionMsg_SoundEnded(context.render_view_id,
    151                                            context.request_id));
    152 }
    153 
    154 void SpeechRecognitionDispatcherHost::OnAudioEnd(int session_id) {
    155   const SpeechRecognitionSessionContext& context =
    156       SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
    157   Send(new SpeechRecognitionMsg_AudioEnded(context.render_view_id,
    158                                            context.request_id));
    159 }
    160 
    161 void SpeechRecognitionDispatcherHost::OnRecognitionEnd(int session_id) {
    162   const SpeechRecognitionSessionContext& context =
    163       SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
    164   Send(new SpeechRecognitionMsg_Ended(context.render_view_id,
    165                                       context.request_id));
    166 }
    167 
    168 void SpeechRecognitionDispatcherHost::OnRecognitionResults(
    169     int session_id,
    170     const SpeechRecognitionResults& results) {
    171   const SpeechRecognitionSessionContext& context =
    172       SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
    173   Send(new SpeechRecognitionMsg_ResultRetrieved(context.render_view_id,
    174                                                 context.request_id,
    175                                                 results));
    176 }
    177 
    178 void SpeechRecognitionDispatcherHost::OnRecognitionError(
    179     int session_id,
    180     const SpeechRecognitionError& error) {
    181   const SpeechRecognitionSessionContext& context =
    182       SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id);
    183   Send(new SpeechRecognitionMsg_ErrorOccurred(context.render_view_id,
    184                                               context.request_id,
    185                                               error));
    186 }
    187 
    188 // The events below are currently not used by speech JS APIs implementation.
    189 void SpeechRecognitionDispatcherHost::OnAudioLevelsChange(int session_id,
    190                                                           float volume,
    191                                                           float noise_volume) {
    192 }
    193 
    194 void SpeechRecognitionDispatcherHost::OnEnvironmentEstimationComplete(
    195     int session_id) {
    196 }
    197 
    198 }  // namespace content
    199