Add logic to avoid reconnetion when finalize
[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         int     pid;
23
24         vc_result_cb                    result_cb;
25         void*                           result_user_data;
26         vc_error_cb                     error_cb;
27         void*                           error_user_data;
28         vc_service_state_changed_cb     service_state_changed_cb;
29         void*                           service_state_changed_user_data;
30         vc_state_changed_cb             state_changed_cb;
31         void*                           state_changed_user_data;
32         vc_current_language_changed_cb  current_lang_changed_cb;
33         void*                           current_lang_changed_user_data;
34
35         /* tts feedback */
36         vc_tts_streaming_cb tts_streaming_cb;
37         void*                           tts_streaming_user_data;
38         vc_tts_utterance_status_cb      tts_utterance_status_cb;
39         void*                                           tts_utterance_status_user_data;
40
41 #if 0
42         /* exclusive option */
43         bool                    exclusive_cmd;
44 #endif
45
46         /* service state */
47         vc_service_state_e      service_state;
48
49         /* state */
50         vc_state_e      previous_state;
51         vc_state_e      current_state;
52
53         /* mutex */
54         int     cb_ref_count;
55
56         /* error data */
57         int     reason;
58
59         /* Authority */
60         vc_auth_state_e         auth_previous_state;
61         vc_auth_state_e         auth_current_state;
62         vc_auth_state_changed_cb        auth_state_changed_cb;
63         void*                           auth_state_changed_user_data;
64
65         int     mgr_pid;
66
67         /* is foreground */
68         bool    is_foreground;
69
70         /* Invocation name */
71         char*   invocation_name;
72
73         /* Listening IPC message from service */
74         bool    start_listening;
75 } vc_client_s;
76
77 static vc_client_s *g_client = NULL;
78
79
80 int vc_client_create(void)
81 {
82         if (NULL != g_client) {
83                 SLOG(LOG_WARN, TAG_VCC, "[WARNING] A client is already exist.");
84                 return VC_ERROR_NONE;
85         }
86
87         g_client = (vc_client_s*)calloc(1, sizeof(vc_client_s));
88         if (NULL == g_client) {
89                 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to allocate memory"); //LCOV_EXCL_LINE
90                 return VC_ERROR_OUT_OF_MEMORY;
91         }
92
93         /* initialize client data */
94         g_client->pid = getpid();
95
96         g_client->result_cb = NULL;
97         g_client->result_user_data = NULL;
98         g_client->service_state_changed_cb = NULL;
99         g_client->service_state_changed_user_data = NULL;
100         g_client->state_changed_cb = NULL;
101         g_client->state_changed_user_data = NULL;
102         g_client->current_lang_changed_cb = NULL;
103         g_client->current_lang_changed_user_data = NULL;
104         g_client->error_cb = NULL;
105         g_client->error_user_data = NULL;
106         g_client->tts_streaming_cb = NULL;
107         g_client->tts_streaming_user_data = NULL;
108         g_client->tts_utterance_status_cb = NULL;
109         g_client->tts_utterance_status_user_data = NULL;
110
111 #if 0
112         g_client->exclusive_cmd = false;
113 #endif
114
115         g_client->service_state = VC_RUNTIME_INFO_NO_FOREGROUND;
116
117         g_client->previous_state = VC_STATE_INITIALIZED;
118         g_client->current_state = VC_STATE_INITIALIZED;
119
120         g_client->cb_ref_count = 0;
121
122         /* Authority */
123         g_client->auth_previous_state = VC_AUTH_STATE_NONE;
124         g_client->auth_current_state = VC_AUTH_STATE_NONE;
125         g_client->auth_state_changed_cb = NULL;
126         g_client->auth_state_changed_user_data = NULL;
127
128         g_client->is_foreground = false;
129         g_client->invocation_name = NULL;
130         g_client->start_listening = false;
131
132         SLOG(LOG_INFO, TAG_VCC, "[INFO] client create. pid(%u)", g_client->pid);
133
134         return VC_ERROR_NONE;
135 }
136
137 int vc_client_destroy(void)
138 {
139         if (NULL == g_client) {
140                 SLOG(LOG_ERROR, TAG_VCC, "A client is already NULL"); //LCOV_EXCL_LINE
141                 return VC_ERROR_NONE;
142         }
143
144         while (0 != g_client->cb_ref_count) {
145                 /* wait for release callback function */
146         }
147         if (NULL != g_client->invocation_name) {
148                 free(g_client->invocation_name);
149                 g_client->invocation_name = NULL;
150         }
151         free(g_client);
152         g_client = NULL;
153
154         return VC_ERROR_NONE;
155 }
156
157 bool vc_client_is_valid(void)
158 {
159         /* check handle */
160         if (NULL == g_client) {
161                 SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] The current client is not valid");
162                 return false;
163         }
164
165         return true;
166 }
167
168 /* set/get callback function */
169 int vc_client_set_result_cb(vc_result_cb callback, void* user_data)
170 {
171         /* check handle */
172         if (NULL == g_client)
173                 return VC_ERROR_INVALID_PARAMETER;
174
175         g_client->result_cb = callback;
176         g_client->result_user_data = user_data;
177
178         return VC_ERROR_NONE;
179 }
180
181 //LCOV_EXCL_START
182 int vc_client_get_result_cb(vc_result_cb* callback, void** user_data)
183 {
184         /* check handle */
185         if (NULL == g_client)
186                 return VC_ERROR_INVALID_PARAMETER;
187
188         *callback = g_client->result_cb;
189         *user_data = g_client->result_user_data;
190
191         return VC_ERROR_NONE;
192 }
193 //LCOV_EXCL_STOP
194
195 int vc_client_set_service_state_changed_cb(vc_service_state_changed_cb callback, void* user_data)
196 {
197         /* check handle */
198         if (NULL == g_client)
199                 return VC_ERROR_INVALID_PARAMETER;
200
201         g_client->service_state_changed_cb = callback;
202         g_client->service_state_changed_user_data = user_data;
203
204         return VC_ERROR_NONE;
205 }
206
207 //LCOV_EXCL_START
208 int vc_client_get_service_state_changed_cb(vc_service_state_changed_cb* callback, void** user_data)
209 {
210         /* check handle */
211         if (NULL == g_client)
212                 return VC_ERROR_INVALID_PARAMETER;
213
214         *callback = g_client->service_state_changed_cb;
215         *user_data = g_client->service_state_changed_user_data;
216
217         return VC_ERROR_NONE;
218 }
219 //LCOV_EXCL_STOP
220
221 int vc_client_set_state_changed_cb(vc_state_changed_cb callback, void* user_data)
222 {
223         /* check handle */
224         if (NULL == g_client)
225                 return VC_ERROR_INVALID_PARAMETER;
226
227         g_client->state_changed_cb = callback;
228         g_client->state_changed_user_data = user_data;
229
230         return VC_ERROR_NONE;
231 }
232
233 //LCOV_EXCL_START
234 int vc_client_get_state_changed_cb(vc_state_changed_cb* callback, void** user_data)
235 {
236         /* check handle */
237         if (NULL == g_client)
238                 return VC_ERROR_INVALID_PARAMETER;
239
240         *callback = g_client->state_changed_cb;
241         *user_data = g_client->state_changed_user_data;
242
243         return VC_ERROR_NONE;
244 }
245 //LCOV_EXCL_STOP
246
247 int vc_client_set_current_lang_changed_cb(vc_current_language_changed_cb callback, void* user_data)
248 {
249         /* check handle */
250         if (NULL == g_client)
251                 return VC_ERROR_INVALID_PARAMETER;
252
253         g_client->current_lang_changed_cb = callback;
254         g_client->current_lang_changed_user_data = user_data;
255
256         return VC_ERROR_NONE;
257 }
258
259 //LCOV_EXCL_START
260 int vc_client_get_current_lang_changed_cb(vc_current_language_changed_cb* callback, void** user_data)
261 {
262         /* check handle */
263         if (NULL == g_client)
264                 return VC_ERROR_INVALID_PARAMETER;
265
266         *callback = g_client->current_lang_changed_cb;
267         *user_data = g_client->current_lang_changed_user_data;
268
269         return VC_ERROR_NONE;
270 }
271 //LCOV_EXCL_STOP
272
273 int vc_client_set_error_cb(vc_error_cb callback, void* user_data)
274 {
275         /* check handle */
276         if (NULL == g_client)
277                 return VC_ERROR_INVALID_PARAMETER;
278
279         g_client->error_cb = callback;
280         g_client->error_user_data = user_data;
281
282         return VC_ERROR_NONE;
283 }
284
285 //LCOV_EXCL_START
286 int vc_client_get_error_cb(vc_error_cb* callback, void** user_data)
287 {
288         /* check handle */
289         if (NULL == g_client)
290                 return VC_ERROR_INVALID_PARAMETER;
291
292         *callback = g_client->error_cb;
293         *user_data = g_client->error_user_data;
294
295         return VC_ERROR_NONE;
296 }
297 //LCOV_EXCL_STOP
298
299 /* set/get option */
300 int vc_client_set_service_state(vc_service_state_e state)
301 {
302         /* check handle */
303         if (NULL == g_client)
304                 return VC_ERROR_INVALID_PARAMETER;
305
306         g_client->service_state = state;
307
308         return VC_ERROR_NONE;
309 }
310
311 int vc_client_get_service_state(vc_service_state_e* state)
312 {
313         /* check handle */
314         if (NULL == g_client)
315                 return VC_ERROR_INVALID_PARAMETER;
316
317         *state = g_client->service_state;
318
319         return VC_ERROR_NONE;
320 }
321
322 int vc_client_set_client_state(vc_state_e state)
323 {
324         /* check handle */
325         if (NULL == g_client)
326                 return VC_ERROR_INVALID_PARAMETER;
327
328         g_client->previous_state = g_client->current_state;
329         g_client->current_state = state;
330
331         return VC_ERROR_NONE;
332 }
333
334 int vc_client_get_client_state(vc_state_e* state)
335 {
336         /* check handle */
337         if (NULL == g_client)
338                 return VC_ERROR_INVALID_PARAMETER;
339
340         *state = g_client->current_state;
341
342         return VC_ERROR_NONE;
343 }
344
345 int vc_client_get_previous_state(vc_state_e* state, vc_state_e* previous_state)
346 {
347         /* check handle */
348         if (NULL == g_client)
349                 return VC_ERROR_INVALID_PARAMETER;
350
351         *previous_state = g_client->previous_state;
352         *state = g_client->current_state;
353
354         return VC_ERROR_NONE;
355 }
356
357 int vc_client_set_invocation_name(const char* invocation_name)
358 {
359         /* check handle */
360         if (NULL == g_client)
361                 return VC_ERROR_INVALID_PARAMETER;
362
363         if (NULL != g_client->invocation_name) {
364                 free(g_client->invocation_name);
365                 g_client->invocation_name = NULL;
366         }
367
368         if (NULL != invocation_name) {
369                 g_client->invocation_name = strdup(invocation_name);
370         }
371         return VC_ERROR_NONE;
372 }
373
374 int vc_client_get_invocation_name(char** invocation_name)
375 {
376         /* check handle */
377         if (NULL == g_client)
378                 return VC_ERROR_INVALID_PARAMETER;
379
380         if (NULL != g_client->invocation_name)
381                 *invocation_name = strdup(g_client->invocation_name);
382         return VC_ERROR_NONE;
383 }
384
385 int vc_client_set_is_foreground(bool value)
386 {
387         /* check handle */
388         if (NULL == g_client)
389                 return VC_ERROR_INVALID_PARAMETER;
390
391         g_client->is_foreground = value;
392         return VC_ERROR_NONE;
393 }
394
395 int vc_client_get_is_foreground(bool* value)
396 {
397         /* check handle */
398         if (NULL == g_client)
399                 return VC_ERROR_INVALID_PARAMETER;
400
401         *value = g_client->is_foreground;
402
403         return VC_ERROR_NONE;
404 }
405
406 //LCOV_EXCL_START
407 #if 0
408 int vc_client_set_exclusive_cmd(vc_h vc, bool value)
409 {
410         vc_client_s* client = __client_get(vc);
411
412         /* check handle */
413         if (NULL == client)
414                 return VC_ERROR_INVALID_PARAMETER;
415
416         client->exclusive_cmd = value;
417
418         return VC_ERROR_NONE;
419 }
420
421 int vc_client_get_exclusive_cmd(vc_h vc, bool* value)
422 {
423         vc_client_s* client = __client_get(vc);
424
425         /* check handle */
426         if (NULL == client)
427                 return VC_ERROR_INVALID_PARAMETER;
428
429         *value = client->exclusive_cmd;
430
431         return VC_ERROR_NONE;
432 }
433 #endif
434 //LCOV_EXCL_STOP
435
436 int vc_client_set_error(int reason)
437 {
438         /* check handle */
439         if (NULL == g_client)
440                 return VC_ERROR_INVALID_PARAMETER;
441
442         g_client->reason = reason;
443
444         return VC_ERROR_NONE;
445 }
446
447 int vc_client_get_error(int* reason)
448 {
449         /* check handle */
450         if (NULL == g_client)
451                 return VC_ERROR_INVALID_PARAMETER;
452
453         *reason = g_client->reason;
454
455         return VC_ERROR_NONE;
456 }
457
458
459 /* utils */
460 int vc_client_use_callback(void)
461 {
462         /* check handle */
463         if (NULL == g_client)
464                 return VC_ERROR_INVALID_PARAMETER;
465
466         g_client->cb_ref_count++;
467         return VC_ERROR_NONE;
468 }
469
470 int vc_client_not_use_callback(void)
471 {
472         /* check handle */
473         if (NULL == g_client)
474                 return VC_ERROR_INVALID_PARAMETER;
475
476         g_client->cb_ref_count--;
477         return VC_ERROR_NONE;
478 }
479
480 //LCOV_EXCL_START
481 /* Authority */
482 int vc_client_set_auth_state_changed_cb(vc_auth_state_changed_cb callback, void* user_data)
483 {
484         /* check handle */
485         if (NULL == g_client)
486                 return VC_ERROR_INVALID_PARAMETER;
487
488         g_client->auth_state_changed_cb = callback;
489         g_client->auth_state_changed_user_data = user_data;
490
491         return VC_ERROR_NONE;
492 }
493
494 int vc_client_get_auth_state_changed_cb(vc_auth_state_changed_cb* callback, void** user_data)
495 {
496         /* check handle */
497         if (NULL == g_client)
498                 return VC_ERROR_INVALID_PARAMETER;
499
500         *callback = g_client->auth_state_changed_cb;
501         *user_data = g_client->auth_state_changed_user_data;
502
503         return VC_ERROR_NONE;
504 }
505
506 int vc_client_unset_auth_state_changed_cb(void)
507 {
508         /* check handle */
509         if (NULL == g_client)
510                 return VC_ERROR_INVALID_PARAMETER;
511
512         g_client->auth_state_changed_cb = NULL;
513         g_client->auth_state_changed_user_data = NULL;
514
515         return VC_ERROR_NONE;
516 }
517
518 int vc_client_set_auth_state(vc_auth_state_e state)
519 {
520         /* check handle */
521         if (NULL == g_client)
522                 return VC_ERROR_INVALID_PARAMETER;
523
524         g_client->auth_previous_state = g_client->auth_current_state;
525         g_client->auth_current_state = state;
526
527         return VC_ERROR_NONE;
528 }
529
530 int vc_client_get_auth_state(vc_auth_state_e* state)
531 {
532         /* check handle */
533         if (NULL == g_client)
534                 return VC_ERROR_INVALID_PARAMETER;
535
536         *state = g_client->auth_current_state;
537
538         return VC_ERROR_NONE;
539 }
540
541 int vc_client_get_previous_auth_state(vc_auth_state_e* previous, vc_auth_state_e* current)
542 {
543         /* check handle */
544         if (NULL == g_client)
545                 return VC_ERROR_INVALID_PARAMETER;
546
547         *previous = g_client->auth_previous_state;
548         *current = g_client->auth_current_state;
549
550         return VC_ERROR_NONE;
551 }
552 //LCOV_EXCL_STOP
553
554 int vc_client_set_mgr_pid(int mgr_pid)
555 {
556         /* check handle */
557         if (NULL == g_client)
558                 return VC_ERROR_INVALID_PARAMETER;
559
560         g_client->mgr_pid = mgr_pid;
561
562         return VC_ERROR_NONE;
563 }
564
565 int vc_client_get_mgr_pid(int* mgr_pid)
566 {
567         /* check handle */
568         if (NULL == g_client)
569                 return VC_ERROR_INVALID_PARAMETER;
570
571         *mgr_pid = g_client->mgr_pid;
572
573         return VC_ERROR_NONE;
574 }
575
576 int vc_client_set_tts_streaming_cb(vc_tts_streaming_cb callback, void* user_data)
577 {
578         /* check handle */
579         if (NULL == g_client)
580                 return VC_ERROR_INVALID_PARAMETER;
581
582         g_client->tts_streaming_cb = callback;
583         g_client->tts_streaming_user_data = user_data;
584
585         return VC_ERROR_NONE;
586 }
587
588 int vc_client_get_tts_streaming_cb(vc_tts_streaming_cb* callback, void** user_data)
589 {
590         /* check handle */
591         if (NULL == g_client)
592                 return VC_ERROR_INVALID_PARAMETER;
593
594         *callback = g_client->tts_streaming_cb;
595         *user_data = g_client->tts_streaming_user_data;
596
597         return VC_ERROR_NONE;
598 }
599
600 int vc_client_set_tts_utterance_status_cb(vc_tts_utterance_status_cb callback, void* user_data)
601 {
602         /* check handle */
603         if (NULL == g_client)
604                 return VC_ERROR_INVALID_PARAMETER;
605
606         g_client->tts_utterance_status_cb = callback;
607         g_client->tts_utterance_status_user_data = user_data;
608
609         return VC_ERROR_NONE;
610 }
611
612 int vc_client_get_tts_utterance_status_cb(vc_tts_utterance_status_cb* callback, void** user_data)
613 {
614         /* check handle */
615         if (NULL == g_client)
616                 return VC_ERROR_INVALID_PARAMETER;
617
618         *callback = g_client->tts_utterance_status_cb;
619         *user_data = g_client->tts_utterance_status_user_data;
620
621         return VC_ERROR_NONE;
622 }
623
624 int vc_client_set_start_listening(bool is_listening_started)
625 {
626         if (NULL == g_client)
627                 return VC_ERROR_INVALID_PARAMETER;
628
629         g_client->start_listening = is_listening_started;
630         return VC_ERROR_NONE;
631 }
632
633 bool vc_client_is_listening_started()
634 {
635         if (NULL == g_client)
636                 return false;
637
638         return g_client->start_listening;
639 }