2 * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 * http://www.apache.org/licenses/LICENSE-2.0
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS,
9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and
11 * limitations under the License.
15 #include <stdatomic.h>
17 #include <app_manager.h>
19 #include <package-manager.h>
21 #include "tts_internal.h"
28 static const int TTS_ERROR_FAIL_TO_SEND_HELLO = TIZEN_ERROR_TTS | 0xFF;
31 /* Static variables */
32 static atomic_bool g_is_thread_canceled = false;
34 static char* g_engine_name = NULL;
35 static int g_engine_update_status = 0;
36 static atomic_bool g_is_engine_name_changed = false;
38 static Ecore_Thread* g_reprepare_thread = NULL;
40 static char* g_pkgmgr_status = NULL;
41 static pkgmgr_client* g_pkgmgr = NULL;
42 static Ecore_Thread* g_pkgmgr_thread = NULL;
43 static pthread_mutex_t g_pkgmgr_mutex = PTHREAD_MUTEX_INITIALIZER;
45 static char* g_language = NULL;
46 static int g_voice_type = -1;
47 static int g_speed = -1;
50 /* Static functions */
51 // TODO: make tts_util? or tts_log?
52 static const char* __convert_state(tts_state_e state)
55 case TTS_STATE_CREATED: return "Created";
56 case TTS_STATE_READY: return "Ready";
57 case TTS_STATE_PLAYING: return "Playing";
58 case TTS_STATE_PAUSED: return "Paused";
61 return "Invalid state";
64 static char* __get_engine_appid() {
65 if (NULL == g_engine_name) {
69 char* appid = (char*)calloc(TTS_ENGINE_APPID_LEN, sizeof(char));
74 snprintf(appid, TTS_ENGINE_APPID_LEN, "%s", g_engine_name);
78 static int __update_engine_name()
80 char* new_engine_name = vconf_get_str(TTS_ENGINE_DB_DEFAULT);
81 RETVM_IF(NULL == new_engine_name, TTS_ERROR_OPERATION_FAILED, "[ERROR] Fail to get engine name");
83 if (NULL != g_engine_name && 0 == strncmp(g_engine_name, new_engine_name, TTS_ENGINE_APPID_LEN)) {
84 SLOG(LOG_INFO, TAG_TTSC, "[INFO] engine name is same");
85 free(new_engine_name);
86 return TTS_ERROR_NONE;
90 g_engine_name = new_engine_name;
91 g_is_engine_name_changed = true;
93 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Engine name(%s)", g_engine_name);
94 return TTS_ERROR_NONE;
97 static inline void __client_error_cb(tts_client_s* client, int utt_id, tts_error_e reason)
99 tts_error_cb callback = tts_client_get_error_cb(client);
100 void* data = tts_client_get_error_user_data(client);
102 if (NULL != callback) {
103 SLOG(LOG_DEBUG, TAG_TTSC, "Notify error");
104 tts_client_use_callback(client);
105 callback(tts_client_get_handle(client), utt_id, reason, data);
106 tts_client_not_use_callback(client);
108 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(error)");
112 static inline void __client_state_changed_cb(tts_client_s* client, tts_state_e before_state, tts_state_e current_state)
114 tts_state_changed_cb callback = tts_client_get_state_changed_cb(client);
115 void* data = tts_client_get_state_changed_user_data(client);
117 if (NULL != callback) {
118 SLOG(LOG_DEBUG, TAG_TTSC, "State changed data : before_state(%s) curret_state(%s)", __convert_state(before_state), __convert_state(current_state));
119 tts_client_use_callback(client);
120 callback(tts_client_get_handle(client), before_state, current_state, data);
121 tts_client_not_use_callback(client);
123 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(state_changed)");
127 static Eina_Bool __notify_error_timer_cb(void *data)
129 unsigned int uid = (uintptr_t)data;
130 tts_client_s* client = tts_client_get_by_uid(uid);
131 RETVM_IF(NULL == client, EINA_FALSE, "[ERROR] uid(%u) is not valid.", uid);
133 __client_error_cb(client, client->utt_id, client->reason);
134 client->notify_error_timer = NULL;
139 static bool __is_engine_installed(const char* appid)
141 app_info_h app_info = NULL;
142 int ret = app_manager_get_app_info(appid, &app_info);
143 if (APP_MANAGER_ERROR_NONE != ret || NULL == app_info) {
144 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] There is no tts engine (%s). ret(%d)", appid, ret);
147 SLOG(LOG_INFO, TAG_TTSC, "[INFO] There is tts engine (%s)", appid);
150 ret = app_info_destroy(app_info);
151 if (APP_MANAGER_ERROR_NONE != ret)
152 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to destroy app_info. ret(%d)", ret);
157 static bool __is_engine_launched()
159 char* appid = __get_engine_appid();
161 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine app ID");
165 bool is_installed = __is_engine_installed(appid);
166 if (false == is_installed) {
167 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] tts engine(%s) is not installed", appid);
172 bool is_running = false;
173 int ret = app_manager_is_running(appid, &is_running);
174 if (APP_MANAGER_ERROR_NONE != ret) {
175 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to check whether appid(%s) is running or not. ret(%d)", appid, ret);
176 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is installed(%d)", is_installed);
182 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is %s running. is_installed(%d)", (is_running) ? "" : " not", is_installed);
187 static int __pkgmgr_status_cb(uid_t target_uid, int req_id, const char *type, const char *pkgname, const char *key, const char *val, const void *pmsg, void *data)
189 // type (the type of the pkgname)
190 SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status cb is invoked. pkgname(%s), type(%s), key(%s), val(%s)", pkgname, type, key, val);
192 if (NULL == g_engine_name) {
193 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] engine name is NULL");
197 if (0 != strncmp(g_engine_name, pkgname, strlen(g_engine_name))) {
198 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] this is not tts engine");
203 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] key is NULL");
207 if (0 == strncmp(key, "start", strlen(key))) {
208 if (NULL != g_pkgmgr_status) {
209 free(g_pkgmgr_status);
210 g_pkgmgr_status = NULL;
214 g_pkgmgr_status = strdup(val);
215 SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status. key(%s), status(%s)", key, g_pkgmgr_status);
217 if ((0 == strncmp(val, "update", strlen(val) || 0 == strncmp(val, "uninstall", strlen(val))))) {
218 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] start to install.");
219 g_engine_update_status = 1;
222 } else if (0 == strncmp(key, "end", strlen(key)) && val && 0 == strncmp(val, "ok", strlen(val))) {
223 if (g_pkgmgr_status) {
224 if (0 == strncmp(g_pkgmgr_status, "install", strlen(g_pkgmgr_status)) || 0 == strncmp(g_pkgmgr_status, "update", strlen(g_pkgmgr_status))) {
225 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] finish to install");
226 g_engine_update_status = 0;
228 free(g_pkgmgr_status);
229 g_pkgmgr_status = NULL;
238 static void __create_pkgmgr_thread(void* data, Ecore_Thread* thread)
240 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] create pkgmgr thread");
242 pthread_mutex_lock(&g_pkgmgr_mutex);
243 while (NULL == g_pkgmgr) {
244 /* Checking the thread is canceled or not */
245 if (g_is_thread_canceled) {
246 SLOG(LOG_INFO, TAG_TTSC, "[INFO] g_pkgmgr_thread is canceled. Exit");
250 /* Checking handle which can be destroyed on other thread */
251 if (0 == tts_client_get_size()) {
252 SLOG(LOG_INFO, TAG_TTSC, "[INFO] All client is already destroyed");
256 g_pkgmgr = pkgmgr_client_new(PC_LISTENING);
257 if (NULL == g_pkgmgr) {
258 // SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create pkgmgr handle");
260 int ret = pkgmgr_client_set_status_type(g_pkgmgr, PKGMGR_CLIENT_STATUS_INSTALL | PKGMGR_CLIENT_STATUS_UNINSTALL | PKGMGR_CLIENT_STATUS_UPGRADE);
262 if (pkgmgr_client_listen_status(g_pkgmgr, __pkgmgr_status_cb, NULL) < 0) {
263 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to listen pkgmgr status. remove and recreate client");
264 pkgmgr_client_free(g_pkgmgr);
267 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Succeed to register pkgmgr cb");
271 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set status type on pkgmgr, ret(%d)", ret);
272 pkgmgr_client_free(g_pkgmgr);
279 pthread_mutex_unlock(&g_pkgmgr_mutex);
281 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] create pkgmgr end");
284 static void __finish_pkgmgr_thread(void* data, Ecore_Thread* thread)
286 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] Finish pkgmgr thread");
287 g_is_thread_canceled = false;
288 g_pkgmgr_thread = NULL;
292 static void __cancel_pkgmgr_thread(void* data, Ecore_Thread* thread)
294 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] Cancel pkgmgr thread");
295 g_is_thread_canceled = false;
296 g_pkgmgr_thread = NULL;
300 static void __pkgmgr_thread(void* data)
302 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] call pkgmgr_thread");
303 if (NULL == g_pkgmgr_thread) {
304 SLOG(LOG_INFO, TAG_TTSC, "[INFO] ecore thread run: create_pkgmgr_thread");
305 g_pkgmgr_thread = ecore_thread_run(__create_pkgmgr_thread, __finish_pkgmgr_thread, __cancel_pkgmgr_thread, NULL);
312 static void __start_reprepare_thread(void* data, Ecore_Thread* thread)
314 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] start reprepare thread. engine update status(%d)", g_engine_update_status);
316 if (0 == g_engine_update_status && g_is_engine_name_changed) {
317 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Reprepare by engine change");
322 while (!g_engine_update_status && cnt < 20) {
323 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] wait for starting update");
328 // TODO: fix way to exit thread safely
329 /* Checking thread is canceled or not */
330 if (ecore_thread_check(g_reprepare_thread)) {
331 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] client thread is canceled. Exit");
336 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] update status(%d)", g_engine_update_status);
338 while (g_engine_update_status && (NULL != g_pkgmgr)) {
341 // TODO: fix way to exit thread safely
342 /* Checking thread is canceled or not */
343 if (ecore_thread_check(g_reprepare_thread)) {
344 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] client thread is canceled. Exit");
349 SLOG(LOG_INFO, TAG_TTSC, "[INFO] finish updating. request to prepare");
355 static void __end_reprepare_thread(void* data, Ecore_Thread* thread)
357 SLOG(LOG_INFO, TAG_TTSC, "[INFO] end reprepare thread");
359 GList* clients = tts_client_get_client_list();
360 if (NULL == clients) {
361 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get client list");
362 g_is_engine_name_changed = false;
363 g_reprepare_thread = NULL;
368 if (g_list_length(clients) > 0) {
369 iter = g_list_first(clients);
371 while (NULL != iter) {
372 tts_client_s* client = iter->data;
373 if (NULL != client) {
374 tts_core_prepare(client);
377 iter = g_list_next(iter);
381 g_list_free(clients);
382 g_is_engine_name_changed = false;
383 g_reprepare_thread = NULL;
387 static void __cancel_reprepare_thread(void* data, Ecore_Thread* thread)
389 SLOG(LOG_INFO, TAG_TTSC, "[INFO] cancel reprepare thread");
390 g_is_engine_name_changed = false;
391 g_reprepare_thread = NULL;
395 static inline void __run_client_reprepare_thread()
397 if (NULL == g_reprepare_thread) {
398 SLOG(LOG_INFO, TAG_TTSC, "[INFO] ecore thread run: start_reprepare_thread");
399 g_reprepare_thread = ecore_thread_run(__start_reprepare_thread, __end_reprepare_thread, __cancel_reprepare_thread, NULL);
401 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Reprepare thread is already running");
405 static int __send_hello_msg(tts_client_s* client)
407 tts_state_e current_state = tts_client_get_current_state(client);
408 if (TTS_STATE_READY == current_state) {
409 SLOG(LOG_INFO, TAG_TTSC, "[INFO] TTS client has been already connected to tts service"); //LCOV_EXCL_LINE
410 return TTS_ERROR_INVALID_STATE;
413 if (false == tts_core_check_screen_reader(client)) {
414 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is not available");
415 return TTS_ERROR_SCREEN_READER_OFF;
418 unsigned int uid = tts_client_get_uid(client);
419 tts_mode_e mode = tts_client_get_mode(client);
420 int registered_callback_mask = tts_client_get_registered_event_mask(client);
421 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%u), mode(%d)", tts_client_get_handle(client), client, uid, (int)mode);
423 /* check service engine status */
424 bool is_launched = __is_engine_launched();
425 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
426 if (false == is_launched) {
427 /* If engine is NOT launched, check whether engine is updating or not */
428 if (g_engine_update_status) {
429 /* suyeon wait engine update */
430 SLOG(LOG_INFO, TAG_TTSC, "[INFO] cannot prepare due to engine update");
431 __run_client_reprepare_thread();
432 return TTS_ERROR_INVALID_STATE;
436 if (0 != tts_ipc_request_hello(uid, mode, registered_callback_mask)) {
437 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request hello !!"); //LCOV_EXCL_LINE
439 SLOG(LOG_INFO, TAG_TTSC, "@@@ Send Hello");
442 return TTS_ERROR_NONE;
445 static Eina_Bool __prepare_cb(void *data)
447 unsigned int uid = (uintptr_t)data;
448 tts_client_s* client = tts_client_get_by_uid(uid);
449 RETVM_IF(NULL == client, EINA_FALSE, "[ERROR] uid(%u) is not valid.", uid);
451 int ret = __send_hello_msg(client);
452 if (ret != TTS_ERROR_NONE) {
453 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to send hello message"); //LCOV_EXCL_LINE
454 client->hello_timer = NULL;
458 client->prepare_count++;
459 if (TTS_HELLO_RETRY_COUNT == client->prepare_count) {
460 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare, retry count reaches the limit");
462 bool is_launched = __is_engine_launched();
463 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
465 client->hello_timer = NULL;
467 tts_core_notify_error_async(client, TTS_ERROR_TIMED_OUT, -1, "[ERROR] Fail to prepare. Please call tts_prepare() again.");
475 static Eina_Bool __prepare_first_cb(void *data)
477 /* send first hello message */
478 unsigned int uid = (uintptr_t)data;
479 tts_client_s* client = tts_client_get_by_uid(uid);
480 RETVM_IF(NULL == client, EINA_FALSE, "[ERROR] uid(%u) is not valid.", uid);
482 int ret = __send_hello_msg(client);
483 if (ret != TTS_ERROR_NONE) {
484 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to sent hello message"); //LCOV_EXCL_LINE
485 client->hello_timer = NULL;
487 /* Set retry timer callback */
488 client->prepare_count = 0;
489 client->hello_timer = ecore_timer_add(0.5, __prepare_cb, data);
495 static int __prepare_sync_cb(tts_client_s* client)
497 // TODO: make function duplicated block
498 bool is_launched = __is_engine_launched();
499 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
501 if (false == is_launched) {
502 /* check whether engine is updating or not */
503 if (g_engine_update_status) {
504 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Cannot prepare due to engine update.");
505 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client automatically tries to reprepare asynchrnously.");
506 __run_client_reprepare_thread();
507 return TTS_ERROR_OPERATION_FAILED;
511 // TODO: make function duplicated block
512 unsigned int uid = tts_client_get_uid(client);
513 if (TTS_ERROR_NONE != tts_ipc_request_hello_sync(uid)) {
514 return TTS_ERROR_FAIL_TO_SEND_HELLO;
517 SLOG(LOG_INFO, TAG_TTSC, "@@@ Connect daemon");
519 // TODO: make function duplicated block
520 /* do request initialize */
521 bool credential_needed = false;
522 tts_mode_e mode = tts_client_get_mode(client);
523 int registered_callback_mask = tts_client_get_registered_event_mask(client);
524 int ret = tts_ipc_request_initialize(uid, mode, registered_callback_mask, &credential_needed);
525 if (TTS_ERROR_ENGINE_NOT_FOUND == ret || TTS_ERROR_PERMISSION_DENIED == ret) {
526 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize. ret(%d/%s)", ret, get_error_message(ret));
527 tts_core_notify_error_async(client, ret, -1, NULL);
530 } else if (TTS_ERROR_NONE != ret) {
531 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect. ret(%d/%s)", ret, get_error_message(ret));
532 return TTS_ERROR_FAIL_TO_SEND_HELLO;
534 /* success to connect tts-daemon */
535 client->credential_needed = credential_needed;
536 SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%s)", credential_needed ? "need" : "no need");
538 // TODO: make function duplicated block
540 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
541 return TTS_ERROR_NONE;
544 static void __engine_changed_cb(keynode_t* key, void* data)
546 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine vconfkey is changed");
547 if (0 != __update_engine_name()) {
548 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
554 static bool __supported_voice_cb(const char* engine_id, const char* language, int type, void* user_data)
556 unsigned int uid = (uintptr_t)user_data;
557 tts_client_s* client = tts_client_get_by_uid(uid);
558 RETVM_IF(NULL == client, false, "[ERROR] uid(%u) is not valid.", uid);
560 /* call callback function */
561 tts_supported_voice_cb callback = tts_client_get_supported_voice_cb(client);
562 void* data = tts_client_get_supported_voice_user_data(client);
564 if (NULL == callback) {
565 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get callback.");
569 return callback(tts_client_get_handle(client), language, type, data);
572 static bool __is_screen_reader_turned_on()
574 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Update screen reader state");
576 int screen_reader = 0;
577 int ret = vconf_get_bool(TTS_ACCESSIBILITY_KEY, &screen_reader);
579 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
583 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Current screen reader status(%d)", screen_reader);
584 return (bool)screen_reader;
587 static inline bool __is_ipc_retry_needed(tts_client_s* client, tts_error_e ret)
589 if (TTS_ERROR_NONE == ret) {
590 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success the IPC request");
594 if (TTS_ERROR_TIMED_OUT == ret) {
595 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] IPC is failed. Try again. ret(%d/%s)", ret, get_error_message(ret));
600 if (tts_client_is_reprepared(client)) {
601 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Prepare was already tried.");
602 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] IPC request is failed. ret(%d/%s)", ret, get_error_message(ret));
606 if (TTS_ERROR_INVALID_PARAMETER == ret || TTS_ERROR_IO_ERROR == ret) {
607 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] IPC is failed by unregistered client or network error. ret(%d/%s)", ret, get_error_message(ret));
608 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Try to prepare again");
609 tts_client_set_current_state(client, TTS_STATE_CREATED);
610 tts_core_prepare_sync(client);
611 tts_client_set_reprepared(client, true);
615 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] IPC request is failed. ret(%d/%s)", ret, get_error_message(ret));
619 static inline int __request_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id)
621 /* change default language value */
622 const char* convert_language = (NULL == language ? "default" : language);
623 int new_utt_id = tts_client_new_utterance_id(client);
624 if (0 > new_utt_id) {
625 return TTS_ERROR_OPERATION_FAILED;
628 // TODO: If use cpp, remove dupliceated code using command class pattern
629 unsigned int uid = tts_client_get_uid(client);
631 tts_client_set_reprepared(client, false);
632 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
633 ret = tts_ipc_request_add_text(uid, text, convert_language, voice_type, speed, new_utt_id, client->credential);
634 if (false == __is_ipc_retry_needed(client, ret)) {
639 if (TTS_ERROR_NONE != ret) {
640 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
644 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_add_text");
645 *utt_id = new_utt_id;
646 return TTS_ERROR_NONE;
649 static inline int __request_play(tts_client_s* client)
651 unsigned int uid = tts_client_get_uid(client);
653 tts_client_set_reprepared(client, false);
654 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
655 ret = tts_ipc_request_play(uid, client->credential);
656 if (false == __is_ipc_retry_needed(client, ret)) {
661 if (TTS_ERROR_NONE != ret) {
662 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request. ret(%d)", ret);
666 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Success tts_dbus_request_play");
667 return tts_core_notify_state_changed(client, TTS_STATE_PLAYING);
670 int tts_core_initialize()
672 ecore_main_loop_thread_safe_call_async(__pkgmgr_thread, NULL);
674 if (0 != __update_engine_name()) {
675 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
677 g_is_engine_name_changed = false;
679 /* Register vconfkey callback to detect engine change */
680 vconf_notify_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb, NULL);
682 return TTS_ERROR_NONE;
685 int tts_core_deinitialize()
687 if (NULL != g_reprepare_thread && EINA_FALSE == ecore_thread_check(g_reprepare_thread)) {
688 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Cancel reprepare thread");
689 ecore_thread_cancel(g_reprepare_thread);
690 ecore_thread_wait(g_reprepare_thread, 0.5); // wait g_reprepare_thread is terminated.
693 if (NULL != g_pkgmgr_thread) {
694 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Cancel pkgmgr thread");
695 g_is_thread_canceled = true;
698 if (NULL != g_language) {
703 if (NULL != g_engine_name) {
705 g_engine_name = NULL;
708 pthread_mutex_lock(&g_pkgmgr_mutex);
709 if (NULL != g_pkgmgr) {
710 pkgmgr_client_remove_listen_status(g_pkgmgr);
711 pkgmgr_client_free(g_pkgmgr);
715 if (NULL != g_pkgmgr_status) {
716 free(g_pkgmgr_status);
717 g_pkgmgr_status = NULL;
719 pthread_mutex_unlock(&g_pkgmgr_mutex);
721 /* Unregister vconfkey callback */
722 vconf_ignore_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb);
724 return TTS_ERROR_NONE;
727 int tts_core_notify_state_changed(tts_client_s* client, tts_state_e current_state)
729 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
731 tts_state_e before_state = tts_client_get_current_state(client);
732 if (before_state == current_state) {
733 SLOG(LOG_INFO, TAG_TTSC, "[INFO] State is not changed. before(%s), current(%s)", __convert_state(before_state), __convert_state(current_state));
734 return TTS_ERROR_NONE;
737 SLOG(LOG_DEBUG, TAG_TTSC, "State changed to (%s).", __convert_state(current_state));
738 tts_client_set_current_state(client, current_state);
739 __client_state_changed_cb(client, before_state, current_state);
741 return TTS_ERROR_NONE;
744 int tts_core_notify_utt_started(tts_client_s* client, int utt_id)
746 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
748 client->utt_id = utt_id;
749 SLOG(LOG_DEBUG, TAG_TTSC, "Utterance started data : utt_id(%d)", client->utt_id);
751 tts_utterance_started_cb callback = tts_client_get_utterance_started_cb(client);
752 void* data = tts_client_get_utterance_started_user_data(client);
754 if (NULL != callback) {
755 SLOG(LOG_DEBUG, TAG_TTSC, "Notify utterance started");
756 tts_client_use_callback(client);
757 callback(tts_client_get_handle(client), client->utt_id, data);
758 tts_client_not_use_callback(client);
760 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(utt_started)");
763 return TTS_ERROR_NONE;
766 int tts_core_notify_utt_completeted(tts_client_s* client, int utt_id)
768 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
770 client->utt_id = utt_id;
771 SLOG(LOG_DEBUG, TAG_TTSC, "Utterance completed data : utt_id(%d)", utt_id);
773 tts_utterance_completed_cb callback = tts_client_get_utterance_completed_cb(client);
774 void* data = tts_client_get_utterance_completed_user_data(client);
776 if (NULL != callback) {
777 SLOG(LOG_DEBUG, TAG_TTSC, "Notify utterance started");
778 tts_client_use_callback(client);
779 callback(tts_client_get_handle(client), utt_id, data);
780 tts_client_not_use_callback(client);
782 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(utt_completed)");
785 return TTS_ERROR_NONE;
788 int tts_core_notify_error_async(tts_client_s* client, tts_error_e reason, int utt_id, const char* err_msg)
790 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
792 SLOG(LOG_DEBUG, TAG_TTSC, "Error data : utt_id(%d) reason(%s)", utt_id, tts_core_covert_error_code(reason));
793 client->utt_id = utt_id;
794 client->reason = reason;
795 tts_client_set_error_message(client, err_msg);
797 SLOG(LOG_DEBUG, TAG_TTSC, "Notify error asynchronously");
798 if (NULL != client->notify_error_timer) {
799 ecore_timer_del(client->notify_error_timer);
802 uintptr_t uid = tts_client_get_uid(client);
803 client->notify_error_timer = ecore_timer_add(0, __notify_error_timer_cb, (void*)uid);
805 return TTS_ERROR_NONE;
809 int tts_core_notify_default_voice_changed(tts_client_s* client, const char* before_lang, int before_voice_type, const char* language, int voice_type)
811 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
813 SLOG(LOG_DEBUG, TAG_TTSC, "Default voice changed data : before_lang(%s), before_voice_type(%d), language(%s), voice_type(%d)",
814 before_lang, before_voice_type, language, voice_type);
816 tts_default_voice_changed_cb callback = tts_client_get_default_voice_changed_cb(client);
817 void* data = tts_client_get_default_voice_changed_user_data(client);
819 if (NULL != callback) {
820 SLOG(LOG_DEBUG, TAG_TTSC, "Notify default voice changed");
821 tts_client_use_callback(client);
822 callback(tts_client_get_handle(client), before_lang, before_voice_type, language, voice_type, data);
823 tts_client_not_use_callback(client);
825 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(default_voice_changed)");
828 return TTS_ERROR_NONE;
831 int tts_core_notify_engine_changed(tts_client_s* client, const char* engine_id, const char* language, int voice_type, bool need_credential)
833 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
835 SLOG(LOG_DEBUG, TAG_TTSC, "Engine changed data : engine_id(%s) language(%s), voicd_type(%d), need_credential(%d)",
836 engine_id, language, voice_type, need_credential);
838 tts_engine_changed_cb callback = tts_client_get_engine_changed_cb(client);
839 void* data = tts_client_get_engine_changed_user_data(client);
841 if (NULL != callback) {
842 SLOG(LOG_DEBUG, TAG_TTSC, "Notify engine changed");
843 tts_client_use_callback(client);
844 callback(tts_client_get_handle(client), engine_id, language, voice_type, need_credential, data);
845 tts_client_not_use_callback(client);
847 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(engine_changed)");
850 return TTS_ERROR_NONE;
854 int tts_core_notify_screen_reader_changed(tts_client_s* client, bool value)
856 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
858 SLOG(LOG_DEBUG, TAG_TTSC, "Screen reader is changed. Current status(%d)", value);
860 tts_screen_reader_changed_cb callback = tts_client_get_screen_reader_changed_cb(client);
861 void* data = tts_client_get_screen_reader_changed_user_data(client);
863 if (NULL != callback) {
864 SLOG(LOG_DEBUG, TAG_TTSC, "Notify screen reader changed");
865 tts_client_use_callback(client);
866 callback(tts_client_get_handle(client), value, data);
867 tts_client_not_use_callback(client);
869 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(screen_reader_changed)");
872 return TTS_ERROR_NONE;
875 int tts_core_notify_service_state_changed(tts_client_s* client, tts_service_state_e before_state, tts_service_state_e current_state)
877 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
879 SLOG(LOG_DEBUG, TAG_TTSC, "Service state changed from (%d) to (%d).", before_state, current_state);
881 tts_service_state_changed_cb callback = tts_client_get_service_state_changed_cb(client);
882 void* data = tts_client_get_service_state_changed_user_data(client);
884 if (NULL != callback) {
885 SLOG(LOG_DEBUG, TAG_TTSC, "Notify service state changed");
886 tts_client_use_callback(client);
887 callback(tts_client_get_handle(client), before_state, current_state, data);
888 tts_client_not_use_callback(client);
890 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(service_state_changed)");
893 return TTS_ERROR_NONE;
896 bool tts_core_is_valid_text(const char* text)
902 /* check valid utf8 */
904 dbus_error_init(&err);
905 bool valid = dbus_validate_utf8(text, &err);
906 if (dbus_error_is_set(&err)) {
907 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Dbus Error(%s), text(%s)", err.message, text);
908 dbus_error_free(&err);
912 if (false == valid) {
913 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Text is invalid - '%s'", text);
917 if (strlen(text) <= 0) {
918 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is invalid.");
922 unsigned int max_text_size = 0;
923 /* check text size */
924 if (0 != tts_config_mgr_get_max_text_size(&max_text_size)) {
925 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get max text size");
929 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] max_text_size is %d byte", max_text_size);
930 if (0 < max_text_size && max_text_size < strlen(text)) {
931 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is bigger than maximum test size. text_size(%zu byte)", strlen(text));
938 bool tts_core_check_screen_reader(tts_client_s* client)
940 RETVM_IF(false == tts_client_is_valid_client(client), false, "[ERROR] Client is invalid.");
942 tts_mode_e mode = tts_client_get_mode(client);
943 if (TTS_MODE_SCREEN_READER == mode && false == __is_screen_reader_turned_on()) {
950 bool tts_core_check_credential(tts_client_s* client)
952 RETVM_IF(false == tts_client_is_valid_client(client), false, "[ERROR] Client is invalid.");
954 if (true == client->credential_needed && NULL == tts_client_get_credential_key(client)) {
955 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Do not have app credential for this engine");
963 const char* tts_core_covert_error_code(tts_error_e err)
966 case TTS_ERROR_NONE: return "TTS_ERROR_NONE";
967 case TTS_ERROR_OUT_OF_MEMORY: return "TTS_ERROR_OUT_OF_MEMORY";
968 case TTS_ERROR_IO_ERROR: return "TTS_ERROR_IO_ERROR";
969 case TTS_ERROR_INVALID_PARAMETER: return "TTS_ERROR_INVALID_PARAMETER";
970 case TTS_ERROR_OUT_OF_NETWORK: return "TTS_ERROR_OUT_OF_NETWORK";
971 case TTS_ERROR_TIMED_OUT: return "TTS_ERROR_TIMED_OUT";
972 case TTS_ERROR_PERMISSION_DENIED: return "TTS_ERROR_PERMISSION_DENIED";
973 case TTS_ERROR_NOT_SUPPORTED: return "TTS_ERROR_NOT_SUPPORTED";
974 case TTS_ERROR_INVALID_STATE: return "TTS_ERROR_INVALID_STATE";
975 case TTS_ERROR_INVALID_VOICE: return "TTS_ERROR_INVALID_VOICE";
976 case TTS_ERROR_ENGINE_NOT_FOUND: return "TTS_ERROR_ENGINE_NOT_FOUND";
977 case TTS_ERROR_OPERATION_FAILED: return "TTS_ERROR_OPERATION_FAILED";
978 case TTS_ERROR_AUDIO_POLICY_BLOCKED: return "TTS_ERROR_AUDIO_POLICY_BLOCKED";
979 case TTS_ERROR_NOT_SUPPORTED_FEATURE: return "TTS_ERROR_NOT_SUPPORTED_FEATURE";
980 case TTS_ERROR_SERVICE_RESET: return "TTS_ERROR_SERVICE_RESET";
981 case TTS_ERROR_SCREEN_READER_OFF: return "TTS_ERROR_SCREEN_READER_OFF";
983 return "Invalid error code";
989 int tts_core_receive_hello(unsigned int uid, int ret, int credential_needed)
991 tts_client_s* client = tts_client_get_by_uid(uid);
992 RETVM_IF(NULL == client, TTS_ERROR_OPERATION_FAILED, "Fail to get TTS client or ignore this uid(%u)", uid);
994 tts_state_e current_state = tts_client_get_current_state(client);
995 RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_NONE, "[INFO] tts client is already READY");
997 if (client->hello_timer) {
998 ecore_timer_del(client->hello_timer);
999 client->hello_timer = NULL;
1002 if (TTS_ERROR_ENGINE_NOT_FOUND == ret || TTS_ERROR_PERMISSION_DENIED == ret) {
1003 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", tts_core_covert_error_code(ret));
1004 tts_core_notify_error_async(client, ret, -1, NULL);
1006 return TTS_ERROR_OPERATION_FAILED;
1007 } else if (TTS_ERROR_ALREADY_INITIALIZED == ret) {
1008 /* success to connect tts-daemon */
1009 if (TTS_CREDENTIAL_NEEDED_ALREADY_INITIALIZED != credential_needed) {
1010 client->credential_needed = credential_needed;
1011 SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%d)", credential_needed);
1013 } else if (TTS_ERROR_NONE != ret) {
1014 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect : %s", tts_core_covert_error_code(ret));
1015 return TTS_ERROR_OPERATION_FAILED;
1018 tts_core_notify_state_changed(client, TTS_STATE_READY);
1020 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1021 return TTS_ERROR_NONE;
1024 int tts_core_prepare(tts_client_s* client)
1026 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1028 if (false == tts_core_check_screen_reader(client)) {
1029 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is not available");
1030 return TTS_ERROR_SCREEN_READER_OFF;
1033 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Start core_prepare. tts_h(%p), tts_client(%p)", tts_client_get_handle(client), client);
1034 if (NULL == client->hello_timer) {
1035 SLOG(LOG_ERROR, TAG_TTSC, "Register timer for __prepare_first_cb");
1037 ecore_thread_main_loop_begin();
1038 uintptr_t uid = tts_client_get_uid(client);
1039 client->hello_timer = ecore_timer_add(0.0, __prepare_first_cb, (void*)uid);
1040 ecore_thread_main_loop_end();
1042 LOGD("Client is already trying to prepare");
1045 return TTS_ERROR_NONE;
1048 int tts_core_prepare_sync(tts_client_s* client)
1050 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1052 unsigned int uid = tts_client_get_uid(client);
1053 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Start core_prepare_sync. tts_h(%p), tts_client(%p), uid(%u)", tts_client_get_handle(client), client, uid);
1055 while (TTS_CONNECTION_RETRY_COUNT > cnt) {
1056 if (false == tts_core_check_screen_reader(client)) {
1057 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is not available");
1058 return TTS_ERROR_SCREEN_READER_OFF;
1061 int ret = __prepare_sync_cb(client);
1062 if (TTS_ERROR_NONE == ret) {
1063 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Prepare succeeds. uid(%u)", uid);
1067 if (TTS_ERROR_FAIL_TO_SEND_HELLO == ret) {
1068 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Fail to send hello. Try again. uid(%u)", uid);
1070 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare. uid(%u), ret(%d/%s)", uid, ret, get_error_message(ret));
1077 if (TTS_CONNECTION_RETRY_COUNT == cnt) {
1078 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connect daemon");
1079 return TTS_ERROR_OPERATION_FAILED;
1082 tts_core_notify_state_changed(client, TTS_STATE_READY);
1084 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1085 return TTS_ERROR_NONE;
1088 int tts_core_unprepare(tts_client_s* client)
1090 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1092 unsigned int uid = tts_client_get_uid(client);
1093 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%u)", tts_client_get_handle(client), client, uid);
1094 if (client->hello_timer) {
1095 ecore_timer_del(client->hello_timer);
1096 client->hello_timer = NULL;
1100 if (false == tts_core_check_screen_reader(client)) {
1101 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Do not request finalize. Handled by screen reader");
1103 ret = tts_ipc_stop_listening(uid);
1105 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to remove match : %s", tts_core_covert_error_code(ret));
1108 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Request finalize");
1110 tts_client_set_reprepared(client, false);
1111 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1112 ret = tts_ipc_request_finalize(uid);
1113 if (false == __is_ipc_retry_needed(client, ret)) {
1118 if (TTS_ERROR_NONE == ret) {
1119 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_finalize");
1123 return TTS_ERROR_NONE;
1126 int tts_core_reprepare()
1128 GList* clients = tts_client_get_client_list();
1129 RETVM_IF(NULL == clients, TTS_ERROR_OPERATION_FAILED, "[ERROR] Fail to get client list");
1132 if (g_list_length(clients) > 0) {
1133 iter = g_list_first(clients);
1135 while (NULL != iter) {
1136 tts_client_s* client = iter->data;
1137 if (true == tts_client_is_valid_client(client)) {
1138 tts_client_set_current_state(client, TTS_STATE_CREATED);
1141 iter = g_list_next(iter);
1145 g_list_free(clients);
1146 __run_client_reprepare_thread();
1148 return TTS_ERROR_NONE;
1151 int tts_core_foreach_supported_voices(tts_client_s* client, const char* engine_id, tts_supported_voice_cb callback, void* user_data)
1153 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1155 tts_client_set_supported_voice_cb(client, callback, user_data);
1156 uintptr_t uid = tts_client_get_uid(client);
1157 int ret = tts_config_mgr_get_voice_list(engine_id, __supported_voice_cb, (void*)uid);
1158 tts_client_set_supported_voice_cb(client, NULL, NULL);
1161 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get voice list");
1162 return TTS_ERROR_OPERATION_FAILED;
1165 return TTS_ERROR_NONE;
1168 int tts_core_handle_service_reset()
1170 GList* client_list = tts_client_get_client_list();
1171 RETVM_IF(NULL == client_list, TTS_ERROR_OPERATION_FAILED, "[ERROR] Fail to get client list");
1173 if (g_list_length(client_list) > 0) {
1174 GList *iter = g_list_first(client_list);
1175 while (NULL != iter) {
1176 tts_client_s *client = iter->data;
1177 if (false == tts_client_is_valid_client(client)) {
1178 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid");
1180 tts_core_notify_error_async(client, TTS_ERROR_SERVICE_RESET, -1, "Daemon Reset");
1183 iter = g_list_next(iter);
1187 g_list_free(client_list);
1189 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset");
1190 tts_core_reprepare();
1192 return TTS_ERROR_NONE;
1195 int tts_core_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id)
1197 RETVM_IF(NULL == text || NULL == utt_id, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Parameter is invalid.");
1198 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1200 tts_client_set_repeat_text(client, text);
1202 if (NULL != g_language) {
1206 g_language = (NULL == language ? NULL : strdup(language));
1207 g_voice_type = voice_type;
1210 SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] text(%s), language(%s), voice type(%d), speed(%d)", text, (g_language) ? g_language : "NULL", g_voice_type, g_speed);
1211 return __request_add_text(client, text, language, voice_type, speed, utt_id);
1214 int tts_core_play(tts_client_s* client)
1216 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1218 return __request_play(client);
1221 int tts_core_stop(tts_client_s* client)
1223 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1225 unsigned int uid = tts_client_get_uid(client);
1227 tts_client_set_reprepared(client, false);
1228 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1229 ret = tts_ipc_request_stop(uid);
1230 if (false == __is_ipc_retry_needed(client, ret)) {
1235 if (TTS_ERROR_NONE != ret) {
1236 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1240 return tts_core_notify_state_changed(client, TTS_STATE_READY);
1243 int tts_core_pause(tts_client_s* client)
1245 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1247 unsigned int uid = tts_client_get_uid(client);
1249 tts_client_set_reprepared(client, false);
1250 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1251 ret = tts_ipc_request_pause(uid);
1252 if (false == __is_ipc_retry_needed(client, ret)) {
1257 if (TTS_ERROR_NONE != ret) {
1258 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1262 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_pause");
1263 return tts_core_notify_state_changed(client, TTS_STATE_PAUSED);
1266 int tts_core_repeat(tts_client_s* client, char** text_repeat, int* utt_id)
1268 RETVM_IF(NULL == text_repeat || NULL == utt_id, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Parameter is invalid.");
1269 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1271 char* repeat_text = tts_client_get_repeat_text(client);
1272 if (NULL == repeat_text) {
1273 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] There is no previous added texts. Please add texts");
1274 return TTS_ERROR_OPERATION_FAILED;
1277 int new_utt_id = -1;
1278 int ret = __request_add_text(client, repeat_text, g_language, g_voice_type, g_speed, &new_utt_id);
1279 if (TTS_ERROR_NONE != ret) {
1280 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to add texts for repetition.");
1285 /* Play added texts */
1286 ret = __request_play(client);
1287 if (TTS_ERROR_NONE != ret) {
1288 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to play texts for repetition.");
1293 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] text to repeat(%s), utt_id(%d)", repeat_text, new_utt_id);
1295 *utt_id = new_utt_id;
1296 *text_repeat = repeat_text;
1297 return TTS_ERROR_NONE;
1300 int tts_core_add_pcm(tts_client_s* client, int event, const void* data, unsigned int data_size, int audio_type, int rate)
1302 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1304 unsigned int uid = tts_client_get_uid(client);
1306 tts_client_set_reprepared(client, false);
1307 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1308 ret = tts_ipc_request_add_pcm(uid, event, data, data_size, audio_type, rate);
1309 if (false == __is_ipc_retry_needed(client, ret)) {
1314 if (TTS_ERROR_NONE != ret) {
1315 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1319 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_add_pcm");
1320 return TTS_ERROR_NONE;
1323 int tts_core_play_pcm(tts_client_s* client)
1325 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1327 unsigned int uid = tts_client_get_uid(client);
1329 tts_client_set_reprepared(client, false);
1330 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1331 ret = tts_ipc_request_play_pcm(uid);
1332 if (false == __is_ipc_retry_needed(client, ret)) {
1337 if (TTS_ERROR_NONE != ret) {
1338 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1342 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_play_pcm");
1343 return tts_core_notify_state_changed(client, TTS_STATE_PLAYING);
1346 int tts_core_stop_pcm(tts_client_s* client)
1348 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1350 unsigned int uid = tts_client_get_uid(client);
1352 tts_client_set_reprepared(client, false);
1353 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1354 ret = tts_ipc_request_stop_pcm(uid);
1355 if (false == __is_ipc_retry_needed(client, ret)) {
1360 if (TTS_ERROR_NONE != ret) {
1361 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1365 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_stop_pcm");
1366 return tts_core_notify_state_changed(client, TTS_STATE_READY);
1369 int tts_core_set_private_data(tts_client_s* client, const char* key, const char* data)
1371 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1373 unsigned int uid = tts_client_get_uid(client);
1375 tts_client_set_reprepared(client, false);
1376 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1377 ret = tts_ipc_request_set_private_data(uid, key, data);
1378 if (false == __is_ipc_retry_needed(client, ret)) {
1383 if (TTS_ERROR_NONE != ret) {
1384 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1388 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_set_private_data");
1389 return TTS_ERROR_NONE;
1392 int tts_core_get_private_data(tts_client_s* client, const char* key, char** data)
1394 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1396 unsigned int uid = tts_client_get_uid(client);
1398 tts_client_set_reprepared(client, false);
1399 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1400 ret = tts_ipc_request_get_private_data(uid, key, data);
1401 if (false == __is_ipc_retry_needed(client, ret)) {
1406 if (TTS_ERROR_NONE != ret) {
1407 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1411 if (0 == strncmp(*data, "NULL", strlen(*data))) {
1416 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_get_private_data");
1417 return TTS_ERROR_NONE;
1420 int tts_core_get_service_state(tts_client_s* client, tts_service_state_e* service_state)
1422 RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1424 unsigned int uid = tts_client_get_uid(client);
1426 tts_client_set_reprepared(client, false);
1427 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1428 ret = tts_ipc_request_get_service_state(uid, service_state);
1429 if (false == __is_ipc_retry_needed(client, ret)) {
1434 if (TTS_ERROR_NONE != ret) {
1435 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1439 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_core_get_service_state");
1440 return TTS_ERROR_NONE;