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