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
TtsMessageFilter(int render_process_id,Profile * profile)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
OverrideThreadForMessage(const IPC::Message & message,BrowserThread::ID * thread)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
OnMessageReceived(const IPC::Message & message)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
OnChannelClosing()51 void TtsMessageFilter::OnChannelClosing() {
52 BrowserThread::PostTask(
53 BrowserThread::UI, FROM_HERE,
54 base::Bind(&TtsMessageFilter::OnChannelClosingInUIThread, this));
55 }
56
OnDestruct() const57 void TtsMessageFilter::OnDestruct() const {
58 BrowserThread::DeleteOnUIThread::Destruct(this);
59 }
60
OnInitializeVoiceList()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
OnSpeak(const TtsUtteranceRequest & request)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
OnPause()100 void TtsMessageFilter::OnPause() {
101 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
102 TtsController::GetInstance()->Pause();
103 }
104
OnResume()105 void TtsMessageFilter::OnResume() {
106 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
107 TtsController::GetInstance()->Resume();
108 }
109
OnCancel()110 void TtsMessageFilter::OnCancel() {
111 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
112 TtsController::GetInstance()->Stop();
113 }
114
OnTtsEvent(Utterance * utterance,TtsEventType event_type,int char_index,const std::string & error_message)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
OnVoicesChanged()155 void TtsMessageFilter::OnVoicesChanged() {
156 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
157 OnInitializeVoiceList();
158 }
159
OnChannelClosingInUIThread()160 void TtsMessageFilter::OnChannelClosingInUIThread() {
161 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
162 TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
163 }
164
~TtsMessageFilter()165 TtsMessageFilter::~TtsMessageFilter() {
166 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
167 TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
168 }
169