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