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