2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://floralicense.org/license/
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
18 #include <FBaseColArrayList.h>
19 #include <FBaseString.h>
20 #include <FBaseSysLog.h>
21 #include <FBaseUtilStringTokenizer.h>
22 #include <FLclLocale.h>
23 #include <FBase_StringConverter.h>
24 #include "FUi_AccessibilityTtsPlayer.h"
25 #include "FUi_AccessibilityManager.h"
27 using namespace Tizen::Base;
28 using namespace Tizen::Base::Collection;
29 using namespace Tizen::Locales;
31 namespace Tizen { namespace Ui {
33 _AccessibilityTtsPlayer::_AccessibilityTtsPlayer(_AccessibilityManager& manager)
34 : __initialized(false)
37 , __speed(TTS_SPEED_AUTO)
38 , __status(ACCESSIBILITY_SCREEN_READER_STATUS_ERROR)
40 , __pCurrentLocale(null)
41 , __pSupportedLocaleList(null)
42 , __pManager(&manager)
46 _AccessibilityTtsPlayer::~_AccessibilityTtsPlayer(void)
48 tts_state_e ttsState = TTS_STATE_READY;
50 int ttsError = tts_get_state(__ttsHandle, &ttsState);
51 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to get the current state.", GetEngineErrorMessage(ttsError));
53 if (ttsState == TTS_STATE_PLAYING || ttsState == TTS_STATE_PAUSED)
55 ttsError = tts_stop(__ttsHandle);
56 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to stop.", GetEngineErrorMessage(ttsError));
61 ttsError = tts_unprepare(__ttsHandle);
62 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to unprepare.", GetEngineErrorMessage(ttsError));
64 ttsError = tts_unset_utterance_completed_cb(__ttsHandle);
65 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to unset the utterance completed callback.", GetEngineErrorMessage(ttsError));
67 ttsError = tts_unset_utterance_started_cb(__ttsHandle);
68 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to unset the utterance started callback.", GetEngineErrorMessage(ttsError));
70 ttsError = tts_unset_state_changed_cb(__ttsHandle);
71 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to unset the state changed callback.", GetEngineErrorMessage(ttsError));
73 ttsError = tts_unset_error_cb(__ttsHandle);
74 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to unset the error callback.", GetEngineErrorMessage(ttsError));
76 ttsError = tts_destroy(__ttsHandle);
77 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to destroy.", GetEngineErrorMessage(ttsError));
80 delete __pCurrentLocale;
82 if (__pSupportedLocaleList != null)
84 __pSupportedLocaleList->RemoveAll(true);
85 delete __pSupportedLocaleList;
90 _AccessibilityTtsPlayer::Construct(void)
92 Locale *pLocale = new (std::nothrow) Locale(LANGUAGE_INVALID, COUNTRY_INVALID);
93 SysTryReturnResult(NID_UI, pLocale != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
95 ArrayList* pLocaleList = new (std::nothrow) ArrayList();
96 SysTryReturnResult(NID_UI, pLocaleList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
98 result r = pLocaleList->Construct();
99 SysTryReturnResult(NID_UI, r == E_SUCCESS, E_OUT_OF_MEMORY, "The memory is insufficient.");
101 __pCurrentLocale = pLocale;
102 __pSupportedLocaleList = pLocaleList;
108 _AccessibilityTtsPlayer::Activate(void)
110 SysAssertf(__initialized != true,
111 "Already calling Initialize() twice or more on a same instance is not allowed for this class.");
113 int ttsError = tts_create(&__ttsHandle);
114 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to create.");
116 ttsError = tts_set_error_cb(__ttsHandle, TtsErrorReceiver, (void*)(this));
117 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
119 ttsError = tts_set_state_changed_cb(__ttsHandle, TtsStateChangedReceiver, (void*)(this));
120 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
122 ttsError = tts_set_utterance_started_cb(__ttsHandle, TtsStartedReceiver, (void*)(this));
123 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
125 ttsError = tts_set_utterance_completed_cb(__ttsHandle, TtsCompletedReceiver, (void*)(this));
126 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
128 ttsError = tts_prepare(__ttsHandle);
129 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
135 _AccessibilityTtsPlayer::GetEngineStateMessage(const tts_state_e state)
139 case TTS_STATE_CREATED:
142 case TTS_STATE_READY:
145 case TTS_STATE_PLAYING:
148 case TTS_STATE_PAUSED:
157 _AccessibilityTtsPlayer::GetEngineErrorMessage(const int errorType)
162 return "TTS_ERROR_NONE";
164 case TTS_ERROR_OUT_OF_MEMORY:
165 return "TTS_ERROR_OUT_OF_MEMORY";
167 case TTS_ERROR_IO_ERROR:
168 return "TTS_ERROR_IO_ERROR";
170 case TTS_ERROR_INVALID_PARAMETER:
171 return "TTS_ERROR_INVALID_PARAMETER";
173 case TTS_ERROR_INVALID_STATE:
174 return "TTS_ERROR_INVALID_STATE";
176 case TTS_ERROR_INVALID_VOICE:
177 return "TTS_ERROR_INVALID_VOICE";
179 case TTS_ERROR_ENGINE_NOT_FOUND:
180 return "TTS_ERROR_ENGINE_NOT_FOUND";
182 case TTS_ERROR_TIMED_OUT:
183 return "TTS_ERROR_TIMED_OUT";
185 case TTS_ERROR_OPERATION_FAILED:
186 return "TTS_ERROR_OPERATION_FAILED";
189 return "TTS_ERROR_UNKNOWN_ERROR";
194 _AccessibilityTtsPlayer::TtsStateChangedReceiver(tts_h ttsHandle, tts_state_e previousState, tts_state_e currentState, void* pTtsInstance)
196 SysLog(NID_UI, "[Accessibility TTS] [%s] ---> [%s]", GetEngineStateMessage(previousState), GetEngineStateMessage(currentState));
198 if ((previousState == TTS_STATE_CREATED) && (currentState == TTS_STATE_READY))
200 char *pDefaultLang = null;
201 tts_voice_type_e defaultVoiceType;
203 int ttsError = tts_get_default_voice(ttsHandle, &pDefaultLang, &defaultVoiceType);
204 if (ttsError == TTS_ERROR_NONE)
206 SysLog(NID_UI, "Default language[%s] and voice[%d]", pDefaultLang, defaultVoiceType);
207 const Locale* pDefaultLocale = ConvertEngineLocaleToNativeN(pDefaultLang);
210 delete static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->__pCurrentLocale;
211 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->__pCurrentLocale = const_cast<Locale*>(pDefaultLocale);
216 ttsError = tts_foreach_supported_voices(ttsHandle, TtsSupportedLocaleListGetter, (void*)(static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->__pSupportedLocaleList));
217 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to get supported voices", GetEngineErrorMessage(ttsError));
219 tts_set_mode(ttsHandle, TTS_MODE_SCREEN_READER);
220 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->__initialized = true;
221 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->OnStatusChanged(ACCESSIBILITY_SCREEN_READER_STATUS_READY);
223 else if ((previousState == TTS_STATE_READY || previousState == TTS_STATE_PAUSED) && (currentState == TTS_STATE_PLAYING))
225 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->OnStatusChanged(ACCESSIBILITY_SCREEN_READER_STATUS_PLAYING);
227 else if ((previousState == TTS_STATE_PLAYING) && (currentState == TTS_STATE_PAUSED))
229 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->OnStatusChanged(ACCESSIBILITY_SCREEN_READER_STATUS_PAUSE);
231 else if ((previousState == TTS_STATE_PLAYING || previousState == TTS_STATE_PAUSED) && (currentState == TTS_STATE_READY))
233 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->OnStatusChanged(ACCESSIBILITY_SCREEN_READER_STATUS_READY);
237 SysLog(NID_UI, "[CB] Unknown state. / [%s] ---> [%s]",
238 GetEngineStateMessage(previousState), GetEngineStateMessage(currentState));
242 _AccessibilityTtsPlayer::TtsStartedReceiver(tts_h ttsHandle, int utteranceId, void* pListener)
244 SysLog(NID_UI, "Accessibility TTS reader is started", utteranceId);
247 _AccessibilityTtsPlayer::TtsCompletedReceiver(tts_h ttsHandle, int utteranceId, void* pTtsInstance)
249 int ttsError = tts_stop(ttsHandle);
250 SysTryReturnVoidResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM,
251 "[CB] Failed to stop, error[%s]", GetEngineErrorMessage(ttsError));
252 _AccessibilityTtsPlayer* pPlayer = static_cast<_AccessibilityTtsPlayer*>(pTtsInstance);
253 pPlayer->SetStatus(ACCESSIBILITY_SCREEN_READER_STATUS_READY);
254 pPlayer->__pManager->OnFinishReading(pPlayer->__grammar);
257 _AccessibilityTtsPlayer::TtsErrorReceiver(tts_h ttsHandle, int ttsUtteranceId, tts_error_e error, void* pTtsInstance)
259 Tizen::Base::String errorMessage =L"";
262 case TTS_ERROR_OUT_OF_MEMORY:
263 errorMessage = L"TEXT_TO_SPEECH_ERROR_OUT_OF_MEMORY";
265 case TTS_ERROR_IO_ERROR:
266 errorMessage = L"TEXT_TO_SPEECH_ERROR_IO_ERROR";
268 case TTS_ERROR_OUT_OF_NETWORK:
269 errorMessage = L"TEXT_TO_SPEECH_ERROR_NETWORK_ERROR";
271 case TTS_ERROR_ENGINE_NOT_FOUND:
272 errorMessage = L"TEXT_TO_SPEECH_ERROR_UNSUPPORTED_SERVICE";
274 case TTS_ERROR_TIMED_OUT:
275 errorMessage = L"TEXT_TO_SPEECH_ERROR_TIME_OUT";
278 errorMessage = L"TEXT_TO_SPEECH_ERROR_SYSTEM_ERROR";
281 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->OnErrorOccurred(errorMessage);
284 _AccessibilityTtsPlayer::TtsSupportedLocaleListGetter(tts_h ttsHandle, const char* pLanguage, tts_voice_type_e voiceType, void* pLocaleList)
286 const Locale* pLocale = ConvertEngineLocaleToNativeN(String(pLanguage));
289 static_cast <ArrayList*>(pLocaleList)->RemoveAll(true);
293 if (pLocale->GetLanguageCode() == LANGUAGE_INVALID)
295 SysLog(NID_UI, "[CB] Not support language[%s]", pLanguage);
300 result r = static_cast<ArrayList*>(pLocaleList)->Add(*pLocale);
303 static_cast<ArrayList*>(pLocaleList)->RemoveAll(true);
310 _AccessibilityTtsPlayer::ConvertTizenLocaleToEngineN(const Tizen::Locales::Locale& locale)
312 String strLanguageCode = Locale::LanguageCodeToTwoLetterLanguageCodeString(locale.GetLanguageCode());
313 String strCountryCode = Locale::CountryCodeToString(locale.GetCountryCode());
314 String strLanguage = strLanguageCode + L"_" + strCountryCode;
316 return _StringConverter::CopyToCharArrayN(strLanguage);
318 const Tizen::Locales::Locale*
319 _AccessibilityTtsPlayer::ConvertEngineLocaleToNativeN(const Tizen::Base::String& strSource)
321 String strDelim(L"_");
322 String strLanguageCode;
323 String strCountryCode;
325 LanguageCode languageCode = LANGUAGE_INVALID;
326 CountryCode countryCode = COUNTRY_INVALID;
328 Utility::StringTokenizer toknizer(strSource, strDelim);
329 if (toknizer.GetTokenCount() == 2)
331 toknizer.GetNextToken(strLanguageCode);
332 toknizer.GetNextToken(strCountryCode);
334 languageCode = Locale::TwoLetterLanguageCodeStringToLanguageCode(strLanguageCode);
335 countryCode = Locale::StringToCountryCode(strCountryCode);
338 return new (std::nothrow) Locale(languageCode, countryCode);
342 _AccessibilityTtsPlayer::Speak(const String& text)
344 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
345 "Not yet initialized! This method should be called after initialized.");
347 result r = E_SUCCESS;
348 tts_state_e ttsState = TTS_STATE_READY;
350 int ttsError = tts_get_state(__ttsHandle, &ttsState);
351 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to get the current state.");
353 const char* pLanguage = ConvertTizenLocaleToEngineN(*__pCurrentLocale);
354 SysTryReturnResult(NID_UI, pLanguage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
356 // if (ttsState != TTS_STATE_READY)
361 const char* pTextN = _StringConverter::CopyToCharArrayN(text);
362 int ttsUtteranceId = 0;
364 SysTryCatchLabel(NID_UI, pTextN != null, r = E_OUT_OF_MEMORY, CATCH_LANG, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
366 ttsError = tts_add_text(__ttsHandle, pTextN, pLanguage, TTS_VOICE_TYPE_AUTO, __speed, &ttsUtteranceId);
367 SysTryCatch(NID_UI, ttsError == TTS_ERROR_NONE, r = E_OUT_OF_MEMORY, E_SYSTEM, "[E_SYSTEM] Failed to add a text.");
368 ttsError = tts_play(__ttsHandle);
369 SysTryCatch(NID_UI, ttsError == TTS_ERROR_NONE, r = E_SYSTEM, E_SYSTEM, "[%s] Failed to play.", GetEngineErrorMessage(ttsError));
371 OnStatusChanged(ACCESSIBILITY_SCREEN_READER_STATUS_PLAYING);
383 _AccessibilityTtsPlayer::Stop(void)
385 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
386 "Not yet initialized! This method should be called after initialized.");
388 tts_state_e ttsState = TTS_STATE_READY;
390 int ttsError = tts_get_state(__ttsHandle, &ttsState);
391 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to get the current state.");
392 ttsError = tts_stop(__ttsHandle);
393 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to stop.");
399 _AccessibilityTtsPlayer::Pause(void)
401 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
402 "Not yet initialized! This method should be called after initialized.");
404 tts_state_e ttsState = TTS_STATE_READY;
406 int ttsError = tts_get_state(__ttsHandle, &ttsState);
407 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to get the current state.");
408 SysTryReturnResult(NID_UI, ttsState == TTS_STATE_PLAYING, E_INVALID_OPERATION, "The TTS state should be TTS_STATUS_PLAYING.");
410 ttsError = tts_pause(__ttsHandle);
411 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to pause.");
417 _AccessibilityTtsPlayer::Resume(void)
419 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
420 "Not yet initialized! This method should be called after initialized.");
422 tts_state_e ttsState = TTS_STATE_READY;
424 int ttsError = tts_get_state(__ttsHandle, &ttsState);
425 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to get the current state.");
426 SysTryReturnResult(NID_UI, ttsState == TTS_STATE_PAUSED, E_INVALID_OPERATION, "The TTS state should be TTS_STATUS_PAUSED.");
428 ttsError = tts_play(__ttsHandle);
429 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to resume.");
435 _AccessibilityTtsPlayer::SetLocale(const Locale& locale)
437 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
438 "Not yet initialized! This method should be called after initialized.");
439 SysTryReturnResult(NID_UI, __pSupportedLocaleList->Contains(locale), E_UNSUPPORTED_LOCALE, "This locale is not supported.");
441 *__pCurrentLocale = locale;
445 Tizen::Locales::Locale
446 _AccessibilityTtsPlayer::GetLocale(void) const
448 SysTryReturn(NID_UI, __initialized, Locale(LANGUAGE_INVALID, COUNTRY_INVALID), E_INVALID_STATE,
449 "[E_INVALID_STATE] Not yet initialized! This method should be called after initialized.");
451 SetLastResult(E_SUCCESS);
452 return *__pCurrentLocale;
455 const Tizen::Base::Collection::IList*
456 _AccessibilityTtsPlayer::GetSupportedLocales(void) const
458 SysTryReturnResult(NID_UI, __initialized , null,
459 "Not yet initialized! This method should be called after initialized.");
461 SetLastResult(E_SUCCESS);
462 return __pSupportedLocaleList->GetCount() > 0 ? __pSupportedLocaleList : null;
466 _AccessibilityTtsPlayer::IsLocaleSupported(const Tizen::Locales::Locale& locale) const
468 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
469 "Not yet initialized! This method should be called after initialized.");
471 SetLastResult(E_SUCCESS);
472 return __pSupportedLocaleList->Contains(locale);
476 _AccessibilityTtsPlayer::SetSpeechRate(tts_speed_e speechRate)
478 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
479 "Not yet initialized! This method should be called after initialized.");
481 __speed = speechRate;
487 _AccessibilityTtsPlayer::ReadGrammar(const Tizen::Base::String& grammar, bool init)
489 if(grammar.GetLength() == 0)
493 if(init && GetStatus() == ACCESSIBILITY_SCREEN_READER_STATUS_PLAYING)
497 SetStatus(ACCESSIBILITY_SCREEN_READER_STATUS_PLAYING);
503 _AccessibilityTtsPlayer::StopReading(void)
508 AccessibilityScreenReaderStatus
509 _AccessibilityTtsPlayer::GetStatus(void)
514 _AccessibilityTtsPlayer::GetCurrentGrammar(void)
520 _AccessibilityTtsPlayer::Deactivate(void)
526 _AccessibilityTtsPlayer::OnErrorOccurred(Tizen::Base::String& errorString)
530 _AccessibilityTtsPlayer::OnStatusChanged(AccessibilityScreenReaderStatus status)
534 case ACCESSIBILITY_SCREEN_READER_STATUS_PLAYING:
535 __pManager->OnStartReading(__grammar);
544 _AccessibilityTtsPlayer::SetStatus(AccessibilityScreenReaderStatus status)