Fix memory leak
[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(int uid, sound_data_s** sound_data)
551 {
552         pthread_mutex_lock(&g_sound_data_mutex);
553
554         int index = 0;
555         index = ttsd_data_is_client(uid);
556         if (index >= 0) {
557                 if (NULL != *sound_data) {
558                         SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] event(%d) data(%p) size(%d) rate(%d) utt(%d)", 
559                                         (*sound_data), (*sound_data)->event, (*sound_data)->data, (*sound_data)->data_size, (*sound_data)->rate, (*sound_data)->utt_id);
560
561                         if (NULL != (*sound_data)->data) {
562                                 free((*sound_data)->data);
563                                 (*sound_data)->data = NULL;
564                         }
565
566                         free(*sound_data);
567                         *sound_data = NULL;
568                 }
569         }
570         pthread_mutex_unlock(&g_sound_data_mutex);
571
572         return TTSD_ERROR_NONE;
573 }
574
575 int ttsd_data_clear_data(int uid)
576 {
577         int index = 0;
578
579         index = ttsd_data_is_client(uid);
580         if (index < 0) {
581                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
582                 return TTSD_ERROR_INVALID_PARAMETER;
583         }
584
585         int removed_last_uttid = -1;
586         speak_data_s* temp_speak = NULL;
587         sound_data_s* temp_sound = NULL;
588
589         /* free allocated data */
590         pthread_mutex_lock(&g_speak_data_mutex);
591         while(1) {
592                 if (0 != __get_speak_data(index, &temp_speak)) {
593                         break;
594                 }
595
596                 if (NULL != temp_speak) {
597                         SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)", 
598                                         temp_speak->utt_id, temp_speak->text, temp_speak->lang, temp_speak->vctype, temp_speak->speed);
599
600                         if (NULL != temp_speak->text) {
601                                 free(temp_speak->text);
602                                 temp_speak->text = NULL;
603                         }
604                         if (NULL != temp_speak->lang) {
605                                 free(temp_speak->lang);
606                                 temp_speak->lang = NULL;
607                         }
608                         removed_last_uttid = temp_speak->utt_id;
609
610                         free(temp_speak);
611                         temp_speak = NULL;
612                 }
613         }
614
615         if (-1 != removed_last_uttid) {
616                 g_app_list[index].utt_id_stopped = removed_last_uttid;
617         }
618
619         g_app_list[index].m_speak_data.clear();
620         pthread_mutex_unlock(&g_speak_data_mutex);
621
622         pthread_mutex_lock(&g_sound_data_mutex);
623         while(1) {
624                 if (0 != __get_sound_data(index, &temp_sound)) {
625                         break;
626                 }
627
628                 if (NULL != temp_sound) {
629                         SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] uid(%d), event(%d) data(%p) size(%d) rate(%d) utt(%d)", 
630                                 temp_sound, uid, temp_sound->event, temp_sound->data, temp_sound->data_size, temp_sound->rate, temp_sound->utt_id);
631
632                         if (NULL != temp_sound->data) {
633                                 free(temp_sound->data);
634                                 temp_sound->data = NULL;
635                         }
636
637                         free(temp_sound);
638                         temp_sound = NULL;
639                 }
640         }
641
642         g_app_list[index].m_wav_data.clear();
643         pthread_mutex_unlock(&g_sound_data_mutex);
644
645         return TTSD_ERROR_NONE;
646 }
647
648 int ttsd_data_get_client_state(int uid, app_tts_state_e* state)
649 {
650         int index = 0;
651
652         index = ttsd_data_is_client(uid);
653         if (index < 0)  {
654                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
655                 return TTSD_ERROR_INVALID_PARAMETER;
656         }
657
658         *state = g_app_list[index].state;
659
660         return TTSD_ERROR_NONE;
661 }
662
663 int ttsd_data_set_client_state(int uid, app_tts_state_e state)
664 {
665         int index = 0;
666
667         index = ttsd_data_is_client(uid);
668         if (index < 0)  {
669                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
670                 return TTSD_ERROR_INVALID_PARAMETER;
671         }
672
673         /* The client of playing state of all clients is only one. need to check state. */
674         if (APP_STATE_PLAYING == state) {
675                 int vsize = g_app_list.size();
676                 for (int i = 0; i < vsize; i++) {
677                         if(g_app_list[i].state == APP_STATE_PLAYING) {
678                                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] A playing client has already existed.");
679                                 return -1;
680                         }
681                 }
682         }
683
684         g_app_list[index].state = state;
685
686         return TTSD_ERROR_NONE;
687 }
688
689 int ttsd_data_get_current_playing()
690 {
691         int vsize = g_app_list.size();
692
693         for (int i = 0; i < vsize; i++) {
694                 if (APP_STATE_PLAYING == g_app_list[i].state) {
695                         SLOG(LOG_DEBUG, tts_tag(), "[DATA] uid(%d) is playing", g_app_list[i].uid);
696                         return g_app_list[i].uid;
697                 }
698         }
699
700         return -1;
701 }
702
703 int ttsd_data_foreach_clients(ttsd_data_get_client_cb callback, void* user_data)
704 {
705         if (NULL == callback) {
706                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] input data is NULL!!");
707                 return -1;
708         }
709
710 #ifdef DATA_DEBUG
711         __data_show_list();
712 #endif
713
714         /* Copy app info */
715         vector<app_data_s> temp_app_list;
716         int vsize = g_app_list.size();
717
718         int i = 0;
719         for (i = 0;i < vsize;i++) {
720                 app_data_s app;
721                 app.pid = g_app_list[i].pid;
722                 app.uid = g_app_list[i].uid;
723                 app.utt_id_stopped = 0;
724                 app.state = g_app_list[i].state;
725
726                 temp_app_list.insert(temp_app_list.end(), app);
727         }
728
729         for (i = 0;i < vsize;i++) {
730                 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);
731                 if (false == callback(temp_app_list[i].pid, temp_app_list[i].uid, temp_app_list[i].state, user_data)) {
732                         break;
733                 }
734         }
735
736         for (i = 0;i < vsize;i++) {
737                 temp_app_list.erase(temp_app_list.begin());
738         }
739
740         return 0;
741 }
742
743 bool ttsd_data_is_uttid_valid(int uid, int uttid)
744 {
745         int index = 0;
746
747         index = ttsd_data_is_client(uid);
748         if (index < 0)  {
749                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
750                 return false;
751         }
752
753         if (uttid < g_app_list[index].utt_id_stopped)
754                 return false;
755
756         return true;
757 }
758
759 int ttsd_data_is_current_playing()
760 {
761         int vsize = g_app_list.size();
762
763         for (int i = 0; i < vsize; i++) {
764                 if(g_app_list[i].state == APP_STATE_PLAYING) {
765                         return g_app_list[i].uid;
766                 }
767         }
768
769         return -1;
770 }
771
772 int ttsd_data_get_same_pid_client_count(int pid)
773 {
774         int vsize = g_app_list.size();
775         int number = 0;
776
777         for (int i = 0;i < vsize;i++) {
778                 if(g_app_list[i].pid == pid) {
779                         number++;
780                 }
781         }
782
783         return number;
784 }
785
786 int ttsd_data_save_error_log(int uid, FILE* fp)
787 {
788         int ret;
789         int pid;
790         /* pid */
791         pid = ttsd_data_get_pid(uid);
792         if (0 > pid) {
793                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get pid");
794         } else {
795                 fprintf(fp, "pid - %d", pid);
796         }
797         /* app state */
798         app_tts_state_e state;
799         ret = ttsd_data_get_client_state(uid, &state);
800         if (0 != ret) {
801                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get app state");
802         } else {
803                 fprintf(fp, "app state - %d", state);
804         }
805
806         int index = 0;
807         unsigned int i;
808
809         index = ttsd_data_is_client(uid);
810         if (0 > index) {
811                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid client");
812                 return -1;
813         }
814
815         /* get sound data */
816         fprintf(fp, "----- Sound list -----");
817
818         i = 0;
819         if (!g_app_list[index].m_wav_data.empty()) {
820                 std::list<sound_data_s*>::iterator iter;
821                 for (iter = g_app_list[index].m_wav_data.begin(); (NULL != *iter && iter != g_app_list[index].m_wav_data.end()); ++iter) {
822                         SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%d), uttid(%d), type(%d)",
823                                         i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
824                         i++;
825                 }
826         }
827
828         fprintf(fp, "----------------------");
829
830         /* get speck data */
831         fprintf(fp, "----- Text list -----");
832
833         i = 0;
834         if (!g_app_list[index].m_speak_data.empty()) {
835                 std::list<speak_data_s*>::iterator iter_speak;
836                 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) {
837                         SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)",
838                                         i, *iter_speak, (*iter_speak)->lang, (*iter_speak)->vctype, (*iter_speak)->speed, (*iter_speak)->utt_id, (*iter_speak)->text);
839                         i++;
840                 }
841         }
842         fprintf(fp, "---------------------");
843
844         return 0;
845 }