Merge "Fix segmentation fault" 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 * 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(%ld), 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         if (index < 0)  {
432                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
433                 return TTSD_ERROR_INVALID_PARAMETER;
434         }
435
436         /* mutex is locked */
437         pthread_mutex_lock(&g_sound_data_mutex);
438
439         if (0 == g_app_list[index].m_wav_data.size()) {
440 #ifdef DATA_DEBUG
441                 SLOG(LOG_DEBUG, tts_tag(), "[DATA] There is no wav data");
442 #endif
443                 /* mutex is unlocked */
444                 pthread_mutex_unlock(&g_sound_data_mutex);
445                 return -1;
446         }
447
448         if (!g_app_list[index].m_wav_data.empty()) {
449                 std::list<sound_data_s*>::iterator iter = g_app_list[index].m_wav_data.begin();
450                 *data = *iter;
451                 g_app_list[index].m_wav_data.pop_front();
452         }
453
454 #ifdef DATA_DEBUG
455         __data_show_sound_list(index);
456 #endif
457
458         /* mutex is unlocked */
459         pthread_mutex_unlock(&g_sound_data_mutex);
460
461         return TTSD_ERROR_NONE;
462 }
463
464 int ttsd_data_get_sound_data_size(int uid)
465 {
466         int index = 0;
467         int data_size = 0;
468         index = ttsd_data_is_client(uid);
469
470         if (index < 0)  {
471                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
472                 return TTSD_ERROR_INVALID_PARAMETER;
473         }
474
475         /* mutex is locked */
476         pthread_mutex_lock(&g_sound_data_mutex);
477         data_size = g_app_list[index].m_wav_data.size();
478
479         /* mutex is unlocked */
480         pthread_mutex_unlock(&g_sound_data_mutex);
481
482         return data_size;
483 }
484
485 int ttsd_data_clear_data(int uid)
486 {
487         int index = 0;
488
489         index = ttsd_data_is_client(uid);
490         if (index < 0) {
491                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
492                 return TTSD_ERROR_INVALID_PARAMETER;
493         }
494
495         int removed_last_uttid = -1;
496         speak_data_s* temp_speak = NULL;
497         sound_data_s* temp_sound = NULL;
498
499         /* free allocated data */
500         while(1) {
501                 if (0 != ttsd_data_get_speak_data(uid, &temp_speak)) {
502                         break;
503                 }
504
505                 pthread_mutex_lock(&g_speak_data_mutex);
506                 if (NULL != temp_speak) {
507                         SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)", 
508                                         temp_speak->utt_id, temp_speak->text, temp_speak->lang, temp_speak->vctype, temp_speak->speed);
509
510                         if (NULL != temp_speak->text) {
511                                 free(temp_speak->text);
512                                 temp_speak->text = NULL;
513                         }
514                         if (NULL != temp_speak->lang) {
515                                 free(temp_speak->lang);
516                                 temp_speak->lang = NULL;
517                         }
518                         removed_last_uttid = temp_speak->utt_id;
519
520                         free(temp_speak);
521                         temp_speak = NULL;
522                 }
523                 pthread_mutex_unlock(&g_speak_data_mutex);
524         }
525
526         if (-1 != removed_last_uttid) {
527                 g_app_list[index].utt_id_stopped = removed_last_uttid;
528         }
529
530         pthread_mutex_lock(&g_speak_data_mutex);
531         g_app_list[index].m_speak_data.clear();
532         pthread_mutex_unlock(&g_speak_data_mutex);
533
534         while(1) {
535                 if (0 != ttsd_data_get_sound_data(uid, &temp_sound)) {
536                         break;
537                 }
538
539                 pthread_mutex_lock(&g_sound_data_mutex);
540                 if (NULL != temp_sound) {
541                         SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] uid(%d), event(%d) data(%p) size(%d) rate(%d) utt(%d)", 
542                                 temp_sound, uid, temp_sound->event, temp_sound->data, temp_sound->data_size, temp_sound->rate, temp_sound->utt_id);
543
544                         if (NULL != temp_sound->data) {
545                                 free(temp_sound->data);
546                                 temp_sound->data = NULL;
547                         }
548
549                         free(temp_sound);
550                         temp_sound = NULL;
551                 }
552                 pthread_mutex_unlock(&g_sound_data_mutex);
553         }
554
555         pthread_mutex_lock(&g_sound_data_mutex);
556         g_app_list[index].m_wav_data.clear();
557         pthread_mutex_unlock(&g_sound_data_mutex);
558
559         return TTSD_ERROR_NONE;
560 }
561
562 int ttsd_data_get_client_state(int uid, app_tts_state_e* state)
563 {
564         int index = 0;
565
566         index = ttsd_data_is_client(uid);
567         if (index < 0)  {
568                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
569                 return TTSD_ERROR_INVALID_PARAMETER;
570         }
571
572         *state = g_app_list[index].state;
573
574         return TTSD_ERROR_NONE;
575 }
576
577 int ttsd_data_set_client_state(int uid, app_tts_state_e state)
578 {
579         int index = 0;
580
581         index = ttsd_data_is_client(uid);
582         if (index < 0)  {
583                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
584                 return TTSD_ERROR_INVALID_PARAMETER;
585         }
586
587         /* The client of playing state of all clients is only one. need to check state. */
588         if (APP_STATE_PLAYING == state) {
589                 int vsize = g_app_list.size();
590                 for (int i = 0; i < vsize; i++) {
591                         if(g_app_list[i].state == APP_STATE_PLAYING) {
592                                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] A playing client has already existed.");
593                                 return -1;
594                         }
595                 }
596         }
597
598         g_app_list[index].state = state;
599
600         return TTSD_ERROR_NONE;
601 }
602
603 int ttsd_data_get_current_playing()
604 {
605         int vsize = g_app_list.size();
606
607         for (int i = 0; i < vsize; i++) {
608                 if (APP_STATE_PLAYING == g_app_list[i].state) {
609                         SLOG(LOG_DEBUG, tts_tag(), "[DATA] uid(%d) is playing", g_app_list[i].uid);
610                         return g_app_list[i].uid;
611                 }
612         }
613
614         return -1;
615 }
616
617 int ttsd_data_foreach_clients(ttsd_data_get_client_cb callback, void* user_data)
618 {
619         if (NULL == callback) {
620                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] input data is NULL!!");
621                 return -1;
622         }
623
624 #ifdef DATA_DEBUG
625         __data_show_list();
626 #endif
627
628         /* Copy app info */
629         vector<app_data_s> temp_app_list;
630         int vsize = g_app_list.size();
631
632         int i = 0;
633         for (i = 0;i < vsize;i++) {
634                 app_data_s app;
635                 app.pid = g_app_list[i].pid;
636                 app.uid = g_app_list[i].uid;
637                 app.utt_id_stopped = 0;
638                 app.state = g_app_list[i].state;
639
640                 temp_app_list.insert(temp_app_list.end(), app);
641         }
642
643         for (i = 0;i < vsize;i++) {
644                 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);
645                 if (false == callback(temp_app_list[i].pid, temp_app_list[i].uid, temp_app_list[i].state, user_data)) {
646                         break;
647                 }
648         }
649
650         for (i = 0;i < vsize;i++) {
651                 temp_app_list.erase(temp_app_list.begin());
652         }
653
654         return 0;
655 }
656
657 bool ttsd_data_is_uttid_valid(int uid, int uttid)
658 {
659         int index = 0;
660
661         index = ttsd_data_is_client(uid);
662         if (index < 0)  {
663                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
664                 return false;
665         }
666
667         if (uttid < g_app_list[index].utt_id_stopped)
668                 return false;
669
670         return true;
671 }
672
673 int ttsd_data_is_current_playing()
674 {
675         int vsize = g_app_list.size();
676
677         for (int i = 0; i < vsize; i++) {
678                 if(g_app_list[i].state == APP_STATE_PLAYING) {
679                         return g_app_list[i].uid;
680                 }
681         }
682
683         return -1;
684 }
685
686 int ttsd_data_get_same_pid_client_count(int pid)
687 {
688         int vsize = g_app_list.size();
689         int number = 0;
690
691         for (int i = 0;i < vsize;i++) {
692                 if(g_app_list[i].pid == pid) {
693                         number++;
694                 }
695         }
696
697         return number;
698 }
699
700 int ttsd_data_save_error_log(int uid, FILE* fp)
701 {
702         int ret;
703         int pid;
704         /* pid */
705         pid = ttsd_data_get_pid(uid);
706         if (0 > pid) {
707                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get pid");
708         } else {
709                 fprintf(fp, "pid - %d", pid);
710         }
711         /* app state */
712         app_tts_state_e state;
713         ret = ttsd_data_get_client_state(uid, &state);
714         if (0 != ret) {
715                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get app state");
716         } else {
717                 fprintf(fp, "app state - %d", state);
718         }
719
720         int index = 0;
721         unsigned int i;
722
723         index = ttsd_data_is_client(uid);
724         if (0 > index) {
725                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid client");
726                 return -1;
727         }
728
729         /* get sound data */
730         fprintf(fp, "----- Sound list -----");
731
732         i = 0;
733         if (!g_app_list[index].m_wav_data.empty()) {
734                 std::list<sound_data_s*>::iterator iter;
735                 for (iter = g_app_list[index].m_wav_data.begin(); (NULL != *iter && iter != g_app_list[index].m_wav_data.end()); ++iter) {
736                         SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%ld), uttid(%d), type(%d)",
737                                         i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
738                         i++;
739                 }
740         }
741
742         fprintf(fp, "----------------------");
743
744         /* get speck data */
745         fprintf(fp, "----- Text list -----");
746
747         i = 0;
748         if (!g_app_list[index].m_speak_data.empty()) {
749                 std::list<speak_data_s*>::iterator iter_speak;
750                 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) {
751                         SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)",
752                                         i, *iter_speak, (*iter_speak)->lang, (*iter_speak)->vctype, (*iter_speak)->speed, (*iter_speak)->utt_id, (*iter_speak)->text);
753                         i++;
754                 }
755         }
756         fprintf(fp, "---------------------");
757
758         return 0;
759 }