[ACR-1297] Add VCE APIs for supporting tts feedback
[platform/core/uifw/voice-control.git] / client / vc_client.c
1 /*
2 * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18 #include "vc_client.h"
19
20 typedef struct {
21         /* base info */
22         vc_h    vc;
23         int     pid;
24         int     uid;            /*<< unique id = pid + handle */
25         int     xid;            /*<< main X window id */
26
27         vc_result_cb                    result_cb;
28         void*                           result_user_data;
29         vc_error_cb                     error_cb;
30         void*                           error_user_data;
31         vc_service_state_changed_cb     service_state_changed_cb;
32         void*                           service_state_changed_user_data;
33         vc_state_changed_cb             state_changed_cb;
34         void*                           state_changed_user_data;
35         vc_current_language_changed_cb  current_lang_changed_cb;
36         void*                           current_lang_changed_user_data;
37
38         /* tts feedback */
39         vc_tts_streaming_cb tts_streaming_cb;
40         void*                           tts_streaming_user_data;
41         vc_tts_utterance_status_cb      tts_utterance_status_cb;
42         void*                                           tts_utterance_status_user_data;
43
44 #if 0
45         /* exclusive option */
46         bool                    exclusive_cmd;
47 #endif
48
49         /* service state */
50         vc_service_state_e      service_state;
51
52         /* state */
53         vc_state_e      before_state;
54         vc_state_e      current_state;
55
56         /* mutex */
57         int     cb_ref_count;
58
59         /* error data */
60         int     reason;
61
62         /* Authority */
63         vc_auth_state_e         auth_before_state;
64         vc_auth_state_e         auth_current_state;
65         vc_auth_state_changed_cb        auth_state_changed_cb;
66         void*                           auth_state_changed_user_data;
67
68         int     mgr_pid;
69
70         /* is foreground */
71         bool    is_foreground;
72
73         /* Invocation name */
74         char*   invocation_name;
75 } vc_client_s;
76
77 /* client list */
78 static GSList *g_client_list = NULL;
79
80
81 static vc_client_s* __client_get(vc_h vc)
82 {
83         if (vc == NULL) {
84                 return NULL;
85         }
86
87         vc_client_s *data = NULL;
88
89         int count = g_slist_length(g_client_list);
90         int i;
91
92         for (i = 0; i < count; i++) {
93                 data = g_slist_nth_data(g_client_list, i);
94
95                 if (NULL != data) {
96                         if (vc->handle == data->vc->handle) {
97                                 return data;
98                         }
99                 }
100         }
101
102         SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] Fail to get client by vc"); //LCOV_EXCL_LINE
103
104         return NULL;
105 }
106
107 int vc_client_create(vc_h* vc)
108 {
109         vc_client_s *client = NULL;
110
111         client = (vc_client_s*)calloc(1, sizeof(vc_client_s));
112         if (NULL == client) {
113                 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to allocate memory"); //LCOV_EXCL_LINE
114                 return VC_ERROR_OUT_OF_MEMORY;
115         }
116
117         vc_h temp = (vc_h)calloc(1, sizeof(struct vc_s));
118         if (NULL == temp) {
119                 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to allocate memory"); //LCOV_EXCL_LINE
120                 free(client);
121                 return VC_ERROR_OUT_OF_MEMORY;
122         }
123
124         temp->handle = getpid();
125
126         /* initialize client data */
127         client->vc = temp;
128         client->pid = getpid();
129         client->uid = temp->handle;
130         client->xid = -1;
131
132         client->result_cb = NULL;
133         client->result_user_data = NULL;
134         client->service_state_changed_cb = NULL;
135         client->service_state_changed_user_data = NULL;
136         client->state_changed_cb = NULL;
137         client->state_changed_user_data = NULL;
138         client->current_lang_changed_cb = NULL;
139         client->current_lang_changed_user_data = NULL;
140         client->error_cb = NULL;
141         client->error_user_data = NULL;
142         client->tts_streaming_cb = NULL;
143         client->tts_streaming_user_data = NULL;
144         client->tts_utterance_status_cb = NULL;
145         client->tts_utterance_status_user_data = NULL;
146
147 #if 0
148         client->exclusive_cmd = false;
149 #endif
150
151         client->service_state = VC_RUNTIME_INFO_NO_FOREGROUND;
152
153         client->before_state = VC_STATE_INITIALIZED;
154         client->current_state = VC_STATE_INITIALIZED;
155
156         client->cb_ref_count = 0;
157
158         /* Authority */
159         client->auth_before_state = VC_AUTH_STATE_NONE;
160         client->auth_current_state = VC_AUTH_STATE_NONE;
161         client->auth_state_changed_cb = NULL;
162         client->auth_state_changed_user_data = NULL;
163
164         client->is_foreground = false;
165         client->invocation_name = NULL;
166
167         g_client_list = g_slist_append(g_client_list, client);
168
169         *vc = temp;
170
171         return 0;
172 }
173
174 int vc_client_destroy(vc_h vc)
175 {
176         if (vc == NULL) {
177                 SLOG(LOG_ERROR, TAG_VCC, "Input parameter is NULL"); //LCOV_EXCL_LINE
178                 return 0;
179         }
180
181         vc_client_s *data = NULL;
182
183         int count = g_slist_length(g_client_list);
184         int i;
185
186         for (i = 0; i < count; i++) {
187                 data = g_slist_nth_data(g_client_list, i);
188
189                 if (NULL != data) {
190                         if (vc->handle == data->vc->handle) {
191                                 g_client_list =  g_slist_remove(g_client_list, data);
192
193                                 while (0 != data->cb_ref_count) {
194                                         /* wait for release callback function */
195                                 }
196                                 if (NULL != data->invocation_name) {
197                                         free(data->invocation_name);
198                                         data->invocation_name = NULL;
199                                 }
200                                 free(data);
201                                 free(vc);
202                                 data = NULL;
203                                 vc = NULL;
204                                 return 0;
205                         }
206                 }
207         }
208
209         SLOG(LOG_ERROR, TAG_VCC, "[ERROR] client Not found");
210
211         return -1;
212 }
213
214 bool vc_client_is_valid(vc_h vc)
215 {
216         vc_client_s* client = __client_get(vc);
217
218         /* check handle */
219         if (NULL == client) {
220                 SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] vc is not valid");
221                 return false;
222         }
223
224         return true;
225 }
226
227 bool vc_client_is_valid_by_uid(int uid)
228 {
229         vc_client_s *data = NULL;
230
231         int count = g_slist_length(g_client_list);
232         int i;
233
234         for (i = 0; i < count; i++) {
235                 data = g_slist_nth_data(g_client_list, i);
236
237                 if (NULL != data) {
238                         if (uid == data->vc->handle)
239                                 return true;
240                 }
241         }
242
243         SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] Fail to get client by vc");
244
245         return false;
246 }
247
248 //LCOV_EXCL_START
249 int vc_client_get_handle(int uid, vc_h* vc)
250 {
251         vc_client_s *data = NULL;
252
253         int count = g_slist_length(g_client_list);
254         int i;
255
256         for (i = 0; i < count; i++) {
257                 data = g_slist_nth_data(g_client_list, i);
258
259                 if (NULL != data) {
260                         if (uid == data->vc->handle) {
261                                 *vc = data->vc;
262                                 return 0;
263                         }
264                 }
265         }
266
267         return -1;
268 }
269 //LCOV_EXCL_STOP
270
271 /* set/get callback function */
272 int vc_client_set_result_cb(vc_h vc, vc_result_cb callback, void* user_data)
273 {
274         vc_client_s* client = __client_get(vc);
275
276         /* check handle */
277         if (NULL == client)
278                 return VC_ERROR_INVALID_PARAMETER;
279
280         client->result_cb = callback;
281         client->result_user_data = user_data;
282
283         return 0;
284 }
285
286 //LCOV_EXCL_START
287 int vc_client_get_result_cb(vc_h vc, vc_result_cb* callback, void** user_data)
288 {
289         vc_client_s* client = __client_get(vc);
290
291         /* check handle */
292         if (NULL == client)
293                 return VC_ERROR_INVALID_PARAMETER;
294
295         *callback = client->result_cb;
296         *user_data = client->result_user_data;
297
298         return 0;
299 }
300 //LCOV_EXCL_STOP
301
302 int vc_client_set_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb callback, void* user_data)
303 {
304         vc_client_s* client = __client_get(vc);
305
306         /* check handle */
307         if (NULL == client)
308                 return VC_ERROR_INVALID_PARAMETER;
309
310         client->service_state_changed_cb = callback;
311         client->service_state_changed_user_data = user_data;
312
313         return 0;
314 }
315
316 //LCOV_EXCL_START
317 int vc_client_get_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb* callback, void** user_data)
318 {
319         vc_client_s* client = __client_get(vc);
320
321         /* check handle */
322         if (NULL == client)
323                 return VC_ERROR_INVALID_PARAMETER;
324
325         *callback = client->service_state_changed_cb;
326         *user_data = client->service_state_changed_user_data;
327
328         return 0;
329 }
330 //LCOV_EXCL_STOP
331
332 int vc_client_set_state_changed_cb(vc_h vc, vc_state_changed_cb callback, void* user_data)
333 {
334         vc_client_s* client = __client_get(vc);
335
336         /* check handle */
337         if (NULL == client)
338                 return VC_ERROR_INVALID_PARAMETER;
339
340         client->state_changed_cb = callback;
341         client->state_changed_user_data = user_data;
342
343         return 0;
344 }
345
346 //LCOV_EXCL_START
347 int vc_client_get_state_changed_cb(vc_h vc, vc_state_changed_cb* callback, void** user_data)
348 {
349         vc_client_s* client = __client_get(vc);
350
351         /* check handle */
352         if (NULL == client)
353                 return VC_ERROR_INVALID_PARAMETER;
354
355         *callback = client->state_changed_cb;
356         *user_data = client->state_changed_user_data;
357
358         return 0;
359 }
360 //LCOV_EXCL_STOP
361
362 int vc_client_set_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb callback, void* user_data)
363 {
364         vc_client_s* client = __client_get(vc);
365
366         /* check handle */
367         if (NULL == client)
368                 return VC_ERROR_INVALID_PARAMETER;
369
370         client->current_lang_changed_cb = callback;
371         client->current_lang_changed_user_data = user_data;
372
373         return 0;
374 }
375
376 //LCOV_EXCL_START
377 int vc_client_get_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb* callback, void** user_data)
378 {
379         vc_client_s* client = __client_get(vc);
380
381         /* check handle */
382         if (NULL == client)
383                 return VC_ERROR_INVALID_PARAMETER;
384
385         *callback = client->current_lang_changed_cb;
386         *user_data = client->current_lang_changed_user_data;
387
388         return 0;
389 }
390 //LCOV_EXCL_STOP
391
392 int vc_client_set_error_cb(vc_h vc, vc_error_cb callback, void* user_data)
393 {
394         vc_client_s* client = __client_get(vc);
395
396         /* check handle */
397         if (NULL == client)
398                 return VC_ERROR_INVALID_PARAMETER;
399
400         client->error_cb = callback;
401         client->error_user_data = user_data;
402
403         return 0;
404 }
405
406 //LCOV_EXCL_START
407 int vc_client_get_error_cb(vc_h vc, vc_error_cb* callback, void** user_data)
408 {
409         vc_client_s* client = __client_get(vc);
410
411         /* check handle */
412         if (NULL == client)
413                 return VC_ERROR_INVALID_PARAMETER;
414
415         *callback = client->error_cb;
416         *user_data = client->error_user_data;
417
418         return 0;
419 }
420 //LCOV_EXCL_STOP
421
422 /* set/get option */
423 int vc_client_set_service_state(vc_h vc, vc_service_state_e state)
424 {
425         vc_client_s* client = __client_get(vc);
426
427         /* check handle */
428         if (NULL == client)
429                 return VC_ERROR_INVALID_PARAMETER;
430
431         client->service_state = state;
432
433         return 0;
434 }
435
436 int vc_client_get_service_state(vc_h vc, vc_service_state_e* state)
437 {
438         vc_client_s* client = __client_get(vc);
439
440         /* check handle */
441         if (NULL == client)
442                 return VC_ERROR_INVALID_PARAMETER;
443
444         *state = client->service_state;
445
446         return 0;
447 }
448
449 int vc_client_set_client_state(vc_h vc, vc_state_e state)
450 {
451         vc_client_s* client = __client_get(vc);
452
453         /* check handle */
454         if (NULL == client)
455                 return VC_ERROR_INVALID_PARAMETER;
456
457         client->before_state = client->current_state;
458         client->current_state = state;
459
460         return 0;
461 }
462
463 int vc_client_get_client_state(vc_h vc, vc_state_e* state)
464 {
465         vc_client_s* client = __client_get(vc);
466
467         /* check handle */
468         if (NULL == client)
469                 return VC_ERROR_INVALID_PARAMETER;
470
471         *state = client->current_state;
472
473         return 0;
474 }
475
476 int vc_client_get_client_state_by_uid(int uid, vc_state_e* state)
477 {
478         vc_client_s *data = NULL;
479
480         int count = g_slist_length(g_client_list);
481         int i;
482
483         for (i = 0; i < count; i++) {
484                 data = g_slist_nth_data(g_client_list, i);
485
486                 if (NULL != data) {
487                         if (uid == data->vc->handle) {
488                                 *state = data->current_state;
489                                 return 0;
490                         }
491                 }
492         }
493
494         return -1;
495 }
496
497 int vc_client_get_before_state(vc_h vc, vc_state_e* state, vc_state_e* before_state)
498 {
499         vc_client_s* client = __client_get(vc);
500
501         /* check handle */
502         if (NULL == client)
503                 return VC_ERROR_INVALID_PARAMETER;
504
505         *before_state = client->before_state;
506         *state = client->current_state;
507
508         return 0;
509 }
510
511 int vc_client_set_invocation_name(vc_h vc, const char* invocation_name)
512 {
513         vc_client_s* client = __client_get(vc);
514
515         /* check handle */
516         if (NULL == client)
517                 return VC_ERROR_INVALID_PARAMETER;
518
519         if (NULL != client->invocation_name) {
520                 free(client->invocation_name);
521                 client->invocation_name = NULL;
522         }
523
524         if (NULL != invocation_name) {
525                 client->invocation_name = strdup(invocation_name);
526         }
527         return 0;
528 }
529
530 int vc_client_get_invocation_name(vc_h vc, char** invocation_name)
531 {
532         vc_client_s* client = __client_get(vc);
533
534         /* check handle */
535         if (NULL == client)
536                 return VC_ERROR_INVALID_PARAMETER;
537
538         if (NULL != client->invocation_name)
539                 *invocation_name = strdup(client->invocation_name);
540         return 0;
541 }
542
543 //LCOV_EXCL_START
544 int vc_client_set_xid(vc_h vc, int xid)
545 {
546         vc_client_s* client = __client_get(vc);
547
548         /* check handle */
549         if (NULL == client)
550                 return VC_ERROR_INVALID_PARAMETER;
551
552         client->xid = xid;
553
554         return 0;
555 }
556
557 int vc_client_get_xid(vc_h vc, int* xid)
558 {
559         vc_client_s* client = __client_get(vc);
560
561         /* check handle */
562         if (NULL == client)
563                 return VC_ERROR_INVALID_PARAMETER;
564
565         *xid = client->xid;
566
567         return 0;
568 }
569 //LCOV_EXCL_STOP
570
571 int vc_client_set_is_foreground(vc_h vc, bool value)
572 {
573         vc_client_s* client = __client_get(vc);
574
575         /* check handle */
576         if (NULL == client)
577                 return VC_ERROR_INVALID_PARAMETER;
578
579         client->is_foreground = value;
580         return 0;
581 }
582
583 int vc_client_get_is_foreground(vc_h vc, bool* value)
584 {
585         vc_client_s* client = __client_get(vc);
586
587         /* check handle */
588         if (NULL == client)
589                 return VC_ERROR_INVALID_PARAMETER;
590
591         *value = client->is_foreground;
592
593         return 0;
594 }
595
596 //LCOV_EXCL_START
597 #if 0
598 int vc_client_set_exclusive_cmd(vc_h vc, bool value)
599 {
600         vc_client_s* client = __client_get(vc);
601
602         /* check handle */
603         if (NULL == client)
604                 return VC_ERROR_INVALID_PARAMETER;
605
606         client->exclusive_cmd = value;
607
608         return 0;
609 }
610
611 int vc_client_get_exclusive_cmd(vc_h vc, bool* value)
612 {
613         vc_client_s* client = __client_get(vc);
614
615         /* check handle */
616         if (NULL == client)
617                 return VC_ERROR_INVALID_PARAMETER;
618
619         *value = client->exclusive_cmd;
620
621         return 0;
622 }
623 #endif
624 //LCOV_EXCL_STOP
625
626 int vc_client_set_error(vc_h vc, int reason)
627 {
628         vc_client_s* client = __client_get(vc);
629
630         /* check handle */
631         if (NULL == client)
632                 return VC_ERROR_INVALID_PARAMETER;
633
634         client->reason = reason;
635
636         return 0;
637 }
638
639 int vc_client_get_error(vc_h vc, int* reason)
640 {
641         vc_client_s* client = __client_get(vc);
642
643         /* check handle */
644         if (NULL == client)
645                 return VC_ERROR_INVALID_PARAMETER;
646
647         *reason = client->reason;
648
649         return 0;
650 }
651
652
653 /* utils */
654 int vc_client_get_count()
655 {
656         return g_slist_length(g_client_list);
657 }
658
659 int vc_client_use_callback(vc_h vc)
660 {
661         vc_client_s* client = __client_get(vc);
662
663         /* check handle */
664         if (NULL == client)
665                 return VC_ERROR_INVALID_PARAMETER;
666
667         client->cb_ref_count++;
668         return 0;
669 }
670
671 int vc_client_not_use_callback(vc_h vc)
672 {
673         vc_client_s* client = __client_get(vc);
674
675         /* check handle */
676         if (NULL == client)
677                 return VC_ERROR_INVALID_PARAMETER;
678
679         client->cb_ref_count--;
680         return 0;
681 }
682
683 //LCOV_EXCL_START
684 /* Authority */
685 int vc_client_set_auth_state_changed_cb(vc_h vc, vc_auth_state_changed_cb callback, void* user_data)
686 {
687         vc_client_s* client = __client_get(vc);
688
689         /* check handle */
690         if (NULL == client)
691                 return VC_ERROR_INVALID_PARAMETER;
692
693         client->auth_state_changed_cb = callback;
694         client->auth_state_changed_user_data = user_data;
695
696         return 0;
697 }
698
699 int vc_client_get_auth_state_changed_cb(vc_h vc, vc_auth_state_changed_cb* callback, void** user_data)
700 {
701         vc_client_s* client = __client_get(vc);
702
703         /* check handle */
704         if (NULL == client)
705                 return VC_ERROR_INVALID_PARAMETER;
706
707         *callback = client->auth_state_changed_cb;
708         *user_data = client->auth_state_changed_user_data;
709
710         return 0;
711 }
712
713 int vc_client_unset_auth_state_changed_cb(vc_h vc)
714 {
715         vc_client_s* client = __client_get(vc);
716
717         /* check handle */
718         if (NULL == client)
719                 return VC_ERROR_INVALID_PARAMETER;
720
721         client->auth_state_changed_cb = NULL;
722         client->auth_state_changed_user_data = NULL;
723
724         return 0;
725 }
726
727 int vc_client_set_auth_state(vc_h vc, vc_auth_state_e state)
728 {
729         vc_client_s* client = __client_get(vc);
730
731         /* check handle */
732         if (NULL == client)
733                 return VC_ERROR_INVALID_PARAMETER;
734
735         client->auth_before_state = client->auth_current_state;
736         client->auth_current_state = state;
737
738         return 0;
739 }
740
741 int vc_client_get_auth_state(vc_h vc, vc_auth_state_e* state)
742 {
743         vc_client_s* client = __client_get(vc);
744
745         /* check handle */
746         if (NULL == client)
747                 return VC_ERROR_INVALID_PARAMETER;
748
749         *state = client->auth_current_state;
750
751         return 0;
752 }
753
754 int vc_client_get_before_auth_state(vc_h vc, vc_auth_state_e* before, vc_auth_state_e* current)
755 {
756         vc_client_s* client = __client_get(vc);
757
758         /* check handle */
759         if (NULL == client)
760                 return VC_ERROR_INVALID_PARAMETER;
761
762         *before = client->auth_before_state;
763         *current = client->auth_current_state;
764
765         return 0;
766 }
767 //LCOV_EXCL_STOP
768
769 int vc_client_set_mgr_pid(vc_h vc, int mgr_pid)
770 {
771         vc_client_s* client = __client_get(vc);
772
773         /* check handle */
774         if (NULL == client)
775                 return VC_ERROR_INVALID_PARAMETER;
776
777         client->mgr_pid = mgr_pid;
778
779         return 0;
780 }
781
782 int vc_client_get_mgr_pid(vc_h vc, int* mgr_pid)
783 {
784         vc_client_s* client = __client_get(vc);
785
786         /* check handle */
787         if (NULL == client)
788                 return VC_ERROR_INVALID_PARAMETER;
789
790         *mgr_pid = client->mgr_pid;
791
792         return 0;
793 }
794
795 int vc_client_set_tts_streaming_cb(vc_h vc, vc_tts_streaming_cb callback, void* user_data)
796 {
797         vc_client_s* client = __client_get(vc);
798
799         /* check handle */
800         if (NULL == client)
801                 return VC_ERROR_INVALID_PARAMETER;
802
803         client->tts_streaming_cb = callback;
804         client->tts_streaming_user_data = user_data;
805
806         return 0;
807 }
808
809 int vc_client_get_tts_streaming_cb(vc_h vc, vc_tts_streaming_cb* callback, void** user_data)
810 {
811         vc_client_s* client = __client_get(vc);
812
813         /* check handle */
814         if (NULL == client)
815                 return VC_ERROR_INVALID_PARAMETER;
816
817         *callback = client->tts_streaming_cb;
818         *user_data = client->tts_streaming_user_data;
819
820         return 0;
821 }
822
823 int vc_client_set_tts_utterance_status_cb(vc_h vc, vc_tts_utterance_status_cb callback, void* user_data)
824 {
825         vc_client_s* client = __client_get(vc);
826
827         /* check handle */
828         if (NULL == client)
829                 return VC_ERROR_INVALID_PARAMETER;
830
831         client->tts_utterance_status_cb = callback;
832         client->tts_utterance_status_user_data = user_data;
833
834         return 0;
835 }
836
837 int vc_client_get_tts_utterance_status_cb(vc_h vc, vc_tts_utterance_status_cb* callback, void** user_data)
838 {
839         vc_client_s* client = __client_get(vc);
840
841         /* check handle */
842         if (NULL == client)
843                 return VC_ERROR_INVALID_PARAMETER;
844
845         *callback = client->tts_utterance_status_cb;
846         *user_data = client->tts_utterance_status_user_data;
847
848         return 0;
849 }