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