Fix the data type for uid
[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
16 #include <app_manager.h>
17 #include <dlog.h>
18 #include <package-manager.h>
19
20 #include "tts_internal.h"
21 #include "tts_defs.h"
22 #include "tts_core.h"
23 #include "tts_ipc.h"
24
25 /* Static variables */
26 static volatile bool g_is_thread_canceled = false;
27
28 static char* g_engine_name = NULL;
29 static int g_engine_update_status = 0;
30
31 static Ecore_Thread* g_reprepare_thread = NULL;
32
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;
37
38 static char* g_language = NULL;
39 static int g_voice_type = -1;
40 static int g_speed = -1;
41
42
43 /* Static functions */
44 // TODO: make tts_util? or tts_log?
45 static const char* __convert_state(tts_state_e state)
46 {
47         switch (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";
52         }
53
54         return "Invalid state";
55 }
56
57 static char* __get_engine_appid(int mode) {
58         if (NULL == g_engine_name) {
59                 return NULL;
60         }
61
62         char* appid = (char*)calloc(256, sizeof(char));
63         if (NULL == appid) {
64                 return NULL;
65         }
66
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);
75         } else {
76                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] mode is not valid. mode(%d)", mode);
77                 free(appid);
78                 return NULL;
79         }
80
81         return appid;
82 }
83
84 static int __update_engine_name()
85 {
86         if (g_engine_name) {
87                 free(g_engine_name);
88                 g_engine_name = NULL;
89         }
90
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;
95         }
96
97         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Engine name(%s)", g_engine_name);
98         return TTS_ERROR_NONE;
99 }
100
101 static inline void __client_error_cb(tts_client_s* client, int utt_id, tts_error_e reason)
102 {
103         tts_error_cb callback = tts_client_get_error_cb(client);
104         void* data = tts_client_get_error_user_data(client);
105
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);
111         } else {
112                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(error)");
113         }
114 }
115
116 static inline void __client_state_changed_cb(tts_client_s* client, tts_state_e before_state, tts_state_e current_state)
117 {
118         tts_state_changed_cb callback = tts_client_get_state_changed_cb(client);
119         void* data = tts_client_get_state_changed_user_data(client);
120
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);
126         } else {
127                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(state_changed)");
128         }
129 }
130
131 static Eina_Bool __notify_error_timer_cb(void *data)
132 {
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);
137         } else {
138                 __client_error_cb(client, client->utt_id, client->reason);
139                 client->notify_error_timer = NULL;
140         }
141
142         return EINA_FALSE;
143 }
144
145 static Eina_Bool __notify_state_timer_cb(void *data)
146 {
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);
151         } else {
152                 __client_state_changed_cb(client, client->before_state, client->current_state);
153                 client->notify_state_timer = NULL;
154         }
155
156         return EINA_FALSE;
157 }
158
159 static bool __is_engine_installed(const char* appid)
160 {
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);
165                 return false;
166         } else {
167                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] There is tts engine (%s)", appid);
168         }
169
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);
173
174         return true;
175 }
176
177 static bool __is_engine_launched(tts_mode_e mode)
178 {
179         char* appid = __get_engine_appid(mode);
180         if (NULL == appid) {
181                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine app ID");
182                 return false;
183         }
184
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);
188                 free(appid);
189                 return false;
190         }
191
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);
197                 free(appid);
198                 return false;
199         }
200
201         free(appid);
202         SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is %s running. is_installed(%d)", (is_running) ? "" : " not", is_installed);
203         return is_running;
204 }
205
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)
207 {
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);
210
211         if (NULL == g_engine_name) {
212                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] engine name is NULL");
213                 return 0;
214         }
215
216         if (0 != strncmp(g_engine_name, pkgname, strlen(g_engine_name))) {
217                 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] this is not tts engine");
218                 return 0;
219         }
220
221         if (NULL == key) {
222                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] key is NULL");
223                 return 0;
224         }
225
226         if (0 == strncmp(key, "start", strlen(key))) {
227                 if (NULL != g_pkgmgr_status) {
228                         free(g_pkgmgr_status);
229                         g_pkgmgr_status = NULL;
230                 }
231
232                 if (val) {
233                         g_pkgmgr_status = strdup(val);
234                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status. key(%s), status(%s)", key, g_pkgmgr_status);
235
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;
239                         }
240                 }
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;
246
247                                 free(g_pkgmgr_status);
248                                 g_pkgmgr_status = NULL;
249                         }
250                 }
251         }
252
253         return 0;
254 }
255
256 static void __create_pkgmgr_thread(void* data, Ecore_Thread* thread)
257 {
258         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] create pkgmgr thread");
259
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");
265                         break;
266                 }
267
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");
271                         break;
272                 }
273
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");
277                 } else {
278                         int ret = pkgmgr_client_set_status_type(g_pkgmgr, PKGMGR_CLIENT_STATUS_INSTALL | PKGMGR_CLIENT_STATUS_UNINSTALL | PKGMGR_CLIENT_STATUS_UPGRADE);
279                         if (0 == ret) {
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);
283                                         g_pkgmgr = NULL;
284                                 } else {
285                                         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Succeed to register pkgmgr cb");
286                                         break;
287                                 }
288                         } else {
289                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set status type on pkgmgr, ret(%d)", ret);
290                                 pkgmgr_client_free(g_pkgmgr);
291                                 g_pkgmgr = NULL;
292                         }
293                 }
294
295                 usleep(10000);
296         }
297         pthread_mutex_unlock(&g_pkgmgr_mutex);
298
299         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] create pkgmgr end");
300 }
301
302 static void __finish_pkgmgr_thread(void* data, Ecore_Thread* thread)
303 {
304         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] Finish pkgmgr thread");
305         g_is_thread_canceled = false;
306         g_pkgmgr_thread = NULL;
307 }
308
309 static void __cancel_pkgmgr_thread(void* data, Ecore_Thread* thread)
310 {
311         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] Cancel pkgmgr thread");
312         g_is_thread_canceled = false;
313         g_pkgmgr_thread = NULL;
314 }
315
316 static void __pkgmgr_thread(void* data)
317 {
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);
322         }
323
324         return;
325 }
326
327 static void __start_reprepare_thread(void* data, Ecore_Thread* thread)
328 {
329         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] start reprepare thread. engine update status(%d)", g_engine_update_status);
330
331         int cnt = 0;
332         while (!g_engine_update_status && cnt < 20) {
333                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] wait for starting update");
334
335                 usleep(50000);
336                 cnt++;
337
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");
342                         return;
343                 }
344         }
345
346         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] update status(%d)", g_engine_update_status);
347
348         while (g_engine_update_status && (NULL != g_pkgmgr)) {
349                 usleep(200000);
350
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");
355                         return;
356                 }
357         }
358
359         SLOG(LOG_INFO, TAG_TTSC, "[INFO] finish updating. request to prepare");
360
361         return;
362 }
363
364 static void __end_reprepare_thread(void* data, Ecore_Thread* thread)
365 {
366         SLOG(LOG_INFO, TAG_TTSC, "[INFO] end reprepare thread");
367
368         GList* clients = tts_client_get_client_list();
369         if (NULL == clients) {
370                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get client list");
371                 return;
372         }
373
374         GList *iter = NULL;
375         if (g_list_length(clients) > 0) {
376                 iter = g_list_first(clients);
377
378                 while (NULL != iter) {
379                         tts_client_s* client = iter->data;
380                         if (NULL != client) {
381                                 tts_core_prepare(client);
382                         }
383
384                         iter = g_list_next(iter);
385                 }
386         }
387
388         g_list_free(clients);
389         g_reprepare_thread = NULL;
390 }
391
392 static void __cancel_reprepare_thread(void* data, Ecore_Thread* thread)
393 {
394         SLOG(LOG_INFO, TAG_TTSC, "[INFO] cancel reprepare thread");
395         g_reprepare_thread = NULL;
396 }
397
398 static inline void __run_client_reprepare_thread()
399 {
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);
403         } else {
404                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Reprepare thread is already running");
405         }
406 }
407
408 static int __send_hello_msg(tts_client_s* client)
409 {
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;
414         }
415
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;
419         }
420
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);
423
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;
434                 }
435         }
436
437         if (0 != tts_ipc_request_hello(uid)) {
438                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request hello !!"); //LCOV_EXCL_LINE
439         } else {
440                 SLOG(LOG_INFO, TAG_TTSC, "@@@ Send Hello");
441         }
442
443         return TTS_ERROR_NONE;
444 }
445
446 static Eina_Bool __prepare_cb(void *data)
447 {
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.");
452                 return EINA_FALSE;
453         }
454
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;
459                 return EINA_FALSE;
460         }
461
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");
465
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);
468
469                 client->hello_timer = NULL;
470                 return EINA_FALSE;
471         }
472
473         return EINA_TRUE;
474 }
475
476 static Eina_Bool __prepare_first_cb(void *data)
477 {
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.");
483                 return EINA_FALSE;
484         }
485
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;
490         } else {
491                 /* Set retry timer callback */
492                 client->prepare_count = 0;
493                 client->hello_timer = ecore_timer_add(0.5, __prepare_cb, data);
494         }
495
496         return EINA_FALSE;
497 }
498
499 static Eina_Bool __prepare_sync_cb(tts_client_s* client)
500 {
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);
504
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();
510                         return EINA_FALSE;
511                 }
512         }
513         // TODO: make function duplicated block
514         unsigned int uid = tts_client_get_uid(client);
515         if (0 != tts_ipc_request_hello_sync(uid)) {
516                 return EINA_TRUE;
517         }
518
519         SLOG(LOG_INFO, TAG_TTSC, "@@@ Connect daemon");
520
521         // TODO: make function duplicated block
522         /* do request initialize */
523         int ret = -1;
524         bool credential_needed = false;
525
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);
530
531                 return EINA_FALSE;
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));
534                 return EINA_TRUE;
535         } else {
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");
539         }
540         // TODO: make function duplicated block
541
542         tts_ipc_request_set_mode(uid, tts_client_get_mode(client));
543
544         tts_core_notify_state_changed(client, TTS_STATE_READY);
545
546         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
547         return EINA_FALSE;
548 }
549
550 static void __engine_changed_cb(keynode_t* key, void* data)
551 {
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");
555         }
556
557         return;
558 }
559
560 static bool __supported_voice_cb(const char* engine_id, const char* language, int type, void* user_data)
561 {
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);
566                 return false;
567         }
568
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);
572
573         if (NULL == callback) {
574                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get callback.");
575                 return false;
576         }
577
578         return callback(tts_client_get_handle(client), language, type, data);
579 }
580
581 static bool __is_screen_reader_turned_on()
582 {
583         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Update screen reader state");
584
585         int screen_reader = 0;
586         int ret = vconf_get_bool(TTS_ACCESSIBILITY_KEY, &screen_reader);
587         if (0 != ret) {
588                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
589                 return false;
590         }
591
592         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Current screen reader status(%d)", screen_reader);
593         return (bool)screen_reader;
594 }
595
596 static inline bool __handle_dbus_request_result(tts_client_s* client, tts_error_e ret, bool* is_prepared)
597 {
598         if (TTS_ERROR_NONE == ret) {
599                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success the dbus request");
600                 return false;
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)) {
604                         *is_prepared = true;
605                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
606                 }
607         } else if (TTS_ERROR_TIMED_OUT != ret) {
608                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", tts_core_covert_error_code(ret));
609                 return false;
610         } else {
611                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry play : %s", tts_core_covert_error_code(ret));
612                 usleep(10000);
613         }
614
615         return true;
616 }
617
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)
619 {
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;
625         }
626
627         // TODO: If use cpp, remove dupliceated code using command class pattern
628         unsigned int uid = tts_client_get_uid(client);
629         int ret = -1;
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)) {
634                         break;
635                 }
636         }
637
638         if (TTS_ERROR_NONE != ret) {
639                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
640                 return ret;
641         }
642
643         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_add_text");
644         *utt_id = new_utt_id;
645         return TTS_ERROR_NONE;
646 }
647
648 static inline int __request_play(tts_client_s* client)
649 {
650         unsigned int uid = tts_client_get_uid(client);
651         int ret = -1;
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)) {
656                         break;
657                 }
658         }
659
660         if (TTS_ERROR_NONE != ret) {
661                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
662                 return ret;
663         }
664
665         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_play");
666         return tts_core_notify_state_changed(client, TTS_STATE_PLAYING);
667 }
668
669 int tts_core_initialize()
670 {
671         ecore_main_loop_thread_safe_call_async(__pkgmgr_thread, NULL);
672
673         if (0 != __update_engine_name()) {
674                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
675         }
676
677         /* Register vconfkey callback to detect engine change */
678         vconf_notify_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb, NULL);
679
680         return TTS_ERROR_NONE;
681 }
682
683 int tts_core_deinitialize()
684 {
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.
689         }
690
691         if (NULL != g_pkgmgr_thread) {
692                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Cancel pkgmgr thread");
693                 g_is_thread_canceled = true;
694         }
695
696         if (NULL != g_language) {
697                 free(g_language);
698                 g_language = NULL;
699         }
700
701         if (NULL != g_engine_name) {
702                 free(g_engine_name);
703                 g_engine_name = NULL;
704         }
705
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);
710                 g_pkgmgr = NULL;
711         }
712
713         if (NULL != g_pkgmgr_status) {
714                 free(g_pkgmgr_status);
715                 g_pkgmgr_status = NULL;
716         }
717         pthread_mutex_unlock(&g_pkgmgr_mutex);
718
719         /* Unregister vconfkey callback */
720         vconf_ignore_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb);
721
722         return TTS_ERROR_NONE;
723 }
724
725 int tts_core_notify_state_changed(tts_client_s* client, tts_state_e current_state)
726 {
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;
730         }
731
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;
736         }
737
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);
741
742         return TTS_ERROR_NONE;
743 }
744
745 int tts_core_notify_state_changed_async(tts_client_s* client, tts_state_e current_state)
746 {
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;
750         }
751
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;
756         }
757
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);
762         }
763
764         uintptr_t uid = tts_client_get_uid(client);
765         client->notify_state_timer = ecore_timer_add(0, __notify_state_timer_cb, (void*)uid);
766
767         return TTS_ERROR_NONE;
768 }
769
770 int tts_core_notify_utt_started(tts_client_s* client, int utt_id)
771 {
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;
775         }
776
777         client->utt_id = utt_id;
778         SLOG(LOG_DEBUG, TAG_TTSC, "Utterance started data : utt_id(%d)", client->utt_id);
779
780         tts_utterance_started_cb callback = tts_client_get_utterance_started_cb(client);
781         void* data = tts_client_get_utterance_started_user_data(client);
782
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);
788         } else {
789                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(utt_started)");
790         }
791
792         return TTS_ERROR_NONE;
793 }
794
795 int tts_core_notify_utt_completeted(tts_client_s* client, int utt_id)
796 {
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;
800         }
801
802         client->utt_id = utt_id;
803         SLOG(LOG_DEBUG, TAG_TTSC, "Utterance completed data : utt_id(%d)", utt_id);
804
805         tts_utterance_completed_cb callback = tts_client_get_utterance_completed_cb(client);
806         void* data = tts_client_get_utterance_completed_user_data(client);
807
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);
813         } else {
814                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(utt_completed)");
815         }
816
817         return TTS_ERROR_NONE;
818 }
819
820 int tts_core_notify_error_async(tts_client_s* client, tts_error_e reason, int utt_id, const char* err_msg)
821 {
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;
825         }
826
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);
831
832         SLOG(LOG_DEBUG, TAG_TTSC, "Notify error asynchronously");
833         if (NULL != client->notify_error_timer) {
834                 ecore_timer_del(client->notify_error_timer);
835         }
836
837         uintptr_t uid = tts_client_get_uid(client);
838         client->notify_error_timer = ecore_timer_add(0, __notify_error_timer_cb, (void*)uid);
839
840         return TTS_ERROR_NONE;
841 }
842
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)
844 {
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;
848         }
849
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);
852
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);
855
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);
861         } else {
862                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(default_voice_changed)");
863         }
864
865         return TTS_ERROR_NONE;
866 }
867
868 int tts_core_notify_engine_changed(tts_client_s* client, const char* engine_id, const char* language, int voice_type, bool need_credential)
869 {
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;
873         }
874
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);
877
878         tts_engine_changed_cb callback = tts_client_get_engine_changed_cb(client);
879         void* data = tts_client_get_engine_changed_user_data(client);
880
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);
886         } else {
887                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(engine_changed)");
888         }
889
890         return TTS_ERROR_NONE;
891 }
892
893 int tts_core_notify_screen_reader_changed(tts_client_s* client, bool value)
894 {
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;
898         }
899
900         SLOG(LOG_DEBUG, TAG_TTSC, "Screen reader is changed. Current status(%d)", value);
901
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);
904
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);
910         } else {
911                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(screen_reader_changed)");
912         }
913
914         return TTS_ERROR_NONE;
915 }
916
917 bool tts_core_is_valid_text(const char* text)
918 {
919         if (NULL == text) {
920                 return false;
921         }
922
923         /* check valid utf8 */
924         DBusError err;
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);
930                 return false;
931         }
932
933         if (false == valid) {
934                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Text is invalid - '%s'", text);
935                 return false;
936         }
937
938         if (strlen(text) <= 0) {
939                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is invalid.");
940                 return false;
941         }
942
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");
947                 return false;
948         }
949
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));
953                 return false;
954         }
955
956         return true;
957 }
958
959 bool tts_core_check_screen_reader(tts_client_s* client)
960 {
961         if (false == tts_client_is_valid_client(client)) {
962                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] client is not valid");
963                 return false;
964         }
965
966         tts_mode_e mode = tts_client_get_mode(client);
967         if (TTS_MODE_SCREEN_READER == mode && false == __is_screen_reader_turned_on()) {
968                 return false;
969         }
970
971         return true;
972 }
973
974 const char* tts_core_covert_error_code(tts_error_e err)
975 {
976         switch (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";
992         default:
993                 return "Invalid error code";
994         }
995         return NULL;
996 }
997
998 int tts_core_receive_hello(unsigned int uid, int ret, int credential_needed)
999 {
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;
1004         }
1005
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;
1010         }
1011
1012         if (client->hello_timer) {
1013                 ecore_timer_del(client->hello_timer);
1014                 client->hello_timer = NULL;
1015         }
1016
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);
1020
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);
1027                 }
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;
1031         }
1032
1033         tts_ipc_request_set_mode(uid, tts_client_get_mode(client));
1034
1035         tts_core_notify_state_changed_async(client, TTS_STATE_READY);
1036
1037         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1038         return TTS_ERROR_NONE;
1039 }
1040
1041 const char* tts_core_get_engine_name()
1042 {
1043         return g_engine_name;
1044 }
1045
1046 int tts_core_prepare(tts_client_s* client)
1047 {
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;
1051         }
1052
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;
1056         }
1057
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");
1061
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();
1066         } else {
1067                 LOGD("Client is already trying to prepare");
1068         }
1069
1070         return TTS_ERROR_NONE;
1071 }
1072
1073 int tts_core_prepare_sync(tts_client_s* client)
1074 {
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;
1078         }
1079
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));
1081         int cnt = 0;
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;
1086                 }
1087
1088                 if (EINA_FALSE == __prepare_sync_cb(client)) {
1089                         break;
1090                 }
1091
1092                 cnt++;
1093         }
1094
1095         if (TTS_CONNECTION_RETRY_COUNT == cnt) {
1096                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connect daemon");
1097                 return TTS_ERROR_OPERATION_FAILED;
1098         }
1099
1100         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1101         return TTS_ERROR_NONE;
1102 }
1103
1104 int tts_core_unprepare(tts_client_s* client)
1105 {
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;
1109         }
1110
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;
1116         }
1117
1118         int ret = -1;
1119         if (false == tts_core_check_screen_reader(client)) {
1120                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Do not request finalize. Handled by screen reader");
1121
1122                 ret = tts_ipc_stop_listening(uid);
1123                 if (0 != ret) {
1124                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to remove match : %s", tts_core_covert_error_code(ret));
1125                 }
1126         } else {
1127                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Request finalize");
1128
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)) {
1133                                 break;
1134                         }
1135                 }
1136
1137                 if (TTS_ERROR_NONE == ret) {
1138                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_finalize");
1139                 }
1140         }
1141
1142         return TTS_ERROR_NONE;
1143 }
1144
1145 int tts_core_reprepare()
1146 {
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;
1151         }
1152
1153         GList *iter = NULL;
1154         if (g_list_length(clients) > 0) {
1155                 iter = g_list_first(clients);
1156
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);
1161                         }
1162
1163                         iter = g_list_next(iter);
1164                 }
1165         }
1166
1167         g_list_free(clients);
1168         __run_client_reprepare_thread();
1169
1170         return TTS_ERROR_NONE;
1171 }
1172
1173 int tts_core_foreach_supported_voices(tts_client_s* client, const char* engine_id, tts_supported_voice_cb callback, void* user_data)
1174 {
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;
1178         }
1179
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);
1184
1185         if (0 != ret) {
1186                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get voice list");
1187                 return TTS_ERROR_OPERATION_FAILED;
1188         }
1189
1190         return TTS_ERROR_NONE;
1191 }
1192
1193 int tts_core_handle_service_reset()
1194 {
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;
1199         }
1200
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");
1207                         } else {
1208                                 tts_core_notify_error_async(client, TTS_ERROR_SERVICE_RESET, -1, "Daemon Reset");
1209                         }
1210
1211                         iter = g_list_next(iter);
1212                 }
1213         }
1214
1215         g_list_free(client_list);
1216
1217         SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset");
1218         tts_core_reprepare();
1219
1220         return TTS_ERROR_NONE;
1221 }
1222
1223 int tts_core_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id)
1224 {
1225         if (NULL == text || NULL == utt_id) {
1226                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Parameter is invalid.");
1227                 return TTS_ERROR_INVALID_PARAMETER;
1228         }
1229
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;
1233         }
1234
1235         tts_client_set_repeat_text(client, text);
1236
1237         if (NULL != g_language) {
1238                 free(g_language);
1239         }
1240
1241         g_language = (NULL == language ? NULL : strdup(language));
1242         g_voice_type = voice_type;
1243         g_speed = speed;
1244
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);
1247 }
1248
1249 int tts_core_play(tts_client_s* client)
1250 {
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;
1254         }
1255
1256         return __request_play(client);
1257 }
1258
1259 int tts_core_stop(tts_client_s* client)
1260 {
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;
1264         }
1265
1266         unsigned int uid = tts_client_get_uid(client);
1267         int ret = 0;
1268         int count = 0;
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)) {
1273                         break;
1274                 }
1275
1276                 count++;
1277         }
1278
1279         if (TTS_ERROR_NONE != ret) {
1280                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1281                 return ret;
1282         }
1283
1284         return tts_core_notify_state_changed(client, TTS_STATE_READY);
1285 }
1286
1287 int tts_core_pause(tts_client_s* client)
1288 {
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;
1292         }
1293
1294         unsigned int uid = tts_client_get_uid(client);
1295         int ret = -1;
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)) {
1300                         break;
1301                 }
1302         }
1303
1304         if (TTS_ERROR_NONE != ret) {
1305                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1306                 return ret;
1307         }
1308
1309         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_pause");
1310         return tts_core_notify_state_changed(client, TTS_STATE_PAUSED);
1311 }
1312
1313 int tts_core_repeat(tts_client_s* client, char** text_repeat, int* utt_id)
1314 {
1315         if (NULL == text_repeat || NULL == utt_id) {
1316                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Parameter is invalid.");
1317                 return TTS_ERROR_INVALID_PARAMETER;
1318         }
1319
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;
1323         }
1324
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;
1329         }
1330
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.");
1335                 return ret;
1336         }
1337
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.");
1342                 return ret;
1343         }
1344
1345         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] text to repeat(%s), utt_id(%d)", repeat_text, new_utt_id);
1346
1347         *utt_id = new_utt_id;
1348         *text_repeat = strdup(repeat_text);
1349         return TTS_ERROR_NONE;
1350 }
1351
1352 int tts_core_add_pcm(tts_client_s* client, int event, const void* data, unsigned int data_size, int audio_type, int rate)
1353 {
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;
1357         }
1358
1359         unsigned int uid = tts_client_get_uid(client);
1360         int ret = -1;
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)) {
1365                         break;
1366                 }
1367         }
1368
1369         if (TTS_ERROR_NONE != ret) {
1370                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1371                 return ret;
1372         }
1373
1374         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_add_pcm");
1375         return TTS_ERROR_NONE;
1376 }
1377
1378 int tts_core_play_pcm(tts_client_s* client)
1379 {
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;
1383         }
1384
1385         unsigned int uid = tts_client_get_uid(client);
1386         int ret = -1;
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)) {
1391                         break;
1392                 }
1393         }
1394
1395         if (TTS_ERROR_NONE != ret) {
1396                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1397                 return ret;
1398         }
1399
1400         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_play_pcm");
1401         return tts_core_notify_state_changed(client, TTS_STATE_PLAYING);
1402 }
1403
1404 int tts_core_stop_pcm(tts_client_s* client)
1405 {
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;
1409         }
1410
1411         unsigned int uid = tts_client_get_uid(client);
1412         int ret = -1;
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)) {
1417                         break;
1418                 }
1419         }
1420
1421         if (TTS_ERROR_NONE != ret) {
1422                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1423                 return ret;
1424         }
1425
1426         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_stop_pcm");
1427         return tts_core_notify_state_changed(client, TTS_STATE_READY);
1428 }
1429
1430 int tts_core_set_private_data(tts_client_s* client, const char* key, const char* data)
1431 {
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;
1435         }
1436
1437         unsigned int uid = tts_client_get_uid(client);
1438         int ret = -1;
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)) {
1443                         break;
1444                 }
1445         }
1446
1447         if (TTS_ERROR_NONE != ret) {
1448                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1449                 return ret;
1450         }
1451
1452         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_set_private_data");
1453         return TTS_ERROR_NONE;
1454 }
1455
1456 int tts_core_get_private_data(tts_client_s* client, const char* key, char** data)
1457 {
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;
1461         }
1462
1463         unsigned int uid = tts_client_get_uid(client);
1464         int ret = -1;
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)) {
1469                         break;
1470                 }
1471         }
1472
1473         if (TTS_ERROR_NONE != ret) {
1474                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1475                 return ret;
1476         }
1477
1478         if (0 == strncmp(*data, "NULL", strlen(*data))) {
1479                 free(*data);
1480                 *data = NULL;
1481         }
1482
1483         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_get_private_data");
1484         return TTS_ERROR_NONE;
1485 }