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