Fix build error on gcc-13 Build
[platform/core/uifw/voice-control.git] / client / vc_mgr_core.c
1 /*
2 * Copyright (c) 2022 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 #include <aul.h>
17 #include <system_info.h>
18 #include <pthread.h>
19 #include <sound_manager.h>
20 #include <sound_manager_internal.h>
21 #include <math.h>
22
23 #include "vc_cmd_db.h"
24 #include "vc_command.h"
25 #include "vc_config_mgr.h"
26 #include "vc_info_parser.h"
27 #include "vc_json_parser.h"
28 #include "vc_main.h"
29 #include "vc_mgr_core.h"
30 #include "vc_mgr_client.h"
31 #include "vc_mgr_tidl.h"
32 #include "vc_mgr_data.h"
33 #include "voice_control_command.h"
34 #include "voice_control_command_expand.h"
35 #include "voice_control_common.h"
36 #include "voice_control_manager.h"
37 #include "voice_control_manager_internal.h"
38
39
40 static Ecore_Timer* g_m_set_volume_timer = NULL;
41
42 static GSList* g_demandable_client_list = NULL;
43
44 static float g_volume_db = 0;
45
46 static float g_prev_volume_db = 0;
47
48 static float g_cur_volume_db = 0;
49
50 static int g_volume_timer_cnt = 0;
51
52 static bool g_err_callback_status = false;
53
54 /* for TTS feedback */
55 static int g_feedback_rate = 16000;
56 static vc_audio_channel_e g_feedback_audio_channel = 0;
57 static vc_audio_type_e g_feedback_audio_type = 0;
58
59 static Eina_Bool __vc_mgr_core_set_volume_timer_cb(void* data)
60 {
61         g_volume_timer_cnt++;
62         g_volume_db = g_prev_volume_db + (g_cur_volume_db - g_prev_volume_db) / 5 * g_volume_timer_cnt;
63
64         SLOG(LOG_INFO, TAG_VCM, "Set volume (%f)(%f)", g_volume_db, g_cur_volume_db);
65
66         if (0 == g_volume_timer_cnt % 5) {
67                 return EINA_FALSE;
68         }
69         return EINA_TRUE;
70 }
71
72 static Eina_Bool __vc_mgr_core_set_select_result(void *data)
73 {
74         // TODO: remove vc_mgr dependency by separate vc_mgr_set_selected_results core logic to core layer
75         vc_mgr_set_selected_results(NULL);
76         return EINA_FALSE;
77 }
78
79 static void __vc_mgr_core_notify_all_result(vc_result_type_e result_type)
80 {
81         char* temp_text = NULL;
82         int event;
83         char* temp_message = NULL;
84         vc_cmd_list_h vc_cmd_list = NULL;
85
86         vc_mgr_all_result_cb all_callback = NULL;
87         void* all_user_data = NULL;
88
89         vc_mgr_client_get_all_result_cb(&all_callback, &all_user_data);
90         RETM_IF(NULL == all_callback, TAG_VCM, "[ERROR] All result callback is NULL");
91
92         if (VC_ERROR_NONE != vc_cmd_list_create(&vc_cmd_list)) {
93                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to create command list");
94                 return;
95         }
96
97         vc_info_parser_get_result(&temp_text, &event, &temp_message, -1, vc_cmd_list, vc_mgr_client_get_exclusive_command());
98
99         SECURE_SLOG(LOG_INFO, TAG_VCM, "Result info : result type(%d) result text(%s) event(%d) result_message(%s)",
100                 result_type, temp_text, event, temp_message);
101
102         vc_cmd_print_list(vc_cmd_list);
103
104         bool cb_ret = false;
105
106         vc_mgr_client_set_all_result(event, temp_text);
107
108         vc_mgr_client_use_callback();
109         cb_ret = all_callback(event, vc_cmd_list, temp_text, temp_message, all_user_data);
110         vc_mgr_client_not_use_callback();
111
112         if (true == vc_mgr_client_get_exclusive_command()) {
113                 /* exclusive */
114                 vc_result_cb callback = NULL;
115                 void* user_data = NULL;
116
117                 vc_mgr_client_get_result_cb(&callback, &user_data);
118                 RETM_IF(NULL == callback, TAG_VCM, "[ERROR] Client result callback is NULL");
119
120                 vc_mgr_client_use_callback();
121                 callback(event, vc_cmd_list, temp_text, user_data);
122                 vc_mgr_client_not_use_callback();
123                 SLOG(LOG_DEBUG, TAG_VCM, "Exclusive result callback called");
124
125                 /* Release result */
126                 if (NULL != temp_text) {
127                         free(temp_text);
128                         temp_text = NULL;
129                 }
130                 if (NULL != temp_message) {
131                         free(temp_message);
132                         temp_message = NULL;
133                 }
134
135                 /* Release list */
136                 if (vc_cmd_list)
137                         vc_cmd_list_destroy(vc_cmd_list, true);
138                 vc_cmd_list = NULL;
139
140                 vc_mgr_client_set_exclusive_command(false);
141
142                 return;
143         }
144
145         int count = 0;
146         vc_cmd_list_get_count(vc_cmd_list, &count);
147         if (0 < count) {
148                 if (true == cb_ret) {
149                         SLOG(LOG_INFO, TAG_VCM, "Callback result is true");
150                         if (VC_RESULT_TYPE_NOTIFICATION != result_type)
151                                 ecore_idler_add(__vc_mgr_core_set_select_result, NULL);
152                 } else {
153                         SLOG(LOG_INFO, TAG_VCM, "Callback result is false");
154                         /* need to select conflicted result */
155                 }
156         } else {
157                 if (VC_RESULT_TYPE_NOTIFICATION != result_type)
158                         ecore_idler_add(__vc_mgr_core_set_select_result, NULL);
159
160                 vc_mgr_client_set_exclusive_command(false);
161                 vc_mgr_client_unset_all_result();
162         }
163
164         /* Release result */
165         if (NULL != temp_text) {
166                 free(temp_text);
167                 temp_text = NULL;
168         }
169         if (NULL != temp_message) {
170                 free(temp_message);
171                 temp_message = NULL;
172         }
173
174         /* Release list */
175         if (vc_cmd_list)
176                 vc_cmd_list_destroy(vc_cmd_list, true);
177         vc_cmd_list = NULL;
178
179         return;
180 }
181
182 static void __vc_mgr_core_notify_result()
183 {
184         char* temp_text = NULL;
185         int event;
186         vc_cmd_list_h vc_cmd_list = NULL;
187
188         vc_result_cb callback = NULL;
189         void* user_data = NULL;
190
191         vc_mgr_client_get_result_cb(&callback, &user_data);
192         RETM_IF(NULL == callback, TAG_VCM, "[ERROR] Client result callback is NULL");
193
194         if (VC_ERROR_NONE != vc_cmd_list_create(&vc_cmd_list)) {
195                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to create command list");
196                 return;
197         }
198
199         vc_info_parser_get_result(&temp_text, &event, NULL, getpid(), vc_cmd_list, false);
200
201         SECURE_SLOG(LOG_INFO, TAG_VCM, "Result : result text(%s) event(%d)", temp_text, event);
202
203         vc_cmd_print_list(vc_cmd_list);
204
205         vc_mgr_client_use_callback();
206         callback(event, vc_cmd_list, temp_text, user_data);
207         vc_mgr_client_not_use_callback();
208         SLOG(LOG_INFO, TAG_VCM, "Result callback called");
209
210         if (vc_cmd_list)
211                 vc_cmd_list_destroy(vc_cmd_list, true);
212         vc_cmd_list = NULL;
213
214         /* Release result */
215         if (temp_text)
216                 free(temp_text);
217         temp_text = NULL;
218 }
219
220 void vc_mgr_core_send_all_result(vc_result_type_e type)
221 {
222         if (false == vc_mgr_client_get_exclusive_command()) {
223                 __vc_mgr_core_notify_all_result(type);
224         } else {
225                 __vc_mgr_core_notify_result();
226         }
227
228         return;
229 }
230
231 void vc_mgr_core_send_pre_result(vc_pre_result_event_e event, const char* pre_result)
232 {
233         vc_mgr_pre_result_cb callback = NULL;
234         void* user_data = NULL;
235
236         vc_mgr_client_get_pre_result_cb(&callback, &user_data);
237         RETM_IF(NULL == callback, TAG_VCM, "[ERROR] Client pre result callback is NULL");
238
239         vc_mgr_client_use_callback();
240         callback(event, pre_result, user_data);
241         vc_mgr_client_not_use_callback();
242         SLOG(LOG_INFO, TAG_VCM, "Pre result callback is called");
243
244         return;
245 }
246
247 void vc_mgr_core_send_system_result()
248 {
249         __vc_mgr_core_notify_result();
250         return;
251 }
252
253 void vc_mgr_core_send_speech_detected()
254 {
255         vc_mgr_begin_speech_detected_cb callback = NULL;
256         void* user_data = NULL;
257
258         vc_mgr_client_get_speech_detected_cb(&callback, &user_data);
259         RETM_IF(NULL == callback, TAG_VCM, "[ERROR] Client speech detected callback is NULL");
260
261         vc_mgr_client_use_callback();
262         callback(user_data);
263         vc_mgr_client_not_use_callback();
264         SLOG(LOG_INFO, TAG_VCM, "Speech detected callback called");
265
266
267         return;
268 }
269
270 void vc_mgr_core_notify_error()
271 {
272         vc_error_cb callback = NULL;
273         void* user_data = NULL;
274         int reason;
275
276         vc_mgr_client_get_error_cb(&callback, &user_data);
277         vc_mgr_client_get_error(&reason);
278
279         if (NULL != callback) {
280                 vc_mgr_client_use_callback();
281                 g_err_callback_status = true;
282                 callback(reason, user_data);
283                 g_err_callback_status = false;
284                 vc_mgr_client_not_use_callback();
285                 SLOG(LOG_INFO, TAG_VCM, "Error callback is called");
286         } else {
287                 SLOG(LOG_WARN, TAG_VCM, "[WARNING] Error callback is null");
288         }
289 }
290
291 int vc_mgr_core_set_selected_results(vc_cmd_list_h vc_cmd_list, int pid)
292 {
293         if (NULL != vc_cmd_list) {
294                 int event = 0;
295                 char* result_text = NULL;
296
297                 vc_mgr_client_get_all_result(&event, &result_text);
298
299                 vc_info_parser_set_result(result_text, event, NULL, vc_cmd_list, false);
300
301                 if (NULL != result_text) {
302                         free(result_text);
303                         result_text = NULL;
304                 }
305         }
306
307         /* Request */
308         int ret = vc_mgr_tidl_send_result_selection(pid);
309         if (0 != ret) {
310                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to send result selection : %d", ret);
311                 return ret;
312         } else {
313                 SLOG(LOG_INFO, TAG_VCM, "[SUCCESS] result selection");
314         }
315
316         vc_mgr_client_unset_all_result();
317
318         SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Select result DONE");
319
320         return VC_ERROR_NONE;
321 }
322
323 static void vc_mgr_core_notify_state_changed()
324 {
325         vc_state_changed_cb changed_callback = NULL;
326         void* user_data;
327
328         vc_mgr_client_get_state_changed_cb(&changed_callback, &user_data);
329
330         vc_state_e current_state;
331         vc_state_e previous_state;
332
333         vc_mgr_client_get_previous_state(&current_state, &previous_state);
334
335         if (NULL != changed_callback) {
336                 vc_mgr_client_use_callback();
337                 changed_callback(previous_state, current_state, user_data);
338                 vc_mgr_client_not_use_callback();
339                 SLOG(LOG_INFO, TAG_VCM, "State changed callback is called");
340         } else {
341                 SLOG(LOG_WARN, TAG_VCM, "[WARNING] State changed callback is null");
342         }
343 }
344
345 int vc_mgr_core_send_error(int reason, int daemon_pid, char* msg)
346 {
347         vc_state_e state;
348         if (VC_ERROR_NONE != vc_mgr_client_get_client_state(&state)) {
349                 SLOG(LOG_ERROR, TAG_VCM, "[WARNING] Invalid client");
350                 return VC_ERROR_INVALID_PARAMETER;
351         }
352
353         /* check state */
354         if (state != VC_STATE_INITIALIZED && state != VC_STATE_READY) {
355                 SLOG(LOG_ERROR, TAG_VCM, "[WARNING] not connected client yet");
356                 return VC_ERROR_INVALID_STATE;
357         }
358
359         vc_mgr_client_set_internal_state(VC_INTERNAL_STATE_NONE);
360
361         if (VC_ERROR_SERVICE_RESET == reason) {
362                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] VC daemon reset");
363
364                 vc_service_state_e service_state = -1;
365                 vc_mgr_client_get_service_state(&service_state);
366                 if (VC_SERVICE_STATE_UPDATING == service_state) {
367                         SLOG(LOG_INFO, TAG_VCM, "[INFO] VC daemon is terminated by update manager");
368                         return VC_ERROR_NONE;
369                 }
370
371                 vc_mgr_client_set_client_state(VC_STATE_INITIALIZED);
372                 vc_mgr_core_notify_state_changed();
373
374                 if (VC_ERROR_NONE != vc_mgr_prepare()) {
375                         SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to prepare");
376                 }
377         }
378
379         SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Error reason(%d), msg(%s)", reason, msg);
380
381         vc_mgr_client_set_error(reason);
382         vc_mgr_client_set_error_message(msg);
383         vc_mgr_core_notify_error();
384
385         return VC_ERROR_NONE;
386 }
387
388 int vc_mgr_core_get_error_message(char** err_msg)
389 {
390         if (false == g_err_callback_status) {
391                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Not in error callback");
392                 return VC_ERROR_OPERATION_FAILED;
393         }
394
395         int ret = vc_mgr_client_get_error_message(err_msg);
396         if (0 != ret) {
397                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get error message");
398         }
399
400         return ret;
401 }
402
403
404
405 int vc_mgr_core_send_service_state(int state)
406 {
407         vc_service_state_e current_state = (vc_service_state_e)state;
408         vc_service_state_e previous_state;
409         vc_mgr_client_get_service_state(&previous_state);
410
411         SLOG(LOG_INFO, TAG_VCM, "Service State changed : previous(%d) current(%d)",
412                 previous_state, current_state);
413
414         vc_internal_state_e internal_state = -1;
415         vc_mgr_client_get_internal_state(&internal_state);
416         if ((VC_INTERNAL_STATE_STARTING == internal_state && VC_SERVICE_STATE_RECORDING == current_state) ||
417                 (VC_INTERNAL_STATE_STOPPING == internal_state && VC_SERVICE_STATE_PROCESSING == current_state) ||
418                 (VC_INTERNAL_STATE_CANCELING == internal_state && VC_SERVICE_STATE_READY == current_state)) {
419                         SLOG(LOG_INFO, TAG_VCM, "Internal state is changed to NONE");
420                         vc_mgr_client_set_internal_state(VC_INTERNAL_STATE_NONE);
421         }
422         if (VC_SERVICE_STATE_UPDATING == current_state) {
423                 SLOG(LOG_INFO, TAG_VCM, "Internal state is changed to NONE by updating");
424                 vc_mgr_client_set_internal_state(VC_INTERNAL_STATE_NONE);
425         }
426
427         if (current_state == previous_state) {
428                 SLOG(LOG_WARN, TAG_VCM, "Service State NOT changed : previous(%d) current(%d)",
429                         previous_state, current_state);
430                 return VC_ERROR_NONE;
431         }
432
433         /* Save service state */
434         vc_mgr_client_set_service_state(current_state);
435
436         vc_service_state_changed_cb callback = NULL;
437         void* service_user_data = NULL;
438         vc_mgr_client_get_service_state_changed_cb(&callback, &service_user_data);
439
440         if (NULL != callback) {
441                 vc_mgr_client_use_callback();
442                 callback(previous_state, current_state, service_user_data);
443                 vc_mgr_client_not_use_callback();
444                 SLOG(LOG_INFO, TAG_VCM, "Service state changed callback is called");
445         } else {
446                 SLOG(LOG_WARN, TAG_VCM, "[WARNING] Service state changed callback is null");
447         }
448
449         return VC_ERROR_NONE;
450 }
451
452 int vc_mgr_core_send_dialog(int pid, const char* disp_text, const char* utt_text, bool continuous)
453 {
454         vc_mgr_dialog_request_cb callback = NULL;
455         void* user_data = NULL;
456
457         vc_mgr_client_get_dialog_request_cb(&callback, &user_data);
458
459         if (NULL != callback) {
460                 vc_mgr_client_use_callback();
461                 callback(pid, disp_text, utt_text, continuous, user_data);
462                 vc_mgr_client_not_use_callback();
463                 SLOG(LOG_INFO, TAG_VCM, "Dialog callback is called, disp_text(%s), utt)text(%s), continuous(%d)", disp_text, utt_text, continuous);
464         } else {
465                 SLOG(LOG_WARN, TAG_VCM, "[WARNING] Error callback is null");
466         }
467
468         return VC_ERROR_NONE;
469 }
470
471 int vc_mgr_core_send_private_data_set(const char* key, const char* data)
472 {
473         vc_mgr_private_data_set_cb callback = NULL;
474         void* user_data = NULL;
475         int ret = -1;
476
477         vc_mgr_client_get_private_data_set_cb(&callback, &user_data);
478
479         if (NULL != callback) {
480                 vc_mgr_client_use_callback();
481                 ret = callback(key, data, user_data);
482                 vc_mgr_client_not_use_callback();
483                 SLOG(LOG_INFO, TAG_VCM, "Private data set callback is called");
484         } else {
485                 SLOG(LOG_WARN, TAG_VCM, "[WARNING] Private data set callback is null");
486         }
487
488         return ret;
489 }
490
491 int vc_mgr_core_send_private_data_requested(const char* key, char** data)
492 {
493         vc_mgr_private_data_requested_cb callback = NULL;
494         void* user_data = NULL;
495         int ret = -1;
496
497         vc_mgr_client_get_private_data_requested_cb(&callback, &user_data);
498
499         if (NULL != callback) {
500                 vc_mgr_client_use_callback();
501                 ret = callback(key, data, user_data);
502                 vc_mgr_client_not_use_callback();
503                 SLOG(LOG_INFO, TAG_VCM, "Private data requested callback is called");
504         } else {
505                 SLOG(LOG_WARN, TAG_VCM, "[WARNING] Private data requested callback is null");
506         }
507
508         return ret;
509 }
510
511 void vc_mgr_core_send_specific_engine_result(const char* engine_app_id, const char* event, const char* result)
512 {
513         vc_mgr_specific_engine_result_cb callback = NULL;
514         void* user_data = NULL;
515
516         vc_mgr_client_get_specific_engine_result_cb(&callback, &user_data);
517         RETM_IF(NULL == callback, TAG_VCM, "[ERROR] Client specific engine result callback is NULL");
518
519         vc_mgr_client_use_callback();
520         callback(engine_app_id, event, result, user_data);
521         vc_mgr_client_not_use_callback();
522         SLOG(LOG_INFO, TAG_VCM, "Specific engine result callback is called, engine app id(%s), event(%s), result(%s)", engine_app_id, event, result);
523
524         return;
525 }
526
527 int vc_mgr_core_send_set_volume(float volume)
528 {
529         g_prev_volume_db = g_volume_db;
530         g_cur_volume_db = volume;
531
532         g_volume_db = g_prev_volume_db + (g_cur_volume_db - g_prev_volume_db) / 5;
533
534         if (NULL != g_m_set_volume_timer) {
535                 ecore_timer_del(g_m_set_volume_timer);
536         }
537
538         g_volume_timer_cnt = 1;
539         g_m_set_volume_timer = ecore_timer_add(0.05, __vc_mgr_core_set_volume_timer_cb, NULL);
540
541         return VC_ERROR_NONE;
542 }
543
544 void vc_mgr_core_set_volume(float volume)
545 {
546         g_volume_db = volume;
547 }
548
549 float vc_mgr_core_get_volume()
550 {
551         return g_volume_db;
552 }
553
554 void vc_mgr_core_initialize_volume_variable()
555 {
556         g_volume_db = 0;
557         g_prev_volume_db = 0;
558         g_cur_volume_db = 0;
559 }
560
561 int vc_mgr_core_send_set_foreground(int pid, bool value)
562 {
563         vc_mgr_client_set_foreground(pid, value);
564
565         /* get authorized valid app */
566         int tmp_pid;
567         if (VC_ERROR_NONE != vc_mgr_client_get_valid_authorized_client(&tmp_pid)) {
568                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get authorized valid app");
569                 return VC_ERROR_INVALID_PARAMETER;
570         }
571
572         if (true == value) {
573                 /* compare & set valid */
574                 if (tmp_pid != pid) {
575                         SLOG(LOG_INFO, TAG_VCM, "Authority(%d) changed to invalid", tmp_pid);
576
577                         /* set authorized valid */
578                         if (true == vc_mgr_client_is_authorized_client(pid)) {
579                                 SLOG(LOG_DEBUG, TAG_VCM, "Authority(%d) change to valid", pid);
580                                 vc_mgr_client_set_valid_authorized_client(pid);
581                         } else {
582                                 SLOG(LOG_DEBUG, TAG_VCM, "No valid Authority");
583                                 vc_mgr_client_set_valid_authorized_client(-1);
584                         }
585                 }
586         } else {
587                 if (tmp_pid == pid) {
588                         SLOG(LOG_INFO, TAG_VCM, "Authority(%d) changed to invalid", tmp_pid);
589                         vc_mgr_client_set_valid_authorized_client(-1);
590                 }
591         }
592
593         return VC_ERROR_NONE;
594 }
595
596 /* for TTS feedback */
597 int vc_mgr_core_send_feedback_audio_format(int rate, vc_audio_channel_e channel, vc_audio_type_e audio_type)
598 {
599         vc_mgr_feedback_audio_format_cb callback = NULL;
600         void* user_data = NULL;
601
602         /* set global audio formats */
603         g_feedback_rate = rate;
604         g_feedback_audio_channel = channel;
605         g_feedback_audio_type = audio_type;
606
607         vc_mgr_client_get_feedback_audio_format_cb(&callback, &user_data);
608
609         if (NULL != callback) {
610                 vc_mgr_client_use_callback();
611                 callback(rate, channel, audio_type, user_data);
612                 vc_mgr_client_not_use_callback();
613                 SLOG(LOG_INFO, TAG_VCM, "TTS feedback audio format callback is called");
614         } else {
615                 SLOG(LOG_WARN, TAG_VCM, "[WARNING] TTS feedback audio format callback is null");
616         }
617
618         return VC_ERROR_NONE;
619 }
620
621 int vc_mgr_core_send_feedback_streaming(int pid, int utt_id, vc_feedback_event_e event, char* buffer, int len)
622 {
623         /* add feedback data */
624         vc_feedback_data_s* temp_feedback_data = NULL;
625         temp_feedback_data = (vc_feedback_data_s*)calloc(1, sizeof(vc_feedback_data_s));
626         RETVM_IF(NULL == temp_feedback_data, VC_ERROR_OUT_OF_MEMORY, TAG_VCM, "[ERROR] Out of memory");
627         SLOG(LOG_INFO, TAG_VCM, "[INFO] feedback streaming before queuing");
628
629         temp_feedback_data->data = NULL;
630         temp_feedback_data->rate = g_feedback_rate;
631         temp_feedback_data->data_size = 0;
632
633         if (0 < len) {
634                 temp_feedback_data->data = (char*)calloc(len + 5, sizeof(char));
635                 if (NULL != temp_feedback_data->data) {
636                         memcpy(temp_feedback_data->data, buffer, len);
637                         temp_feedback_data->data_size = len;
638                         SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG][memcpy] data(%p) size(%d)",
639                                         temp_feedback_data->data, temp_feedback_data->data_size);
640                 } else {
641                         SLOG(LOG_ERROR, TAG_VCM, "[ERROR] fail to allocate memory");
642                 }
643         } else {
644                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] feedback data is NULL");
645         }
646
647         temp_feedback_data->pid = pid;
648         temp_feedback_data->utt_id = utt_id;
649         temp_feedback_data->event = event;
650         temp_feedback_data->audio_type = g_feedback_audio_type;
651         temp_feedback_data->channel = g_feedback_audio_channel;
652
653         SLOG(LOG_INFO, TAG_VCM, "[INFO] add feedback data, pid(%d), utt_id(%d), event(%d), audio_type(%d), channel(%d)", pid, utt_id, event, g_feedback_audio_type, g_feedback_audio_channel);
654
655         int ret = vc_mgr_data_add_feedback_data(temp_feedback_data);
656         if (VC_ERROR_NONE != ret) {
657                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to add feedback data");
658                 if (NULL != temp_feedback_data->data) {
659                         free(temp_feedback_data->data);
660                         temp_feedback_data->data = NULL;
661                 }
662                 if (NULL != temp_feedback_data) {
663                         free(temp_feedback_data);
664                         temp_feedback_data = NULL;
665                 }
666         }
667
668         return ret;
669 }
670
671 /* Authority */
672 static bool __vc_mgr_core_check_demandable_client(int pid)
673 {
674         if (0 == g_slist_length(g_demandable_client_list)) {
675                 SLOG(LOG_WARN, TAG_VCM, "[WARNING] No demandable clients");
676                 return false;
677         }
678
679         char appid[1024] = {'\0', };
680         if (VC_ERROR_NONE != aul_app_get_appid_bypid(pid, appid, sizeof(appid) - 1)) {
681                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get callee appid by pid");
682                 return false;
683         }
684         SLOG(LOG_INFO, TAG_VCM, "[CHECK] Appid - %s", appid);
685
686         GSList *iter = NULL;
687         vc_demandable_client_s* temp_client;
688         iter = g_slist_nth(g_demandable_client_list, 0);
689
690         while (NULL != iter) {
691                 temp_client = iter->data;
692
693                 if (NULL != temp_client) {
694                         if (NULL != temp_client->appid) {
695                                 if (!strcmp(temp_client->appid, appid)) {
696                                         SLOG(LOG_DEBUG, TAG_VCM, "pid(%d) is available", pid);
697                                         return true;
698                                 }
699                         }
700                 }
701
702                 iter = g_slist_next(iter);
703         }
704
705         return false;
706 }
707
708 int vc_mgr_core_set_demandable_client_rule(const char* rule)
709 {
710         if (0 != vc_info_parser_set_demandable_client(rule)) {
711                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] rule is NOT valid");
712                 SLOG(LOG_DEBUG, TAG_VCM, "@@@");
713                 return VC_ERROR_INVALID_PARAMETER;
714         }
715
716         if (0 != vc_info_parser_get_demandable_clients(&g_demandable_client_list)) {
717                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get demandable clients");
718                 return VC_ERROR_OPERATION_FAILED;
719         }
720
721         return VC_ERROR_NONE;
722 }
723
724 int vc_mgr_core_request_auth_enable(int pid)
725 {
726         if (false == __vc_mgr_core_check_demandable_client(pid)) {
727                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Not demandable client");
728                 return VC_ERROR_INVALID_PARAMETER;
729         }
730
731         /* check already authorized */
732         if (true == vc_mgr_client_is_authorized_client(pid)) {
733                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Already authorized");
734                 return VC_ERROR_INVALID_PARAMETER;
735         }
736
737         /* add authorized list */
738         if (VC_ERROR_NONE != vc_mgr_client_add_authorized_client(pid)) {
739                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to add authorized client");
740                 return VC_ERROR_OPERATION_FAILED;
741         }
742
743         /* foreground check */
744         int fore_pid = 0;
745         if (VC_ERROR_NONE != vc_mgr_client_get_foreground(&fore_pid)) {
746                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get foreground");
747                 return VC_ERROR_OPERATION_FAILED;
748         }
749
750         if (pid == fore_pid) {
751                 vc_mgr_client_set_valid_authorized_client(pid);
752         }
753
754         return VC_ERROR_NONE;
755 }
756
757 int vc_mgr_core_request_auth_disable(int pid)
758 {
759         /* check authorized */
760         if (false == vc_mgr_client_is_authorized_client(pid)) {
761                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] No authorized");
762                 return VC_ERROR_INVALID_PARAMETER;
763         }
764
765         /* remove authorized list */
766         if (VC_ERROR_NONE != vc_mgr_client_remove_authorized_client(pid)) {
767                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to remove authorized client");
768                 return VC_ERROR_OPERATION_FAILED;
769         }
770
771         /* check authority valid */
772         if (true == vc_mgr_client_is_valid_authorized_client(pid)) {
773                 SLOG(LOG_DEBUG, TAG_VCM, "Valid authorized client is removed");
774                 if (VC_ERROR_NONE != vc_mgr_client_set_valid_authorized_client(-1)) {
775                         SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to set valid authorized client");
776                         return VC_ERROR_OPERATION_FAILED;
777                 }
778         }
779
780         return VC_ERROR_NONE;
781 }
782
783 static Eina_Bool __request_auth_start(void* data)
784 {
785         SLOG(LOG_INFO, TAG_VCM, "Request Start");
786
787         if (VC_ERROR_NONE != vc_mgr_client_set_start_by_client(true)) {
788                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to set start by client");
789         }
790
791         if (VC_ERROR_NONE != vc_mgr_start(false)) {
792                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Request start is failed");
793                 /* TODO - Error handling? */
794         }
795
796         if (VC_ERROR_NONE != vc_mgr_client_set_start_by_client(false)) {
797                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to set start by client");
798         }
799
800
801         return EINA_FALSE;
802 }
803
804 int vc_mgr_core_request_auth_start(int pid)
805 {
806         /* check authorized */
807         if (false == vc_mgr_client_is_valid_authorized_client(pid)) {
808                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] No valid authorized client");
809                 return VC_ERROR_INVALID_PARAMETER;
810         }
811
812         /* add timer for start recording */
813         ecore_timer_add(0, __request_auth_start, NULL);
814
815         return VC_ERROR_NONE;
816 }
817
818 static Eina_Bool __request_auth_stop(void* data)
819 {
820         SLOG(LOG_INFO, TAG_VCM, "Request Stop");
821
822         if (VC_ERROR_NONE != vc_mgr_stop()) {
823                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Request stop is failed");
824                 /* TODO - Error handling? */
825         }
826
827         return EINA_FALSE;
828 }
829
830 int vc_mgr_core_request_auth_stop(int pid)
831 {
832         /* check authorized */
833         if (false == vc_mgr_client_is_valid_authorized_client(pid)) {
834                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] No valid authorized client");
835                 return VC_ERROR_INVALID_PARAMETER;
836         }
837
838         /* add timer for start recording */
839         ecore_timer_add(0, __request_auth_stop, NULL);
840
841         return VC_ERROR_NONE;
842 }
843
844 static Eina_Bool __request_auth_cancel(void* data)
845 {
846         SLOG(LOG_INFO, TAG_VCM, "Request Cancel");
847
848         if (VC_ERROR_NONE != vc_mgr_cancel()) {
849                 SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Request cancel is failed");
850                 /* TODO - Error handling? */
851         }
852
853         return EINA_FALSE;
854 }
855
856 int vc_mgr_core_request_auth_cancel(int pid)
857 {
858         /* check authorized */
859         if (false == vc_mgr_client_is_valid_authorized_client(pid)) {
860                 SLOG(LOG_ERROR,  TAG_VCM, "[ERROR] No valid authorized client");
861                 return VC_ERROR_INVALID_PARAMETER;
862         }
863
864         /* add timer for start recording */
865         ecore_timer_add(0, __request_auth_cancel, NULL);
866
867         return VC_ERROR_NONE;
868 }