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 : render_process_id_(render_process_id),
19 profile_(profile) {
20 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
21 TtsController::GetInstance()->AddVoicesChangedDelegate(this);
22 }
23
OverrideThreadForMessage(const IPC::Message & message,BrowserThread::ID * thread)24 void 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
OnMessageReceived(const IPC::Message & message,bool * message_was_ok)37 bool 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
OnChannelClosing()51 void TtsMessageFilter::OnChannelClosing() {
52 BrowserThread::PostTask(
53 BrowserThread::UI, FROM_HERE,
54 base::Bind(&TtsMessageFilter::OnChannelClosingInUIThread, this));
55 }
56
OnInitializeVoiceList()57 void 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
OnSpeak(const TtsUtteranceRequest & request)76 void 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->AsWeakPtr());
92
93 TtsController::GetInstance()->SpeakOrEnqueue(utterance.release());
94 }
95
OnPause()96 void TtsMessageFilter::OnPause() {
97 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
98 TtsController::GetInstance()->Pause();
99 }
100
OnResume()101 void TtsMessageFilter::OnResume() {
102 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
103 TtsController::GetInstance()->Resume();
104 }
105
OnCancel()106 void TtsMessageFilter::OnCancel() {
107 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
108 TtsController::GetInstance()->Stop();
109 }
110
OnTtsEvent(Utterance * utterance,TtsEventType event_type,int char_index,const std::string & error_message)111 void 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
OnVoicesChanged()151 void TtsMessageFilter::OnVoicesChanged() {
152 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
153 OnInitializeVoiceList();
154 }
155
OnChannelClosingInUIThread()156 void TtsMessageFilter::OnChannelClosingInUIThread() {
157 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
158 TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
159 }
160
~TtsMessageFilter()161 TtsMessageFilter::~TtsMessageFilter() {
162 }
163