Add new flag variable for checking state
[platform/core/uifw/tts.git] / client / tts_client.c
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
15 #include "tts_client.h"
16
17 /* Constant value */
18 static const int MAX_HANDLE_NUM = 999;
19 static const int INVALID_HANDLE = -1;
20
21 /* allocated handle */
22 static unsigned int g_allocated_handle = 0;
23 /* client list */
24 static GList *g_client_list = NULL;
25
26 /* pthread mutex */
27 static pthread_mutex_t g_allocated_handle_mutex = PTHREAD_MUTEX_INITIALIZER;
28 static pthread_mutex_t g_client_list_mutex = PTHREAD_MUTEX_INITIALIZER;
29
30
31 static unsigned int __client_generate_uid(unsigned int pid)
32 {
33         pthread_mutex_lock(&g_allocated_handle_mutex);
34         g_allocated_handle++;
35
36         if (g_allocated_handle > MAX_HANDLE_NUM) {
37                 g_allocated_handle = 1;
38         }
39
40         /* generate uid, handle number should be smaller than 1000 */
41         unsigned int uid = pid * 1000u + g_allocated_handle;
42         pthread_mutex_unlock(&g_allocated_handle_mutex);
43
44         return uid;
45 }
46
47 static inline void __set_state_changed_cb(tts_client_s* client, tts_state_changed_cb callback, void* user_data)
48 {
49         client->state_changed_cb = callback;
50         client->state_changed_user_data = user_data;
51 }
52
53 static inline void __set_utterance_started_cb(tts_client_s* client, tts_utterance_started_cb callback, void* user_data)
54 {
55         client->utt_started_cb = callback;
56         client->utt_started_user_data = user_data;
57 }
58
59 static inline void __set_utterance_completed_cb(tts_client_s* client, tts_utterance_completed_cb callback, void* user_data)
60 {
61         client->utt_completed_cb = callback;
62         client->utt_completed_user_data = user_data;
63 }
64
65 static inline void __set_error_cb(tts_client_s* client, tts_error_cb callback, void* user_data)
66 {
67         client->error_cb = callback;
68         client->error_user_data = user_data;
69 }
70
71 static inline void __set_default_voice_changed_cb(tts_client_s* client, tts_default_voice_changed_cb callback, void* user_data)
72 {
73         client->default_voice_changed_cb = callback;
74         client->default_voice_changed_user_data = user_data;
75 }
76
77 static inline void __set_engine_changed_cb(tts_client_s* client, tts_engine_changed_cb callback, void* user_data)
78 {
79         client->engine_changed_cb = callback;
80         client->engine_changed_user_data = user_data;
81 }
82
83 static inline void __set_screen_reader_changed_cb(tts_client_s* client, tts_screen_reader_changed_cb callback, void* user_data)
84 {
85         client->screen_reader_changed_cb = callback;
86         client->screen_reader_changed_user_data = user_data;
87 }
88
89 static inline void __set_supported_voice_cb(tts_client_s* client, tts_supported_voice_cb callback, void* user_data)
90 {
91         client->supported_voice_cb = callback;
92         client->supported_voice_user_data = user_data;
93 }
94
95 int tts_client_new(tts_h* tts)
96 {
97         tts_client_s* client = (tts_client_s*)calloc(1, sizeof(tts_client_s));
98         if (NULL == client) {
99                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to allocate memory");
100                 return TTS_ERROR_OUT_OF_MEMORY;
101         }
102
103         tts_h temp = (tts_h)calloc(1, sizeof(struct tts_s));
104         if (NULL == temp) {
105                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to allocate memory");
106                 free(client);
107                 return TTS_ERROR_OUT_OF_MEMORY;
108         }
109
110         temp->handle = __client_generate_uid((unsigned int)getpid());
111
112         /* initialize client data */
113         client->tts = temp;
114         client->pid = getpid();
115         client->uid = temp->handle;
116
117         pthread_mutex_lock(&g_client_list_mutex);
118         g_client_list = g_list_append(g_client_list, client);
119         pthread_mutex_unlock(&g_client_list_mutex);
120
121         *tts = temp;
122
123         SLOG(LOG_ERROR, TAG_TTSC, "[Success] Create client object : uid(%u)", client->uid);
124
125         return TTS_ERROR_NONE;
126 }
127
128 int tts_client_destroy(tts_h tts)
129 {
130         if (tts == NULL) {
131                 SLOG(LOG_ERROR, TAG_TTSC, "Input parameter is NULL");
132                 return TTS_ERROR_INVALID_PARAMETER;
133         }
134
135         GList *iter = NULL;
136         tts_client_s *data = NULL;
137
138         pthread_mutex_lock(&g_client_list_mutex);
139         /* if list have item */
140         if (g_list_length(g_client_list) > 0) {
141                 /* Get a first item */
142                 iter = g_list_first(g_client_list);
143
144                 while (NULL != iter) {
145                         data = iter->data;
146                         if (tts->handle == data->tts->handle) {
147                                 tts->handle = TTS_INVALID_UID;
148                                 g_client_list = g_list_remove_link(g_client_list, iter);
149
150                                 while (0 != data->cb_ref_count) {
151                                         /* wait for release callback function */
152                                 }
153
154                                 unsigned int uid = data->uid;
155
156                                 free(data->err_msg);
157                                 free(data->credential);
158                                 free(data->text_repeat);
159                                 memset(data, 0, sizeof(tts_client_s));
160
161                                 free(data);
162                                 data = NULL;
163
164                                 free(tts);
165                                 tts = NULL;
166
167                                 g_list_free(iter);
168
169                                 pthread_mutex_unlock(&g_client_list_mutex);
170                                 SLOG(LOG_ERROR, TAG_TTSC, "Client destroy : uid(%u)", uid);
171                                 return TTS_ERROR_NONE;
172                         }
173
174                         /* Next item */
175                         iter = g_list_next(iter);
176                 }
177         }
178         pthread_mutex_unlock(&g_client_list_mutex);
179         SLOG(LOG_ERROR, TAG_TTSC, "Fail to destroy client : handle is not valid");
180
181         return TTS_ERROR_INVALID_PARAMETER;
182 }
183
184 tts_client_s* tts_client_get(tts_h tts)
185 {
186         if (tts == NULL) {
187                 SLOG(LOG_ERROR, TAG_TTSC, "Input parameter is NULL");
188                 return NULL;
189         }
190
191         GList *iter = NULL;
192         tts_client_s *data = NULL;
193
194         pthread_mutex_lock(&g_client_list_mutex);
195         if (g_list_length(g_client_list) > 0) {
196                 /* Get a first item */
197                 iter = g_list_first(g_client_list);
198
199                 while (NULL != iter) {
200                         data = iter->data;
201
202                         if (tts->handle == data->tts->handle) {
203                                 pthread_mutex_unlock(&g_client_list_mutex);
204                                 return data;
205                         }
206
207                         /* Next item */
208                         iter = g_list_next(iter);
209                 }
210         }
211
212         pthread_mutex_unlock(&g_client_list_mutex);
213         SLOG(LOG_ERROR, TAG_TTSC, "handle is not valid");
214
215         return NULL;
216 }
217
218 tts_client_s* tts_client_get_by_uid(unsigned int uid)
219 {
220         if (uid == TTS_INVALID_UID) {
221                 SLOG(LOG_ERROR, TAG_TTSC, "out of range : handle");
222                 return NULL;
223         }
224
225         GList *iter = NULL;
226         tts_client_s *data = NULL;
227
228         pthread_mutex_lock(&g_client_list_mutex);
229         if (g_list_length(g_client_list) > 0) {
230                 /* Get a first item */
231                 iter = g_list_first(g_client_list);
232
233                 while (NULL != iter) {
234                         data = iter->data;
235                         if (uid == data->uid) {
236                                 pthread_mutex_unlock(&g_client_list_mutex);
237                                 return data;
238                         }
239
240                         /* Next item */
241                         iter = g_list_next(iter);
242                 }
243         }
244
245         pthread_mutex_unlock(&g_client_list_mutex);
246         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] uid(%u) is not valid", uid);
247
248         return NULL;
249 }
250
251 bool tts_client_is_valid_uid(unsigned int uid)
252 {
253         if (NULL == tts_client_get_by_uid(uid)) {
254                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Uid is not valid");
255                 return false;
256         }
257
258         return true;
259 }
260
261 bool tts_client_is_valid_client(tts_client_s* client)
262 {
263         if (NULL == client) {
264                 SLOG(LOG_ERROR, TAG_TTSC, "[WARNING] Client is NULL");
265                 return false;
266         }
267
268         pthread_mutex_lock(&g_client_list_mutex);
269         if (g_list_length(g_client_list) > 0) {
270                 GList *iter = g_list_first(g_client_list);
271                 while (NULL != iter) {
272                         if (iter->data == client) {
273                                 pthread_mutex_unlock(&g_client_list_mutex);
274                                 return true;
275                         }
276
277                         iter = g_list_next(iter);
278                 }
279         }
280         pthread_mutex_unlock(&g_client_list_mutex);
281
282         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client(%p) is not valid", client);
283         return false;
284 }
285
286 tts_h tts_client_get_handle(tts_client_s* client)
287 {
288         if (false == tts_client_is_valid_client(client)) {
289                 return NULL;
290         }
291
292         return client->tts;
293 }
294
295 unsigned int tts_client_get_size()
296 {
297         pthread_mutex_lock(&g_client_list_mutex);
298         unsigned int size = g_list_length(g_client_list);
299         pthread_mutex_unlock(&g_client_list_mutex);
300
301         return size;
302 }
303
304 int tts_client_use_callback(tts_client_s* client)
305 {
306         client->cb_ref_count++;
307         return 0;
308 }
309
310 int tts_client_not_use_callback(tts_client_s* client)
311 {
312         client->cb_ref_count--;
313         return 0;
314 }
315
316 int tts_client_get_use_callback(tts_client_s* client)
317 {
318         return client->cb_ref_count;
319 }
320
321 GList* tts_client_get_client_list()
322 {
323         GList* copy_list = NULL;
324         pthread_mutex_lock(&g_client_list_mutex);
325         copy_list = g_list_copy(g_client_list);
326         pthread_mutex_unlock(&g_client_list_mutex);
327
328         return copy_list;
329 }
330
331 unsigned int tts_client_get_uid(tts_client_s* client)
332 {
333         if (NULL == client || false == tts_client_is_valid_client(client)) {
334                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client(%p) is not valid", client);
335                 return TTS_INVALID_UID;
336         }
337
338         return client->uid;
339 }
340
341 void tts_client_set_current_state(tts_client_s* client, tts_state_e state)
342 {
343         if (false == tts_client_is_valid_client(client)) {
344                 return;
345         }
346
347         client->before_state = client->current_state;
348         client->current_state = state;
349 }
350
351 tts_state_e tts_client_get_current_state(tts_client_s* client)
352 {
353         if (false == tts_client_is_valid_client(client)) {
354                 return TTS_STATE_INVALID;
355         }
356
357         return client->current_state;
358 }
359
360 void tts_client_set_start_listening(unsigned int uid, bool is_listening_started)
361 {
362         tts_client_s* client = tts_client_get_by_uid(uid);
363         if (NULL == client) {
364                 return;
365         }
366
367         client->start_listening = is_listening_started;
368 }
369
370 bool tts_client_is_listening_started(unsigned int uid)
371 {
372         tts_client_s* client = tts_client_get_by_uid(uid);
373         if (NULL == client) {
374                 return false;
375         }
376
377         return client->start_listening;
378 }
379
380 void tts_client_set_reprepared(tts_client_s* client, bool is_reprepared)
381 {
382         if (false == tts_client_is_valid_client(client)) {
383                 return;
384         }
385
386         client->reprepared = is_reprepared;
387 }
388
389 bool tts_client_is_reprepared(tts_client_s* client)
390 {
391         if (false == tts_client_is_valid_client(client)) {
392                 return INVALID_HANDLE;
393         }
394
395         return client->reprepared;
396 }
397
398 void tts_client_set_mode(tts_client_s* client, tts_mode_e mode)
399 {
400         if (false == tts_client_is_valid_client(client)) {
401                 return;
402         }
403
404         client->mode = mode;
405 }
406
407 tts_mode_e tts_client_get_mode(tts_client_s* client)
408 {
409         if (false == tts_client_is_valid_client(client)) {
410                 return INVALID_HANDLE;
411         }
412
413         return client->mode;
414 }
415
416 void tts_client_set_repeat_text(tts_client_s* client, const char* text)
417 {
418         if (NULL == client || false == tts_client_is_valid_client(client)) {
419                 return;
420         }
421
422         if (NULL != client->text_repeat) {
423                 free(client->text_repeat);
424         }
425
426         if (NULL != text) {
427                 client->text_repeat = strdup(text);
428         } else {
429                 client->text_repeat = NULL;
430         }
431 }
432
433 const char* tts_client_get_repeat_text(tts_client_s* client)
434 {
435         if (NULL == client || false == tts_client_is_valid_client(client)) {
436                 return NULL;
437         }
438
439         return client->text_repeat;
440 }
441
442 int tts_client_new_utterance_id(tts_client_s* client)
443 {
444         if (NULL == client || false == tts_client_is_valid_client(client)) {
445                 return INVALID_HANDLE;
446         }
447
448         client->current_utt_id++;
449         if (client->current_utt_id == 10000) {
450                 client->current_utt_id = 1;
451         }
452
453         return client->current_utt_id;
454 }
455
456 void tts_client_set_error_message(tts_client_s* client, const char* error_message)
457 {
458         if (false == tts_client_is_valid_client(client)) {
459                 return;
460         }
461
462         if (NULL != client->err_msg) {
463                 free(client->err_msg);
464                 client->err_msg = NULL;
465         }
466
467         if (NULL != error_message) {
468                 client->err_msg = strdup(error_message);
469         }
470 }
471
472 const char* tts_client_get_error_message(tts_client_s* client)
473 {
474         if (false == tts_client_is_valid_client(client)) {
475                 return NULL;
476         }
477
478         return client->err_msg;
479 }
480
481 void tts_client_set_credential_key(tts_client_s* client, const char* credential_key)
482 {
483         if (false == tts_client_is_valid_client(client)) {
484                 return;
485         }
486
487         free(client->credential);
488         client->credential = NULL;
489
490         if (NULL != credential_key) {
491                 client->credential = strdup(credential_key);
492         }
493 }
494
495 const char* tts_client_get_credential_key(tts_client_s* client)
496 {
497         if (false == tts_client_is_valid_client(client)) {
498                 return NULL;
499         }
500
501         return client->credential;
502 }
503
504 void tts_client_set_state_changed_cb(tts_client_s* client, tts_state_changed_cb callback, void* user_data)
505 {
506         if (false == tts_client_is_valid_client(client)) {
507                 return;
508         }
509
510         if (NULL == callback) {
511                 if (NULL != client->notify_state_timer) {
512                         ecore_timer_del(client->notify_state_timer);
513                         client->notify_state_timer = NULL;
514                 }
515         }
516         __set_state_changed_cb(client, callback, user_data);
517 }
518
519 void tts_client_set_utterance_started_cb(tts_client_s* client, tts_utterance_started_cb callback, void* user_data)
520 {
521         if (false == tts_client_is_valid_client(client)) {
522                 return;
523         }
524         __set_utterance_started_cb(client, callback, user_data);
525 }
526
527 void tts_client_set_utterance_completed_cb(tts_client_s* client, tts_utterance_completed_cb callback, void* user_data)
528 {
529         if (false == tts_client_is_valid_client(client)) {
530                 return;
531         }
532         __set_utterance_completed_cb(client, callback, user_data);
533 }
534
535 void tts_client_set_error_cb(tts_client_s* client, tts_error_cb callback, void* user_data)
536 {
537         if (false == tts_client_is_valid_client(client)) {
538                 return;
539         }
540
541         if (NULL == callback) {
542                 if (NULL != client->notify_error_timer) {
543                         ecore_timer_del(client->notify_error_timer);
544                         client->notify_error_timer = NULL;
545                 }
546         }
547         __set_error_cb(client, callback, user_data);
548 }
549
550 void tts_client_set_default_voice_changed_cb(tts_client_s* client, tts_default_voice_changed_cb callback, void* user_data)
551 {
552         if (false == tts_client_is_valid_client(client)) {
553                 return;
554         }
555         __set_default_voice_changed_cb(client, callback, user_data);
556 }
557
558 void tts_client_set_engine_changed_cb(tts_client_s* client, tts_engine_changed_cb callback, void* user_data)
559 {
560         if (false == tts_client_is_valid_client(client)) {
561                 return;
562         }
563         __set_engine_changed_cb(client, callback, user_data);
564 }
565
566 void tts_client_set_screen_reader_changed_cb(tts_client_s* client, tts_screen_reader_changed_cb callback, void* user_data)
567 {
568         if (false == tts_client_is_valid_client(client)) {
569                 return;
570         }
571         __set_screen_reader_changed_cb(client, callback, user_data);
572 }
573
574 void tts_client_set_supported_voice_cb(tts_client_s* client, tts_supported_voice_cb callback, void* user_data)
575 {
576         if (false == tts_client_is_valid_client(client)) {
577                 return;
578         }
579         __set_supported_voice_cb(client, callback, user_data);
580 }
581
582 tts_state_changed_cb tts_client_get_state_changed_cb(tts_client_s* client)
583 {
584         if (false == tts_client_is_valid_client(client)) {
585                 return NULL;
586         }
587         return client->state_changed_cb;
588 }
589
590 void* tts_client_get_state_changed_user_data(tts_client_s* client)
591 {
592         if (false == tts_client_is_valid_client(client)) {
593                 return NULL;
594         }
595         return client->state_changed_user_data;
596 }
597
598 tts_utterance_started_cb tts_client_get_utterance_started_cb(tts_client_s* client)
599 {
600         if (false == tts_client_is_valid_client(client)) {
601                 return NULL;
602         }
603         return client->utt_started_cb;
604 }
605
606 void* tts_client_get_utterance_started_user_data(tts_client_s* client)
607 {
608         if (false == tts_client_is_valid_client(client)) {
609                 return NULL;
610         }
611         return client->utt_started_user_data;
612 }
613
614 tts_utterance_completed_cb tts_client_get_utterance_completed_cb(tts_client_s* client)
615 {
616         if (false == tts_client_is_valid_client(client)) {
617                 return NULL;
618         }
619         return client->utt_completed_cb;
620 }
621
622 void* tts_client_get_utterance_completed_user_data(tts_client_s* client)
623 {
624         if (false == tts_client_is_valid_client(client)) {
625                 return NULL;
626         }
627         return client->utt_completed_user_data;
628 }
629
630 tts_error_cb tts_client_get_error_cb(tts_client_s* client)
631 {
632         if (false == tts_client_is_valid_client(client)) {
633                 return NULL;
634         }
635         return client->error_cb;
636 }
637
638 void* tts_client_get_error_user_data(tts_client_s* client)
639 {
640         if (false == tts_client_is_valid_client(client)) {
641                 return NULL;
642         }
643         return client->error_user_data;
644 }
645
646 //LCOV_EXCL_START
647 tts_default_voice_changed_cb tts_client_get_default_voice_changed_cb(tts_client_s* client)
648 {
649         if (false == tts_client_is_valid_client(client)) {
650                 return NULL;
651         }
652         return client->default_voice_changed_cb;
653 }
654
655 void* tts_client_get_default_voice_changed_user_data(tts_client_s* client)
656 {
657         if (false == tts_client_is_valid_client(client)) {
658                 return NULL;
659         }
660         return client->default_voice_changed_user_data;
661 }
662
663 tts_engine_changed_cb tts_client_get_engine_changed_cb(tts_client_s* client)
664 {
665         if (false == tts_client_is_valid_client(client)) {
666                 return NULL;
667         }
668         return client->engine_changed_cb;
669 }
670
671 void* tts_client_get_engine_changed_user_data(tts_client_s* client)
672 {
673         if (false == tts_client_is_valid_client(client)) {
674                 return NULL;
675         }
676         return client->engine_changed_user_data;
677 }
678 //LCOV_EXCL_STOP
679
680 tts_screen_reader_changed_cb tts_client_get_screen_reader_changed_cb(tts_client_s* client)
681 {
682         if (false == tts_client_is_valid_client(client)) {
683                 return NULL;
684         }
685         return client->screen_reader_changed_cb;
686 }
687
688 void* tts_client_get_screen_reader_changed_user_data(tts_client_s* client)
689 {
690         if (false == tts_client_is_valid_client(client)) {
691                 return NULL;
692         }
693         return client->screen_reader_changed_user_data;
694 }
695
696 tts_supported_voice_cb tts_client_get_supported_voice_cb(tts_client_s* client)
697 {
698         if (false == tts_client_is_valid_client(client)) {
699                 return NULL;
700         }
701         return client->supported_voice_cb;
702 }
703
704 void* tts_client_get_supported_voice_user_data(tts_client_s* client)
705 {
706         if (false == tts_client_is_valid_client(client)) {
707                 return NULL;
708         }
709         return client->supported_voice_user_data;
710 }
711
712 void tts_client_unset_all_cb(tts_client_s* client)
713 {
714         if (false == tts_client_is_valid_client(client)) {
715                 return;
716         }
717
718         if (NULL != client->notify_state_timer) {
719                 ecore_timer_del(client->notify_state_timer);
720                 client->notify_state_timer = NULL;
721         }
722
723         if (NULL != client->notify_error_timer) {
724                 ecore_timer_del(client->notify_error_timer);
725                 client->notify_error_timer = NULL;
726         }
727
728         __set_state_changed_cb(client, NULL, NULL);
729         __set_utterance_started_cb(client, NULL, NULL);
730         __set_utterance_completed_cb(client, NULL, NULL);
731         __set_error_cb(client, NULL, NULL);
732         __set_default_voice_changed_cb(client, NULL, NULL);
733         __set_engine_changed_cb(client, NULL, NULL);
734         __set_supported_voice_cb(client, NULL, NULL);
735 }