Merge "Add codes in client side to set/unset callback for retrieving sythesized pcm...
[platform/core/uifw/tts.git] / client / tts_core.c
1 /*
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.
12 */
13
14 #include <string.h>
15 #include <stdatomic.h>
16
17 #include <app_manager.h>
18 #include <dlog.h>
19 #include <package-manager.h>
20
21 #include "tts_internal.h"
22 #include "tts_defs.h"
23 #include "tts_core.h"
24 #include "tts_ipc.h"
25 #include "tts_dlog.h"
26
27
28 static const int TTS_ERROR_FAIL_TO_SEND_HELLO = TIZEN_ERROR_TTS | 0xFF;
29
30
31 /* Static variables */
32 static atomic_bool g_is_thread_canceled = false;
33
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;
37
38 static Ecore_Thread* g_reprepare_thread = NULL;
39
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;
44
45 static char* g_language = NULL;
46 static int g_voice_type = -1;
47 static int g_speed = -1;
48
49
50 /* Static functions */
51 // TODO: make tts_util? or tts_log?
52 static const char* __convert_state(tts_state_e state)
53 {
54         switch (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";
59         }
60
61         return "Invalid state";
62 }
63
64 static char* __get_engine_appid() {
65         if (NULL == g_engine_name) {
66                 return NULL;
67         }
68
69         char* appid = (char*)calloc(TTS_ENGINE_APPID_LEN, sizeof(char));
70         if (NULL == appid) {
71                 return NULL;
72         }
73
74         snprintf(appid, TTS_ENGINE_APPID_LEN, "%s", g_engine_name);
75         return appid;
76 }
77
78 static int __update_engine_name()
79 {
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");
82
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;
87         }
88
89         free(g_engine_name);
90         g_engine_name = new_engine_name;
91         g_is_engine_name_changed = true;
92
93         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Engine name(%s)", g_engine_name);
94         return TTS_ERROR_NONE;
95 }
96
97 static inline void __client_error_cb(tts_client_s* client, int utt_id, tts_error_e reason)
98 {
99         tts_error_cb callback = tts_client_get_error_cb(client);
100         void* data = tts_client_get_error_user_data(client);
101
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);
107         } else {
108                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(error)");
109         }
110 }
111
112 static inline void __client_state_changed_cb(tts_client_s* client, tts_state_e before_state, tts_state_e current_state)
113 {
114         tts_state_changed_cb callback = tts_client_get_state_changed_cb(client);
115         void* data = tts_client_get_state_changed_user_data(client);
116
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);
122         } else {
123                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(state_changed)");
124         }
125 }
126
127 static Eina_Bool __notify_error_timer_cb(void *data)
128 {
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);
132
133         __client_error_cb(client, client->utt_id, client->reason);
134         client->notify_error_timer = NULL;
135
136         return EINA_FALSE;
137 }
138
139 static bool __is_engine_installed(const char* appid)
140 {
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);
145                 return false;
146         } else {
147                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] There is tts engine (%s)", appid);
148         }
149
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);
153
154         return true;
155 }
156
157 static bool __is_engine_launched()
158 {
159         char* appid = __get_engine_appid();
160         if (NULL == appid) {
161                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine app ID");
162                 return false;
163         }
164
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);
168                 free(appid);
169                 return false;
170         }
171
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);
177                 free(appid);
178                 return false;
179         }
180
181         free(appid);
182         SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is %s running. is_installed(%d)", (is_running) ? "" : " not", is_installed);
183         return is_running;
184 }
185
186 //LCOV_EXCL_START
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)
188 {
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);
191
192         if (NULL == g_engine_name) {
193                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] engine name is NULL");
194                 return 0;
195         }
196
197         if (0 != strncmp(g_engine_name, pkgname, strlen(g_engine_name))) {
198                 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] this is not tts engine");
199                 return 0;
200         }
201
202         if (NULL == key) {
203                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] key is NULL");
204                 return 0;
205         }
206
207         if (0 == strncmp(key, "start", strlen(key))) {
208                 if (NULL != g_pkgmgr_status) {
209                         free(g_pkgmgr_status);
210                         g_pkgmgr_status = NULL;
211                 }
212
213                 if (val) {
214                         g_pkgmgr_status = strdup(val);
215                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status. key(%s), status(%s)", key, g_pkgmgr_status);
216
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;
220                         }
221                 }
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;
227
228                                 free(g_pkgmgr_status);
229                                 g_pkgmgr_status = NULL;
230                         }
231                 }
232         }
233
234         return 0;
235 }
236 //LCOV_EXCL_STOP
237
238 static void __create_pkgmgr_thread(void* data, Ecore_Thread* thread)
239 {
240         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] create pkgmgr thread");
241
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");
247                         break;
248                 }
249
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");
253                         break;
254                 }
255
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");
259                 } else {
260                         int ret = pkgmgr_client_set_status_type(g_pkgmgr, PKGMGR_CLIENT_STATUS_INSTALL | PKGMGR_CLIENT_STATUS_UNINSTALL | PKGMGR_CLIENT_STATUS_UPGRADE);
261                         if (0 == ret) {
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);
265                                         g_pkgmgr = NULL;
266                                 } else {
267                                         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Succeed to register pkgmgr cb");
268                                         break;
269                                 }
270                         } else {
271                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set status type on pkgmgr, ret(%d)", ret);
272                                 pkgmgr_client_free(g_pkgmgr);
273                                 g_pkgmgr = NULL;
274                         }
275                 }
276
277                 usleep(10000);
278         }
279         pthread_mutex_unlock(&g_pkgmgr_mutex);
280
281         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] create pkgmgr end");
282 }
283
284 static void __finish_pkgmgr_thread(void* data, Ecore_Thread* thread)
285 {
286         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] Finish pkgmgr thread");
287         g_is_thread_canceled = false;
288         g_pkgmgr_thread = NULL;
289 }
290
291 //LCOV_EXCL_START
292 static void __cancel_pkgmgr_thread(void* data, Ecore_Thread* thread)
293 {
294         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] Cancel pkgmgr thread");
295         g_is_thread_canceled = false;
296         g_pkgmgr_thread = NULL;
297 }
298 //LCOV_EXCL_STOP
299
300 static void __pkgmgr_thread(void* data)
301 {
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);
306         }
307
308         return;
309 }
310
311 //LCOV_EXCL_START
312 static void __start_reprepare_thread(void* data, Ecore_Thread* thread)
313 {
314         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] start reprepare thread. engine update status(%d)", g_engine_update_status);
315
316         if (0 == g_engine_update_status && g_is_engine_name_changed) {
317                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Reprepare by engine change");
318                 return;
319         }
320
321         int cnt = 0;
322         while (!g_engine_update_status && cnt < 20) {
323                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] wait for starting update");
324
325                 usleep(50000);
326                 cnt++;
327
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");
332                         return;
333                 }
334         }
335
336         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] update status(%d)", g_engine_update_status);
337
338         while (g_engine_update_status && (NULL != g_pkgmgr)) {
339                 usleep(200000);
340
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");
345                         return;
346                 }
347         }
348
349         SLOG(LOG_INFO, TAG_TTSC, "[INFO] finish updating. request to prepare");
350
351         return;
352 }
353 //LCOV_EXCL_STOP
354
355 static void __end_reprepare_thread(void* data, Ecore_Thread* thread)
356 {
357         SLOG(LOG_INFO, TAG_TTSC, "[INFO] end reprepare thread");
358
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;
364                 return;
365         }
366
367         GList *iter = NULL;
368         if (g_list_length(clients) > 0) {
369                 iter = g_list_first(clients);
370
371                 while (NULL != iter) {
372                         tts_client_s* client = iter->data;
373                         if (NULL != client) {
374                                 tts_core_prepare(client);
375                         }
376
377                         iter = g_list_next(iter);
378                 }
379         }
380
381         g_list_free(clients);
382         g_is_engine_name_changed = false;
383         g_reprepare_thread = NULL;
384 }
385
386 //LCOV_EXCL_START
387 static void __cancel_reprepare_thread(void* data, Ecore_Thread* thread)
388 {
389         SLOG(LOG_INFO, TAG_TTSC, "[INFO] cancel reprepare thread");
390         g_is_engine_name_changed = false;
391         g_reprepare_thread = NULL;
392 }
393 //LCOV_EXCL_STOP
394
395 static inline void __run_client_reprepare_thread()
396 {
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);
400         } else {
401                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Reprepare thread is already running");
402         }
403 }
404
405 static int __send_hello_msg(tts_client_s* client)
406 {
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;
411         }
412
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;
416         }
417
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);
422
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;
433                 }
434         }
435
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
438         } else {
439                 SLOG(LOG_INFO, TAG_TTSC, "@@@ Send Hello");
440         }
441
442         return TTS_ERROR_NONE;
443 }
444
445 static Eina_Bool __prepare_cb(void *data)
446 {
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);
450
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;
455                 return EINA_FALSE;
456         }
457
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");
461
462                 bool is_launched = __is_engine_launched();
463                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
464
465                 client->hello_timer = NULL;
466
467                 tts_core_notify_error_async(client, TTS_ERROR_TIMED_OUT, -1, "[ERROR] Fail to prepare. Please call tts_prepare() again.");
468
469                 return EINA_FALSE;
470         }
471
472         return EINA_TRUE;
473 }
474
475 static Eina_Bool __prepare_first_cb(void *data)
476 {
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);
481
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;
486         } else {
487                 /* Set retry timer callback */
488                 client->prepare_count = 0;
489                 client->hello_timer = ecore_timer_add(0.5, __prepare_cb, data);
490         }
491
492         return EINA_FALSE;
493 }
494
495 static int __prepare_sync_cb(tts_client_s* client)
496 {
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);
500
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;
508                 }
509         }
510
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;
515         }
516
517         SLOG(LOG_INFO, TAG_TTSC, "@@@ Connect daemon");
518
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);
528
529                 return ret;
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;
533         } else {
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");
537         }
538         // TODO: make function duplicated block
539
540         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
541         return TTS_ERROR_NONE;
542 }
543
544 static void __engine_changed_cb(keynode_t* key, void* data)
545 {
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");
549         }
550
551         return;
552 }
553
554 static bool __supported_voice_cb(const char* engine_id, const char* language, int type, void* user_data)
555 {
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);
559
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);
563
564         if (NULL == callback) {
565                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get callback.");
566                 return false;
567         }
568
569         return callback(tts_client_get_handle(client), language, type, data);
570 }
571
572 static bool __is_screen_reader_turned_on()
573 {
574         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Update screen reader state");
575
576         int screen_reader = 0;
577         int ret = vconf_get_bool(TTS_ACCESSIBILITY_KEY, &screen_reader);
578         if (0 != ret) {
579                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
580                 return false;
581         }
582
583         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Current screen reader status(%d)", screen_reader);
584         return (bool)screen_reader;
585 }
586
587 static inline bool __is_ipc_retry_needed(tts_client_s* client, tts_error_e ret)
588 {
589         if (TTS_ERROR_NONE == ret) {
590                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success the IPC request");
591                 return false;
592         }
593
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));
596                 usleep(10000);
597                 return true;
598         }
599
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));
603                 return false;
604         }
605
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);
612                 return true;
613         }
614
615         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] IPC request is failed. ret(%d/%s)", ret, get_error_message(ret));
616         return false;
617 }
618
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)
620 {
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;
626         }
627
628         // TODO: If use cpp, remove dupliceated code using command class pattern
629         unsigned int uid = tts_client_get_uid(client);
630         int ret = -1;
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)) {
635                         break;
636                 }
637         }
638
639         if (TTS_ERROR_NONE != ret) {
640                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
641                 return ret;
642         }
643
644         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_add_text");
645         *utt_id = new_utt_id;
646         return TTS_ERROR_NONE;
647 }
648
649 static inline int __request_play(tts_client_s* client)
650 {
651         unsigned int uid = tts_client_get_uid(client);
652         int ret = -1;
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)) {
657                         break;
658                 }
659         }
660
661         if (TTS_ERROR_NONE != ret) {
662                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request. ret(%d)", ret);
663                 return ret;
664         }
665
666         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Success tts_dbus_request_play");
667         return tts_core_notify_state_changed(client, TTS_STATE_PLAYING);
668 }
669
670 int tts_core_initialize()
671 {
672         ecore_main_loop_thread_safe_call_async(__pkgmgr_thread, NULL);
673
674         if (0 != __update_engine_name()) {
675                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
676         }
677         g_is_engine_name_changed = false;
678
679         /* Register vconfkey callback to detect engine change */
680         vconf_notify_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb, NULL);
681
682         return TTS_ERROR_NONE;
683 }
684
685 int tts_core_deinitialize()
686 {
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.
691         }
692
693         if (NULL != g_pkgmgr_thread) {
694                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Cancel pkgmgr thread");
695                 g_is_thread_canceled = true;
696         }
697
698         if (NULL != g_language) {
699                 free(g_language);
700                 g_language = NULL;
701         }
702
703         if (NULL != g_engine_name) {
704                 free(g_engine_name);
705                 g_engine_name = NULL;
706         }
707
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);
712                 g_pkgmgr = NULL;
713         }
714
715         if (NULL != g_pkgmgr_status) {
716                 free(g_pkgmgr_status);
717                 g_pkgmgr_status = NULL;
718         }
719         pthread_mutex_unlock(&g_pkgmgr_mutex);
720
721         /* Unregister vconfkey callback */
722         vconf_ignore_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb);
723
724         return TTS_ERROR_NONE;
725 }
726
727 int tts_core_notify_state_changed(tts_client_s* client, tts_state_e current_state)
728 {
729         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
730
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;
735         }
736
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);
740
741         return TTS_ERROR_NONE;
742 }
743
744 int tts_core_notify_utt_started(tts_client_s* client, int utt_id)
745 {
746         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
747
748         client->utt_id = utt_id;
749         SLOG(LOG_DEBUG, TAG_TTSC, "Utterance started data : utt_id(%d)", client->utt_id);
750
751         tts_utterance_started_cb callback = tts_client_get_utterance_started_cb(client);
752         void* data = tts_client_get_utterance_started_user_data(client);
753
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);
759         } else {
760                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(utt_started)");
761         }
762
763         return TTS_ERROR_NONE;
764 }
765
766 int tts_core_notify_utt_completeted(tts_client_s* client, int utt_id)
767 {
768         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
769
770         client->utt_id = utt_id;
771         SLOG(LOG_DEBUG, TAG_TTSC, "Utterance completed data : utt_id(%d)", utt_id);
772
773         tts_utterance_completed_cb callback = tts_client_get_utterance_completed_cb(client);
774         void* data = tts_client_get_utterance_completed_user_data(client);
775
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);
781         } else {
782                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(utt_completed)");
783         }
784
785         return TTS_ERROR_NONE;
786 }
787
788 int tts_core_notify_error_async(tts_client_s* client, tts_error_e reason, int utt_id, const char* err_msg)
789 {
790         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
791
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);
796
797         SLOG(LOG_DEBUG, TAG_TTSC, "Notify error asynchronously");
798         if (NULL != client->notify_error_timer) {
799                 ecore_timer_del(client->notify_error_timer);
800         }
801
802         uintptr_t uid = tts_client_get_uid(client);
803         client->notify_error_timer = ecore_timer_add(0, __notify_error_timer_cb, (void*)uid);
804
805         return TTS_ERROR_NONE;
806 }
807
808 //LCOV_EXCL_START
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)
810 {
811         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
812
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);
815
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);
818
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);
824         } else {
825                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(default_voice_changed)");
826         }
827
828         return TTS_ERROR_NONE;
829 }
830
831 int tts_core_notify_engine_changed(tts_client_s* client, const char* engine_id, const char* language, int voice_type, bool need_credential)
832 {
833         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
834
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);
837
838         tts_engine_changed_cb callback = tts_client_get_engine_changed_cb(client);
839         void* data = tts_client_get_engine_changed_user_data(client);
840
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);
846         } else {
847                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(engine_changed)");
848         }
849
850         return TTS_ERROR_NONE;
851 }
852 //LCOV_EXCL_STOP
853
854 int tts_core_notify_screen_reader_changed(tts_client_s* client, bool value)
855 {
856         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
857
858         SLOG(LOG_DEBUG, TAG_TTSC, "Screen reader is changed. Current status(%d)", value);
859
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);
862
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);
868         } else {
869                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(screen_reader_changed)");
870         }
871
872         return TTS_ERROR_NONE;
873 }
874
875 int tts_core_notify_service_state_changed(tts_client_s* client, tts_service_state_e before_state, tts_service_state_e current_state)
876 {
877         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
878
879         SLOG(LOG_DEBUG, TAG_TTSC, "Service state changed from (%d) to (%d).", before_state, current_state);
880
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);
883
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);
889         } else {
890                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(service_state_changed)");
891         }
892
893         return TTS_ERROR_NONE;
894 }
895
896 bool tts_core_is_valid_text(const char* text)
897 {
898         if (NULL == text) {
899                 return false;
900         }
901
902         /* check valid utf8 */
903         DBusError err;
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);
909                 return false;
910         }
911
912         if (false == valid) {
913                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Text is invalid - '%s'", text);
914                 return false;
915         }
916
917         if (strlen(text) <= 0) {
918                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is invalid.");
919                 return false;
920         }
921
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");
926                 return false;
927         }
928
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));
932                 return false;
933         }
934
935         return true;
936 }
937
938 bool tts_core_check_screen_reader(tts_client_s* client)
939 {
940         RETVM_IF(false == tts_client_is_valid_client(client), false, "[ERROR] Client is invalid.");
941
942         tts_mode_e mode = tts_client_get_mode(client);
943         if (TTS_MODE_SCREEN_READER == mode && false == __is_screen_reader_turned_on()) {
944                 return false;
945         }
946
947         return true;
948 }
949
950 bool tts_core_check_credential(tts_client_s* client)
951 {
952         RETVM_IF(false == tts_client_is_valid_client(client), false, "[ERROR] Client is invalid.");
953
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");
956                 return false;
957         }
958
959         return true;
960 }
961
962 //LCOV_EXCL_START
963 const char* tts_core_covert_error_code(tts_error_e err)
964 {
965         switch (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";
982         default:
983                 return "Invalid error code";
984         }
985         return NULL;
986 }
987 //LCOV_EXCL_STOP
988
989 int tts_core_receive_hello(unsigned int uid, int ret, int credential_needed)
990 {
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);
993
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");
996
997         if (client->hello_timer) {
998                 ecore_timer_del(client->hello_timer);
999                 client->hello_timer = NULL;
1000         }
1001
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);
1005
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);
1012                 }
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;
1016         }
1017
1018         tts_core_notify_state_changed(client, TTS_STATE_READY);
1019
1020         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1021         return TTS_ERROR_NONE;
1022 }
1023
1024 int tts_core_prepare(tts_client_s* client)
1025 {
1026         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1027
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;
1031         }
1032
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");
1036
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();
1041         } else {
1042                 LOGD("Client is already trying to prepare");
1043         }
1044
1045         return TTS_ERROR_NONE;
1046 }
1047
1048 int tts_core_prepare_sync(tts_client_s* client)
1049 {
1050         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1051
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);
1054         int cnt = 0;
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;
1059                 }
1060
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);
1064                         break;
1065                 }
1066
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);
1069                 } else {
1070                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare. uid(%u), ret(%d/%s)", uid, ret, get_error_message(ret));
1071                         return ret;
1072                 }
1073
1074                 cnt++;
1075         }
1076
1077         if (TTS_CONNECTION_RETRY_COUNT == cnt) {
1078                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connect daemon");
1079                 return TTS_ERROR_OPERATION_FAILED;
1080         }
1081
1082         tts_core_notify_state_changed(client, TTS_STATE_READY);
1083
1084         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1085         return TTS_ERROR_NONE;
1086 }
1087
1088 int tts_core_unprepare(tts_client_s* client)
1089 {
1090         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1091
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;
1097         }
1098
1099         int ret = -1;
1100         if (false == tts_core_check_screen_reader(client)) {
1101                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Do not request finalize. Handled by screen reader");
1102
1103                 ret = tts_ipc_stop_listening(uid);
1104                 if (0 != ret) {
1105                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to remove match : %s", tts_core_covert_error_code(ret));
1106                 }
1107         } else {
1108                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Request finalize");
1109
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)) {
1114                                 break;
1115                         }
1116                 }
1117
1118                 if (TTS_ERROR_NONE == ret) {
1119                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_finalize");
1120                 }
1121         }
1122
1123         return TTS_ERROR_NONE;
1124 }
1125
1126 int tts_core_reprepare()
1127 {
1128         GList* clients = tts_client_get_client_list();
1129         RETVM_IF(NULL == clients, TTS_ERROR_OPERATION_FAILED, "[ERROR] Fail to get client list");
1130
1131         GList *iter = NULL;
1132         if (g_list_length(clients) > 0) {
1133                 iter = g_list_first(clients);
1134
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);
1139                         }
1140
1141                         iter = g_list_next(iter);
1142                 }
1143         }
1144
1145         g_list_free(clients);
1146         __run_client_reprepare_thread();
1147
1148         return TTS_ERROR_NONE;
1149 }
1150
1151 int tts_core_foreach_supported_voices(tts_client_s* client, const char* engine_id, tts_supported_voice_cb callback, void* user_data)
1152 {
1153         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1154
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);
1159
1160         if (0 != ret) {
1161                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get voice list");
1162                 return TTS_ERROR_OPERATION_FAILED;
1163         }
1164
1165         return TTS_ERROR_NONE;
1166 }
1167
1168 int tts_core_handle_service_reset()
1169 {
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");
1172
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");
1179                         } else {
1180                                 tts_core_notify_error_async(client, TTS_ERROR_SERVICE_RESET, -1, "Daemon Reset");
1181                         }
1182
1183                         iter = g_list_next(iter);
1184                 }
1185         }
1186
1187         g_list_free(client_list);
1188
1189         SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset");
1190         tts_core_reprepare();
1191
1192         return TTS_ERROR_NONE;
1193 }
1194
1195 int tts_core_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id)
1196 {
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.");
1199
1200         tts_client_set_repeat_text(client, text);
1201
1202         if (NULL != g_language) {
1203                 free(g_language);
1204         }
1205
1206         g_language = (NULL == language ? NULL : strdup(language));
1207         g_voice_type = voice_type;
1208         g_speed = speed;
1209
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);
1212 }
1213
1214 int tts_core_play(tts_client_s* client)
1215 {
1216         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1217
1218         return __request_play(client);
1219 }
1220
1221 int tts_core_stop(tts_client_s* client)
1222 {
1223         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1224
1225         unsigned int uid = tts_client_get_uid(client);
1226         int ret = -1;
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)) {
1231                         break;
1232                 }
1233         }
1234
1235         if (TTS_ERROR_NONE != ret) {
1236                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1237                 return ret;
1238         }
1239
1240         return tts_core_notify_state_changed(client, TTS_STATE_READY);
1241 }
1242
1243 int tts_core_pause(tts_client_s* client)
1244 {
1245         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1246
1247         unsigned int uid = tts_client_get_uid(client);
1248         int ret = -1;
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)) {
1253                         break;
1254                 }
1255         }
1256
1257         if (TTS_ERROR_NONE != ret) {
1258                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1259                 return ret;
1260         }
1261
1262         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_pause");
1263         return tts_core_notify_state_changed(client, TTS_STATE_PAUSED);
1264 }
1265
1266 int tts_core_repeat(tts_client_s* client, char** text_repeat, int* utt_id)
1267 {
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.");
1270
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;
1275         }
1276
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.");
1281                 free(repeat_text);
1282                 return ret;
1283         }
1284
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.");
1289                 free(repeat_text);
1290                 return ret;
1291         }
1292
1293         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] text to repeat(%s), utt_id(%d)", repeat_text, new_utt_id);
1294
1295         *utt_id = new_utt_id;
1296         *text_repeat = repeat_text;
1297         return TTS_ERROR_NONE;
1298 }
1299
1300 int tts_core_add_pcm(tts_client_s* client, int event, const void* data, unsigned int data_size, int audio_type, int rate)
1301 {
1302         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1303
1304         unsigned int uid = tts_client_get_uid(client);
1305         int ret = -1;
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)) {
1310                         break;
1311                 }
1312         }
1313
1314         if (TTS_ERROR_NONE != ret) {
1315                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1316                 return ret;
1317         }
1318
1319         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_add_pcm");
1320         return TTS_ERROR_NONE;
1321 }
1322
1323 int tts_core_play_pcm(tts_client_s* client)
1324 {
1325         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1326
1327         unsigned int uid = tts_client_get_uid(client);
1328         int ret = -1;
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)) {
1333                         break;
1334                 }
1335         }
1336
1337         if (TTS_ERROR_NONE != ret) {
1338                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1339                 return ret;
1340         }
1341
1342         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_play_pcm");
1343         return tts_core_notify_state_changed(client, TTS_STATE_PLAYING);
1344 }
1345
1346 int tts_core_stop_pcm(tts_client_s* client)
1347 {
1348         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1349
1350         unsigned int uid = tts_client_get_uid(client);
1351         int ret = -1;
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)) {
1356                         break;
1357                 }
1358         }
1359
1360         if (TTS_ERROR_NONE != ret) {
1361                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1362                 return ret;
1363         }
1364
1365         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_stop_pcm");
1366         return tts_core_notify_state_changed(client, TTS_STATE_READY);
1367 }
1368
1369 int tts_core_set_private_data(tts_client_s* client, const char* key, const char* data)
1370 {
1371         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1372
1373         unsigned int uid = tts_client_get_uid(client);
1374         int ret = -1;
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)) {
1379                         break;
1380                 }
1381         }
1382
1383         if (TTS_ERROR_NONE != ret) {
1384                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1385                 return ret;
1386         }
1387
1388         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_set_private_data");
1389         return TTS_ERROR_NONE;
1390 }
1391
1392 int tts_core_get_private_data(tts_client_s* client, const char* key, char** data)
1393 {
1394         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1395
1396         unsigned int uid = tts_client_get_uid(client);
1397         int ret = -1;
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)) {
1402                         break;
1403                 }
1404         }
1405
1406         if (TTS_ERROR_NONE != ret) {
1407                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1408                 return ret;
1409         }
1410
1411         if (0 == strncmp(*data, "NULL", strlen(*data))) {
1412                 free(*data);
1413                 *data = NULL;
1414         }
1415
1416         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_get_private_data");
1417         return TTS_ERROR_NONE;
1418 }
1419
1420 int tts_core_get_service_state(tts_client_s* client, tts_service_state_e* service_state)
1421 {
1422         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1423
1424         unsigned int uid = tts_client_get_uid(client);
1425         int ret = -1;
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)) {
1430                         break;
1431                 }
1432         }
1433
1434         if (TTS_ERROR_NONE != ret) {
1435                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1436                 return ret;
1437         }
1438
1439         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_core_get_service_state");
1440         return TTS_ERROR_NONE;
1441 }