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