Add g_steal_pointer to avoid double-free
[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 <system_info.h>
18 #include <vconf.h>
19 #include <package-manager.h>
20 #include <pthread.h>
21
22 #include "tts.h"
23 #include "tts_client.h"
24 #include "tts_config_mgr.h"
25 #include "tts_main.h"
26 #include "tts_core.h"
27 #include "tts_ipc.h"
28 #include "tts_dlog.h"
29
30 #include "tts_internal.h"
31
32 #define MAX_SILENT_DURATION 5000
33
34 static int g_feature_enabled = -1;
35
36
37 static int __tts_get_feature_enabled()
38 {
39         RETV_IF(1 == g_feature_enabled, TTS_ERROR_NONE);
40         RETVM_IF(0 == g_feature_enabled, TTS_ERROR_NOT_SUPPORTED, "[ERROR] TTS feature NOT supported");
41
42         bool tts_supported = false;
43         if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_bool(TTS_FEATURE_PATH, &tts_supported)) {
44                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get feature value");
45                 return TTS_ERROR_NOT_SUPPORTED;
46         }
47
48         if (false == tts_supported) {
49                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] TTS feature NOT supported");
50                 g_feature_enabled = 0;
51                 return TTS_ERROR_NOT_SUPPORTED;
52         }
53
54         g_feature_enabled = 1;
55         return TTS_ERROR_NONE;
56 }
57
58 // TODO: move into tts_core to make common function
59 //LCOV_EXCL_START
60 static int __tts_convert_config_error_code(tts_config_error_e code)
61 {
62         if (code == TTS_CONFIG_ERROR_NONE)                      return TTS_ERROR_NONE;
63         if (code == TTS_CONFIG_ERROR_OUT_OF_MEMORY)             return TTS_ERROR_OUT_OF_MEMORY;
64         if (code == TTS_CONFIG_ERROR_IO_ERROR)                  return TTS_ERROR_IO_ERROR;
65         if (code == TTS_CONFIG_ERROR_INVALID_PARAMETER)         return TTS_ERROR_INVALID_PARAMETER;
66         if (code == TTS_CONFIG_ERROR_INVALID_STATE)             return TTS_ERROR_INVALID_STATE;
67         if (code == TTS_CONFIG_ERROR_INVALID_VOICE)             return TTS_ERROR_INVALID_VOICE;
68         if (code == TTS_CONFIG_ERROR_ENGINE_NOT_FOUND)          return TTS_ERROR_ENGINE_NOT_FOUND;
69         if (code == TTS_CONFIG_ERROR_OPERATION_FAILED)          return TTS_ERROR_OPERATION_FAILED;
70         if (code == TTS_CONFIG_ERROR_NOT_SUPPORTED_FEATURE)     return TTS_ERROR_NOT_SUPPORTED_FEATURE;
71
72         return code;
73 }
74
75 static 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)
76 {
77         SLOG(LOG_DEBUG, TAG_TTSC, "Voice changed : Before lang(%s) type(%d) , Current lang(%s), type(%d)",
78                 before_lang, before_voice_type, language, voice_type);
79
80         GList* client_list = tts_client_get_client_list();
81         if (NULL == client_list) {
82                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get client list");
83                 return;
84         }
85
86         GList *iter = NULL;
87         if (g_list_length(client_list) > 0) {
88                 /* Get a first item */
89                 iter = g_list_first(client_list);
90
91                 while (NULL != iter) {
92                         tts_client_s *client = iter->data;
93                         if (tts_client_is_valid_client(client)) {
94                                 tts_core_notify_default_voice_changed(client, before_lang, before_voice_type, language, voice_type);
95
96                                 /* Check whether language is changed or not. If it is changed, make 'text_repeat' NULL */
97                                 if (0 != strncmp(before_lang, language, strlen(before_lang))) {
98                                         tts_client_set_repeat_text(client, NULL);
99                                 }
100                         } else {
101                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid (%p)", client);
102                         }
103
104                         /* Next item */
105                         iter = g_list_next(iter);
106                 }
107         }
108
109         g_list_free(client_list);
110
111         return;
112 }
113
114 static 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)
115 {
116         tts_h tts = (tts_h)user_data;
117
118         tts_client_s* client = tts_client_get(tts);
119         RETM_IF(NULL == client, "[ERROR] A handle is not valid. tts(%p)", tts);
120
121         if (NULL != engine_id)  SLOG(LOG_DEBUG, TAG_TTSC, "Engine id(%s)", engine_id);
122         if (NULL != setting)    SLOG(LOG_DEBUG, TAG_TTSC, "Engine setting(%s)", setting);
123         if (NULL != language)   SLOG(LOG_DEBUG, TAG_TTSC, "Language(%s)", language);
124         SLOG(LOG_DEBUG, TAG_TTSC, "Voice type(%d), Auto voice(%s), Credential(%s)", voice_type, auto_voice ? "on" : "off", need_credential ? "need" : "no need");
125
126         /* When the default engine is changed, please unload the old engine and load the new one. */
127 /*      int ret = -1;
128
129         tts_state_e current_state = tts_client_get_current_state(client);
130         if (TTS_STATE_PLAYING == current_state || TTS_STATE_PAUSED == current_state) {
131                 ret = tts_stop(tts);
132                 if (0 != ret) {
133                         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] TTS client stopping...");
134                 }
135
136                 ecore_idler_add(__reconnect_by_engine_changed, (void*)tts);
137         } else if (TTS_STATE_READY == current_state) {
138                 // TODO: change to tts_core function
139                 ret = tts_unprepare(tts);
140                 if (0 != ret) {
141                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to unprepare for setting a new engine... (%d)", ret);
142                 }
143                 ret = tts_prepare(tts);
144                 if (0 != ret) {
145                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
146                 }
147         }
148 */
149         /* call callback function */
150         tts_core_notify_engine_changed(client, engine_id, language, voice_type, need_credential);
151         return;
152 }
153 //LCOV_EXCL_STOP
154
155 static void __tts_config_screen_reader_changed_cb(bool value, void* user_data)
156 {
157         tts_h tts = (tts_h)user_data;
158
159         tts_client_s* client = tts_client_get(tts);
160         RETM_IF(NULL == client, "[ERROR] A handle is not valid. tts(%p)", tts);
161
162         SLOG(LOG_DEBUG, TAG_TTSC, "Screen reader is changed. current status (%d)", value);
163
164         /* call callback function */
165         tts_core_notify_screen_reader_changed(client, value);
166 }
167
168 static int __initialize_tts_config(unsigned int uid, tts_h new_tts)
169 {
170         int ret = tts_config_mgr_initialize(uid, TTS_CONFIG_CLIENT_TYPE_DEFAULT);
171         if (TTS_CONFIG_ERROR_NONE != ret) {
172                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to init config manager : %d", ret);
173                 return __tts_convert_config_error_code(ret);
174         }
175
176         ret = tts_config_mgr_set_callback(uid, __tts_config_engine_changed_cb, __tts_config_voice_changed_cb, NULL, NULL, NULL, new_tts);
177         if (TTS_CONFIG_ERROR_NONE != ret) {
178                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set config changed : %d", ret);
179                 tts_config_mgr_finalize(uid, TTS_CONFIG_CLIENT_TYPE_DEFAULT);
180                 return __tts_convert_config_error_code(ret);
181         }
182
183         ret = tts_config_mgr_set_screen_reader_callback(uid, __tts_config_screen_reader_changed_cb, new_tts);
184         if (TTS_CONFIG_ERROR_NONE != ret) {
185                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set config changed : %d", ret);
186                 tts_config_mgr_finalize(uid, TTS_CONFIG_CLIENT_TYPE_DEFAULT);
187                 return __tts_convert_config_error_code(ret);
188         }
189
190         return TTS_ERROR_NONE;
191 }
192
193 int tts_create(tts_h* tts)
194 {
195         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
196
197         SLOG(LOG_INFO, TAG_TTSC, "@@@ Create TTS");
198
199         RETVM_IF(NULL == tts, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input handle is null");
200
201         bool is_first_client = false;
202         if (0 == tts_client_get_size()) {
203                 is_first_client = true;
204         }
205
206         tts_h new_tts = NULL;
207         if (0 != tts_client_new(&new_tts)) {
208                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create client!!!!!");
209                 return TTS_ERROR_OUT_OF_MEMORY;
210         }
211
212         tts_client_s* client = tts_client_get(new_tts);
213         if (NULL == client) {
214                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get client");
215                 tts_client_destroy(new_tts);
216                 return TTS_ERROR_OPERATION_FAILED;
217         }
218
219         unsigned int uid = tts_client_get_uid(client);
220         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%u)", tts, client, uid);
221
222         if (false == tts_ipc_is_method_set()) {
223                 int pid = getpid();
224                 char* appid = NULL;
225                 int ret = app_manager_get_app_id(pid, &appid);
226                 if (0 != ret || NULL == appid) {
227                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get appid, ret(%d), pid(%d)", ret, pid);
228                         tts_ipc_set_method(TTS_IPC_METHOD_DBUS);
229                 } else {
230                         SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_create : client appid(%s), pid(%d)", appid, pid);
231                         tts_ipc_set_method(TTS_IPC_METHOD_TIDL);
232                 }
233
234                 if (NULL != appid) {
235                         free(appid);
236                         appid = NULL;
237                 }
238         }
239
240         if (0 != tts_ipc_open_connection(uid)) {
241                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open ipc connection");
242                 tts_client_destroy(new_tts);
243                 return TTS_ERROR_OPERATION_FAILED;
244         }
245
246         int ret = __initialize_tts_config(uid, new_tts);
247         if (TTS_ERROR_NONE != ret) {
248                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to init config manager : %d", ret);
249                 tts_client_destroy(new_tts);
250                 return ret;
251         }
252
253         if (is_first_client) {
254                 // These function would be called only when first client is created.
255                 if (0 != tts_core_initialize()) {
256                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize core");
257                         tts_config_mgr_finalize(uid, TTS_CONFIG_CLIENT_TYPE_DEFAULT);
258                         tts_client_destroy(new_tts);
259                         return TTS_ERROR_OPERATION_FAILED;
260                 }
261         }
262
263         *tts = new_tts;
264         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
265         return TTS_ERROR_NONE;
266 }
267
268 static int destroy_tts_handle(tts_h tts)
269 {
270         SLOG(LOG_INFO, TAG_TTSC, "Destroy TTS handle");
271         tts_client_s* client = tts_client_get(tts);
272         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
273
274         unsigned int uid = tts_client_get_uid(client);
275         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%u)", tts, client, uid);
276
277         /* check used callback */
278         if (0 != tts_client_get_use_callback(client)) {
279                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Cannot destroy in Callback function");
280                 return TTS_ERROR_OPERATION_FAILED;
281         }
282
283         tts_config_mgr_finalize(uid, TTS_CONFIG_CLIENT_TYPE_DEFAULT);
284
285         // TODO: move into tts_client
286         if (client->hello_timer) {
287                 ecore_timer_del(client->hello_timer);
288                 client->hello_timer = NULL;
289         }
290
291         switch (tts_client_get_current_state(client)) {
292         case TTS_STATE_PAUSED:
293         case TTS_STATE_PLAYING:
294         case TTS_STATE_READY: {
295                 if (0 != tts_core_unprepare(client)) {
296                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to unprepare");
297                 }
298                 tts_client_set_current_state(client, TTS_STATE_CREATED);
299         }
300         case TTS_STATE_CREATED: {
301                 /* Unset registered callbacks */
302                 tts_client_unset_all_cb(client);
303
304                 if (0 != tts_ipc_close_connection(uid)) {
305                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection");
306                         return TTS_ERROR_OPERATION_FAILED;
307                 }
308
309                 /* Free resources */
310                 tts_client_destroy(tts);
311
312                 break;
313         }
314         default: {
315                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid");
316                 return TTS_ERROR_INVALID_PARAMETER;
317         }
318         }
319
320         unsigned int num_of_client = tts_client_get_size();
321         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] num_of_client(%u)", num_of_client);
322
323         if (0 == num_of_client) {
324                 if (0 != tts_core_deinitialize()) {
325                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to deinitialize core");
326                 }
327         }
328
329         return TTS_ERROR_NONE;
330 }
331
332 static void *destroy_tts_handle_on_main_thread(void* data)
333 {
334         SLOG(LOG_INFO, TAG_TTSC, "Destroy on main thread synchronously");
335         tts_h tts = (tts_h)data;
336
337         int ret = destroy_tts_handle(tts);
338         intptr_t p_ret = (intptr_t)ret;
339
340         return (void *)p_ret;
341 }
342
343 int tts_destroy(tts_h tts)
344 {
345         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
346         SLOG(LOG_INFO, TAG_TTSC, "@@@ Destroy TTS");
347
348         intptr_t ret = (intptr_t)ecore_main_loop_thread_safe_call_sync(destroy_tts_handle_on_main_thread, (void *)tts);
349         SLOG(LOG_INFO, TAG_TTSC, "Return value: (%d/%s)", (int)ret, get_error_message((int)ret));
350
351         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
352         return (int)ret;
353 }
354
355 int tts_set_mode(tts_h tts, tts_mode_e mode)
356 {
357         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
358
359         SLOG(LOG_INFO, TAG_TTSC, "@@@ Set TTS mode(%d)", mode);
360
361         RETVM_IF(TTS_MODE_DEFAULT > mode || TTS_MODE_INTERRUPT < mode, TTS_ERROR_INVALID_PARAMETER, "[ERROR] mode is not valid : %d", mode);
362
363         tts_client_s* client = tts_client_get(tts);
364         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
365
366         tts_state_e current_state = tts_client_get_current_state(client);
367         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
368
369         tts_client_set_mode(client, mode);
370
371         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
372         return TTS_ERROR_NONE;
373 }
374
375 int tts_get_mode(tts_h tts, tts_mode_e* mode)
376 {
377         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
378
379         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Get TTS mode");
380
381         RETVM_IF(NULL == mode, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter(mode) is NULL");
382
383         tts_client_s* client = tts_client_get(tts);
384         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
385
386         tts_state_e current_state = tts_client_get_current_state(client);
387         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
388
389         *mode = tts_client_get_mode(client);
390
391         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
392         return TTS_ERROR_NONE;
393 }
394
395 int tts_set_playing_mode(tts_h tts, tts_playing_mode_e mode)
396 {
397         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
398
399         SLOG(LOG_INFO, TAG_TTSC, "@@@ Set TTS playing mode(%d)", mode);
400
401         RETVM_IF(TTS_PLAYING_MODE_BY_SERVICE > mode || TTS_PLAYING_MODE_BY_CLIENT < mode, TTS_ERROR_INVALID_PARAMETER, "[ERROR] mode is not valid : %d", mode);
402
403         tts_client_s* client = tts_client_get(tts);
404         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
405
406         tts_state_e current_state = tts_client_get_current_state(client);
407         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
408
409         tts_client_set_playing_mode(client, mode);
410
411         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
412         return TTS_ERROR_NONE;
413 }
414
415 int tts_set_credential(tts_h tts, const char* credential)
416 {
417         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
418
419         RETVM_IF(NULL == credential, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter is null");
420
421         tts_client_s* client = tts_client_get(tts);
422         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
423
424         tts_state_e current_state = tts_client_get_current_state(client);
425         RETVM_IF(TTS_STATE_CREATED != current_state && TTS_STATE_READY != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
426
427         tts_client_set_credential_key(client, credential);
428
429         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
430         return TTS_ERROR_NONE;
431 }
432
433 int tts_set_server_tts(tts_h tts, const char* credential)
434 {
435         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
436
437         tts_client_s* client = tts_client_get(tts);
438         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
439
440         // TODO: fix state check, because set_private_data runs only ready state
441         tts_state_e current_state = tts_client_get_current_state(client);
442         RETVM_IF(TTS_STATE_CREATED != current_state && TTS_STATE_READY != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
443
444         // TODO: fix name more clear and move into tts_client
445         client->internal = true;
446
447         char* key = NULL;
448         if (NULL != credential) {
449                 key = "EnableServerTTS";
450                 tts_client_set_credential_key(client, credential);
451                 if (NULL == tts_client_get_credential_key(client)) {
452                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to allocate memory");
453                         return TTS_ERROR_OUT_OF_MEMORY;
454                 }
455         } else {
456                 key = "DisableServerTTS";
457         }
458
459         int pid = getpid();
460         char* appid = NULL;
461         int ret = app_manager_get_app_id(pid, &appid);
462         if (0 != ret || NULL == appid) {
463                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get appid, ret(%d), pid(%d), appid(%s)", ret, pid, appid);;
464                 free(appid);
465                 appid = NULL;
466                 return TTS_ERROR_OPERATION_FAILED;
467         }
468
469         ret = tts_core_set_private_data(client, key, appid);
470         if (0 != ret) {
471                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set private data, ret(%d), pid(%d), appid(%s)", ret, pid, appid);
472                 free(appid);
473                 appid = NULL;
474                 return ret;
475         }
476
477         free(appid);
478         appid = NULL;
479
480         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
481         return TTS_ERROR_NONE;
482 }
483
484 int tts_prepare(tts_h tts)
485 {
486         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
487
488         tts_client_s* client = tts_client_get(tts);
489         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
490
491         tts_state_e current_state = tts_client_get_current_state(client);
492         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
493
494         SLOG(LOG_INFO, TAG_TTSC, "@@@ Prepare TTS");
495         int ret = tts_core_prepare(client);
496         if (0 != ret) {
497                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] tts_core_prepare failed. (%s)", tts_core_covert_error_code(ret));
498                 return ret;
499         }
500
501         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
502         return TTS_ERROR_NONE;
503 }
504
505 int tts_prepare_sync(tts_h tts)
506 {
507         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
508
509         tts_client_s* client = tts_client_get(tts);
510         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
511
512         tts_state_e current_state = tts_client_get_current_state(client);
513         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
514
515         SLOG(LOG_INFO, TAG_TTSC, "@@@ Prepare TTS synchronously");
516         int ret = tts_core_prepare_sync(client);
517         if (TTS_ERROR_NONE != ret) {
518                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] tts_core_prepare_sync failed. (%s)", tts_core_covert_error_code(ret));
519                 return ret;
520         }
521
522         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
523         return TTS_ERROR_NONE;
524 }
525
526 int tts_unprepare(tts_h tts)
527 {
528         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
529
530         tts_client_s* client = tts_client_get(tts);
531         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
532
533         tts_state_e current_state = tts_client_get_current_state(client);
534         RETVM_IF(TTS_STATE_READY != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
535
536         SLOG(LOG_INFO, TAG_TTSC, "@@@ Unprepare TTS");
537         int ret = tts_core_unprepare(client);
538         if (0 != ret) {
539                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] tts_core_unprepare is failed(%s)", tts_core_covert_error_code(ret));
540                 return ret;
541         }
542
543         tts_core_notify_state_changed(client, TTS_STATE_CREATED);
544
545         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
546         return TTS_ERROR_NONE;
547 }
548
549 int tts_foreach_supported_voices(tts_h tts, tts_supported_voice_cb callback, void* user_data)
550 {
551         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
552
553         SLOG(LOG_INFO, TAG_TTSC, "@@@ Foreach supported voices");
554
555         RETVM_IF(NULL == callback, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter is null");
556
557         tts_client_s* client = tts_client_get(tts);
558         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
559
560         int ret = 0;
561         char* current_engine = NULL;
562         ret = tts_config_mgr_get_engine(&current_engine);
563         if (0 != ret || NULL == current_engine) {
564                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get current engine : %d", ret);
565                 return __tts_convert_config_error_code(ret);
566         }
567
568         ret = tts_core_foreach_supported_voices(client, current_engine, callback, user_data);
569         free(current_engine);
570
571         if (0 != ret) {
572                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
573                 return ret;
574         }
575
576         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
577         return TTS_ERROR_NONE;
578 }
579
580 int tts_get_default_voice(tts_h tts, char** lang, int* vctype)
581 {
582         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
583
584         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Get default voice");
585
586         RETVM_IF(NULL == lang || NULL == vctype, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid");
587
588         tts_client_s* client = tts_client_get(tts);
589         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
590
591         /* Request call remote method */
592         int ret = 0;
593         ret = tts_config_mgr_get_voice(lang, vctype);
594         if (0 != ret) {
595                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
596                 return __tts_convert_config_error_code(ret);
597         }
598
599         SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Default language(%s), type(%d)", *lang, *vctype);
600         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
601         return TTS_ERROR_NONE;
602 }
603
604 int tts_get_max_text_size(tts_h tts, unsigned int* size)
605 {
606         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
607
608         RETVM_IF(NULL == size, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Get max text count : Input parameter is null");
609
610         tts_client_s* client = tts_client_get(tts);
611         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
612
613         tts_state_e current_state = tts_client_get_current_state(client);
614         RETVM_IF(TTS_STATE_READY != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
615
616         if (0 != tts_config_mgr_get_max_text_size(size)) {
617                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get max text size");
618                 return TTS_ERROR_OPERATION_FAILED;
619         }
620
621         SLOG(LOG_INFO, TAG_TTSC, "Get max text size : %d byte", *size);
622         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
623         return TTS_ERROR_NONE;
624 }
625
626 int tts_get_state(tts_h tts, tts_state_e* state)
627 {
628         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
629
630         RETVM_IF(NULL == state, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Get state : Input parameter is null");
631
632         tts_client_s* client = tts_client_get(tts);
633         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
634
635         tts_state_e current_state = tts_client_get_current_state(client);
636         switch (current_state) {
637         case TTS_STATE_CREATED: SLOG(LOG_INFO, TAG_TTSC, "Current state is 'Created'"); break;
638         case TTS_STATE_READY:   SLOG(LOG_INFO, TAG_TTSC, "Current state is 'Ready'");   break;
639         case TTS_STATE_PLAYING: SLOG(LOG_INFO, TAG_TTSC, "Current state is 'Playing'"); break;
640         case TTS_STATE_PAUSED:  SLOG(LOG_INFO, TAG_TTSC, "Current state is 'Paused'");  break;
641         default:
642                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid");
643                 return TTS_ERROR_INVALID_PARAMETER;
644         }
645
646         *state = current_state;
647         return TTS_ERROR_NONE;
648 }
649
650 int tts_get_speed_range(tts_h tts, int* min, int* normal, int* max)
651 {
652         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
653
654         RETVM_IF(NULL == min || NULL == normal || NULL == max, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter is null");
655
656         tts_client_s* client = tts_client_get(tts);
657         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
658
659         *min = TTS_SPEED_MIN;
660         *normal = TTS_SPEED_NORMAL;
661         *max = TTS_SPEED_MAX;
662
663         return TTS_ERROR_NONE;
664 }
665
666 int tts_get_error_message(tts_h tts, char** err_msg)
667 {
668         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
669
670         RETVM_IF(NULL == err_msg, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter is null");
671
672         tts_client_s* client = tts_client_get(tts);
673         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
674
675         const char* error_message = tts_client_get_error_message(client);
676         if (NULL != error_message) {
677                 *err_msg = strdup(error_message);
678                 SLOG(LOG_DEBUG, TAG_TTSC, "Error msg (%s)", error_message);
679         } else {
680                 *err_msg = NULL;
681                 SLOG(LOG_DEBUG, TAG_TTSC, "Error msg (NULL)");
682         }
683
684         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
685         return TTS_ERROR_NONE;
686 }
687
688 int tts_check_screen_reader_on(tts_h tts, bool* is_on)
689 {
690         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
691
692         RETVM_IF(NULL == is_on, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter is null");
693
694         tts_client_s* client = tts_client_get(tts);
695         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
696
697         if (false == tts_core_check_screen_reader(client)) {
698                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Screen reader option is not available");
699                 *is_on = false;
700         } else {
701                 SLOG(LOG_INFO, TAG_TTSC, "[INFO] Screen reader option is available");
702                 *is_on = true;
703         }
704
705         return TTS_ERROR_NONE;
706 }
707
708 int tts_get_service_state(tts_h tts, tts_service_state_e* service_state)
709 {
710         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
711
712         RETVM_IF(NULL == service_state, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Get service state : Input parameter is null");
713
714         tts_client_s* client = tts_client_get(tts);
715         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
716
717         tts_state_e current_state = tts_client_get_current_state(client);
718         RETVM_IF(TTS_STATE_CREATED == current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
719
720         int ret = tts_core_get_service_state(client, service_state);
721         if (TTS_ERROR_NONE != ret) {
722                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get service state. ret(%d/%s)", ret, get_error_message(ret));
723                 return ret;
724         }
725
726         return TTS_ERROR_NONE;
727 }
728
729 int tts_add_text(tts_h tts, const char* text, const char* language, int voice_type, int speed, int* utt_id)
730 {
731         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
732
733         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Add text: text(%s), language(%s), type(%d)", (NULL == text) ? "NULL" : text, (NULL == language) ? "NULL" : language, voice_type);
734
735         RETVM_IF(TTS_SPEED_AUTO > speed || TTS_SPEED_MAX < speed, TTS_ERROR_INVALID_PARAMETER, "[ERROR] speed value(%d) is invalid.", speed);
736         RETVM_IF(voice_type < 0, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Voice type should not be negative(%d)", voice_type);
737         RETVM_IF(NULL == utt_id, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter is null");
738         RETVM_IF(false == tts_core_is_valid_text(text), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input text is invalid");
739
740         tts_client_s* client = tts_client_get(tts);
741         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
742
743         tts_state_e current_state = tts_client_get_current_state(client);
744         RETVM_IF(TTS_STATE_CREATED == current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
745
746         RETVM_IF(false == tts_core_check_screen_reader(client), TTS_ERROR_SCREEN_READER_OFF, "[ERROR] Screen reader option is not available");
747         RETVM_IF(false == tts_core_check_credential(client), TTS_ERROR_PERMISSION_DENIED, "[ERROR] Do not have app credential for this engine");
748
749         int ret = tts_core_add_text(client, text, language, voice_type, speed, utt_id);
750         if (TTS_ERROR_NONE != ret) {
751                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request add text. ret(%s)", tts_core_covert_error_code(ret));
752                 return ret;
753         }
754
755         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
756         return TTS_ERROR_NONE;
757 }
758
759 //LCOV_EXCL_START
760 static void __tts_play_async(void *data)
761 {
762         tts_h tts = (tts_h)data;
763
764         tts_client_s* client = tts_client_get(tts);
765         RETM_IF(NULL == client, "[ERROR] A handle is not valid. tts(%p)", tts);
766
767         int ret = tts_core_play(client);
768         if (0 != ret) {
769                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to play tts : %s", tts_core_covert_error_code(ret));
770                 tts_core_notify_error_async(client, ret, -1, NULL);
771                 return;
772         }
773
774         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
775         return;
776 }
777
778 int tts_play_async(tts_h tts)
779 {
780         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
781
782         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Play asynchronously tts");
783
784         tts_client_s* client = tts_client_get(tts);
785         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
786
787         tts_state_e current_state = tts_client_get_current_state(client);
788         RETVM_IF(TTS_STATE_PLAYING == current_state || TTS_STATE_CREATED == current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
789
790         RETVM_IF(false == tts_core_check_screen_reader(client), TTS_ERROR_SCREEN_READER_OFF, "[ERROR] Screen reader option is not available");
791         RETVM_IF(false == tts_core_check_credential(client), TTS_ERROR_PERMISSION_DENIED, "[ERROR] Do not have app credential for this engine");
792
793         ecore_main_loop_thread_safe_call_async(__tts_play_async, (void*)tts);
794
795         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
796         return TTS_ERROR_NONE;
797 }
798 //LCOV_EXCL_STOP
799
800 int tts_play(tts_h tts)
801 {
802         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
803
804         SLOG(LOG_INFO, TAG_TTSC, "@@@ Play tts");
805
806         tts_client_s* client = tts_client_get(tts);
807         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
808
809         tts_state_e current_state = tts_client_get_current_state(client);
810         RETVM_IF(TTS_STATE_PLAYING == current_state || TTS_STATE_CREATED == current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
811
812         RETVM_IF(false == tts_core_check_screen_reader(client), TTS_ERROR_SCREEN_READER_OFF, "[ERROR] Screen reader option is not available");
813         RETVM_IF(false == tts_core_check_credential(client), TTS_ERROR_PERMISSION_DENIED, "[ERROR] Do not have app credential for this engine");
814
815         int ret = tts_core_play(client);
816         if (TTS_ERROR_NONE != ret) {
817                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request play. ret(%s)", tts_core_covert_error_code(ret));
818                 return ret;
819         }
820
821         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
822         return TTS_ERROR_NONE;
823 }
824
825 //LCOV_EXCL_START
826 static void __tts_stop_async(void *data)
827 {
828         tts_h tts = (tts_h)data;
829
830         tts_client_s* client = tts_client_get(tts);
831         RETM_IF(NULL == client, "[ERROR] A handle is not valid. tts(%p)", tts);
832
833         int ret = tts_core_stop(client);
834         if (0 != ret) {
835                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to stop tts : %s", tts_core_covert_error_code(ret));
836                 tts_core_notify_error_async(client, ret, -1, NULL);
837                 return;
838         }
839
840         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
841         return;
842 }
843
844 int tts_stop_aync(tts_h tts)
845 {
846         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
847
848         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Stop asynchronously tts");
849
850         tts_client_s* client = tts_client_get(tts);
851         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
852
853         tts_state_e current_state = tts_client_get_current_state(client);
854         RETVM_IF(TTS_STATE_CREATED == current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
855
856         RETVM_IF(false == tts_core_check_screen_reader(client), TTS_ERROR_SCREEN_READER_OFF, "[ERROR] Screen reader option is not available");
857
858         ecore_main_loop_thread_safe_call_async(__tts_stop_async, (void*)tts);
859
860         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
861         return TTS_ERROR_NONE;
862 }
863 //LCOV_EXCL_STOP
864
865 int tts_stop(tts_h tts)
866 {
867         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
868
869         SLOG(LOG_INFO, TAG_TTSC, "@@@ Stop tts");
870
871         tts_client_s* client = tts_client_get(tts);
872         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
873
874         tts_state_e current_state = tts_client_get_current_state(client);
875         RETVM_IF(TTS_STATE_CREATED == current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
876
877         int ret = tts_core_stop(client);
878         if (TTS_ERROR_NONE != ret) {
879                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request stop. ret(%s)", tts_core_covert_error_code(ret));
880                 return ret;
881         }
882
883         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
884         return TTS_ERROR_NONE;
885 }
886
887 //LCOV_EXCL_START
888 static void __tts_pause_async(void *data)
889 {
890         tts_h tts = (tts_h)data;
891
892         tts_client_s* client = tts_client_get(tts);
893         RETM_IF(NULL == client, "[ERROR] A handle is not valid. tts(%p)", tts);
894
895         int ret = tts_core_pause(client);
896         if (0 != ret) {
897                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to pause tts : %s", tts_core_covert_error_code(ret));
898                 tts_core_notify_error_async(client, ret, -1, NULL);
899                 return;
900         }
901
902         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
903         return;
904 }
905
906 int tts_pause_async(tts_h tts)
907 {
908         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
909
910         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Pause asynchronously tts");
911
912         tts_client_s* client = tts_client_get(tts);
913         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
914
915         tts_state_e current_state = tts_client_get_current_state(client);
916         RETVM_IF(TTS_STATE_PLAYING != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
917
918         RETVM_IF(false == tts_core_check_screen_reader(client), TTS_ERROR_SCREEN_READER_OFF, "[ERROR] Screen reader option is not available");
919
920         ecore_main_loop_thread_safe_call_async(__tts_pause_async, (void*)tts);
921
922         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
923         return TTS_ERROR_NONE;
924 }
925 //LCOV_EXCL_STOP
926 int tts_pause(tts_h tts)
927 {
928         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
929
930         SLOG(LOG_INFO, TAG_TTSC, "@@@ Pause tts");
931
932         tts_client_s* client = tts_client_get(tts);
933         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
934
935         tts_state_e current_state = tts_client_get_current_state(client);
936         RETVM_IF(TTS_STATE_PLAYING != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
937
938         RETVM_IF(false == tts_core_check_screen_reader(client), TTS_ERROR_SCREEN_READER_OFF, "[ERROR] Screen reader option is not available");
939
940         int ret = tts_core_pause(client);
941         if (TTS_ERROR_NONE != ret) {
942                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request pause. ret(%s)", tts_core_covert_error_code(ret));
943                 return ret;
944         }
945
946         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
947         return TTS_ERROR_NONE;
948 }
949
950 int tts_set_private_data(tts_h tts, const char* key, const char* data)
951 {
952         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
953
954         SLOG(LOG_INFO, TAG_TTSC, "@@@ Set private data, key(%s), data(%s)", key, data);
955
956         RETVM_IF(NULL == key || NULL == data, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Invalid parameter");
957
958         tts_client_s* client = tts_client_get(tts);
959         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
960
961         tts_state_e current_state = tts_client_get_current_state(client);
962         RETVM_IF(TTS_STATE_READY != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
963
964         if (true != client->internal && (0 == strcmp(key, "EnableServerTTS") || 0 == strcmp(key, "DisableServerTTS"))) {
965                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] This is not an internal app");
966                 return TTS_ERROR_INVALID_PARAMETER;
967         }
968
969         int ret = tts_core_set_private_data(client, key, data);
970         if (TTS_ERROR_NONE != ret) {
971                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request set private data. ret(%s)", tts_core_covert_error_code(ret));
972                 return ret;
973         }
974
975         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
976         return 0;
977 }
978
979 int tts_get_private_data(tts_h tts, const char* key, char** data)
980 {
981         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
982
983         SLOG(LOG_INFO, TAG_TTSC, "@@@ Get private data, key(%s)", key);
984
985         RETVM_IF(NULL == key || NULL == data, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Invalid parameter");
986
987         tts_client_s* client = tts_client_get(tts);
988         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
989
990         tts_state_e current_state = tts_client_get_current_state(client);
991         RETVM_IF(TTS_STATE_READY != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
992
993         int ret = tts_core_get_private_data(client, key, data);
994         if (TTS_ERROR_NONE != ret) {
995                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request get private data. ret(%s)", tts_core_covert_error_code(ret));
996                 return ret;
997         }
998
999         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1000         return 0;
1001 }
1002
1003 int tts_set_state_changed_cb(tts_h tts, tts_state_changed_cb callback, void* user_data)
1004 {
1005         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1006
1007         tts_client_s* client = tts_client_get(tts);
1008         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1009
1010         RETVM_IF(NULL == callback, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Set state changed cb : Input parameter is null");
1011
1012         tts_state_e current_state = tts_client_get_current_state(client);
1013         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1014
1015         tts_client_set_state_changed_cb(client, callback, user_data);
1016
1017         SLOG(LOG_INFO, TAG_TTSC, "[SUCCESS] Set state changed cb");
1018         return 0;
1019 }
1020
1021 int tts_unset_state_changed_cb(tts_h tts)
1022 {
1023         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1024
1025         tts_client_s* client = tts_client_get(tts);
1026         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1027
1028         tts_state_e current_state = tts_client_get_current_state(client);
1029         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1030
1031         tts_client_set_state_changed_cb(client, NULL, NULL);
1032
1033         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset state changed cb");
1034         return 0;
1035 }
1036
1037 int tts_set_utterance_started_cb(tts_h tts, tts_utterance_started_cb callback, void* user_data)
1038 {
1039         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1040
1041         tts_client_s* client = tts_client_get(tts);
1042         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1043
1044         RETVM_IF(NULL == callback, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Set utt started cb : Input parameter is null");
1045
1046         tts_state_e current_state = tts_client_get_current_state(client);
1047         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1048
1049         tts_client_set_utterance_started_cb(client, callback, user_data);
1050
1051         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt started cb");
1052
1053         return 0;
1054 }
1055
1056 int tts_unset_utterance_started_cb(tts_h tts)
1057 {
1058         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1059
1060         tts_client_s* client = tts_client_get(tts);
1061         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1062
1063         tts_state_e current_state = tts_client_get_current_state(client);
1064         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1065
1066         tts_client_set_utterance_started_cb(client, NULL, NULL);
1067
1068         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt started cb");
1069
1070         return 0;
1071 }
1072
1073 int tts_set_utterance_completed_cb(tts_h tts, tts_utterance_completed_cb callback, void* user_data)
1074 {
1075         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1076
1077         tts_client_s* client = tts_client_get(tts);
1078         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1079
1080         RETVM_IF(NULL == callback, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Set utt completed cb : Input parameter is null");
1081
1082         tts_state_e current_state = tts_client_get_current_state(client);
1083         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1084
1085         tts_client_set_utterance_completed_cb(client, callback, user_data);
1086
1087         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt completed cb");
1088
1089         return 0;
1090 }
1091
1092 int tts_unset_utterance_completed_cb(tts_h tts)
1093 {
1094         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1095
1096         tts_client_s* client = tts_client_get(tts);
1097         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1098
1099         tts_state_e current_state = tts_client_get_current_state(client);
1100         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1101
1102         tts_client_set_utterance_completed_cb(client, NULL, NULL);
1103
1104         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt completed cb");
1105         return 0;
1106 }
1107
1108 int tts_set_error_cb(tts_h tts, tts_error_cb callback, void* user_data)
1109 {
1110         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1111
1112         tts_client_s* client = tts_client_get(tts);
1113         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1114
1115         RETVM_IF(NULL == callback, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Set error cb : Input parameter is null");
1116
1117         tts_state_e current_state = tts_client_get_current_state(client);
1118         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1119
1120         tts_client_set_error_cb(client, callback, user_data);
1121
1122         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set error cb");
1123
1124         return 0;
1125 }
1126
1127 int tts_unset_error_cb(tts_h tts)
1128 {
1129         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1130
1131         tts_client_s* client = tts_client_get(tts);
1132         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1133
1134         tts_state_e current_state = tts_client_get_current_state(client);
1135         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1136
1137         tts_client_set_error_cb(client, NULL, NULL);
1138
1139         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset error cb");
1140
1141         return 0;
1142 }
1143
1144 int tts_set_default_voice_changed_cb(tts_h tts, tts_default_voice_changed_cb callback, void* user_data)
1145 {
1146         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1147
1148         tts_client_s* client = tts_client_get(tts);
1149         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1150
1151         RETVM_IF(NULL == callback, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Set default voice changed cb : Input parameter is null");
1152
1153         tts_state_e current_state = tts_client_get_current_state(client);
1154         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1155
1156         tts_client_set_default_voice_changed_cb(client, callback, user_data);
1157
1158         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set default voice changed cb");
1159
1160         return 0;
1161 }
1162
1163 int tts_unset_default_voice_changed_cb(tts_h tts)
1164 {
1165         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1166
1167         tts_client_s* client = tts_client_get(tts);
1168         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1169
1170         tts_state_e current_state = tts_client_get_current_state(client);
1171         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1172
1173         tts_client_set_default_voice_changed_cb(client, NULL, NULL);
1174
1175         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset default voice changed cb");
1176
1177         return 0;
1178 }
1179
1180 int tts_set_engine_changed_cb(tts_h tts, tts_engine_changed_cb callback, void* user_data)
1181 {
1182         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1183
1184         tts_client_s* client = tts_client_get(tts);
1185         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1186
1187         RETVM_IF(NULL == callback, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Set engine changed cb : Input parameter is null");
1188
1189         tts_state_e current_state = tts_client_get_current_state(client);
1190         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1191
1192         tts_client_set_engine_changed_cb(client, callback, user_data);
1193
1194         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set engine changed cb");
1195
1196         return 0;
1197 }
1198
1199 int tts_unset_engine_changed_cb(tts_h tts)
1200 {
1201         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1202
1203         tts_client_s* client = tts_client_get(tts);
1204         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1205
1206         tts_state_e current_state = tts_client_get_current_state(client);
1207         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1208
1209         tts_client_set_engine_changed_cb(client, NULL, NULL);
1210
1211         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset engine changed cb");
1212
1213         return 0;
1214 }
1215
1216 int tts_set_screen_reader_changed_cb(tts_h tts, tts_screen_reader_changed_cb callback, void* user_data)
1217 {
1218         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1219
1220         tts_client_s* client = tts_client_get(tts);
1221         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1222
1223         RETVM_IF(NULL == callback, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Set screen reader changed cb : Input parameter is null");
1224
1225         tts_state_e current_state = tts_client_get_current_state(client);
1226         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1227
1228         tts_client_set_screen_reader_changed_cb(client, callback, user_data);
1229
1230         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set screen reader changed cb");
1231
1232         return 0;
1233 }
1234
1235 int tts_unset_screen_reader_changed_cb(tts_h tts)
1236 {
1237         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1238
1239         tts_client_s* client = tts_client_get(tts);
1240         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1241
1242         tts_state_e current_state = tts_client_get_current_state(client);
1243         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1244
1245         tts_client_set_screen_reader_changed_cb(client, NULL, NULL);
1246
1247         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset screen reader changed cb");
1248
1249         return 0;
1250 }
1251
1252 int tts_add_pcm(tts_h tts, int event, const void* data, unsigned int data_size, int audio_type, int rate)
1253 {
1254         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1255
1256         SLOG(LOG_INFO, TAG_TTSC, "@@@ Add pcm tts");
1257
1258         tts_client_s* client = tts_client_get(tts);
1259         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1260
1261         tts_state_e current_state = tts_client_get_current_state(client);
1262         RETVM_IF(TTS_STATE_CREATED == current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1263
1264         RETVM_IF(false == tts_core_check_screen_reader(client), TTS_ERROR_SCREEN_READER_OFF, "[ERROR] Screen reader option is not available");
1265
1266         int ret = tts_core_add_pcm(client, event, data, data_size, audio_type, rate);
1267         if (TTS_ERROR_NONE != ret) {
1268                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request add_pcm. ret(%s)", tts_core_covert_error_code(ret));
1269                 return ret;
1270         }
1271
1272         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1273         return TTS_ERROR_NONE;
1274 }
1275
1276 int tts_play_pcm(tts_h tts)
1277 {
1278         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1279
1280         SLOG(LOG_INFO, TAG_TTSC, "@@@ Play pcm tts");
1281
1282         tts_client_s* client = tts_client_get(tts);
1283         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1284
1285         tts_state_e current_state = tts_client_get_current_state(client);
1286         RETVM_IF(TTS_STATE_PLAYING == current_state || TTS_STATE_CREATED == current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1287
1288         RETVM_IF(false == tts_core_check_screen_reader(client), TTS_ERROR_SCREEN_READER_OFF, "[ERROR] Screen reader option is not available");
1289
1290         int ret = tts_core_play_pcm(client);
1291         if (TTS_ERROR_NONE != ret) {
1292                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request play_pcm. ret(%s)", tts_core_covert_error_code(ret));
1293                 return ret;
1294         }
1295
1296         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1297         return TTS_ERROR_NONE;
1298 }
1299
1300 int tts_stop_pcm(tts_h tts)
1301 {
1302         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1303
1304         SLOG(LOG_INFO, TAG_TTSC, "@@@ Stop pcm tts");
1305
1306         tts_client_s* client = tts_client_get(tts);
1307         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1308
1309         tts_state_e current_state = tts_client_get_current_state(client);
1310         RETVM_IF(TTS_STATE_CREATED == current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1311
1312         RETVM_IF(false == tts_core_check_screen_reader(client), TTS_ERROR_SCREEN_READER_OFF, "[ERROR] Screen reader option is not available");
1313
1314         int ret = tts_core_stop_pcm(client);
1315         if (TTS_ERROR_NONE != ret) {
1316                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request stop_pcm. ret(%s)", tts_core_covert_error_code(ret));
1317                 return ret;
1318         }
1319
1320         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1321         return TTS_ERROR_NONE;
1322 }
1323
1324 int tts_repeat(tts_h tts, char** text_repeat, int* utt_id)
1325 {
1326         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1327
1328         SLOG(LOG_INFO, TAG_TTSC, "@@@ Repeat TTS");
1329
1330         RETVM_IF(NULL == text_repeat || NULL == utt_id, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter is null.");
1331
1332         tts_client_s* client = tts_client_get(tts);
1333         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1334
1335         tts_state_e current_state = tts_client_get_current_state(client);
1336         RETVM_IF(TTS_STATE_READY != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1337
1338         RETVM_IF(false == tts_core_check_screen_reader(client), TTS_ERROR_SCREEN_READER_OFF, "[ERROR] Screen reader option is not available");
1339
1340         if (true == client->credential_needed && NULL == client->credential) {
1341                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Do not have app credential for this engine");
1342                 return TTS_ERROR_PERMISSION_DENIED;
1343         }
1344
1345         *text_repeat = NULL;
1346         *utt_id = -1;
1347
1348         int ret = tts_core_repeat(client, text_repeat, utt_id);
1349         if (TTS_ERROR_NONE != ret) {
1350                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request stop. ret(%s)", tts_core_covert_error_code(ret));
1351                 return ret;
1352         }
1353
1354         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1355         return TTS_ERROR_NONE;
1356 }
1357
1358 int tts_set_service_state_changed_cb(tts_h tts, tts_service_state_changed_cb callback, void* user_data)
1359 {
1360         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1361
1362         tts_client_s* client = tts_client_get(tts);
1363         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1364         RETVM_IF(NULL == callback, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Set service state changed cb : Input parameter is null");
1365
1366         tts_state_e current_state = tts_client_get_current_state(client);
1367         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1368
1369         tts_client_set_service_state_changed_cb(client, callback, user_data);
1370
1371         SLOG(LOG_INFO, TAG_TTSC, "[SUCCESS] Set service state changed cb");
1372         return TTS_ERROR_NONE;
1373 }
1374
1375 int tts_unset_service_state_changed_cb(tts_h tts)
1376 {
1377         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1378
1379         tts_client_s* client = tts_client_get(tts);
1380         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1381
1382         tts_state_e current_state = tts_client_get_current_state(client);
1383         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1384
1385         tts_client_set_service_state_changed_cb(client, NULL, NULL);
1386
1387         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset service state changed cb");
1388         return TTS_ERROR_NONE;
1389 }
1390
1391 int tts_set_synthesized_pcm_cb(tts_h tts, tts_synthesized_pcm_cb callback, void* user_data)
1392 {
1393         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1394
1395         tts_client_s* client = tts_client_get(tts);
1396         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1397         RETVM_IF(NULL == callback, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Set synthesized pcm cb : Input parameter is null");
1398
1399         tts_state_e current_state = tts_client_get_current_state(client);
1400         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1401
1402         tts_client_set_synthesized_pcm_cb(client, callback, user_data);
1403
1404         SLOG(LOG_INFO, TAG_TTSC, "[SUCCESS] Set synthesized pcm cb");
1405         return TTS_ERROR_NONE;
1406 }
1407
1408 int tts_unset_synthesized_pcm_cb(tts_h tts)
1409 {
1410         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1411
1412         tts_client_s* client = tts_client_get(tts);
1413         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1414
1415         tts_state_e current_state = tts_client_get_current_state(client);
1416         RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1417
1418         tts_client_set_synthesized_pcm_cb(client, NULL, NULL);
1419
1420         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset synthesized pcm cb");
1421         return TTS_ERROR_NONE;
1422 }
1423
1424 int tts_add_silent_utterance(tts_h tts, unsigned int duration_in_msec, int* utt_id)
1425 {
1426         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1427
1428         tts_client_s* client = tts_client_get(tts);
1429         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1430         RETVM_IF(NULL == utt_id, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter is null.");
1431
1432         tts_state_e current_state = tts_client_get_current_state(client);
1433         RETVM_IF(TTS_STATE_CREATED == current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1434
1435         RETVM_IF(false == tts_core_check_screen_reader(client), TTS_ERROR_SCREEN_READER_OFF, "[ERROR] Screen reader option is not available");
1436         RETVM_IF(false == tts_core_check_credential(client), TTS_ERROR_PERMISSION_DENIED, "[ERROR] Do not have app credential for this engine");
1437
1438         if (duration_in_msec < 0) {
1439                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to add silent. The duration of silent should be above than zero.");
1440                 return TTS_ERROR_INVALID_PARAMETER;
1441         }
1442
1443         if (duration_in_msec > MAX_SILENT_DURATION) {
1444                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to add silent. The max duration for silent is 5000 msec");
1445                 return TTS_ERROR_INVALID_PARAMETER;
1446         }
1447
1448         int ret = tts_core_add_silent_utterance(client, duration_in_msec, utt_id);
1449         if (TTS_ERROR_NONE != ret) {
1450                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request add silent. ret(%s)", tts_core_covert_error_code(ret));
1451                 return ret;
1452         }
1453
1454         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1455         return TTS_ERROR_NONE;
1456 }
1457
1458 int tts_synthesis_parameter_create(tts_synthesis_parameter_h *parameter)
1459 {
1460         SLOG(LOG_INFO, TAG_TTSC, "@@@ Create TTS synthesis parameter handle");
1461         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1462
1463         RETVM_IF(NULL == parameter, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input handle is null");
1464
1465         tts_synthesis_parameter_h new_parameter = (tts_synthesis_parameter_h)calloc(1, sizeof(struct tts_synthesis_parameter_s));
1466         RETVM_IF(NULL == new_parameter, TTS_ERROR_OUT_OF_MEMORY, "[ERROR] Fail to allocate memory for a handle");
1467
1468         *parameter = new_parameter;
1469
1470         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Create a handle for a synthesis parameter");
1471         return TTS_ERROR_NONE;
1472 }
1473
1474 int tts_synthesis_parameter_destroy(tts_synthesis_parameter_h parameter)
1475 {
1476         SLOG(LOG_INFO, TAG_TTSC, "@@@ Destroy TTS synthesis parameter handle");
1477         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1478
1479         RETVM_IF(NULL == parameter, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input handle is null");
1480
1481         free(parameter->language);
1482         parameter->language = NULL;
1483         free(parameter->ptts_id);
1484         parameter->ptts_id = NULL;
1485
1486         free(parameter);
1487
1488         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Destroy the handle for a synthesis parameter");
1489         return TTS_ERROR_NONE;
1490 }
1491
1492 int tts_synthesis_parameter_set_language(tts_synthesis_parameter_h parameter, const char *language)
1493 {
1494         SLOG(LOG_INFO, TAG_TTSC, "@@@ Set language to a synthesis parameter");
1495         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1496
1497         RETVM_IF(NULL == parameter || NULL == language, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input handle is null");
1498
1499         char *new_language = strdup(language);
1500         RETVM_IF(NULL == new_language, TTS_ERROR_OUT_OF_MEMORY, "[ERROR] Fail to allocate memory for language");
1501
1502         free(parameter->language);
1503         parameter->language = new_language;
1504
1505         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set language(%s) to a synthesis parameter", language);
1506         return TTS_ERROR_NONE;
1507 }
1508
1509 int tts_synthesis_parameter_set_voice_type(tts_synthesis_parameter_h parameter, int voice_type)
1510 {
1511         SLOG(LOG_INFO, TAG_TTSC, "@@@ Set voice type to a synthesis parameter");
1512         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1513
1514         RETVM_IF(NULL == parameter, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input handle is null");
1515         RETVM_IF(voice_type < 0, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Voice type should not be negative(%d)", voice_type);
1516
1517         parameter->voice_type = voice_type;
1518
1519         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set voice type(%d) to a synthesis parameter", voice_type);
1520         return TTS_ERROR_NONE;
1521 }
1522
1523 int tts_synthesis_parameter_set_personal_voice(tts_synthesis_parameter_h parameter, const char *ptts_id)
1524 {
1525         SLOG(LOG_INFO, TAG_TTSC, "@@@ Set personal voice id to a synthesis parameter");
1526         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1527
1528         RETVM_IF(NULL == parameter || NULL == ptts_id, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input handle is null");
1529
1530         char *new_ptts_id = strdup(ptts_id);
1531         RETVM_IF(NULL == new_ptts_id, TTS_ERROR_OUT_OF_MEMORY, "[ERROR] Fail to allocate memory for personal voice id");
1532
1533         free(parameter->ptts_id);
1534         parameter->ptts_id = new_ptts_id;
1535
1536         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set personal voice id(%s) to a synthesis parameter", ptts_id);
1537         return TTS_ERROR_NONE;
1538 }
1539
1540 int tts_synthesis_parameter_set_speed(tts_synthesis_parameter_h parameter, int speed)
1541 {
1542         SLOG(LOG_INFO, TAG_TTSC, "@@@ Set speed to a synthesis parameter");
1543         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1544
1545         RETVM_IF(NULL == parameter, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input handle is null");
1546         RETVM_IF(TTS_SPEED_AUTO > speed || TTS_SPEED_MAX < speed, TTS_ERROR_INVALID_PARAMETER, "[ERROR] speed value(%d) is invalid.", speed);
1547
1548         parameter->speed = speed;
1549
1550         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set speed(%d) to a synthesis parameter", speed);
1551         return TTS_ERROR_NONE;
1552 }
1553
1554 int tts_synthesis_parameter_set_pitch(tts_synthesis_parameter_h parameter, int pitch)
1555 {
1556         SLOG(LOG_INFO, TAG_TTSC, "@@@ Set pitch to a synthesis parameter");
1557         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1558
1559         RETVM_IF(NULL == parameter, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input handle is null");
1560         RETVM_IF(TTS_PITCH_AUTO > pitch || TTS_PITCH_MAX < pitch, TTS_ERROR_INVALID_PARAMETER, "[ERROR] pitch value(%d) is invalid.", pitch);
1561
1562         parameter->pitch = pitch;
1563
1564         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set pitch(%d) to a synthesis parameter", pitch);
1565         return TTS_ERROR_NONE;
1566 }
1567
1568 int tts_synthesis_parameter_set_volume(tts_synthesis_parameter_h parameter, double volume)
1569 {
1570         SLOG(LOG_INFO, TAG_TTSC, "@@@ Set volume to a synthesis parameter");
1571         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1572
1573         RETVM_IF(NULL == parameter, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input handle is null");
1574         RETVM_IF(0.0 > volume || 1.0 < volume, TTS_ERROR_INVALID_PARAMETER, "[ERROR] volume value(%f) is invalid.", volume);
1575
1576         parameter->volume = volume;
1577
1578         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set volume(%f) to a synthesis parameter", volume);
1579         return TTS_ERROR_NONE;
1580 }
1581
1582 int tts_synthesis_parameter_set_background_volume_ratio(tts_synthesis_parameter_h parameter, double background_volume_ratio)
1583 {
1584         SLOG(LOG_INFO, TAG_TTSC, "@@@ Set background volume ratio to a synthesis parameter");
1585         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1586
1587         RETVM_IF(NULL == parameter, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input handle is null");
1588         RETVM_IF(0.0 > background_volume_ratio || 1.0 < background_volume_ratio, TTS_ERROR_INVALID_PARAMETER, "[ERROR] background volume value ratio(%f) is invalid.", background_volume_ratio);
1589
1590         parameter->background_volume_ratio = background_volume_ratio;
1591
1592         SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set background volume ratio(%f) to a synthesis parameter", background_volume_ratio);
1593         return TTS_ERROR_NONE;
1594 }
1595
1596 int tts_get_pitch_range(tts_h tts, int* min, int* normal, int* max)
1597 {
1598         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1599
1600         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Get pitch range");
1601
1602         RETVM_IF(NULL == min || NULL == normal || NULL == max, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter is null");
1603
1604         tts_client_s* client = tts_client_get(tts);
1605         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1606
1607         *min = TTS_PITCH_MIN;
1608         *normal = TTS_PITCH_NORMAL;
1609         *max = TTS_PITCH_MAX;
1610
1611         return TTS_ERROR_NONE;
1612 }
1613
1614 int tts_get_volume_range(tts_h tts, int* min, int* max)
1615 {
1616         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1617
1618         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Get volume range");
1619
1620         RETVM_IF(NULL == min || NULL == max, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter is null");
1621
1622         tts_client_s* client = tts_client_get(tts);
1623         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1624
1625         *min = 0;
1626         *max = 0;
1627
1628         return TTS_ERROR_NONE;
1629 }
1630
1631 int tts_add_text_with_synthesis_parameter(tts_h tts, const char* text, tts_synthesis_parameter_h parameter, int* utt_id)
1632 {
1633         RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
1634
1635         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Add text with synthesis parameter: text(%s), language(%s), ptts_id(%s), type(%d), speed(%d), pitch(%d), volume(%lf), background_volume(%lf)",
1636         (NULL == text) ? "NULL" : text, (NULL == parameter->language) ? "NULL" : parameter->language, (NULL == parameter->ptts_id) ? "NULL" : parameter->ptts_id, parameter->voice_type, parameter->speed, parameter->pitch, parameter->volume, parameter->background_volume_ratio);
1637
1638         RETVM_IF(NULL == parameter, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter is null");
1639         RETVM_IF(NULL == utt_id, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter is null");
1640         RETVM_IF(false == tts_core_is_valid_text(text), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input text is invalid");
1641
1642         tts_client_s* client = tts_client_get(tts);
1643         RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
1644
1645         tts_state_e current_state = tts_client_get_current_state(client);
1646         RETVM_IF(TTS_STATE_CREATED == current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state);
1647
1648         RETVM_IF(false == tts_core_check_screen_reader(client), TTS_ERROR_SCREEN_READER_OFF, "[ERROR] Screen reader option is not available");
1649         RETVM_IF(false == tts_core_check_credential(client), TTS_ERROR_PERMISSION_DENIED, "[ERROR] Do not have app credential for this engine");
1650
1651         int ret = tts_core_add_text_with_synthesis_parameter(client, text, parameter, utt_id);
1652         if (TTS_ERROR_NONE != ret) {
1653                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request add text. ret(%s)", tts_core_covert_error_code(ret));
1654                 return ret;
1655         }
1656
1657         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
1658         return TTS_ERROR_NONE;
1659 }