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