Implement behavior of new APIs
[platform/core/uifw/tts.git] / server / ttsd_engine_agent.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
15 #include <dlfcn.h>
16 #include <dirent.h>
17
18 #include "tts_defs.h"
19 #include "ttsd_main.h"
20 #include "ttsd_engine_agent.h"
21 #include "ttsd_config.h"
22
23 #define ENGINE_PATH_SIZE        256
24
25 /*
26 * Internal data structure
27 */
28 typedef struct _ttsengine_info {
29         /* base info */
30         char*   engine_uuid;
31         char*   engine_path;
32         char*   engine_name;
33         char*   engine_setting_path;
34
35         /* info for using engine load */
36         bool    is_loaded;
37         bool    use_network;
38
39         tts_engine_callback_s* callbacks;
40
41         /* engine base setting */
42         char*   default_lang;
43         int     default_vctype;
44         int     default_speed;
45         int     default_pitch;
46 } ttsengine_info_s;
47
48 typedef struct {
49         bool    is_default;
50         bool    is_loaded;
51         int     client_ref_count;
52
53         char*   lang;
54         int     type;
55 } ttsvoice_s;
56
57
58 /** Init flag */
59 static bool g_agent_init;
60
61 /** Current engine information */
62 static ttsengine_info_s* g_engine_info = NULL;
63
64 /** Current voice information */
65 static GSList* g_cur_voices = NULL;
66
67 /** Callback function for voice list */
68 static bool __supported_voice_cb(const char* language, int type, void* user_data);
69
70 /** Free voice list */
71 static void __free_voice_list(GList* voice_list);
72
73 static int ttsd_print_voicelist();
74
75 static const char* __ttsd_get_engine_error_code(ttse_error_e err)
76 {
77         switch (err) {
78         case TTSE_ERROR_NONE:                   return "TTSE_ERROR_NONE";
79         case TTSE_ERROR_OUT_OF_MEMORY:          return "TTSE_ERROR_OUT_OF_MEMORY";
80         case TTSE_ERROR_IO_ERROR:               return "TTSE_ERROR_IO_ERROR";
81         case TTSE_ERROR_INVALID_PARAMETER:      return "TTSE_ERROR_INVALID_PARAMETER";
82         case TTSE_ERROR_NETWORK_DOWN:           return "TTSE_ERROR_NETWORK_DOWN";
83         case TTSE_ERROR_INVALID_STATE:          return "TTSE_ERROR_INVALID_STATE";
84         case TTSE_ERROR_INVALID_VOICE:          return "TTSE_ERROR_INVALID_VOICE";
85         case TTSE_ERROR_OPERATION_FAILED:       return "TTSE_ERROR_OPERATION_FAILED";
86         default:
87                 return "Invalid error code";
88         }
89 }
90
91 inline static bool __is_agent_initialized()
92 {
93         if (false == g_agent_init) {
94                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
95                 return false;
96         }
97
98         if (NULL == g_engine_info) {
99                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No engine info");
100                 return false;
101         }
102
103         return true;
104 }
105
106 inline static bool __is_engine_loaded()
107 {
108         if (false == g_engine_info->is_loaded) {
109                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
110                 return false;
111         }
112
113         return true;
114 }
115
116 inline static int __check_engine_initialized_and_loaded()
117 {
118         if (false == __is_agent_initialized()) {
119                 return TTSD_ERROR_INVALID_STATE;
120         }
121
122         if (false == __is_engine_loaded()) {
123                 return TTSD_ERROR_ENGINE_NOT_FOUND;
124         }
125
126         return TTSD_ERROR_NONE;
127 }
128
129 static bool __is_callback_valid(ttse_request_callback_s *callback)
130 {
131         if (NULL == callback) {
132                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
133                 return false;
134         }
135
136         if (NULL == callback->get_info
137                 || NULL == callback->initialize || NULL == callback->deinitialize
138                 || NULL == callback->foreach_voices || NULL == callback->is_valid_voice
139                 || NULL == callback->set_pitch
140                 || NULL == callback->load_voice || NULL == callback->unload_voice
141                 || NULL == callback->start_synth || NULL == callback->cancel_synth
142                 || NULL == callback->check_app_agreed || NULL == callback->need_app_credential) {
143                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
144                 return false;
145         }
146
147         return true;
148 }
149
150 static int __set_engine_callback(ttse_request_callback_s* callback, ttsengine_info_s* engine_info)
151 {
152         SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent DEBUG] internal get engine info");
153
154         if (0 != callback->get_info(&(engine_info->engine_uuid), &(engine_info->engine_name), &(engine_info->engine_setting_path), &(engine_info->use_network))) {
155                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get engine info");
156                 return TTSD_ERROR_ENGINE_NOT_FOUND;
157         }
158
159         if (NULL != engine_info->engine_path) {
160                 free(engine_info->engine_path);
161                 engine_info->engine_path = NULL;
162         }
163         engine_info->engine_path = strdup("empty");
164         engine_info->is_loaded = false;
165
166         if (NULL != engine_info->callbacks) {
167                 free(engine_info->callbacks);
168                 engine_info->callbacks = NULL;
169         }
170
171         engine_info->callbacks = (tts_engine_callback_s*)calloc(1, sizeof(tts_engine_callback_s));
172         if (NULL == engine_info->callbacks) {
173                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
174                 return TTSD_ERROR_OUT_OF_MEMORY;
175         }
176
177         engine_info->callbacks->get_info = callback->get_info;
178         engine_info->callbacks->initialize = callback->initialize;
179         engine_info->callbacks->deinitialize = callback->deinitialize;
180         engine_info->callbacks->foreach_voices = callback->foreach_voices;
181         engine_info->callbacks->is_valid_voice = callback->is_valid_voice;
182         engine_info->callbacks->set_pitch = callback->set_pitch;
183         engine_info->callbacks->load_voice = callback->load_voice;
184         engine_info->callbacks->unload_voice = callback->unload_voice;
185         engine_info->callbacks->start_synth = callback->start_synth;
186         engine_info->callbacks->cancel_synth = callback->cancel_synth;
187         engine_info->callbacks->check_app_agreed = callback->check_app_agreed;
188         engine_info->callbacks->need_app_credential = callback->need_app_credential;
189
190         engine_info->callbacks->private_data_set = NULL;
191         engine_info->callbacks->private_data_requested = NULL;
192         engine_info->callbacks->activated_mode_changed = NULL;
193
194         SLOG(LOG_DEBUG, tts_tag(), "--- Valid Engine ---");
195         SLOG(LOG_DEBUG, tts_tag(), "Engine uuid : %s", engine_info->engine_uuid);
196         SLOG(LOG_DEBUG, tts_tag(), "Engine name : %s", engine_info->engine_name);
197         SLOG(LOG_DEBUG, tts_tag(), "Engine path : %s", engine_info->engine_path);
198         SLOG(LOG_DEBUG, tts_tag(), "Engine setting path : %s", engine_info->engine_setting_path);
199         SLOG(LOG_DEBUG, tts_tag(), "Use network : %s", engine_info->use_network ? "true" : "false");
200         SLOG(LOG_DEBUG, tts_tag(), "--------------------");
201         SLOG(LOG_DEBUG, tts_tag(), "  ");
202
203         return TTSD_ERROR_NONE;
204 }
205
206 int ttsd_engine_agent_init(ttse_request_callback_s *callback)
207 {
208         if (__is_agent_initialized()) {
209                 SLOG(LOG_WARN, tts_tag(), "[Engine Agent] Already initialized");
210                 return TTSD_ERROR_NONE;
211         }
212
213         if (false == __is_callback_valid(callback)) {
214                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
215                 return TTSD_ERROR_ENGINE_NOT_FOUND;
216         }
217
218         ttsengine_info_s* temp;
219         temp = (ttsengine_info_s*)calloc(1, sizeof(ttsengine_info_s));
220         if (NULL == temp) {
221                 SLOG(LOG_WARN, tts_tag(), "[Engine Agent] Fail to alloc memory");
222                 return TTSD_ERROR_OUT_OF_MEMORY;
223         }
224
225         if (0 != ttsd_config_get_default_voice(&(temp->default_lang), &(temp->default_vctype))) {
226                 SLOG(LOG_WARN, tts_tag(), "[Server WARNING] There is No default voice in config");
227                 /* Set default voice */
228                 temp->default_lang = strdup(TTS_BASE_LANGUAGE);
229                 temp->default_vctype = TTSE_VOICE_TYPE_FEMALE;
230         }
231
232         SLOG(LOG_DEBUG, tts_tag(), "[Server DEBUG] language(%s), type(%d)", temp->default_lang, temp->default_vctype);
233
234         if (0 != ttsd_config_get_default_speed(&(temp->default_speed))) {
235                 SLOG(LOG_WARN, tts_tag(), "[Server WARNING] There is No default speed in config");
236                 temp->default_speed = TTS_SPEED_NORMAL;
237         }
238
239         if (0 != ttsd_config_get_default_pitch(&(temp->default_pitch))) {
240                 SLOG(LOG_WARN, tts_tag(), "[Server WARNING] There is No default pitch in config");
241                 temp->default_pitch = TTS_PITCH_NORMAL;
242         }
243
244         /* Get current engine info */
245         int ret = __set_engine_callback(callback, temp);
246         if (TTSD_ERROR_NONE != ret) {
247                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get engine info");
248                 free(temp);
249                 temp = NULL;
250                 return ret;
251         }
252
253         g_engine_info = temp;
254         g_agent_init = true;
255
256         SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Initialize Engine Agent");
257         return TTSD_ERROR_NONE;
258 }
259
260 int ttsd_engine_agent_release()
261 {
262         if (false == __is_agent_initialized()) {
263                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
264                 return TTSD_ERROR_INVALID_STATE;
265         }
266
267         /* unload current engine */
268         if (__is_engine_loaded()) {
269                 ttsd_engine_agent_unload_current_engine();
270         }
271
272         if (NULL != g_engine_info->default_lang) {
273                 free(g_engine_info->default_lang);
274                 g_engine_info->default_lang = NULL;
275         }
276
277         if (NULL != g_engine_info->engine_uuid) {
278                 free(g_engine_info->engine_uuid);
279                 g_engine_info->engine_uuid = NULL;
280         }
281
282         if (NULL != g_engine_info->engine_name) {
283                 free(g_engine_info->engine_name);
284                 g_engine_info->engine_name = NULL;
285         }
286
287         if (NULL != g_engine_info->engine_setting_path) {
288                 free(g_engine_info->engine_setting_path);
289                 g_engine_info->engine_setting_path = NULL;
290         }
291
292         if (NULL != g_engine_info->engine_path) {
293                 free(g_engine_info->engine_path);
294                 g_engine_info->engine_path = NULL;
295         }
296
297         free(g_engine_info);
298         g_engine_info = NULL;
299
300         g_agent_init = false;
301
302         SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Release Engine Agent");
303
304         return TTSD_ERROR_NONE;
305 }
306
307 static bool __set_voice_info_cb(const char* language, int type, void* user_data)
308 {
309         if (NULL == language) {
310                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
311                 return false;
312         }
313
314         ttsvoice_s* voice = calloc(1, sizeof(ttsvoice_s));
315         if (NULL == voice) {
316                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
317                 return false;
318         }
319         voice->lang = strdup(language);
320         voice->type = type;
321
322         voice->client_ref_count = 0;
323         voice->is_loaded = false;
324
325         if (0 == strcmp(g_engine_info->default_lang, language) && g_engine_info->default_vctype == type) {
326                 voice->is_default = true;
327                 voice->is_loaded = true;
328         } else {
329                 voice->is_default = false;
330         }
331
332         g_cur_voices = g_slist_append(g_cur_voices, voice);
333
334         return true;
335 }
336
337 static void __clear_voice_list()
338 {
339         if (NULL == g_cur_voices) {
340                 return;
341         }
342
343         GSList *iter = g_slist_nth(g_cur_voices, 0);
344         while (NULL != iter) {
345                 ttsvoice_s* data = iter->data;
346
347                 if (NULL != data) {
348                         if (NULL != data->lang) {
349                                 free(data->lang);
350                                 data->lang = NULL;
351                         }
352
353                         g_cur_voices = g_slist_remove(g_cur_voices, data);
354                         free(data);
355                         data = NULL;
356                 }
357
358                 iter = g_slist_nth(g_cur_voices, 0);
359         }
360
361         g_slist_free(g_cur_voices);
362         g_cur_voices = NULL;
363 }
364
365 static int __update_voice_list()
366 {
367         if (false == __is_agent_initialized()) {
368                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
369                 return TTSD_ERROR_INVALID_STATE;
370         }
371
372         __clear_voice_list();
373
374         int ret = -1;
375         ret = g_engine_info->callbacks->foreach_voices(__set_voice_info_cb, NULL);
376
377         if (0 != ret || 0 >= g_slist_length(g_cur_voices)) {
378                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
379                 return TTSD_ERROR_OPERATION_FAILED;
380         }
381
382 #ifdef ENGINE_AGENT_DEBUG
383         ttsd_print_voicelist();
384 #endif
385         return TTSD_ERROR_NONE;
386 }
387
388 int ttsd_engine_agent_load_current_engine()
389 {
390         SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent DEBUG] load current engine START");
391
392         if (false == __is_agent_initialized()) {
393                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
394                 return TTSD_ERROR_INVALID_STATE;
395         }
396
397         /* check whether current engine is loaded or not */
398         if (__is_engine_loaded()) {
399                 SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Engine has already been loaded ");
400                 return TTSD_ERROR_NONE;
401         }
402
403         /* Initialize engine */
404         int ret = g_engine_info->callbacks->initialize();
405         if (0 != ret) {
406                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to initialize current engine : %s", __ttsd_get_engine_error_code(ret));
407                 return TTSD_ERROR_OPERATION_FAILED;
408         }
409
410         /* Get voice info of current engine */
411         ret = __update_voice_list();
412         if (0 != ret) {
413                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set voice info : result(%d)", ret);
414                 return TTSD_ERROR_OPERATION_FAILED;
415         }
416
417         /* Select default voice */
418         if (NULL != g_engine_info->default_lang) {
419                 bool is_valid = false;
420                 ret = g_engine_info->callbacks->is_valid_voice(g_engine_info->default_lang, g_engine_info->default_vctype, &is_valid);
421                 if (0 == ret) {
422                         if (true == is_valid) {
423                                 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Set origin default voice to current engine : lang(%s), type(%d)",
424                                         g_engine_info->default_lang, g_engine_info->default_vctype);
425                         } else {
426                                 SLOG(LOG_WARN, tts_tag(), "[Engine Agent WARNING] Fail to set origin default voice : lang(%s), type(%d)",
427                                         g_engine_info->default_lang, g_engine_info->default_vctype);
428
429                                 /* TODO - Error Tolerance when Default voice is not valid */
430                                 return TTSD_ERROR_OPERATION_FAILED;
431                         }
432                 } else {
433                         SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail(Engine ERROR) : %s", __ttsd_get_engine_error_code(ret));
434                         return ret;
435                 }
436         }
437
438         /* load default voice */
439         ret = g_engine_info->callbacks->load_voice(g_engine_info->default_lang, g_engine_info->default_vctype);
440         if (0 == ret) {
441                 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Load default voice : lang(%s), type(%d)",
442                         g_engine_info->default_lang, g_engine_info->default_vctype);
443         } else {
444                 SLOG(LOG_WARN, tts_tag(), "[Engine Agent ERROR] Fail to load default voice : lang(%s), type(%d) result(%s)",
445                         g_engine_info->default_lang, g_engine_info->default_vctype, __ttsd_get_engine_error_code(ret));
446
447                 return TTSD_ERROR_OPERATION_FAILED;
448         }
449
450         /* set default pitch */
451         ret = g_engine_info->callbacks->set_pitch(g_engine_info->default_pitch);
452         if (0 != ret) {
453                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)",
454                         g_engine_info->default_pitch, __ttsd_get_engine_error_code(ret));
455                 return ret;
456         } else {
457                 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Set default pitch : pitch(%d)", g_engine_info->default_pitch);
458         }
459
460         g_engine_info->is_loaded = true;
461
462         return TTSD_ERROR_NONE;
463 }
464
465 int ttsd_engine_agent_unload_current_engine()
466 {
467         if (false == __is_agent_initialized()) {
468                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
469                 return TTSD_ERROR_INVALID_STATE;
470         }
471
472         if (false == __is_engine_loaded()) {
473                 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Engine has already been unloaded ");
474                 return TTSD_ERROR_NONE;
475         }
476
477         /* shutdown engine */
478         int ret = 0;
479         ret = g_engine_info->callbacks->deinitialize();
480         if (0 != ret) {
481                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent] Fail deinitialize() : %s", __ttsd_get_engine_error_code(ret));
482         }
483
484         /* reset current engine data */
485         g_engine_info->is_loaded = false;
486
487         __clear_voice_list();
488
489         SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent Success] Unload current engine");
490
491         return TTSD_ERROR_NONE;
492 }
493
494 bool ttsd_engine_agent_need_network()
495 {
496         if (false == __is_agent_initialized()) {
497                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
498                 return false;
499         }
500
501         return g_engine_info->use_network;
502 }
503
504 bool ttsd_engine_agent_is_same_engine(const char* engine_id)
505 {
506         if (NULL == engine_id) {
507                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] engine_id is NULL");
508                 return false;
509         }
510
511         int ret = __check_engine_initialized_and_loaded();
512         if (TTSD_ERROR_NONE != ret) {
513                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
514                 return false;
515         }
516
517         /* compare current engine and engine id.*/
518         if (NULL != g_engine_info->engine_uuid && 0 == strncmp(g_engine_info->engine_uuid, engine_id, strlen(engine_id))) {
519                 return true;
520         }
521
522         return false;
523 }
524
525 bool ttsd_engine_select_valid_voice(const char* lang, int type, char** out_lang, int* out_type)
526 {
527         if (NULL == lang || NULL == out_lang || NULL == out_type) {
528                 return false;
529         }
530
531         int ret = __check_engine_initialized_and_loaded();
532         if (TTSD_ERROR_NONE != ret) {
533                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
534                 return false;
535         }
536
537         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Select voice : input lang(%s), input type(%d), default lang(%s), default type(%d)",
538                 (NULL == lang) ? "NULL" : lang, type, (NULL == g_engine_info->default_lang) ? "NULL" : g_engine_info->default_lang, g_engine_info->default_vctype);
539
540         /* case 1 : Both are default */
541         if (0 == strncmp(lang, "default", strlen(lang)) && 0 == type) {
542                 if (NULL != g_engine_info->default_lang) {
543                         *out_lang = strdup(g_engine_info->default_lang);
544                 } else {
545                         *out_lang = NULL;
546                 }
547
548                 *out_type = g_engine_info->default_vctype;
549                 return true;
550         }
551
552         /* Get voice list */
553         GList* voice_list = NULL;
554         ret = g_engine_info->callbacks->foreach_voices(__supported_voice_cb, &voice_list);
555         if (0 != ret || 0 >= g_list_length(voice_list)) {
556                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
557                 return false;
558         }
559
560         bool result;
561         result = false;
562
563         GList *iter = NULL;
564         voice_s* voice;
565
566         /* case 2 : lang and type are not default type */
567         if (0 != strncmp(lang, "default", strlen("default")) && 0 != type) {
568                 iter = g_list_first(voice_list);
569
570                 while (NULL != iter) {
571                         /* Get handle data from list */
572                         voice = iter->data;
573
574                         if (0 == strncmp(voice->language, lang, strlen(lang)) &&  voice->type == type) {
575                                 *out_lang = strdup(voice->language);
576                                 *out_type = voice->type;
577                                 result = true;
578                                 break;
579                         }
580
581                         iter = g_list_next(iter);
582                 }
583
584         } else if (0 != strncmp(lang, "default", strlen("default")) && 0 == type) {
585                 /* Only type is default */
586                 if (0 == strncmp(lang, g_engine_info->default_lang, strlen(g_engine_info->default_lang))) {
587                         *out_lang = strdup(g_engine_info->default_lang);
588                         *out_type = g_engine_info->default_vctype;
589                         result = true;
590                 } else {
591                         voice_s* voice_selected = NULL;
592                         iter = g_list_first(voice_list);
593                         while (NULL != iter) {
594                                 /* Get handle data from list */
595                                 voice = iter->data;
596
597                                 if (0 == strncmp(voice->language, lang, strlen(lang))) {
598                                         voice_selected = voice;
599                                         if (voice->type == g_engine_info->default_vctype) {
600                                                 voice_selected = voice;
601                                                 break;
602                                         }
603                                 }
604                                 iter = g_list_next(iter);
605                         }
606
607                         if (NULL != voice_selected) {
608                                 *out_lang = strdup(voice_selected->language);
609                                 *out_type = voice_selected->type;
610                                 result = true;
611                         }
612                 }
613         } else if (0 == strncmp(lang, "default", strlen("default")) && 0 != type) {
614                 /* Only lang is default */
615                 if (type == g_engine_info->default_vctype) {
616                         *out_lang = strdup(g_engine_info->default_lang);
617                         *out_type = g_engine_info->default_vctype;
618                         result = true;
619                 } else {
620                         voice_s* voice_selected = NULL;
621                         iter = g_list_first(voice_list);
622                         while (NULL != iter) {
623                                 /* Get handle data from list */
624                                 voice = iter->data;
625
626                                 if (0 == strncmp(voice->language, g_engine_info->default_lang, strlen(g_engine_info->default_lang))) {
627                                         voice_selected = voice;
628                                         if (voice->type == type) {
629                                                 voice_selected = voice;
630                                                 break;
631                                         }
632                                 }
633                                 iter = g_list_next(iter);
634                         }
635
636                         if (NULL != voice_selected) {
637                                 *out_lang = strdup(voice->language);
638                                 *out_type = voice_selected->type;
639                                 result = true;
640                         }
641                 }
642         }
643
644         if (true == result) {
645                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Selected voice : lang(%s), type(%d)", *out_lang, *out_type);
646         }
647
648         __free_voice_list(voice_list);
649
650         return result;
651 }
652
653 static ttsvoice_s* __get_ttsvoice(const char* lang, const int vctype)
654 {
655         GSList *iter = NULL;
656         ttsvoice_s* data = NULL;
657
658         iter = g_slist_nth(g_cur_voices, 0);
659         while (NULL != iter) {
660                 /*Get handle data from list*/
661                 data = iter->data;
662
663                 if (NULL != data) {
664                         if (NULL != data->lang && 0 == strcmp(data->lang, lang) && data->type == vctype) {
665                                 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
666                                         data->is_default, data->is_loaded,  data->client_ref_count, data->lang, data->type);
667                                 break;
668                         }
669                 }
670
671                 /*Get next item*/
672                 iter = g_slist_next(iter);
673                 data = NULL;
674         }
675
676         return data;
677 }
678
679 int ttsd_engine_agent_set_default_voice(const char* language, int vctype)
680 {
681         if (NULL == language) {
682                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] language is NULL");
683                 return TTSD_ERROR_INVALID_PARAMETER;
684         }
685
686         int ret = __check_engine_initialized_and_loaded();
687         if (TTSD_ERROR_NONE != ret) {
688                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
689                 return ret;
690         }
691
692         bool is_valid = false;
693         ret = g_engine_info->callbacks->is_valid_voice(language, vctype, &is_valid);
694         if (0 == ret) {
695                 if (true == is_valid) {
696                         SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Current voice is valid : lang(%s), type(%d)",
697                                 (NULL == g_engine_info->default_lang) ? "NULL" : g_engine_info->default_lang, g_engine_info->default_vctype);
698                 } else {
699                         SLOG(LOG_WARN, tts_tag(), "[Engine Agent WARNING] Current voice is invalid : lang(%s), type(%d)",
700                                 (NULL == g_engine_info->default_lang) ? "NULL" : g_engine_info->default_lang, g_engine_info->default_vctype);
701
702                         return TTSD_ERROR_OPERATION_FAILED;
703                 }
704         } else {
705                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail(Engine ERROR) : %s", __ttsd_get_engine_error_code(ret));
706                 return ret;
707         }
708
709         /* Update new default voice info */
710         ttsvoice_s* data = __get_ttsvoice(language, vctype);
711         if (NULL != data) {
712                 data->is_default = true;
713                 if (0 == data->client_ref_count) {
714                         /* load voice */
715                         ret = g_engine_info->callbacks->load_voice(data->lang, data->type);
716                         if (0 == ret) {
717                                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] load voice : lang(%s), type(%d)",
718                                         data->lang, data->type);
719                                 data->is_loaded = true;
720                         } else {
721                                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
722                                         data->lang, data->type, __ttsd_get_engine_error_code(ret));
723                         }
724                 }
725         }
726
727 #ifdef ENGINE_AGENT_DEBUG
728         ttsd_print_voicelist();
729 #endif
730
731         /* Update old default voice info */
732         data = __get_ttsvoice(g_engine_info->default_lang, g_engine_info->default_vctype);
733         if (NULL != data) {
734                 data->is_default = false;
735                 if (0 == data->client_ref_count) {
736                         /* Unload voice */
737                         ret = g_engine_info->callbacks->unload_voice(data->lang, data->type);
738                         if (0 == ret) {
739                                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
740                                         data->lang, data->type);
741                                 data->is_loaded = false;
742                         } else {
743                                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
744                                         data->lang, data->type, __ttsd_get_engine_error_code(ret));
745                         }
746                 }
747         }
748
749         if (NULL != g_engine_info->default_lang) {
750                 free(g_engine_info->default_lang);
751                 g_engine_info->default_lang = NULL;
752         }
753
754         g_engine_info->default_lang = strdup(language);
755         g_engine_info->default_vctype = vctype;
756
757 #ifdef ENGINE_AGENT_DEBUG
758         ttsd_print_voicelist();
759 #endif
760
761         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Set default voice : lang(%s), type(%d)",
762                 g_engine_info->default_lang, g_engine_info->default_vctype);
763
764         return TTSD_ERROR_NONE;
765 }
766
767 int ttsd_engine_agent_set_default_speed(int speed)
768 {
769         if (false == __is_agent_initialized()) {
770                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
771                 return TTSD_ERROR_INVALID_STATE;
772         }
773
774         g_engine_info->default_speed = speed;
775
776         return TTSD_ERROR_NONE;
777 }
778
779 int ttsd_engine_agent_set_default_pitch(int pitch)
780 {
781         int ret = __check_engine_initialized_and_loaded();
782         if (TTSD_ERROR_NONE != ret) {
783                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
784                 return ret;
785         }
786
787         ret = g_engine_info->callbacks->set_pitch(pitch);
788         if (0 != ret) {
789                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)",
790                          pitch, __ttsd_get_engine_error_code(ret));
791                 return TTSD_ERROR_OPERATION_FAILED;
792         }
793
794         g_engine_info->default_pitch = pitch;
795
796         SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Set pitch(%d)", pitch);
797         return TTSD_ERROR_NONE;
798 }
799
800 int ttsd_engine_agent_is_credential_needed(unsigned int uid, bool* credential_needed)
801 {
802         if (NULL == credential_needed) {
803                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid Parameter");
804                 return TTSD_ERROR_INVALID_PARAMETER;
805         }
806
807         int ret = __check_engine_initialized_and_loaded();
808         if (TTSD_ERROR_NONE != ret) {
809                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
810                 return ret;
811         }
812
813         if (NULL == g_engine_info->callbacks->need_app_credential) {
814                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not support to check app credential");
815                 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
816         }
817
818         bool result = false;
819         result = g_engine_info->callbacks->need_app_credential();
820         *credential_needed = result;
821
822         SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Need app credential, credential_needed(%d)", *credential_needed);
823         return TTSD_ERROR_NONE;
824 }
825
826 /******************************************************************************************
827 * TTS Engine Interfaces for client
828 *******************************************************************************************/
829
830 int ttsd_engine_load_voice(const char* lang, const int vctype)
831 {
832         if (NULL == lang) {
833                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No language parameter");
834                 return TTSD_ERROR_INVALID_PARAMETER;
835         }
836
837         int ret = __check_engine_initialized_and_loaded();
838         if (TTSD_ERROR_NONE != ret) {
839                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
840                 return ret;
841         }
842
843         /* 1. Find voice info */
844         ttsvoice_s* data = __get_ttsvoice(lang, vctype);
845         if (NULL == data) {
846                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
847                 return TTSD_ERROR_OPERATION_FAILED;
848         }
849
850         /* 2. increase ref count */
851         data->client_ref_count++;
852
853         /* 3. if ref count change 0 to 1 and not default, load voice */
854         if (1 == data->client_ref_count && false == data->is_default) {
855                 /* load voice */
856                 ret = g_engine_info->callbacks->load_voice(data->lang, data->type);
857                 if (0 == ret) {
858                         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Load voice : lang(%s), type(%d)",
859                                 data->lang, data->type);
860                         data->is_loaded = true;
861                 } else {
862                         SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
863                                 data->lang, data->type, __ttsd_get_engine_error_code(ret));
864
865                         return TTSD_ERROR_OPERATION_FAILED;
866                 }
867         } else {
868                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Not load voice : default voice(%d) or ref count(%d)",
869                 data->is_default, data->client_ref_count);
870         }
871
872 #ifdef ENGINE_AGENT_DEBUG
873         ttsd_print_voicelist();
874 #endif
875
876         return TTSD_ERROR_NONE;
877 }
878
879 int ttsd_engine_unload_voice(const char* lang, const int vctype)
880 {
881         if (NULL == lang) {
882                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No language parameter");
883                 return TTSD_ERROR_INVALID_PARAMETER;
884         }
885
886         int ret = __check_engine_initialized_and_loaded();
887         if (TTSD_ERROR_NONE != ret) {
888                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
889                 return ret;
890         }
891
892         /* 1. Find voice info */
893         ttsvoice_s* data = __get_ttsvoice(lang, vctype);
894         if (NULL == data) {
895                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
896                 return TTSD_ERROR_OPERATION_FAILED;
897         }
898
899         /* 2. Decrease ref count */
900         data->client_ref_count--;
901
902         /* 3. if ref count change 0 and not default, load voice */
903         if (0 == data->client_ref_count && false == data->is_default) {
904                 /* unload voice */
905                 ret = g_engine_info->callbacks->unload_voice(data->lang, data->type);
906                 if (0 == ret) {
907                         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
908                                 data->lang, data->type);
909                         data->is_loaded = false;
910                 } else {
911                         SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
912                                 data->lang, data->type, __ttsd_get_engine_error_code(ret));
913
914                         return TTSD_ERROR_OPERATION_FAILED;
915                 }
916         } else {
917                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Not unload voice : default voice(%d) or ref count(%d)",
918                 data->is_default, data->client_ref_count);
919         }
920
921 #ifdef ENGINE_AGENT_DEBUG
922         ttsd_print_voicelist();
923 #endif
924         return TTSD_ERROR_NONE;
925 }
926
927 int ttsd_engine_start_synthesis(const char* lang, int vctype, const char* text, int speed, const char* appid, const char* credential, void* user_param)
928 {
929         if (NULL == lang || NULL == text) {
930                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
931                 return TTSD_ERROR_INVALID_PARAMETER;
932         }
933
934         int ret = __check_engine_initialized_and_loaded();
935         if (TTSD_ERROR_NONE != ret) {
936                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
937                 return ret;
938         }
939
940         /* select voice for default */
941         char* temp_lang = NULL;
942         int temp_type;
943         if (true != ttsd_engine_select_valid_voice(lang, vctype, &temp_lang, &temp_type)) {
944                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to select default voice");
945                 if (NULL != temp_lang) {
946                         free(temp_lang);
947                         temp_lang = NULL;
948                 }
949                 return TTSD_ERROR_INVALID_VOICE;
950         } else {
951                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Start synthesis : language(%s), type(%d), speed(%d), text(%s), credential(%s)",
952                         (NULL == temp_lang) ? "NULL" : temp_lang, temp_type, speed, (NULL == text) ? "NULL" : text, (NULL == credential) ? "NULL" : credential);
953         }
954
955         int temp_speed;
956
957         if (0 == speed) {
958                 temp_speed = g_engine_info->default_speed;
959         } else {
960                 temp_speed = speed;
961         }
962
963         /* synthesize text */
964         ret = g_engine_info->callbacks->start_synth(temp_lang, temp_type, text, temp_speed, appid, credential, user_param);
965         if (0 != ret) {
966                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] ***************************************");
967                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] * synthesize error : %s *", __ttsd_get_engine_error_code(ret));
968                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] ***************************************");
969                 if (NULL != temp_lang) {
970                         free(temp_lang);
971                         temp_lang = NULL;
972                 }
973                 return ret;
974         }
975
976         if (NULL != temp_lang)  {
977                 free(temp_lang);
978                 temp_lang = NULL;
979         }
980         return TTSD_ERROR_NONE;
981 }
982
983 int ttsd_engine_cancel_synthesis()
984 {
985         int ret = __check_engine_initialized_and_loaded();
986         if (TTSD_ERROR_NONE != ret) {
987                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
988                 return ret;
989         }
990
991         SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Cancel synth");
992         /* stop synthesis */
993         ret = g_engine_info->callbacks->cancel_synth();
994         if (0 != ret) {
995                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail cancel synthesis : %s", __ttsd_get_engine_error_code(ret));
996         }
997
998         return ret;
999 }
1000
1001 bool __supported_voice_cb(const char* language, int type, void* user_data)
1002 {
1003         GList** voice_list = (GList**)user_data;
1004
1005         if (NULL == language || NULL == voice_list) {
1006                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
1007                 return false;
1008         }
1009
1010         voice_s* voice = calloc(1, sizeof(voice_s));
1011         if (NULL == voice) {
1012                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
1013                 return false;
1014         }
1015         voice->language = strdup(language);
1016         voice->type = type;
1017
1018         *voice_list = g_list_append(*voice_list, voice);
1019
1020         return true;
1021 }
1022
1023 int ttsd_engine_get_voice_list(GList** voice_list)
1024 {
1025         if (NULL == voice_list) {
1026                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1027                 return TTSD_ERROR_INVALID_PARAMETER;
1028         }
1029
1030         int ret = __check_engine_initialized_and_loaded();
1031         if (TTSD_ERROR_NONE != ret) {
1032                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
1033                 return ret;
1034         }
1035
1036         ret = g_engine_info->callbacks->foreach_voices(__supported_voice_cb, (void*)voice_list);
1037         if (0 != ret) {
1038                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get voice list : %s", __ttsd_get_engine_error_code(ret));
1039         }
1040
1041         return ret;
1042 }
1043
1044 int ttsd_engine_get_default_voice(char** lang, int* vctype)
1045 {
1046         if (NULL == lang || NULL == vctype) {
1047                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] BAD Parameter");
1048                 return TTSD_ERROR_INVALID_PARAMETER;
1049         }
1050
1051         int ret = __check_engine_initialized_and_loaded();
1052         if (TTSD_ERROR_NONE != ret) {
1053                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
1054                 return ret;
1055         }
1056
1057         if (NULL != g_engine_info->default_lang) {
1058                 *lang = strdup(g_engine_info->default_lang);
1059                 *vctype = g_engine_info->default_vctype;
1060
1061                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine] Get default voice : language(%s), type(%d)", *lang, *vctype);
1062         } else {
1063                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Default voice is NULL");
1064                 return TTSD_ERROR_OPERATION_FAILED;
1065         }
1066
1067         return TTSD_ERROR_NONE;
1068 }
1069
1070 int ttsd_engine_set_private_data(const char* key, const char* data)
1071 {
1072         if (NULL == key) {
1073                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1074                 return TTSD_ERROR_INVALID_PARAMETER;
1075         }
1076
1077         int ret = __check_engine_initialized_and_loaded();
1078         if (TTSD_ERROR_NONE != ret) {
1079                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
1080                 return ret;
1081         }
1082
1083         if (NULL == g_engine_info->callbacks->private_data_set) {
1084                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1085                 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1086         }
1087
1088         ret = g_engine_info->callbacks->private_data_set(key, data);
1089         if (0 != ret) {
1090                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set private data(%d)", ret);
1091         }
1092
1093         return ret;
1094 }
1095
1096 int ttsd_engine_get_private_data(const char* key, char** data)
1097 {
1098         if (NULL == key || NULL == data) {
1099                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1100                 return TTSD_ERROR_INVALID_PARAMETER;
1101         }
1102
1103         int ret = __check_engine_initialized_and_loaded();
1104         if (TTSD_ERROR_NONE != ret) {
1105                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
1106                 return ret;
1107         }
1108
1109         if (NULL == g_engine_info->callbacks->private_data_requested) {
1110                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1111                 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1112         }
1113
1114         char* temp = NULL;
1115         ret = g_engine_info->callbacks->private_data_requested(key, &temp);
1116         if (0 != ret) {
1117                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get private data(%d)", ret);
1118         }
1119
1120         if (NULL == temp)
1121                 *data = strdup("NULL");
1122         else
1123                 *data = strdup(temp);
1124
1125         return ret;
1126 }
1127
1128 int ttsd_engine_check_app_agreed(const char* appid, bool* is_agreed)
1129 {
1130         if (NULL == appid || NULL == is_agreed) {
1131                 SLOG(LOG_WARN, tts_tag(), "[Engine Agent WARNING] Invalid parameter, appid is NULL");
1132                 return TTSD_ERROR_NONE;
1133         }
1134
1135         int ret = __check_engine_initialized_and_loaded();
1136         if (TTSD_ERROR_NONE != ret) {
1137                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
1138                 return ret;
1139         }
1140
1141         if (NULL == g_engine_info->callbacks->check_app_agreed) {
1142                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1143                 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1144         }
1145
1146         bool tmp = true; // default value is true until now
1147         ret = g_engine_info->callbacks->check_app_agreed(appid, &tmp);
1148         if (0 != ret) {
1149                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to check app agreed(%d)", ret);
1150                 return TTSD_ERROR_OPERATION_FAILED;
1151         }
1152
1153         *is_agreed = tmp;
1154
1155         return ret;
1156 }
1157
1158 int ttsd_engine_notify_activated_mode_changed(int activated_mode)
1159 {
1160         if (false == __is_agent_initialized()) {
1161                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1162                 return TTSD_ERROR_INVALID_STATE;
1163         }
1164
1165         if (NULL == g_engine_info->callbacks->activated_mode_changed) {
1166                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1167                 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1168         }
1169
1170         g_engine_info->callbacks->activated_mode_changed(activated_mode);
1171
1172         return TTSD_ERROR_NONE;
1173 }
1174
1175 void __free_voice_list(GList* voice_list)
1176 {
1177         GList *iter = NULL;
1178         voice_s* data = NULL;
1179
1180         /* if list have item */
1181         if (g_list_length(voice_list) > 0) {
1182                 /* Get a first item */
1183                 iter = g_list_first(voice_list);
1184
1185                 while (NULL != iter) {
1186                         data = iter->data;
1187
1188                         if (NULL != data) {
1189                                 if (NULL != data->language) {
1190                                         free(data->language);
1191                                         data->language = NULL;
1192                                 }
1193                                 free(data);
1194                                 data = NULL;
1195                         }
1196
1197                         voice_list = g_list_remove_link(voice_list, iter);
1198                         g_list_free(iter);
1199                         iter = g_list_first(voice_list);
1200                 }
1201         }
1202 }
1203
1204 /*
1205 * TTS Engine Callback Functions                                                                                 `                                 *
1206 */
1207
1208 /* function for debugging */
1209 int ttsd_print_voicelist()
1210 {
1211         /* Test log */
1212         GSList *iter = NULL;
1213         ttsvoice_s* data = NULL;
1214
1215         SLOG(LOG_DEBUG, tts_tag(), "@@@ Voice list @@@");
1216
1217         if (g_slist_length(g_cur_voices) > 0) {
1218                 /* Get a first item */
1219                 iter = g_slist_nth(g_cur_voices, 0);
1220
1221                 int i = 1;
1222                 while (NULL != iter) {
1223                         /*Get handle data from list*/
1224                         data = iter->data;
1225
1226                         if (NULL == data || NULL == data->lang) {
1227                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Data is invalid");
1228                                 return TTSD_ERROR_NONE;
1229                         }
1230
1231                         SLOG(LOG_DEBUG, tts_tag(), "[%dth] default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1232                                  i, data->is_default, data->is_loaded,  data->client_ref_count, data->lang, data->type);
1233
1234                         /*Get next item*/
1235                         iter = g_slist_next(iter);
1236                         i++;
1237                 }
1238         }
1239
1240         SLOG(LOG_DEBUG, tts_tag(), "@@@@@");
1241
1242         return TTSD_ERROR_NONE;
1243 }
1244
1245
1246 /** Set callbacks of the current engine */
1247 int ttsd_engine_agent_set_private_data_set_cb(ttse_private_data_set_cb callback)
1248 {
1249         if (false == __is_agent_initialized()) {
1250                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1251                 return TTSD_ERROR_INVALID_STATE;
1252         }
1253
1254         g_engine_info->callbacks->private_data_set = callback;
1255
1256         return TTSD_ERROR_NONE;
1257 }
1258
1259 int ttsd_engine_agent_set_private_data_requested_cb(ttse_private_data_requested_cb callback)
1260 {
1261         if (false == __is_agent_initialized()) {
1262                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1263                 return TTSD_ERROR_INVALID_STATE;
1264         }
1265
1266         g_engine_info->callbacks->private_data_requested = callback;
1267
1268         return TTSD_ERROR_NONE;
1269 }
1270
1271 int ttsd_engine_agent_set_activated_mode_changed_cb(ttse_activated_mode_changed_cb callback)
1272 {
1273         if (false == __is_agent_initialized()) {
1274                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1275                 return TTSD_ERROR_INVALID_STATE;
1276         }
1277
1278         g_engine_info->callbacks->activated_mode_changed = callback;
1279
1280         return TTSD_ERROR_NONE;
1281 }