Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(347)

Side by Side Diff: chrome/browser/speech/tts_controller_impl.cc

Issue 412783002: Separate out the TtsController interface from it's impl (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix coding style Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/speech/tts_controller.h" 5 #include "chrome/browser/speech/tts_controller_impl.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/float_util.h" 10 #include "base/float_util.h"
11 #include "base/values.h" 11 #include "base/values.h"
12 #include "chrome/browser/browser_process.h" 12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/speech/tts_platform.h" 13 #include "chrome/browser/speech/tts_platform.h"
14 14
15 namespace { 15 namespace {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 } 95 }
96 96
97 void Utterance::Finish() { 97 void Utterance::Finish() {
98 finished_ = true; 98 finished_ = true;
99 } 99 }
100 100
101 void Utterance::set_options(const base::Value* options) { 101 void Utterance::set_options(const base::Value* options) {
102 options_.reset(options->DeepCopy()); 102 options_.reset(options->DeepCopy());
103 } 103 }
104 104
105 TtsController* TtsController::GetInstance() {
106 return TtsControllerImpl::GetInstance();
107 }
108
105 // 109 //
106 // TtsController 110 // TtsControllerImpl
107 // 111 //
108 112
109 // static 113 // static
110 TtsController* TtsController::GetInstance() { 114 TtsControllerImpl* TtsControllerImpl::GetInstance() {
111 return Singleton<TtsController>::get(); 115 return Singleton<TtsControllerImpl>::get();
112 } 116 }
113 117
114 TtsController::TtsController() 118 TtsControllerImpl::TtsControllerImpl()
115 : current_utterance_(NULL), 119 : current_utterance_(NULL),
116 paused_(false), 120 paused_(false),
117 platform_impl_(NULL), 121 platform_impl_(NULL),
118 tts_engine_delegate_(NULL) { 122 tts_engine_delegate_(NULL) {
119 } 123 }
120 124
121 TtsController::~TtsController() { 125 TtsControllerImpl::~TtsControllerImpl() {
122 if (current_utterance_) { 126 if (current_utterance_) {
123 current_utterance_->Finish(); 127 current_utterance_->Finish();
124 delete current_utterance_; 128 delete current_utterance_;
125 } 129 }
126 130
127 // Clear any queued utterances too. 131 // Clear any queued utterances too.
128 ClearUtteranceQueue(false); // Don't sent events. 132 ClearUtteranceQueue(false); // Don't sent events.
129 } 133 }
130 134
131 void TtsController::SpeakOrEnqueue(Utterance* utterance) { 135 void TtsControllerImpl::SpeakOrEnqueue(Utterance* utterance) {
132 // If we're paused and we get an utterance that can't be queued, 136 // If we're paused and we get an utterance that can't be queued,
133 // flush the queue but stay in the paused state. 137 // flush the queue but stay in the paused state.
134 if (paused_ && !utterance->can_enqueue()) { 138 if (paused_ && !utterance->can_enqueue()) {
135 Stop(); 139 Stop();
136 paused_ = true; 140 paused_ = true;
137 return; 141 return;
138 } 142 }
139 143
140 if (paused_ || (IsSpeaking() && utterance->can_enqueue())) { 144 if (paused_ || (IsSpeaking() && utterance->can_enqueue())) {
141 utterance_queue_.push(utterance); 145 utterance_queue_.push(utterance);
142 } else { 146 } else {
143 Stop(); 147 Stop();
144 SpeakNow(utterance); 148 SpeakNow(utterance);
145 } 149 }
146 } 150 }
147 151
148 void TtsController::SpeakNow(Utterance* utterance) { 152 void TtsControllerImpl::SpeakNow(Utterance* utterance) {
149 // Ensure we have all built-in voices loaded. This is a no-op if already 153 // Ensure we have all built-in voices loaded. This is a no-op if already
150 // loaded. 154 // loaded.
151 bool loaded_built_in = 155 bool loaded_built_in =
152 GetPlatformImpl()->LoadBuiltInTtsExtension(utterance->profile()); 156 GetPlatformImpl()->LoadBuiltInTtsExtension(utterance->profile());
153 157
154 // Get all available voices and try to find a matching voice. 158 // Get all available voices and try to find a matching voice.
155 std::vector<VoiceData> voices; 159 std::vector<VoiceData> voices;
156 GetVoices(utterance->profile(), &voices); 160 GetVoices(utterance->profile(), &voices);
157 int index = GetMatchingVoice(utterance, voices); 161 int index = GetMatchingVoice(utterance, voices);
158 162
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 233
230 if (!success) { 234 if (!success) {
231 utterance->OnTtsEvent(TTS_EVENT_ERROR, kInvalidCharIndex, 235 utterance->OnTtsEvent(TTS_EVENT_ERROR, kInvalidCharIndex,
232 GetPlatformImpl()->error()); 236 GetPlatformImpl()->error());
233 delete utterance; 237 delete utterance;
234 return; 238 return;
235 } 239 }
236 } 240 }
237 } 241 }
238 242
239 void TtsController::Stop() { 243 void TtsControllerImpl::Stop() {
240 paused_ = false; 244 paused_ = false;
241 if (current_utterance_ && !current_utterance_->extension_id().empty()) { 245 if (current_utterance_ && !current_utterance_->extension_id().empty()) {
242 #if !defined(OS_ANDROID) 246 #if !defined(OS_ANDROID)
243 if (tts_engine_delegate_) 247 if (tts_engine_delegate_)
244 tts_engine_delegate_->Stop(current_utterance_); 248 tts_engine_delegate_->Stop(current_utterance_);
245 #endif 249 #endif
246 } else { 250 } else {
247 GetPlatformImpl()->clear_error(); 251 GetPlatformImpl()->clear_error();
248 GetPlatformImpl()->StopSpeaking(); 252 GetPlatformImpl()->StopSpeaking();
249 } 253 }
250 254
251 if (current_utterance_) 255 if (current_utterance_)
252 current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex, 256 current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex,
253 std::string()); 257 std::string());
254 FinishCurrentUtterance(); 258 FinishCurrentUtterance();
255 ClearUtteranceQueue(true); // Send events. 259 ClearUtteranceQueue(true); // Send events.
256 } 260 }
257 261
258 void TtsController::Pause() { 262 void TtsControllerImpl::Pause() {
259 paused_ = true; 263 paused_ = true;
260 if (current_utterance_ && !current_utterance_->extension_id().empty()) { 264 if (current_utterance_ && !current_utterance_->extension_id().empty()) {
261 #if !defined(OS_ANDROID) 265 #if !defined(OS_ANDROID)
262 if (tts_engine_delegate_) 266 if (tts_engine_delegate_)
263 tts_engine_delegate_->Pause(current_utterance_); 267 tts_engine_delegate_->Pause(current_utterance_);
264 #endif 268 #endif
265 } else if (current_utterance_) { 269 } else if (current_utterance_) {
266 GetPlatformImpl()->clear_error(); 270 GetPlatformImpl()->clear_error();
267 GetPlatformImpl()->Pause(); 271 GetPlatformImpl()->Pause();
268 } 272 }
269 } 273 }
270 274
271 void TtsController::Resume() { 275 void TtsControllerImpl::Resume() {
272 paused_ = false; 276 paused_ = false;
273 if (current_utterance_ && !current_utterance_->extension_id().empty()) { 277 if (current_utterance_ && !current_utterance_->extension_id().empty()) {
274 #if !defined(OS_ANDROID) 278 #if !defined(OS_ANDROID)
275 if (tts_engine_delegate_) 279 if (tts_engine_delegate_)
276 tts_engine_delegate_->Resume(current_utterance_); 280 tts_engine_delegate_->Resume(current_utterance_);
277 #endif 281 #endif
278 } else if (current_utterance_) { 282 } else if (current_utterance_) {
279 GetPlatformImpl()->clear_error(); 283 GetPlatformImpl()->clear_error();
280 GetPlatformImpl()->Resume(); 284 GetPlatformImpl()->Resume();
281 } else { 285 } else {
282 SpeakNextUtterance(); 286 SpeakNextUtterance();
283 } 287 }
284 } 288 }
285 289
286 void TtsController::OnTtsEvent(int utterance_id, 290 void TtsControllerImpl::OnTtsEvent(int utterance_id,
287 TtsEventType event_type, 291 TtsEventType event_type,
288 int char_index, 292 int char_index,
289 const std::string& error_message) { 293 const std::string& error_message) {
290 // We may sometimes receive completion callbacks "late", after we've 294 // We may sometimes receive completion callbacks "late", after we've
291 // already finished the utterance (for example because another utterance 295 // already finished the utterance (for example because another utterance
292 // interrupted or we got a call to Stop). This is normal and we can 296 // interrupted or we got a call to Stop). This is normal and we can
293 // safely just ignore these events. 297 // safely just ignore these events.
294 if (!current_utterance_ || utterance_id != current_utterance_->id()) { 298 if (!current_utterance_ || utterance_id != current_utterance_->id()) {
295 return; 299 return;
296 } 300 }
297 current_utterance_->OnTtsEvent(event_type, char_index, error_message); 301 current_utterance_->OnTtsEvent(event_type, char_index, error_message);
298 if (current_utterance_->finished()) { 302 if (current_utterance_->finished()) {
299 FinishCurrentUtterance(); 303 FinishCurrentUtterance();
300 SpeakNextUtterance(); 304 SpeakNextUtterance();
301 } 305 }
302 } 306 }
303 307
304 void TtsController::GetVoices(Profile* profile, 308 void TtsControllerImpl::GetVoices(Profile* profile,
305 std::vector<VoiceData>* out_voices) { 309 std::vector<VoiceData>* out_voices) {
306 #if !defined(OS_ANDROID) 310 #if !defined(OS_ANDROID)
307 if (profile && tts_engine_delegate_) 311 if (profile && tts_engine_delegate_)
308 tts_engine_delegate_->GetVoices(profile, out_voices); 312 tts_engine_delegate_->GetVoices(profile, out_voices);
309 #endif 313 #endif
310 314
311 TtsPlatformImpl* platform_impl = GetPlatformImpl(); 315 TtsPlatformImpl* platform_impl = GetPlatformImpl();
312 if (platform_impl) { 316 if (platform_impl) {
313 // Ensure we have all built-in voices loaded. This is a no-op if already 317 // Ensure we have all built-in voices loaded. This is a no-op if already
314 // loaded. 318 // loaded.
315 platform_impl->LoadBuiltInTtsExtension(profile); 319 platform_impl->LoadBuiltInTtsExtension(profile);
316 if (platform_impl->PlatformImplAvailable()) 320 if (platform_impl->PlatformImplAvailable())
317 platform_impl->GetVoices(out_voices); 321 platform_impl->GetVoices(out_voices);
318 } 322 }
319 } 323 }
320 324
321 bool TtsController::IsSpeaking() { 325 bool TtsControllerImpl::IsSpeaking() {
322 return current_utterance_ != NULL || GetPlatformImpl()->IsSpeaking(); 326 return current_utterance_ != NULL || GetPlatformImpl()->IsSpeaking();
323 } 327 }
324 328
325 void TtsController::FinishCurrentUtterance() { 329 void TtsControllerImpl::FinishCurrentUtterance() {
326 if (current_utterance_) { 330 if (current_utterance_) {
327 if (!current_utterance_->finished()) 331 if (!current_utterance_->finished())
328 current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex, 332 current_utterance_->OnTtsEvent(TTS_EVENT_INTERRUPTED, kInvalidCharIndex,
329 std::string()); 333 std::string());
330 delete current_utterance_; 334 delete current_utterance_;
331 current_utterance_ = NULL; 335 current_utterance_ = NULL;
332 } 336 }
333 } 337 }
334 338
335 void TtsController::SpeakNextUtterance() { 339 void TtsControllerImpl::SpeakNextUtterance() {
336 if (paused_) 340 if (paused_)
337 return; 341 return;
338 342
339 // Start speaking the next utterance in the queue. Keep trying in case 343 // Start speaking the next utterance in the queue. Keep trying in case
340 // one fails but there are still more in the queue to try. 344 // one fails but there are still more in the queue to try.
341 while (!utterance_queue_.empty() && !current_utterance_) { 345 while (!utterance_queue_.empty() && !current_utterance_) {
342 Utterance* utterance = utterance_queue_.front(); 346 Utterance* utterance = utterance_queue_.front();
343 utterance_queue_.pop(); 347 utterance_queue_.pop();
344 SpeakNow(utterance); 348 SpeakNow(utterance);
345 } 349 }
346 } 350 }
347 351
348 void TtsController::RetrySpeakingQueuedUtterances() { 352 void TtsControllerImpl::RetrySpeakingQueuedUtterances() {
349 if (current_utterance_ == NULL && !utterance_queue_.empty()) 353 if (current_utterance_ == NULL && !utterance_queue_.empty())
350 SpeakNextUtterance(); 354 SpeakNextUtterance();
351 } 355 }
352 356
353 void TtsController::ClearUtteranceQueue(bool send_events) { 357 void TtsControllerImpl::ClearUtteranceQueue(bool send_events) {
354 while (!utterance_queue_.empty()) { 358 while (!utterance_queue_.empty()) {
355 Utterance* utterance = utterance_queue_.front(); 359 Utterance* utterance = utterance_queue_.front();
356 utterance_queue_.pop(); 360 utterance_queue_.pop();
357 if (send_events) 361 if (send_events)
358 utterance->OnTtsEvent(TTS_EVENT_CANCELLED, kInvalidCharIndex, 362 utterance->OnTtsEvent(TTS_EVENT_CANCELLED, kInvalidCharIndex,
359 std::string()); 363 std::string());
360 else 364 else
361 utterance->Finish(); 365 utterance->Finish();
362 delete utterance; 366 delete utterance;
363 } 367 }
364 } 368 }
365 369
366 void TtsController::SetPlatformImpl( 370 void TtsControllerImpl::SetPlatformImpl(
367 TtsPlatformImpl* platform_impl) { 371 TtsPlatformImpl* platform_impl) {
368 platform_impl_ = platform_impl; 372 platform_impl_ = platform_impl;
369 } 373 }
370 374
371 int TtsController::QueueSize() { 375 int TtsControllerImpl::QueueSize() {
372 return static_cast<int>(utterance_queue_.size()); 376 return static_cast<int>(utterance_queue_.size());
373 } 377 }
374 378
375 TtsPlatformImpl* TtsController::GetPlatformImpl() { 379 TtsPlatformImpl* TtsControllerImpl::GetPlatformImpl() {
376 if (!platform_impl_) 380 if (!platform_impl_)
377 platform_impl_ = TtsPlatformImpl::GetInstance(); 381 platform_impl_ = TtsPlatformImpl::GetInstance();
378 return platform_impl_; 382 return platform_impl_;
379 } 383 }
380 384
381 int TtsController::GetMatchingVoice( 385 int TtsControllerImpl::GetMatchingVoice(
382 const Utterance* utterance, std::vector<VoiceData>& voices) { 386 const Utterance* utterance, std::vector<VoiceData>& voices) {
383 // Make two passes: the first time, do strict language matching 387 // Make two passes: the first time, do strict language matching
384 // ('fr-FR' does not match 'fr-CA'). The second time, do prefix 388 // ('fr-FR' does not match 'fr-CA'). The second time, do prefix
385 // language matching ('fr-FR' matches 'fr' and 'fr-CA') 389 // language matching ('fr-FR' matches 'fr' and 'fr-CA')
386 for (int pass = 0; pass < 2; ++pass) { 390 for (int pass = 0; pass < 2; ++pass) {
387 for (size_t i = 0; i < voices.size(); ++i) { 391 for (size_t i = 0; i < voices.size(); ++i) {
388 const VoiceData& voice = voices[i]; 392 const VoiceData& voice = voices[i];
389 393
390 if (!utterance->extension_id().empty() && 394 if (!utterance->extension_id().empty() &&
391 utterance->extension_id() != voice.extension_id) { 395 utterance->extension_id() != voice.extension_id) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 continue; 433 continue;
430 } 434 }
431 435
432 return static_cast<int>(i); 436 return static_cast<int>(i);
433 } 437 }
434 } 438 }
435 439
436 return -1; 440 return -1;
437 } 441 }
438 442
439 void TtsController::VoicesChanged() { 443 void TtsControllerImpl::VoicesChanged() {
440 for (std::set<VoicesChangedDelegate*>::iterator iter = 444 for (std::set<VoicesChangedDelegate*>::iterator iter =
441 voices_changed_delegates_.begin(); 445 voices_changed_delegates_.begin();
442 iter != voices_changed_delegates_.end(); ++iter) { 446 iter != voices_changed_delegates_.end(); ++iter) {
443 (*iter)->OnVoicesChanged(); 447 (*iter)->OnVoicesChanged();
444 } 448 }
445 } 449 }
446 450
447 void TtsController::AddVoicesChangedDelegate(VoicesChangedDelegate* delegate) { 451 void TtsControllerImpl::AddVoicesChangedDelegate(
452 VoicesChangedDelegate* delegate) {
448 voices_changed_delegates_.insert(delegate); 453 voices_changed_delegates_.insert(delegate);
449 } 454 }
450 455
451 void TtsController::RemoveVoicesChangedDelegate( 456 void TtsControllerImpl::RemoveVoicesChangedDelegate(
452 VoicesChangedDelegate* delegate) { 457 VoicesChangedDelegate* delegate) {
453 voices_changed_delegates_.erase(delegate); 458 voices_changed_delegates_.erase(delegate);
454 } 459 }
455 460
456 void TtsController::SetTtsEngineDelegate( 461 void TtsControllerImpl::SetTtsEngineDelegate(
457 TtsEngineDelegate* delegate) { 462 TtsEngineDelegate* delegate) {
458 tts_engine_delegate_ = delegate; 463 tts_engine_delegate_ = delegate;
459 } 464 }
OLDNEW
« no previous file with comments | « chrome/browser/speech/tts_controller_impl.h ('k') | chrome/browser/speech/tts_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698