OLD | NEW |
(Empty) | |
| 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/renderer/tts_dispatcher.h" |
| 6 |
| 7 #include "base/basictypes.h" |
| 8 #include "base/utf_string_conversions.h" |
| 9 #include "chrome/common/tts_messages.h" |
| 10 #include "chrome/common/tts_utterance_request.h" |
| 11 #include "content/public/renderer/render_thread.h" |
| 12 #include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h" |
| 13 #include "third_party/WebKit/Source/Platform/chromium/public/WebSpeechSynthesisU
tterance.h" |
| 14 #include "third_party/WebKit/Source/Platform/chromium/public/WebSpeechSynthesisV
oice.h" |
| 15 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" |
| 16 #include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h" |
| 17 |
| 18 using content::RenderThread; |
| 19 using WebKit::WebSpeechSynthesizerClient; |
| 20 using WebKit::WebSpeechSynthesisUtterance; |
| 21 using WebKit::WebSpeechSynthesisVoice; |
| 22 using WebKit::WebString; |
| 23 using WebKit::WebVector; |
| 24 |
| 25 int TtsDispatcher::next_utterance_id_ = 1; |
| 26 |
| 27 TtsDispatcher::TtsDispatcher(WebSpeechSynthesizerClient* client) |
| 28 : synthesizer_client_(client), |
| 29 main_loop_(base::MessageLoopProxy::current()) { |
| 30 RenderThread::Get()->AddFilter(this); |
| 31 } |
| 32 |
| 33 TtsDispatcher::~TtsDispatcher() { |
| 34 } |
| 35 |
| 36 bool TtsDispatcher::OnMessageReceived(const IPC::Message& message) { |
| 37 bool handled = true; |
| 38 IPC_BEGIN_MESSAGE_MAP(TtsDispatcher, message) |
| 39 IPC_MESSAGE_HANDLER(TtsMsg_SetVoiceList, OnSetVoiceList) |
| 40 IPC_MESSAGE_HANDLER(TtsMsg_DidStartSpeaking, OnDidStartSpeaking) |
| 41 IPC_MESSAGE_HANDLER(TtsMsg_DidFinishSpeaking, OnDidFinishSpeaking) |
| 42 IPC_MESSAGE_HANDLER(TtsMsg_DidPauseSpeaking, OnDidPauseSpeaking) |
| 43 IPC_MESSAGE_HANDLER(TtsMsg_DidResumeSpeaking, OnDidResumeSpeaking) |
| 44 IPC_MESSAGE_HANDLER(TtsMsg_WordBoundary, OnWordBoundary) |
| 45 IPC_MESSAGE_HANDLER(TtsMsg_SentenceBoundary, OnSentenceBoundary) |
| 46 IPC_MESSAGE_HANDLER(TtsMsg_MarkerEvent, OnMarkerEvent) |
| 47 IPC_MESSAGE_HANDLER(TtsMsg_WasInterrupted, OnWasInterrupted) |
| 48 IPC_MESSAGE_HANDLER(TtsMsg_WasCancelled, OnWasCancelled) |
| 49 IPC_MESSAGE_HANDLER(TtsMsg_SpeakingErrorOccurred, OnSpeakingErrorOccurred) |
| 50 IPC_MESSAGE_UNHANDLED(handled = false) |
| 51 IPC_END_MESSAGE_MAP() |
| 52 return handled; |
| 53 } |
| 54 |
| 55 void TtsDispatcher::updateVoiceList() { |
| 56 RenderThread::Get()->Send(new TtsHostMsg_InitializeVoiceList()); |
| 57 } |
| 58 |
| 59 void TtsDispatcher::speak(const WebSpeechSynthesisUtterance& web_utterance) { |
| 60 int id = next_utterance_id_++; |
| 61 |
| 62 utterance_id_map_[id] = web_utterance; |
| 63 |
| 64 TtsUtteranceRequest utterance; |
| 65 utterance.id = id; |
| 66 utterance.text = web_utterance.text().utf8(); |
| 67 utterance.lang = web_utterance.lang().utf8(); |
| 68 utterance.voice = web_utterance.voice().utf8(); |
| 69 utterance.volume = web_utterance.volume(); |
| 70 utterance.rate = web_utterance.rate(); |
| 71 utterance.pitch = web_utterance.pitch(); |
| 72 RenderThread::Get()->Send(new TtsHostMsg_Speak(utterance)); |
| 73 } |
| 74 |
| 75 void TtsDispatcher::pause() { |
| 76 RenderThread::Get()->Send(new TtsHostMsg_Pause()); |
| 77 } |
| 78 |
| 79 void TtsDispatcher::resume() { |
| 80 RenderThread::Get()->Send(new TtsHostMsg_Resume()); |
| 81 } |
| 82 |
| 83 void TtsDispatcher::cancel() { |
| 84 RenderThread::Get()->Send(new TtsHostMsg_Cancel()); |
| 85 } |
| 86 |
| 87 WebSpeechSynthesisUtterance TtsDispatcher::FindUtterance(int utterance_id) { |
| 88 base::hash_map<int, WebSpeechSynthesisUtterance>::const_iterator iter = |
| 89 utterance_id_map_.find(utterance_id); |
| 90 if (iter == utterance_id_map_.end()) |
| 91 return WebSpeechSynthesisUtterance(); |
| 92 return iter->second; |
| 93 } |
| 94 |
| 95 void TtsDispatcher::OnSetVoiceList(const std::vector<TtsVoice>& voices) { |
| 96 WebVector<WebSpeechSynthesisVoice> out_voices(voices.size()); |
| 97 for (size_t i = 0; i < voices.size(); ++i) { |
| 98 out_voices[i] = WebSpeechSynthesisVoice(); |
| 99 out_voices[i].setVoiceURI(WebString::fromUTF8(voices[i].voice_uri)); |
| 100 out_voices[i].setName(WebString::fromUTF8(voices[i].name)); |
| 101 out_voices[i].setLanguage(WebString::fromUTF8(voices[i].lang)); |
| 102 out_voices[i].setIsLocalService(voices[i].local_service); |
| 103 out_voices[i].setIsDefault(voices[i].is_default); |
| 104 } |
| 105 synthesizer_client_->setVoiceList(out_voices); |
| 106 } |
| 107 |
| 108 void TtsDispatcher::OnDidStartSpeaking(int utterance_id) { |
| 109 if (utterance_id_map_.find(utterance_id) == utterance_id_map_.end()) |
| 110 return; |
| 111 |
| 112 WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); |
| 113 if (utterance.isNull()) |
| 114 return; |
| 115 |
| 116 synthesizer_client_->didStartSpeaking(utterance); |
| 117 } |
| 118 |
| 119 void TtsDispatcher::OnDidFinishSpeaking(int utterance_id) { |
| 120 WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); |
| 121 if (utterance.isNull()) |
| 122 return; |
| 123 |
| 124 synthesizer_client_->didFinishSpeaking(utterance); |
| 125 utterance_id_map_.erase(utterance_id); |
| 126 } |
| 127 |
| 128 void TtsDispatcher::OnDidPauseSpeaking(int utterance_id) { |
| 129 WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); |
| 130 if (utterance.isNull()) |
| 131 return; |
| 132 |
| 133 synthesizer_client_->didPauseSpeaking(utterance); |
| 134 } |
| 135 |
| 136 void TtsDispatcher::OnDidResumeSpeaking(int utterance_id) { |
| 137 WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); |
| 138 if (utterance.isNull()) |
| 139 return; |
| 140 |
| 141 synthesizer_client_->didResumeSpeaking(utterance); |
| 142 } |
| 143 |
| 144 void TtsDispatcher::OnWordBoundary(int utterance_id, int char_index) { |
| 145 CHECK(char_index >= 0); |
| 146 |
| 147 WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); |
| 148 if (utterance.isNull()) |
| 149 return; |
| 150 |
| 151 synthesizer_client_->wordBoundaryEventOccurred( |
| 152 utterance, static_cast<unsigned>(char_index)); |
| 153 } |
| 154 |
| 155 void TtsDispatcher::OnSentenceBoundary(int utterance_id, int char_index) { |
| 156 CHECK(char_index >= 0); |
| 157 |
| 158 WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); |
| 159 if (utterance.isNull()) |
| 160 return; |
| 161 |
| 162 synthesizer_client_->sentenceBoundaryEventOccurred( |
| 163 utterance, static_cast<unsigned>(char_index)); |
| 164 } |
| 165 |
| 166 void TtsDispatcher::OnMarkerEvent(int utterance_id, int char_index) { |
| 167 // Not supported yet. |
| 168 } |
| 169 |
| 170 void TtsDispatcher::OnWasInterrupted(int utterance_id) { |
| 171 WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); |
| 172 if (utterance.isNull()) |
| 173 return; |
| 174 |
| 175 // The web speech API doesn't support "interrupted". |
| 176 synthesizer_client_->didFinishSpeaking(utterance); |
| 177 utterance_id_map_.erase(utterance_id); |
| 178 } |
| 179 |
| 180 void TtsDispatcher::OnWasCancelled(int utterance_id) { |
| 181 WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); |
| 182 if (utterance.isNull()) |
| 183 return; |
| 184 |
| 185 // The web speech API doesn't support "cancelled". |
| 186 synthesizer_client_->didFinishSpeaking(utterance); |
| 187 utterance_id_map_.erase(utterance_id); |
| 188 } |
| 189 |
| 190 void TtsDispatcher::OnSpeakingErrorOccurred(int utterance_id, |
| 191 const std::string& error_message) { |
| 192 WebSpeechSynthesisUtterance utterance = FindUtterance(utterance_id); |
| 193 if (utterance.isNull()) |
| 194 return; |
| 195 |
| 196 // The web speech API doesn't support an error message. |
| 197 synthesizer_client_->speakingErrorOccurred(utterance); |
| 198 utterance_id_map_.erase(utterance_id); |
| 199 } |
OLD | NEW |