Merge "Change the step of checking utf8 validation and text size" into tizen
[platform/core/uifw/tts.git] / client / tts.c
1 /*
2 *  Copyright (c) 2011-2016 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 <app_manager.h>
15 #include <dirent.h>
16 #include <Ecore.h>
17 #include <iconv.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <sys/wait.h>
21 #include <system_info.h>
22 #include <vconf.h>
23 #include <package-manager.h>
24 #include <pthread.h>
25
26 #include "tts.h"
27 #include "tts_client.h"
28 #include "tts_config_mgr.h"
29 #include "tts_dbus.h"
30 #include "tts_main.h"
31
32 #include "tts_internal.h"
33
34 static bool g_screen_reader;
35
36 static int g_feature_enabled = -1;
37
38 static bool g_err_callback_status = false;
39
40 static int g_max_text_size = -1;
41
42 static Ecore_Timer* g_check_state_timer = NULL;
43
44 /* for repetition */
45 static char* g_language = NULL;
46
47 static int g_voice_type = -1;
48
49 static int g_speed = -1;
50 static int g_retry_cnt = 0;
51
52 /* for checking engine update */
53 static pkgmgr_client* g_pkgmgr = NULL;
54 static char* g_engine_name = NULL;
55 static int g_engine_update_status = 0;
56 static pthread_mutex_t g_pkgmgr_mutex = PTHREAD_MUTEX_INITIALIZER;
57
58
59 /* Function definition */
60 static Eina_Bool __tts_notify_state_changed(void *data);
61 static Eina_Bool __tts_notify_error(void *data);
62 int __tts_cb_error(int uid, tts_error_e reason, int utt_id, char* err_msg);
63 int __tts_recheck_screen_reader();
64
65 const char* tts_tag()
66 {
67         return "ttsc";
68 }
69
70 static int __tts_get_feature_enabled()
71 {
72         if (0 == g_feature_enabled) {
73                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] TTS feature NOT supported");
74                 return TTS_ERROR_NOT_SUPPORTED;
75         } else if (-1 == g_feature_enabled) {
76                 bool tts_supported = false;
77                 if (0 == system_info_get_platform_bool(TTS_FEATURE_PATH, &tts_supported)) {
78                         if (false == tts_supported) {
79                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] TTS feature NOT supported");
80                                 g_feature_enabled = 0;
81                                 return TTS_ERROR_NOT_SUPPORTED;
82                         }
83
84                         g_feature_enabled = 1;
85                 } else {
86                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get feature value");
87                         return TTS_ERROR_NOT_SUPPORTED;
88                 }
89         }
90
91         return 0;
92 }
93
94 static const char* __tts_get_error_code(tts_error_e err)
95 {
96         switch (err) {
97         case TTS_ERROR_NONE:                    return "TTS_ERROR_NONE";
98         case TTS_ERROR_OUT_OF_MEMORY:           return "TTS_ERROR_OUT_OF_MEMORY";
99         case TTS_ERROR_IO_ERROR:                return "TTS_ERROR_IO_ERROR";
100         case TTS_ERROR_INVALID_PARAMETER:       return "TTS_ERROR_INVALID_PARAMETER";
101         case TTS_ERROR_OUT_OF_NETWORK:          return "TTS_ERROR_OUT_OF_NETWORK";
102         case TTS_ERROR_TIMED_OUT:               return "TTS_ERROR_TIMED_OUT";
103         case TTS_ERROR_PERMISSION_DENIED:       return "TTS_ERROR_PERMISSION_DENIED";
104         case TTS_ERROR_NOT_SUPPORTED:           return "TTS_ERROR_NOT_SUPPORTED";
105         case TTS_ERROR_INVALID_STATE:           return "TTS_ERROR_INVALID_STATE";
106         case TTS_ERROR_INVALID_VOICE:           return "TTS_ERROR_INVALID_VOICE";
107         case TTS_ERROR_ENGINE_NOT_FOUND:        return "TTS_ERROR_ENGINE_NOT_FOUND";
108         case TTS_ERROR_OPERATION_FAILED:        return "TTS_ERROR_OPERATION_FAILED";
109         case TTS_ERROR_AUDIO_POLICY_BLOCKED:    return "TTS_ERROR_AUDIO_POLICY_BLOCKED";
110         case TTS_ERROR_NOT_SUPPORTED_FEATURE:   return "TTS_ERROR_NOT_SUPPORTED_FEATURE";
111         case TTS_ERROR_SERVICE_RESET:           return "TTS_ERROR_SERVICE_RESET";
112         default:
113                 return "Invalid error code";
114         }
115         return NULL;
116 }
117
118 static int __tts_convert_config_error_code(tts_config_error_e code)
119 {
120         if (code == TTS_CONFIG_ERROR_NONE)                      return TTS_ERROR_NONE;
121         if (code == TTS_CONFIG_ERROR_OUT_OF_MEMORY)             return TTS_ERROR_OUT_OF_MEMORY;
122         if (code == TTS_CONFIG_ERROR_IO_ERROR)                  return TTS_ERROR_IO_ERROR;
123         if (code == TTS_CONFIG_ERROR_INVALID_PARAMETER)         return TTS_ERROR_INVALID_PARAMETER;
124         if (code == TTS_CONFIG_ERROR_INVALID_STATE)             return TTS_ERROR_INVALID_STATE;
125         if (code == TTS_CONFIG_ERROR_INVALID_VOICE)             return TTS_ERROR_INVALID_VOICE;
126         if (code == TTS_CONFIG_ERROR_ENGINE_NOT_FOUND)          return TTS_ERROR_ENGINE_NOT_FOUND;
127         if (code == TTS_CONFIG_ERROR_OPERATION_FAILED)          return TTS_ERROR_OPERATION_FAILED;
128         if (code == TTS_CONFIG_ERROR_NOT_SUPPORTED_FEATURE)     return TTS_ERROR_NOT_SUPPORTED_FEATURE;
129
130         return code;
131 }
132
133 //LCOV_EXCL_START
134 void __tts_config_voice_changed_cb(const char* before_lang, int before_voice_type, const char* language, int voice_type, bool auto_voice, void* user_data)
135 {
136         SLOG(LOG_DEBUG, TAG_TTSC, "Voice changed : Before lang(%s) type(%d) , Current lang(%s), type(%d)",
137                 before_lang, before_voice_type, language, voice_type);
138
139         GList* client_list = NULL;
140         client_list = tts_client_get_client_list();
141
142         GList *iter = NULL;
143         tts_client_s *data = NULL;
144
145         if (g_list_length(client_list) > 0) {
146                 /* Get a first item */
147                 iter = g_list_first(client_list);
148
149                 while (NULL != iter) {
150                         data = iter->data;
151                         if (NULL != data->default_voice_changed_cb) {
152                                 SLOG(LOG_DEBUG, TAG_TTSC, "Call default voice changed callback : uid(%d)", data->uid);
153                                 data->default_voice_changed_cb(data->tts, before_lang, before_voice_type, 
154                                         language, voice_type, data->default_voice_changed_user_data);
155                         }
156
157                         /* Check whether language is changed or not. If it is changed, make 'text_repeat' NULL */
158                         if (0 != strncmp(before_lang, language, strlen(before_lang))) {
159                                 if (NULL != data->text_repeat) {
160                                         free(data->text_repeat);
161                                         data->text_repeat = NULL;
162                                 }
163                         }
164
165                         /* Next item */
166                         iter = g_list_next(iter);
167                 }
168         }
169
170         return;
171 }
172
173 static Eina_Bool __reconnect_by_engine_changed(void* data)
174 {
175         tts_h tts = (tts_h)data;
176
177         tts_client_s* client = tts_client_get(tts);
178         if (NULL == client) {
179                 SLOG(LOG_ERROR, TAG_TTSC, "[WARNING] A handle is not valid");
180                 return EINA_FALSE;
181         }
182
183         if (TTS_STATE_READY != client->current_state) {
184                 usleep(10000);
185                 return EINA_TRUE;
186         }
187
188         int ret = tts_unprepare(tts);
189         if (0 != ret) {
190                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
191         }
192         ret = tts_prepare(tts);
193         if (0 != ret) {
194                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
195         }
196
197         return EINA_FALSE;
198 }
199
200 void _tts_config_engine_changed_cb(const char* engine_id, const char* setting, const char* language, int voice_type, bool auto_voice, bool need_credential, void* user_data)
201 {
202         tts_h tts = (tts_h)user_data;
203
204         tts_client_s* client = tts_client_get(tts);
205         if (NULL == client) {
206                 SLOG(LOG_ERROR, TAG_TTSC, "[WARNING] A handle is not valid");
207                 return;
208         }
209
210         if (NULL != engine_id)  SLOG(LOG_DEBUG, TAG_TTSC, "Engine id(%s)", engine_id);
211         if (NULL != setting)    SLOG(LOG_DEBUG, TAG_TTSC, "Engine setting(%s)", setting);
212         if (NULL != language)   SLOG(LOG_DEBUG, TAG_TTSC, "Language(%s)", language);
213         SLOG(LOG_DEBUG, TAG_TTSC, "Voice type(%d), Auto voice(%s), Credential(%s)", voice_type, auto_voice ? "on" : "off", need_credential ? "need" : "no need");
214
215         /* When the default engine is changed, please unload the old engine and load the new one. */
216         int ret = -1;
217
218         if (TTS_STATE_PLAYING == client->current_state || TTS_STATE_PAUSED == client->current_state) {
219                 ret = tts_stop(tts);
220                 if (0 != ret) {
221                         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] TTS client stopping...");
222                 }
223
224                 ecore_idler_add(__reconnect_by_engine_changed, (void*)tts);
225         } else if (TTS_STATE_READY == client->current_state) {
226                 ret = tts_unprepare(tts);
227                 if (0 != ret) {
228                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to unprepare for setting a new engine... (%d)", ret);
229                 }
230                 ret = tts_prepare(tts);
231                 if (0 != ret) {
232                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
233                 }
234         }
235
236         /* call callback function */
237         if (NULL != client->engine_changed_cb) {
238                 client->engine_changed_cb(tts, engine_id, language, voice_type, need_credential, client->engine_changed_user_data);
239         } else {
240                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function for changed engine");
241         }
242         return;
243 }
244 //LCOV_EXCL_STOP
245
246 void __tts_unset_all_callbacks(tts_h tts)
247 {
248         SLOG(LOG_INFO, TAG_TTSC, "@@@ unset all callbacks");
249
250         tts_unset_state_changed_cb(tts);
251         tts_unset_utterance_started_cb(tts);
252         tts_unset_utterance_completed_cb(tts);
253         tts_unset_error_cb(tts);
254         tts_unset_default_voice_changed_cb(tts);
255         tts_unset_engine_changed_cb(tts);
256
257         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
258 }
259
260 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)
261 {
262         SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status cb is invoked. pkgname(%s), type(%s), key(%s), val(%s)", pkgname, type, key, val);
263
264         if (0 != strncmp(g_engine_name, pkgname, strlen(g_engine_name))) {
265                 SLOG(LOG_DEBUG, TAG_TTSC, "[WARN] this is not tts engine");
266                 return 0;
267         } else {
268                 if (key && 0 == strncmp(key, "start", strlen(key))) {
269                         if (val && (0 == strncmp(val, "update", strlen(val) || 0 == strncmp(val, "uninstall", strlen(val))))) {
270                                 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] start to install.");
271                                 g_engine_update_status = 1;
272                         }
273                 } else if (key && 0 == strncmp(key, "end", strlen(key))) {
274                         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] finish to install");
275                         g_engine_update_status = 0;
276                 }
277         }
278
279         return 0;
280 }
281
282 static void __create_pkgmgr_thread(void* data, Ecore_Thread* thread)
283 {
284         SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] create pkgmgr thread");
285
286         pthread_mutex_lock(&g_pkgmgr_mutex);
287
288         while (!g_pkgmgr) {
289                 g_pkgmgr = pkgmgr_client_new(PC_LISTENING);
290                 if (NULL == g_pkgmgr) {
291                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create pkgmgr handle");
292                 } else {
293                         int ret = pkgmgr_client_set_status_type(g_pkgmgr, PKGMGR_CLIENT_STATUS_UNINSTALL | PKGMGR_CLIENT_STATUS_UPGRADE);
294                         if (0 == ret) {
295                                 if (pkgmgr_client_listen_status(g_pkgmgr, __pkgmgr_status_cb, NULL) < 0) {
296                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to listen pkgmgr status. remove and recreate client");
297                                         pkgmgr_client_free(g_pkgmgr);
298                                         g_pkgmgr = NULL;
299                                         usleep(10000);
300                                         continue;
301                                 } else {
302                                         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Succeed to register pkgmgr cb");
303                                 }
304                         } else {
305                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set status type on pkgmgr, ret(%d)", ret);
306                                 pkgmgr_client_free(g_pkgmgr);
307                                 g_pkgmgr = NULL;
308                                 usleep(10000);
309                                 continue;
310                         }
311                 }
312                 usleep(10000);
313         }
314
315         pthread_mutex_unlock(&g_pkgmgr_mutex);
316
317         return ;
318 }
319
320 static void __finish_pkgmgr_thread(void* data, Ecore_Thread* thread)
321 {
322         SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] Finish pkgmgr thread");
323 }
324
325 static void __pkgmgr_thread(void* data)
326 {
327         SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] call pkgmgr_thread");
328
329         ecore_thread_run(__create_pkgmgr_thread, __finish_pkgmgr_thread, NULL, NULL);
330
331         return ;
332 }
333
334 int tts_create(tts_h* tts)
335 {
336         if (0 != __tts_get_feature_enabled()) {
337                 return TTS_ERROR_NOT_SUPPORTED;
338         }
339
340         SLOG(LOG_INFO, TAG_TTSC, "@@@ Create TTS");
341
342         /* check param */
343         if (NULL == tts) {
344                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
345                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
346                 return TTS_ERROR_INVALID_PARAMETER;
347         }
348
349         if (0 == tts_client_get_size()) {
350                 if (0 != tts_dbus_open_connection()) {
351                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open dbus connection");
352                         return TTS_ERROR_OPERATION_FAILED;
353                 }
354         }
355
356         if (0 != tts_client_new(tts)) {
357                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create client!!!!!");
358                 return TTS_ERROR_OUT_OF_MEMORY;
359         }
360
361         tts_client_s* client = tts_client_get(*tts);
362         if (NULL == client) {
363                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get client");
364                 return TTS_ERROR_OPERATION_FAILED;
365         }
366
367         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", tts, client, client->uid);
368
369         int ret = tts_config_mgr_initialize(client->uid);
370         if (0 != ret) {
371                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to init config manager : %d", ret);
372                 tts_client_destroy(*tts);
373                 return __tts_convert_config_error_code(ret);
374         }
375
376         ret = tts_config_mgr_set_callback(client->uid, _tts_config_engine_changed_cb, __tts_config_voice_changed_cb, NULL, NULL, NULL, client->tts);
377         if (0 != ret) {
378                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set config changed : %d", ret);
379                 tts_client_destroy(*tts);
380                 return __tts_convert_config_error_code(ret);
381         }
382
383         ecore_main_loop_thread_safe_call_async(__pkgmgr_thread, NULL);
384
385         SLOG(LOG_INFO, TAG_TTSC, "[INFO] call ecore thread for creating pkgmgr thread");
386
387         g_engine_name = vconf_get_str(TTS_ENGINE_DB_DEFAULT);
388         if (NULL == g_engine_name) {
389                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine name");
390         } else {
391                 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Engine name(%s)", g_engine_name);
392         }
393
394         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
395         SLOG(LOG_DEBUG, TAG_TTSC, " ");
396
397         return TTS_ERROR_NONE;
398 }
399
400 int tts_destroy(tts_h tts)
401 {
402         if (0 != __tts_get_feature_enabled()) {
403                 return TTS_ERROR_NOT_SUPPORTED;
404         }
405
406         SLOG(LOG_INFO, TAG_TTSC, "@@@ Destroy TTS");
407
408         if (NULL == tts) {
409                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
410                 return TTS_ERROR_INVALID_PARAMETER;
411         }
412
413         tts_client_s* client = tts_client_get(tts);
414
415         /* check handle */
416         if (NULL == client) {
417                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
418                 return TTS_ERROR_INVALID_PARAMETER;
419         }
420
421         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", tts, client, client->uid);
422
423         /* check used callback */
424         if (0 != tts_client_get_use_callback(client)) {
425                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Cannot destroy in Callback function");
426                 return TTS_ERROR_OPERATION_FAILED;
427         }
428
429         tts_config_mgr_finalize(client->uid);
430
431         if (client->hello_timer) {
432                 ecore_timer_del(client->hello_timer);
433                 client->hello_timer = NULL;
434         }
435
436         int ret = -1;
437         int count = 0;
438
439         /* check state */
440         switch (client->current_state) {
441         case TTS_STATE_PAUSED:
442         case TTS_STATE_PLAYING:
443         case TTS_STATE_READY:
444                 ret = __tts_recheck_screen_reader();
445                 if (0 != ret) {
446                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get screen reader(%d)", ret);
447                 }
448
449                 SLOG(LOG_INFO, tts_tag(), "[INFO] g_screen_reader(%s), client->mode(%d)", (true == g_screen_reader) ? "True" : "False", client->mode);
450
451                 if (!(false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode)) {
452                         do {
453                                 ret = tts_dbus_request_finalize(client->uid);
454                                 if (0 != ret) {
455                                         //LCOV_EXCL_START
456                                         if (TTS_ERROR_TIMED_OUT != ret) {
457                                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
458                                                 break;
459                                         } else {
460                                                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry finalize");
461                                                 usleep(10000);
462                                                 count++;
463                                                 if (TTS_RETRY_COUNT == count) {
464                                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
465                                                         break;
466                                                 }
467                                         }
468                                         //LCOV_EXCL_STOP
469                                 }
470                         } while (0 != ret);
471                 } else {
472                         SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Do not request finalize : g_sr(%d) mode(%d)", g_screen_reader, client->mode);
473                 }
474
475                 client->before_state = client->current_state;
476                 client->current_state = TTS_STATE_CREATED;
477
478         case TTS_STATE_CREATED:
479                 if (NULL != client->conn_timer) {
480                         SLOG(LOG_DEBUG, TAG_TTSC, "Connect Timer is deleted");
481                         ecore_timer_del(client->conn_timer);
482                         client->conn_timer = NULL;
483                 }
484                 /* Unset registered callbacks */
485                 __tts_unset_all_callbacks(tts);
486
487                 /* Free resources */
488                 tts_client_destroy(tts);
489                 break;
490
491         default:
492                 break;
493         }
494
495         int num_of_client = tts_client_get_size();
496         if (0 == num_of_client) {
497                 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] all clients are destroied");
498                 if (0 != tts_dbus_close_connection()) {
499                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection");
500                 }
501                 pthread_mutex_lock(&g_pkgmgr_mutex);
502                 if (g_pkgmgr) {
503                         pkgmgr_client_remove_listen_status(g_pkgmgr);
504                         pkgmgr_client_free(g_pkgmgr);
505                         g_pkgmgr = NULL;
506                 }
507                 pthread_mutex_unlock(&g_pkgmgr_mutex);
508         } else {
509                 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] num_of_client(%d)", num_of_client);
510         }
511
512         if (NULL != g_language) {
513                 free(g_language);
514                 g_language = NULL;
515         }
516
517         /* Delete state timer before destroying handle */
518         if (NULL != g_check_state_timer) {
519                 ecore_timer_del(g_check_state_timer);
520                 g_check_state_timer = NULL;
521         }
522
523         tts = NULL;
524
525         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
526
527         return TTS_ERROR_NONE;
528 }
529
530 //LCOV_EXCL_START
531 void __tts_screen_reader_changed_cb(bool value)
532 {
533         g_screen_reader = value;
534 }
535 //LCOV_EXCL_STOP
536
537 int tts_set_mode(tts_h tts, tts_mode_e mode)
538 {
539         if (0 != __tts_get_feature_enabled()) {
540                 return TTS_ERROR_NOT_SUPPORTED;
541         }
542
543         SLOG(LOG_INFO, TAG_TTSC, "@@@ Set TTS mode(%d)", mode);
544
545         tts_client_s* client = tts_client_get(tts);
546
547         /* check handle */
548         if (NULL == client) {
549                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
550                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
551                 return TTS_ERROR_INVALID_PARAMETER;
552         }
553
554         /* check state */
555         if (client->current_state != TTS_STATE_CREATED) {
556                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'");
557                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
558                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
559                 return TTS_ERROR_INVALID_STATE;
560         }
561
562         if (TTS_MODE_DEFAULT <= mode && mode <= TTS_MODE_INTERRUPT) {
563                 client->mode = mode;
564         } else {
565                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] mode is not valid : %d", mode);
566                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
567                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
568                 return TTS_ERROR_INVALID_PARAMETER;
569         }
570
571         if (TTS_MODE_SCREEN_READER == mode) {
572                 int ret;
573                 ret = __tts_recheck_screen_reader();
574                 if (0 != ret) {
575                         SLOG(LOG_ERROR, tts_tag(), "[Config ERROR] Fail to get screen reader(%d)", ret);
576                         return TTS_ERROR_OPERATION_FAILED;
577                 }
578                 tts_config_set_screen_reader_callback(client->uid, __tts_screen_reader_changed_cb);
579         } else {
580                 tts_config_unset_screen_reader_callback(client->uid);
581         }
582
583         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
584
585         return TTS_ERROR_NONE;
586 }
587
588 int tts_get_mode(tts_h tts, tts_mode_e* mode)
589 {
590         if (0 != __tts_get_feature_enabled()) {
591                 return TTS_ERROR_NOT_SUPPORTED;
592         }
593
594         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Get TTS mode");
595
596         tts_client_s* client = tts_client_get(tts);
597
598         /* check handle */
599         if (NULL == client) {
600                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
601                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
602                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
603                 return TTS_ERROR_INVALID_PARAMETER;
604         }
605
606         /* check state */
607         if (client->current_state != TTS_STATE_CREATED) {
608                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'");
609                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
610                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
611                 return TTS_ERROR_INVALID_STATE;
612         }
613
614         if (NULL == mode) {
615                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter(mode) is NULL");
616                 return TTS_ERROR_INVALID_PARAMETER;
617         }
618
619         *mode = client->mode;
620
621         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
622         SLOG(LOG_DEBUG, TAG_TTSC, " ");
623
624         return TTS_ERROR_NONE;
625 }
626
627 int tts_set_credential(tts_h tts, const char* credential)
628 {
629         if (0 != __tts_get_feature_enabled()) {
630                 return TTS_ERROR_NOT_SUPPORTED;
631         }
632
633         if (NULL == tts || NULL == credential) {
634                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
635                 return TTS_ERROR_INVALID_PARAMETER;
636         }
637
638         tts_client_s* client = tts_client_get(tts);
639
640         if (NULL == client) {
641                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : A handle is not valid");
642                 return TTS_ERROR_INVALID_PARAMETER;
643         }
644
645         if (TTS_STATE_CREATED != client->current_state && TTS_STATE_READY != client->current_state) {
646                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid (%d).", client->current_state);
647                 return TTS_ERROR_INVALID_STATE;
648         }
649
650         if (NULL != client->credential) {
651                 free(client->credential);
652                 client->credential = NULL;
653         }
654         client->credential = strdup(credential);
655
656         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
657
658         return TTS_ERROR_NONE;
659 }
660
661 //LCOV_EXCL_START
662 int tts_set_server_tts(tts_h tts, const char* credential)
663 {
664         if (0 != __tts_get_feature_enabled()) {
665                 return TTS_ERROR_NOT_SUPPORTED;
666         }
667
668         if (NULL == tts) {
669                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
670                 return TTS_ERROR_INVALID_PARAMETER;
671         }
672
673         tts_client_s* client = tts_client_get(tts);
674
675         if (NULL == client) {
676                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : A handle is not valid");
677                 return TTS_ERROR_INVALID_PARAMETER;
678         }
679
680         if (TTS_STATE_CREATED != client->current_state && TTS_STATE_READY != client->current_state) {
681                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid (%d).", client->current_state);
682                 return TTS_ERROR_INVALID_STATE;
683         }
684
685         if (NULL != client->credential) {
686                 free(client->credential);
687                 client->credential = NULL;
688         }
689
690         client->internal = true;
691
692         char* key = NULL;
693         if (NULL != credential) {
694                 key = strdup("EnableServerTTS");
695                 client->credential = strdup(credential);
696                 if (NULL == client->credential) {
697                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to allocate memory");
698                         if (NULL != key) {
699                                 free(key);
700                                 key = NULL;
701                         }
702                         return TTS_ERROR_OUT_OF_MEMORY;
703                 }
704         } else {
705                 key = strdup("DisableServerTTS");
706         }
707
708         if (NULL == key) {
709                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to allocate memory");
710                 return TTS_ERROR_OUT_OF_MEMORY;
711         }
712
713         int pid = getpid();
714         char* appid = NULL;
715         int ret = app_manager_get_app_id(pid, &appid);
716         if (0 != ret || NULL == appid) {
717                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get appid, ret(%d), pid(%d), appid(%s)", ret, pid, appid);
718                 free(key);
719                 key = NULL;
720                 if (NULL != appid) {
721                         free(appid);
722                         appid = NULL;
723                 }
724                 return TTS_ERROR_OPERATION_FAILED;
725         }
726
727         ret = tts_set_private_data(tts, key, appid);
728         if (0 != ret) {
729                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set private data, ret(%d), pid(%d), appid(%s)", ret, pid, appid);
730                 free(key);
731                 key = NULL;
732                 free(appid);
733                 appid = NULL;
734                 return ret;
735         }
736
737         free(appid);
738         appid = NULL;
739         free(key);
740         key = NULL;
741
742         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
743
744         return TTS_ERROR_NONE;
745 }
746 // LCOV_EXCL_STOP
747
748 static Eina_Bool __tts_connect_daemon(void *data)
749 {
750         tts_h tts = (tts_h)data;
751         tts_client_s* client = tts_client_get(tts);
752
753         /* check handle */
754         if (NULL == client) {
755                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
756                 return EINA_FALSE;
757         }
758
759         /* check whether engine is updating or not */
760         if (g_engine_update_status) {
761                 SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] cannot prepare due to engine update");
762                 __tts_cb_error(-1, TTS_ERROR_SERVICE_RESET, -1, "Daemon Reset");
763
764                 return EINA_FALSE;
765         }
766
767         /* Send hello */
768         if (0 != tts_dbus_request_hello_sync(client->uid)) {
769                 return EINA_TRUE;
770         }
771
772         SLOG(LOG_INFO, TAG_TTSC, "@@@ Connect daemon");
773
774         /* do request initialize */
775         int ret = -1;
776         bool credential_needed = false;
777
778         ret = tts_dbus_request_initialize(client->uid, &credential_needed);
779
780         if (TTS_ERROR_ENGINE_NOT_FOUND == ret) {
781                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", __tts_get_error_code(ret));
782
783                 client->reason = TTS_ERROR_ENGINE_NOT_FOUND;
784                 client->utt_id = -1;
785
786                 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
787                 if (client->conn_timer) {
788                         ecore_timer_del(client->conn_timer);
789                         client->conn_timer = NULL;
790                 }
791                 return EINA_FALSE;
792
793         } else if (TTS_ERROR_PERMISSION_DENIED == ret) {
794                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", __tts_get_error_code(ret));
795
796                 client->reason = TTS_ERROR_PERMISSION_DENIED;
797                 client->utt_id = -1;
798
799                 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
800                 if (client->conn_timer) {
801                         ecore_timer_del(client->conn_timer);
802                         client->conn_timer = NULL;
803                 }
804                 return EINA_FALSE;
805
806         } else if (TTS_ERROR_NONE != ret) {
807                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect : %s", __tts_get_error_code(ret));
808                 return EINA_TRUE;
809
810         } else {
811                 /* success to connect tts-daemon */
812                 client->credential_needed = credential_needed;
813                 SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%s)", credential_needed ? "need" : "no need");
814         }
815
816         if (client->conn_timer) {
817                 ecore_timer_del(client->conn_timer);
818                 client->conn_timer = NULL;
819         }
820
821         client = tts_client_get(tts);
822         /* check handle */
823         if (NULL == client) {
824                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
825                 return EINA_FALSE;
826         }
827
828         client->before_state = client->current_state;
829         client->current_state = TTS_STATE_READY;
830
831         if (NULL != client->state_changed_cb) {
832                 tts_client_use_callback(client);
833                 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
834                 tts_client_not_use_callback(client);
835         } else {
836                 SLOG(LOG_WARN, TAG_TTSC, "State changed callback is NULL");
837         }
838
839         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
840
841         return EINA_FALSE;
842 }
843
844 int __tts_cb_hello(int uid, int ret, int credential_needed)
845 {
846         tts_client_s* client = tts_client_get_by_uid(uid);
847         if (NULL == client) {
848                 SLOG(LOG_ERROR, TAG_TTSC, "Fail to get TTS client or ignore this uid(%d)", uid);
849                 return TTS_ERROR_OPERATION_FAILED;
850         }
851
852         if (client->hello_timer) {
853                 ecore_timer_del(client->hello_timer);
854                 client->hello_timer = NULL;
855         }
856
857         if (TTS_STATE_READY == client->current_state) {
858                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts client is already READY");
859                 return TTS_ERROR_NONE;
860         }
861
862         if (TTS_ERROR_ENGINE_NOT_FOUND == ret) {
863                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", __tts_get_error_code(ret));
864
865                 client->reason = TTS_ERROR_ENGINE_NOT_FOUND;
866                 client->utt_id = -1;
867
868                 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
869                 return TTS_ERROR_OPERATION_FAILED;
870
871         } else if (TTS_ERROR_PERMISSION_DENIED == ret) {
872                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize : %s", __tts_get_error_code(ret));
873
874                 client->reason = TTS_ERROR_PERMISSION_DENIED;
875                 client->utt_id = -1;
876
877                 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
878                 return TTS_ERROR_PERMISSION_DENIED;
879
880         } else if (TTS_ERROR_NONE != ret) {
881                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to connection. Retry to connect : %s", __tts_get_error_code(ret));
882                 return TTS_ERROR_OPERATION_FAILED;
883
884         } else {
885                 /* success to connect tts-daemon */
886                 client->credential_needed = credential_needed;
887                 SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%s)", credential_needed ? "need" : "no need");
888         }
889
890         client->before_state = client->current_state;
891         client->current_state = TTS_STATE_READY;
892
893         ecore_timer_add(0.0, __tts_notify_state_changed, client->tts);
894
895         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
896         return TTS_ERROR_NONE;
897 }
898
899 static Eina_Bool __send_hello(void *data)
900 {
901         tts_h tts = (tts_h)data;
902         tts_client_s* client = tts_client_get(tts);
903
904         /* check handle */
905         if (NULL == client) {
906                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
907                 return EINA_FALSE;
908         }
909
910         /* check state */
911         if (client->current_state == TTS_STATE_READY) {
912                 SLOG(LOG_ERROR, TAG_TTSC, "[INFO] TTS client has been already connected to tts service"); //LCOV_EXCL_LINE
913                 SLOG(LOG_ERROR, TAG_TTSC, "@@@");
914                 client->hello_timer = NULL;
915                 return EINA_FALSE;
916         }
917
918         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", tts, client, client->uid);
919
920         /* check whether engine is updating or not */
921         if (g_engine_update_status) {
922                 SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] cannot prepare due to engine update");
923                 __tts_cb_error(-1, TTS_ERROR_SERVICE_RESET, -1, "Daemon Reset");
924                 client->hello_timer = NULL;
925                 return EINA_FALSE;
926         }
927
928         /* Send hello */
929         int ret = tts_dbus_request_hello(client->uid);
930         if (0 != ret)  {
931                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request hello !!"); //LCOV_EXCL_LINE
932         } else {
933                 SLOG(LOG_ERROR, TAG_TTSC, "@@@ Send Hello");
934         }
935
936         g_retry_cnt++;
937         if (TTS_HELLO_RETRY_COUNT == g_retry_cnt) {
938                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Stop to send hello, retry count reaches the limit");
939                 g_retry_cnt = 0;
940                 client->hello_timer = NULL;
941                 return EINA_FALSE;
942         }
943
944         if (!client->hello_timer) {
945                 SLOG(LOG_ERROR, TAG_TTSC, "@@@ Call checking Hello timer callback");
946                 client->hello_timer = ecore_timer_add(0.5, __send_hello, tts);
947                 return EINA_FALSE;
948         }
949         return EINA_TRUE;
950 }
951
952 int tts_prepare(tts_h tts)
953 {
954         if (0 != __tts_get_feature_enabled()) {
955                 return TTS_ERROR_NOT_SUPPORTED;
956         }
957
958         SLOG(LOG_INFO, TAG_TTSC, "@@@ Prepare TTS");
959
960         tts_client_s* client = tts_client_get(tts);
961
962         /* check handle */
963         if (NULL == client) {
964                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
965                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
966                 return TTS_ERROR_INVALID_PARAMETER;
967         }
968
969         /* check state */
970         if (client->current_state != TTS_STATE_CREATED) {
971                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'");
972                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
973                 return TTS_ERROR_INVALID_STATE;
974         }
975
976         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", tts, client, client->uid);
977
978         if (NULL == client->hello_timer) {
979                 SLOG(LOG_ERROR, TAG_TTSC, "@@@ Call checking Hello timer callback");
980                 g_retry_cnt = 0;
981                 ecore_thread_main_loop_begin();
982                 ecore_timer_add(0.0, __send_hello, (void*)tts);
983                 ecore_thread_main_loop_end();
984         }
985
986         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
987
988         return TTS_ERROR_NONE;
989 }
990
991 //LCOV_EXCL_START
992 int tts_prepare_sync(tts_h tts)
993 {
994         if (0 != __tts_get_feature_enabled()) {
995                 return TTS_ERROR_NOT_SUPPORTED;
996         }
997
998         SLOG(LOG_INFO, TAG_TTSC, "@@@ Prepare TTS");
999
1000         tts_client_s* client = tts_client_get(tts);
1001
1002         /* check handle */
1003         if (NULL == client) {
1004                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
1005                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1006                 return TTS_ERROR_INVALID_PARAMETER;
1007         }
1008
1009         /* check state */
1010         if (client->current_state != TTS_STATE_CREATED) {
1011                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'");
1012                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1013                 return TTS_ERROR_INVALID_STATE;
1014         }
1015
1016         int cnt = 0;
1017         while (EINA_TRUE == __tts_connect_daemon((void*)tts) && TTS_CONNECTION_RETRY_COUNT > cnt) {
1018                 cnt++;
1019         }
1020
1021         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1022
1023         if (TTS_CONNECTION_RETRY_COUNT == cnt) {
1024                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connect daemon");
1025                 return TTS_ERROR_OPERATION_FAILED;
1026         }
1027
1028         return TTS_ERROR_NONE;
1029 }
1030 //LCOV_EXCL_STOP
1031
1032 int tts_unprepare(tts_h tts)
1033 {
1034         if (0 != __tts_get_feature_enabled()) {
1035                 return TTS_ERROR_NOT_SUPPORTED;
1036         }
1037
1038         SLOG(LOG_INFO, TAG_TTSC, "@@@ Unprepare TTS");
1039
1040         tts_client_s* client = tts_client_get(tts);
1041
1042         /* check handle */
1043         if (NULL == client) {
1044                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
1045                 return TTS_ERROR_INVALID_PARAMETER;
1046         }
1047
1048         /* check state */
1049         if (client->current_state != TTS_STATE_READY) {
1050                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'READY'");
1051                 return TTS_ERROR_INVALID_STATE;
1052         }
1053
1054         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%d)", tts, client, client->uid);
1055
1056         if (client->hello_timer) {
1057                 ecore_timer_del(client->hello_timer);
1058                 client->hello_timer = NULL;
1059         }
1060
1061         int ret = -1;
1062         int count = 0;
1063
1064         ret = __tts_recheck_screen_reader();
1065         if (0 != ret) {
1066                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get screen reader(%d)", ret);
1067         }
1068
1069         SLOG(LOG_INFO, tts_tag(), "[INFO] g_screen_reader(%s), client->mode(%d)", (true == g_screen_reader) ? "True" : "False", client->mode);
1070
1071         bool is_prepared = false;
1072         if (!(false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode)) {
1073                 do {
1074                         ret = tts_dbus_request_finalize(client->uid);
1075                         if (0 != ret) {
1076                                 //LCOV_EXCL_START
1077                                 if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
1078                                         client->current_state = TTS_STATE_CREATED;
1079                                         if (0 == tts_prepare_sync(tts)) {
1080                                                 is_prepared = true;
1081                                                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
1082                                         }
1083                                 } else if (TTS_ERROR_TIMED_OUT != ret) {
1084                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
1085                                         break;
1086                                 } else {
1087                                         SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry finalize : %s", __tts_get_error_code(ret));
1088                                         usleep(10000);
1089                                         count++;
1090                                         if (TTS_RETRY_COUNT == count) {
1091                                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1092                                                 break;
1093                                         }
1094                                 }
1095                                 //LCOV_EXCL_STOP
1096                         }
1097                 } while (0 != ret);
1098         } else {
1099                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Do not request finalize : g_sr(%d) mode(%d)", g_screen_reader, client->mode);
1100         }
1101
1102         client->before_state = client->current_state;
1103         client->current_state = TTS_STATE_CREATED;
1104
1105         if (NULL != client->state_changed_cb) {
1106                 tts_client_use_callback(client);
1107                 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
1108                 tts_client_not_use_callback(client);
1109                 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
1110         }
1111
1112         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1113
1114         return TTS_ERROR_NONE;
1115 }
1116
1117 bool __tts_supported_voice_cb(const char* engine_id, const char* language, int type, void* user_data)
1118 {
1119         tts_h tts = (tts_h)user_data;
1120
1121         tts_client_s* client = tts_client_get(tts);
1122         if (NULL == client) {
1123                 SLOG(LOG_ERROR, TAG_TTSC, "[WARNING] A handle is not valid");
1124                 return false;
1125         }
1126
1127         /* call callback function */
1128         if (NULL != client->supported_voice_cb) {
1129                 return client->supported_voice_cb(tts, language, type, client->supported_voice_user_data);
1130         } else {
1131                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of supported voice");
1132         }
1133
1134         return false;
1135 }
1136
1137 int tts_foreach_supported_voices(tts_h tts, tts_supported_voice_cb callback, void* user_data)
1138 {
1139         if (0 != __tts_get_feature_enabled()) {
1140                 return TTS_ERROR_NOT_SUPPORTED;
1141         }
1142
1143         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Foreach supported voices");
1144
1145         if (NULL == tts || NULL == callback) {
1146                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
1147                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1148                 return TTS_ERROR_INVALID_PARAMETER;
1149         }
1150
1151         tts_client_s* client = tts_client_get(tts);
1152
1153         /* check handle */
1154         if (NULL == client) {
1155                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
1156                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1157                 return TTS_ERROR_INVALID_PARAMETER;
1158         }
1159
1160         int ret = 0;
1161         char* current_engine = NULL;
1162         ret = tts_config_mgr_get_engine(&current_engine);
1163         if (0 != ret) {
1164                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get current engine : %d", ret);
1165                 return __tts_convert_config_error_code(ret);
1166         }
1167
1168         client->supported_voice_cb = callback;
1169         client->supported_voice_user_data = user_data;
1170
1171         ret = tts_config_mgr_get_voice_list(current_engine, __tts_supported_voice_cb, client->tts);
1172
1173         if (NULL != current_engine) {
1174                 free(current_engine);
1175                 current_engine = NULL;
1176         }
1177
1178         client->supported_voice_cb = NULL;
1179         client->supported_voice_user_data = NULL;
1180
1181         if (0 != ret) {
1182                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
1183                 ret = TTS_ERROR_OPERATION_FAILED;
1184         }
1185
1186         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1187
1188         return ret;
1189 }
1190
1191 int tts_get_default_voice(tts_h tts, char** lang, int* vctype)
1192 {
1193         if (0 != __tts_get_feature_enabled()) {
1194                 return TTS_ERROR_NOT_SUPPORTED;
1195         }
1196
1197         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Get default voice");
1198
1199         if (NULL == tts) {
1200                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
1201                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1202                 return TTS_ERROR_INVALID_PARAMETER;
1203
1204         }
1205         tts_client_s* client = tts_client_get(tts);
1206
1207         if (NULL == client) {
1208                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
1209                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1210                 return TTS_ERROR_INVALID_PARAMETER;
1211         }
1212
1213         /* Request call remote method */
1214         int ret = 0;
1215         ret = tts_config_mgr_get_voice(lang, vctype);
1216         if (0 != ret) {
1217                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
1218                 return __tts_convert_config_error_code(ret);
1219         } else {
1220                 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Default language(%s), type(%d)", *lang, *vctype);
1221         }
1222
1223         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1224
1225         return ret;
1226 }
1227
1228 int tts_get_max_text_size(tts_h tts, unsigned int* size)
1229 {
1230         if (0 != __tts_get_feature_enabled()) {
1231                 return TTS_ERROR_NOT_SUPPORTED;
1232         }
1233
1234         if (NULL == tts || NULL == size) {
1235                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Input parameter is null");
1236                 return TTS_ERROR_INVALID_PARAMETER;
1237         }
1238
1239         tts_client_s* client = tts_client_get(tts);
1240
1241         if (NULL == client) {
1242                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : A handle is not valid");
1243                 return TTS_ERROR_INVALID_PARAMETER;
1244         }
1245
1246         if (TTS_STATE_READY != client->current_state) {
1247                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Current state is NOT 'READY'.");
1248                 return TTS_ERROR_INVALID_STATE;
1249         }
1250
1251         if (0 != tts_config_mgr_get_max_text_size(size)) {
1252                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get max text size");
1253                 return TTS_ERROR_INVALID_PARAMETER;
1254         }
1255
1256         g_max_text_size = (int)*size;
1257
1258         SLOG(LOG_INFO, TAG_TTSC, "Get max text size : %d byte", *size);
1259         return TTS_ERROR_NONE;
1260 }
1261
1262 int tts_get_state(tts_h tts, tts_state_e* state)
1263 {
1264         if (0 != __tts_get_feature_enabled()) {
1265                 return TTS_ERROR_NOT_SUPPORTED;
1266         }
1267
1268         if (NULL == tts || NULL == state) {
1269                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : Input parameter is null");
1270                 return TTS_ERROR_INVALID_PARAMETER;
1271         }
1272
1273         tts_client_s* client = tts_client_get(tts);
1274
1275         if (NULL == client) {
1276                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : A handle is not valid");
1277                 return TTS_ERROR_INVALID_PARAMETER;
1278         }
1279
1280         *state = client->current_state;
1281
1282         switch (*state) {
1283         case TTS_STATE_CREATED: SLOG(LOG_INFO, TAG_TTSC, "Current state is 'Created'"); break;
1284         case TTS_STATE_READY:   SLOG(LOG_INFO, TAG_TTSC, "Current state is 'Ready'");           break;
1285         case TTS_STATE_PLAYING: SLOG(LOG_INFO, TAG_TTSC, "Current state is 'Playing'"); break;
1286         case TTS_STATE_PAUSED:  SLOG(LOG_INFO, TAG_TTSC, "Current state is 'Paused'");          break;
1287         default:                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid value");             break;
1288         }
1289
1290         return TTS_ERROR_NONE;
1291 }
1292
1293 int tts_get_speed_range(tts_h tts, int* min, int* normal, int* max)
1294 {
1295         if (0 != __tts_get_feature_enabled()) {
1296                 return TTS_ERROR_NOT_SUPPORTED;
1297         }
1298
1299         if (NULL == tts || NULL == min || NULL == normal || NULL == max) {
1300                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
1301                 return TTS_ERROR_INVALID_PARAMETER;
1302         }
1303
1304         tts_client_s* client = tts_client_get(tts);
1305
1306         if (NULL == client) {
1307                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : A handle is not valid");
1308                 return TTS_ERROR_INVALID_PARAMETER;
1309         }
1310
1311         *min = TTS_SPEED_MIN;
1312         *normal = TTS_SPEED_NORMAL;
1313         *max = TTS_SPEED_MAX;
1314
1315         return TTS_ERROR_NONE;
1316 }
1317
1318 int tts_get_error_message(tts_h tts, char** err_msg)
1319 {
1320         if (0 != __tts_get_feature_enabled()) {
1321                 return TTS_ERROR_NOT_SUPPORTED;
1322         }
1323
1324         if (NULL == tts || NULL == err_msg) {
1325                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
1326                 return TTS_ERROR_INVALID_PARAMETER;
1327         }
1328
1329         tts_client_s* client = tts_client_get(tts);
1330
1331         if (NULL == client) {
1332                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : A handle is not valid");
1333                 return TTS_ERROR_INVALID_PARAMETER;
1334         }
1335
1336         if (NULL != client->err_msg) {
1337                 *err_msg = strdup(client->err_msg);
1338                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Error msg (%s)", *err_msg);
1339         } else {
1340                 *err_msg = NULL;
1341                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Error msg (NULL)");
1342         }
1343
1344         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1345
1346         return TTS_ERROR_NONE;
1347 }
1348
1349 int __tts_recheck_screen_reader()
1350 {
1351         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Check screen reader again");
1352
1353         int ret = -1;
1354         int screen_reader = 0;
1355
1356         ret = vconf_get_bool(TTS_ACCESSIBILITY_KEY, &screen_reader);
1357         if (0 != ret) {
1358                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
1359                 return TTS_ERROR_INVALID_STATE;
1360         } else {
1361                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Current screen reader status(%d)", screen_reader);
1362                 g_screen_reader = (bool)screen_reader;
1363         }
1364
1365         return TTS_ERROR_NONE;
1366 }
1367
1368 int tts_add_text(tts_h tts, const char* text, const char* language, int voice_type, int speed, int* utt_id)
1369 {
1370         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Add text: text(%s), language(%s), type(%d)", (NULL == text) ? "NULL" : text, (NULL == language) ? "NULL" : language, voice_type);
1371
1372         if (0 != __tts_get_feature_enabled()) {
1373                 return TTS_ERROR_NOT_SUPPORTED;
1374         }
1375
1376         if (speed < 0) {
1377                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Speed should not be negative(%d)", speed);
1378                 return TTS_ERROR_INVALID_PARAMETER;
1379         }
1380
1381         if (voice_type < 0) {
1382                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Voice type should not be negative(%d)", voice_type);
1383                 return TTS_ERROR_INVALID_PARAMETER;
1384         }
1385
1386         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Add text");
1387
1388         int ret = -1;
1389
1390         if (NULL == tts || NULL == utt_id) {
1391                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
1392                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1393                 return TTS_ERROR_INVALID_PARAMETER;
1394         }
1395
1396         tts_client_s* client = tts_client_get(tts);
1397
1398         if (NULL == client) {
1399                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
1400                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1401                 return TTS_ERROR_INVALID_PARAMETER;
1402         }
1403
1404         if (TTS_STATE_CREATED == client->current_state) {
1405                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'.");
1406                 return TTS_ERROR_INVALID_STATE;
1407         }
1408
1409         if (TTS_SPEED_AUTO > speed || TTS_SPEED_MAX < speed) {
1410                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] speed value(%d) is invalid.", speed);
1411                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1412                 return TTS_ERROR_INVALID_PARAMETER;
1413         }
1414
1415         if (false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode) {
1416                 /* check screen reader option one more time */
1417                 ret = __tts_recheck_screen_reader();
1418                 if (0 != ret) {
1419                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
1420                         return TTS_ERROR_INVALID_STATE;
1421                 } else {
1422                         if (false == g_screen_reader) {
1423                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is NOT available.");
1424                                 return TTS_ERROR_INVALID_STATE;
1425                         }
1426                 }
1427         }
1428
1429         if (true == client->credential_needed && NULL == client->credential) {
1430                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Do not have app credential for this engine");
1431                 return TTS_ERROR_PERMISSION_DENIED;
1432         }
1433
1434         /* check valid utf8 */
1435         bool valid = false;
1436
1437         DBusError err;
1438         dbus_error_init(&err);
1439
1440         valid = dbus_validate_utf8(text, &err);
1441         if (dbus_error_is_set(&err)) {
1442                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Dbus Error(%s), text(%s)", err.message, text);
1443                 dbus_error_free(&err);
1444                 return TTS_ERROR_INVALID_PARAMETER;
1445         }
1446
1447         if (valid != true) {
1448                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Text is invalid - '%s'", text);
1449                 return TTS_ERROR_INVALID_PARAMETER;
1450         }
1451
1452         /* check text size */
1453         if (-1 == g_max_text_size) {
1454                 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] g_max_text_size is %d byte", g_max_text_size);
1455                 if (0 != tts_config_mgr_get_max_text_size((unsigned int*)&g_max_text_size)) {
1456                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get max text size");
1457                         return TTS_ERROR_INVALID_PARAMETER;
1458                 }
1459         }
1460
1461         if (0 == g_max_text_size) {
1462                 if (strlen(text) <= 0) {
1463                         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Max Text Size is %d byte", g_max_text_size);
1464                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is invalid. (max text size is unlimited.)");
1465                         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1466                         return TTS_ERROR_INVALID_PARAMETER;
1467                 }
1468         } else {
1469                 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] g_max_text_size is %d byte", g_max_text_size);
1470                 if (g_max_text_size < strlen(text) || strlen(text) <= 0) {
1471                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input text size is invalid. current text_size(%d byte)", strlen(text));
1472                         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1473                         return TTS_ERROR_INVALID_PARAMETER;
1474                 }
1475         }
1476
1477         SLOG(LOG_DEBUG, TAG_TTSC, "Text is valid - text(%d byte) is '%s'", strlen(text), text);
1478
1479         /* save texts for repetition */
1480         if (NULL != client->text_repeat) {
1481                 free(client->text_repeat);
1482                 client->text_repeat = NULL;
1483         }
1484
1485         client->text_repeat = strdup(text);
1486
1487         if (NULL != g_language) {
1488                 free(g_language);
1489                 g_language = NULL;
1490         }
1491         if (NULL == language)
1492                 g_language = NULL;
1493         else
1494                 g_language = strdup(language);
1495
1496         g_voice_type = voice_type;
1497         g_speed = speed;
1498
1499         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] repeat: text(%s), language(%s), voice type(%d), speed(%d)", client->text_repeat, (g_language) ? g_language : "NULL", g_voice_type, g_speed);
1500
1501         /* change default language value */
1502         char* temp = NULL;
1503
1504         if (NULL == language)
1505                 temp = strdup("default");
1506         else
1507                 temp = strdup(language);
1508
1509         client->current_utt_id++;
1510         if (client->current_utt_id == 10000) {
1511                 client->current_utt_id = 1;
1512         }
1513
1514         /* do request */
1515         ret = -1;
1516         int count = 0;
1517         bool is_prepared = false;
1518         while (0 != ret) {
1519                 ret = tts_dbus_request_add_text(client->uid, text, temp, voice_type, speed, client->current_utt_id, client->credential);
1520                 if (0 != ret) {
1521                         //LCOV_EXCL_START
1522                         if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
1523                                 client->current_state = TTS_STATE_CREATED;
1524                                 if (0 == tts_prepare_sync(tts)) {
1525                                         is_prepared = true;
1526                                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
1527                                 }
1528                         } else if (TTS_ERROR_TIMED_OUT != ret) {
1529                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
1530                                 break;
1531                         } else {
1532                                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry add text : %s", __tts_get_error_code(ret));
1533                                 usleep(10000);
1534                                 count++;
1535                                 if (TTS_RETRY_MIN_COUNT == count) {
1536                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1537                                         break;
1538                                 }
1539                         }
1540                         //LCOV_EXCL_STOP
1541                 } else {
1542                         *utt_id = client->current_utt_id;
1543                 }
1544         }
1545
1546         if (NULL != temp) {
1547                 free(temp);
1548                 temp = NULL;
1549         }
1550
1551         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1552
1553         return ret;
1554 }
1555
1556 //LCOV_EXCL_START
1557 static void __tts_play_async(void *data)
1558 {
1559         tts_h tts = (tts_h)data;
1560         tts_client_s* client = tts_client_get(tts);
1561
1562         /* check handle */
1563         if (NULL == client) {
1564                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
1565                 return;
1566         }
1567
1568         int ret = -1;
1569         int count = 0;
1570         bool is_prepared = false;
1571         while (0 != ret) {
1572                 ret = tts_dbus_request_play(client->uid, client->credential);
1573                 if (0 != ret) {
1574                         if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
1575                                 client->current_state = TTS_STATE_CREATED;
1576                                 if (0 == tts_prepare_sync(tts)) {
1577                                         is_prepared = true;
1578                                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
1579                                 }
1580                         } else if (TTS_ERROR_TIMED_OUT != ret) {
1581                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
1582                                 break;
1583                         } else {
1584                                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry play : %s", __tts_get_error_code(ret));
1585                                 usleep(10000);
1586                                 count++;
1587                                 if (TTS_RETRY_COUNT == count) {
1588                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1589                                         break;
1590                                 }
1591                         }
1592                 }
1593         }
1594
1595         if (0 != ret) {
1596                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to play tts : %s", __tts_get_error_code(ret));
1597
1598                 client->reason = ret;
1599                 client->utt_id = -1;
1600
1601                 ecore_timer_add(0, __tts_notify_error, client->tts);
1602                 return;
1603         }
1604
1605         client->before_state = client->current_state;
1606         client->current_state = TTS_STATE_PLAYING;
1607
1608         if (NULL != client->state_changed_cb) {
1609                 tts_client_use_callback(client);
1610                 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
1611                 tts_client_not_use_callback(client);
1612                 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
1613         }
1614
1615         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1616
1617         return;
1618 }
1619
1620 int tts_play_async(tts_h tts)
1621 {
1622         if (0 != __tts_get_feature_enabled()) {
1623                 return TTS_ERROR_NOT_SUPPORTED;
1624         }
1625
1626         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Play tts");
1627
1628         if (NULL == tts) {
1629                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null.");
1630                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1631                 return TTS_ERROR_INVALID_PARAMETER;
1632         }
1633
1634         tts_client_s* client = tts_client_get(tts);
1635
1636         if (NULL == client) {
1637                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid.");
1638                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1639                 return TTS_ERROR_INVALID_PARAMETER;
1640         }
1641
1642         if (TTS_STATE_PLAYING == client->current_state || TTS_STATE_CREATED == client->current_state) {
1643                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid.");
1644                 return TTS_ERROR_INVALID_STATE;
1645         }
1646
1647         if (false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode) {
1648                 /* check screen reader vconf one more time */
1649                 int ret = -1;
1650                 ret = __tts_recheck_screen_reader();
1651                 if (0 != ret) {
1652                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
1653                         return TTS_ERROR_INVALID_STATE;
1654                 } else {
1655                         if (false == g_screen_reader) {
1656                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is NOT available.");
1657                                 return TTS_ERROR_INVALID_STATE;
1658                         }
1659                 }
1660         }
1661
1662         if (true == client->credential_needed && NULL == client->credential) {
1663                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Do not have app credential for this engine");
1664                 return TTS_ERROR_PERMISSION_DENIED;
1665         }
1666
1667         ecore_main_loop_thread_safe_call_async(__tts_play_async, (void*)tts);
1668
1669         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1670
1671         return TTS_ERROR_NONE;
1672 }
1673 //LCOV_EXCL_STOP
1674 int tts_play(tts_h tts)
1675 {
1676         if (0 != __tts_get_feature_enabled()) {
1677                 return TTS_ERROR_NOT_SUPPORTED;
1678         }
1679
1680         SLOG(LOG_INFO, TAG_TTSC, "@@@ Play tts");
1681
1682         int ret = -1;
1683
1684         if (NULL == tts) {
1685                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null.");
1686                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1687                 return TTS_ERROR_INVALID_PARAMETER;
1688         }
1689
1690         tts_client_s* client = tts_client_get(tts);
1691
1692         if (NULL == client) {
1693                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid.");
1694                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1695                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
1696                 return TTS_ERROR_INVALID_PARAMETER;
1697         }
1698
1699         if (TTS_STATE_PLAYING == client->current_state || TTS_STATE_CREATED == client->current_state) {
1700                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid.");
1701                 return TTS_ERROR_INVALID_STATE;
1702         }
1703
1704         if (false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode) {
1705                 /* check screen reader option one more time */
1706                 ret = __tts_recheck_screen_reader();
1707                 if (0 != ret) {
1708                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
1709                         return TTS_ERROR_INVALID_STATE;
1710                 } else {
1711                         if (false == g_screen_reader) {
1712                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is NOT available.");
1713                                 return TTS_ERROR_INVALID_STATE;
1714                         }
1715                 }
1716         }
1717
1718         if (true == client->credential_needed && NULL == client->credential) {
1719                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Do not have app credential for this engine");
1720                 return TTS_ERROR_PERMISSION_DENIED;
1721         }
1722
1723         ret = -1;
1724         int count = 0;
1725         bool is_prepared = false;
1726         while (0 != ret) {
1727                 ret = tts_dbus_request_play(client->uid, client->credential);
1728                 if (0 != ret) {
1729                         //LCOV_EXCL_START
1730                         if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
1731                                 client->current_state = TTS_STATE_CREATED;
1732                                 if (0 == tts_prepare_sync(tts)) {
1733                                         is_prepared = true;
1734                                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
1735                                 }
1736                         } else if (TTS_ERROR_TIMED_OUT != ret) {
1737                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
1738                                 return ret;
1739                         } else {
1740                                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry play : %s", __tts_get_error_code(ret));
1741                                 usleep(10000);
1742                                 count++;
1743                                 if (TTS_RETRY_COUNT == count) {
1744                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1745                                         return ret;
1746                                 }
1747                         }
1748                         //LCOV_EXCL_STOP
1749                 }
1750         }
1751
1752         client->before_state = client->current_state;
1753         client->current_state = TTS_STATE_PLAYING;
1754
1755         if (NULL != client->state_changed_cb) {
1756                 tts_client_use_callback(client);
1757                 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
1758                 tts_client_not_use_callback(client);
1759                 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
1760         }
1761
1762         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1763
1764         return TTS_ERROR_NONE;
1765 }
1766 //LCOV_EXCL_START
1767 static void __tts_stop_async(void *data)
1768 {
1769         tts_h tts = (tts_h)data;
1770         tts_client_s* client = tts_client_get(tts);
1771
1772         /* check handle */
1773         if (NULL == client) {
1774                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
1775                 return;
1776         }
1777
1778         int ret = -1;
1779         int count = 0;
1780         bool is_prepared = false;
1781         while (0 != ret) {
1782                 ret = tts_dbus_request_stop(client->uid);
1783                 if (0 != ret) {
1784                         if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
1785                                 client->current_state = TTS_STATE_CREATED;
1786                                 if (0 == tts_prepare_sync(tts)) {
1787                                         is_prepared = true;
1788                                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
1789                                 }
1790                         } else if (TTS_ERROR_TIMED_OUT != ret) {
1791                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
1792                                 break;
1793                         } else {
1794                                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry stop : %s", __tts_get_error_code(ret));
1795                                 usleep(10000);
1796                                 count++;
1797                                 if (TTS_RETRY_COUNT == count) {
1798                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1799                                         break;
1800                                 }
1801                         }
1802                 }
1803         }
1804
1805         if (0 != ret) {
1806                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to stop tts : %s", __tts_get_error_code(ret));
1807
1808                 client->reason = ret;
1809                 client->utt_id = -1;
1810
1811                 ecore_timer_add(0, __tts_notify_error, client->tts);
1812                 return;
1813         }
1814
1815         client->before_state = client->current_state;
1816         client->current_state = TTS_STATE_READY;
1817
1818         if (NULL != client->state_changed_cb) {
1819                 tts_client_use_callback(client);
1820                 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
1821                 tts_client_not_use_callback(client);
1822                 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
1823         }
1824
1825         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1826
1827         return;
1828 }
1829
1830 int tts_stop_aync(tts_h tts)
1831 {
1832         if (0 != __tts_get_feature_enabled()) {
1833                 return TTS_ERROR_NOT_SUPPORTED;
1834         }
1835
1836         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Stop tts");
1837
1838         if (NULL == tts) {
1839                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
1840                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1841                 return TTS_ERROR_INVALID_PARAMETER;
1842         }
1843
1844         tts_client_s* client = tts_client_get(tts);
1845
1846         if (NULL == client) {
1847                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
1848                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1849                 return TTS_ERROR_INVALID_PARAMETER;
1850         }
1851
1852         if (TTS_STATE_CREATED == client->current_state) {
1853                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'.");
1854                 return TTS_ERROR_INVALID_STATE;
1855         }
1856
1857         if (false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode) {
1858                 /* check screen reader option one more time */
1859                 int ret = __tts_recheck_screen_reader();
1860                 if (0 != ret) {
1861                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
1862                         return TTS_ERROR_INVALID_STATE;
1863                 } else {
1864                         if (false == g_screen_reader) {
1865                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is NOT available.");
1866                                 return TTS_ERROR_INVALID_STATE;
1867                         }
1868                 }
1869         }
1870
1871         ecore_main_loop_thread_safe_call_async(__tts_stop_async, (void*)tts);
1872
1873         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1874
1875         return TTS_ERROR_NONE;
1876 }
1877 //LCOV_EXCL_STOP
1878 int tts_stop(tts_h tts)
1879 {
1880         if (0 != __tts_get_feature_enabled()) {
1881                 return TTS_ERROR_NOT_SUPPORTED;
1882         }
1883
1884         SLOG(LOG_INFO, TAG_TTSC, "@@@ Stop tts");
1885
1886         int ret = -1;
1887
1888         if (NULL == tts) {
1889                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
1890                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1891                 return TTS_ERROR_INVALID_PARAMETER;
1892         }
1893
1894         tts_client_s* client = tts_client_get(tts);
1895
1896         if (NULL == client) {
1897                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
1898                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1899                 return TTS_ERROR_INVALID_PARAMETER;
1900         }
1901
1902         if (TTS_STATE_CREATED == client->current_state) {
1903                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'.");
1904                 return TTS_ERROR_INVALID_STATE;
1905         }
1906
1907         if (false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode) {
1908                 /* check screen reader option one more time */
1909                 ret = __tts_recheck_screen_reader();
1910                 if (0 != ret) {
1911                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
1912                         return TTS_ERROR_INVALID_STATE;
1913                 } else {
1914                         if (false == g_screen_reader) {
1915                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is NOT available.");
1916                                 return TTS_ERROR_INVALID_STATE;
1917                         }
1918                 }
1919         }
1920
1921         ret = -1;
1922         int count = 0;
1923         bool is_prepared = false;
1924         while (0 != ret) {
1925                 ret = tts_dbus_request_stop(client->uid);
1926                 if (0 != ret) {
1927                         //LCOV_EXCL_START
1928                         if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
1929                                 client->current_state = TTS_STATE_CREATED;
1930                                 if (0 == tts_prepare_sync(tts)) {
1931                                         is_prepared = true;
1932                                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
1933                                 }
1934                         } else if (TTS_ERROR_TIMED_OUT != ret) {
1935                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
1936                                 return ret;
1937                         } else {
1938                                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry stop : %s", __tts_get_error_code(ret));
1939                                 usleep(10000);
1940                                 count++;
1941                                 if (TTS_RETRY_COUNT == count) {
1942                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1943                                         return ret;
1944                                 }
1945                         }
1946                         //LCOV_EXCL_STOP
1947                 }
1948         }
1949
1950         client->before_state = client->current_state;
1951         client->current_state = TTS_STATE_READY;
1952
1953         if (NULL != client->state_changed_cb) {
1954                 tts_client_use_callback(client);
1955                 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
1956                 tts_client_not_use_callback(client);
1957                 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
1958         }
1959
1960         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1961
1962         return TTS_ERROR_NONE;
1963 }
1964 //LCOV_EXCL_START
1965 static void __tts_pause_async(void *data)
1966 {
1967         tts_h tts = (tts_h)data;
1968         tts_client_s* client = tts_client_get(tts);
1969
1970         /* check handle */
1971         if (NULL == client) {
1972                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
1973                 return;
1974         }
1975
1976         int ret = -1;
1977         int count = 0;
1978         bool is_prepared = false;
1979         while (0 != ret) {
1980                 ret = tts_dbus_request_pause(client->uid);
1981                 if (0 != ret) {
1982                         if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
1983                                 client->current_state = TTS_STATE_CREATED;
1984                                 if (0 == tts_prepare_sync(tts)) {
1985                                         is_prepared = true;
1986                                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
1987                                 }
1988                         } else if (TTS_ERROR_TIMED_OUT != ret) {
1989                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
1990                                 break;
1991                         } else {
1992                                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry pause : %s", __tts_get_error_code(ret));
1993                                 usleep(10000);
1994                                 count++;
1995                                 if (TTS_RETRY_COUNT == count) {
1996                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
1997                                         break;
1998                                 }
1999                         }
2000                 }
2001         }
2002
2003         if (0 != ret) {
2004                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to pause tts : %s", __tts_get_error_code(ret));
2005
2006                 client->reason = ret;
2007                 client->utt_id = -1;
2008
2009                 ecore_timer_add(0, __tts_notify_error, client->tts);
2010                 return;
2011         }
2012
2013         client->before_state = client->current_state;
2014         client->current_state = TTS_STATE_PAUSED;
2015
2016         if (NULL != client->state_changed_cb) {
2017                 tts_client_use_callback(client);
2018                 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
2019                 tts_client_not_use_callback(client);
2020                 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
2021         }
2022
2023         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
2024
2025         return;
2026 }
2027
2028 int tts_pause_async(tts_h tts)
2029 {
2030         if (0 != __tts_get_feature_enabled()) {
2031                 return TTS_ERROR_NOT_SUPPORTED;
2032         }
2033
2034         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Pause tts");
2035
2036         if (NULL == tts) {
2037                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
2038                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
2039                 return TTS_ERROR_INVALID_PARAMETER;
2040         }
2041
2042         tts_client_s* client = tts_client_get(tts);
2043
2044         if (NULL == client) {
2045                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
2046                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
2047                 return TTS_ERROR_INVALID_PARAMETER;
2048         }
2049
2050         if (TTS_STATE_PLAYING != client->current_state) {
2051                 SLOG(LOG_ERROR, TAG_TTSC, "[Error] The Current state is NOT 'playing'. So this request should be not running.");
2052                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
2053                 return TTS_ERROR_INVALID_STATE;
2054         }
2055
2056         if (false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode) {
2057                 /* check screen reader option one more time */
2058                 int ret = __tts_recheck_screen_reader();
2059                 if (0 != ret) {
2060                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
2061                         return TTS_ERROR_INVALID_STATE;
2062                 } else {
2063                         if (false == g_screen_reader) {
2064                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is NOT available.");
2065                                 return TTS_ERROR_INVALID_STATE;
2066                         }
2067                 }
2068         }
2069
2070         ecore_main_loop_thread_safe_call_async(__tts_pause_async, (void*)tts);
2071
2072         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
2073
2074         return TTS_ERROR_NONE;
2075 }
2076 //LCOV_EXCL_STOP
2077 int tts_pause(tts_h tts)
2078 {
2079         if (0 != __tts_get_feature_enabled()) {
2080                 return TTS_ERROR_NOT_SUPPORTED;
2081         }
2082
2083         SLOG(LOG_INFO, TAG_TTSC, "@@@ Pause tts");
2084
2085         int ret = -1;
2086
2087         if (NULL == tts) {
2088                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
2089                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
2090                 return TTS_ERROR_INVALID_PARAMETER;
2091         }
2092
2093         tts_client_s* client = tts_client_get(tts);
2094
2095         if (NULL == client) {
2096                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
2097                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
2098                 return TTS_ERROR_INVALID_PARAMETER;
2099         }
2100
2101         if (TTS_STATE_PLAYING != client->current_state) {
2102                 SLOG(LOG_ERROR, TAG_TTSC, "[Error] The Current state is NOT 'playing'. So this request should be not running.");
2103                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
2104                 return TTS_ERROR_INVALID_STATE;
2105         }
2106
2107         if (false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode) {
2108                 ret = __tts_recheck_screen_reader();
2109                 if (0 != ret) {
2110                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
2111                         return TTS_ERROR_INVALID_STATE;
2112                 } else {
2113                         if (false == g_screen_reader) {
2114                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is NOT available.");
2115                                 return TTS_ERROR_INVALID_STATE;
2116                         }
2117                 }
2118         }
2119
2120         ret = -1;
2121         int count = 0;
2122         bool is_prepared = false;
2123         while (0 != ret) {
2124                 ret = tts_dbus_request_pause(client->uid);
2125                 if (0 != ret) {
2126                         //LCOV_EXCL_START
2127                         if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
2128                                 client->current_state = TTS_STATE_CREATED;
2129                                 if (0 == tts_prepare_sync(tts)) {
2130                                         is_prepared = true;
2131                                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
2132                                 }
2133                         } else if (TTS_ERROR_TIMED_OUT != ret) {
2134                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
2135                                 return ret;
2136                         } else {
2137                                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry pause : %s", __tts_get_error_code(ret));
2138                                 usleep(10000);
2139                                 count++;
2140                                 if (TTS_RETRY_COUNT == count) {
2141                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
2142                                         return ret;
2143                                 }
2144                         }
2145                         //LCOV_EXCL_STOP
2146                 }
2147         }
2148
2149         client->before_state = client->current_state;
2150         client->current_state = TTS_STATE_PAUSED;
2151
2152         if (NULL != client->state_changed_cb) {
2153                 tts_client_use_callback(client);
2154                 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
2155                 tts_client_not_use_callback(client);
2156                 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
2157         }
2158
2159         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
2160
2161         return TTS_ERROR_NONE;
2162 }
2163
2164 int tts_set_private_data(tts_h tts, const char* key, const char* data)
2165 {
2166         if (0 != __tts_get_feature_enabled()) {
2167                 return TTS_ERROR_NOT_SUPPORTED;
2168         }
2169
2170         SLOG(LOG_INFO, TAG_TTSC, "@@@ Set private data, key(%s), data(%s)", key, data);
2171
2172         if (NULL == tts) {
2173                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
2174                 return TTS_ERROR_INVALID_PARAMETER;
2175         }
2176
2177         if (NULL == key || NULL == data) {
2178                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid parameter");
2179                 return TTS_ERROR_INVALID_PARAMETER;
2180         }
2181
2182         tts_client_s* client = tts_client_get(tts);
2183
2184         if (NULL == client) {
2185                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
2186                 return TTS_ERROR_INVALID_PARAMETER;
2187         }
2188
2189         if (TTS_STATE_READY != client->current_state) {
2190                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid state : Current state is NOT 'READY'");
2191                 return TTS_ERROR_INVALID_STATE;
2192         }
2193
2194         if (true != client->internal && (0 == strcmp(key, "EnableServerTTS") || 0 == strcmp(key, "DisableServerTTS"))) {
2195                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] This is not an internal app");
2196                 return TTS_ERROR_INVALID_PARAMETER;
2197         }
2198
2199         int ret = -1;
2200         int count = 0;
2201         bool is_prepared = false;
2202         while (0 != ret) {
2203                 ret = tts_dbus_request_set_private_data(client->uid, key, data);
2204                 if (0 != ret) {
2205                         //LCOV_EXCL_START
2206                         if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
2207                                 client->current_state = TTS_STATE_CREATED;
2208                                 if (0 == tts_prepare_sync(tts)) {
2209                                         is_prepared = true;
2210                                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
2211                                 }
2212                         } else if (TTS_ERROR_TIMED_OUT != ret) {
2213                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
2214                                 return ret;
2215                         } else {
2216                                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry : %s", __tts_get_error_code(ret));
2217                                 usleep(10000);
2218                                 count++;
2219                                 if (TTS_RETRY_COUNT == count) {
2220                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
2221                                         return ret;
2222                                 }
2223                         }
2224                         //LCOV_EXCL_STOP
2225                 }
2226         }
2227
2228         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
2229
2230         return 0;
2231 }
2232
2233 int tts_get_private_data(tts_h tts, const char* key, char** data)
2234 {
2235         if (0 != __tts_get_feature_enabled()) {
2236                 return TTS_ERROR_NOT_SUPPORTED;
2237         }
2238
2239         SLOG(LOG_INFO, TAG_TTSC, "@@@ Get private data, key(%s)", key);
2240
2241         if (NULL == tts) {
2242                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
2243                 return TTS_ERROR_INVALID_PARAMETER;
2244         }
2245
2246         if (NULL == key || NULL == data) {
2247                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid parameter");
2248                 return TTS_ERROR_INVALID_PARAMETER;
2249         }
2250
2251         tts_client_s* client = tts_client_get(tts);
2252
2253         if (NULL == client) {
2254                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
2255                 return TTS_ERROR_INVALID_PARAMETER;
2256         }
2257
2258         if (TTS_STATE_READY != client->current_state) {
2259                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid state : Current state is NOT 'READY'");
2260                 return TTS_ERROR_INVALID_STATE;
2261         }
2262
2263         int ret = -1;
2264         int count = 0;
2265         bool is_prepared = false;
2266         while (0 != ret) {
2267                 ret = tts_dbus_request_get_private_data(client->uid, key, data);
2268                 if (0 != ret) {
2269                         //LCOV_EXCL_START
2270                         if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
2271                                 client->current_state = TTS_STATE_CREATED;
2272                                 if (0 == tts_prepare_sync(tts)) {
2273                                         is_prepared = true;
2274                                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
2275                                 }
2276                         } else if (TTS_ERROR_TIMED_OUT != ret) {
2277                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
2278                                 return ret;
2279                         } else {
2280                                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry : %s", __tts_get_error_code(ret));
2281                                 usleep(10000);
2282                                 count++;
2283                                 if (TTS_RETRY_COUNT == count) {
2284                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
2285                                         return ret;
2286                                 }
2287                         }
2288                         //LCOV_EXCL_STOP
2289                 }
2290         }
2291
2292         if (0 == strncmp(*data, "NULL", strlen(*data))) {
2293                 free(*data);
2294                 *data = NULL;
2295         }
2296
2297         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
2298
2299         return 0;
2300 }
2301
2302 //LCOV_EXCL_START
2303 static Eina_Bool __tts_notify_error(void *data)
2304 {
2305         tts_h tts = (tts_h)data;
2306
2307         tts_client_s* client = tts_client_get(tts);
2308
2309         /* check handle */
2310         if (NULL == client) {
2311                 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify error msg : A handle is not valid");
2312                 return EINA_FALSE;
2313         }
2314
2315         SLOG(LOG_DEBUG, TAG_TTSC, "Error data : uttid(%d) reason(%s)", client->utt_id, __tts_get_error_code(client->reason));
2316
2317         if (NULL != client->error_cb) {
2318                 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of error");
2319                 tts_client_use_callback(client);
2320                 g_err_callback_status = true;
2321                 client->error_cb(client->tts, client->utt_id, client->reason, client->error_user_data);
2322                 g_err_callback_status = false;
2323                 tts_client_not_use_callback(client);
2324         } else {
2325                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
2326         }
2327
2328         return EINA_FALSE;
2329 }
2330
2331 static void __start_reprepare_thread(void* data, Ecore_Thread* thread)
2332 {
2333         SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] start reprepare thread. engine update status(%d)", g_engine_update_status);
2334
2335         tts_client_s* temp = (tts_client_s*)data;
2336         if (NULL == temp) {
2337                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] data is null");
2338                 return ;
2339         }
2340
2341         int cnt = 0;
2342         while (!g_engine_update_status && (cnt < 10)) {
2343                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] wait for starting update");
2344                 usleep(50000);
2345                 cnt++;
2346         }
2347
2348         SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] update status(%d)", g_engine_update_status);
2349
2350         while (g_engine_update_status && (NULL != g_pkgmgr)) {
2351 //              SLOG(LOG_WARN, TAG_TTSC, "[WARNING] wait for finishing update");
2352                 usleep(200000);
2353         }
2354
2355         SLOG(LOG_INFO, TAG_TTSC, "[INFO] finish updating. request to prepare");
2356
2357         if (0 != tts_prepare(temp->tts)) {
2358                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare");
2359         }
2360
2361         return ;
2362 }
2363
2364 static void __end_reprepare_thread(void* data, Ecore_Thread* thread)
2365 {
2366         SLOG(LOG_INFO, TAG_TTSC, "[INFO] end reprepare thread");
2367 }
2368
2369 int __tts_cb_error(int uid, tts_error_e reason, int utt_id, char* err_msg)
2370 {
2371         if (-1 == uid) {
2372                 GList* client_list = NULL;
2373                 client_list = tts_client_get_client_list();
2374
2375                 GList *iter = NULL;
2376                 tts_client_s *data = NULL;
2377
2378                 if (g_list_length(client_list) > 0) {
2379                         /* Get a first item */
2380                         iter = g_list_first(client_list);
2381
2382                         while (NULL != iter) {
2383                                 data = iter->data;
2384
2385                                 data->utt_id = utt_id;
2386                                 data->reason = reason;
2387                                 if (NULL != data->err_msg) {
2388                                         free(data->err_msg);
2389                                         data->err_msg = NULL;
2390                                 }
2391                                 if (NULL != err_msg)
2392                                         data->err_msg = strdup(err_msg);
2393
2394                                 /* call callback function */
2395                                 if (NULL != data->error_cb) {
2396                                         ecore_timer_add(0, __tts_notify_error, data->tts);
2397                                 } else {
2398                                         SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
2399                                 }
2400
2401                                 if (TTS_ERROR_SERVICE_RESET == reason) {
2402                                         SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset");
2403
2404                                         data->current_state = TTS_STATE_CREATED;
2405                                         data->reason = 0;
2406                                         ecore_thread_run(__start_reprepare_thread, __end_reprepare_thread, NULL, data);
2407                                 }
2408
2409                                 /* Next item */
2410                                 iter = g_list_next(iter);
2411                         }
2412                 }
2413         } else {
2414                 tts_client_s* client = tts_client_get_by_uid(uid);
2415
2416                 if (NULL == client) {
2417                         SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
2418                         return TTS_ERROR_INVALID_PARAMETER;
2419                 }
2420
2421                 client->utt_id = utt_id;
2422                 client->reason = reason;
2423                 if (NULL != client->err_msg) {
2424                         free(client->err_msg);
2425                         client->err_msg = NULL;
2426                 }
2427                 if (NULL != err_msg)
2428                         client->err_msg = strdup(err_msg);
2429
2430                 /* call callback function */
2431                 if (NULL != client->error_cb) {
2432                         ecore_timer_add(0, __tts_notify_error, client->tts);
2433                 } else {
2434                         SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
2435                 }
2436
2437                 if (TTS_ERROR_SERVICE_RESET == reason) {
2438                         SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset");
2439
2440                         client->current_state = TTS_STATE_CREATED;
2441                         client->reason = 0;
2442                         ecore_thread_run(__start_reprepare_thread, __end_reprepare_thread, NULL, client);
2443                 }
2444         }
2445
2446         return 0;
2447 }
2448
2449 static Eina_Bool __tts_notify_state_changed(void *data)
2450 {
2451         tts_h tts = (tts_h)data;
2452
2453         tts_client_s* client = tts_client_get(tts);
2454
2455         /* check handle */
2456         if (NULL == client) {
2457                 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify state changed : A handle is not valid");
2458                 g_check_state_timer = NULL;
2459                 return EINA_FALSE;
2460         }
2461
2462         if (NULL != client->state_changed_cb) {
2463                 tts_client_use_callback(client);
2464                 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
2465                 tts_client_not_use_callback(client);
2466                 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called : pre(%d) cur(%d)", client->before_state, client->current_state);
2467         } else {
2468                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
2469         }
2470
2471         g_check_state_timer = NULL;
2472
2473         return EINA_FALSE;
2474 }
2475
2476 int __tts_cb_set_state(int uid, int state)
2477 {
2478         tts_client_s* client = tts_client_get_by_uid(uid);
2479         if (NULL == client) {
2480                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] The handle is not valid");
2481                 return -1;
2482         }
2483
2484         tts_state_e state_from_daemon = (tts_state_e)state;
2485
2486         if (client->current_state == state_from_daemon) {
2487                 SLOG(LOG_DEBUG, TAG_TTSC, "Current state has already been %d", client->current_state);
2488                 return 0;
2489         }
2490
2491         if (NULL != client->state_changed_cb) {
2492                 if (NULL != g_check_state_timer) {
2493                         ecore_timer_del(g_check_state_timer);
2494                         g_check_state_timer = NULL;
2495                 }
2496                 g_check_state_timer = ecore_timer_add(0, __tts_notify_state_changed, client->tts);
2497         } else {
2498                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
2499         }
2500
2501         client->before_state = client->current_state;
2502         client->current_state = state_from_daemon;
2503
2504         return 0;
2505 }
2506 //LCOV_EXCL_STOP
2507
2508 int __tts_cb_utt_started(int uid, int utt_id)
2509 {
2510         tts_client_s* client = tts_client_get_by_uid(uid);
2511
2512         if (NULL == client) {
2513                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
2514                 return TTS_ERROR_INVALID_PARAMETER;
2515         }
2516
2517         SLOG(LOG_INFO, TAG_TTSC, "utterance started : utt id(%d) ", utt_id);
2518
2519         client->utt_id = utt_id;
2520
2521         /* call callback function */
2522         if (NULL != client->utt_started_cb) {
2523                 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance started ");
2524                 tts_client_use_callback(client);
2525                 client->utt_started_cb(client->tts, client->utt_id, client->utt_started_user_data);
2526                 tts_client_not_use_callback(client);
2527         } else {
2528                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started ");
2529         }
2530
2531         return 0;
2532 }
2533
2534 int __tts_cb_utt_completed(int uid, int utt_id)
2535 {
2536         tts_client_s* client = tts_client_get_by_uid(uid);
2537
2538         if (NULL == client) {
2539                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
2540                 return TTS_ERROR_INVALID_PARAMETER;
2541         }
2542
2543         SLOG(LOG_INFO, TAG_TTSC, "utterance completed : uttid(%d) ", utt_id);
2544
2545         client->utt_id = utt_id;
2546
2547         /* call callback function */
2548         if (NULL != client->utt_completeted_cb) {
2549                 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance completed ");
2550                 tts_client_use_callback(client);
2551                 client->utt_completeted_cb(client->tts, client->utt_id, client->utt_completed_user_data);
2552                 tts_client_not_use_callback(client);
2553         } else {
2554                 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed ");
2555         }
2556
2557         return 0;
2558 }
2559
2560 int tts_set_state_changed_cb(tts_h tts, tts_state_changed_cb callback, void* user_data)
2561 {
2562         if (0 != __tts_get_feature_enabled()) {
2563                 return TTS_ERROR_NOT_SUPPORTED;
2564         }
2565
2566         if (NULL == tts || NULL == callback) {
2567                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Input parameter is null");
2568                 return TTS_ERROR_INVALID_PARAMETER;
2569         }
2570
2571         tts_client_s* client = tts_client_get(tts);
2572
2573         if (NULL == client) {
2574                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : A handle is not valid");
2575                 return TTS_ERROR_INVALID_PARAMETER;
2576         }
2577
2578         if (TTS_STATE_CREATED != client->current_state) {
2579                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Current state is not 'Created'.");
2580                 return TTS_ERROR_INVALID_STATE;
2581         }
2582
2583         client->state_changed_cb = callback;
2584         client->state_changed_user_data = user_data;
2585
2586         SLOG(LOG_INFO, TAG_TTSC, "[SUCCESS] Set state changed cb");
2587
2588         return 0;
2589 }
2590
2591 int tts_unset_state_changed_cb(tts_h tts)
2592 {
2593         if (0 != __tts_get_feature_enabled()) {
2594                 return TTS_ERROR_NOT_SUPPORTED;
2595         }
2596
2597         if (NULL == tts) {
2598                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Input parameter is null");
2599                 return TTS_ERROR_INVALID_PARAMETER;
2600         }
2601
2602         tts_client_s* client = tts_client_get(tts);
2603
2604         if (NULL == client) {
2605                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : A handle is not valid");
2606                 return TTS_ERROR_INVALID_PARAMETER;
2607         }
2608
2609         if (TTS_STATE_CREATED != client->current_state) {
2610                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Current state is not 'Created'.");
2611                 return TTS_ERROR_INVALID_STATE;
2612         }
2613
2614         client->state_changed_cb = NULL;
2615         client->state_changed_user_data = NULL;
2616
2617         if (NULL != g_check_state_timer) {
2618                 ecore_timer_del(g_check_state_timer);
2619                 g_check_state_timer = NULL;
2620         }
2621
2622         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset state changed cb");
2623
2624         return 0;
2625 }
2626
2627 int tts_set_utterance_started_cb(tts_h tts, tts_utterance_started_cb callback, void* user_data)
2628 {
2629         if (0 != __tts_get_feature_enabled()) {
2630                 return TTS_ERROR_NOT_SUPPORTED;
2631         }
2632
2633         if (NULL == tts || NULL == callback) {
2634                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Input parameter is null");
2635                 return TTS_ERROR_INVALID_PARAMETER;
2636         }
2637
2638         tts_client_s* client = tts_client_get(tts);
2639
2640         if (NULL == client) {
2641                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : A handle is not valid");
2642                 return TTS_ERROR_INVALID_PARAMETER;
2643         }
2644
2645         if (TTS_STATE_CREATED != client->current_state) {
2646                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Current state is not 'Created'.");
2647                 return TTS_ERROR_INVALID_STATE;
2648         }
2649
2650         client->utt_started_cb = callback;
2651         client->utt_started_user_data = user_data;
2652
2653         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt started cb");
2654
2655         return 0;
2656 }
2657
2658 int tts_unset_utterance_started_cb(tts_h tts)
2659 {
2660         if (0 != __tts_get_feature_enabled()) {
2661                 return TTS_ERROR_NOT_SUPPORTED;
2662         }
2663
2664         if (NULL == tts) {
2665                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Input parameter is null");
2666                 return TTS_ERROR_INVALID_PARAMETER;
2667         }
2668
2669         tts_client_s* client = tts_client_get(tts);
2670
2671         if (NULL == client) {
2672                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : A handle is not valid");
2673                 return TTS_ERROR_INVALID_PARAMETER;
2674         }
2675
2676         if (TTS_STATE_CREATED != client->current_state) {
2677                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Current state is not 'Created'.");
2678                 return TTS_ERROR_INVALID_STATE;
2679         }
2680
2681         client->utt_started_cb = NULL;
2682         client->utt_started_user_data = NULL;
2683
2684         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt started cb");
2685
2686         return 0;
2687 }
2688
2689 int tts_set_utterance_completed_cb(tts_h tts, tts_utterance_completed_cb callback, void* user_data)
2690 {
2691         if (0 != __tts_get_feature_enabled()) {
2692                 return TTS_ERROR_NOT_SUPPORTED;
2693         }
2694
2695         if (NULL == tts || NULL == callback) {
2696                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Input parameter is null");
2697                 return TTS_ERROR_INVALID_PARAMETER;
2698         }
2699
2700         tts_client_s* client = tts_client_get(tts);
2701
2702         if (NULL == client) {
2703                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : A handle is not valid");
2704                 return TTS_ERROR_INVALID_PARAMETER;
2705         }
2706
2707         if (TTS_STATE_CREATED != client->current_state) {
2708                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Current state is not 'Created'.");
2709                 return TTS_ERROR_INVALID_STATE;
2710         }
2711
2712         client->utt_completeted_cb = callback;
2713         client->utt_completed_user_data = user_data;
2714
2715         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt completed cb");
2716
2717         return 0;
2718 }
2719
2720 int tts_unset_utterance_completed_cb(tts_h tts)
2721 {
2722         if (0 != __tts_get_feature_enabled()) {
2723                 return TTS_ERROR_NOT_SUPPORTED;
2724         }
2725
2726         if (NULL == tts) {
2727                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Input parameter is null");
2728                 return TTS_ERROR_INVALID_PARAMETER;
2729         }
2730
2731         tts_client_s* client = tts_client_get(tts);
2732
2733         if (NULL == client) {
2734                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : A handle is not valid");
2735                 return TTS_ERROR_INVALID_PARAMETER;
2736         }
2737
2738         if (TTS_STATE_CREATED != client->current_state) {
2739                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Current state is not 'Created'.");
2740                 return TTS_ERROR_INVALID_STATE;
2741         }
2742
2743         client->utt_completeted_cb = NULL;
2744         client->utt_completed_user_data = NULL;
2745
2746         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt completed cb");
2747         return 0;
2748 }
2749
2750 int tts_set_error_cb(tts_h tts, tts_error_cb callback, void* user_data)
2751 {
2752         if (0 != __tts_get_feature_enabled()) {
2753                 return TTS_ERROR_NOT_SUPPORTED;
2754         }
2755
2756         if (NULL == tts || NULL == callback) {
2757                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Input parameter is null");
2758                 return TTS_ERROR_INVALID_PARAMETER;
2759         }
2760
2761         tts_client_s* client = tts_client_get(tts);
2762
2763         if (NULL == client) {
2764                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : A handle is not valid");
2765                 return TTS_ERROR_INVALID_PARAMETER;
2766         }
2767
2768         if (TTS_STATE_CREATED != client->current_state) {
2769                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Current state is not 'Created'.");
2770                 return TTS_ERROR_INVALID_STATE;
2771         }
2772
2773         client->error_cb = callback;
2774         client->error_user_data = user_data;
2775
2776         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set error cb");
2777
2778         return 0;
2779 }
2780
2781 int tts_unset_error_cb(tts_h tts)
2782 {
2783         if (0 != __tts_get_feature_enabled()) {
2784                 return TTS_ERROR_NOT_SUPPORTED;
2785         }
2786
2787         if (NULL == tts) {
2788                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Input parameter is null");
2789                 return TTS_ERROR_INVALID_PARAMETER;
2790         }
2791
2792         tts_client_s* client = tts_client_get(tts);
2793
2794         if (NULL == client) {
2795                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : A handle is not valid");
2796                 return TTS_ERROR_INVALID_PARAMETER;
2797         }
2798
2799         if (TTS_STATE_CREATED != client->current_state) {
2800                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Current state is not 'Created'.");
2801                 return TTS_ERROR_INVALID_STATE;
2802         }
2803
2804         client->error_cb = NULL;
2805         client->error_user_data = NULL;
2806
2807         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset error cb");
2808
2809         return 0;
2810 }
2811
2812 int tts_set_default_voice_changed_cb(tts_h tts, tts_default_voice_changed_cb callback, void* user_data)
2813 {
2814         if (0 != __tts_get_feature_enabled()) {
2815                 return TTS_ERROR_NOT_SUPPORTED;
2816         }
2817
2818         if (NULL == tts || NULL == callback) {
2819                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set default voice changed cb : Input parameter is null");
2820                 return TTS_ERROR_INVALID_PARAMETER;
2821         }
2822
2823         tts_client_s* client = tts_client_get(tts);
2824
2825         if (NULL == client) {
2826                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set default voice changed cb : A handle is not valid");
2827                 return TTS_ERROR_INVALID_PARAMETER;
2828         }
2829
2830         if (TTS_STATE_CREATED != client->current_state) {
2831                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set default voice changed cb : Current state is not 'Created'.");
2832                 return TTS_ERROR_INVALID_STATE;
2833         }
2834
2835         client->default_voice_changed_cb = callback;
2836         client->default_voice_changed_user_data = user_data;
2837
2838         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set default voice changed cb");
2839
2840         return 0;
2841 }
2842
2843 int tts_unset_default_voice_changed_cb(tts_h tts)
2844 {
2845         if (0 != __tts_get_feature_enabled()) {
2846                 return TTS_ERROR_NOT_SUPPORTED;
2847         }
2848
2849         if (NULL == tts) {
2850                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset default voice changed cb : Input parameter is null");
2851                 return TTS_ERROR_INVALID_PARAMETER;
2852         }
2853
2854         tts_client_s* client = tts_client_get(tts);
2855
2856         if (NULL == client) {
2857                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset default voice changed cb : A handle is not valid");
2858                 return TTS_ERROR_INVALID_PARAMETER;
2859         }
2860
2861         if (TTS_STATE_CREATED != client->current_state) {
2862                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset default voice changed cb : Current state is not 'Created'.");
2863                 return TTS_ERROR_INVALID_STATE;
2864         }
2865
2866         client->default_voice_changed_cb = NULL;
2867         client->default_voice_changed_user_data = NULL;
2868
2869         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset default voice changed cb");
2870
2871         return 0;
2872 }
2873
2874 int tts_set_engine_changed_cb(tts_h tts, tts_engine_changed_cb callback, void* user_data)
2875 {
2876         if (0 != __tts_get_feature_enabled()) {
2877                 return TTS_ERROR_NOT_SUPPORTED;
2878         }
2879
2880         if (NULL == tts || NULL == callback) {
2881                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set engine changed cb : Input parameter is null");
2882                 return TTS_ERROR_INVALID_PARAMETER;
2883         }
2884
2885         tts_client_s* client = tts_client_get(tts);
2886
2887         if (NULL == client) {
2888                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set engine changed cb : A handle is not valid");
2889                 return TTS_ERROR_INVALID_PARAMETER;
2890         }
2891
2892         if (TTS_STATE_CREATED != client->current_state) {
2893                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set engine changed cb : Current state is not 'Created'.");
2894                 return TTS_ERROR_INVALID_STATE;
2895         }
2896
2897         client->engine_changed_cb = callback;
2898         client->engine_changed_user_data = user_data;
2899
2900         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set engine changed cb");
2901
2902         return 0;
2903 }
2904
2905 int tts_unset_engine_changed_cb(tts_h tts)
2906 {
2907         if (0 != __tts_get_feature_enabled()) {
2908                 return TTS_ERROR_NOT_SUPPORTED;
2909         }
2910
2911         if (NULL == tts) {
2912                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset engine changed cb : Input parameter is null");
2913                 return TTS_ERROR_INVALID_PARAMETER;
2914         }
2915
2916         tts_client_s* client = tts_client_get(tts);
2917
2918         if (NULL == client) {
2919                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset engine changed cb : A handle is not valid");
2920                 return TTS_ERROR_INVALID_PARAMETER;
2921         }
2922
2923         if (TTS_STATE_CREATED != client->current_state) {
2924                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset engine changed cb : Current state is not 'Created'.");
2925                 return TTS_ERROR_INVALID_STATE;
2926         }
2927
2928         client->engine_changed_cb = NULL;
2929         client->engine_changed_user_data = NULL;
2930
2931         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset engine changed cb");
2932
2933         return 0;
2934 }
2935
2936 //LCOV_EXCL_START
2937 int tts_add_pcm(tts_h tts, int event, const void* data, unsigned int data_size, int audio_type, int rate)
2938 {
2939         if (0 != __tts_get_feature_enabled()) {
2940                 return TTS_ERROR_NOT_SUPPORTED;
2941         }
2942
2943         SLOG(LOG_INFO, TAG_TTSC, "@@@ Add pcm tts");
2944
2945         int ret = -1;
2946
2947         if (NULL == tts) {
2948                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null.");
2949                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
2950                 return TTS_ERROR_INVALID_PARAMETER;
2951         }
2952
2953         tts_client_s* client = tts_client_get(tts);
2954
2955         if (NULL == client) {
2956                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid.");
2957                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
2958                 return TTS_ERROR_INVALID_PARAMETER;
2959         }
2960
2961         if (TTS_STATE_CREATED == client->current_state) {
2962                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid.");
2963                 return TTS_ERROR_INVALID_STATE;
2964         }
2965
2966         if (false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode) {
2967                 ret = __tts_recheck_screen_reader();
2968                 if (0 != ret) {
2969                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
2970                         return TTS_ERROR_INVALID_STATE;
2971                 } else {
2972                         if (false == g_screen_reader) {
2973                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is NOT available.");
2974                                 return TTS_ERROR_INVALID_STATE;
2975                         }
2976                 }
2977         }
2978
2979         ret = -1;
2980         int count = 0;
2981         bool is_prepared = false;
2982         while (0 != ret) {
2983                 ret = tts_dbus_request_add_pcm(client->uid, event, data, data_size, audio_type, rate);
2984                 if (0 != ret) {
2985                         if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
2986                                 client->current_state = TTS_STATE_CREATED;
2987                                 if (0 == tts_prepare_sync(tts)) {
2988                                         is_prepared = true;
2989                                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
2990                                 }
2991                         } else if (TTS_ERROR_TIMED_OUT != ret) {
2992                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
2993                                 return ret;
2994                         } else {
2995                                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry add pcm : %s", __tts_get_error_code(ret));
2996                                 usleep(10000);
2997                                 count++;
2998                                 if (TTS_RETRY_COUNT == count) {
2999                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
3000                                         return ret;
3001                                 }
3002                         }
3003                 }
3004         }
3005
3006         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
3007
3008         return TTS_ERROR_NONE;
3009 }
3010
3011 int tts_play_pcm(tts_h tts)
3012 {
3013         if (0 != __tts_get_feature_enabled()) {
3014                 return TTS_ERROR_NOT_SUPPORTED;
3015         }
3016
3017         SLOG(LOG_INFO, TAG_TTSC, "@@@ Play pcm tts");
3018
3019         int ret = -1;
3020
3021         if (NULL == tts) {
3022                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null.");
3023                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
3024                 return TTS_ERROR_INVALID_PARAMETER;
3025         }
3026
3027         tts_client_s* client = tts_client_get(tts);
3028
3029         if (NULL == client) {
3030                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid.");
3031                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
3032                 return TTS_ERROR_INVALID_PARAMETER;
3033         }
3034
3035         if (TTS_STATE_PLAYING == client->current_state || TTS_STATE_CREATED == client->current_state) {
3036                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid.");
3037                 return TTS_ERROR_INVALID_STATE;
3038         }
3039
3040         if (false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode) {
3041                 ret = __tts_recheck_screen_reader();
3042                 if (0 != ret) {
3043                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
3044                         return TTS_ERROR_INVALID_STATE;
3045                 } else {
3046                         if (false == g_screen_reader) {
3047                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is NOT available.");
3048                                 return TTS_ERROR_INVALID_STATE;
3049                         }
3050                 }
3051         }
3052
3053         ret = -1;
3054         int count = 0;
3055         bool is_prepared = false;
3056         while (0 != ret) {
3057                 ret = tts_dbus_request_play_pcm(client->uid);
3058                 if (0 != ret) {
3059                         if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
3060                                 client->current_state = TTS_STATE_CREATED;
3061                                 if (0 == tts_prepare_sync(tts)) {
3062                                         is_prepared = true;
3063                                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
3064                                 }
3065                         } else if (TTS_ERROR_TIMED_OUT != ret) {
3066                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
3067                                 return ret;
3068                         } else {
3069                                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry play pcm : %s", __tts_get_error_code(ret));
3070                                 usleep(10000);
3071                                 count++;
3072                                 if (TTS_RETRY_COUNT == count) {
3073                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
3074                                         return ret;
3075                                 }
3076                         }
3077                 }
3078         }
3079
3080         client->before_state = client->current_state;
3081         client->current_state = TTS_STATE_PLAYING;
3082
3083         if (NULL != client->state_changed_cb) {
3084                 tts_client_use_callback(client);
3085                 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
3086                 tts_client_not_use_callback(client);
3087                 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
3088         }
3089
3090         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
3091
3092         return TTS_ERROR_NONE;
3093 }
3094
3095 int tts_stop_pcm(tts_h tts)
3096 {
3097         if (0 != __tts_get_feature_enabled()) {
3098                 return TTS_ERROR_NOT_SUPPORTED;
3099         }
3100
3101         SLOG(LOG_INFO, TAG_TTSC, "@@@ Stop pcm tts");
3102
3103         int ret = -1;
3104
3105         if (NULL == tts) {
3106                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null.");
3107                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
3108                 return TTS_ERROR_INVALID_PARAMETER;
3109         }
3110
3111         tts_client_s* client = tts_client_get(tts);
3112
3113         if (NULL == client) {
3114                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid.");
3115                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
3116                 return TTS_ERROR_INVALID_PARAMETER;
3117         }
3118
3119         if (TTS_STATE_CREATED == client->current_state) {
3120                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid.");
3121                 return TTS_ERROR_INVALID_STATE;
3122         }
3123
3124         if (false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode) {
3125                 ret = __tts_recheck_screen_reader();
3126                 if (0 != ret) {
3127                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret);
3128                         return TTS_ERROR_INVALID_STATE;
3129                 } else {
3130                         if (false == g_screen_reader) {
3131                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is NOT available.");
3132                                 return TTS_ERROR_INVALID_STATE;
3133                         }
3134                 }
3135         }
3136
3137         ret = -1;
3138         int count = 0;
3139         bool is_prepared = false;
3140         while (0 != ret) {
3141                 ret = tts_dbus_request_stop_pcm(client->uid);
3142                 if (0 != ret) {
3143                         if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
3144                                 client->current_state = TTS_STATE_CREATED;
3145                                 if (0 == tts_prepare_sync(tts)) {
3146                                         is_prepared = true;
3147                                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
3148                                 }
3149                         } else if (TTS_ERROR_TIMED_OUT != ret) {
3150                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
3151                                 return ret;
3152                         } else {
3153                                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry stop pcm : %s", __tts_get_error_code(ret));
3154                                 usleep(10000);
3155                                 count++;
3156                                 if (TTS_RETRY_COUNT == count) {
3157                                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request");
3158                                         return ret;
3159                                 }
3160                         }
3161                 }
3162         }
3163
3164         client->before_state = client->current_state;
3165         client->current_state = TTS_STATE_READY;
3166
3167         if (NULL != client->state_changed_cb) {
3168                 tts_client_use_callback(client);
3169                 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
3170                 tts_client_not_use_callback(client);
3171                 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
3172         }
3173
3174         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
3175
3176         return TTS_ERROR_NONE;
3177 }
3178 //LCOV_EXCL_STOP
3179
3180 int tts_repeat(tts_h tts, char** text_repeat, int* utt_id)
3181 {
3182         if (0 != __tts_get_feature_enabled()) {
3183                 return TTS_ERROR_NOT_SUPPORTED;
3184         }
3185
3186         SLOG(LOG_INFO, TAG_TTSC, "@@@ Repeat TTS");
3187
3188         if (NULL == tts) {
3189                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null.");
3190                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
3191                 return TTS_ERROR_INVALID_PARAMETER;
3192         }
3193
3194         if (NULL == text_repeat || NULL == utt_id) {
3195                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null.");
3196                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
3197                 return TTS_ERROR_INVALID_PARAMETER;
3198         }
3199
3200         *text_repeat = NULL;
3201         *utt_id = -1;
3202
3203         tts_client_s* client = tts_client_get(tts);
3204
3205         if (NULL == client) {
3206                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid.");
3207                 SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
3208                 return TTS_ERROR_INVALID_PARAMETER;
3209         }
3210
3211         if (TTS_STATE_READY != client->current_state) {
3212                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid. (%d)", client->current_state);
3213                 return TTS_ERROR_INVALID_STATE;
3214         }
3215
3216         /* Clear the legacy and Add texts to be played repeatedly */
3217         int ret = -1;
3218         ret = tts_stop(tts);
3219         if (TTS_ERROR_NONE != ret) {
3220                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to clear the legacy");
3221                 return ret;
3222         }
3223
3224         if (NULL != client->text_repeat) {
3225                 char* tmp_text = strdup(client->text_repeat);
3226                 char* tmp_lang = NULL;
3227                 if (NULL != g_language) {
3228                         tmp_lang = strdup(g_language);
3229                 }
3230                 ret = tts_add_text(tts, tmp_text, tmp_lang, g_voice_type, g_speed, utt_id);
3231                 if (TTS_ERROR_NONE != ret) {
3232                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to add texts for repetition.");
3233                         if (NULL != tmp_text) {
3234                                 free(tmp_text);
3235                                 tmp_text = NULL;
3236                         }
3237                         if (NULL != tmp_lang) {
3238                                 free(tmp_lang);
3239                                 tmp_lang = NULL;
3240                         }
3241                         return ret;
3242                 }
3243                 *text_repeat = strdup(client->text_repeat);
3244                 SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] text to repeat(%s), utt_id(%d)", (*text_repeat) ? *text_repeat : "NULL", *utt_id);
3245                 if (NULL != tmp_text) {
3246                         free(tmp_text);
3247                         tmp_text = NULL;
3248                 }
3249                 if (NULL != tmp_lang) {
3250                         free(tmp_lang);
3251                         tmp_lang = NULL;
3252                 }
3253         } else {
3254                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] There is no previous added texts. Please add texts");
3255                 return TTS_ERROR_OPERATION_FAILED;
3256         }
3257
3258         /* Play added texts */
3259         ret = tts_play(tts);
3260         if (TTS_ERROR_NONE != ret) {
3261                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to play texts for repetition.");
3262                 if (NULL != *text_repeat) {
3263                         free(*text_repeat);
3264                         *text_repeat = NULL;
3265                 }
3266                 *utt_id = -1;
3267                 return ret;
3268         }
3269
3270         return TTS_ERROR_NONE;
3271 }