Delete ecore timer when quit ecore main loop
[platform/core/uifw/tts.git] / server / ttsd_data.cpp
1 /*
2 *  Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved 
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <list>
15 #include <pthread.h>
16 #include <vector>
17
18 #include "ttsd_main.h"
19 #include "ttsd_data.h"
20
21 using namespace std;
22
23 typedef struct
24 {
25         char*   lang;
26         int     vctype;
27 }used_voice_s;
28
29 typedef struct
30 {
31         int             pid;
32         int             uid;
33         int             utt_id_stopped;
34         app_tts_state_e state;
35
36         std::list<speak_data_s*> m_speak_data;
37         std::list<sound_data_s*> m_wav_data;
38
39         std::list<used_voice_s> m_used_voice;
40 }app_data_s;
41
42 static vector<app_data_s> g_app_list;
43
44 static pthread_mutex_t g_speak_data_mutex = PTHREAD_MUTEX_INITIALIZER;
45 static pthread_mutex_t g_sound_data_mutex = PTHREAD_MUTEX_INITIALIZER;
46
47
48 /* If engine is running */
49 static ttsd_synthesis_control_e g_synth_control;
50
51 /*
52 * functions for debug
53 */
54 int __data_show_list()
55 {
56         int vsize = g_app_list.size();
57
58         SLOG(LOG_DEBUG, tts_tag(), "----- client list -----");
59
60         for (int i=0; i < vsize; i++) {
61                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[%dth] pid(%d), uid(%d), state(%d)", i, g_app_list[i].pid, g_app_list[i].uid, g_app_list[i].state);
62         }
63
64         if (0 == vsize) {
65                 SLOG(LOG_DEBUG, tts_tag(), "No Client");
66         }
67
68         SLOG(LOG_DEBUG, tts_tag(), "-----------------------");
69
70         return TTSD_ERROR_NONE;
71 }
72
73 int __data_show_sound_list(int index)
74 {
75         SLOG(LOG_DEBUG, tts_tag(), "----- Sound list -----");
76
77         unsigned int i = 0;
78         if (!g_app_list[index].m_wav_data.empty()) {
79                 std::list<sound_data_s*>::iterator iter;
80                 for (iter = g_app_list[index].m_wav_data.begin(); (NULL != *iter && iter != g_app_list[index].m_wav_data.end()); ++iter) {
81                         SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%d), uttid(%d), type(%d)",
82                                         i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
83                         i++;
84                 }
85         }
86
87         if (i == 0) {
88                 SLOG(LOG_DEBUG, tts_tag(), "No Sound Data");
89         }
90
91         SLOG(LOG_DEBUG, tts_tag(), "----------------------");
92         return TTSD_ERROR_NONE;
93 }
94
95 int __data_show_text_list(int index)
96 {
97         SLOG(LOG_DEBUG, tts_tag(), "----- Text list -----");
98
99         unsigned int i = 0;
100         if (!g_app_list[index].m_speak_data.empty()) {
101                 std::list<speak_data_s*>::iterator iter;
102                 for (iter = g_app_list[index].m_speak_data.begin(); (NULL != *iter && iter != g_app_list[index].m_speak_data.end()); ++iter) {
103                         SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)", 
104                                         i + 1, *iter, (*iter)->lang, (*iter)->vctype, (*iter)->speed, (*iter)->utt_id, (*iter)->text);
105                         i++;
106                 }
107         }
108
109         if (0 == i) {
110                 SLOG(LOG_DEBUG, tts_tag(), "No Text Data");
111         }
112
113         SLOG(LOG_DEBUG, tts_tag(), "---------------------");
114         return TTSD_ERROR_NONE;
115 }
116
117 int __data_show_used_voice_list(int index)
118 {
119         SLOG(LOG_DEBUG, tts_tag(), "----- Used voice list -----");
120
121         unsigned int i = 0;
122         if (!g_app_list[index].m_used_voice.empty()) {
123                 std::list<used_voice_s>::iterator iter;
124                 for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end(); ++iter) {
125                         SLOG(LOG_DEBUG, tts_tag(), "[%dth] lang(%s), vctype(%d)", i + 1, iter->lang, iter->vctype);
126                         i++;
127                 }
128         }
129
130         if (0 == i) {
131                 SLOG(LOG_DEBUG, tts_tag(), "No Voice Data");
132         }
133
134         SLOG(LOG_DEBUG, tts_tag(), "---------------------------");
135         return TTSD_ERROR_NONE;
136 }
137
138 /*
139 * ttsd data functions
140 */
141
142 int ttsd_set_synth_control(ttsd_synthesis_control_e control)
143 {
144         g_synth_control = control;
145         return 0;
146 }
147
148 ttsd_synthesis_control_e ttsd_get_synth_control()
149 {
150         return g_synth_control;
151 }
152
153 int ttsd_data_new_client(int pid, int uid)
154 {
155         if( -1 != ttsd_data_is_client(uid) ) {
156                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
157                 return TTSD_ERROR_INVALID_PARAMETER;
158         }
159
160         app_data_s app;
161         app.pid = pid;
162         app.uid = uid;
163         app.utt_id_stopped = 0;
164         app.state = APP_STATE_READY;
165
166         g_app_list.insert(g_app_list.end(), app);
167
168 #ifdef DATA_DEBUG
169         __data_show_list();
170 #endif
171         return TTSD_ERROR_NONE;
172 }
173
174 int ttsd_data_delete_client(int uid)
175 {
176         int index = 0;
177
178         index = ttsd_data_is_client(uid);
179
180         if (index < 0) {
181                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
182                 return -1;
183         }
184
185         if (0 != ttsd_data_clear_data(uid)) {
186                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] Fail to clear data");
187                 return -1;
188         }
189
190         g_app_list.erase(g_app_list.begin()+index);
191
192 #ifdef DATA_DEBUG
193         __data_show_list();
194 #endif
195         return TTSD_ERROR_NONE;
196 }
197
198 int ttsd_data_is_client(int uid)
199 {
200         int vsize = g_app_list.size();
201
202         for (int i = 0; i < vsize; i++) {
203                 if(g_app_list[i].uid == uid) {
204                         return i;
205                 }
206         }
207
208         return -1;
209 }
210
211 int ttsd_data_get_client_count()
212 {
213         return g_app_list.size();
214 }
215
216 int ttsd_data_get_pid(int uid)
217 {
218         int index;
219
220         index = ttsd_data_is_client(uid);
221
222         if (index < 0)  {
223                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
224                 return TTSD_ERROR_INVALID_PARAMETER;
225         }
226
227         return g_app_list[index].pid;
228 }
229
230 int ttsd_data_get_speak_data_size(int uid)
231 {
232         int index = 0;
233         index = ttsd_data_is_client(uid);
234
235         if (index < 0) {
236                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
237                 return TTSD_ERROR_INVALID_PARAMETER;
238         }
239
240         /* mutex is locked */
241         pthread_mutex_lock(&g_speak_data_mutex);
242         int size = g_app_list[index].m_speak_data.size();
243
244         /* mutex is unlocked */
245         pthread_mutex_unlock(&g_speak_data_mutex);
246
247         return size;
248 }
249
250 int ttsd_data_set_used_voice(int uid, const char* lang, int type)
251 {
252         int index = 0;
253         index = ttsd_data_is_client(uid);
254
255         if (index < 0) {
256                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
257                 return TTSD_ERROR_INVALID_PARAMETER;
258         }
259
260         /* Find voice */
261         std::list<used_voice_s>::iterator iter;
262         if (!g_app_list[index].m_used_voice.empty()) {
263                 for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end();++iter) {
264                         if (0 == strcmp(lang, iter->lang) && type == iter->vctype) {
265                                 SLOG(LOG_DEBUG, tts_tag(), "[DATA] The voice is already registered (%s)(%d)", lang, type);
266                                 return 0;
267                         }
268                 }
269         }
270
271         /* Add voice */
272         used_voice_s used_voice;
273         used_voice.lang = strdup(lang);
274         used_voice.vctype = type;
275
276         try {
277                 iter = g_app_list[index].m_used_voice.insert(g_app_list[index].m_used_voice.end(), used_voice);
278         } catch (const std::bad_alloc&) {
279                 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_used_voice (bad_alloc)");
280                 return -1;
281         }
282         SLOG(LOG_ERROR, tts_tag(), "[DATA] lang(%s), vctype(%d)", iter->lang, iter->vctype);
283
284 #ifdef DATA_DEBUG
285         __data_show_used_voice_list(index);
286 #endif
287
288         return -1;      /* Need to load voice*/
289 }
290
291 int ttsd_data_reset_used_voice(int uid, ttsd_used_voice_cb callback)
292 {
293         int index = 0;
294         index = ttsd_data_is_client(uid);
295
296         if (index < 0) {
297                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
298                 return TTSD_ERROR_INVALID_PARAMETER;
299         }
300
301         if (NULL == callback) {
302                 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] Used voice callback is NULL");
303         }
304
305         /* Find voice */
306         if (!g_app_list[index].m_used_voice.empty()) {
307                 std::list<used_voice_s>::iterator iter;
308
309                 for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end(); ++iter) {
310                         if (NULL != callback) {
311                                 callback(iter->lang, iter->vctype);
312                         }
313
314                         if (NULL != iter->lang) {
315                                 free(iter->lang);
316                                 iter->lang = NULL;
317                         }
318                 }
319
320                 g_app_list[index].m_used_voice.clear();
321         }
322
323 #ifdef DATA_DEBUG
324         __data_show_used_voice_list(index);
325 #endif
326
327         return TTSD_ERROR_NONE;
328 }
329
330 int ttsd_data_add_speak_data(int uid, speak_data_s* data)
331 {
332         int index = 0;
333         index = ttsd_data_is_client(uid);
334
335         if (index < 0) {
336                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
337                 return TTSD_ERROR_INVALID_PARAMETER;
338         }
339
340         /* mutex is locked */
341         pthread_mutex_lock(&g_speak_data_mutex);
342
343         std::list<speak_data_s*>::iterator iter;
344
345         try {
346                 iter = g_app_list[index].m_speak_data.insert(g_app_list[index].m_speak_data.end(), data);
347         } catch (const std::bad_alloc&) {
348                 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_speak_data (bad_alloc)");
349                 pthread_mutex_unlock(&g_speak_data_mutex);
350
351                 return TTSD_ERROR_OUT_OF_MEMORY;
352         }
353         SLOG(LOG_ERROR, tts_tag(), "[DATA][%p] utt_id(%d), text(%s), lang(%s), vctype(%d), speed(%d)", 
354                         *iter, (*iter)->utt_id, (*iter)->text, (*iter)->lang, (*iter)->vctype, (*iter)->speed);
355
356         if (1 == data->utt_id)
357                 g_app_list[index].utt_id_stopped = 0;
358
359 #ifdef DATA_DEBUG
360         __data_show_text_list(index);
361 #endif
362         pthread_mutex_unlock(&g_speak_data_mutex);
363
364         return TTSD_ERROR_NONE;
365 }
366
367 int __get_speak_data(int index, speak_data_s** data)
368 {
369         if (0 == g_app_list[index].m_speak_data.size()) {
370 #ifdef DATA_DEBUG
371                 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] There is no speak data");
372 #endif
373                 return -1;
374         }
375
376         if (!g_app_list[index].m_speak_data.empty()) {
377                 std::list<speak_data_s*>::iterator iter = g_app_list[index].m_speak_data.begin();
378                 *data = *iter;
379                 g_app_list[index].m_speak_data.pop_front();
380         }
381
382 #ifdef DATA_DEBUG
383         __data_show_text_list(index);
384 #endif
385         return 0;
386 }
387
388 int ttsd_data_get_speak_data(int uid, speak_data_s** data)
389 {
390         int index = 0;
391         index = ttsd_data_is_client(uid);
392
393         if (index < 0) {
394                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid(%d)", uid);
395                 return TTSD_ERROR_INVALID_PARAMETER;
396         }
397
398         /* mutex is locked */
399         pthread_mutex_lock(&g_speak_data_mutex);
400
401         if (0 != __get_speak_data(index, data)) {
402                 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] There is no speak data");
403                 pthread_mutex_unlock(&g_speak_data_mutex);
404                 return -1;
405         }
406
407         pthread_mutex_unlock(&g_speak_data_mutex);
408
409         return TTSD_ERROR_NONE;
410 }
411
412 int ttsd_data_add_sound_data(int uid, sound_data_s* data)
413 {
414         int index = 0;
415         index = ttsd_data_is_client(uid);
416
417         if(index < 0) {
418                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
419                 return TTSD_ERROR_INVALID_PARAMETER;
420         }
421
422         if (NULL == data) {
423                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] sound data is NULL");
424                 return TTSD_ERROR_INVALID_PARAMETER;
425         }
426         /* mutex is locked */
427         pthread_mutex_lock(&g_sound_data_mutex);
428
429         std::list<sound_data_s*>::iterator iter;
430
431         try {
432                 iter = g_app_list[index].m_wav_data.insert(g_app_list[index].m_wav_data.end(), data);
433         } catch (const std::bad_alloc&) {
434                 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_sound_data (bad_alloc)");
435                 pthread_mutex_unlock(&g_sound_data_mutex);
436
437                 return TTSD_ERROR_OUT_OF_MEMORY;
438         }
439         SLOG(LOG_ERROR, tts_tag(), "[DATA][%p] utt_id(%d), data(%p) data size(%d), type(%d)", *iter, (*iter)->utt_id, (*iter)->data, (*iter)->data_size, (*iter)->audio_type);
440
441 #ifdef DATA_DEBUG
442         __data_show_sound_list(index);
443 #endif
444
445         /* mutex is unlocked */
446         pthread_mutex_unlock(&g_sound_data_mutex);
447
448         return TTSD_ERROR_NONE;
449 }
450
451 int __get_sound_data(int index, sound_data_s** data)
452 {
453         if (0 == g_app_list[index].m_wav_data.size()) {
454 #ifdef DATA_DEBUG
455                 SLOG(LOG_DEBUG, tts_tag(), "[DATA] There is no wav data");
456 #endif
457                 return -1;
458         }
459
460         if (!g_app_list[index].m_wav_data.empty()) {
461                 std::list<sound_data_s*>::iterator iter = g_app_list[index].m_wav_data.begin();
462                 *data = *iter;
463                 g_app_list[index].m_wav_data.pop_front();
464         }
465
466 #ifdef DATA_DEBUG
467         __data_show_sound_list(index);
468 #endif
469         return 0;
470 }
471
472 int ttsd_data_get_sound_data(int uid, sound_data_s** data)
473 {
474         int index = 0;
475         index = ttsd_data_is_client(uid);
476
477         SLOG(LOG_DEBUG, tts_tag(), "[DATA] sound_data_s: %p", *data);
478
479         if (index < 0)  {
480                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
481                 return TTSD_ERROR_INVALID_PARAMETER;
482         }
483
484         /* mutex is locked */
485         pthread_mutex_lock(&g_sound_data_mutex);
486
487         if (0 != __get_sound_data(index, data)) {
488                 SLOG(LOG_DEBUG, tts_tag(), "[DATA] There is no wav data");
489                 /* mutex is unlocked */
490                 pthread_mutex_unlock(&g_sound_data_mutex);
491                 return -1;
492         }
493         /* mutex is unlocked */
494         pthread_mutex_unlock(&g_sound_data_mutex);
495
496         return TTSD_ERROR_NONE;
497 }
498
499 int ttsd_data_get_sound_data_size(int uid)
500 {
501         int index = 0;
502         int data_size = 0;
503         index = ttsd_data_is_client(uid);
504
505         if (index < 0)  {
506                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
507                 return TTSD_ERROR_INVALID_PARAMETER;
508         }
509
510         /* mutex is locked */
511         pthread_mutex_lock(&g_sound_data_mutex);
512         data_size = g_app_list[index].m_wav_data.size();
513
514         /* mutex is unlocked */
515         pthread_mutex_unlock(&g_sound_data_mutex);
516
517         return data_size;
518 }
519
520 int ttsd_data_clear_speak_data(int uid, speak_data_s** speak_data)
521 {
522         pthread_mutex_lock(&g_speak_data_mutex);
523
524         int index = 0;
525         index = ttsd_data_is_client(uid);
526         if (index >= 0) {
527                 if (NULL != *speak_data) {
528                         SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)", 
529                                         (*speak_data)->utt_id, (*speak_data)->text, (*speak_data)->lang, (*speak_data)->vctype, (*speak_data)->speed);
530
531                         if (NULL != (*speak_data)->text) {
532                                 free((*speak_data)->text);
533                                 (*speak_data)->text = NULL;
534                         }
535                         if (NULL != (*speak_data)->lang) {
536                                 free((*speak_data)->lang);
537                                 (*speak_data)->lang = NULL;
538                         }
539
540                         free(*speak_data);
541                         *speak_data = NULL;
542                 }
543         }
544
545         pthread_mutex_unlock(&g_speak_data_mutex);
546
547         return TTSD_ERROR_NONE;
548 }
549
550 int ttsd_data_clear_sound_data(sound_data_s** sound_data)
551 {
552         pthread_mutex_lock(&g_sound_data_mutex);
553
554         if (NULL != *sound_data) {
555                 SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] event(%d) data(%p) size(%d) rate(%d) utt(%d)", 
556                                 (*sound_data), (*sound_data)->event, (*sound_data)->data, (*sound_data)->data_size, (*sound_data)->rate, (*sound_data)->utt_id);
557
558                 if (NULL != (*sound_data)->data) {
559                         free((*sound_data)->data);
560                         (*sound_data)->data = NULL;
561                 }
562
563                 free(*sound_data);
564                 *sound_data = NULL;
565         }
566
567         pthread_mutex_unlock(&g_sound_data_mutex);
568
569         return TTSD_ERROR_NONE;
570 }
571
572 int ttsd_data_clear_data(int uid)
573 {
574         int index = 0;
575
576         index = ttsd_data_is_client(uid);
577         if (index < 0) {
578                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
579                 return TTSD_ERROR_INVALID_PARAMETER;
580         }
581
582         int removed_last_uttid = -1;
583         speak_data_s* temp_speak = NULL;
584         sound_data_s* temp_sound = NULL;
585
586         /* free allocated data */
587         pthread_mutex_lock(&g_speak_data_mutex);
588         while(1) {
589                 if (0 != __get_speak_data(index, &temp_speak)) {
590                         break;
591                 }
592
593                 if (NULL != temp_speak) {
594                         SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)", 
595                                         temp_speak->utt_id, temp_speak->text, temp_speak->lang, temp_speak->vctype, temp_speak->speed);
596
597                         if (NULL != temp_speak->text) {
598                                 free(temp_speak->text);
599                                 temp_speak->text = NULL;
600                         }
601                         if (NULL != temp_speak->lang) {
602                                 free(temp_speak->lang);
603                                 temp_speak->lang = NULL;
604                         }
605                         removed_last_uttid = temp_speak->utt_id;
606
607                         free(temp_speak);
608                         temp_speak = NULL;
609                 }
610         }
611
612         if (-1 != removed_last_uttid) {
613                 g_app_list[index].utt_id_stopped = removed_last_uttid;
614         }
615
616         g_app_list[index].m_speak_data.clear();
617         pthread_mutex_unlock(&g_speak_data_mutex);
618
619         pthread_mutex_lock(&g_sound_data_mutex);
620         while(1) {
621                 if (0 != __get_sound_data(index, &temp_sound)) {
622                         break;
623                 }
624
625                 if (NULL != temp_sound) {
626                         SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] uid(%d), event(%d) data(%p) size(%d) rate(%d) utt(%d)", 
627                                 temp_sound, uid, temp_sound->event, temp_sound->data, temp_sound->data_size, temp_sound->rate, temp_sound->utt_id);
628
629                         if (NULL != temp_sound->data) {
630                                 free(temp_sound->data);
631                                 temp_sound->data = NULL;
632                         }
633
634                         free(temp_sound);
635                         temp_sound = NULL;
636                 }
637         }
638
639         g_app_list[index].m_wav_data.clear();
640         pthread_mutex_unlock(&g_sound_data_mutex);
641
642         return TTSD_ERROR_NONE;
643 }
644
645 int ttsd_data_get_client_state(int uid, app_tts_state_e* state)
646 {
647         int index = 0;
648
649         index = ttsd_data_is_client(uid);
650         if (index < 0)  {
651                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
652                 return TTSD_ERROR_INVALID_PARAMETER;
653         }
654
655         *state = g_app_list[index].state;
656
657         return TTSD_ERROR_NONE;
658 }
659
660 int ttsd_data_set_client_state(int uid, app_tts_state_e state)
661 {
662         int index = 0;
663
664         index = ttsd_data_is_client(uid);
665         if (index < 0)  {
666                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
667                 return TTSD_ERROR_INVALID_PARAMETER;
668         }
669
670         /* The client of playing state of all clients is only one. need to check state. */
671         if (APP_STATE_PLAYING == state) {
672                 int vsize = g_app_list.size();
673                 for (int i = 0; i < vsize; i++) {
674                         if(g_app_list[i].state == APP_STATE_PLAYING) {
675                                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] A playing client has already existed.");
676                                 return -1;
677                         }
678                 }
679         }
680
681         g_app_list[index].state = state;
682
683         return TTSD_ERROR_NONE;
684 }
685
686 int ttsd_data_get_current_playing()
687 {
688         int vsize = g_app_list.size();
689
690         for (int i = 0; i < vsize; i++) {
691                 if (APP_STATE_PLAYING == g_app_list[i].state) {
692                         SLOG(LOG_DEBUG, tts_tag(), "[DATA] uid(%d) is playing", g_app_list[i].uid);
693                         return g_app_list[i].uid;
694                 }
695         }
696
697         return -1;
698 }
699
700 int ttsd_data_foreach_clients(ttsd_data_get_client_cb callback, void* user_data)
701 {
702         if (NULL == callback) {
703                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] input data is NULL!!");
704                 return -1;
705         }
706
707 #ifdef DATA_DEBUG
708         __data_show_list();
709 #endif
710
711         /* Copy app info */
712         vector<app_data_s> temp_app_list;
713         int vsize = g_app_list.size();
714
715         int i = 0;
716         for (i = 0;i < vsize;i++) {
717                 app_data_s app;
718                 app.pid = g_app_list[i].pid;
719                 app.uid = g_app_list[i].uid;
720                 app.utt_id_stopped = 0;
721                 app.state = g_app_list[i].state;
722
723                 temp_app_list.insert(temp_app_list.end(), app);
724         }
725
726         for (i = 0;i < vsize;i++) {
727                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[%dth] pid(%d), uid(%d), state(%d)", i, temp_app_list[i].pid, temp_app_list[i].uid, temp_app_list[i].state);
728                 if (false == callback(temp_app_list[i].pid, temp_app_list[i].uid, temp_app_list[i].state, user_data)) {
729                         break;
730                 }
731         }
732
733         for (i = 0;i < vsize;i++) {
734                 temp_app_list.erase(temp_app_list.begin());
735         }
736
737         return 0;
738 }
739
740 bool ttsd_data_is_uttid_valid(int uid, int uttid)
741 {
742         int index = 0;
743
744         index = ttsd_data_is_client(uid);
745         if (index < 0)  {
746                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
747                 return false;
748         }
749
750         if (uttid < g_app_list[index].utt_id_stopped)
751                 return false;
752
753         return true;
754 }
755
756 int ttsd_data_is_current_playing()
757 {
758         int vsize = g_app_list.size();
759
760         for (int i = 0; i < vsize; i++) {
761                 if(g_app_list[i].state == APP_STATE_PLAYING) {
762                         return g_app_list[i].uid;
763                 }
764         }
765
766         return -1;
767 }
768
769 int ttsd_data_get_same_pid_client_count(int pid)
770 {
771         int vsize = g_app_list.size();
772         int number = 0;
773
774         for (int i = 0;i < vsize;i++) {
775                 if(g_app_list[i].pid == pid) {
776                         number++;
777                 }
778         }
779
780         return number;
781 }
782
783 int ttsd_data_save_error_log(int uid, FILE* fp)
784 {
785         int ret;
786         int pid;
787         /* pid */
788         pid = ttsd_data_get_pid(uid);
789         if (0 > pid) {
790                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get pid");
791         } else {
792                 fprintf(fp, "pid - %d", pid);
793         }
794         /* app state */
795         app_tts_state_e state;
796         ret = ttsd_data_get_client_state(uid, &state);
797         if (0 != ret) {
798                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get app state");
799         } else {
800                 fprintf(fp, "app state - %d", state);
801         }
802
803         int index = 0;
804         unsigned int i;
805
806         index = ttsd_data_is_client(uid);
807         if (0 > index) {
808                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid client");
809                 return -1;
810         }
811
812         /* get sound data */
813         fprintf(fp, "----- Sound list -----");
814
815         i = 0;
816         if (!g_app_list[index].m_wav_data.empty()) {
817                 std::list<sound_data_s*>::iterator iter;
818                 for (iter = g_app_list[index].m_wav_data.begin(); (NULL != *iter && iter != g_app_list[index].m_wav_data.end()); ++iter) {
819                         SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%d), uttid(%d), type(%d)",
820                                         i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
821                         i++;
822                 }
823         }
824
825         fprintf(fp, "----------------------");
826
827         /* get speck data */
828         fprintf(fp, "----- Text list -----");
829
830         i = 0;
831         if (!g_app_list[index].m_speak_data.empty()) {
832                 std::list<speak_data_s*>::iterator iter_speak;
833                 for (iter_speak = g_app_list[index].m_speak_data.begin(); (NULL != *iter_speak && iter_speak != g_app_list[index].m_speak_data.end()); ++iter_speak) {
834                         SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)",
835                                         i, *iter_speak, (*iter_speak)->lang, (*iter_speak)->vctype, (*iter_speak)->speed, (*iter_speak)->utt_id, (*iter_speak)->text);
836                         i++;
837                 }
838         }
839         fprintf(fp, "---------------------");
840
841         return 0;
842 }