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