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.
16 #include <app_manager.h>
18 #include <package-manager.h>
20 #include "tts_internal.h"
25 /* Static variables */
26 static volatile bool g_is_thread_canceled = false;
28 static char* g_engine_name = NULL;
29 static int g_engine_update_status = 0;
31 static Ecore_Thread* g_reprepare_thread = NULL;
33 static char* g_pkgmgr_status = NULL;
34 static pkgmgr_client* g_pkgmgr = NULL;
35 static Ecore_Thread* g_pkgmgr_thread = NULL;
36 static pthread_mutex_t g_pkgmgr_mutex = PTHREAD_MUTEX_INITIALIZER;
38 static char* g_language = NULL;
39 static int g_voice_type = -1;
40 static int g_speed = -1;
43 /* Static functions */
44 // TODO: make tts_util? or tts_log?
45 static const char* __convert_state(tts_state_e state)
48 case TTS_STATE_CREATED: return "Created";
49 case TTS_STATE_READY: return "Ready";
50 case TTS_STATE_PLAYING: return "Playing";
51 case TTS_STATE_PAUSED: return "Paused";
54 return "Invalid state";
57 static char* __get_engine_appid(int mode) {
58 if (NULL == g_engine_name) {
62 char* appid = (char*)calloc(256, sizeof(char));
67 if (TTS_MODE_DEFAULT <= mode && TTS_MODE_SCREEN_READER >= mode) {
68 snprintf(appid, 256, "%s", g_engine_name);
69 // } else if (TTS_MODE_NOTIFICATION == mode) {
70 // snprintf(appid, 256, "%s-noti", g_engine_name);
71 // } else if (TTS_MODE_SCREEN_READER == mode) {
72 // snprintf(appid, 256, "%s-sr", g_engine_name);
73 } else if (TTS_MODE_INTERRUPT == mode) {
74 snprintf(appid, 256, "%s-interrupt", g_engine_name);
76 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] mode is not valid. mode(%d)", mode);
84 static int __update_engine_name()
91 g_engine_name = vconf_get_str(TTS_ENGINE_DB_DEFAULT);
92 if (NULL == g_engine_name) {
93 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine name");
94 return TTS_ERROR_OPERATION_FAILED;
97 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Engine name(%s)", g_engine_name);
98 return TTS_ERROR_NONE;
101 static inline void __client_error_cb(tts_client_s* client, int utt_id, tts_error_e reason)
103 tts_error_cb callback = tts_client_get_error_cb(client);
104 void* data = tts_client_get_error_user_data(client);
106 if (NULL != callback) {
107 SLOG(LOG_DEBUG, TAG_TTSC, "Notify error");
108 tts_client_use_callback(client);
109 callback(tts_client_get_handle(client), utt_id, reason, data);
110 tts_client_not_use_callback(client);
112 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(error)");
116 static inline void __client_state_changed_cb(tts_client_s* client, tts_state_e before_state, tts_state_e current_state)
118 tts_state_changed_cb callback = tts_client_get_state_changed_cb(client);
119 void* data = tts_client_get_state_changed_user_data(client);
121 if (NULL != callback) {
122 SLOG(LOG_DEBUG, TAG_TTSC, "State changed data : before_state(%s) curret_state(%s)", __convert_state(before_state), __convert_state(current_state));
123 tts_client_use_callback(client);
124 callback(tts_client_get_handle(client), before_state, current_state, data);
125 tts_client_not_use_callback(client);
127 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(state_changed)");
131 static Eina_Bool __notify_error_timer_cb(void *data)
133 unsigned int uid = (uintptr_t)data;
134 tts_client_s* client = tts_client_get_by_uid(uid);
135 if (NULL == client) {
136 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] UID is not valid. (%u)", uid);
138 __client_error_cb(client, client->utt_id, client->reason);
139 client->notify_error_timer = NULL;
145 static Eina_Bool __notify_state_timer_cb(void *data)
147 unsigned int uid = (uintptr_t)data;
148 tts_client_s* client = tts_client_get_by_uid(uid);
149 if (NULL == client) {
150 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] UID is not valid. (%u)", uid);
152 __client_state_changed_cb(client, client->before_state, client->current_state);
153 client->notify_state_timer = NULL;
159 static bool __is_engine_installed(const char* appid)
161 app_info_h app_info = NULL;
162 int ret = app_manager_get_app_info(appid, &app_info);
163 if (APP_MANAGER_ERROR_NONE != ret || NULL == app_info) {
164 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] There is no tts engine (%s). ret(%d)", appid, ret);
167 SLOG(LOG_INFO, TAG_TTSC, "[INFO] There is tts engine (%s)", appid);
170 ret = app_info_destroy(app_info);
171 if (APP_MANAGER_ERROR_NONE != ret)
172 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to destroy app_info. ret(%d)", ret);
177 static bool __is_engine_launched(tts_mode_e mode)
179 char* appid = __get_engine_appid(mode);
181 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine app ID");
185 bool is_installed = __is_engine_installed(appid);
186 if (false == is_installed) {
187 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] tts engine(%s) is not installed", appid);
192 bool is_running = false;
193 int ret = app_manager_is_running(appid, &is_running);
194 if (APP_MANAGER_ERROR_NONE != ret) {
195 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to check whether appid(%s) is running or not. ret(%d)", appid, ret);
196 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is installed(%d)", is_installed);
202 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is %s running. is_installed(%d)", (is_running) ? "" : " not", is_installed);
206 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)
208 // type (the type of the pkgname)
209 SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status cb is invoked. pkgname(%s), type(%s), key(%s), val(%s)", pkgname, type, key, val);
211 if (NULL == g_engine_name) {
212 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] engine name is NULL");
216 if (0 != strncmp(g_engine_name, pkgname, strlen(g_engine_name))) {
217 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] this is not tts engine");
222 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] key is NULL");
226 if (0 == strncmp(key, "start", strlen(key))) {
227 if (NULL != g_pkgmgr_status) {
228 free(g_pkgmgr_status);
229 g_pkgmgr_status = NULL;
233 g_pkgmgr_status = strdup(val);
234 SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status. key(%s), status(%s)", key, g_pkgmgr_status);
236 if ((0 == strncmp(val, "update", strlen(val) || 0 == strncmp(val, "uninstall", strlen(val))))) {
237 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] start to install.");
238 g_engine_update_status = 1;
241 } else if (0 == strncmp(key, "end", strlen(key)) && val && 0 == strncmp(val, "ok", strlen(val))) {
242 if (g_pkgmgr_status) {
243 if (0 == strncmp(g_pkgmgr_status, "install", strlen(g_pkgmgr_status)) || 0 == strncmp(g_pkgmgr_status, "update", strlen(g_pkgmgr_status))) {
244 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] finish to install");
245 g_engine_update_status = 0;
247 free(g_pkgmgr_status);
248 g_pkgmgr_status = NULL;
256 static void __create_pkgmgr_thread(void* data, Ecore_Thread* thread)
258 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] create pkgmgr thread");
260 pthread_mutex_lock(&g_pkgmgr_mutex);
261 while (NULL == g_pkgmgr) {
262 /* Checking the thread is canceled or not */
263 if (g_is_thread_canceled) {
264 SLOG(LOG_INFO, TAG_TTSC, "[INFO] g_pkgmgr_thread is canceled. Exit");
268 /* Checking handle which can be destroyed on other thread */
269 if (0 == tts_client_get_size()) {
270 SLOG(LOG_INFO, TAG_TTSC, "[INFO] All client is already destroyed");
274 g_pkgmgr = pkgmgr_client_new(PC_LISTENING);
275 if (NULL == g_pkgmgr) {
276 // SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create pkgmgr handle");
278 int ret = pkgmgr_client_set_status_type(g_pkgmgr, PKGMGR_CLIENT_STATUS_INSTALL | PKGMGR_CLIENT_STATUS_UNINSTALL | PKGMGR_CLIENT_STATUS_UPGRADE);
280 if (pkgmgr_client_listen_status(g_pkgmgr, __pkgmgr_status_cb, NULL) < 0) {
281 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to listen pkgmgr status. remove and recreate client");
282 pkgmgr_client_free(g_pkgmgr);
285 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Succeed to register pkgmgr cb");
289 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set status type on pkgmgr, ret(%d)", ret);
290 pkgmgr_client_free(g_pkgmgr);
297 pthread_mutex_unlock(&g_pkgmgr_mutex);
299 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] create pkgmgr end");
302 static void __finish_pkgmgr_thread(void* data, Ecore_Thread* thread)
304 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] Finish pkgmgr thread");
305 g_is_thread_canceled = false;
306 g_pkgmgr_thread = NULL;
309 static void __cancel_pkgmgr_thread(void* data, Ecore_Thread* thread)
311 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] Cancel pkgmgr thread");
312 g_is_thread_canceled = false;
313 g_pkgmgr_thread = NULL;
316 static void __pkgmgr_thread(void* data)
318 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] call pkgmgr_thread");
319 if (NULL == g_pkgmgr_thread) {
320 SLOG(LOG_INFO, TAG_TTSC, "[INFO] ecore thread run: create_pkgmgr_thread");
321 g_pkgmgr_thread = ecore_thread_run(__create_pkgmgr_thread, __finish_pkgmgr_thread, __cancel_pkgmgr_thread, NULL);
327 static void __start_reprepare_thread(void* data, Ecore_Thread* thread)
329 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] start reprepare thread. engine update status(%d)", g_engine_update_status);
332 while (!g_engine_update_status && cnt < 20) {
333 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] wait for starting update");
338 // TODO: fix way to exit thread safely
339 /* Checking thread is canceled or not */
340 if (ecore_thread_check(g_reprepare_thread)) {
341 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] client thread is canceled. Exit");
346 SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] update status(%d)", g_engine_update_status);
348 while (g_engine_update_status && (NULL != g_pkgmgr)) {
351 // TODO: fix way to exit thread safely
352 /* Checking thread is canceled or not */
353 if (ecore_thread_check(g_reprepare_thread)) {
354 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] client thread is canceled. Exit");
359 SLOG(LOG_INFO, TAG_TTSC, "[INFO] finish updating. request to prepare");
364 static void __end_reprepare_thread(void* data, Ecore_Thread* thread)
366 SLOG(LOG_INFO, TAG_TTSC, "[INFO] end reprepare thread");
368 GList* clients = tts_client_get_client_list();
369 if (NULL == clients) {
370 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get client list");
375 if (g_list_length(clients) > 0) {
376 iter = g_list_first(clients);
378 while (NULL != iter) {
379 tts_client_s* client = iter->data;
380 if (NULL != client) {
381 tts_core_prepare(client);
384 iter = g_list_next(iter);
388 g_list_free(clients);
389 g_reprepare_thread = NULL;
392 static void __cancel_reprepare_thread(void* data, Ecore_Thread* thread)
394 SLOG(LOG_INFO, TAG_TTSC, "[INFO] cancel reprepare thread");
395 g_reprepare_thread = NULL;
398 static inline void __run_client_reprepare_thread()
400 if (NULL == g_reprepare_thread) {
401 SLOG(LOG_INFO, TAG_TTSC, "[INFO] ecore thread run: start_reprepare_thread");
402 g_reprepare_thread = ecore_thread_run(__start_reprepare_thread, __end_reprepare_thread, __cancel_reprepare_thread, NULL);
404 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Reprepare thread is already running");
408 static int __send_hello_msg(tts_client_s* client)
410 tts_state_e current_state = tts_client_get_current_state(client);
411 if (TTS_STATE_READY == current_state) {
412 SLOG(LOG_INFO, TAG_TTSC, "[INFO] TTS client has been already connected to tts service"); //LCOV_EXCL_LINE
413 return TTS_ERROR_INVALID_STATE;
416 if (false == tts_core_check_screen_reader(client)) {
417 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is not available");
418 return TTS_ERROR_SCREEN_READER_OFF;
421 unsigned int uid = tts_client_get_uid(client);
422 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%u)", tts_client_get_handle(client), client, uid);
424 /* check service engine status */
425 bool is_launched = __is_engine_launched(tts_client_get_mode(client));
426 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
427 if (false == is_launched) {
428 /* If engine is NOT launched, check whether engine is updating or not */
429 if (g_engine_update_status) {
430 /* suyeon wait engine update */
431 SLOG(LOG_INFO, TAG_TTSC, "[INFO] cannot prepare due to engine update");
432 __run_client_reprepare_thread();
433 return TTS_ERROR_INVALID_STATE;
437 if (0 != tts_ipc_request_hello(uid)) {
438 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request hello !!"); //LCOV_EXCL_LINE
440 SLOG(LOG_INFO, TAG_TTSC, "@@@ Send Hello");
443 return TTS_ERROR_NONE;
446 static Eina_Bool __prepare_cb(void *data)
448 unsigned int uid = (uintptr_t)data;
449 tts_client_s* client = tts_client_get_by_uid(uid);
450 if (NULL == client) {
451 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
455 int ret = __send_hello_msg(client);
456 if (ret != TTS_ERROR_NONE) {
457 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to send hello message"); //LCOV_EXCL_LINE
458 client->hello_timer = NULL;
462 client->prepare_count++;
463 if (TTS_HELLO_RETRY_COUNT == client->prepare_count) {
464 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Stop to prepare, retry count reaches the limit");
466 bool is_launched = __is_engine_launched(tts_client_get_mode(client));
467 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
469 client->hello_timer = NULL;
476 static Eina_Bool __prepare_first_cb(void *data)
478 /* send first hello message */
479 unsigned int uid = (uintptr_t)data;
480 tts_client_s* client = tts_client_get_by_uid(uid);
481 if (NULL == client) {
482 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
486 int ret = __send_hello_msg(client);
487 if (ret != TTS_ERROR_NONE) {
488 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to sent hello message"); //LCOV_EXCL_LINE
489 client->hello_timer = NULL;
491 /* Set retry timer callback */
492 client->prepare_count = 0;
493 client->hello_timer = ecore_timer_add(0.5, __prepare_cb, data);
499 static Eina_Bool __prepare_sync_cb(tts_client_s* client)
501 // TODO: make function duplicated block
502 bool is_launched = __is_engine_launched(tts_client_get_mode(client));
503 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
505 if (false == is_launched) {
506 /* check whether engine is updating or not */
507 if (g_engine_update_status) {
508 SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] cannot prepare due to engine update");
509 __run_client_reprepare_thread();
513 // TODO: make function duplicated block
514 unsigned int uid = tts_client_get_uid(client);
515 if (0 != tts_ipc_request_hello_sync(uid)) {
519 SLOG(LOG_INFO, TAG_TTSC, "@@@ Connect daemon");
521 // TODO: make function duplicated block
522 /* do request initialize */
524 bool credential_needed = false;
526 ret = tts_ipc_request_initialize(uid, &credential_needed);
527 if (TTS_ERROR_ENGINE_NOT_FOUND == ret || TTS_ERROR_PERMISSION_DENIED == ret) {
528 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", tts_core_covert_error_code(ret));
529 tts_core_notify_error_async(client, ret, -1, NULL);
532 } else if (TTS_ERROR_NONE != ret) {
533 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect : %s", tts_core_covert_error_code(ret));
536 /* success to connect tts-daemon */
537 client->credential_needed = credential_needed;
538 SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%s)", credential_needed ? "need" : "no need");
540 // TODO: make function duplicated block
542 tts_ipc_request_set_mode(uid, tts_client_get_mode(client));
544 tts_core_notify_state_changed(client, TTS_STATE_READY);
546 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
550 static void __engine_changed_cb(keynode_t* key, void* data)
552 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine vconfkey is changed");
553 if (0 != __update_engine_name()) {
554 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
560 static bool __supported_voice_cb(const char* engine_id, const char* language, int type, void* user_data)
562 unsigned int uid = (uintptr_t)user_data;
563 tts_client_s* client = tts_client_get_by_uid(uid);
564 if (NULL == client) {
565 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Uid is not valid. (%d)", uid);
569 /* call callback function */
570 tts_supported_voice_cb callback = tts_client_get_supported_voice_cb(client);
571 void* data = tts_client_get_supported_voice_user_data(client);
573 if (NULL == callback) {
574 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get callback.");
578 return callback(tts_client_get_handle(client), language, type, data);
581 static bool __is_screen_reader_turned_on()
583 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Update screen reader state");
585 int screen_reader = 0;
586 int ret = vconf_get_bool(TTS_ACCESSIBILITY_KEY, &screen_reader);
588 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
592 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Current screen reader status(%d)", screen_reader);
593 return (bool)screen_reader;
596 static inline bool __handle_dbus_request_result(tts_client_s* client, tts_error_e ret, bool* is_prepared)
598 if (TTS_ERROR_NONE == ret) {
599 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success the dbus request");
601 } else if (TTS_ERROR_INVALID_PARAMETER == ret && false == *is_prepared) {
602 tts_client_set_current_state(client, TTS_STATE_CREATED);
603 if (0 == tts_core_prepare_sync(client)) {
605 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
607 } else if (TTS_ERROR_TIMED_OUT != ret) {
608 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", tts_core_covert_error_code(ret));
611 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry play : %s", tts_core_covert_error_code(ret));
618 static inline int __request_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id)
620 /* change default language value */
621 const char* convert_language = (NULL == language ? "default" : language);
622 int new_utt_id = tts_client_new_utterance_id(client);
623 if (0 > new_utt_id) {
624 return TTS_ERROR_OPERATION_FAILED;
627 // TODO: If use cpp, remove dupliceated code using command class pattern
628 unsigned int uid = tts_client_get_uid(client);
630 bool is_prepared = false;
631 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
632 ret = tts_ipc_request_add_text(uid, text, convert_language, voice_type, speed, new_utt_id, client->credential);
633 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
638 if (TTS_ERROR_NONE != ret) {
639 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
643 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_add_text");
644 *utt_id = new_utt_id;
645 return TTS_ERROR_NONE;
648 static inline int __request_play(tts_client_s* client)
650 unsigned int uid = tts_client_get_uid(client);
652 bool is_prepared = false;
653 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
654 ret = tts_ipc_request_play(uid, client->credential);
655 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
660 if (TTS_ERROR_NONE != ret) {
661 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
665 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_play");
666 return tts_core_notify_state_changed(client, TTS_STATE_PLAYING);
669 int tts_core_initialize()
671 ecore_main_loop_thread_safe_call_async(__pkgmgr_thread, NULL);
673 if (0 != __update_engine_name()) {
674 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
677 /* Register vconfkey callback to detect engine change */
678 vconf_notify_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb, NULL);
680 return TTS_ERROR_NONE;
683 int tts_core_deinitialize()
685 if (NULL != g_reprepare_thread && EINA_FALSE == ecore_thread_check(g_reprepare_thread)) {
686 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Cancel reprepare thread");
687 ecore_thread_cancel(g_reprepare_thread);
688 ecore_thread_wait(g_reprepare_thread, 0.5); // wait g_reprepare_thread is terminated.
691 if (NULL != g_pkgmgr_thread) {
692 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Cancel pkgmgr thread");
693 g_is_thread_canceled = true;
696 if (NULL != g_language) {
701 if (NULL != g_engine_name) {
703 g_engine_name = NULL;
706 pthread_mutex_lock(&g_pkgmgr_mutex);
707 if (NULL != g_pkgmgr) {
708 pkgmgr_client_remove_listen_status(g_pkgmgr);
709 pkgmgr_client_free(g_pkgmgr);
713 if (NULL != g_pkgmgr_status) {
714 free(g_pkgmgr_status);
715 g_pkgmgr_status = NULL;
717 pthread_mutex_unlock(&g_pkgmgr_mutex);
719 /* Unregister vconfkey callback */
720 vconf_ignore_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb);
722 return TTS_ERROR_NONE;
725 int tts_core_notify_state_changed(tts_client_s* client, tts_state_e current_state)
727 if (false == tts_client_is_valid_client(client)) {
728 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is invalid.");
729 return TTS_ERROR_INVALID_PARAMETER;
732 tts_state_e before_state = tts_client_get_current_state(client);
733 if (before_state == current_state) {
734 SLOG(LOG_INFO, TAG_TTSC, "[INFO] State is not changed. before(%s), current(%s)", __convert_state(before_state), __convert_state(current_state));
735 return TTS_ERROR_NONE;
738 SLOG(LOG_DEBUG, TAG_TTSC, "State changed to (%s).", __convert_state(current_state));
739 tts_client_set_current_state(client, current_state);
740 __client_state_changed_cb(client, before_state, current_state);
742 return TTS_ERROR_NONE;
745 int tts_core_notify_state_changed_async(tts_client_s* client, tts_state_e current_state)
747 if (false == tts_client_is_valid_client(client)) {
748 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
749 return TTS_ERROR_INVALID_PARAMETER;
752 tts_state_e before_state = tts_client_get_current_state(client);
753 if (before_state == current_state) {
754 SLOG(LOG_INFO, TAG_TTSC, "[INFO] State is not changed. before(%s), current(%s)", __convert_state(before_state), __convert_state(current_state));
755 return TTS_ERROR_NONE;
758 SLOG(LOG_DEBUG, TAG_TTSC, "Notify state changed asynchronously");
759 tts_client_set_current_state(client, current_state);
760 if (NULL != client->notify_state_timer) {
761 ecore_timer_del(client->notify_state_timer);
764 uintptr_t uid = tts_client_get_uid(client);
765 client->notify_state_timer = ecore_timer_add(0, __notify_state_timer_cb, (void*)uid);
767 return TTS_ERROR_NONE;
770 int tts_core_notify_utt_started(tts_client_s* client, int utt_id)
772 if (false == tts_client_is_valid_client(client)) {
773 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
774 return TTS_ERROR_INVALID_PARAMETER;
777 client->utt_id = utt_id;
778 SLOG(LOG_DEBUG, TAG_TTSC, "Utterance started data : utt_id(%d)", client->utt_id);
780 tts_utterance_started_cb callback = tts_client_get_utterance_started_cb(client);
781 void* data = tts_client_get_utterance_started_user_data(client);
783 if (NULL != callback) {
784 SLOG(LOG_DEBUG, TAG_TTSC, "Notify utterance started");
785 tts_client_use_callback(client);
786 callback(tts_client_get_handle(client), client->utt_id, data);
787 tts_client_not_use_callback(client);
789 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(utt_started)");
792 return TTS_ERROR_NONE;
795 int tts_core_notify_utt_completeted(tts_client_s* client, int utt_id)
797 if (false == tts_client_is_valid_client(client)) {
798 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
799 return TTS_ERROR_INVALID_PARAMETER;
802 client->utt_id = utt_id;
803 SLOG(LOG_DEBUG, TAG_TTSC, "Utterance completed data : utt_id(%d)", utt_id);
805 tts_utterance_completed_cb callback = tts_client_get_utterance_completed_cb(client);
806 void* data = tts_client_get_utterance_completed_user_data(client);
808 if (NULL != callback) {
809 SLOG(LOG_DEBUG, TAG_TTSC, "Notify utterance started");
810 tts_client_use_callback(client);
811 callback(tts_client_get_handle(client), utt_id, data);
812 tts_client_not_use_callback(client);
814 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(utt_completed)");
817 return TTS_ERROR_NONE;
820 int tts_core_notify_error_async(tts_client_s* client, tts_error_e reason, int utt_id, const char* err_msg)
822 if (false == tts_client_is_valid_client(client)) {
823 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
824 return TTS_ERROR_INVALID_PARAMETER;
827 SLOG(LOG_DEBUG, TAG_TTSC, "Error data : utt_id(%d) reason(%s)", utt_id, tts_core_covert_error_code(reason));
828 client->utt_id = utt_id;
829 client->reason = reason;
830 tts_client_set_error_message(client, err_msg);
832 SLOG(LOG_DEBUG, TAG_TTSC, "Notify error asynchronously");
833 if (NULL != client->notify_error_timer) {
834 ecore_timer_del(client->notify_error_timer);
837 uintptr_t uid = tts_client_get_uid(client);
838 client->notify_error_timer = ecore_timer_add(0, __notify_error_timer_cb, (void*)uid);
840 return TTS_ERROR_NONE;
843 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)
845 if (false == tts_client_is_valid_client(client)) {
846 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
847 return TTS_ERROR_INVALID_PARAMETER;
850 SLOG(LOG_DEBUG, TAG_TTSC, "Default voice changed data : before_lang(%s), before_voice_type(%d), language(%s), voice_type(%d)",
851 before_lang, before_voice_type, language, voice_type);
853 tts_default_voice_changed_cb callback = tts_client_get_default_voice_changed_cb(client);
854 void* data = tts_client_get_default_voice_changed_user_data(client);
856 if (NULL != callback) {
857 SLOG(LOG_DEBUG, TAG_TTSC, "Notify default voice changed");
858 tts_client_use_callback(client);
859 callback(tts_client_get_handle(client), before_lang, before_voice_type, language, voice_type, data);
860 tts_client_not_use_callback(client);
862 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(default_voice_changed)");
865 return TTS_ERROR_NONE;
868 int tts_core_notify_engine_changed(tts_client_s* client, const char* engine_id, const char* language, int voice_type, bool need_credential)
870 if (false == tts_client_is_valid_client(client)) {
871 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
872 return TTS_ERROR_INVALID_PARAMETER;
875 SLOG(LOG_DEBUG, TAG_TTSC, "Engine changed data : engine_id(%s) language(%s), voicd_type(%d), need_credential(%d)",
876 engine_id, language, voice_type, need_credential);
878 tts_engine_changed_cb callback = tts_client_get_engine_changed_cb(client);
879 void* data = tts_client_get_engine_changed_user_data(client);
881 if (NULL != callback) {
882 SLOG(LOG_DEBUG, TAG_TTSC, "Notify engine changed");
883 tts_client_use_callback(client);
884 callback(tts_client_get_handle(client), engine_id, language, voice_type, need_credential, data);
885 tts_client_not_use_callback(client);
887 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(engine_changed)");
890 return TTS_ERROR_NONE;
893 int tts_core_notify_screen_reader_changed(tts_client_s* client, bool value)
895 if (false == tts_client_is_valid_client(client)) {
896 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
897 return TTS_ERROR_INVALID_PARAMETER;
900 SLOG(LOG_DEBUG, TAG_TTSC, "Screen reader is changed. Current status(%d)", value);
902 tts_screen_reader_changed_cb callback = tts_client_get_screen_reader_changed_cb(client);
903 void* data = tts_client_get_screen_reader_changed_user_data(client);
905 if (NULL != callback) {
906 SLOG(LOG_DEBUG, TAG_TTSC, "Notify screen reader changed");
907 tts_client_use_callback(client);
908 callback(tts_client_get_handle(client), value, data);
909 tts_client_not_use_callback(client);
911 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(screen_reader_changed)");
914 return TTS_ERROR_NONE;
917 bool tts_core_is_valid_text(const char* text)
923 /* check valid utf8 */
925 dbus_error_init(&err);
926 bool valid = dbus_validate_utf8(text, &err);
927 if (dbus_error_is_set(&err)) {
928 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Dbus Error(%s), text(%s)", err.message, text);
929 dbus_error_free(&err);
933 if (false == valid) {
934 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Text is invalid - '%s'", text);
938 if (strlen(text) <= 0) {
939 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is invalid.");
943 unsigned int max_text_size = 0;
944 /* check text size */
945 if (0 != tts_config_mgr_get_max_text_size(&max_text_size)) {
946 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get max text size");
950 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] max_text_size is %d byte", max_text_size);
951 if (0 < max_text_size && max_text_size < strlen(text)) {
952 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is bigger than maximum test size. text_size(%zu byte)", strlen(text));
959 bool tts_core_check_screen_reader(tts_client_s* client)
961 if (false == tts_client_is_valid_client(client)) {
962 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] client is not valid");
966 tts_mode_e mode = tts_client_get_mode(client);
967 if (TTS_MODE_SCREEN_READER == mode && false == __is_screen_reader_turned_on()) {
974 const char* tts_core_covert_error_code(tts_error_e err)
977 case TTS_ERROR_NONE: return "TTS_ERROR_NONE";
978 case TTS_ERROR_OUT_OF_MEMORY: return "TTS_ERROR_OUT_OF_MEMORY";
979 case TTS_ERROR_IO_ERROR: return "TTS_ERROR_IO_ERROR";
980 case TTS_ERROR_INVALID_PARAMETER: return "TTS_ERROR_INVALID_PARAMETER";
981 case TTS_ERROR_OUT_OF_NETWORK: return "TTS_ERROR_OUT_OF_NETWORK";
982 case TTS_ERROR_TIMED_OUT: return "TTS_ERROR_TIMED_OUT";
983 case TTS_ERROR_PERMISSION_DENIED: return "TTS_ERROR_PERMISSION_DENIED";
984 case TTS_ERROR_NOT_SUPPORTED: return "TTS_ERROR_NOT_SUPPORTED";
985 case TTS_ERROR_INVALID_STATE: return "TTS_ERROR_INVALID_STATE";
986 case TTS_ERROR_INVALID_VOICE: return "TTS_ERROR_INVALID_VOICE";
987 case TTS_ERROR_ENGINE_NOT_FOUND: return "TTS_ERROR_ENGINE_NOT_FOUND";
988 case TTS_ERROR_OPERATION_FAILED: return "TTS_ERROR_OPERATION_FAILED";
989 case TTS_ERROR_AUDIO_POLICY_BLOCKED: return "TTS_ERROR_AUDIO_POLICY_BLOCKED";
990 case TTS_ERROR_NOT_SUPPORTED_FEATURE: return "TTS_ERROR_NOT_SUPPORTED_FEATURE";
991 case TTS_ERROR_SERVICE_RESET: return "TTS_ERROR_SERVICE_RESET";
993 return "Invalid error code";
998 int tts_core_receive_hello(unsigned int uid, int ret, int credential_needed)
1000 tts_client_s* client = tts_client_get_by_uid(uid);
1001 if (NULL == client) {
1002 SLOG(LOG_ERROR, TAG_TTSC, "Fail to get TTS client or ignore this uid(%u)", uid);
1003 return TTS_ERROR_OPERATION_FAILED;
1006 tts_state_e current_state = tts_client_get_current_state(client);
1007 if (TTS_STATE_CREATED != current_state) {
1008 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts client is already READY");
1009 return TTS_ERROR_NONE;
1012 if (client->hello_timer) {
1013 ecore_timer_del(client->hello_timer);
1014 client->hello_timer = NULL;
1017 if (TTS_ERROR_ENGINE_NOT_FOUND == ret || TTS_ERROR_PERMISSION_DENIED == ret) {
1018 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", tts_core_covert_error_code(ret));
1019 tts_core_notify_error_async(client, ret, -1, NULL);
1021 return TTS_ERROR_OPERATION_FAILED;
1022 } else if (TTS_ERROR_ALREADY_INITIALIZED == ret) {
1023 /* success to connect tts-daemon */
1024 if (TTS_CREDENTIAL_NEEDED_ALREADY_INITIALIZED != credential_needed) {
1025 client->credential_needed = credential_needed;
1026 SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%d)", credential_needed);
1028 } else if (TTS_ERROR_NONE != ret) {
1029 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect : %s", tts_core_covert_error_code(ret));
1030 return TTS_ERROR_OPERATION_FAILED;
1033 tts_ipc_request_set_mode(uid, tts_client_get_mode(client));
1035 tts_core_notify_state_changed_async(client, TTS_STATE_READY);
1037 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1038 return TTS_ERROR_NONE;
1041 const char* tts_core_get_engine_name()
1043 return g_engine_name;
1046 int tts_core_prepare(tts_client_s* client)
1048 if (false == tts_client_is_valid_client(client)) {
1049 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
1050 return TTS_ERROR_INVALID_PARAMETER;
1053 if (false == tts_core_check_screen_reader(client)) {
1054 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is not available");
1055 return TTS_ERROR_SCREEN_READER_OFF;
1058 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Start core_prepare. tts_h(%p), tts_client(%p)", tts_client_get_handle(client), client);
1059 if (NULL == client->hello_timer) {
1060 SLOG(LOG_ERROR, TAG_TTSC, "Register timer for __prepare_first_cb");
1062 ecore_thread_main_loop_begin();
1063 uintptr_t uid = tts_client_get_uid(client);
1064 client->hello_timer = ecore_timer_add(0.0, __prepare_first_cb, (void*)uid);
1065 ecore_thread_main_loop_end();
1067 LOGD("Client is already trying to prepare");
1070 return TTS_ERROR_NONE;
1073 int tts_core_prepare_sync(tts_client_s* client)
1075 if (false == tts_client_is_valid_client(client)) {
1076 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
1077 return TTS_ERROR_INVALID_PARAMETER;
1080 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Start core_prepare_sync. tts_h(%p), tts_client(%p), uid(%u)", tts_client_get_handle(client), client, tts_client_get_uid(client));
1082 while (TTS_CONNECTION_RETRY_COUNT > cnt) {
1083 if (false == tts_core_check_screen_reader(client)) {
1084 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is not available");
1085 return TTS_ERROR_SCREEN_READER_OFF;
1088 if (EINA_FALSE == __prepare_sync_cb(client)) {
1095 if (TTS_CONNECTION_RETRY_COUNT == cnt) {
1096 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connect daemon");
1097 return TTS_ERROR_OPERATION_FAILED;
1100 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1101 return TTS_ERROR_NONE;
1104 int tts_core_unprepare(tts_client_s* client)
1106 if (false == tts_client_is_valid_client(client)) {
1107 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
1108 return TTS_ERROR_INVALID_PARAMETER;
1111 unsigned int uid = tts_client_get_uid(client);
1112 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%u)", tts_client_get_handle(client), client, uid);
1113 if (client->hello_timer) {
1114 ecore_timer_del(client->hello_timer);
1115 client->hello_timer = NULL;
1119 if (false == tts_core_check_screen_reader(client)) {
1120 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Do not request finalize. Handled by screen reader");
1122 ret = tts_ipc_stop_listening(uid);
1124 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to remove match : %s", tts_core_covert_error_code(ret));
1127 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Request finalize");
1129 bool is_prepared = false;
1130 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1131 ret = tts_ipc_request_finalize(uid);
1132 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1137 if (TTS_ERROR_NONE == ret) {
1138 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_finalize");
1142 return TTS_ERROR_NONE;
1145 int tts_core_reprepare()
1147 GList* clients = tts_client_get_client_list();
1148 if (NULL == clients) {
1149 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get client list");
1150 return TTS_ERROR_OPERATION_FAILED;
1154 if (g_list_length(clients) > 0) {
1155 iter = g_list_first(clients);
1157 while (NULL != iter) {
1158 tts_client_s* client = iter->data;
1159 if (true == tts_client_is_valid_client(client)) {
1160 tts_client_set_current_state(client, TTS_STATE_CREATED);
1163 iter = g_list_next(iter);
1167 g_list_free(clients);
1168 __run_client_reprepare_thread();
1170 return TTS_ERROR_NONE;
1173 int tts_core_foreach_supported_voices(tts_client_s* client, const char* engine_id, tts_supported_voice_cb callback, void* user_data)
1175 if (false == tts_client_is_valid_client(client)) {
1176 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] client is not valid");
1177 return TTS_ERROR_INVALID_PARAMETER;
1180 tts_client_set_supported_voice_cb(client, callback, user_data);
1181 uintptr_t uid = tts_client_get_uid(client);
1182 int ret = tts_config_mgr_get_voice_list(engine_id, __supported_voice_cb, (void*)uid);
1183 tts_client_set_supported_voice_cb(client, NULL, NULL);
1186 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get voice list");
1187 return TTS_ERROR_OPERATION_FAILED;
1190 return TTS_ERROR_NONE;
1193 int tts_core_handle_service_reset()
1195 GList* client_list = tts_client_get_client_list();
1196 if (NULL == client_list) {
1197 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get client list");
1198 return TTS_ERROR_OPERATION_FAILED;
1201 if (g_list_length(client_list) > 0) {
1202 GList *iter = g_list_first(client_list);
1203 while (NULL != iter) {
1204 tts_client_s *client = iter->data;
1205 if (false == tts_client_is_valid_client(client)) {
1206 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid");
1208 tts_core_notify_error_async(client, TTS_ERROR_SERVICE_RESET, -1, "Daemon Reset");
1211 iter = g_list_next(iter);
1215 g_list_free(client_list);
1217 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset");
1218 tts_core_reprepare();
1220 return TTS_ERROR_NONE;
1223 int tts_core_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id)
1225 if (NULL == text || NULL == utt_id) {
1226 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Parameter is invalid.");
1227 return TTS_ERROR_INVALID_PARAMETER;
1230 if (false == tts_client_is_valid_client(client)) {
1231 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1232 return TTS_ERROR_INVALID_PARAMETER;
1235 tts_client_set_repeat_text(client, text);
1237 if (NULL != g_language) {
1241 g_language = (NULL == language ? NULL : strdup(language));
1242 g_voice_type = voice_type;
1245 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] text(%s), language(%s), voice type(%d), speed(%d)", text, (g_language) ? g_language : "NULL", g_voice_type, g_speed);
1246 return __request_add_text(client, text, language, voice_type, speed, utt_id);
1249 int tts_core_play(tts_client_s* client)
1251 if (false == tts_client_is_valid_client(client)) {
1252 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1253 return TTS_ERROR_INVALID_PARAMETER;
1256 return __request_play(client);
1259 int tts_core_stop(tts_client_s* client)
1261 if (false == tts_client_is_valid_client(client)) {
1262 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1263 return TTS_ERROR_INVALID_PARAMETER;
1266 unsigned int uid = tts_client_get_uid(client);
1269 bool is_prepared = false;
1270 while (TTS_RETRY_COUNT > count) {
1271 ret = tts_ipc_request_stop(uid);
1272 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1279 if (TTS_ERROR_NONE != ret) {
1280 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1284 return tts_core_notify_state_changed(client, TTS_STATE_READY);
1287 int tts_core_pause(tts_client_s* client)
1289 if (false == tts_client_is_valid_client(client)) {
1290 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1291 return TTS_ERROR_INVALID_PARAMETER;
1294 unsigned int uid = tts_client_get_uid(client);
1296 bool is_prepared = false;
1297 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1298 ret = tts_ipc_request_pause(uid);
1299 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1304 if (TTS_ERROR_NONE != ret) {
1305 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1309 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_pause");
1310 return tts_core_notify_state_changed(client, TTS_STATE_PAUSED);
1313 int tts_core_repeat(tts_client_s* client, char** text_repeat, int* utt_id)
1315 if (NULL == text_repeat || NULL == utt_id) {
1316 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Parameter is invalid.");
1317 return TTS_ERROR_INVALID_PARAMETER;
1320 if (false == tts_client_is_valid_client(client)) {
1321 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1322 return TTS_ERROR_INVALID_PARAMETER;
1325 const char* repeat_text = tts_client_get_repeat_text(client);
1326 if (NULL == repeat_text) {
1327 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] There is no previous added texts. Please add texts");
1328 return TTS_ERROR_OPERATION_FAILED;
1331 int new_utt_id = -1;
1332 int ret = __request_add_text(client, repeat_text, g_language, g_voice_type, g_speed, &new_utt_id);
1333 if (TTS_ERROR_NONE != ret) {
1334 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to add texts for repetition.");
1338 /* Play added texts */
1339 ret = __request_play(client);
1340 if (TTS_ERROR_NONE != ret) {
1341 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to play texts for repetition.");
1345 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] text to repeat(%s), utt_id(%d)", repeat_text, new_utt_id);
1347 *utt_id = new_utt_id;
1348 *text_repeat = strdup(repeat_text);
1349 return TTS_ERROR_NONE;
1352 int tts_core_add_pcm(tts_client_s* client, int event, const void* data, unsigned int data_size, int audio_type, int rate)
1354 if (false == tts_client_is_valid_client(client)) {
1355 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1356 return TTS_ERROR_INVALID_PARAMETER;
1359 unsigned int uid = tts_client_get_uid(client);
1361 bool is_prepared = false;
1362 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1363 ret = tts_ipc_request_add_pcm(uid, event, data, data_size, audio_type, rate);
1364 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1369 if (TTS_ERROR_NONE != ret) {
1370 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1374 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_add_pcm");
1375 return TTS_ERROR_NONE;
1378 int tts_core_play_pcm(tts_client_s* client)
1380 if (false == tts_client_is_valid_client(client)) {
1381 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1382 return TTS_ERROR_INVALID_PARAMETER;
1385 unsigned int uid = tts_client_get_uid(client);
1387 bool is_prepared = false;
1388 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1389 ret = tts_ipc_request_play_pcm(uid);
1390 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1395 if (TTS_ERROR_NONE != ret) {
1396 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1400 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_play_pcm");
1401 return tts_core_notify_state_changed(client, TTS_STATE_PLAYING);
1404 int tts_core_stop_pcm(tts_client_s* client)
1406 if (false == tts_client_is_valid_client(client)) {
1407 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1408 return TTS_ERROR_INVALID_PARAMETER;
1411 unsigned int uid = tts_client_get_uid(client);
1413 bool is_prepared = false;
1414 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1415 ret = tts_ipc_request_stop_pcm(uid);
1416 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1421 if (TTS_ERROR_NONE != ret) {
1422 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1426 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_stop_pcm");
1427 return tts_core_notify_state_changed(client, TTS_STATE_READY);
1430 int tts_core_set_private_data(tts_client_s* client, const char* key, const char* data)
1432 if (false == tts_client_is_valid_client(client)) {
1433 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1434 return TTS_ERROR_INVALID_PARAMETER;
1437 unsigned int uid = tts_client_get_uid(client);
1439 bool is_prepared = false;
1440 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1441 ret = tts_ipc_request_set_private_data(uid, key, data);
1442 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1447 if (TTS_ERROR_NONE != ret) {
1448 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1452 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_set_private_data");
1453 return TTS_ERROR_NONE;
1456 int tts_core_get_private_data(tts_client_s* client, const char* key, char** data)
1458 if (false == tts_client_is_valid_client(client)) {
1459 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1460 return TTS_ERROR_INVALID_PARAMETER;
1463 unsigned int uid = tts_client_get_uid(client);
1465 bool is_prepared = false;
1466 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1467 ret = tts_ipc_request_get_private_data(uid, key, data);
1468 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1473 if (TTS_ERROR_NONE != ret) {
1474 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1478 if (0 == strncmp(*data, "NULL", strlen(*data))) {
1483 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_get_private_data");
1484 return TTS_ERROR_NONE;