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