Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / speech / tts_message_filter.cc
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
12 using content::BrowserThread;
13
14 TtsMessageFilter::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       valid_(true) {
20   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
21   TtsController::GetInstance()->AddVoicesChangedDelegate(this);
22
23   // Balanced in OnChannelClosingInUIThread() to keep the ref-count be non-zero
24   // until all pointers to this class are invalidated.
25   AddRef();
26 }
27
28 void TtsMessageFilter::OverrideThreadForMessage(
29     const IPC::Message& message, BrowserThread::ID* thread) {
30   switch (message.type()) {
31   case TtsHostMsg_InitializeVoiceList::ID:
32   case TtsHostMsg_Speak::ID:
33   case TtsHostMsg_Pause::ID:
34   case TtsHostMsg_Resume::ID:
35   case TtsHostMsg_Cancel::ID:
36     *thread = BrowserThread::UI;
37     break;
38   }
39 }
40
41 bool TtsMessageFilter::OnMessageReceived(const IPC::Message& message) {
42   bool handled = true;
43   IPC_BEGIN_MESSAGE_MAP(TtsMessageFilter, message)
44     IPC_MESSAGE_HANDLER(TtsHostMsg_InitializeVoiceList, OnInitializeVoiceList)
45     IPC_MESSAGE_HANDLER(TtsHostMsg_Speak, OnSpeak)
46     IPC_MESSAGE_HANDLER(TtsHostMsg_Pause, OnPause)
47     IPC_MESSAGE_HANDLER(TtsHostMsg_Resume, OnResume)
48     IPC_MESSAGE_HANDLER(TtsHostMsg_Cancel, OnCancel)
49     IPC_MESSAGE_UNHANDLED(handled = false)
50   IPC_END_MESSAGE_MAP()
51   return handled;
52 }
53
54 void TtsMessageFilter::OnChannelClosing() {
55   base::AutoLock lock(mutex_);
56   valid_ = false;
57   BrowserThread::PostTask(
58       BrowserThread::UI, FROM_HERE,
59       base::Bind(&TtsMessageFilter::OnChannelClosingInUIThread, this));
60 }
61
62 bool TtsMessageFilter::Valid() {
63   base::AutoLock lock(mutex_);
64   return valid_;
65 }
66
67 void TtsMessageFilter::OnDestruct() const {
68   {
69     base::AutoLock lock(mutex_);
70     valid_ = false;
71   }
72   BrowserThread::DeleteOnUIThread::Destruct(this);
73 }
74
75 TtsMessageFilter::~TtsMessageFilter() {
76   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
77   Cleanup();
78 }
79
80 void TtsMessageFilter::OnInitializeVoiceList() {
81   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
82   TtsController* tts_controller = TtsController::GetInstance();
83   std::vector<VoiceData> voices;
84   tts_controller->GetVoices(browser_context_, &voices);
85
86   std::vector<TtsVoice> out_voices;
87   out_voices.resize(voices.size());
88   for (size_t i = 0; i < voices.size(); ++i) {
89     TtsVoice& out_voice = out_voices[i];
90     out_voice.voice_uri = voices[i].name;
91     out_voice.name = voices[i].name;
92     out_voice.lang = voices[i].lang;
93     out_voice.local_service = !voices[i].remote;
94     out_voice.is_default = (i == 0);
95   }
96   Send(new TtsMsg_SetVoiceList(out_voices));
97 }
98
99 void TtsMessageFilter::OnSpeak(const TtsUtteranceRequest& request) {
100   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
101
102   scoped_ptr<Utterance> utterance(new Utterance(browser_context_));
103   utterance->set_src_id(request.id);
104   utterance->set_text(request.text);
105   utterance->set_lang(request.lang);
106   utterance->set_voice_name(request.voice);
107   utterance->set_can_enqueue(true);
108
109   UtteranceContinuousParameters params;
110   params.rate = request.rate;
111   params.pitch = request.pitch;
112   params.volume = request.volume;
113   utterance->set_continuous_parameters(params);
114
115   utterance->set_event_delegate(this);
116
117   TtsController::GetInstance()->SpeakOrEnqueue(utterance.release());
118 }
119
120 void TtsMessageFilter::OnPause() {
121   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
122   TtsController::GetInstance()->Pause();
123 }
124
125 void TtsMessageFilter::OnResume() {
126   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
127   TtsController::GetInstance()->Resume();
128 }
129
130 void TtsMessageFilter::OnCancel() {
131   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
132   TtsController::GetInstance()->Stop();
133 }
134
135 void TtsMessageFilter::OnTtsEvent(Utterance* utterance,
136                                   TtsEventType event_type,
137                                   int char_index,
138                                   const std::string& error_message) {
139   if (!Valid())
140     return;
141
142   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
143   switch (event_type) {
144     case TTS_EVENT_START:
145       Send(new TtsMsg_DidStartSpeaking(utterance->src_id()));
146       break;
147     case TTS_EVENT_END:
148       Send(new TtsMsg_DidFinishSpeaking(utterance->src_id()));
149       break;
150     case TTS_EVENT_WORD:
151       Send(new TtsMsg_WordBoundary(utterance->src_id(), char_index));
152       break;
153     case TTS_EVENT_SENTENCE:
154       Send(new TtsMsg_SentenceBoundary(utterance->src_id(), char_index));
155       break;
156     case TTS_EVENT_MARKER:
157       Send(new TtsMsg_MarkerEvent(utterance->src_id(), char_index));
158       break;
159     case TTS_EVENT_INTERRUPTED:
160       Send(new TtsMsg_WasInterrupted(utterance->src_id()));
161       break;
162     case TTS_EVENT_CANCELLED:
163       Send(new TtsMsg_WasCancelled(utterance->src_id()));
164       break;
165     case TTS_EVENT_ERROR:
166       Send(new TtsMsg_SpeakingErrorOccurred(
167           utterance->src_id(), error_message));
168       break;
169     case TTS_EVENT_PAUSE:
170       Send(new TtsMsg_DidPauseSpeaking(utterance->src_id()));
171       break;
172     case TTS_EVENT_RESUME:
173       Send(new TtsMsg_DidResumeSpeaking(utterance->src_id()));
174       break;
175   }
176 }
177
178 void TtsMessageFilter::OnVoicesChanged() {
179   if (!Valid())
180     return;
181
182   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
183   OnInitializeVoiceList();
184 }
185
186 void TtsMessageFilter::OnChannelClosingInUIThread() {
187   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
188   Cleanup();
189   Release();  // Balanced in TtsMessageFilter().
190 }
191
192 void TtsMessageFilter::Cleanup() {
193   TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
194   TtsController::GetInstance()->RemoveUtteranceEventDelegate(this);
195 }