Merge "Fix typo error" into tizen
[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) {
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         int uid = (intptr_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. (%d)", 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         int uid = (intptr_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. (%d)", 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         int uid = tts_client_get_uid(client);
422         SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", 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         int uid = (intptr_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         int uid = (intptr_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         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_core_notify_state_changed(client, TTS_STATE_READY);
543
544         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
545         return EINA_FALSE;
546 }
547
548 static void __engine_changed_cb(keynode_t* key, void* data)
549 {
550         SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine vconfkey is changed");
551         if (0 != __update_engine_name()) {
552                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
553         }
554
555         return;
556 }
557
558 static bool __supported_voice_cb(const char* engine_id, const char* language, int type, void* user_data)
559 {
560         int uid = (intptr_t)user_data;
561         tts_client_s* client = tts_client_get_by_uid(uid);
562         if (NULL == client) {
563                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Uid is not valid. (%d)", uid);
564                 return false;
565         }
566
567         /* call callback function */
568         tts_supported_voice_cb callback = tts_client_get_supported_voice_cb(client);
569         void* data = tts_client_get_supported_voice_user_data(client);
570
571         if (NULL == callback) {
572                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get callback.");
573                 return false;
574         }
575
576         return callback(tts_client_get_handle(client), language, type, data);
577 }
578
579 static bool __is_screen_reader_turned_on()
580 {
581         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Update screen reader state");
582
583         int screen_reader = 0;
584         int ret = vconf_get_bool(TTS_ACCESSIBILITY_KEY, &screen_reader);
585         if (0 != ret) {
586                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
587                 return false;
588         }
589
590         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Current screen reader status(%d)", screen_reader);
591         return (bool)screen_reader;
592 }
593
594 static inline bool __handle_dbus_request_result(tts_client_s* client, tts_error_e ret, bool* is_prepared)
595 {
596         if (TTS_ERROR_NONE == ret) {
597                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success the dbus request");
598                 return false;
599         } else if (TTS_ERROR_INVALID_PARAMETER == ret && false == *is_prepared) {
600                 tts_client_set_current_state(client, TTS_STATE_CREATED);
601                 if (0 == tts_core_prepare_sync(client)) {
602                         *is_prepared = true;
603                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
604                 }
605         } else if (TTS_ERROR_TIMED_OUT != ret) {
606                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", tts_core_covert_error_code(ret));
607                 return false;
608         } else {
609                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry play : %s", tts_core_covert_error_code(ret));
610                 usleep(10000);
611         }
612
613         return true;
614 }
615
616 static inline int __request_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id)
617 {
618         /* change default language value */
619         const char* convert_language = (NULL == language ? "default" : language);
620         int new_utt_id = tts_client_new_utterance_id(client);
621         if (0 > new_utt_id) {
622                 return TTS_ERROR_OPERATION_FAILED;
623         }
624
625         // TODO: If use cpp, remove dupliceated code using command class pattern
626         int uid = tts_client_get_uid(client);
627         int ret = -1;
628         bool is_prepared = false;
629         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
630                 ret = tts_ipc_request_add_text(uid, text, convert_language, voice_type, speed, new_utt_id, client->credential);
631                 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
632                         break;
633                 }
634         }
635
636         if (TTS_ERROR_NONE != ret) {
637                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
638                 return ret;
639         }
640
641         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_add_text");
642         *utt_id = new_utt_id;
643         return TTS_ERROR_NONE;
644 }
645
646 static inline int __request_play(tts_client_s* client)
647 {
648         int uid = tts_client_get_uid(client);
649         int ret = -1;
650         bool is_prepared = false;
651         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
652                 ret = tts_ipc_request_play(uid, client->credential);
653                 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
654                         break;
655                 }
656         }
657
658         if (TTS_ERROR_NONE != ret) {
659                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
660                 return ret;
661         }
662
663         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_play");
664         return tts_core_notify_state_changed(client, TTS_STATE_PLAYING);
665 }
666
667 int tts_core_initialize()
668 {
669         ecore_main_loop_thread_safe_call_async(__pkgmgr_thread, NULL);
670
671         if (0 != __update_engine_name()) {
672                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
673         }
674
675         /* Register vconfkey callback to detect engine change */
676         vconf_notify_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb, NULL);
677
678         return TTS_ERROR_NONE;
679 }
680
681 int tts_core_deinitialize()
682 {
683         if (NULL != g_reprepare_thread && EINA_FALSE == ecore_thread_check(g_reprepare_thread)) {
684                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Cancel reprepare thread");
685                 ecore_thread_cancel(g_reprepare_thread);
686         }
687
688         if (NULL != g_pkgmgr_thread) {
689                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Cancel pkgmgr thread");
690                 g_is_thread_canceled = true;
691         }
692
693         if (NULL != g_language) {
694                 free(g_language);
695                 g_language = NULL;
696         }
697
698         if (NULL != g_engine_name) {
699                 free(g_engine_name);
700                 g_engine_name = NULL;
701         }
702
703         pthread_mutex_lock(&g_pkgmgr_mutex);
704         if (NULL != g_pkgmgr) {
705                 pkgmgr_client_remove_listen_status(g_pkgmgr);
706                 pkgmgr_client_free(g_pkgmgr);
707                 g_pkgmgr = NULL;
708         }
709
710         if (NULL != g_pkgmgr_status) {
711                 free(g_pkgmgr_status);
712                 g_pkgmgr_status = NULL;
713         }
714         pthread_mutex_unlock(&g_pkgmgr_mutex);
715
716         /* Unregister vconfkey callback */
717         vconf_ignore_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb);
718
719         return TTS_ERROR_NONE;
720 }
721
722 int tts_core_notify_state_changed(tts_client_s* client, tts_state_e current_state)
723 {
724         if (false == tts_client_is_valid_client(client)) {
725                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is invalid.");
726                 return TTS_ERROR_INVALID_PARAMETER;
727         }
728
729         tts_state_e before_state = tts_client_get_current_state(client);
730         if (before_state == current_state) {
731                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] State is not changed. before(%s), current(%s)", __convert_state(before_state), __convert_state(current_state));
732                 return TTS_ERROR_NONE;
733         }
734
735         SLOG(LOG_DEBUG, TAG_TTSC, "State changed to (%s).", __convert_state(current_state));
736         tts_client_set_current_state(client, current_state);
737         __client_state_changed_cb(client, before_state, current_state);
738
739         return TTS_ERROR_NONE;
740 }
741
742 int tts_core_notify_state_changed_async(tts_client_s* client, tts_state_e current_state)
743 {
744         if (false == tts_client_is_valid_client(client)) {
745                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
746                 return TTS_ERROR_INVALID_PARAMETER;
747         }
748
749         tts_state_e before_state = tts_client_get_current_state(client);
750         if (before_state == current_state) {
751                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] State is not changed. before(%s), current(%s)", __convert_state(before_state), __convert_state(current_state));
752                 return TTS_ERROR_NONE;
753         }
754
755         SLOG(LOG_DEBUG, TAG_TTSC, "Notify state changed asynchronously");
756         tts_client_set_current_state(client, current_state);
757         if (NULL != client->notify_state_timer) {
758                 ecore_timer_del(client->notify_state_timer);
759         }
760
761         intptr_t uid = tts_client_get_uid(client);
762         client->notify_state_timer = ecore_timer_add(0, __notify_state_timer_cb, (void*)uid);
763
764         return TTS_ERROR_NONE;
765 }
766
767 int tts_core_notify_utt_started(tts_client_s* client, int utt_id)
768 {
769         if (false == tts_client_is_valid_client(client)) {
770                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
771                 return TTS_ERROR_INVALID_PARAMETER;
772         }
773
774         client->utt_id = utt_id;
775         SLOG(LOG_DEBUG, TAG_TTSC, "Utterance started data : utt_id(%d)", client->utt_id);
776
777         tts_utterance_started_cb callback = tts_client_get_utterance_started_cb(client);
778         void* data = tts_client_get_utterance_started_user_data(client);
779
780         if (NULL != callback) {
781                 SLOG(LOG_DEBUG, TAG_TTSC, "Notify utterance started");
782                 tts_client_use_callback(client);
783                 callback(tts_client_get_handle(client), client->utt_id, data);
784                 tts_client_not_use_callback(client);
785         } else {
786                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(utt_started)");
787         }
788
789         return TTS_ERROR_NONE;
790 }
791
792 int tts_core_notify_utt_completeted(tts_client_s* client, int utt_id)
793 {
794         if (false == tts_client_is_valid_client(client)) {
795                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
796                 return TTS_ERROR_INVALID_PARAMETER;
797         }
798
799         client->utt_id = utt_id;
800         SLOG(LOG_DEBUG, TAG_TTSC, "Utterance completed data : utt_id(%d)", utt_id);
801
802         tts_utterance_completed_cb callback = tts_client_get_utterance_completed_cb(client);
803         void* data = tts_client_get_utterance_completed_user_data(client);
804
805         if (NULL != callback) {
806                 SLOG(LOG_DEBUG, TAG_TTSC, "Notify utterance started");
807                 tts_client_use_callback(client);
808                 callback(tts_client_get_handle(client), utt_id, data);
809                 tts_client_not_use_callback(client);
810         } else {
811                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(utt_completed)");
812         }
813
814         return TTS_ERROR_NONE;
815 }
816
817 int tts_core_notify_error_async(tts_client_s* client, tts_error_e reason, int utt_id, const char* err_msg)
818 {
819         if (false == tts_client_is_valid_client(client)) {
820                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
821                 return TTS_ERROR_INVALID_PARAMETER;
822         }
823
824         SLOG(LOG_DEBUG, TAG_TTSC, "Error data : utt_id(%d) reason(%s)", utt_id, tts_core_covert_error_code(reason));
825         client->utt_id = utt_id;
826         client->reason = reason;
827         tts_client_set_error_message(client, err_msg);
828
829         SLOG(LOG_DEBUG, TAG_TTSC, "Notify error asynchronously");
830         if (NULL != client->notify_error_timer) {
831                 ecore_timer_del(client->notify_error_timer);
832         }
833
834         intptr_t uid = tts_client_get_uid(client);
835         client->notify_error_timer = ecore_timer_add(0, __notify_error_timer_cb, (void*)uid);
836
837         return TTS_ERROR_NONE;
838 }
839
840 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)
841 {
842         if (false == tts_client_is_valid_client(client)) {
843                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
844                 return TTS_ERROR_INVALID_PARAMETER;
845         }
846
847         SLOG(LOG_DEBUG, TAG_TTSC, "Default voice changed data : before_lang(%s), before_voice_type(%d), language(%s), voice_type(%d)",
848                         before_lang, before_voice_type, language, voice_type);
849
850         tts_default_voice_changed_cb callback = tts_client_get_default_voice_changed_cb(client);
851         void* data = tts_client_get_default_voice_changed_user_data(client);
852
853         if (NULL != callback) {
854                 SLOG(LOG_DEBUG, TAG_TTSC, "Notify default voice changed");
855                 tts_client_use_callback(client);
856                 callback(tts_client_get_handle(client), before_lang, before_voice_type, language, voice_type, data);
857                 tts_client_not_use_callback(client);
858         } else {
859                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(default_voice_changed)");
860         }
861
862         return TTS_ERROR_NONE;
863 }
864
865 int tts_core_notify_engine_changed(tts_client_s* client, const char* engine_id, const char* language, int voice_type, bool need_credential)
866 {
867         if (false == tts_client_is_valid_client(client)) {
868                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
869                 return TTS_ERROR_INVALID_PARAMETER;
870         }
871
872         SLOG(LOG_DEBUG, TAG_TTSC, "Engine changed data : engine_id(%s) language(%s), voicd_type(%d), need_credential(%d)",
873                         engine_id, language, voice_type, need_credential);
874
875         tts_engine_changed_cb callback = tts_client_get_engine_changed_cb(client);
876         void* data = tts_client_get_engine_changed_user_data(client);
877
878         if (NULL != callback) {
879                 SLOG(LOG_DEBUG, TAG_TTSC, "Notify engine changed");
880                 tts_client_use_callback(client);
881                 callback(tts_client_get_handle(client), engine_id, language, voice_type, need_credential, data);
882                 tts_client_not_use_callback(client);
883         } else {
884                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(engine_changed)");
885         }
886
887         return TTS_ERROR_NONE;
888 }
889
890 int tts_core_notify_screen_reader_changed(tts_client_s* client, bool value)
891 {
892         if (false == tts_client_is_valid_client(client)) {
893                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
894                 return TTS_ERROR_INVALID_PARAMETER;
895         }
896
897         SLOG(LOG_DEBUG, TAG_TTSC, "Screen reader is changed. Current status(%d)", value);
898
899         tts_screen_reader_changed_cb callback = tts_client_get_screen_reader_changed_cb(client);
900         void* data = tts_client_get_screen_reader_changed_user_data(client);
901
902         if (NULL != callback) {
903                 SLOG(LOG_DEBUG, TAG_TTSC, "Notify screen reader changed");
904                 tts_client_use_callback(client);
905                 callback(tts_client_get_handle(client), value, data);
906                 tts_client_not_use_callback(client);
907         } else {
908                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(screen_reader_changed)");
909         }
910
911         return TTS_ERROR_NONE;
912 }
913
914 bool tts_core_is_valid_text(const char* text)
915 {
916         if (NULL == text) {
917                 return false;
918         }
919
920         /* check valid utf8 */
921         DBusError err;
922         dbus_error_init(&err);
923         bool valid = dbus_validate_utf8(text, &err);
924         if (dbus_error_is_set(&err)) {
925                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Dbus Error(%s), text(%s)", err.message, text);
926                 dbus_error_free(&err);
927                 return false;
928         }
929
930         if (false == valid) {
931                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Text is invalid - '%s'", text);
932                 return false;
933         }
934
935         if (strlen(text) <= 0) {
936                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is invalid.");
937                 return false;
938         }
939
940         unsigned int max_text_size = 0;
941         /* check text size */
942         if (0 != tts_config_mgr_get_max_text_size(&max_text_size)) {
943                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get max text size");
944                 return false;
945         }
946
947         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] max_text_size is %d byte", max_text_size);
948         if (0 < max_text_size && max_text_size < strlen(text)) {
949                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is bigger than maximum test size. text_size(%zu byte)", strlen(text));
950                 return false;
951         }
952
953         return true;
954 }
955
956 bool tts_core_check_screen_reader(tts_client_s* client)
957 {
958         if (false == tts_client_is_valid_client(client)) {
959                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] client is not valid");
960                 return false;
961         }
962
963         tts_mode_e mode = tts_client_get_mode(client);
964         if (false == __is_screen_reader_turned_on() && TTS_MODE_SCREEN_READER == mode) {
965                 return false;
966         }
967
968         return true;
969 }
970
971 const char* tts_core_covert_error_code(tts_error_e err)
972 {
973         switch (err) {
974         case TTS_ERROR_NONE:                    return "TTS_ERROR_NONE";
975         case TTS_ERROR_OUT_OF_MEMORY:           return "TTS_ERROR_OUT_OF_MEMORY";
976         case TTS_ERROR_IO_ERROR:                return "TTS_ERROR_IO_ERROR";
977         case TTS_ERROR_INVALID_PARAMETER:       return "TTS_ERROR_INVALID_PARAMETER";
978         case TTS_ERROR_OUT_OF_NETWORK:          return "TTS_ERROR_OUT_OF_NETWORK";
979         case TTS_ERROR_TIMED_OUT:               return "TTS_ERROR_TIMED_OUT";
980         case TTS_ERROR_PERMISSION_DENIED:       return "TTS_ERROR_PERMISSION_DENIED";
981         case TTS_ERROR_NOT_SUPPORTED:           return "TTS_ERROR_NOT_SUPPORTED";
982         case TTS_ERROR_INVALID_STATE:           return "TTS_ERROR_INVALID_STATE";
983         case TTS_ERROR_INVALID_VOICE:           return "TTS_ERROR_INVALID_VOICE";
984         case TTS_ERROR_ENGINE_NOT_FOUND:        return "TTS_ERROR_ENGINE_NOT_FOUND";
985         case TTS_ERROR_OPERATION_FAILED:        return "TTS_ERROR_OPERATION_FAILED";
986         case TTS_ERROR_AUDIO_POLICY_BLOCKED:    return "TTS_ERROR_AUDIO_POLICY_BLOCKED";
987         case TTS_ERROR_NOT_SUPPORTED_FEATURE:   return "TTS_ERROR_NOT_SUPPORTED_FEATURE";
988         case TTS_ERROR_SERVICE_RESET:           return "TTS_ERROR_SERVICE_RESET";
989         default:
990                 return "Invalid error code";
991         }
992         return NULL;
993 }
994
995 int tts_core_receive_hello(int uid, int ret, int credential_needed)
996 {
997         tts_client_s* client = tts_client_get_by_uid(uid);
998         if (NULL == client) {
999                 SLOG(LOG_ERROR, TAG_TTSC, "Fail to get TTS client or ignore this uid(%d)", uid);
1000                 return TTS_ERROR_OPERATION_FAILED;
1001         }
1002
1003         tts_state_e current_state = tts_client_get_current_state(client);
1004         if (TTS_STATE_CREATED != current_state) {
1005                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts client is already READY");
1006                 return TTS_ERROR_NONE;
1007         }
1008
1009         if (client->hello_timer) {
1010                 ecore_timer_del(client->hello_timer);
1011                 client->hello_timer = NULL;
1012         }
1013
1014         if (TTS_ERROR_ENGINE_NOT_FOUND == ret || TTS_ERROR_PERMISSION_DENIED == ret) {
1015                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", tts_core_covert_error_code(ret));
1016                 tts_core_notify_error_async(client, ret, -1, NULL);
1017
1018                 return TTS_ERROR_OPERATION_FAILED;
1019         } else if (TTS_ERROR_ALREADY_INITIALIZED == ret) {
1020                 /* success to connect tts-daemon */
1021                 if (TTS_CREDENTIAL_NEEDED_ALREADY_INITIALIZED != credential_needed) {
1022                         client->credential_needed = credential_needed;
1023                         SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%d)", credential_needed);
1024                 }
1025         } else if (TTS_ERROR_NONE != ret) {
1026                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect : %s", tts_core_covert_error_code(ret));
1027                 return TTS_ERROR_OPERATION_FAILED;
1028         }
1029
1030         tts_core_notify_state_changed_async(client, TTS_STATE_READY);
1031
1032         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1033         return TTS_ERROR_NONE;
1034 }
1035
1036 const char* tts_core_get_engine_name()
1037 {
1038         return g_engine_name;
1039 }
1040
1041 int tts_core_prepare(tts_client_s* client)
1042 {
1043         if (false == tts_client_is_valid_client(client)) {
1044                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
1045                 return TTS_ERROR_INVALID_PARAMETER;
1046         }
1047
1048         if (false == tts_core_check_screen_reader(client)) {
1049                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is not available");
1050                 return TTS_ERROR_SCREEN_READER_OFF;
1051         }
1052
1053         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Start core_prepare. tts_h(%p), tts_client(%p)", tts_client_get_handle(client), client);
1054         if (NULL == client->hello_timer) {
1055                 SLOG(LOG_ERROR, TAG_TTSC, "Register timer for __prepare_first_cb");
1056
1057                 ecore_thread_main_loop_begin();
1058                 intptr_t uid = tts_client_get_uid(client);
1059                 client->hello_timer = ecore_timer_add(0.0, __prepare_first_cb, (void*)uid);
1060                 ecore_thread_main_loop_end();
1061         } else {
1062                 LOGD("Client is already trying to prepare");
1063         }
1064
1065         return TTS_ERROR_NONE;
1066 }
1067
1068 int tts_core_prepare_sync(tts_client_s* client)
1069 {
1070         if (false == tts_client_is_valid_client(client)) {
1071                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
1072                 return TTS_ERROR_INVALID_PARAMETER;
1073         }
1074
1075         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Start core_prepare_sync. tts_h(%p), tts_client(%p), uid(%d)", tts_client_get_handle(client), client, tts_client_get_uid(client));
1076         int cnt = 0;
1077         while (TTS_CONNECTION_RETRY_COUNT > cnt) {
1078                 if (false == tts_core_check_screen_reader(client)) {
1079                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is not available");
1080                         return TTS_ERROR_SCREEN_READER_OFF;
1081                 }
1082
1083                 if (EINA_FALSE == __prepare_sync_cb(client)) {
1084                         break;
1085                 }
1086
1087                 cnt++;
1088         }
1089
1090         if (TTS_CONNECTION_RETRY_COUNT == cnt) {
1091                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connect daemon");
1092                 return TTS_ERROR_OPERATION_FAILED;
1093         }
1094
1095         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1096         return TTS_ERROR_NONE;
1097 }
1098
1099 int tts_core_unprepare(tts_client_s* client)
1100 {
1101         if (false == tts_client_is_valid_client(client)) {
1102                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
1103                 return TTS_ERROR_INVALID_PARAMETER;
1104         }
1105
1106         int uid = tts_client_get_uid(client);
1107         SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", tts_client_get_handle(client), client, uid);
1108         if (client->hello_timer) {
1109                 ecore_timer_del(client->hello_timer);
1110                 client->hello_timer = NULL;
1111         }
1112
1113         int ret = -1;
1114         if (false == tts_core_check_screen_reader(client)) {
1115                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Do not request finalize. Handled by screen reader");
1116
1117                 ret = tts_ipc_stop_listening(uid);
1118                 if (0 != ret) {
1119                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to remove match : %s", tts_core_covert_error_code(ret));
1120                 }
1121         } else {
1122                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Request finalize");
1123
1124                 bool is_prepared = false;
1125                 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1126                         ret = tts_ipc_request_finalize(uid);
1127                         if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1128                                 break;
1129                         }
1130                 }
1131
1132                 if (TTS_ERROR_NONE == ret) {
1133                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_finalize");
1134                 }
1135         }
1136
1137         return TTS_ERROR_NONE;
1138 }
1139
1140 int tts_core_reprepare()
1141 {
1142         GList* clients = tts_client_get_client_list();
1143         if (NULL == clients) {
1144                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get client list");
1145                 return TTS_ERROR_OPERATION_FAILED;
1146         }
1147
1148         GList *iter = NULL;
1149         if (g_list_length(clients) > 0) {
1150                 iter = g_list_first(clients);
1151
1152                 while (NULL != iter) {
1153                         tts_client_s* client = iter->data;
1154                         if (true == tts_client_is_valid_client(client)) {
1155                                 tts_client_set_current_state(client, TTS_STATE_CREATED);
1156                         }
1157
1158                         iter = g_list_next(iter);
1159                 }
1160         }
1161
1162         g_list_free(clients);
1163         __run_client_reprepare_thread();
1164
1165         return TTS_ERROR_NONE;
1166 }
1167
1168 int tts_core_foreach_supported_voices(tts_client_s* client, const char* engine_id, tts_supported_voice_cb callback, void* user_data)
1169 {
1170         if (false == tts_client_is_valid_client(client)) {
1171                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] client is not valid");
1172                 return TTS_ERROR_INVALID_PARAMETER;
1173         }
1174
1175         tts_client_set_supported_voice_cb(client, callback, user_data);
1176         intptr_t uid = tts_client_get_uid(client);
1177         int ret = tts_config_mgr_get_voice_list(engine_id, __supported_voice_cb, (void*)uid);
1178         tts_client_set_supported_voice_cb(client, NULL, NULL);
1179
1180         if (0 != ret) {
1181                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get voice list");
1182                 return TTS_ERROR_OPERATION_FAILED;
1183         }
1184
1185         return TTS_ERROR_NONE;
1186 }
1187
1188 int tts_core_handle_service_reset()
1189 {
1190         GList* client_list = tts_client_get_client_list();
1191         if (NULL == client_list) {
1192                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get client list");
1193                 return TTS_ERROR_OPERATION_FAILED;
1194         }
1195
1196         if (g_list_length(client_list) > 0) {
1197                 GList *iter = g_list_first(client_list);
1198                 while (NULL != iter) {
1199                         tts_client_s *client = iter->data;
1200                         if (false == tts_client_is_valid_client(client)) {
1201                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid");
1202                         } else {
1203                                 tts_core_notify_error_async(client, TTS_ERROR_SERVICE_RESET, -1, "Daemon Reset");
1204                         }
1205
1206                         iter = g_list_next(iter);
1207                 }
1208         }
1209
1210         g_list_free(client_list);
1211
1212         SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset");
1213         tts_core_reprepare();
1214
1215         return TTS_ERROR_NONE;
1216 }
1217
1218 int tts_core_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id)
1219 {
1220         if (NULL == text || NULL == utt_id) {
1221                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Parameter is invalid.");
1222                 return TTS_ERROR_INVALID_PARAMETER;
1223         }
1224
1225         if (false == tts_client_is_valid_client(client)) {
1226                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1227                 return TTS_ERROR_INVALID_PARAMETER;
1228         }
1229
1230         tts_client_set_repeat_text(client, text);
1231
1232         if (NULL != g_language) {
1233                 free(g_language);
1234         }
1235
1236         g_language = (NULL == language ? NULL : strdup(language));
1237         g_voice_type = voice_type;
1238         g_speed = speed;
1239
1240         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);
1241         return __request_add_text(client, text, language, voice_type, speed, utt_id);
1242 }
1243
1244 int tts_core_play(tts_client_s* client)
1245 {
1246         if (false == tts_client_is_valid_client(client)) {
1247                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1248                 return TTS_ERROR_INVALID_PARAMETER;
1249         }
1250
1251         return __request_play(client);
1252 }
1253
1254 int tts_core_stop(tts_client_s* client)
1255 {
1256         if (false == tts_client_is_valid_client(client)) {
1257                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1258                 return TTS_ERROR_INVALID_PARAMETER;
1259         }
1260
1261         int uid = tts_client_get_uid(client);
1262         int ret = 0;
1263         int count = 0;
1264         bool is_prepared = false;
1265         while (TTS_RETRY_COUNT > count) {
1266                 ret = tts_ipc_request_stop(uid);
1267                 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1268                         break;
1269                 }
1270
1271                 count++;
1272         }
1273
1274         if (TTS_ERROR_NONE != ret) {
1275                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1276                 return ret;
1277         }
1278
1279         return tts_core_notify_state_changed(client, TTS_STATE_READY);
1280 }
1281
1282 int tts_core_pause(tts_client_s* client)
1283 {
1284         if (false == tts_client_is_valid_client(client)) {
1285                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1286                 return TTS_ERROR_INVALID_PARAMETER;
1287         }
1288
1289         int uid = tts_client_get_uid(client);
1290         int ret = -1;
1291         bool is_prepared = false;
1292         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1293                 ret = tts_ipc_request_pause(uid);
1294                 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1295                         break;
1296                 }
1297         }
1298
1299         if (TTS_ERROR_NONE != ret) {
1300                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1301                 return ret;
1302         }
1303
1304         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_pause");
1305         return tts_core_notify_state_changed(client, TTS_STATE_PAUSED);
1306 }
1307
1308 int tts_core_repeat(tts_client_s* client, char** text_repeat, int* utt_id)
1309 {
1310         if (NULL == text_repeat || NULL == utt_id) {
1311                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Parameter is invalid.");
1312                 return TTS_ERROR_INVALID_PARAMETER;
1313         }
1314
1315         if (false == tts_client_is_valid_client(client)) {
1316                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1317                 return TTS_ERROR_INVALID_PARAMETER;
1318         }
1319
1320         const char* repeat_text = tts_client_get_repeat_text(client);
1321         if (NULL == repeat_text) {
1322                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] There is no previous added texts. Please add texts");
1323                 return TTS_ERROR_OPERATION_FAILED;
1324         }
1325
1326         int new_utt_id = -1;
1327         int ret = __request_add_text(client, repeat_text, g_language, g_voice_type, g_speed, &new_utt_id);
1328         if (TTS_ERROR_NONE != ret) {
1329                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to add texts for repetition.");
1330                 return ret;
1331         }
1332
1333         /* Play added texts */
1334         ret = __request_play(client);
1335         if (TTS_ERROR_NONE != ret) {
1336                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to play texts for repetition.");
1337                 return ret;
1338         }
1339
1340         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] text to repeat(%s), utt_id(%d)", repeat_text, new_utt_id);
1341
1342         *utt_id = new_utt_id;
1343         *text_repeat = strdup(repeat_text);
1344         return TTS_ERROR_NONE;
1345 }
1346
1347 int tts_core_add_pcm(tts_client_s* client, int event, const void* data, unsigned int data_size, int audio_type, int rate)
1348 {
1349         if (false == tts_client_is_valid_client(client)) {
1350                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1351                 return TTS_ERROR_INVALID_PARAMETER;
1352         }
1353
1354         int uid = tts_client_get_uid(client);
1355         int ret = -1;
1356         bool is_prepared = false;
1357         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1358                 ret = tts_ipc_request_add_pcm(uid, event, data, data_size, audio_type, rate);
1359                 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1360                         break;
1361                 }
1362         }
1363
1364         if (TTS_ERROR_NONE != ret) {
1365                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1366                 return ret;
1367         }
1368
1369         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_add_pcm");
1370         return TTS_ERROR_NONE;
1371 }
1372
1373 int tts_core_play_pcm(tts_client_s* client)
1374 {
1375         if (false == tts_client_is_valid_client(client)) {
1376                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1377                 return TTS_ERROR_INVALID_PARAMETER;
1378         }
1379
1380         int uid = tts_client_get_uid(client);
1381         int ret = -1;
1382         bool is_prepared = false;
1383         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1384                 ret = tts_ipc_request_play_pcm(uid);
1385                 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1386                         break;
1387                 }
1388         }
1389
1390         if (TTS_ERROR_NONE != ret) {
1391                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1392                 return ret;
1393         }
1394
1395         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_play_pcm");
1396         return tts_core_notify_state_changed(client, TTS_STATE_PLAYING);
1397 }
1398
1399 int tts_core_stop_pcm(tts_client_s* client)
1400 {
1401         if (false == tts_client_is_valid_client(client)) {
1402                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1403                 return TTS_ERROR_INVALID_PARAMETER;
1404         }
1405
1406         int uid = tts_client_get_uid(client);
1407         int ret = -1;
1408         bool is_prepared = false;
1409         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1410                 ret = tts_ipc_request_stop_pcm(uid);
1411                 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1412                         break;
1413                 }
1414         }
1415
1416         if (TTS_ERROR_NONE != ret) {
1417                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1418                 return ret;
1419         }
1420
1421         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_stop_pcm");
1422         return tts_core_notify_state_changed(client, TTS_STATE_READY);
1423 }
1424
1425 int tts_core_set_private_data(tts_client_s* client, const char* key, const char* data)
1426 {
1427         if (false == tts_client_is_valid_client(client)) {
1428                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1429                 return TTS_ERROR_INVALID_PARAMETER;
1430         }
1431
1432         int uid = tts_client_get_uid(client);
1433         int ret = -1;
1434         bool is_prepared = false;
1435         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1436                 ret = tts_ipc_request_set_private_data(uid, key, data);
1437                 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1438                         break;
1439                 }
1440         }
1441
1442         if (TTS_ERROR_NONE != ret) {
1443                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1444                 return ret;
1445         }
1446
1447         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_set_private_data");
1448         return TTS_ERROR_NONE;
1449 }
1450
1451 int tts_core_get_private_data(tts_client_s* client, const char* key, char** data)
1452 {
1453         if (false == tts_client_is_valid_client(client)) {
1454                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid.");
1455                 return TTS_ERROR_INVALID_PARAMETER;
1456         }
1457
1458         int uid = tts_client_get_uid(client);
1459         int ret = -1;
1460         bool is_prepared = false;
1461         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1462                 ret = tts_ipc_request_get_private_data(uid, key, data);
1463                 if (false == __handle_dbus_request_result(client, ret, &is_prepared)) {
1464                         break;
1465                 }
1466         }
1467
1468         if (TTS_ERROR_NONE != ret) {
1469                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1470                 return ret;
1471         }
1472
1473         if (0 == strncmp(*data, "NULL", strlen(*data))) {
1474                 free(*data);
1475                 *data = NULL;
1476         }
1477
1478         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_get_private_data");
1479         return TTS_ERROR_NONE;
1480 }