Home | History | Annotate | Download | only in speech
      1 // Copyright (c) 2013 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 "chrome/browser/speech/tts_message_filter.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/logging.h"
      9 #include "chrome/browser/profiles/profile.h"
     10 #include "chrome/browser/speech/tts_controller.h"
     11 #include "chrome/browser/speech/tts_message_filter.h"
     12 #include "content/public/browser/browser_context.h"
     13 #include "content/public/browser/render_process_host.h"
     14 
     15 using content::BrowserThread;
     16 
     17 TtsMessageFilter::TtsMessageFilter(int render_process_id, Profile* profile)
     18     : BrowserMessageFilter(TtsMsgStart),
     19       render_process_id_(render_process_id),
     20       profile_(profile) {
     21   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     22   TtsController::GetInstance()->AddVoicesChangedDelegate(this);
     23 }
     24 
     25 void TtsMessageFilter::OverrideThreadForMessage(
     26     const IPC::Message& message, BrowserThread::ID* thread) {
     27   switch (message.type()) {
     28   case TtsHostMsg_InitializeVoiceList::ID:
     29   case TtsHostMsg_Speak::ID:
     30   case TtsHostMsg_Pause::ID:
     31   case TtsHostMsg_Resume::ID:
     32   case TtsHostMsg_Cancel::ID:
     33     *thread = BrowserThread::UI;
     34     break;
     35   }
     36 }
     37 
     38 bool TtsMessageFilter::OnMessageReceived(const IPC::Message& message) {
     39   bool handled = true;
     40   IPC_BEGIN_MESSAGE_MAP(TtsMessageFilter, message)
     41     IPC_MESSAGE_HANDLER(TtsHostMsg_InitializeVoiceList, OnInitializeVoiceList)
     42     IPC_MESSAGE_HANDLER(TtsHostMsg_Speak, OnSpeak)
     43     IPC_MESSAGE_HANDLER(TtsHostMsg_Pause, OnPause)
     44     IPC_MESSAGE_HANDLER(TtsHostMsg_Resume, OnResume)
     45     IPC_MESSAGE_HANDLER(TtsHostMsg_Cancel, OnCancel)
     46     IPC_MESSAGE_UNHANDLED(handled = false)
     47   IPC_END_MESSAGE_MAP()
     48   return handled;
     49 }
     50 
     51 void TtsMessageFilter::OnChannelClosing() {
     52   BrowserThread::PostTask(
     53       BrowserThread::UI, FROM_HERE,
     54       base::Bind(&TtsMessageFilter::OnChannelClosingInUIThread, this));
     55 }
     56 
     57 void TtsMessageFilter::OnDestruct() const {
     58   BrowserThread::DeleteOnUIThread::Destruct(this);
     59 }
     60 
     61 void TtsMessageFilter::OnInitializeVoiceList() {
     62   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     63   TtsController* tts_controller = TtsController::GetInstance();
     64   std::vector<VoiceData> voices;
     65   tts_controller->GetVoices(profile_, &voices);
     66 
     67   std::vector<TtsVoice> out_voices;
     68   out_voices.resize(voices.size());
     69   for (size_t i = 0; i < voices.size(); ++i) {
     70     TtsVoice& out_voice = out_voices[i];
     71     out_voice.voice_uri = voices[i].name;
     72     out_voice.name = voices[i].name;
     73     out_voice.lang = voices[i].lang;
     74     out_voice.local_service = !voices[i].remote;
     75     out_voice.is_default = (i == 0);
     76   }
     77   Send(new TtsMsg_SetVoiceList(out_voices));
     78 }
     79 
     80 void TtsMessageFilter::OnSpeak(const TtsUtteranceRequest& request) {
     81   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     82   scoped_ptr<Utterance> utterance(new Utterance(profile_));
     83   utterance->set_src_id(request.id);
     84   utterance->set_text(request.text);
     85   utterance->set_lang(request.lang);
     86   utterance->set_voice_name(request.voice);
     87   utterance->set_can_enqueue(true);
     88 
     89   UtteranceContinuousParameters params;
     90   params.rate = request.rate;
     91   params.pitch = request.pitch;
     92   params.volume = request.volume;
     93   utterance->set_continuous_parameters(params);
     94 
     95   utterance->set_event_delegate(this->AsWeakPtr());
     96 
     97   TtsController::GetInstance()->SpeakOrEnqueue(utterance.release());
     98 }
     99 
    100 void TtsMessageFilter::OnPause() {
    101   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    102   TtsController::GetInstance()->Pause();
    103 }
    104 
    105 void TtsMessageFilter::OnResume() {
    106   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    107   TtsController::GetInstance()->Resume();
    108 }
    109 
    110 void TtsMessageFilter::OnCancel() {
    111   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    112   TtsController::GetInstance()->Stop();
    113 }
    114 
    115 void TtsMessageFilter::OnTtsEvent(Utterance* utterance,
    116                                   TtsEventType event_type,
    117                                   int char_index,
    118                                   const std::string& error_message) {
    119   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    120   switch (event_type) {
    121     case TTS_EVENT_START:
    122       Send(new TtsMsg_DidStartSpeaking(utterance->src_id()));
    123       break;
    124     case TTS_EVENT_END:
    125       Send(new TtsMsg_DidFinishSpeaking(utterance->src_id()));
    126       break;
    127     case TTS_EVENT_WORD:
    128       Send(new TtsMsg_WordBoundary(utterance->src_id(), char_index));
    129       break;
    130     case TTS_EVENT_SENTENCE:
    131       Send(new TtsMsg_SentenceBoundary(utterance->src_id(), char_index));
    132       break;
    133     case TTS_EVENT_MARKER:
    134       Send(new TtsMsg_MarkerEvent(utterance->src_id(), char_index));
    135       break;
    136     case TTS_EVENT_INTERRUPTED:
    137       Send(new TtsMsg_WasInterrupted(utterance->src_id()));
    138       break;
    139     case TTS_EVENT_CANCELLED:
    140       Send(new TtsMsg_WasCancelled(utterance->src_id()));
    141       break;
    142     case TTS_EVENT_ERROR:
    143       Send(new TtsMsg_SpeakingErrorOccurred(
    144           utterance->src_id(), error_message));
    145       break;
    146     case TTS_EVENT_PAUSE:
    147       Send(new TtsMsg_DidPauseSpeaking(utterance->src_id()));
    148       break;
    149     case TTS_EVENT_RESUME:
    150       Send(new TtsMsg_DidResumeSpeaking(utterance->src_id()));
    151       break;
    152   }
    153 }
    154 
    155 void TtsMessageFilter::OnVoicesChanged() {
    156   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    157   OnInitializeVoiceList();
    158 }
    159 
    160 void TtsMessageFilter::OnChannelClosingInUIThread() {
    161   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    162   TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
    163 }
    164 
    165 TtsMessageFilter::~TtsMessageFilter() {
    166   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    167   TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
    168 }
    169