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