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