sync codes to 2.4 spin
[platform/core/uifw/tts.git] / server / ttsd_server.c
1 /*
2 *  Copyright (c) 2011-2014 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 <aul.h>
15 #include <Ecore.h>
16
17 #include "ttsd_config.h"
18 #include "ttsd_data.h"
19 #include "ttsd_dbus.h"
20 #include "ttsd_dbus_server.h"
21 #include "ttsd_engine_agent.h"
22 #include "ttsd_main.h"
23 #include "ttsd_network.h"
24 #include "ttsd_player.h"
25 #include "ttsd_server.h"
26 #include "ttsp.h"
27
28
29 typedef enum {
30         TTSD_SYNTHESIS_CONTROL_DOING    = 0,
31         TTSD_SYNTHESIS_CONTROL_DONE     = 1,
32         TTSD_SYNTHESIS_CONTROL_EXPIRED  = 2
33 } ttsd_synthesis_control_e;
34
35 typedef struct {
36         int uid;
37         int uttid;
38 } utterance_t;
39
40 /* If current engine exist */
41 static bool     g_is_engine;
42
43 /* If engine is running */
44 static ttsd_synthesis_control_e g_synth_control;
45
46 static Ecore_Timer* g_wait_timer = NULL;
47
48 static utterance_t g_utt;
49
50 static GList *g_proc_list = NULL;
51
52 /* Function definitions */
53 static int __synthesis(int uid);
54
55 static int __server_set_synth_control(ttsd_synthesis_control_e control)
56 {
57         g_synth_control = control;
58         return 0;
59 }
60
61 static ttsd_synthesis_control_e __server_get_synth_control()
62 {
63         return g_synth_control;
64 }
65
66 static Eina_Bool __wait_synthesis(void *data)
67 {
68         /* get current play */
69         int uid = ttsd_data_get_current_playing();
70
71         if (uid > 0) {
72                 if (TTSD_SYNTHESIS_CONTROL_DOING == __server_get_synth_control()) {
73                         usleep(100000);
74                         return EINA_TRUE;
75                 } else {
76                         g_wait_timer = NULL;
77                         if (TTSD_SYNTHESIS_CONTROL_DONE == __server_get_synth_control()) {
78                                 /* Start next synthesis */
79                                 __synthesis(uid);
80                         }
81                 }
82         } else {
83                 g_wait_timer = NULL;
84         }
85
86         return EINA_FALSE;
87 }
88
89 static int __synthesis(int uid)
90 {
91         SLOG(LOG_DEBUG, get_tag(), "===== SYNTHESIS  START");
92
93         speak_data_s* speak_data = NULL;
94         if (0 == ttsd_data_get_speak_data(uid, &speak_data)) {
95                 if (NULL == speak_data) {
96                         return 0;
97                 }
98
99                 if (NULL == speak_data->lang || NULL == speak_data->text) {
100                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Current data is NOT valid");
101                         ttsd_server_stop(uid);
102
103                         int pid = ttsd_data_get_pid(uid);
104                         ttsdc_send_set_state_message(pid, uid, APP_STATE_READY);
105
106                         if (NULL != speak_data) {
107                                 if (NULL != speak_data->lang)   free(speak_data->lang);
108                                 if (NULL != speak_data->text)   free(speak_data->text);
109
110                                 speak_data->lang = NULL;
111                                 speak_data->text = NULL;
112
113                                 free(speak_data);
114                                 speak_data = NULL;
115                         }
116
117                         return 0;
118                 }
119
120                 g_utt.uid = uid;
121                 g_utt.uttid = speak_data->utt_id;
122
123                 SLOG(LOG_DEBUG, get_tag(), "-----------------------------------------------------------");
124                 SECURE_SLOG(LOG_DEBUG, get_tag(), "ID : uid (%d), uttid(%d) ", g_utt.uid, g_utt.uttid);
125                 SECURE_SLOG(LOG_DEBUG, get_tag(), "Voice : langauge(%s), type(%d), speed(%d)", speak_data->lang, speak_data->vctype, speak_data->speed);
126                 SECURE_SLOG(LOG_DEBUG, get_tag(), "Text : %s", speak_data->text);
127                 SLOG(LOG_DEBUG, get_tag(), "-----------------------------------------------------------");
128
129                 int ret = 0;
130                 __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_DOING);
131                 ret = ttsd_engine_start_synthesis(speak_data->lang, speak_data->vctype, speak_data->text, speak_data->speed, NULL);
132                 if (0 != ret) {
133                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR] * FAIL to start SYNTHESIS !!!! * ");
134
135                         __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_DONE);
136
137                         ttsd_server_stop(uid);
138
139                         int pid = ttsd_data_get_pid(uid);
140                         ttsdc_send_set_state_message(pid, uid, APP_STATE_READY);
141                 } else {
142                         g_wait_timer = ecore_timer_add(0, __wait_synthesis, NULL);
143                 }
144
145                 if (NULL != speak_data) {
146                         if (NULL != speak_data->lang)   free(speak_data->lang);
147                         if (NULL != speak_data->text)   free(speak_data->text);
148
149                         speak_data->lang = NULL;
150                         speak_data->text = NULL;
151
152                         free(speak_data);
153                         speak_data = NULL;
154                 }
155         }
156
157         SLOG(LOG_DEBUG, get_tag(), "===== SYNTHESIS  END");
158         SLOG(LOG_DEBUG, get_tag(), "  ");
159
160         return 0;
161 }
162
163 /*
164 * TTS Server Callback Functions
165 */
166 int __synthesis_result_callback(ttsp_result_event_e event, const void* data, unsigned int data_size, 
167                                 ttsp_audio_type_e audio_type, int rate, void *user_data)
168 {
169         SLOG(LOG_DEBUG, get_tag(), "===== SYNTHESIS RESULT CALLBACK START");
170
171         int uid = g_utt.uid;
172         int uttid = g_utt.uttid;
173
174         /* Synthesis is success */
175         if (TTSP_RESULT_EVENT_START == event || TTSP_RESULT_EVENT_CONTINUE == event || TTSP_RESULT_EVENT_FINISH == event) {
176                 
177                 if (TTSP_RESULT_EVENT_START == event) {
178                         SLOG(LOG_DEBUG, get_tag(), "[SERVER] Event : TTSP_RESULT_EVENT_START");
179                         SECURE_SLOG(LOG_DEBUG, get_tag(), "[SERVER] Result Info : uid(%d), utt(%d), data(%p), data size(%d) audiotype(%d) rate(%d)", 
180                                 uid, uttid, data, data_size, audio_type, rate);
181                 } else if (TTSP_RESULT_EVENT_FINISH == event) {
182                         SLOG(LOG_DEBUG, get_tag(), "[SERVER] Event : TTSP_RESULT_EVENT_FINISH");
183                         SECURE_SLOG(LOG_DEBUG, get_tag(), "[SERVER] Result Info : uid(%d), utt(%d), data(%p), data size(%d) audiotype(%d) rate(%d)", 
184                                 uid, uttid, data, data_size, audio_type, rate);
185                 } else {
186                         /*if (TTSP_RESULT_EVENT_CONTINUE == event)  SLOG(LOG_DEBUG, get_tag(), "[SERVER] Event : TTSP_RESULT_EVENT_CONTINUE");*/
187                 }
188
189
190                 if (false == ttsd_data_is_uttid_valid(uid, uttid)) {
191                         __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_DONE);
192                         SLOG(LOG_ERROR, get_tag(), "[SERVER ERROR] uttid is NOT valid !!!! - uid(%d), uttid(%d)", uid, uttid);
193                         SLOG(LOG_DEBUG, get_tag(), "=====");
194                         SLOG(LOG_DEBUG, get_tag(), "  ");
195                         return 0;
196                 }
197
198                 if (rate <= 0 || audio_type < 0 || audio_type > TTSP_AUDIO_TYPE_MAX) {
199                         __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_DONE);
200                         SLOG(LOG_ERROR, get_tag(), "[SERVER ERROR] audio data is invalid");
201                         SLOG(LOG_DEBUG, get_tag(), "=====");
202                         SLOG(LOG_DEBUG, get_tag(), "  ");
203                         return 0;
204                 }
205
206                 /* add wav data */
207                 sound_data_s* temp_sound_data = NULL;
208                 temp_sound_data = (sound_data_s*)calloc(1, sizeof(sound_data_s));
209                 if (NULL == temp_sound_data) {
210                         SLOG(LOG_ERROR, get_tag(), "[SERVER ERROR] Out of memory");
211                         return 0;
212                 }
213                 
214                 temp_sound_data->data = NULL;
215                 temp_sound_data->rate = 0;
216                 temp_sound_data->data_size = 0;
217
218                 if (0 < data_size) {
219                         temp_sound_data->data = (char*)calloc(data_size + 5, sizeof(char));
220                         if (NULL != temp_sound_data->data) {
221                                 memcpy(temp_sound_data->data, data, data_size);
222                                 temp_sound_data->data_size = data_size;
223                                 SLOG(LOG_ERROR, get_tag(), "[DEBUG][free] uid(%d), event(%d) sound_data(%p) data(%p) size(%d)", 
224                                         uid, event, temp_sound_data, temp_sound_data->data, temp_sound_data->data_size);
225                         } else {
226                                 SLOG(LOG_ERROR, get_tag(), "Fail to allocate memory");
227                         }
228                 } else {
229                         SLOG(LOG_ERROR, get_tag(), "Sound data is NULL");
230                 }
231
232                 temp_sound_data->utt_id = uttid;
233                 temp_sound_data->event = event;
234                 temp_sound_data->audio_type = audio_type;
235                 temp_sound_data->rate = rate;
236
237                 if (0 != ttsd_data_add_sound_data(uid, temp_sound_data)) {
238                         SECURE_SLOG(LOG_ERROR, get_tag(), "[SERVER ERROR] Fail to add sound data : uid(%d)", uid);
239                 }
240
241                 if (event == TTSP_RESULT_EVENT_FINISH) {
242                         __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_DONE);
243                 }
244
245                 if (0 != ttsd_player_play(uid)) {
246                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to play sound : uid(%d)", uid);
247
248                         /* Change ready state */
249                         ttsd_server_stop(uid);
250
251                         int tmp_pid;
252                         tmp_pid = ttsd_data_get_pid(uid);
253                         ttsdc_send_set_state_message(tmp_pid, uid, APP_STATE_READY);
254                 }
255         } else {
256                 SLOG(LOG_DEBUG, get_tag(), "[SERVER] Event : TTSP_RESULT_EVENT_ERROR");
257                 __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_EXPIRED);
258         }
259
260
261         /*SLOG(LOG_DEBUG, get_tag(), "===== SYNTHESIS RESULT CALLBACK END");
262         SLOG(LOG_DEBUG, get_tag(), "  ");*/
263
264         return 0;
265 }
266
267 bool __get_client_cb(int pid, int uid, app_state_e state, void* user_data)
268 {
269         /* clear client data */
270         ttsd_data_clear_data(uid);
271         ttsd_data_set_client_state(uid, APP_STATE_READY);
272
273         /* send message */
274         if (0 != ttsdc_send_set_state_message(pid, uid, APP_STATE_READY)) {
275                 /* remove client */
276                 ttsd_data_delete_client(uid);
277         }
278
279         return true;
280 }
281
282 void __config_changed_cb(tts_config_type_e type, const char* str_param, int int_param)
283 {
284         switch (type) {
285         case TTS_CONFIG_TYPE_ENGINE:
286         {
287                 if (NULL == str_param) {
288                         SLOG(LOG_ERROR, get_tag(), "[Server] engine id from config is NULL");
289                         return;
290                 }
291
292                 int ret = 0;
293                 if (true == ttsd_engine_agent_is_same_engine(str_param)) {
294                         SLOG(LOG_DEBUG, get_tag(), "[Server Setting] new engine is the same as current engine");
295                         ret = ttsd_engine_agent_unload_current_engine();
296                         if (0 != ret) {
297                                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to unload current engine : result(%d)", ret);
298                         }
299
300                         ret = ttsd_engine_agent_load_current_engine();
301                         if (0 != ret) {
302                                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to load current engine : result (%d)", ret);
303                         }
304                         return;
305                 }
306
307                 /* stop all player */ 
308                 ttsd_player_all_stop();
309
310                 /* send interrupt message to  all clients */
311                 ttsd_data_foreach_clients(__get_client_cb, NULL);
312
313                 ttsd_engine_cancel_synthesis();
314
315                 /* set engine */
316                 ret = ttsd_engine_agent_set_default_engine(str_param);
317                 if (0 != ret) {
318                         SLOG(LOG_WARN, get_tag(), "[Server Setting WARNING] Fail to set current engine : result(%d)", ret);
319                 }
320
321                 break;
322         }
323
324         case TTS_CONFIG_TYPE_VOICE:
325         {
326                 if (NULL == str_param) {
327                         SLOG(LOG_ERROR, get_tag(), "[Server] language from config is NULL");
328                         return;
329                 }
330
331                 char* out_lang = NULL;
332                 int out_type;
333                 int ret = -1;
334
335                 if (true == ttsd_engine_select_valid_voice(str_param, int_param, &out_lang, &out_type)) {
336                         SLOG(LOG_ERROR, get_tag(), "[Server] valid language : lang(%s), type(%d)", out_lang, out_type);
337                         ret = ttsd_engine_agent_set_default_voice(out_lang, out_type);
338                         if (0 != ret)
339                                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to set valid language : lang(%s), type(%d)", out_lang, out_type);
340                 } else {
341                         /* Current language is not available */
342                         SLOG(LOG_WARN, get_tag(), "[Server WARNING] Fail to set voice : lang(%s), type(%d)", str_param, int_param);
343                 }
344                 if (NULL != out_lang)   free(out_lang);
345                 break;
346         }
347
348         case TTS_CONFIG_TYPE_SPEED:
349         {
350                 if (TTS_SPEED_MIN <= int_param && int_param <= TTS_SPEED_MAX) {
351                         /* set default speed */
352                         int ret = 0;
353                         ret = ttsd_engine_agent_set_default_speed(int_param);
354                         if (0 != ret) {
355                                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to set default speed : result(%d)", ret);
356                         }       
357                 }
358                 break;
359         }
360
361         case TTS_CONFIG_TYPE_PITCH:
362         {
363                 if (TTS_PITCH_MIN <= int_param && int_param <= TTS_PITCH_MAX) {
364                         /* set default speed */
365                         int ret = 0;
366                         ret = ttsd_engine_agent_set_default_pitch(int_param);
367                         if (0 != ret) {
368                                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to set default pitch : result(%d)", ret);
369                         }       
370                 }
371                 break;
372         }
373
374         default:
375                 break;
376         }
377         
378         return;
379 }
380
381 bool __terminate_client(int pid, int uid, app_state_e state, void* user_data)
382 {
383         SLOG(LOG_DEBUG, get_tag(), "=== Start to terminate client [%d] ===", uid);
384         ttsd_server_finalize(uid);
385         return true;
386 }
387
388 Eina_Bool ttsd_terminate_daemon(void *data) 
389 {
390         ttsd_data_foreach_clients(__terminate_client, NULL);
391         return EINA_FALSE;
392 }
393
394 void __screen_reader_changed_cb(bool value)
395 {
396         if (TTSD_MODE_SCREEN_READER == ttsd_get_mode() && false == value) {
397                 SLOG(LOG_DEBUG, get_tag(), "[Server] Screen reader is OFF. Start to terminate tts daemon");
398                 ecore_timer_add(1, ttsd_terminate_daemon, NULL);
399         } else {
400                 SLOG(LOG_DEBUG, get_tag(), "[Server] Screen reader is %s", value ? "ON" : "OFF");
401         }
402         return;
403 }
404
405 /*
406 * Server APIs
407 */
408
409 int ttsd_initialize()
410 {
411         if (ttsd_config_initialize(__config_changed_cb)) {
412                 SLOG(LOG_ERROR, get_tag(), "[Server WARNING] Fail to initialize config.");
413         }
414
415         /* player init */
416         if (ttsd_player_init()) {
417                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to initialize player init.");
418                 return TTSD_ERROR_OPERATION_FAILED;
419         }
420
421         /* Engine Agent initialize */
422         if (0 != ttsd_engine_agent_init(__synthesis_result_callback)) {
423                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to engine agent initialize.");
424                 return TTSD_ERROR_OPERATION_FAILED;
425         }
426
427         /* set current engine */
428         if (0 != ttsd_engine_agent_initialize_current_engine()) {
429                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] No Engine !!!");
430                 g_is_engine = false;
431         } else
432                 g_is_engine = true;
433
434         __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_EXPIRED);
435
436         if (TTSD_MODE_SCREEN_READER == ttsd_get_mode()) {
437                 ttsd_config_set_screen_reader_callback(__screen_reader_changed_cb);
438         }
439
440         return TTSD_ERROR_NONE;
441 }
442
443 int ttsd_finalize()
444 {
445         GList *iter = NULL;
446         if (0 < g_list_length(g_proc_list)) {
447                 iter = g_list_first(g_proc_list);
448                 while (NULL != iter) {
449                         g_proc_list = g_list_remove_link(g_proc_list, iter);
450                         g_list_free(iter);
451                         iter = g_list_first(g_proc_list);
452                 }
453         }
454         
455         ttsd_config_finalize();
456
457         ttsd_player_release();
458
459         ttsd_engine_agent_release();
460
461         return TTSD_ERROR_NONE;
462 }
463
464 static void __read_proc()
465 {
466         DIR *dp = NULL;
467         struct dirent entry;
468         struct dirent *dirp = NULL;
469         int ret = -1;
470         int tmp;
471
472         GList *iter = NULL;
473         if (0 < g_list_length(g_proc_list)) {
474                 iter = g_list_first(g_proc_list);
475                 while (NULL != iter) {
476                         g_proc_list = g_list_remove_link(g_proc_list, iter);
477                         g_list_free(iter);
478                         iter = g_list_first(g_proc_list);
479                 }
480         }
481
482         dp = opendir("/proc");
483         if (NULL == dp) {
484                 SLOG(LOG_ERROR, get_tag(), "[ERROR] Fail to open proc");
485         } else {
486                 do {
487                         ret = readdir_r(dp, &entry, &dirp);
488                         if (0 != ret) {
489                                 SLOG(LOG_ERROR, get_tag(), "[ERROR] Fail to readdir");
490                                 break;
491                         }
492
493                         if (NULL != dirp) {
494                                 tmp = atoi(dirp->d_name);
495                                 if (0 >= tmp)   continue;
496                                 g_proc_list = g_list_append(g_proc_list, GINT_TO_POINTER(tmp));
497                         }
498                 } while (NULL != dirp);
499                 closedir(dp);
500         }
501         return;
502 }
503
504 bool __get_client_for_clean_up(int pid, int uid, app_state_e state, void* user_data)
505 {
506         bool exist = false;
507         int i = 0;
508         
509         GList *iter = NULL;
510         for (i = 0; i < g_list_length(g_proc_list); i++) {
511                 iter = g_list_nth(g_proc_list, i);
512                 if (NULL != iter) {
513                         if (pid == GPOINTER_TO_INT(iter->data)) {
514                                 SLOG(LOG_DEBUG, get_tag(), "uid (%d) is running", uid);
515                                 exist = true;
516                                 break;
517                         }
518                 }
519         }
520         
521         if (false == exist) {
522                 SLOG(LOG_ERROR, get_tag(), "uid (%d) should be removed", uid);
523                 ttsd_server_finalize(uid);
524         }
525
526         return true;
527 #if 0
528         char appid[128] = {0, };
529         if (0 != aul_app_get_appid_bypid(pid, appid, sizeof(appid))) {
530                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to get app id");
531         }
532
533         if (0 < strlen(appid)) {
534                 SLOG(LOG_DEBUG, get_tag(), "[%d] is running app - %s", pid, appid);
535         } else {
536                 SLOG(LOG_DEBUG, get_tag(), "[%d] is daemon or no_running app", pid);
537
538                 int result = 1;
539                 result = ttsdc_send_hello(pid, uid);
540
541                 if (0 == result) {
542                         SLOG(LOG_DEBUG, get_tag(), "[Server] uid(%d) should be removed.", uid);
543                         ttsd_server_finalize(uid);
544                 } else if (-1 == result) {
545                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Hello result has error");
546                 }
547         }
548         return true;
549 #endif
550 }
551
552
553 Eina_Bool ttsd_cleanup_client(void *data)
554 {
555         SLOG(LOG_DEBUG, get_tag(), "===== CLEAN UP CLIENT START");
556         __read_proc();
557         ttsd_data_foreach_clients(__get_client_for_clean_up, NULL);
558         SLOG(LOG_DEBUG, get_tag(), "=====");
559         SLOG(LOG_DEBUG, get_tag(), "  ");
560
561         return EINA_TRUE;
562 }
563
564 /*
565 * TTS Server Functions for Client
566 */
567
568 int ttsd_server_initialize(int pid, int uid)
569 {
570         if (false == g_is_engine) {
571                 if (0 != ttsd_engine_agent_initialize_current_engine()) {
572                         SLOG(LOG_WARN, get_tag(), "[Server WARNING] No Engine !!!");
573                         g_is_engine = false;
574
575                         return TTSD_ERROR_ENGINE_NOT_FOUND;
576                 } else {
577                         g_is_engine = true;
578                 }
579         }
580
581         if (-1 != ttsd_data_is_client(uid)) {
582                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] Uid has already been registered");
583                 return TTSD_ERROR_NONE;
584         }
585
586         if (0 == ttsd_data_get_client_count()) {
587                 if (0 != ttsd_engine_agent_load_current_engine()) {
588                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to load current engine");
589                         return TTSD_ERROR_OPERATION_FAILED;
590                 }
591         }
592
593         if (0 != ttsd_data_new_client(pid, uid)) {
594                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to add client info");
595                 return TTSD_ERROR_OPERATION_FAILED;
596         }
597
598         if (0 != ttsd_player_create_instance(uid)) {
599                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to create player");
600                 return TTSD_ERROR_OPERATION_FAILED;
601         }
602
603         return TTSD_ERROR_NONE;
604 }
605
606 static Eina_Bool __quit_ecore_loop(void *data)
607 {
608         ecore_main_loop_quit();
609         return EINA_FALSE;
610 }
611
612 void __used_voice_cb(const char* lang, int type)
613 {
614         SLOG(LOG_DEBUG, get_tag(), "[Server] Request to unload voice (%s,%d)", lang, type);
615         if (0 != ttsd_engine_unload_voice(lang, type)) {
616                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to unload voice");
617         }
618 }
619
620 int ttsd_server_finalize(int uid)
621 {
622         app_state_e state;
623         if (0 > ttsd_data_get_client_state(uid, &state)) {
624                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] ttsd_server_finalize : uid is not valid");
625         }
626
627         ttsd_server_stop(uid);
628         ttsd_player_stop(uid);
629         
630         ttsd_player_destroy_instance(uid);
631
632         /* Need to unload voice when used voice is unregistered */
633         if (0 != ttsd_data_reset_used_voice(uid, __used_voice_cb)) {
634                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to set used voice");
635                 return TTSD_ERROR_OPERATION_FAILED;
636         }
637
638         ttsd_data_delete_client(uid);
639
640         /* unload engine, if ref count of client is 0 */
641         if (0 == ttsd_data_get_client_count()) {
642                 SLOG(LOG_DEBUG, get_tag(), "[Server] Quit main loop");
643                 ecore_timer_add(0, __quit_ecore_loop, NULL);
644         }
645
646         return TTSD_ERROR_NONE;
647 }
648
649 int ttsd_server_add_queue(int uid, const char* text, const char* lang, int voice_type, int speed, int utt_id)
650 {
651         app_state_e state;
652         if (0 > ttsd_data_get_client_state(uid, &state)) {
653                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] ttsd_server_add_queue : uid is not valid");
654                 return TTSD_ERROR_INVALID_PARAMETER;
655         }
656
657         /* check valid voice */
658         char* temp_lang = NULL;
659         int temp_type;
660         if (true != ttsd_engine_select_valid_voice((const char*)lang, voice_type, &temp_lang, &temp_type)) {
661                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to select valid voice");
662                 if (NULL != temp_lang)  free(temp_lang);
663                 return TTSD_ERROR_INVALID_VOICE;
664         }
665
666         if (NULL == temp_lang) {
667                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to select valid voice : result lang is NULL");
668                 return TTSD_ERROR_INVALID_VOICE;
669         }
670         
671         speak_data_s* speak_data = NULL;
672         speak_data = (speak_data_s*)calloc(1, sizeof(speak_data_s));
673         if (NULL == speak_data) {
674                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to allocate memory");
675                 if (NULL != temp_lang)  free(temp_lang);
676                 return TTSD_ERROR_OPERATION_FAILED;
677         }
678
679         speak_data->lang = strdup(lang);
680         speak_data->vctype = voice_type;
681
682         speak_data->speed = speed;
683         speak_data->utt_id = utt_id;
684
685         speak_data->text = strdup(text);
686
687         /* if state is APP_STATE_READY , APP_STATE_PAUSED , only need to add speak data to queue*/
688         if (0 != ttsd_data_add_speak_data(uid, speak_data)) {
689                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to add speak data");
690                 if (NULL != temp_lang)  free(temp_lang);
691                 if (NULL != speak_data) {
692                         if (NULL != speak_data->lang)   free(speak_data->lang);
693                         if (NULL != speak_data->text)   free(speak_data->text);
694
695                         speak_data->lang = NULL;
696                         speak_data->text = NULL;
697
698                         free(speak_data);
699                         speak_data = NULL;
700                 }
701
702                 return TTSD_ERROR_OPERATION_FAILED;
703         }
704
705         if (0 != ttsd_data_set_used_voice(uid, temp_lang, temp_type)) {
706                 /* Request load voice */
707                 SLOG(LOG_DEBUG, get_tag(), "[Server] Request to load voice");
708                 if (0 != ttsd_engine_load_voice(temp_lang, temp_type)) {
709                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to load voice");
710                 }
711         }
712
713         if (NULL != temp_lang)  free(temp_lang);
714
715         if (APP_STATE_PLAYING == state) {
716                 /* check if engine use network */
717                 if (ttsd_engine_agent_need_network()) {
718                         if (false == ttsd_network_is_connected()) {
719                                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Disconnect network. Current engine needs network.");
720                                 return TTSD_ERROR_OPERATION_FAILED;
721                         }
722                 }
723
724                 /* Check whether tts-engine is running or not */
725                 if (TTSD_SYNTHESIS_CONTROL_DOING == __server_get_synth_control()) {
726                         SLOG(LOG_WARN, get_tag(), "[Server WARNING] Engine has already been running.");
727                 } else {
728                         __synthesis(uid);
729                 }
730         }
731
732         return TTSD_ERROR_NONE;
733 }
734
735 Eina_Bool __send_interrupt_client(void *data)
736 {
737         int uid = (int)data;
738
739         int pid = ttsd_data_get_pid(uid);
740
741         if (TTSD_MODE_DEFAULT != ttsd_get_mode()) {
742                 /* send message to client about changing state */
743                 ttsdc_send_set_state_message(pid, uid, APP_STATE_READY);
744         } else {
745                 ttsdc_send_set_state_message(pid, uid, APP_STATE_PAUSED);
746         }
747
748         return EINA_FALSE;
749 }
750
751 int ttsd_server_play(int uid)
752 {
753         app_state_e state;
754         if (0 > ttsd_data_get_client_state(uid, &state)) {
755                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] uid(%d) is NOT valid  ", uid);
756                 return TTSD_ERROR_INVALID_PARAMETER;
757         }
758
759         if (APP_STATE_PLAYING == state) {
760                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] Current state(%d) is 'play' ", uid);
761                 return TTSD_ERROR_NONE;
762         }
763
764         /* check if engine use network */
765         if (ttsd_engine_agent_need_network()) {
766                 if (false == ttsd_network_is_connected()) {
767                         SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Disconnect network. Current engine needs network service!!!.");
768                         return TTSD_ERROR_OUT_OF_NETWORK;
769                 }
770         }
771
772         int current_uid = ttsd_data_get_current_playing();
773         SLOG(LOG_ERROR, get_tag(), "[Server] playing uid (%d)", current_uid);
774
775         if (uid != current_uid && -1 != current_uid) {
776                 if (TTSD_MODE_DEFAULT != ttsd_get_mode()) {
777                         /* Send interrupt message */
778                         SLOG(LOG_DEBUG, get_tag(), "[Server] Old uid(%d) will be interrupted into 'Stop' state ", current_uid);
779
780                         /* pause player */
781                         if (0 != ttsd_server_stop(current_uid)) {
782                                 SLOG(LOG_WARN, get_tag(), "[Server ERROR] Fail to stop : uid (%d)", current_uid);
783                         }
784                         if (0 != ttsd_player_stop(current_uid)) {
785                                 SLOG(LOG_WARN, get_tag(), "[Server ERROR] Fail to player stop : uid (%d)", current_uid);
786                         }
787
788                         ecore_timer_add(0, __send_interrupt_client, (void*)current_uid);
789                 } else {
790                         /* Default mode policy of interrupt is "Pause" */
791
792                         /* Send interrupt message */
793                         SLOG(LOG_DEBUG, get_tag(), "[Server] Old uid(%d) will be interrupted into 'Pause' state ", current_uid);
794
795                         /* pause player */
796                         if (0 != ttsd_player_pause(current_uid)) {
797                                 SLOG(LOG_WARN, get_tag(), "[Server ERROR] Fail to ttsd_player_pause() : uid (%d)", current_uid);
798                         }
799
800                         /* change state */
801                         ttsd_data_set_client_state(current_uid, APP_STATE_PAUSED);
802
803                         ecore_timer_add(0, __send_interrupt_client, (void*)current_uid);
804                 }
805         }
806
807         /* Change current play */
808         if (0 != ttsd_data_set_client_state(uid, APP_STATE_PLAYING)) {
809                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to set state : uid(%d)", uid);
810                 return TTSD_ERROR_OPERATION_FAILED;
811         }
812
813         if (APP_STATE_PAUSED == state) {
814                 SLOG(LOG_DEBUG, get_tag(), "[Server] uid(%d) is 'Pause' state : resume player", uid);
815
816                 /* Resume player */
817                 if (0 != ttsd_player_resume(uid)) {
818                         SLOG(LOG_WARN, get_tag(), "[Server WARNING] Fail to ttsd_player_resume()");
819                 }
820         }
821
822         /* Check whether tts-engine is running or not */
823         if (TTSD_SYNTHESIS_CONTROL_DOING == __server_get_synth_control()) {
824                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] Engine has already been running.");
825         } else {
826                 __synthesis(uid);
827         }
828
829         return TTSD_ERROR_NONE;
830 }
831
832
833 int ttsd_server_stop(int uid)
834 {
835         app_state_e state;
836         if (0 > ttsd_data_get_client_state(uid, &state)) {
837                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] uid is not valid");
838                 return TTSD_ERROR_INVALID_PARAMETER;
839         }
840
841         if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
842                 if (TTSD_SYNTHESIS_CONTROL_DOING == __server_get_synth_control()) {
843                         SLOG(LOG_DEBUG, get_tag(), "[Server] TTS-engine is running");
844
845                         int ret = 0;
846                         ret = ttsd_engine_cancel_synthesis();
847                         if (0 != ret)
848                                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail to cancel synthesis : ret(%d)", ret);
849                 }
850
851                 __server_set_synth_control(TTSD_SYNTHESIS_CONTROL_EXPIRED);
852
853                 if (0 != ttsd_player_clear(uid))
854                         SLOG(LOG_WARN, get_tag(), "[Server] Fail to ttsd_player_stop()");
855
856                 ttsd_data_set_client_state(uid, APP_STATE_READY);
857         }
858
859         /* Reset all data */
860         ttsd_data_clear_data(uid);
861
862         return TTSD_ERROR_NONE;
863 }
864
865 int ttsd_server_pause(int uid, int* utt_id)
866 {
867         app_state_e state;
868         if (0 > ttsd_data_get_client_state(uid, &state)) {
869                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] ttsd_server_pause : uid is not valid");
870                 return TTSD_ERROR_INVALID_PARAMETER;
871         }
872
873         if (APP_STATE_PLAYING != state) {
874                 SLOG(LOG_WARN, get_tag(), "[Server WARNING] Current state is not 'play'");
875                 return TTSD_ERROR_INVALID_STATE;
876         }
877
878         int ret = 0;
879         ret = ttsd_player_pause(uid);
880         if (0 != ret) {
881                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail player_pause() : ret(%d)", ret);
882                 return TTSD_ERROR_OPERATION_FAILED;
883         }
884
885         ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
886
887         return TTSD_ERROR_NONE;
888 }
889
890 int ttsd_server_get_support_voices(int uid, GList** voice_list)
891 {
892         app_state_e state;
893         if (0 > ttsd_data_get_client_state(uid, &state)) {
894                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] uid is not valid");
895                 return TTSD_ERROR_INVALID_PARAMETER;
896         }
897
898         /* get voice list*/
899         if (0 != ttsd_engine_get_voice_list(voice_list)) {
900                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail ttsd_server_get_support_voices()");
901                 return TTSD_ERROR_OPERATION_FAILED;
902         }
903
904         SLOG(LOG_DEBUG, get_tag(), "[Server SUCCESS] Get supported voices");
905
906         return TTSD_ERROR_NONE;
907 }
908
909 int ttsd_server_get_current_voice(int uid, char** language, int* voice_type)
910 {
911         app_state_e state;
912         if (0 > ttsd_data_get_client_state(uid, &state)) {
913                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] ttsd_server_get_current_voice : uid is not valid");
914                 return TTSD_ERROR_INVALID_PARAMETER;
915         }
916
917         /* get current voice */
918         int ret = ttsd_engine_get_default_voice(language, voice_type);
919         if (0 != ret) {
920                 SLOG(LOG_ERROR, get_tag(), "[Server ERROR] Fail ttsd_server_get_support_voices()");
921                 return ret;
922         }
923
924         SLOG(LOG_DEBUG, get_tag(), "[Server] Get default language (%s), voice type(%d) ", *language, *voice_type);
925
926         return TTSD_ERROR_NONE;
927 }