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