28d5daa9586532d0a58e9060dcac38d95c2b0b66
[platform/core/uifw/tts.git] / client / tts_core.c
1 /*
2 *  Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <string.h>
15 #include <stdatomic.h>
16
17 #include <app_manager.h>
18 #include <dlog.h>
19 #include <package-manager.h>
20
21 #include "tts_internal.h"
22 #include "tts_defs.h"
23 #include "tts_core.h"
24 #include "tts_ipc.h"
25 #include "tts_dlog.h"
26
27
28 static const int TTS_ERROR_FAIL_TO_SEND_HELLO = TIZEN_ERROR_TTS | 0xFF;
29
30
31 /* Static variables */
32 static atomic_bool g_is_thread_canceled = false;
33
34 static char* g_engine_name = NULL;
35 static int g_engine_update_status = 0;
36 static atomic_bool g_is_engine_name_changed = false;
37
38 static Ecore_Thread* g_reprepare_thread = NULL;
39 static Ecore_Idler *g_unset_app_context_cb_idler = NULL;
40
41 static char* g_pkgmgr_status = NULL;
42 static pkgmgr_client* g_pkgmgr = NULL;
43 static Ecore_Thread* g_pkgmgr_thread = NULL;
44 static pthread_mutex_t g_pkgmgr_mutex = PTHREAD_MUTEX_INITIALIZER;
45
46 static char* g_language = NULL;
47 static int g_voice_type = -1;
48 static int g_speed = -1;
49
50
51 /* Static functions */
52 // TODO: make tts_util? or tts_log?
53 static const char* __convert_state(tts_state_e state)
54 {
55         switch (state) {
56         case TTS_STATE_CREATED: return "Created";
57         case TTS_STATE_READY:   return "Ready";
58         case TTS_STATE_PLAYING: return "Playing";
59         case TTS_STATE_PAUSED:  return "Paused";
60         }
61
62         return "Invalid state";
63 }
64
65 static char* get_engine_appid() {
66         if (NULL == g_engine_name) {
67                 return NULL;
68         }
69
70         char* appid = (char*)calloc(TTS_ENGINE_APPID_LEN, sizeof(char));
71         if (NULL == appid) {
72                 return NULL;
73         }
74
75         snprintf(appid, TTS_ENGINE_APPID_LEN, "%s", g_engine_name);
76         return appid;
77 }
78
79 static int __update_engine_name()
80 {
81         char* new_engine_name = vconf_get_str(TTS_ENGINE_DB_DEFAULT);
82         RETVM_IF(NULL == new_engine_name, TTS_ERROR_OPERATION_FAILED, "[ERROR] Fail to get engine name");
83
84         if (NULL != g_engine_name && 0 == strncmp(g_engine_name, new_engine_name, TTS_ENGINE_APPID_LEN)) {
85                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] engine name is same");
86                 free(new_engine_name);
87                 return TTS_ERROR_NONE;
88         }
89
90         free(g_engine_name);
91         g_engine_name = new_engine_name;
92         g_is_engine_name_changed = true;
93
94         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Engine name(%s)", g_engine_name);
95         return TTS_ERROR_NONE;
96 }
97
98 static inline void __client_error_cb(tts_client_s* client, int utt_id, tts_error_e reason)
99 {
100         tts_error_cb callback = tts_client_get_error_cb(client);
101         void* data = tts_client_get_error_user_data(client);
102
103         if (NULL != callback) {
104                 SLOG(LOG_DEBUG, TAG_TTSC, "Notify error");
105                 tts_client_use_callback(client);
106                 callback(tts_client_get_handle(client), utt_id, reason, data);
107                 tts_client_not_use_callback(client);
108         } else {
109                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(error)");
110         }
111 }
112
113 static inline void __client_state_changed_cb(tts_client_s* client, tts_state_e before_state, tts_state_e current_state)
114 {
115         tts_state_changed_cb callback = tts_client_get_state_changed_cb(client);
116         void* data = tts_client_get_state_changed_user_data(client);
117
118         if (NULL != callback) {
119                 SLOG(LOG_DEBUG, TAG_TTSC, "State changed data : before_state(%s) curret_state(%s)", __convert_state(before_state), __convert_state(current_state));
120                 tts_client_use_callback(client);
121                 callback(tts_client_get_handle(client), before_state, current_state, data);
122                 tts_client_not_use_callback(client);
123         } else {
124                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(state_changed)");
125         }
126 }
127
128 static Eina_Bool __notify_error_timer_cb(void *data)
129 {
130         unsigned int uid = (uintptr_t)data;
131         tts_client_s* client = tts_client_get_by_uid(uid);
132         RETVM_IF(NULL == client, EINA_FALSE, "[ERROR] uid(%u) is not valid.", uid);
133
134         __client_error_cb(client, client->utt_id, client->reason);
135         client->notify_error_timer = NULL;
136
137         return EINA_FALSE;
138 }
139
140 static bool __is_engine_installed(const char* appid)
141 {
142         app_info_h app_info = NULL;
143         int ret = app_manager_get_app_info(appid, &app_info);
144         if (APP_MANAGER_ERROR_NONE != ret || NULL == app_info) {
145                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] There is no tts engine (%s). ret(%d)", appid, ret);
146                 return false;
147         } else {
148                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] There is tts engine (%s)", appid);
149         }
150
151         ret = app_info_destroy(app_info);
152         if (APP_MANAGER_ERROR_NONE != ret)
153                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to destroy app_info. ret(%d)", ret);
154
155         return true;
156 }
157
158 static bool __is_engine_launched()
159 {
160         char* appid = get_engine_appid();
161         if (NULL == appid) {
162                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine app ID");
163                 return false;
164         }
165
166         bool is_installed = __is_engine_installed(appid);
167         if (false == is_installed) {
168                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] tts engine(%s) is not installed", appid);
169                 free(appid);
170                 return false;
171         }
172
173         bool is_running = false;
174         int ret = app_manager_is_running(appid, &is_running);
175         if (APP_MANAGER_ERROR_NONE != ret) {
176                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to check whether appid(%s) is running or not. ret(%d)", appid, ret);
177                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is installed(%d)", is_installed);
178                 free(appid);
179                 return false;
180         }
181
182         free(appid);
183         SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is %s running. is_installed(%d)", (is_running) ? "" : " not", is_installed);
184         return is_running;
185 }
186
187 //LCOV_EXCL_START
188 static int __pkgmgr_status_cb(uid_t target_uid, int req_id, const char *type, const char *pkgname, const char *key, const char *val, const void *pmsg, void *data)
189 {
190         // type (the type of the pkgname)
191         SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status cb is invoked. pkgname(%s), type(%s), key(%s), val(%s)", pkgname, type, key, val);
192
193         if (NULL == g_engine_name) {
194                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] engine name is NULL");
195                 return 0;
196         }
197
198         if (0 != strncmp(g_engine_name, pkgname, strlen(g_engine_name))) {
199                 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] this is not tts engine");
200                 return 0;
201         }
202
203         if (NULL == key) {
204                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] key is NULL");
205                 return 0;
206         }
207
208         if (0 == strncmp(key, "start", strlen(key))) {
209                 if (NULL != g_pkgmgr_status) {
210                         free(g_pkgmgr_status);
211                         g_pkgmgr_status = NULL;
212                 }
213
214                 if (val) {
215                         g_pkgmgr_status = strdup(val);
216                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status. key(%s), status(%s)", key, g_pkgmgr_status);
217
218                         if ((0 == strncmp(val, "update", strlen(val) || 0 == strncmp(val, "uninstall", strlen(val))))) {
219                                 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] start to install.");
220                                 g_engine_update_status = 1;
221                         }
222                 }
223         } else if (0 == strncmp(key, "end", strlen(key)) && val && 0 == strncmp(val, "ok", strlen(val))) {
224                 if (g_pkgmgr_status) {
225                         if (0 == strncmp(g_pkgmgr_status, "install", strlen(g_pkgmgr_status)) || 0 == strncmp(g_pkgmgr_status, "update", strlen(g_pkgmgr_status))) {
226                                 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] finish to install");
227                                 g_engine_update_status = 0;
228
229                                 free(g_pkgmgr_status);
230                                 g_pkgmgr_status = NULL;
231                         }
232                 }
233         }
234
235         return 0;
236 }
237 //LCOV_EXCL_STOP
238
239 static void __create_pkgmgr_thread(void* data, Ecore_Thread* thread)
240 {
241         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] create pkgmgr thread");
242
243         pthread_mutex_lock(&g_pkgmgr_mutex);
244         int time_delay = 10000;
245         int cnt = 0;
246         while (NULL == g_pkgmgr) {
247                 /* Checking the thread is canceled or not */
248                 if (g_is_thread_canceled) {
249                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] g_pkgmgr_thread is canceled. Exit");
250                         break;
251                 }
252
253                 /* Checking handle which can be destroyed on other thread */
254                 if (0 == tts_client_get_size()) {
255                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] All client is already destroyed");
256                         break;
257                 }
258
259                 g_pkgmgr = pkgmgr_client_new(PC_LISTENING);
260                 if (NULL == g_pkgmgr) {
261                         if (0 == cnt % 5) {
262                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create pkgmgr handle");
263                                 time_delay *= 2;
264                         }
265                 } else {
266                         int ret = pkgmgr_client_set_status_type(g_pkgmgr, PKGMGR_CLIENT_STATUS_INSTALL | PKGMGR_CLIENT_STATUS_UNINSTALL | PKGMGR_CLIENT_STATUS_UPGRADE);
267                         if (0 == ret) {
268                                 if (pkgmgr_client_listen_status(g_pkgmgr, __pkgmgr_status_cb, NULL) < 0) {
269                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to listen pkgmgr status. remove and recreate client");
270                                         pkgmgr_client_free(g_pkgmgr);
271                                         g_pkgmgr = NULL;
272                                         if (0 == cnt % 5)
273                                                 time_delay *= 2;
274                                 } else {
275                                         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Succeed to register pkgmgr cb");
276                                         break;
277                                 }
278                         } else {
279                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set status type on pkgmgr, ret(%d)", ret);
280                                 pkgmgr_client_free(g_pkgmgr);
281                                 g_pkgmgr = NULL;
282                                 if (0 == cnt % 5)
283                                         time_delay *= 2;
284                         }
285                 }
286
287                 usleep(time_delay);
288                 cnt++;
289         }
290         pthread_mutex_unlock(&g_pkgmgr_mutex);
291
292         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] create pkgmgr end");
293 }
294
295 static void __finish_pkgmgr_thread(void* data, Ecore_Thread* thread)
296 {
297         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] Finish pkgmgr thread");
298         g_is_thread_canceled = false;
299         g_pkgmgr_thread = NULL;
300 }
301
302 //LCOV_EXCL_START
303 static void __cancel_pkgmgr_thread(void* data, Ecore_Thread* thread)
304 {
305         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] Cancel pkgmgr thread");
306         g_is_thread_canceled = false;
307         g_pkgmgr_thread = NULL;
308 }
309 //LCOV_EXCL_STOP
310
311 static void __pkgmgr_thread(void* data)
312 {
313         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] call pkgmgr_thread");
314         if (NULL == g_pkgmgr_thread) {
315                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] ecore thread run: create_pkgmgr_thread");
316                 g_pkgmgr_thread = ecore_thread_run(__create_pkgmgr_thread, __finish_pkgmgr_thread, __cancel_pkgmgr_thread, NULL);
317         }
318
319         return;
320 }
321
322 //LCOV_EXCL_START
323 static void __start_reprepare_thread(void* data, Ecore_Thread* thread)
324 {
325         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] start reprepare thread. engine update status(%d)", g_engine_update_status);
326
327         if (0 == g_engine_update_status && g_is_engine_name_changed) {
328                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Reprepare by engine change");
329                 return;
330         }
331
332         int cnt = 0;
333         while (!g_engine_update_status && cnt < 20) {
334                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] wait for starting update");
335
336                 usleep(50000);
337                 cnt++;
338
339                 // TODO: fix way to exit thread safely
340                 /* Checking thread is canceled or not */
341                 if (ecore_thread_check(g_reprepare_thread)) {
342                         SLOG(LOG_WARN, TAG_TTSC, "[WARNING] client thread is canceled. Exit");
343                         return;
344                 }
345         }
346
347         SLOG(LOG_INFO, TAG_TTSC, "[DEBUG] update status(%d)", g_engine_update_status);
348
349         while (g_engine_update_status && (NULL != g_pkgmgr)) {
350                 usleep(200000);
351
352                 // TODO: fix way to exit thread safely
353                 /* Checking thread is canceled or not */
354                 if (ecore_thread_check(g_reprepare_thread)) {
355                         SLOG(LOG_WARN, TAG_TTSC, "[WARNING] client thread is canceled. Exit");
356                         return;
357                 }
358         }
359
360         SLOG(LOG_INFO, TAG_TTSC, "[INFO] finish updating. request to prepare");
361
362         return;
363 }
364 //LCOV_EXCL_STOP
365
366 static void __end_reprepare_thread(void* data, Ecore_Thread* thread)
367 {
368         SLOG(LOG_INFO, TAG_TTSC, "[INFO] end reprepare thread");
369
370         GList* clients = tts_client_get_client_list();
371         if (NULL == clients) {
372                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get client list");
373                 g_is_engine_name_changed = false;
374                 g_reprepare_thread = NULL;
375                 return;
376         }
377
378         GList *iter = NULL;
379         if (g_list_length(clients) > 0) {
380                 iter = g_list_first(clients);
381
382                 while (NULL != iter) {
383                         tts_client_s* client = iter->data;
384                         if (NULL != client) {
385                                 tts_core_prepare(client);
386                         }
387
388                         iter = g_list_next(iter);
389                 }
390         }
391
392         g_list_free(clients);
393         g_is_engine_name_changed = false;
394         g_reprepare_thread = NULL;
395 }
396
397 //LCOV_EXCL_START
398 static void __cancel_reprepare_thread(void* data, Ecore_Thread* thread)
399 {
400         SLOG(LOG_INFO, TAG_TTSC, "[INFO] cancel reprepare thread");
401         g_is_engine_name_changed = false;
402         g_reprepare_thread = NULL;
403 }
404 //LCOV_EXCL_STOP
405
406 static inline void __run_client_reprepare_thread()
407 {
408         if (NULL == g_reprepare_thread) {
409                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] ecore thread run: start_reprepare_thread");
410                 g_reprepare_thread = ecore_thread_run(__start_reprepare_thread, __end_reprepare_thread, __cancel_reprepare_thread, NULL);
411         } else {
412                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Reprepare thread is already running");
413         }
414 }
415
416 static int __send_hello_msg(tts_client_s* client)
417 {
418         tts_state_e current_state = tts_client_get_current_state(client);
419         if (TTS_STATE_READY == current_state) {
420                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] TTS client has been already connected to tts service"); //LCOV_EXCL_LINE
421                 return TTS_ERROR_INVALID_STATE;
422         }
423
424         if (false == tts_core_check_screen_reader(client)) {
425                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is not available");
426                 return TTS_ERROR_SCREEN_READER_OFF;
427         }
428
429         unsigned int uid = tts_client_get_uid(client);
430         tts_mode_e mode = tts_client_get_mode(client);
431         tts_playing_mode_e playing_mode = tts_client_get_playing_mode(client);
432         int registered_callback_mask = tts_client_get_registered_event_mask(client);
433         SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%u), mode(%d), playing_mode(%d)", tts_client_get_handle(client), client, uid, (int)mode, (int)playing_mode);
434
435         /* check service engine status */
436         bool is_launched = __is_engine_launched();
437         SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
438         if (false == is_launched) {
439                 /* If engine is NOT launched, check whether engine is updating or not */
440                 if (g_engine_update_status) {
441                         /* suyeon wait engine update */
442                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] cannot prepare due to engine update");
443                         __run_client_reprepare_thread();
444                         return TTS_ERROR_INVALID_STATE;
445                 }
446         }
447
448         if (0 != tts_ipc_request_hello(uid, mode, playing_mode, registered_callback_mask)) {
449                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request hello !!"); //LCOV_EXCL_LINE
450         } else {
451                 SLOG(LOG_INFO, TAG_TTSC, "@@@ Send Hello");
452         }
453
454         return TTS_ERROR_NONE;
455 }
456
457 static Eina_Bool __prepare_cb(void *data)
458 {
459         unsigned int uid = (uintptr_t)data;
460         tts_client_s* client = tts_client_get_by_uid(uid);
461         RETVM_IF(NULL == client, EINA_FALSE, "[ERROR] uid(%u) is not valid.", uid);
462
463         int ret = __send_hello_msg(client);
464         if (ret != TTS_ERROR_NONE) {
465                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to send hello message"); //LCOV_EXCL_LINE
466                 client->hello_timer = NULL;
467                 return EINA_FALSE;
468         }
469
470         client->prepare_count++;
471         if (TTS_HELLO_RETRY_COUNT == client->prepare_count) {
472                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare, retry count reaches the limit");
473
474                 bool is_launched = __is_engine_launched();
475                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
476
477                 client->hello_timer = NULL;
478
479                 tts_core_notify_error_async(client, TTS_ERROR_TIMED_OUT, -1, "[ERROR] Fail to prepare. Please call tts_prepare() again.");
480
481                 return EINA_FALSE;
482         }
483
484         return EINA_TRUE;
485 }
486
487 static Eina_Bool __prepare_first_cb(void *data)
488 {
489         /* send first hello message */
490         unsigned int uid = (uintptr_t)data;
491         tts_client_s* client = tts_client_get_by_uid(uid);
492         RETVM_IF(NULL == client, EINA_FALSE, "[ERROR] uid(%u) is not valid.", uid);
493
494         int ret = __send_hello_msg(client);
495         if (ret != TTS_ERROR_NONE) {
496                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to sent hello message"); //LCOV_EXCL_LINE
497                 client->hello_timer = NULL;
498         } else {
499                 /* Set retry timer callback */
500                 client->prepare_count = 0;
501                 client->hello_timer = ecore_timer_add(0.5, __prepare_cb, data);
502         }
503
504         return EINA_FALSE;
505 }
506
507 static int __prepare_sync_cb(tts_client_s* client, tts_service_state_e* service_state)
508 {
509         // TODO: make function duplicated block
510         bool is_launched = __is_engine_launched();
511         SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
512
513         if (false == is_launched) {
514                 /* check whether engine is updating or not */
515                 if (g_engine_update_status) {
516                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Cannot prepare due to engine update.");
517                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client automatically tries to reprepare asynchrnously.");
518                         __run_client_reprepare_thread();
519                         return TTS_ERROR_OPERATION_FAILED;
520                 }
521         }
522
523         // TODO: make function duplicated block
524         unsigned int uid = tts_client_get_uid(client);
525         if (TTS_ERROR_NONE != tts_ipc_request_hello_sync(uid)) {
526                 return TTS_ERROR_FAIL_TO_SEND_HELLO;
527         }
528
529         SLOG(LOG_INFO, TAG_TTSC, "@@@ Connect daemon");
530
531         // TODO: make function duplicated block
532         /* do request initialize */
533         bool credential_needed = false;
534         tts_service_state_e tmp_service_state = TTS_SERVICE_STATE_NONE;
535         tts_mode_e mode = tts_client_get_mode(client);
536         tts_playing_mode_e playing_mode = tts_client_get_playing_mode(client);
537         int registered_callback_mask = tts_client_get_registered_event_mask(client);
538         int ret = tts_ipc_request_initialize(uid, mode, playing_mode, registered_callback_mask, &tmp_service_state, &credential_needed);
539         if (TTS_ERROR_ENGINE_NOT_FOUND == ret || TTS_ERROR_PERMISSION_DENIED == ret) {
540                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize. ret(%d/%s)", ret, get_error_message(ret));
541                 tts_core_notify_error_async(client, ret, -1, NULL);
542
543                 return ret;
544         } else if (TTS_ERROR_NONE != ret) {
545                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect. ret(%d/%s)", ret, get_error_message(ret));
546                 return TTS_ERROR_FAIL_TO_SEND_HELLO;
547         } else {
548                 /* success to connect tts-daemon */
549                 client->credential_needed = credential_needed;
550                 SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%s)", credential_needed ? "need" : "no need");
551         }
552         // TODO: make function duplicated block
553
554         *service_state = tmp_service_state;
555         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
556         return TTS_ERROR_NONE;
557 }
558
559 static void __engine_changed_cb(keynode_t* key, void* data)
560 {
561         SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine vconfkey is changed");
562         if (0 != __update_engine_name()) {
563                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
564         }
565
566         return;
567 }
568
569 static bool __supported_voice_cb(const char* engine_id, const char* language, int type, void* user_data)
570 {
571         unsigned int uid = (uintptr_t)user_data;
572         tts_client_s* client = tts_client_get_by_uid(uid);
573         RETVM_IF(NULL == client, false, "[ERROR] uid(%u) is not valid.", uid);
574
575         /* call callback function */
576         tts_supported_voice_cb callback = tts_client_get_supported_voice_cb(client);
577         void* data = tts_client_get_supported_voice_user_data(client);
578
579         if (NULL == callback) {
580                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get callback.");
581                 return false;
582         }
583
584         return callback(tts_client_get_handle(client), language, type, data);
585 }
586
587 static bool __is_screen_reader_turned_on()
588 {
589         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Update screen reader state");
590
591         int screen_reader = 0;
592         int ret = vconf_get_bool(TTS_ACCESSIBILITY_KEY, &screen_reader);
593         if (0 != ret) {
594                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
595                 return false;
596         }
597
598         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Current screen reader status(%d)", screen_reader);
599         return (bool)screen_reader;
600 }
601
602 static inline bool __is_ipc_retry_needed(tts_client_s* client, tts_error_e ret)
603 {
604         if (TTS_ERROR_NONE == ret) {
605                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success the IPC request");
606                 return false;
607         }
608
609         if (TTS_ERROR_TIMED_OUT == ret) {
610                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] IPC is failed. Try again. ret(%d/%s)", ret, get_error_message(ret));
611                 usleep(10000);
612                 return true;
613         }
614
615         if (tts_client_is_reprepared(client)) {
616                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Prepare was already tried.");
617                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] IPC request is failed. ret(%d/%s)", ret, get_error_message(ret));
618                 return false;
619         }
620
621         if (TTS_ERROR_INVALID_PARAMETER == ret || TTS_ERROR_IO_ERROR == ret) {
622                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] IPC is failed by unregistered client or network error. ret(%d/%s)", ret, get_error_message(ret));
623                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Try to prepare again");
624                 tts_client_set_current_state(client, TTS_STATE_CREATED);
625                 tts_core_prepare_sync(client);
626                 tts_client_set_reprepared(client, true);
627                 return true;
628         }
629
630         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] IPC request is failed. ret(%d/%s)", ret, get_error_message(ret));
631         return false;
632 }
633
634 static inline int __request_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id)
635 {
636         /* change default language value */
637         const char* convert_language = (NULL == language ? "default" : language);
638         int new_utt_id = tts_client_new_utterance_id(client);
639         if (0 > new_utt_id) {
640                 return TTS_ERROR_OPERATION_FAILED;
641         }
642
643         // TODO: If use cpp, remove dupliceated code using command class pattern
644         unsigned int uid = tts_client_get_uid(client);
645         int ret = -1;
646         tts_client_set_reprepared(client, false);
647         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
648                 ret = tts_ipc_request_add_text(uid, text, convert_language, voice_type, speed, new_utt_id, client->credential);
649                 if (false == __is_ipc_retry_needed(client, ret)) {
650                         break;
651                 }
652         }
653
654         if (TTS_ERROR_NONE != ret) {
655                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
656                 return ret;
657         }
658
659         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_add_text");
660         *utt_id = new_utt_id;
661         return TTS_ERROR_NONE;
662 }
663
664 static inline int __request_play(tts_client_s* client)
665 {
666         unsigned int uid = tts_client_get_uid(client);
667         int ret = -1;
668         tts_client_set_reprepared(client, false);
669         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
670                 ret = tts_ipc_request_play(uid, client->credential);
671                 if (false == __is_ipc_retry_needed(client, ret)) {
672                         break;
673                 }
674         }
675
676         if (TTS_ERROR_NONE != ret) {
677                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request. ret(%d)", ret);
678                 return ret;
679         }
680
681         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Success tts_dbus_request_play");
682         return tts_core_notify_state_changed(client, TTS_STATE_PLAYING);
683 }
684
685 int tts_core_initialize()
686 {
687         ecore_main_loop_thread_safe_call_async(__pkgmgr_thread, NULL);
688
689         if (0 != __update_engine_name()) {
690                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine name into core module");
691         }
692         g_is_engine_name_changed = false;
693
694         /* Register vconfkey callback to detect engine change */
695         vconf_notify_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb, NULL);
696
697         return TTS_ERROR_NONE;
698 }
699
700 int tts_core_deinitialize()
701 {
702         if (NULL != g_reprepare_thread && EINA_FALSE == ecore_thread_check(g_reprepare_thread)) {
703                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Cancel reprepare thread");
704                 ecore_thread_cancel(g_reprepare_thread);
705                 ecore_thread_wait(g_reprepare_thread, 0.5);             // wait g_reprepare_thread is terminated.
706         }
707
708         if (NULL != g_unset_app_context_cb_idler) {
709                 ecore_idler_del(g_unset_app_context_cb_idler);
710                 g_unset_app_context_cb_idler = NULL;
711         }
712
713         if (NULL != g_pkgmgr_thread) {
714                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Cancel pkgmgr thread");
715                 g_is_thread_canceled = true;
716         }
717
718         if (NULL != g_language) {
719                 free(g_language);
720                 g_language = NULL;
721         }
722
723         if (NULL != g_engine_name) {
724                 free(g_engine_name);
725                 g_engine_name = NULL;
726         }
727
728         pthread_mutex_lock(&g_pkgmgr_mutex);
729         if (NULL != g_pkgmgr) {
730                 pkgmgr_client_remove_listen_status(g_pkgmgr);
731                 pkgmgr_client_free(g_pkgmgr);
732                 g_pkgmgr = NULL;
733         }
734
735         if (NULL != g_pkgmgr_status) {
736                 free(g_pkgmgr_status);
737                 g_pkgmgr_status = NULL;
738         }
739         pthread_mutex_unlock(&g_pkgmgr_mutex);
740
741         /* Unregister vconfkey callback */
742         vconf_ignore_key_changed(TTS_ENGINE_DB_DEFAULT, __engine_changed_cb);
743
744         return TTS_ERROR_NONE;
745 }
746
747 int tts_core_notify_state_changed(tts_client_s* client, tts_state_e current_state)
748 {
749         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
750
751         tts_state_e before_state = tts_client_get_current_state(client);
752         if (before_state == current_state) {
753                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] State is not changed. before(%s), current(%s)", __convert_state(before_state), __convert_state(current_state));
754                 return TTS_ERROR_NONE;
755         }
756
757         SLOG(LOG_DEBUG, TAG_TTSC, "State changed to (%s).", __convert_state(current_state));
758         tts_client_set_current_state(client, current_state);
759         __client_state_changed_cb(client, before_state, current_state);
760
761         return TTS_ERROR_NONE;
762 }
763
764 int tts_core_notify_utt_started(tts_client_s* client, int utt_id)
765 {
766         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
767
768         client->utt_id = utt_id;
769         SLOG(LOG_DEBUG, TAG_TTSC, "Utterance started data : utt_id(%d)", client->utt_id);
770
771         tts_utterance_started_cb callback = tts_client_get_utterance_started_cb(client);
772         void* data = tts_client_get_utterance_started_user_data(client);
773
774         if (NULL != callback) {
775                 SLOG(LOG_DEBUG, TAG_TTSC, "Notify utterance started");
776                 tts_client_use_callback(client);
777                 callback(tts_client_get_handle(client), client->utt_id, data);
778                 tts_client_not_use_callback(client);
779         } else {
780                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(utt_started)");
781         }
782
783         return TTS_ERROR_NONE;
784 }
785
786 int tts_core_notify_utt_completeted(tts_client_s* client, int utt_id)
787 {
788         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
789
790         client->utt_id = utt_id;
791         SLOG(LOG_DEBUG, TAG_TTSC, "Utterance completed data : utt_id(%d)", utt_id);
792
793         tts_utterance_completed_cb callback = tts_client_get_utterance_completed_cb(client);
794         void* data = tts_client_get_utterance_completed_user_data(client);
795
796         if (NULL != callback) {
797                 SLOG(LOG_DEBUG, TAG_TTSC, "Notify utterance started");
798                 tts_client_use_callback(client);
799                 callback(tts_client_get_handle(client), utt_id, data);
800                 tts_client_not_use_callback(client);
801         } else {
802                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(utt_completed)");
803         }
804
805         return TTS_ERROR_NONE;
806 }
807
808 int tts_core_notify_error_async(tts_client_s* client, tts_error_e reason, int utt_id, const char* err_msg)
809 {
810         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
811
812         SLOG(LOG_DEBUG, TAG_TTSC, "Error data : utt_id(%d) reason(%s)", utt_id, tts_core_covert_error_code(reason));
813         client->utt_id = utt_id;
814         client->reason = reason;
815         tts_client_set_error_message(client, err_msg);
816
817         SLOG(LOG_DEBUG, TAG_TTSC, "Notify error asynchronously");
818         if (NULL != client->notify_error_timer) {
819                 ecore_timer_del(client->notify_error_timer);
820         }
821
822         uintptr_t uid = tts_client_get_uid(client);
823         client->notify_error_timer = ecore_timer_add(0, __notify_error_timer_cb, (void*)uid);
824
825         return TTS_ERROR_NONE;
826 }
827
828 //LCOV_EXCL_START
829 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)
830 {
831         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
832
833         SLOG(LOG_DEBUG, TAG_TTSC, "Default voice changed data : before_lang(%s), before_voice_type(%d), language(%s), voice_type(%d)",
834                         before_lang, before_voice_type, language, voice_type);
835
836         tts_default_voice_changed_cb callback = tts_client_get_default_voice_changed_cb(client);
837         void* data = tts_client_get_default_voice_changed_user_data(client);
838
839         if (NULL != callback) {
840                 SLOG(LOG_DEBUG, TAG_TTSC, "Notify default voice changed");
841                 tts_client_use_callback(client);
842                 callback(tts_client_get_handle(client), before_lang, before_voice_type, language, voice_type, data);
843                 tts_client_not_use_callback(client);
844         } else {
845                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(default_voice_changed)");
846         }
847
848         return TTS_ERROR_NONE;
849 }
850
851 int tts_core_notify_engine_changed(tts_client_s* client, const char* engine_id, const char* language, int voice_type, bool need_credential)
852 {
853         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
854
855         SLOG(LOG_DEBUG, TAG_TTSC, "Engine changed data : engine_id(%s) language(%s), voicd_type(%d), need_credential(%d)",
856                         engine_id, language, voice_type, need_credential);
857
858         tts_engine_changed_cb callback = tts_client_get_engine_changed_cb(client);
859         void* data = tts_client_get_engine_changed_user_data(client);
860
861         if (NULL != callback) {
862                 SLOG(LOG_DEBUG, TAG_TTSC, "Notify engine changed");
863                 tts_client_use_callback(client);
864                 callback(tts_client_get_handle(client), engine_id, language, voice_type, need_credential, data);
865                 tts_client_not_use_callback(client);
866         } else {
867                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(engine_changed)");
868         }
869
870         return TTS_ERROR_NONE;
871 }
872 //LCOV_EXCL_STOP
873
874 int tts_core_notify_screen_reader_changed(tts_client_s* client, bool value)
875 {
876         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
877
878         SLOG(LOG_DEBUG, TAG_TTSC, "Screen reader is changed. Current status(%d)", value);
879
880         tts_screen_reader_changed_cb callback = tts_client_get_screen_reader_changed_cb(client);
881         void* data = tts_client_get_screen_reader_changed_user_data(client);
882
883         if (NULL != callback) {
884                 SLOG(LOG_DEBUG, TAG_TTSC, "Notify screen reader changed");
885                 tts_client_use_callback(client);
886                 callback(tts_client_get_handle(client), value, data);
887                 tts_client_not_use_callback(client);
888         } else {
889                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(screen_reader_changed)");
890         }
891
892         return TTS_ERROR_NONE;
893 }
894
895 int tts_core_notify_service_state_changed(tts_client_s* client, tts_service_state_e before_state, tts_service_state_e current_state)
896 {
897         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
898
899         SLOG(LOG_DEBUG, TAG_TTSC, "Service state changed from (%d) to (%d).", before_state, current_state);
900
901         tts_service_state_changed_cb callback = tts_client_get_service_state_changed_cb(client);
902         void* data = tts_client_get_service_state_changed_user_data(client);
903
904         if (NULL != callback) {
905                 SLOG(LOG_DEBUG, TAG_TTSC, "Notify service state changed");
906                 tts_client_set_current_service_state(client, current_state);
907
908                 tts_client_use_callback(client);
909                 callback(tts_client_get_handle(client), before_state, current_state, data);
910                 tts_client_not_use_callback(client);
911         } else {
912                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback(service_state_changed)");
913         }
914
915         return TTS_ERROR_NONE;
916 }
917
918 bool tts_core_is_valid_text(const char* text)
919 {
920         if (NULL == text) {
921                 return false;
922         }
923
924         /* check valid utf8 */
925         DBusError err;
926         dbus_error_init(&err);
927         bool valid = dbus_validate_utf8(text, &err);
928         if (dbus_error_is_set(&err)) {
929                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Dbus Error(%s), text(%s)", err.message, text);
930                 dbus_error_free(&err);
931                 return false;
932         }
933
934         if (false == valid) {
935                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Text is invalid - '%s'", text);
936                 return false;
937         }
938
939         if (strlen(text) <= 0) {
940                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is invalid.");
941                 return false;
942         }
943
944         unsigned int max_text_size = 0;
945         /* check text size */
946         if (0 != tts_config_mgr_get_max_text_size(&max_text_size)) {
947                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get max text size");
948                 return false;
949         }
950
951         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] max_text_size is %d byte", max_text_size);
952         if (0 < max_text_size && max_text_size < strlen(text)) {
953                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is bigger than maximum test size. text_size(%zu byte)", strlen(text));
954                 return false;
955         }
956
957         return true;
958 }
959
960 bool tts_core_check_screen_reader(tts_client_s* client)
961 {
962         RETVM_IF(false == tts_client_is_valid_client(client), false, "[ERROR] Client is invalid.");
963
964         tts_mode_e mode = tts_client_get_mode(client);
965         if (TTS_MODE_SCREEN_READER == mode && false == __is_screen_reader_turned_on()) {
966                 return false;
967         }
968
969         return true;
970 }
971
972 bool tts_core_check_credential(tts_client_s* client)
973 {
974         RETVM_IF(false == tts_client_is_valid_client(client), false, "[ERROR] Client is invalid.");
975
976         if (true == client->credential_needed && NULL == tts_client_get_credential_key(client)) {
977                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Do not have app credential for this engine");
978                 return false;
979         }
980
981         return true;
982 }
983
984 //LCOV_EXCL_START
985 const char* tts_core_covert_error_code(tts_error_e err)
986 {
987         switch (err) {
988         case TTS_ERROR_NONE:                    return "TTS_ERROR_NONE";
989         case TTS_ERROR_OUT_OF_MEMORY:           return "TTS_ERROR_OUT_OF_MEMORY";
990         case TTS_ERROR_IO_ERROR:                return "TTS_ERROR_IO_ERROR";
991         case TTS_ERROR_INVALID_PARAMETER:       return "TTS_ERROR_INVALID_PARAMETER";
992         case TTS_ERROR_OUT_OF_NETWORK:          return "TTS_ERROR_OUT_OF_NETWORK";
993         case TTS_ERROR_TIMED_OUT:               return "TTS_ERROR_TIMED_OUT";
994         case TTS_ERROR_PERMISSION_DENIED:       return "TTS_ERROR_PERMISSION_DENIED";
995         case TTS_ERROR_NOT_SUPPORTED:           return "TTS_ERROR_NOT_SUPPORTED";
996         case TTS_ERROR_INVALID_STATE:           return "TTS_ERROR_INVALID_STATE";
997         case TTS_ERROR_INVALID_VOICE:           return "TTS_ERROR_INVALID_VOICE";
998         case TTS_ERROR_ENGINE_NOT_FOUND:        return "TTS_ERROR_ENGINE_NOT_FOUND";
999         case TTS_ERROR_OPERATION_FAILED:        return "TTS_ERROR_OPERATION_FAILED";
1000         case TTS_ERROR_AUDIO_POLICY_BLOCKED:    return "TTS_ERROR_AUDIO_POLICY_BLOCKED";
1001         case TTS_ERROR_NOT_SUPPORTED_FEATURE:   return "TTS_ERROR_NOT_SUPPORTED_FEATURE";
1002         case TTS_ERROR_SERVICE_RESET:           return "TTS_ERROR_SERVICE_RESET";
1003         case TTS_ERROR_SCREEN_READER_OFF:       return "TTS_ERROR_SCREEN_READER_OFF";
1004         default:
1005                 return "Invalid error code";
1006         }
1007         return NULL;
1008 }
1009 //LCOV_EXCL_STOP
1010
1011 int tts_core_receive_hello(unsigned int uid, int ret, tts_service_state_e service_state, int credential_needed)
1012 {
1013         tts_client_s* client = tts_client_get_by_uid(uid);
1014         RETVM_IF(NULL == client, TTS_ERROR_OPERATION_FAILED, "Fail to get TTS client or ignore this uid(%u)", uid);
1015
1016         tts_state_e current_state = tts_client_get_current_state(client);
1017         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_NONE, "[INFO] tts client is already READY");
1018
1019         if (client->hello_timer) {
1020                 ecore_timer_del(client->hello_timer);
1021                 client->hello_timer = NULL;
1022         }
1023
1024         if (TTS_ERROR_ENGINE_NOT_FOUND == ret || TTS_ERROR_PERMISSION_DENIED == ret) {
1025                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", tts_core_covert_error_code(ret));
1026                 tts_core_notify_error_async(client, ret, -1, NULL);
1027
1028                 return TTS_ERROR_OPERATION_FAILED;
1029         } else if (TTS_ERROR_ALREADY_INITIALIZED == ret) {
1030                 /* success to connect tts-daemon */
1031                 if (TTS_CREDENTIAL_NEEDED_ALREADY_INITIALIZED != credential_needed) {
1032                         client->credential_needed = credential_needed;
1033                         SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%d)", credential_needed);
1034                 }
1035         } else if (TTS_ERROR_NONE != ret) {
1036                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect : %s", tts_core_covert_error_code(ret));
1037                 return TTS_ERROR_OPERATION_FAILED;
1038         }
1039
1040         tts_client_set_service_out(client, false);
1041         tts_core_notify_state_changed(client, TTS_STATE_READY);
1042
1043         tts_service_state_e before_state = tts_client_get_current_service_state(client);
1044         tts_core_notify_service_state_changed(client, before_state, service_state);
1045
1046         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1047         return TTS_ERROR_NONE;
1048 }
1049
1050 int tts_core_prepare(tts_client_s* client)
1051 {
1052         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1053
1054         if (false == tts_core_check_screen_reader(client)) {
1055                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is not available");
1056                 return TTS_ERROR_SCREEN_READER_OFF;
1057         }
1058
1059         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Start core_prepare. tts_h(%p), tts_client(%p)", tts_client_get_handle(client), client);
1060         if (NULL == client->hello_timer) {
1061                 SLOG(LOG_ERROR, TAG_TTSC, "Register timer for __prepare_first_cb");
1062
1063                 ecore_thread_main_loop_begin();
1064                 uintptr_t uid = tts_client_get_uid(client);
1065                 client->hello_timer = ecore_timer_add(0.0, __prepare_first_cb, (void*)uid);
1066                 ecore_thread_main_loop_end();
1067         } else {
1068                 LOGD("Client is already trying to prepare");
1069         }
1070
1071         return TTS_ERROR_NONE;
1072 }
1073
1074 int tts_core_prepare_sync(tts_client_s* client)
1075 {
1076         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1077
1078         unsigned int uid = tts_client_get_uid(client);
1079         tts_service_state_e service_state = TTS_SERVICE_STATE_NONE;
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, uid);
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                 int ret = __prepare_sync_cb(client, &service_state);
1089                 if (TTS_ERROR_NONE == ret) {
1090                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Prepare succeeds. uid(%u)", uid);
1091                         break;
1092                 }
1093
1094                 if (TTS_ERROR_FAIL_TO_SEND_HELLO == ret) {
1095                         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Fail to send hello. Try again. uid(%u)", uid);
1096                 } else {
1097                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare. uid(%u), ret(%d/%s)", uid, ret, get_error_message(ret));
1098                         return ret;
1099                 }
1100
1101                 cnt++;
1102         }
1103
1104         if (TTS_CONNECTION_RETRY_COUNT == cnt) {
1105                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connect daemon");
1106                 return TTS_ERROR_OPERATION_FAILED;
1107         }
1108
1109         tts_client_set_service_out(client, false);
1110         tts_core_notify_state_changed(client, TTS_STATE_READY);
1111
1112         tts_service_state_e before_state = tts_client_get_current_service_state(client);
1113         tts_core_notify_service_state_changed(client, before_state, service_state);
1114
1115         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1116         return TTS_ERROR_NONE;
1117 }
1118
1119 int tts_core_unprepare(tts_client_s* client)
1120 {
1121         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1122
1123         unsigned int uid = tts_client_get_uid(client);
1124         SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%u)", tts_client_get_handle(client), client, uid);
1125         if (client->hello_timer) {
1126                 ecore_timer_del(client->hello_timer);
1127                 client->hello_timer = NULL;
1128         }
1129
1130         int ret = tts_ipc_stop_listening(uid);
1131         if (0 != ret) {
1132                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to remove match : %s", tts_core_covert_error_code(ret));
1133         }
1134
1135         if (tts_client_is_service_out(client)) {
1136                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Service is already out. Do not need to finalize");
1137                 tts_client_set_service_out(client, false);
1138                 return TTS_ERROR_NONE;
1139         }
1140
1141         if (false == tts_core_check_screen_reader(client)) {
1142                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Do not request finalize. Handled by screen reader");
1143         } else {
1144                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Request finalize");
1145
1146                 tts_client_set_reprepared(client, false);
1147                 for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1148                         ret = tts_ipc_request_finalize(uid);
1149                         if (false == __is_ipc_retry_needed(client, ret)) {
1150                                 break;
1151                         }
1152                 }
1153
1154                 if (TTS_ERROR_NONE == ret) {
1155                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_finalize");
1156                 }
1157         }
1158
1159         return TTS_ERROR_NONE;
1160 }
1161
1162 int tts_core_reprepare()
1163 {
1164         GList* clients = tts_client_get_client_list();
1165         RETVM_IF(NULL == clients, TTS_ERROR_OPERATION_FAILED, "[ERROR] Fail to get client list");
1166
1167         GList *iter = NULL;
1168         if (g_list_length(clients) > 0) {
1169                 iter = g_list_first(clients);
1170
1171                 while (NULL != iter) {
1172                         tts_client_s* client = iter->data;
1173                         if (true == tts_client_is_valid_client(client)) {
1174                                 tts_client_set_current_state(client, TTS_STATE_CREATED);
1175                         }
1176
1177                         iter = g_list_next(iter);
1178                 }
1179         }
1180
1181         g_list_free(clients);
1182         __run_client_reprepare_thread();
1183
1184         return TTS_ERROR_NONE;
1185 }
1186
1187 int tts_core_foreach_supported_voices(tts_client_s* client, const char* engine_id, tts_supported_voice_cb callback, void* user_data)
1188 {
1189         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1190
1191         tts_client_set_supported_voice_cb(client, callback, user_data);
1192         uintptr_t uid = tts_client_get_uid(client);
1193         int ret = tts_config_mgr_get_voice_list(engine_id, __supported_voice_cb, (void*)uid);
1194         tts_client_set_supported_voice_cb(client, NULL, NULL);
1195
1196         if (0 != ret) {
1197                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get voice list");
1198                 return TTS_ERROR_OPERATION_FAILED;
1199         }
1200
1201         return TTS_ERROR_NONE;
1202 }
1203
1204 static void set_service_out_for_each_client(gpointer data, gpointer user_data)
1205 {
1206         unsigned int instant_reprepare_uid = TTS_INVALID_UID;
1207         if (NULL != user_data) {
1208                 instant_reprepare_uid = *((unsigned int *)user_data);
1209                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Instant on client UID(%u)", instant_reprepare_uid);
1210         }
1211
1212         tts_client_s *client = (tts_client_s *)data;
1213         if (false == tts_client_is_valid_client(client)) {
1214                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid");
1215                 return;
1216         }
1217
1218         const tts_state_e state = tts_client_get_current_state(client);
1219         if (state == TTS_STATE_INVALID || state == TTS_STATE_CREATED) {
1220                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not connected yet. state(%d)", state);
1221                 return;
1222         }
1223
1224         tts_client_set_service_out(client, true);
1225         tts_core_notify_error_async(client, TTS_ERROR_SERVICE_RESET, -1, "Daemon Reset");
1226
1227         unsigned int uid = tts_client_get_uid(client);
1228         if (uid != instant_reprepare_uid) {
1229                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] On-demand repreparation required. UID(%u)", uid);
1230                 tts_client_set_current_state(client, TTS_STATE_READY);
1231         } else {
1232                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Instantly repreparation required. UID(%u)", uid);
1233                 tts_client_set_current_state(client, TTS_STATE_CREATED);
1234                 tts_core_prepare(client);
1235         }
1236
1237         const tts_service_state_e before_state = tts_client_get_current_service_state(client);
1238         tts_core_notify_service_state_changed(client, before_state, TTS_SERVICE_STATE_BLOCKED);
1239 }
1240
1241 static void notify_engine_launch_for_each_client(gpointer data, gpointer user_data)
1242 {
1243         tts_client_s *client = (tts_client_s *)data;
1244         RETM_IF(false == tts_client_is_valid_client(client), "[ERROR] Client is not valid");
1245
1246         const tts_service_state_e before_state = tts_client_get_current_service_state(client);
1247         if (TTS_SERVICE_STATE_BLOCKED == before_state) {
1248                 tts_core_notify_service_state_changed(client, before_state, TTS_SERVICE_STATE_READY);
1249         }
1250 }
1251
1252 static Eina_Bool unset_app_context_cb_by_idler(void *user_data)
1253 {
1254         app_manager_unset_app_context_event_cb();
1255         g_unset_app_context_cb_idler = NULL;
1256         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Unset callback for checking engine launching status");
1257         return EINA_FALSE;
1258 }
1259
1260 static void check_engine_launching_status(app_context_h app_context, app_context_event_e event, void *user_data)
1261 {
1262         RET_IF(event != APP_CONTEXT_EVENT_LAUNCHED);
1263
1264         char *app_id = NULL;
1265         int ret = app_context_get_app_id(app_context, &app_id);
1266
1267         RET_IF(ret != APP_MANAGER_ERROR_NONE || NULL == app_id);
1268
1269         char *engine_id = get_engine_appid();
1270         bool is_engine = (0 == strncmp(app_id, engine_id, TTS_ENGINE_APPID_LEN));
1271         free(app_id);
1272         free(engine_id);
1273
1274         RET_IF(false == is_engine);
1275
1276         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Engine is launched now");
1277         GList* client_list = tts_client_get_client_list();
1278         if (NULL != client_list) {
1279                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Set service out to all clients");
1280                 g_list_foreach(client_list, notify_engine_launch_for_each_client, NULL);
1281                 g_list_free(client_list);
1282         }
1283
1284         if (NULL == g_unset_app_context_cb_idler) {
1285                 g_unset_app_context_cb_idler = ecore_idler_add(unset_app_context_cb_by_idler, NULL);
1286         }
1287 }
1288
1289 int tts_core_handle_service_reset()
1290 {
1291         SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset");
1292
1293         GList* client_list = tts_client_get_client_list();
1294         RETVM_IF(NULL == client_list, TTS_ERROR_OPERATION_FAILED, "[ERROR] Fail to get client list");
1295
1296         unsigned int instant_reprepare_uid = TTS_INVALID_UID;
1297         int ret = tts_config_mgr_get_instant_reprepare_client(&instant_reprepare_uid);
1298         if (TTS_CONFIG_ERROR_NONE != ret) {
1299                 SLOG(LOG_WARN, TAG_TTSC, "[WARN] Fail to get instant reprepare uid. Skip instant reprepare");
1300         }
1301
1302         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Set service out to all clients");
1303         g_list_foreach(client_list, set_service_out_for_each_client, &instant_reprepare_uid);
1304         g_list_free(client_list);
1305
1306         ret = app_manager_set_app_context_event_cb(check_engine_launching_status, NULL);
1307         if (APP_MANAGER_ERROR_NONE != ret) {
1308                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set engine launching status callback. ret(%d/%s)", ret, get_error_message(ret));
1309                 return TTS_ERROR_OPERATION_FAILED;
1310         }
1311
1312         return TTS_ERROR_NONE;
1313 }
1314
1315 static inline void reprepare_on_demand(tts_client_s* client)
1316 {
1317         if (false == tts_client_is_service_out(client)) {
1318                 return;
1319         }
1320
1321         const unsigned int uid = tts_client_get_uid(client);
1322         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Client is out of service. Try to reprepare. uid(%u)", uid);
1323
1324         int ret = tts_core_prepare_sync(client);
1325         if (TTS_ERROR_NONE != ret) {
1326                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client fails to prepare. uid(%u)", uid);
1327         }
1328 }
1329
1330 int tts_core_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id)
1331 {
1332         RETVM_IF(NULL == text || NULL == utt_id, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Parameter is invalid.");
1333         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1334         reprepare_on_demand(client);
1335
1336         tts_client_set_repeat_text(client, text);
1337
1338         if (NULL != g_language) {
1339                 free(g_language);
1340         }
1341
1342         g_language = (NULL == language ? NULL : strdup(language));
1343         g_voice_type = voice_type;
1344         g_speed = speed;
1345
1346         SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] text(%s), language(%s), voice type(%d), speed(%d)", text, (g_language) ? g_language : "NULL", g_voice_type, g_speed);
1347         return __request_add_text(client, text, language, voice_type, speed, utt_id);
1348 }
1349
1350 int tts_core_play(tts_client_s* client)
1351 {
1352         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1353         reprepare_on_demand(client);
1354
1355         return __request_play(client);
1356 }
1357
1358 int tts_core_stop(tts_client_s* client)
1359 {
1360         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1361         reprepare_on_demand(client);
1362
1363         unsigned int uid = tts_client_get_uid(client);
1364         int ret = -1;
1365         tts_client_set_reprepared(client, false);
1366         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1367                 ret = tts_ipc_request_stop(uid);
1368                 if (false == __is_ipc_retry_needed(client, ret)) {
1369                         break;
1370                 }
1371         }
1372
1373         if (TTS_ERROR_NONE != ret) {
1374                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1375                 return ret;
1376         }
1377
1378         return tts_core_notify_state_changed(client, TTS_STATE_READY);
1379 }
1380
1381 int tts_core_pause(tts_client_s* client)
1382 {
1383         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1384         reprepare_on_demand(client);
1385
1386         unsigned int uid = tts_client_get_uid(client);
1387         int ret = -1;
1388         tts_client_set_reprepared(client, false);
1389         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1390                 ret = tts_ipc_request_pause(uid);
1391                 if (false == __is_ipc_retry_needed(client, ret)) {
1392                         break;
1393                 }
1394         }
1395
1396         if (TTS_ERROR_NONE != ret) {
1397                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1398                 return ret;
1399         }
1400
1401         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_pause");
1402         return tts_core_notify_state_changed(client, TTS_STATE_PAUSED);
1403 }
1404
1405 int tts_core_repeat(tts_client_s* client, char** text_repeat, int* utt_id)
1406 {
1407         RETVM_IF(NULL == text_repeat || NULL == utt_id, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Parameter is invalid.");
1408         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1409         reprepare_on_demand(client);
1410
1411         char* repeat_text = tts_client_get_repeat_text(client);
1412         if (NULL == repeat_text) {
1413                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] There is no previous added texts. Please add texts");
1414                 return TTS_ERROR_OPERATION_FAILED;
1415         }
1416
1417         int new_utt_id = -1;
1418         int ret = __request_add_text(client, repeat_text, g_language, g_voice_type, g_speed, &new_utt_id);
1419         if (TTS_ERROR_NONE != ret) {
1420                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to add texts for repetition.");
1421                 free(repeat_text);
1422                 return ret;
1423         }
1424
1425         /* Play added texts */
1426         ret = __request_play(client);
1427         if (TTS_ERROR_NONE != ret) {
1428                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to play texts for repetition.");
1429                 free(repeat_text);
1430                 return ret;
1431         }
1432
1433         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] text to repeat(%s), utt_id(%d)", repeat_text, new_utt_id);
1434
1435         *utt_id = new_utt_id;
1436         *text_repeat = repeat_text;
1437         return TTS_ERROR_NONE;
1438 }
1439
1440 int tts_core_add_pcm(tts_client_s* client, int event, const void* data, unsigned int data_size, int audio_type, int rate)
1441 {
1442         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1443         reprepare_on_demand(client);
1444
1445         unsigned int uid = tts_client_get_uid(client);
1446         int ret = -1;
1447         tts_client_set_reprepared(client, false);
1448         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1449                 ret = tts_ipc_request_add_pcm(uid, event, data, data_size, audio_type, rate);
1450                 if (false == __is_ipc_retry_needed(client, ret)) {
1451                         break;
1452                 }
1453         }
1454
1455         if (TTS_ERROR_NONE != ret) {
1456                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1457                 return ret;
1458         }
1459
1460         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_add_pcm");
1461         return TTS_ERROR_NONE;
1462 }
1463
1464 int tts_core_play_pcm(tts_client_s* client)
1465 {
1466         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1467         reprepare_on_demand(client);
1468
1469         unsigned int uid = tts_client_get_uid(client);
1470         int ret = -1;
1471         tts_client_set_reprepared(client, false);
1472         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1473                 ret = tts_ipc_request_play_pcm(uid);
1474                 if (false == __is_ipc_retry_needed(client, ret)) {
1475                         break;
1476                 }
1477         }
1478
1479         if (TTS_ERROR_NONE != ret) {
1480                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1481                 return ret;
1482         }
1483
1484         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_play_pcm");
1485         return tts_core_notify_state_changed(client, TTS_STATE_PLAYING);
1486 }
1487
1488 int tts_core_stop_pcm(tts_client_s* client)
1489 {
1490         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1491         reprepare_on_demand(client);
1492
1493         unsigned int uid = tts_client_get_uid(client);
1494         int ret = -1;
1495         tts_client_set_reprepared(client, false);
1496         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1497                 ret = tts_ipc_request_stop_pcm(uid);
1498                 if (false == __is_ipc_retry_needed(client, ret)) {
1499                         break;
1500                 }
1501         }
1502
1503         if (TTS_ERROR_NONE != ret) {
1504                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1505                 return ret;
1506         }
1507
1508         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_stop_pcm");
1509         return tts_core_notify_state_changed(client, TTS_STATE_READY);
1510 }
1511
1512 int tts_core_set_private_data(tts_client_s* client, const char* key, const char* data)
1513 {
1514         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1515         reprepare_on_demand(client);
1516
1517         unsigned int uid = tts_client_get_uid(client);
1518         int ret = -1;
1519         tts_client_set_reprepared(client, false);
1520         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1521                 ret = tts_ipc_request_set_private_data(uid, key, data);
1522                 if (false == __is_ipc_retry_needed(client, ret)) {
1523                         break;
1524                 }
1525         }
1526
1527         if (TTS_ERROR_NONE != ret) {
1528                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1529                 return ret;
1530         }
1531
1532         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_set_private_data");
1533         return TTS_ERROR_NONE;
1534 }
1535
1536 int tts_core_get_private_data(tts_client_s* client, const char* key, char** data)
1537 {
1538         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1539         reprepare_on_demand(client);
1540
1541         unsigned int uid = tts_client_get_uid(client);
1542         int ret = -1;
1543         tts_client_set_reprepared(client, false);
1544         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1545                 ret = tts_ipc_request_get_private_data(uid, key, data);
1546                 if (false == __is_ipc_retry_needed(client, ret)) {
1547                         break;
1548                 }
1549         }
1550
1551         if (TTS_ERROR_NONE != ret) {
1552                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1553                 return ret;
1554         }
1555
1556         if (0 == strncmp(*data, "NULL", strlen(*data))) {
1557                 free(*data);
1558                 *data = NULL;
1559         }
1560
1561         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_dbus_request_get_private_data");
1562         return TTS_ERROR_NONE;
1563 }
1564
1565 int tts_core_get_service_state(tts_client_s* client, tts_service_state_e* service_state)
1566 {
1567         RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
1568         reprepare_on_demand(client);
1569
1570         unsigned int uid = tts_client_get_uid(client);
1571         int ret = -1;
1572         tts_client_set_reprepared(client, false);
1573         for (int count = 0; count < TTS_RETRY_COUNT; count++) {
1574                 ret = tts_ipc_request_get_service_state(uid, service_state);
1575                 if (false == __is_ipc_retry_needed(client, ret)) {
1576                         break;
1577                 }
1578         }
1579
1580         if (TTS_ERROR_NONE != ret) {
1581                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1582                 return ret;
1583         }
1584
1585         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_core_get_service_state");
1586         return TTS_ERROR_NONE;
1587 }