2 * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <app_control.h>
18 #include <app_manager.h>
20 #include <sound_manager.h>
22 #include "vc_cmd_db.h"
23 #include "vc_info_parser.h"
25 #include "vcd_server.h"
26 #include "vcd_server_data.h"
27 #include "vcd_client_data.h"
29 #include "vcd_engine_agent.h"
30 #include "vcd_config.h"
31 #include "vcd_recorder.h"
34 #include "voice_control_command_expand.h"
35 #include "voice_control_common.h"
37 #define CLIENT_CLEAN_UP_TIME 500
39 * VC Server static variable
41 static GList *g_proc_list = NULL;
43 static Ecore_Timer *g_restart_timer = NULL;
44 static Ecore_Timer *g_check_widget_client_timer = NULL;
45 static Ecore_Timer *g_check_client_timer = NULL;
47 static Ecore_Thread* g_tts_thread = NULL;
48 static int g_current_uid = -1;
49 static int g_current_utt_id = -1;
52 * @brief Enumerations of send event type.
55 VCD_SEND_EVENT_TYPE_TEXT, /**< send text event to vc engine*/
56 VCD_SEND_EVENT_TYPE_LIST_EVENT, /**< send list event to vc engine */
57 VCD_SEND_EVENT_TYPE_HAPTIC_EVENT /**< send haptic event to vc engine */
58 } vcd_send_event_type_e;
60 static int __vcd_server_launch_manager_app();
61 static int __start_internal_recognition();
64 * VC Server Internal Functions
66 static Eina_Bool __stop_by_silence(void *data)
68 SLOG(LOG_DEBUG, TAG_VCD, "@@@ Silence Detected ");
70 vcd_server_mgr_stop();
72 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
76 static Eina_Bool __cancel_by_interrupt(void *data)
78 SLOG(LOG_DEBUG, TAG_VCD, "@@@ Cancel by interrupt");
80 vcd_server_mgr_cancel();
82 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
86 static void __cancel_by_error(void *data)
88 SLOG(LOG_DEBUG, TAG_VCD, "@@@ Cancel by error");
90 vcd_server_mgr_cancel();
92 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
96 static Eina_Bool __restart_engine(void *data)
98 SLOG(LOG_DEBUG, TAG_VCD, "@@@ Restart by no result");
100 g_restart_timer = NULL;
102 /* Restart recognition */
103 int ret = vcd_engine_recognize_start(true);
105 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to restart recognition : result(%d)", ret);
109 SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Start engine");
111 vcd_recognition_mode_e mode = vcd_client_get_recognition_mode();
112 if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == mode || VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY == mode) {
113 vcd_config_set_service_state(VCD_STATE_RECORDING);
114 vcdc_send_service_state(VCD_STATE_RECORDING);
117 SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Restart recognition");
119 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
123 static int __server_recorder_callback(const void* data, const unsigned int length)
125 vcd_state_e state = vcd_config_get_service_state();
126 if (VCD_STATE_READY == state) {
127 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Ready state, but recording");
128 } else if (VCD_STATE_PROCESSING == state) {
132 vce_speech_detect_e speech_detected = VCE_SPEECH_DETECT_NONE;
135 ret = vcd_engine_recognize_audio(data, length, &speech_detected);
139 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set recording data to engine(%d)", ret);
140 ecore_timer_add(0, __cancel_by_interrupt, NULL);
141 /* Send error cb to manager */
142 if (VCE_ERROR_OUT_OF_NETWORK == ret) {
143 vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_TIMED_OUT, "Engine connection failed");
145 vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "Engine recognition failed");
150 if (VCE_SPEECH_DETECT_BEGIN == speech_detected) {
151 if (-1 != vcd_client_manager_get_pid()) {
152 /* Manager client is available */
153 if (0 != vcdc_send_speech_detected(vcd_client_manager_get_pid())) {
154 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send speech detected");
157 } else if (VCE_SPEECH_DETECT_END == speech_detected) {
158 if (VCD_RECOGNITION_MODE_STOP_BY_SILENCE == vcd_client_get_recognition_mode()) {
159 /* silence detected */
160 ecore_timer_add(0, __stop_by_silence, NULL);
161 } else if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == vcd_client_get_recognition_mode()) {
162 /* Stop engine recognition */
163 int ret = vcd_engine_recognize_stop();
165 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
167 vcd_config_set_service_state(VCD_STATE_PROCESSING);
168 vcdc_send_service_state(VCD_STATE_PROCESSING);
170 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Stop engine only by silence");
171 } else if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY == vcd_client_get_recognition_mode()) {
172 /* Stop engine recognition */
173 int ret = vcd_engine_recognize_stop();
175 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
183 void __server_recorder_interrupt_callback()
185 SLOG(LOG_DEBUG, TAG_VCD, "@@@ Cancel by sound interrupt");
187 ecore_timer_add(0, __cancel_by_interrupt, NULL);
189 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
192 static void __config_lang_changed_cb(const char* current_lang, void* user_data)
194 SLOG(LOG_DEBUG, TAG_VCD, "@@@ Change language ");
196 /* Current state is recording */
197 vcd_state_e state = vcd_config_get_service_state();
198 if (VCD_STATE_RECORDING == state || VCD_STATE_PROCESSING == state) {
199 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is 'Recording'. Cancel recognition");
200 vcd_server_mgr_cancel();
204 ret = vcd_engine_set_current_language(current_lang);
206 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set language of engine : %d", ret);
209 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
214 static void __config_foreground_changed_cb(int previous, int current, void* user_data)
216 SLOG(LOG_DEBUG, TAG_VCD, "@@@ Change foreground");
218 SLOG(LOG_DEBUG, TAG_VCD, "Foreground pid(%d)", current);
220 if (VC_NO_FOREGROUND_PID != current) {
221 /* Foreground app is changed */
222 vcd_state_e state = vcd_config_get_service_state();
223 if (VCD_STATE_RECORDING == state) {
224 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Foreground pid(%d) is changed. Cancel recognition", current);
225 ecore_timer_add(0, __cancel_by_interrupt, NULL);
229 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
234 static int __vcd_activate_app_by_appcontrol(const char* appid)
237 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
238 return VCD_ERROR_INVALID_PARAMETER;
242 app_control_h app_control = NULL;
243 ret = app_control_create(&app_control);
244 if (APP_CONTROL_ERROR_NONE == ret) {
246 ret = app_control_add_extra_data(app_control, "voice_launch", "get_result");
247 if (APP_CONTROL_ERROR_NONE != ret) {
248 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to add extra data, ret(%d)", ret);
249 app_control_destroy(app_control);
250 return VCD_ERROR_OPERATION_FAILED;
253 ret = app_control_set_app_id(app_control, appid);
254 if (APP_CONTROL_ERROR_NONE != ret) {
255 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set app id, ret(%d)", ret);
256 app_control_destroy(app_control);
257 return VCD_ERROR_OPERATION_FAILED;
259 // Sent launch request
260 ret = app_control_send_launch_request(app_control, NULL, NULL);
261 if (APP_CONTROL_ERROR_NONE != ret) {
262 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send launch request, ret(%d)", ret);
263 app_control_destroy(app_control);
264 return VCD_ERROR_OPERATION_FAILED;
266 // Destroy app control
267 ret = app_control_destroy(app_control);
268 if (APP_CONTROL_ERROR_NONE != ret) {
269 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to destroy, ret(%d)", ret);
270 return VCD_ERROR_OPERATION_FAILED;
273 return VCD_ERROR_NONE;
276 static int __vcd_resume_app(const char* appid)
278 app_context_h app_context = NULL;
279 int ret = app_manager_get_app_context(appid, &app_context);
280 if (APP_MANAGER_ERROR_NONE != ret) {
281 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get app_context, ret(%d), appid(%s)", ret, appid);
282 return VCD_ERROR_OPERATION_FAILED;
285 ret = app_manager_resume_app(app_context);
286 if (APP_MANAGER_ERROR_NONE != ret) {
287 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to resume app, ret(%d), appid(%s)", ret, appid);
288 return VCD_ERROR_OPERATION_FAILED;
290 return VCD_ERROR_NONE;
293 static bool __vcd_is_package_installed(const char* appid)
295 app_info_h app_info = NULL;
296 int ret = app_manager_get_app_info(appid, &app_info);
297 if (APP_MANAGER_ERROR_NONE != ret || NULL == app_info)
299 ret = app_info_destroy(app_info);
300 if (APP_MANAGER_ERROR_NONE != ret)
301 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to destroy app_info, ret(%d)", ret);
305 static bool __vcd_launch_app(const char* result)
307 if (NULL == result) {
308 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
309 return VCD_ERROR_INVALID_PARAMETER;
312 GSList* app_list = NULL;
313 if (0 != vc_db_get_appid_list(result, &app_list)) {
314 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] result text is NULL");
315 return VCD_ERROR_INVALID_PARAMETER;
318 if (0 != g_slist_length(app_list)) {
321 vc_deactivated_app_s* temp_app = NULL;
322 iter = g_slist_nth(app_list, 0);
324 while (NULL != iter) {
325 temp_app = iter->data;
327 if (NULL != temp_app) {
328 if (NULL != temp_app->appid) {
330 bool running = false;
331 ret = app_manager_is_running(temp_app->appid, &running);
332 if (APP_MANAGER_ERROR_NONE != ret) {
333 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to check running with appid(%s)", temp_app->appid);
334 free(temp_app->appid);
335 temp_app->appid = NULL;
338 return VCD_ERROR_OPERATION_FAILED;
340 if (false == running) {
341 int tmp_ret = __vcd_is_package_installed(temp_app->appid);
342 if (false == tmp_ret) {
343 SLOG(LOG_WARN, TAG_VCD, "[WARNING] app is not installed, appid(%s)", temp_app->appid);
345 ret = __vcd_activate_app_by_appcontrol(temp_app->appid);
347 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to activate app");
348 free(temp_app->appid);
349 temp_app->appid = NULL;
354 SLOG(LOG_ERROR, TAG_VCD, "Launch app: appid(%s) result(%s)", temp_app->appid, result);
357 ret = __vcd_resume_app(temp_app->appid);
359 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to resume app");
360 free(temp_app->appid);
361 temp_app->appid = NULL;
366 SLOG(LOG_ERROR, TAG_VCD, "Resume app: appid(%s) result(%s)", temp_app->appid, result);
368 free(temp_app->appid);
369 temp_app->appid = NULL;
374 iter = g_slist_next(iter);
379 return VCD_ERROR_NONE;
382 static Eina_Bool __vcd_send_selected_result(void *data)
384 GSList* pid_list = NULL;
385 const char* result = vcd_client_manager_get_result_text();
387 if (0 != vc_info_parser_get_result_pid_list(&pid_list, result)) {
388 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to get pid list. No result");
390 if (0 < g_slist_length(pid_list)) {
392 vc_cmd_s* temp_cmd = NULL;
397 iter = g_slist_nth(pid_list, 0);
398 while (NULL != iter) {
399 temp_cmd = iter->data;
401 if (NULL != temp_cmd && (pre_pid != temp_cmd->pid || pre_type == VC_COMMAND_TYPE_WIDGET || temp_cmd->type == VC_COMMAND_TYPE_WIDGET)) {
402 /* Launch deactivated several apps that is matched with result */
403 ret = __vcd_launch_app(result);
405 SLOG(LOG_ERROR, TAG_VCD, "Fail to launch or resume app, ret(%d) result(%s)", ret, result);
407 /* send result noti */
408 ret = vcdc_send_result(temp_cmd->pid, vcd_client_manager_get_pid(), temp_cmd->type);
410 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result, ret(%d)", ret);
413 SLOG(LOG_ERROR, TAG_VCD, "[Server] Send result : pid(%d) type(%d)", temp_cmd->pid, temp_cmd->type);
414 pre_pid = temp_cmd->pid;
415 pre_type = temp_cmd->type;
421 pid_list = g_slist_remove_link(pid_list, iter);
422 iter = g_slist_nth(pid_list, 0);
427 if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY != vcd_client_get_recognition_mode()) {
428 vcd_config_set_service_state(VCD_STATE_READY);
429 vcdc_send_service_state(VCD_STATE_READY);
435 int vcd_send_asr_result(vce_asr_result_event_e event, const char* asr_result, void *user_data)
437 int ret = __vcd_server_launch_manager_app();
439 SECURE_SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send ASR result : mgr_pid(%d), asr_result(%s)", vcd_client_manager_get_pid(), asr_result);
443 if (NULL != asr_result) {
444 SECURE_SLOG(LOG_DEBUG, TAG_VCD, "[Server] ASR result - Event(%d), Text(%s)", event, asr_result);
445 ret = vcdc_send_pre_result_to_manager(vcd_client_manager_get_pid(), event, asr_result);
447 SECURE_SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send ASR result : mgr_pid(%d), asr_result(%s)", vcd_client_manager_get_pid(), asr_result);
454 int vcd_send_specific_engine_result(const char* engine_app_id, const char* event, const char* result, void *user_info)
456 if (NULL != result) {
457 SLOG(LOG_DEBUG, TAG_VCD, "[Server] specific engine result - Event(%s), Text(%s)", event, result);
458 vcdc_send_specific_engine_result_to_manager(vcd_client_manager_get_pid(), engine_app_id, event, result);
461 return VCD_ERROR_NONE;
464 int vcd_send_nlg_result(const char* nlg_result, void *user_data)
466 int ret = __vcd_server_launch_manager_app();
468 SECURE_SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send dialog : mgr_pid(%d), nlg_result(%s)", vcd_client_manager_get_pid(), nlg_result);
472 SLOG(LOG_ERROR, TAG_VCD, "[Server] send dialog : mgr_pid(%d), nlg_result(%s)", vcd_client_manager_get_pid(), nlg_result);
473 ret = vcdc_send_dialog(vcd_client_manager_get_pid(), -1, nlg_result, NULL, 0); //0: VC_DIALOG_END
475 SECURE_SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send dialog : mgr_pid(%d), nlg_result(%s)", vcd_client_manager_get_pid(), nlg_result);
479 static void* __recorder_stop(void *data)
485 int vcd_send_result(vce_result_event_e event, int* result_id, int count, const char* all_result, const char* non_fixed_result, const char* nlu_result, const char* msg, int* user_info, void *user_data)
488 vcd_recognition_mode_e recognition_mode = vcd_client_get_recognition_mode();
490 if (VCD_STATE_PROCESSING != vcd_config_get_service_state()) {
491 if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY != recognition_mode) {
492 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not 'Processing' and mode is not 'Restart continuously'");
493 return VCD_ERROR_INVALID_STATE;
497 vc_info_parser_unset_result(vcd_client_manager_get_exclusive());
498 vcd_client_manager_set_result_text(all_result);
500 SECURE_SLOG(LOG_INFO, TAG_VCD, "[Server] Event(%d), Text(%s) Nonfixed(%s) Msg(%s) Result count(%d)",
501 event, all_result, non_fixed_result, msg, count);
503 SECURE_SLOG(LOG_ERROR, TAG_VCD, "[Server] NLU result(%s)", nlu_result);
506 /* if nlu_result is exist, Add command handle(is_action) into result list */
508 SLOG(LOG_DEBUG, TAG_VCD, "[Server] @ Get engine result @");
510 vc_cmd_s* temp_cmd = NULL;
511 vc_cmd_list_h vc_cmd_list = NULL;
513 if (0 != vc_cmd_list_create(&vc_cmd_list)) {
514 SLOG(LOG_INFO, TAG_VCD, "[Server] Fail to create command list");
515 vcd_client_manager_set_exclusive(false);
516 vcd_config_set_service_state(VCD_STATE_READY);
517 vcdc_send_service_state(VCD_STATE_READY);
518 return VCD_ERROR_NONE;
521 /* priority filter */
522 /* system > exclusive > widget > foreground > system_background > widget partial > foreground partial > background */
524 int* filtered_id = (int*)calloc(count, sizeof(int));
526 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to allocate memory");
527 vc_cmd_list_destroy(vc_cmd_list, true);
528 return VCD_ERROR_OUT_OF_MEMORY;
530 int filtered_count = 0;
531 int top_priority = VC_COMMAND_PRIORITY_BACKGROUND;
532 for (i = 0; i < count; i++) {
533 SLOG(LOG_INFO, TAG_VCD, "[Server] [%d] Result id(%d)", i, result_id[i]);
535 if (0 > result_id[i]) {
536 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Result ID(%d) is NOT valid", result_id[i]);
540 ret = vcd_client_get_cmd_from_result_id(result_id[i], &temp_cmd);
541 if (0 == ret && NULL != temp_cmd) {
542 if (top_priority == temp_cmd->priority) {
543 filtered_id[filtered_count] = result_id[i];
545 } else if (top_priority > temp_cmd->priority) {
546 filtered_id[0] = result_id[i];
548 top_priority = temp_cmd->priority;
551 vc_cmd_destroy((vc_cmd_h)temp_cmd);
557 if (top_priority >= VC_COMMAND_PRIORITY_WIDGET) {
558 int pid = vcd_client_widget_get_foreground_pid();
560 if (NULL != all_result) {
561 vc_info_parser_set_result(all_result, event, msg, NULL, false);
563 vcd_client_widget_get_asr_result_enabled(pid, &enable);
564 if (true == enable) {
565 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Send ASR result to Widget client");
566 bool is_consumed = false;
567 if (NULL != user_info) {
570 if (0 != vcdc_send_asr_result(pid, event, all_result, VC_COMMAND_TYPE_WIDGET, &is_consumed)) {
571 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send asr result");
573 SLOG(LOG_DEBUG, TAG_VCD, "[Server] ASR result is consumed(%d)", is_consumed);
574 if (true == is_consumed) {
575 if (NULL != user_info) {
577 SLOG(LOG_ERROR, TAG_VCD, "[Server] Send whether ASR result is consumed or not (%d)", *user_info);
579 vcdc_send_show_tooltip(pid, false);
580 if (-1 != vcd_client_manager_get_pid()) {
581 /* Manager client is available */
582 vc_info_parser_unset_result(false);
583 vc_info_parser_set_result(all_result, VC_RESULT_EVENT_RESULT_SUCCESS, msg, NULL, false);
584 if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION)) {
585 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
589 // Set state manually, because the result is already handled in ASR result by client.
590 // So, the daemon does not need to send the result to client.
591 vcd_client_manager_set_exclusive(false);
593 vcd_config_set_service_state(VCD_STATE_READY);
594 vcdc_send_service_state(VCD_STATE_READY);
595 vc_cmd_list_destroy(vc_cmd_list, true);
596 if (NULL != filtered_id) {
600 return VCD_ERROR_NONE;
609 for (i = 0; i < filtered_count; i++) {
610 SLOG(LOG_INFO, TAG_VCD, "[Server] [%d] Filtered Result id(%d)", i, filtered_id[i]);
612 if (filtered_id[i] < 0) {
613 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Filtered ID(%d) is NOT valid", filtered_id[i]);
617 ret = vcd_client_get_cmd_from_result_id(filtered_id[i], &temp_cmd);
618 if (0 == ret && NULL != temp_cmd) {
619 switch (temp_cmd->format) {
620 case VC_CMD_FORMAT_FIXED:
621 case VC_CMD_FORMAT_FIXED_AND_VFIXED:
622 case VC_CMD_FORMAT_VFIXED_AND_FIXED:
623 case VC_CMD_FORMAT_PARTIAL:
624 case VC_CMD_FORMAT_FIXED_AND_NONFIXED:
625 case VC_CMD_FORMAT_NONFIXED_AND_FIXED:
627 case VC_CMD_FORMAT_ACTION:
631 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Unknown command type : %d", temp_cmd->type);
635 if (0 != vc_cmd_list_add(vc_cmd_list, (vc_cmd_h)temp_cmd)) {
636 SLOG(LOG_DEBUG, TAG_VCD, "Fail to add command to list");
637 vc_cmd_destroy((vc_cmd_h)temp_cmd);
641 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] NOT found matched result(%d)", filtered_id[i]);
645 if (NULL != filtered_id) {
650 if (NULL != nlu_result) {
651 SECURE_SLOG(LOG_INFO, TAG_VCD, "[Server] NLU (%s)", nlu_result);
652 vc_info_parser_set_nlu_result(nlu_result);
653 if (0 == is_action) {
655 if (0 != vc_cmd_create(&nlu_cmd)) {
656 SLOG(LOG_ERROR, TAG_VCD, "Fail to nlu cmd create");
658 if (0 != vc_cmd_set_type(nlu_cmd, VC_COMMAND_TYPE_SYSTEM)) {
659 SLOG(LOG_ERROR, TAG_VCD, "Fail to set type");
661 if (0 != vc_cmd_set_pid(nlu_cmd, vcd_client_manager_get_pid())) {
662 SLOG(LOG_ERROR, TAG_VCD, "Fail to set pid");
664 if (0 != vc_cmd_set_format(nlu_cmd, VC_CMD_FORMAT_ACTION)) {
665 SLOG(LOG_ERROR, TAG_VCD, "Fail to set format");
667 if (0 != vc_cmd_list_add(vc_cmd_list, nlu_cmd)) {
668 SLOG(LOG_ERROR, TAG_VCD, "Fail to add nlu cmd to list");
669 vc_cmd_destroy(nlu_cmd);
675 vc_cmd_print_list(vc_cmd_list);
677 SLOG(LOG_DEBUG, TAG_VCD, "[Server] @@@@");
679 int result_count = 0;
680 vc_cmd_list_get_count(vc_cmd_list, &result_count);
682 /* Handle the result list */
683 if (0 == result_count) {
685 vc_cmd_list_h widget_cmd_list = NULL;
686 vc_cmd_list_h foreground_cmd_list = NULL;
687 if (NULL != all_result) {
688 SECURE_SLOG(LOG_DEBUG, TAG_VCD, "[Server] Engine result is no command : %s", all_result);
691 if (0 != vc_cmd_list_create(&widget_cmd_list)) {
692 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create widget command list handle");
693 vc_cmd_list_destroy(vc_cmd_list, true);
694 return VCD_ERROR_OUT_OF_MEMORY;
697 /* Get the list of widget type commands */
698 vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_WIDGET, widget_cmd_list);
699 vc_cmd_list_get_count(widget_cmd_list, &cnt);
701 /* Matched with widget command partially */
702 vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, vc_cmd_list, VC_SEARCH_NONE_LEVEL);
703 vc_cmd_list_get_count(vc_cmd_list, &cnt);
705 top_priority = VC_COMMAND_PRIORITY_WIDGET;
706 SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched widget command");
709 if (0 != vc_cmd_list_create(&foreground_cmd_list)) {
710 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create foreground command list handle");
711 vc_cmd_list_destroy(vc_cmd_list, true);
712 vc_cmd_list_destroy(widget_cmd_list, true);
713 return VCD_ERROR_OUT_OF_MEMORY;
716 /* Get the list of foreground type commands */
717 vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_FOREGROUND, foreground_cmd_list);
718 vc_cmd_list_get_count(foreground_cmd_list, &cnt);
720 /* Matched with foreground command partially */
721 vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, vc_cmd_list, VC_SEARCH_NONE_LEVEL);
722 vc_cmd_list_get_count(vc_cmd_list, &cnt);
724 top_priority = VC_COMMAND_PRIORITY_FOREGROUND;
725 SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched foreground command");
728 vc_cmd_list_destroy(foreground_cmd_list, true);
730 vc_cmd_list_destroy(widget_cmd_list, true);
732 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Engine result is NULL");
735 vc_cmd_list_get_count(vc_cmd_list, &result_count);
737 // After running partial matching algorithm, if there is no result.
738 if (0 == result_count) {
739 SLOG(LOG_DEBUG, TAG_VCD, "[Server] No commands even after partial matching");
741 bool temp = vcd_client_manager_get_exclusive();
742 vc_info_parser_set_result(all_result, event, msg, NULL, temp);
744 int pid = vcd_client_widget_get_foreground_pid();
746 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
747 /* Send to hide tooltip */
748 vcdc_send_show_tooltip(pid, false);
751 if (-1 != vcd_client_manager_get_pid()) {
752 /* Manager client is available */
753 if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
754 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
758 vcd_client_manager_set_exclusive(false);
759 vc_cmd_list_destroy(vc_cmd_list, true);
761 return VCD_ERROR_NONE;
764 // Partial matching algorithm find some commands
765 event = VC_RESULT_EVENT_RESULT_SUCCESS;
768 // There are more than one result.
769 if (false == vcd_client_manager_get_exclusive()) {
770 vc_cmd_list_h temp_list = NULL;
772 /* Foreground, Widget, Background, System, System-Background */
773 if (top_priority >= VC_COMMAND_PRIORITY_BACKGROUND) {
774 vc_cmd_list_h widget_cmd_list = NULL;
775 vc_cmd_list_h foreground_cmd_list = NULL;
778 if (0 != vc_cmd_list_create(&temp_list)) {
779 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create widget command list handle");
780 vc_cmd_list_destroy(vc_cmd_list, true);
781 return VCD_ERROR_OUT_OF_MEMORY;
784 if (0 != vc_cmd_list_create(&widget_cmd_list)) {
785 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create widget command list handle");
786 vc_cmd_list_destroy(vc_cmd_list, true);
787 vc_cmd_list_destroy(temp_list, true);
788 return VCD_ERROR_OUT_OF_MEMORY;
791 /* Get the list of widget type commands */
792 vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_WIDGET, widget_cmd_list);
793 vc_cmd_list_get_count(widget_cmd_list, &cnt);
795 /* Matched with widget command partially */
796 vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, temp_list, VC_SEARCH_NONE_LEVEL);
797 vc_cmd_list_get_count(temp_list, &cnt);
799 if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) {
800 SLOG(LOG_WARN, TAG_VCD, "[WARNING] Fail to destroy list");
802 vc_cmd_list = temp_list;
803 top_priority = VC_COMMAND_PRIORITY_WIDGET;
804 event = VC_RESULT_EVENT_RESULT_SUCCESS;
805 SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched widget command when background cmd exists");
808 if (0 != vc_cmd_list_create(&foreground_cmd_list)) {
809 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create foreground command list handle");
810 vc_cmd_list_destroy(vc_cmd_list, true);
811 vc_cmd_list_destroy(widget_cmd_list, true);
812 return VCD_ERROR_OUT_OF_MEMORY;
815 /* Get the list of foreground type commands */
816 vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_FOREGROUND, foreground_cmd_list);
817 vc_cmd_list_get_count(foreground_cmd_list, &cnt);
819 /* Matched with foreground command partially */
820 vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, temp_list, VC_SEARCH_NONE_LEVEL);
821 vc_cmd_list_get_count(temp_list, &cnt);
823 if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) {
824 SLOG(LOG_WARN, TAG_VCD, "[WARNING] Fail to destroy list");
826 vc_cmd_list = temp_list;
827 top_priority = VC_COMMAND_PRIORITY_FOREGROUND;
828 event = VC_RESULT_EVENT_RESULT_SUCCESS;
829 SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched foreground command when background cmd exists");
832 vc_cmd_list_destroy(foreground_cmd_list, true);
834 vc_cmd_list_destroy(widget_cmd_list, true);
837 int pid = vcd_client_widget_get_foreground_pid();
839 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
840 vcdc_send_show_tooltip(pid, false);
843 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, false);
844 vc_cmd_list_destroy(vc_cmd_list, true);
846 if (-1 != vcd_client_manager_get_pid()) {
847 /* Manager client is available */
848 if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
849 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
852 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available. Send result to client directly");
853 ecore_timer_add(0, __vcd_send_selected_result, NULL);
856 /* exclusive command */
857 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, true);
858 vc_cmd_list_destroy(vc_cmd_list, true);
860 if (-1 != vcd_client_manager_get_pid()) {
861 /* Manager client is available */
862 if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
863 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
866 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Manager is NOT available");
869 vcd_client_manager_set_exclusive(false);
872 if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == recognition_mode) {
873 if (VCE_RESULT_EVENT_REJECTED == event) {
874 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Restart by no or rejected result");
875 /* If no result and restart option is ON */
876 /* Send reject message */
877 bool temp = vcd_client_manager_get_exclusive();
878 vc_info_parser_set_result(all_result, event, msg, NULL, temp);
879 ret = vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION);
881 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
884 g_restart_timer = ecore_timer_add(0, __restart_engine, NULL);
887 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Stop recorder due to success");
888 //vcd_recorder_stop();
889 ecore_main_loop_thread_safe_call_sync(__recorder_stop, NULL);
890 } else if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY == recognition_mode) {
891 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Restart continuously");
892 /* Restart option is ON */
893 g_restart_timer = ecore_timer_add(0, __restart_engine, NULL);
894 if (VCE_RESULT_EVENT_REJECTED == event) {
895 bool temp = vcd_client_manager_get_exclusive();
896 vc_info_parser_set_result(all_result, event, msg, NULL, temp);
897 ret = vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION);
899 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
905 return VCD_ERROR_NONE;
909 if (NULL == result_id) {
911 if (NULL != all_result) {
912 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Engine result is no command : %s", all_result);
913 bool temp = vcd_client_manager_get_exclusive();
914 vc_info_parser_set_result(all_result, event, msg, NULL, temp);
917 int pid = vcd_client_widget_get_foreground_pid();
919 if (NULL != all_result) {
920 /* Send result text to widget */
921 vcdc_send_result(pid, vcd_client_manager_get_pid(), VC_COMMAND_TYPE_WIDGET);
924 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
925 /* Send to hide tooltip */
926 vcdc_send_show_tooltip(pid, false);
929 if (-1 != vcd_client_manager_get_pid()) {
930 /* Manager client is available */
931 if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
932 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
936 vcd_client_manager_set_exclusive(false);
942 SLOG(LOG_DEBUG, TAG_VCD, "[Server] @ Get engine result @");
945 vc_cmd_s* temp_cmd = NULL;
946 vc_cmd_list_h vc_cmd_list = NULL;
948 if (0 != vc_cmd_list_create(&vc_cmd_list)) {
949 SLOG(LOG_ERROR, TAG_VCD, "[Server] Fail to create command list");
950 vcd_client_manager_set_exclusive(false);
951 vcd_config_set_service_state(VCD_STATE_READY);
952 vcdc_send_service_state(VCD_STATE_READY);
957 for (i = 0; i < count; i++) {
958 SLOG(LOG_DEBUG, TAG_VCD, "[Server] [%d] Result ID(%d)", i, result_id[i]);
960 if (result_id[i] < 0) {
961 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Result ID(%d) is NOT valid", result_id[i]);
965 ret = vcd_client_get_cmd_from_result_id(result_id[i], &temp_cmd);
966 if (0 == ret && NULL != temp_cmd) {
967 switch (temp_cmd->format) {
968 case VC_CMD_FORMAT_FIXED:
969 case VC_CMD_FORMAT_FIXED_AND_VFIXED:
970 case VC_CMD_FORMAT_VFIXED_AND_FIXED:
971 case VC_CMD_FORMAT_PARTIAL:
972 /* Nonfixed result is NOT valid */
974 case VC_CMD_FORMAT_FIXED_AND_NONFIXED:
975 if (NULL == temp_cmd->parameter) {
976 if (NULL != non_fixed_result) {
977 temp_cmd->parameter = strdup(non_fixed_result);
980 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Command type is NOT valid. Parameter (%s)", temp_cmd->parameter);
983 case VC_CMD_FORMAT_NONFIXED_AND_FIXED:
984 if (NULL == temp_cmd->command) {
985 if (NULL != non_fixed_result) {
986 temp_cmd->command = strdup(non_fixed_result);
989 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Command type is NOT valid. Command (%s)", temp_cmd->command);
994 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Unknown command type : %d", temp_cmd->type);
998 if (0 != vc_cmd_list_add(vc_cmd_list, (vc_cmd_h)temp_cmd)) {
999 SLOG(LOG_DEBUG, TAG_VCD, "Fail to add command to list");
1000 vc_cmd_destroy((vc_cmd_h)temp_cmd);
1003 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] NOT found matched result(%d)", result_id[i]);
1007 vc_cmd_print_list(vc_cmd_list);
1009 SLOG(LOG_DEBUG, TAG_VCD, "[Server] @@@@");
1011 int result_count = 0;
1012 vc_cmd_list_get_count(vc_cmd_list, &result_count);
1014 if (false == vcd_client_manager_get_exclusive()) {
1015 int pid = vcd_client_widget_get_foreground_pid();
1017 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
1018 vcdc_send_show_tooltip(pid, false);
1021 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, false);
1023 if (-1 != vcd_client_manager_get_pid()) {
1024 /* Manager client is available */
1025 if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
1026 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
1029 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available. Send result to client directly");
1030 /* Send result to client */
1031 ecore_timer_add(0, __vcd_send_selected_result, NULL);
1034 /* exclusive command */
1035 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, true);
1037 if (-1 != vcd_client_manager_get_pid()) {
1038 /* Manager client is available */
1039 if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
1040 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
1043 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Manager is NOT available");
1046 vcd_client_manager_set_exclusive(false);
1049 vc_cmd_list_destroy(vc_cmd_list, true);
1056 static void __vcd_server_nlu_result_cb(vce_result_event_e event, const char* nlu_result, void *user_data)
1058 SECURE_SLOG(LOG_DEBUG, TAG_VCD, "[Server] NLU result cb - event(%d)", event);
1059 SECURE_SLOG(LOG_DEBUG, TAG_VCD, "[Server] result (%s)", nlu_result);
1061 int ret = vc_info_parser_set_nlu_result(nlu_result);
1063 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set nlu result (%d)", ret);
1070 int vcd_send_error(vce_error_e error, const char* msg, void *user_data)
1072 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Engine Error cb - reason(%d), msg(%s)", error, msg);
1073 ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
1075 char* error_msg = NULL;
1077 error_msg = strdup(msg);
1078 if (NULL == error_msg) {
1079 return VCD_ERROR_OUT_OF_MEMORY;
1083 int ret = VCD_ERROR_NONE;
1084 ret = vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), error, error_msg);
1085 if (VCD_ERROR_NONE != ret) {
1086 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send error signal");
1089 if (NULL != error_msg) {
1097 /* for TTS feedback */
1098 int vcd_send_feedback_audio_format(int rate, vce_audio_channel_e channel, vce_audio_type_e audio_type)
1100 SLOG(LOG_INFO, TAG_VCD, "[Server DEBUG] Engine - Send TTS feedback audio format");
1102 /* send TTS feedback audio format to VC manager */
1103 int ret = VCD_ERROR_NONE;
1104 int pid = g_current_uid / 1000;
1105 if (-1 == g_current_uid || vcd_client_manager_get_pid() == pid) {
1106 ret = vcdc_send_feedback_audio_format_to_manager(vcd_client_manager_get_pid(), rate, channel, audio_type);
1107 if (VCD_ERROR_NONE != ret) {
1108 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send TTS feedback audio format to VC manager");
1111 SLOG(LOG_INFO, TAG_VCD, "[Server INFO] Do not send TTS feedback audio format to VC manager");
1117 int vcd_send_feedback_streaming(vce_feedback_event_e event, char* buffer, int len)
1119 if (-1 == g_current_uid && VCE_FEEDBACK_EVENT_START == event) {
1120 g_current_utt_id = (g_current_utt_id + 1) % 1000;
1121 g_current_uid = vcd_client_manager_get_pid() * 1000 + g_current_utt_id;
1122 SLOG(LOG_INFO, TAG_VCD, "[Server info] set current uid and utt_id as manager pid");
1125 int ret = VCD_ERROR_NONE;
1126 int pid = g_current_uid / 1000;
1127 int utt_id = g_current_uid % 1000;
1129 SLOG(LOG_INFO, TAG_VCD, "[Server DEBUG] Engine - Send TTS feedback streaming to pid(%d), is_mgr_client(%d)", pid, (pid == vcd_client_manager_get_pid() ? true : false));
1131 if (pid == vcd_client_manager_get_pid()) {
1132 /* send TTS feedback streaming to manager client */
1133 ret = vcdc_send_feedback_streaming_to_manager(vcd_client_manager_get_pid(), pid, utt_id, event, buffer, len);
1134 if (VCD_ERROR_NONE != ret) {
1135 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send TTS feedback streaming to manager client");
1138 /* send TTS feedback streaming to client */
1139 ret = vcdc_send_feedback_streaming(pid, utt_id, event, buffer, len);
1140 if (VCD_ERROR_NONE != ret) {
1141 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send TTS feedback streaming to client");
1145 if (VCE_FEEDBACK_EVENT_FINISH == event) {
1146 /* reset current uid */
1154 * vcd server Interfaces
1156 static void __vcd_file_clean_up()
1158 SLOG(LOG_DEBUG, TAG_VCD, "== Old file clean up == ");
1161 struct dirent *dirp = NULL;
1163 dp = opendir(VC_RUNTIME_INFO_ROOT);
1165 SLOG(LOG_ERROR, TAG_VCD, "[File message WARN] Fail to open path : %s", VC_RUNTIME_INFO_ROOT);
1169 char remove_path[256] = {0, };
1174 if (!strncmp("vc_", dirp->d_name, strlen("vc_"))) {
1175 memset(remove_path, 0, 256);
1176 snprintf(remove_path, 256, "%s/%s", VC_RUNTIME_INFO_ROOT, dirp->d_name);
1179 if (0 != remove(remove_path)) {
1180 SLOG(LOG_WARN, TAG_VCD, "[File message WARN] Fail to remove file : %s", remove_path);
1182 SLOG(LOG_DEBUG, TAG_VCD, "[File message] Remove file : %s", remove_path);
1186 } while (NULL != dirp);
1193 static int __vcd_db_clean_up()
1196 int cnt = VC_COMMAND_TYPE_FOREGROUND;
1198 if (VC_COMMAND_TYPE_BACKGROUND != cnt)
1199 ret = vc_db_delete_commands(-1, cnt, NULL);
1200 } while (VC_COMMAND_TYPE_EXCLUSIVE >= ++cnt);
1205 int vcd_initialize(vce_request_callback_s *callback)
1209 /* Remove old file */
1210 __vcd_file_clean_up();
1212 /* initialize modules */
1213 ret = vcd_config_initialize(__config_lang_changed_cb, __config_foreground_changed_cb, NULL);
1215 SLOG(LOG_ERROR, TAG_VCD, "[Server WARNING] Fail to initialize config.");
1218 /* Remove db data */
1219 ret = __vcd_db_clean_up();
1221 SLOG(LOG_ERROR, TAG_VCD, "[Server WARNING] Fail to remove db data");
1224 vcd_config_set_service_state(VCD_STATE_NONE);
1226 ret = vcd_engine_agent_init();
1228 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
1232 if (0 != vcd_recorder_create(__server_recorder_callback, __server_recorder_interrupt_callback)) {
1233 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to create recorder");
1234 return VCD_ERROR_OPERATION_FAILED;
1238 if (0 != vcd_engine_agent_load_current_engine(callback)) {
1239 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to load current engine");
1240 return VCD_ERROR_OPERATION_FAILED;
1243 /* Initialize manager info */
1244 vcd_client_manager_unset();
1246 vcd_config_set_service_state(VCD_STATE_READY);
1247 // vcdc_send_service_state(VCD_STATE_READY);
1249 /* Set timer cleanup client all */
1250 g_check_client_timer = ecore_timer_add(CLIENT_CLEAN_UP_TIME, vcd_cleanup_client_all, NULL);
1251 if (NULL == g_check_client_timer) {
1252 SLOG(LOG_WARN, TAG_VCD, "[Server Warning] Fail to create timer of client check");
1256 g_current_utt_id = -1;
1258 SLOG(LOG_ERROR, TAG_VCD, "[Server SUCCESS] initialize");
1266 if (0 < g_list_length(g_proc_list)) {
1267 iter = g_list_first(g_proc_list);
1268 while (NULL != iter) {
1269 g_proc_list = g_list_remove_link(g_proc_list, iter);
1270 iter = g_list_first(g_proc_list);
1274 if (NULL != g_restart_timer) {
1275 ecore_timer_del(g_restart_timer);
1276 g_restart_timer = NULL;
1279 if (NULL != g_check_client_timer) {
1280 ecore_timer_del(g_check_client_timer);
1281 g_check_client_timer = NULL;
1284 vcd_state_e state = vcd_config_get_service_state();
1285 if (VCD_STATE_READY != state) {
1286 if (VCD_STATE_RECORDING == state) {
1287 vcd_recorder_stop();
1289 vcd_engine_recognize_cancel();
1292 if (0 != vcd_recorder_destroy()) {
1293 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to destroy recorder");
1296 SLOG(LOG_DEBUG, TAG_VCD, "[Server] destroy recorder");
1299 if (0 != vcd_engine_agent_release()) {
1300 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to release engine");
1303 SLOG(LOG_DEBUG, TAG_VCD, "[Server] release engine");
1306 vcd_client_manager_unset_appid();
1308 vcd_config_set_service_state(VCD_STATE_NONE);
1309 vcdc_send_service_state(VCD_STATE_NONE);
1311 SLOG(LOG_ERROR, TAG_VCD, "[Server] mode finalize");
1316 static Eina_Bool __finalize_quit_ecore_loop(void *data)
1318 bool ret = vcd_finalize();
1322 ecore_main_loop_quit();
1327 static void __read_proc()
1330 struct dirent *dirp = NULL;
1334 if (0 < g_list_length(g_proc_list)) {
1335 iter = g_list_first(g_proc_list);
1336 while (NULL != iter) {
1337 g_proc_list = g_list_remove_link(g_proc_list, iter);
1338 iter = g_list_first(g_proc_list);
1342 dp = opendir("/proc");
1344 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to open proc");
1350 tmp = atoi(dirp->d_name);
1351 if (0 >= tmp) continue;
1352 g_proc_list = g_list_append(g_proc_list, GINT_TO_POINTER(tmp));
1354 } while (NULL != dirp);
1360 static void __vcd_cleanup_client(vcd_client_type_e type)
1362 int* client_list = NULL;
1363 int client_count = 0;
1370 if (VCD_CLIENT_TYPE_NORMAL == type) {
1371 ret = vcd_client_get_list(&client_list, &client_count);
1372 } else if (VCD_CLIENT_TYPE_WIDGET == type) {
1373 ret = vcd_client_widget_get_list(&client_list, &client_count);
1374 } else if (VCD_CLIENT_TYPE_MANAGER == type) {
1375 mgr_pid = vcd_client_manager_get_pid();
1376 client_list = &mgr_pid;
1378 if (-1 == mgr_pid) {
1379 SLOG(LOG_WARN, TAG_VCD, "[WARNING] Invalid Manager pid");
1384 if (0 == ret || mgr_pid > 0) {
1385 SLOG(LOG_DEBUG, TAG_VCD, "@@@ Clean up %s client ", type ? (type == 1) ? "Widget" : "Manager" : "Normal");
1386 if (NULL != client_list && client_count > 0) {
1387 for (i = 0; i < client_count; i++) {
1390 for (j = 0; j < g_list_length(g_proc_list); j++) {
1391 iter = g_list_nth(g_proc_list, j);
1393 if (*(client_list + i) == GPOINTER_TO_INT(iter->data)) {
1394 SLOG(LOG_DEBUG, TAG_VCD, "%s pid(%d) is running", type ? (type == 1) ? "Widget" : "Manager" : "Normal", *(client_list + i));
1401 if (false == exist) {
1402 SLOG(LOG_ERROR, TAG_VCD, "%s pid(%d) should be removed", type ? (type == 1) ? "Widget" : "Manager" : "Normal", *(client_list + i));
1403 if (VCD_CLIENT_TYPE_NORMAL == type)
1404 vcd_server_finalize(*(client_list + i));
1405 else if (VCD_CLIENT_TYPE_WIDGET == type)
1406 vcd_server_widget_finalize(*(client_list + i));
1408 vcd_server_mgr_finalize(mgr_pid);
1412 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
1414 if (NULL != client_list && -1 == mgr_pid) {
1421 Eina_Bool vcd_cleanup_client_all(void *data)
1425 __vcd_cleanup_client(VCD_CLIENT_TYPE_NORMAL);
1426 __vcd_cleanup_client(VCD_CLIENT_TYPE_WIDGET);
1427 __vcd_cleanup_client(VCD_CLIENT_TYPE_MANAGER);
1430 if (0 == vcd_client_get_list(&client_list, &client_count)) {
1431 SLOG(LOG_DEBUG, TAG_VCD, "@@@ Clean up client ");
1432 if (NULL != client_list && client_count > 0) {
1433 for (i = 0; i < client_count; i++) {
1436 for (j = 0; j < g_list_length(g_proc_list); j++) {
1437 iter = g_list_nth(g_proc_list, j);
1439 if (client_list[i] == GPOINTER_TO_INT(iter->data)) {
1440 SLOG(LOG_DEBUG, TAG_VCD, "pid(%d) is running", client_list[i]);
1447 if (false == exist) {
1448 SLOG(LOG_ERROR, TAG_VCD, "pid(%d) should be removed", client_list[i]);
1449 vcd_server_finalize(client_list[i]);
1452 result = vcdc_send_hello(client_list[i], VCD_CLIENT_TYPE_NORMAL);
1455 SLOG(LOG_DEBUG, TAG_VCD, "[Server] pid(%d) should be removed.", client_list[i]);
1456 vcd_server_finalize(client_list[i]);
1457 } else if (-1 == result) {
1458 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Hello result has error");
1463 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
1465 if (NULL != client_list) {
1470 /* If app is in background state, app cannot response message. */
1471 if (0 == vcd_client_widget_get_list(&client_list, &client_count)) {
1472 SLOG(LOG_DEBUG, TAG_VCD, "@@@ Clean up widget");
1473 if (NULL != client_list && client_count > 0) {
1474 for (i = 0; i < client_count; i++) {
1477 for (j = 0; j < g_list_length(g_proc_list); j++) {
1478 iter = g_list_nth(g_proc_list, j);
1480 if (client_list[i] == GPOINTER_TO_INT(iter->data)) {
1481 SLOG(LOG_DEBUG, TAG_VCD, "widget pid(%d) is running", client_list[i]);
1488 if (false == exist) {
1489 SLOG(LOG_ERROR, TAG_VCD, "widget pid(%d) should be removed", client_list[i]);
1490 vcd_server_widget_finalize(client_list[i]);
1493 result = vcdc_send_hello(client_list[i], VCD_CLIENT_TYPE_WIDGET);
1496 SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget pid(%d) should be removed.", client_list[i]);
1497 vcd_server_widget_finalize(client_list[i]);
1498 } else if (-1 == result) {
1499 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Hello result has error");
1504 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
1507 if (NULL != client_list) {
1515 int mgr_pid = vcd_client_manager_get_pid();
1517 for (j = 0; j < g_list_length(g_proc_list); j++) {
1518 iter = g_list_nth(g_proc_list, j);
1520 if (mgr_pid == GPOINTER_TO_INT(iter->data)) {
1521 SLOG(LOG_DEBUG, TAG_VCD, "manager pid(%d) is running", mgr_pid);
1528 if (false == exist) {
1529 SLOG(LOG_ERROR, TAG_VCD, "manager pid (%d) should be removed", mgr_pid);
1530 vcd_server_mgr_finalize(mgr_pid);
1537 int vcd_server_get_service_state()
1539 return vcd_config_get_service_state();
1542 int vcd_server_get_foreground()
1545 vcd_config_get_foreground(&pid);
1553 int vcd_server_mgr_initialize(int pid)
1555 /* check if pid is valid */
1556 if (false == vcd_client_manager_is_valid(pid)) {
1557 SLOG(LOG_ERROR, TAG_VCD, "[Server] old manager pid(%d) be removed", vcd_client_manager_get_pid());
1558 vcd_server_mgr_cancel();
1559 vcd_client_manager_unset();
1562 /* Add client information to client manager */
1563 if (0 != vcd_client_manager_set(pid)) {
1564 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add manager");
1565 return VCD_ERROR_OPERATION_FAILED;
1568 if (0 != vcdc_send_manager_pid(pid))
1569 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send manager pid");
1571 SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Manager initialize : pid(%d)", pid);
1573 return VCD_ERROR_NONE;
1576 int vcd_server_mgr_finalize(int pid)
1578 /* check if pid is valid */
1579 if (false == vcd_client_manager_is_valid(pid)) {
1580 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1581 return VCD_ERROR_INVALID_PARAMETER;
1584 /* Cancel recognition */
1585 vcd_server_mgr_cancel();
1587 if (0 != vcdc_send_manager_pid(-1))
1588 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send manager pid");
1590 /* Remove manager information */
1591 if (0 != vcd_client_manager_unset()) {
1592 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
1595 if (0 == vcd_client_get_ref_count()) {
1596 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Connected client list is empty");
1597 ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
1600 SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Manager Finalize : pid(%d)", pid);
1602 return VCD_ERROR_NONE;
1605 int vcd_server_mgr_set_command(int pid)
1607 if (0 != vcd_client_manager_set_command(pid)) {
1608 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1609 return VCD_ERROR_INVALID_PARAMETER;
1611 return VCD_ERROR_NONE;
1614 int vcd_server_mgr_unset_command(int pid)
1616 if (0 != vcd_client_manager_unset_command(pid)) {
1617 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1618 return VCD_ERROR_INVALID_PARAMETER;
1620 return VCD_ERROR_NONE;
1623 int vcd_server_mgr_set_demandable_client(int pid)
1625 /* check if pid is valid */
1626 if (false == vcd_client_manager_is_valid(pid)) {
1627 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1628 return VCD_ERROR_INVALID_PARAMETER;
1631 GSList* client_list = NULL;
1632 if (0 != vc_info_parser_get_demandable_clients(&client_list)) {
1633 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get demandable client");
1634 return VCD_ERROR_OPERATION_FAILED;
1637 /* Save client list */
1638 if (0 != vcd_client_manager_set_demandable_client(pid, client_list)) {
1639 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set demandable client list");
1640 return VCD_ERROR_OPERATION_FAILED;
1643 return VCD_ERROR_NONE;
1646 int vcd_server_mgr_set_audio_type(int pid, const char* audio_type)
1648 /* check if pid is valid */
1649 if (false == vcd_client_manager_is_valid(pid)) {
1650 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1651 return VCD_ERROR_INVALID_PARAMETER;
1655 vce_audio_type_e type = VCE_AUDIO_TYPE_PCM_S16_LE;
1659 ret = vcd_engine_get_audio_format(audio_type, &type, &rate, &channel);
1661 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio format : %d", ret);
1662 return VCD_ERROR_OPERATION_FAILED;
1665 ret = vcd_recorder_set(audio_type, type, rate, channel);
1667 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set audio in type : %d", ret);
1668 return VCD_ERROR_OPERATION_FAILED;
1671 return VCD_ERROR_NONE;
1674 int vcd_server_mgr_get_audio_type(int pid, char** audio_type)
1676 /* check if pid is valid */
1677 if (false == vcd_client_manager_is_valid(pid)) {
1678 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1679 return VCD_ERROR_INVALID_PARAMETER;
1682 int ret = vcd_recorder_get(audio_type);
1684 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio in type : %d", ret);
1685 return VCD_ERROR_OPERATION_FAILED;
1688 return VCD_ERROR_NONE;
1691 int vcd_server_mgr_set_client_info(int pid)
1693 /* check if pid is valid */
1694 if (false == vcd_client_manager_is_valid(pid)) {
1695 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1696 return VCD_ERROR_INVALID_PARAMETER;
1699 int ret = vcd_client_save_client_info();
1701 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to save client info : %d", ret);
1702 return VCD_ERROR_OPERATION_FAILED;
1705 return VCD_ERROR_NONE;
1708 static int __reset_waiting_for_widget_recording(void)
1710 SLOG(LOG_ERROR, TAG_VCD, "[Server] Reset waiting for widget recording");
1711 // Delete timer to check that widget client is terminated
1712 if (g_check_widget_client_timer) {
1713 ecore_timer_del(g_check_widget_client_timer);
1714 g_check_widget_client_timer = NULL;
1716 // Reset flag to wait for recording from widget client
1717 vcd_client_widget_set_waiting_for_recording(-1, false);
1722 static Eina_Bool __send_waiting_timeout_error_to_manager(void* data)
1724 intptr_t ppid = (intptr_t)data;
1725 int pid = (int)ppid;
1726 SLOG(LOG_ERROR, TAG_VCD, "Widget client didn't send to start recording, pid(%d)", pid);
1727 __reset_waiting_for_widget_recording();
1729 vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail");
1733 static Eina_Bool __send_waiting_timeout_start_recording(void* data)
1735 intptr_t ppid = (intptr_t)data;
1736 int pid = (int)ppid;
1737 SLOG(LOG_ERROR, TAG_VCD, "Widget client didn't send to start recording, pid(%d)", pid);
1739 int ret = __start_internal_recognition();
1741 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition : %d", ret);
1748 static int __set_waiting_for_widget_recording(int pid)
1750 SLOG(LOG_ERROR, TAG_VCD, "[Server] Set waiting for widget recording, pid(%d)", pid);
1752 // Check if the app included widget client is terminated or not. If it is terminated, vcd_server_widget_finalize() function will be called
1753 // In that function, it will start recording
1754 intptr_t ppid = (intptr_t)pid;
1755 g_check_widget_client_timer = ecore_timer_add(2.0, __send_waiting_timeout_start_recording, (void*)ppid);
1757 // Set flag to wait for recording from widget client
1758 vcd_client_widget_set_waiting_for_recording(pid, true);
1762 static int __start_internal_recognition()
1765 __reset_waiting_for_widget_recording();
1767 if (0 != vcd_client_command_collect_command()) {
1768 SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to collect command");
1769 /* Send error cb to manager */
1770 int pid = vcd_client_widget_get_foreground_pid();
1772 vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail");
1773 return VCD_ERROR_OPERATION_FAILED;
1776 /* 3. Set command to engine */
1777 ret = vcd_engine_set_commands();
1779 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set commands : %d", ret);
1780 /* Send error cb to manager */
1781 int pid = vcd_client_widget_get_foreground_pid();
1783 vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail");
1784 return VCD_ERROR_OPERATION_FAILED;
1787 SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Set command");
1789 bool stop_by_silence = true;
1790 if (VCD_RECOGNITION_MODE_MANUAL == vcd_client_get_recognition_mode()) {
1791 stop_by_silence = false;
1794 vcd_client_manager_set_result_text(NULL);
1796 /* 4. start recognition */
1797 ret = vcd_engine_recognize_start(stop_by_silence);
1799 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1800 /* Send error cb to manager */
1801 int pid = vcd_client_widget_get_foreground_pid();
1803 vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail");
1804 return VCD_ERROR_OPERATION_FAILED;
1807 SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Start engine");
1810 /* 5. recorder start */
1811 ret = vcd_recorder_start();
1813 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1814 vcd_engine_recognize_cancel();
1815 /* Send error cb to manager */
1816 int pid = vcd_client_widget_get_foreground_pid();
1818 vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail");
1823 vcd_config_set_service_state(VCD_STATE_RECORDING);
1824 vcdc_send_service_state(VCD_STATE_RECORDING);
1826 SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Start recognition(%d)", stop_by_silence);
1831 static Eina_Bool __vcd_request_show_tooltip(void *data)
1833 int pid = vcd_client_widget_get_foreground_pid();
1835 SLOG(LOG_ERROR, TAG_VCD, "[Server] Request tooltip show and widget command, show(%d)", (bool)data);
1836 vcdc_send_show_tooltip(pid, (bool)data);
1842 int vcd_server_mgr_start(vcd_recognition_mode_e recognition_mode, bool exclusive_cmd, bool start_by_client)
1844 /* 1. check current state */
1845 vcd_state_e state = vcd_config_get_service_state();
1847 if (VCD_STATE_READY != state) {
1848 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
1849 return VCD_ERROR_INVALID_STATE;
1851 if (-1 == vcd_client_manager_get_pid()) {
1852 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available.");
1853 return VCD_ERROR_OPERATION_FAILED;
1855 __reset_waiting_for_widget_recording();
1857 SLOG(LOG_ERROR, TAG_VCD, "[Server] set recognition mode = %d", recognition_mode);
1858 vcd_client_set_recognition_mode(recognition_mode);
1860 if (false == exclusive_cmd) {
1861 vcd_client_update_foreground_pid();
1862 /* Notify show tooltip */
1863 if (1 == vcd_config_get_command_type_enabled(VC_COMMAND_TYPE_WIDGET)) {
1864 int pid = vcd_client_widget_get_foreground_pid();
1866 SLOG(LOG_ERROR, TAG_VCD, "[Server] Request tooltip show and widget command");
1867 ecore_timer_add(0, __vcd_request_show_tooltip, (void*)true);
1869 __set_waiting_for_widget_recording(pid);
1874 vcd_client_manager_set_exclusive(exclusive_cmd);
1878 if (true == start_by_client) {
1879 /* Get foreground pid */
1880 if (0 != vcd_config_get_foreground(&fg_pid)) {
1881 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get foreground");
1884 /* Set client exclusive option */
1885 if (0 != vcd_client_set_exclusive_command(fg_pid)) {
1886 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set exclusive command");
1890 SLOG(LOG_ERROR, TAG_VCD, "[Server] start internal recognition");
1892 int ret = __start_internal_recognition();
1894 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition : %d", ret);
1898 if (true == start_by_client) {
1899 vcd_client_unset_exclusive_command(fg_pid);
1902 SLOG(LOG_ERROR, TAG_VCD, "[Server Success] start internal recognition");
1903 return VCD_ERROR_NONE;
1906 int vcd_server_mgr_stop()
1908 /* 1. Check current state is recording */
1909 if (VCD_STATE_RECORDING != vcd_config_get_service_state()) {
1910 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not recording");
1911 return VCD_ERROR_INVALID_STATE;
1913 if (-1 == vcd_client_manager_get_pid()) {
1914 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available.");
1915 return VCD_ERROR_OPERATION_FAILED;
1917 SLOG(LOG_ERROR, TAG_VCD, "[Server] stop internal recognition");
1920 /* 2. Stop recorder */
1921 vcd_recorder_stop();
1924 /* 3. Stop engine recognition */
1925 int ret = vcd_engine_recognize_stop();
1927 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
1930 /* 4. Set original mode */
1931 vcd_config_set_service_state(VCD_STATE_PROCESSING);
1932 vcdc_send_service_state(VCD_STATE_PROCESSING);
1934 SLOG(LOG_ERROR, TAG_VCD, "[Server Success] stop internal recognition");
1935 return VCD_ERROR_NONE;
1938 int vcd_server_mgr_cancel()
1940 if (-1 == vcd_client_manager_get_pid()) {
1941 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available.");
1942 return VCD_ERROR_OPERATION_FAILED;
1945 if (g_restart_timer != NULL) {
1946 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Delete restart engine timer");
1947 ecore_timer_del(g_restart_timer);
1948 g_restart_timer = NULL;
1951 /* 1. Check current state */
1952 vcd_state_e state = vcd_config_get_service_state();
1953 if (VCD_STATE_READY == state) {
1954 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is READY");
1955 vcd_recorder_stop();
1957 if (false == vcd_client_manager_get_exclusive()) {
1958 if (1 == vcd_config_get_command_type_enabled(VC_COMMAND_TYPE_WIDGET)) {
1959 int pid = vcd_client_widget_get_foreground_pid();
1961 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
1962 ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
1967 vcdc_send_service_state(VCD_STATE_READY);
1968 return VCD_ERROR_NONE;
1970 SLOG(LOG_ERROR, TAG_VCD, "[Server] cancel internal recognition");
1973 /* 2. Stop recorder */
1974 vcd_recorder_stop();
1977 /* 3. Cancel engine */
1978 int ret = vcd_engine_recognize_cancel();
1980 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to cancel : %d", ret);
1983 if (false == vcd_client_manager_get_exclusive()) {
1984 if (1 == vcd_config_get_command_type_enabled(VC_COMMAND_TYPE_WIDGET)) {
1985 int pid = vcd_client_widget_get_foreground_pid();
1987 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
1988 ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
1992 vcd_client_manager_set_exclusive(false);
1996 vcd_config_set_service_state(VCD_STATE_READY);
1997 vcdc_send_service_state(VCD_STATE_READY);
1999 SLOG(LOG_ERROR, TAG_VCD, "[Server Success] cancel internal recognition");
2000 return VCD_ERROR_NONE;
2004 int vcd_server_mgr_result_select()
2006 __vcd_send_selected_result(NULL);
2008 return VCD_ERROR_NONE;
2011 int vcd_server_mgr_set_domain(int pid, const char* domain)
2013 /* check if pid is valid */
2014 if (false == vcd_client_manager_is_valid(pid)) {
2015 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
2016 return VCD_ERROR_INVALID_PARAMETER;
2019 vcd_state_e state = vcd_config_get_service_state();
2020 if (VCD_STATE_READY != state) {
2021 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
2022 return VCD_ERROR_INVALID_STATE;
2025 /* Set domain to engine */
2026 int ret = vcd_engine_set_domain(pid, domain);
2028 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set domain : %d", ret);
2030 SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Set domain");
2036 int vcd_server_mgr_set_private_data(int pid, const char* key, const char* data)
2038 /* check if pid is valid */
2039 if (false == vcd_client_manager_is_valid(pid)) {
2040 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
2041 return VCD_ERROR_INVALID_PARAMETER;
2044 vcd_state_e state = vcd_config_get_service_state();
2045 if (VCD_STATE_READY != state) {
2046 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
2047 return VCD_ERROR_INVALID_STATE;
2050 /* Set private data to engine */
2051 int ret = vcd_engine_set_private_data(pid, key, data);
2053 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data : %d", ret);
2055 SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Set private data");
2061 int vcd_server_mgr_get_private_data(int pid, const char* key, char** data)
2063 /* check if pid is valid */
2064 if (false == vcd_client_manager_is_valid(pid)) {
2065 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
2066 return VCD_ERROR_INVALID_PARAMETER;
2068 vcd_state_e state = vcd_config_get_service_state();
2069 if (VCD_STATE_READY != state) {
2070 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
2071 return VCD_ERROR_INVALID_STATE;
2074 /* Get private data to engine */
2075 int ret = vcd_engine_get_private_data(pid, key, data);
2077 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get private data : %d", ret);
2079 SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Set private data");
2085 int vcd_server_mgr_send_specific_engine_request(int pid, const char* engine_app_id, const char* event, const char* request)
2087 /* check if pid is valid */
2088 if (false == vcd_client_manager_is_valid(pid)) {
2089 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
2090 return VCD_ERROR_INVALID_PARAMETER;
2092 vcd_state_e state = vcd_config_get_service_state();
2093 if (VCD_STATE_READY != state) {
2094 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
2095 return VCD_ERROR_INVALID_STATE;
2098 /* Get private data to engine */
2099 int ret = vcd_engine_send_specific_engine_request(engine_app_id, event, request);
2101 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set specific engine request : %d", ret);
2103 SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Set specific engine request ");
2109 int vcd_server_mgr_do_action(int pid, int type, const char* action)
2113 /* check if pid is valid */
2114 if (false == vcd_client_manager_is_valid(pid)) {
2115 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
2116 return VCD_ERROR_INVALID_PARAMETER;
2119 vcd_state_e state = vcd_config_get_service_state();
2120 if (VCD_STATE_READY != state) {
2121 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
2122 return VCD_ERROR_INVALID_STATE;
2125 /* Request do action to engine */
2126 if (VCD_SEND_EVENT_TYPE_TEXT == type)
2127 ret = vcd_engine_process_text(pid, action);
2128 else if (VCD_SEND_EVENT_TYPE_LIST_EVENT == type)
2129 ret = vcd_engine_process_list_event(pid, action);
2130 else if (VCD_SEND_EVENT_TYPE_HAPTIC_EVENT == type)
2131 ret = vcd_engine_process_haptic_event(pid, action);
2134 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to process do action : %d", ret);
2136 vcd_config_set_service_state(VCD_STATE_PROCESSING);
2137 vcdc_send_service_state(VCD_STATE_PROCESSING);
2138 SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Process do action");
2144 int vcd_server_mgr_enable_command_type(int pid, int cmd_type)
2148 /* check if pid is valid */
2149 if (false == vcd_client_manager_is_valid(pid)) {
2150 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
2151 return VCD_ERROR_INVALID_PARAMETER;
2154 vcd_state_e state = vcd_config_get_service_state();
2155 if (VCD_STATE_READY != state) {
2156 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
2157 return VCD_ERROR_INVALID_STATE;
2160 ret = vcd_config_enable_command_type(cmd_type);
2162 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to enable command type");
2164 SLOG(LOG_ERROR, TAG_VCD, "[Server] Enable command type(%d)", cmd_type);
2170 int vcd_server_mgr_disable_command_type(int pid, int cmd_type)
2174 /* check if pid is valid */
2175 if (false == vcd_client_manager_is_valid(pid)) {
2176 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
2177 return VCD_ERROR_INVALID_PARAMETER;
2180 vcd_state_e state = vcd_config_get_service_state();
2181 if (VCD_STATE_READY != state) {
2182 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
2183 return VCD_ERROR_INVALID_STATE;
2186 ret = vcd_config_disable_command_type(cmd_type);
2188 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to disable command type");
2190 SLOG(LOG_ERROR, TAG_VCD, "[Server] Disable command type(%d)", cmd_type);
2196 /* for TTS feedback */
2197 int vcd_server_mgr_start_feedback(void)
2199 /* check current state */
2200 /* not Recording??? */
2202 if (-1 == vcd_client_manager_get_pid()) {
2203 SLOG(LOG_ERROR, TAG_VCD, "[Server] Manager is NOT available");
2204 return VCD_ERROR_OPERATION_FAILED;
2207 SLOG(LOG_DEBUG, TAG_VCD, "[Server] start TTS feedback");
2209 /* check there is TTS buffer to be spoken */
2211 return VCD_ERROR_NONE;
2214 int vcd_server_mgr_stop_feedback(void)
2216 /* check current state */
2217 /* not Recording??? */
2219 if (-1 == vcd_client_manager_get_pid()) {
2220 SLOG(LOG_ERROR, TAG_VCD, "[Server] Manager is NOT available");
2221 return VCD_ERROR_OPERATION_FAILED;
2224 SLOG(LOG_DEBUG, TAG_VCD, "[Server] stop TTS feedback");
2226 return VCD_ERROR_NONE;
2229 int vcd_server_mgr_send_audio_streaming(int pid, int event, unsigned char* buffer, unsigned int len)
2231 SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] Send Audio Streaming from Multi-assistant. event(%d), buffer(%p), len(%d)", event, &buffer, len);
2234 if (VCD_AUDIO_STREAMING_EVENT_START == event) {
2235 ret = vcd_recorder_start_streaming();
2237 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to start streaming, ret(%d)", ret);
2242 ret = vcd_recorder_send_streaming((const void*)buffer, (const unsigned int)len);
2244 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to start streaming, ret(%d)", ret);
2248 if (VCD_AUDIO_STREAMING_EVENT_FINISH == event) {
2249 ret = vcd_recorder_stop_streaming();
2251 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to stop streaming, ret(%d)", ret);
2256 return VCD_ERROR_NONE;
2261 * VC Server Functions for Client
2263 int vcd_server_initialize(int pid)
2265 if (false == vcd_engine_is_available_engine()) {
2266 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
2267 return VCD_ERROR_ENGINE_NOT_FOUND;
2270 /* check if pid is valid */
2271 if (true == vcd_client_is_available(pid)) {
2272 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] The pid is already exist");
2273 return VCD_ERROR_NONE;
2276 /* Add client information to client manager */
2277 if (0 != vcd_client_add(pid)) {
2278 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add client info");
2279 return VCD_ERROR_OPERATION_FAILED;
2282 SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Client Initialize : pid(%d)", pid);
2284 return VCD_ERROR_NONE;
2287 int vcd_server_finalize(int pid)
2289 /* check if pid is valid */
2290 if (false == vcd_client_is_available(pid)) {
2291 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2292 return VCD_ERROR_INVALID_PARAMETER;
2295 /* Remove client information */
2296 if (0 != vcd_client_delete(pid)) {
2297 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
2300 if (0 == vcd_client_get_ref_count()) {
2301 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Connected client list is empty");
2302 ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
2305 SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Client Finalize : pid(%d)", pid);
2307 return VCD_ERROR_NONE;
2310 int vcd_server_set_command(int pid, vc_cmd_type_e cmd_type)
2312 /* check if pid is valid */
2313 if (false == vcd_client_is_available(pid)) {
2314 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2315 return VCD_ERROR_INVALID_PARAMETER;
2318 if (0 != vcd_client_set_command_type(pid, cmd_type)) {
2319 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set command type : pid(%d), cmd_type(%d)", pid, cmd_type);
2320 return VCD_ERROR_OPERATION_FAILED;
2326 int vcd_server_unset_command(int pid, vc_cmd_type_e cmd_type)
2328 /* check if pid is valid */
2329 if (false == vcd_client_is_available(pid)) {
2330 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2331 return VCD_ERROR_INVALID_PARAMETER;
2334 if (0 != vcd_client_unset_command_type(pid, cmd_type)) {
2335 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to unset command type : pid(%d), cmd_type(%d)", pid, cmd_type);
2336 return VCD_ERROR_OPERATION_FAILED;
2342 int vcd_server_set_foreground(int pid, bool value)
2344 /* check if pid is valid */
2345 if (false == vcd_client_is_available(pid) && false == vcd_client_widget_is_available(pid)) {
2346 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2347 return VCD_ERROR_INVALID_PARAMETER;
2350 if (0 != vcd_config_set_foreground(pid, value)) {
2351 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set foreground : pid(%d), value(%d)", pid, value);
2352 return VCD_ERROR_OPERATION_FAILED;
2358 static int __vcd_server_launch_manager_app()
2361 bool running = false;
2364 ret = vcd_client_manager_get_appid(&appid);
2365 if (0 != ret || NULL == appid) {
2366 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get manager appid");
2367 return VCD_ERROR_OPERATION_FAILED;
2369 ret = app_manager_is_running(appid, &running);
2371 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to check running with appid(%s)", appid);
2374 return VCD_ERROR_OPERATION_FAILED;
2376 if (false == running) {
2377 int tmp_ret = __vcd_is_package_installed(appid);
2378 if (false == tmp_ret) {
2379 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] manager app is not installed, appid(%s)", appid);
2381 ret = __vcd_activate_app_by_appcontrol(appid);
2383 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to activate app");
2388 SLOG(LOG_ERROR, TAG_VCD, "Launch vc manager app: appid(%s)", appid);
2391 ret = __vcd_resume_app(appid);
2393 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to resume app");
2398 SLOG(LOG_ERROR, TAG_VCD, "Resume vc manager app: appid(%s)", appid);
2404 return VCD_ERROR_NONE;
2407 int vcd_server_set_server_dialog(int pid, const char* app_id, const char* credential)
2409 /* check if pid is valid */
2410 if (false == vcd_client_is_available(pid)) {
2411 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2412 return VCD_ERROR_INVALID_PARAMETER;
2415 int ret = vcd_engine_set_server_dialog(app_id, credential);
2417 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set server dialog, pid(%d), app_id(%s), ret(%d)", pid, app_id, ret);
2418 vcd_client_set_server_dialog(pid, false);
2421 SLOG(LOG_ERROR, TAG_VCD, "[Success] Set server dialog, pid(%d), app_id(%s)", pid, app_id);
2423 if (0 != strncmp(credential, "#NULL", strlen(credential))) {
2424 ret = vcd_client_set_server_dialog(pid, true);
2426 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set to true for server dialog, app_id(%s)", app_id);
2428 ret = vcd_client_set_server_dialog(pid, false);
2430 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set to false for server dialog, app_id(%s)", app_id);
2436 int vcd_server_dialog(int pid, const char* disp_text, const char* utt_text, int continuous)
2438 /* check if pid is valid */
2439 if (false == vcd_client_is_available(pid) && false == vcd_client_widget_is_available(pid)) {
2440 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2441 return VCD_ERROR_INVALID_PARAMETER;
2444 bool is_server_dialog = false;
2445 int ret = vcd_client_get_server_dialog(pid, &is_server_dialog);
2447 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get server dialog, pid(%d), ret(%d)", pid, ret);
2450 if (true == is_server_dialog) {
2451 /* ++ Request tts event to engine */
2453 /* -- Request tts event to engine */
2455 ret = __vcd_server_launch_manager_app();
2457 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send dialog : mgr_pid(%d), pid(%d), disp_text(%s), utt_text(%s), continue(%d)", vcd_client_manager_get_pid(), pid, disp_text, utt_text, continuous);
2461 ret = vcdc_send_dialog(vcd_client_manager_get_pid(), pid, disp_text, utt_text, continuous);
2463 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send dialog : mgr_pid(%d), pid(%d), disp_text(%s), utt_text(%s), continue(%d)", vcd_client_manager_get_pid(), pid, disp_text, utt_text, continuous);
2470 int vcd_server_is_system_command_valid(int pid, int* is_sys_cmd_valid)
2472 /* check if pid is valid */
2473 if (false == vcd_client_is_available(pid) && false == vcd_client_widget_is_available(pid)) {
2474 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2475 return VCD_ERROR_INVALID_PARAMETER;
2478 /* check if system command is valid */
2479 if (true == vcd_client_manager_is_system_command_valid(vcd_client_manager_get_pid()))
2480 *is_sys_cmd_valid = true;
2482 *is_sys_cmd_valid = false;
2487 static void __start_tts_request_thread(void* data, Ecore_Thread* thread)
2489 SLOG(LOG_DEBUG, TAG_VCD, "[SUCCESS] Start tts request thread");
2490 vc_tts_text_data_s* tts_text_data = NULL;
2495 /* Get tts text data */
2496 ret = vcd_data_get_first_tts_text_data(&tts_text_data);
2497 if (0 != ret || NULL == tts_text_data) {
2499 if (0 >= vcd_data_get_tts_text_data_size()) {
2500 SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] No tts text data");
2503 SLOG(LOG_INFO, TAG_VCD, "[INFO] tts text data is just incoming");
2507 /* Request tts to engine */
2508 ret = vcd_engine_request_tts(tts_text_data->pid, tts_text_data->utt_id, tts_text_data->text, tts_text_data->language);
2510 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to request tts : %d", ret);
2512 SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] request tts, uid(%d) pid(%d), text(%s), language(%s), utt_id(%d)",
2513 tts_text_data->uid, tts_text_data->pid, tts_text_data->text, tts_text_data->language, tts_text_data->utt_id);
2515 /* clear tts text data after use */
2516 vcd_data_clear_tts_text_data(&tts_text_data);
2521 static void __end_tts_request_thread(void* data, Ecore_Thread* thread)
2523 SLOG(LOG_DEBUG, TAG_VCD, "[SUCCESS] End tts request thread");
2524 g_tts_thread = NULL;
2527 int vcd_server_request_tts(int pid, const char* text, const char* language, int to_vcm, int* utt_id)
2529 /* check if pid is valid */
2530 if (false == vcd_client_is_available(pid)) {
2531 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2532 return VCD_ERROR_INVALID_PARAMETER;
2535 vcd_state_e state = vcd_config_get_service_state();
2536 if (VCD_STATE_READY != state) {
2537 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready, state(%d)", state);
2538 return VCD_ERROR_INVALID_STATE;
2541 g_current_utt_id = (g_current_utt_id + 1) % 1000;
2542 *utt_id = g_current_utt_id;
2544 g_current_uid = pid * 1000 + g_current_utt_id;
2546 g_current_uid = vcd_client_manager_get_pid() * 1000 + g_current_utt_id;
2548 SLOG(LOG_INFO, TAG_VCD, "[Server INFO] pid(%d), text(%s), language(%s), to_vcm(%d), ", pid, text, language, to_vcm);
2549 SLOG(LOG_INFO, TAG_VCD, "[Server INFO] current_uid(%d), current_utt_id(%d)", g_current_uid, g_current_utt_id);
2551 vc_tts_text_data_s* tts_text_data;
2552 tts_text_data = (vc_tts_text_data_s*)calloc(1, sizeof(vc_tts_text_data_s));
2553 if (!tts_text_data) {
2554 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to callocate memory ");
2555 return VCD_ERROR_OUT_OF_MEMORY;
2557 tts_text_data->uid = g_current_uid;
2558 tts_text_data->pid = pid;
2559 tts_text_data->utt_id = g_current_utt_id;
2560 tts_text_data->text = strdup(text);
2561 tts_text_data->language = strdup(language);
2563 int ret = vcd_data_add_tts_text_data(tts_text_data->uid, tts_text_data);
2565 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add tts text data : %d", ret);
2568 bool is_canceled = ecore_thread_check(g_tts_thread);
2569 if (NULL == g_tts_thread || TRUE == is_canceled) {
2570 SLOG(LOG_INFO, TAG_VCD, "[Server INFO] ecore thread run : start_tts_request_thread ");
2571 g_tts_thread = ecore_thread_run(__start_tts_request_thread, __end_tts_request_thread, NULL, NULL);
2577 int vcd_server_cancel_tts(int pid, int utt_id)
2579 /* check if pid is valid */
2580 if (false == vcd_client_is_available(pid)) {
2581 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2582 return VCD_ERROR_INVALID_PARAMETER;
2585 vcd_state_e state = vcd_config_get_service_state();
2586 if (VCD_STATE_READY != state) {
2587 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready, state(%d)", state);
2588 return VCD_ERROR_INVALID_STATE;
2591 vc_tts_text_data_s* tts_text_data = NULL;
2593 int uid = pid * 1000 + utt_id;
2594 int ret = vcd_data_get_tts_text_data(uid, &tts_text_data);
2596 SLOG(LOG_WARN, TAG_VCD, "[Server WARN] No data in vcd tts text queue");
2598 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Clear tts text data, pid(%d), utt_id(%d), text(%s)", pid, utt_id, tts_text_data->text);
2599 vcd_data_clear_tts_text_data(&tts_text_data);
2602 /* Request tts to engine */
2603 ret = vcd_engine_cancel_tts(pid, utt_id);
2605 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to cancel tts : %d", ret);
2607 SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] request tts, pid(%d), utt_id(%d)", pid, utt_id);
2613 int vcd_server_get_tts_audio_format(int pid, int* rate, int* channel, int* audio_type)
2615 /* check if pid is valid */
2616 if (false == vcd_client_is_available(pid)) {
2617 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2618 return VCD_ERROR_INVALID_PARAMETER;
2621 vcd_state_e state = vcd_config_get_service_state();
2622 if (VCD_STATE_READY != state) {
2623 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
2624 return VCD_ERROR_INVALID_STATE;
2627 /* Request tts to engine */
2628 int ret = vcd_engine_get_tts_audio_format(rate, channel, audio_type);
2630 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get tts audio format : %d", ret);
2632 SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] get tts audio format, pid(%d), rate(%d), channel(%d), audio_type(%d)", pid, *rate, *channel, *audio_type);
2639 int vcd_server_set_exclusive_command(int pid, bool value)
2641 /* check if pid is valid */
2642 if (false == vcd_client_is_available(pid)) {
2643 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2644 return VCD_ERROR_INVALID_PARAMETER;
2647 if (true == value) {
2648 if (0 != vcd_client_set_exclusive_command(pid)) {
2649 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set exclusive command : pid(%d)", pid);
2650 return VCD_ERROR_OPERATION_FAILED;
2653 if (0 != vcd_client_unset_exclusive_command(pid)) {
2654 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to unset exclusive command : pid(%d)", pid);
2655 return VCD_ERROR_OPERATION_FAILED;
2662 int vcd_server_request_start(int pid, bool stop_by_silence)
2664 /* check if pid is valid */
2665 if (false == vcd_client_is_available(pid)) {
2666 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid(%d) is NOT foreground client", pid);
2667 return VCD_ERROR_INVALID_PARAMETER;
2671 /* Check current state */
2672 vcd_state_e state = vcd_config_get_service_state();
2674 /* Service state should be ready */
2675 if (VCD_STATE_READY != state) {
2676 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Ready : pid(%d)", pid);
2677 return VCD_ERROR_INVALID_STATE;
2680 if (-1 != vcd_client_manager_get_pid()) {
2681 /* Check current pid is valid */
2682 if (false == vcd_client_manager_check_demandable_client(pid)) {
2683 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
2684 return VCD_ERROR_INVALID_PARAMETER;
2688 ret = vcd_server_mgr_start(stop_by_silence, false);
2690 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
2691 return VCD_ERROR_INVALID_PARAMETER;
2697 int vcd_server_request_stop(int pid)
2700 /* Check current state */
2701 vcd_state_e state = vcd_config_get_service_state();
2703 /* Service state should be ready */
2704 if (VCD_STATE_RECORDING != state) {
2705 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording : pid(%d)", pid);
2706 return VCD_ERROR_INVALID_STATE;
2709 if (-1 != vcd_client_manager_get_pid()) {
2710 /* Check current pid is valid */
2711 if (false == vcd_client_manager_check_demandable_client(pid)) {
2712 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
2713 return VCD_ERROR_INVALID_PARAMETER;
2717 ret = vcd_server_mgr_stop();
2719 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
2720 return VCD_ERROR_OPERATION_FAILED;
2723 return VCD_ERROR_NONE;
2726 int vcd_server_request_cancel(int pid)
2729 /* Check current state */
2730 vcd_state_e state = vcd_config_get_service_state();
2732 /* Service state should be recording or processing */
2733 if (VCD_STATE_RECORDING != state && VCD_STATE_PROCESSING != state) {
2734 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording or Processing : pid(%d)", pid);
2735 return VCD_ERROR_INVALID_STATE;
2738 if (-1 != vcd_client_manager_get_pid()) {
2739 /* Check current pid is valid */
2740 if (false == vcd_client_manager_check_demandable_client(pid)) {
2741 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
2742 return VCD_ERROR_INVALID_PARAMETER;
2746 ret = vcd_server_mgr_cancel();
2748 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
2749 return VCD_ERROR_OPERATION_FAILED;
2752 return VCD_ERROR_NONE;
2757 * VC Server Functions for Widget lib
2759 int vcd_server_widget_initialize(int pid)
2761 if (false == vcd_engine_is_available_engine()) {
2762 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
2763 return VCD_ERROR_ENGINE_NOT_FOUND;
2766 /* check if pid is valid */
2767 if (true == vcd_client_widget_is_available(pid)) {
2768 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] The pid is already exist");
2769 return VCD_ERROR_NONE;
2772 /* Add client information to client manager */
2773 if (0 != vcd_client_widget_add(pid)) {
2774 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add client info");
2775 return VCD_ERROR_OPERATION_FAILED;
2778 SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Initialize widget : pid(%d)", pid);
2780 return VCD_ERROR_NONE;
2783 static void __vcd_server_widget_start_recording(void *data)
2785 SLOG(LOG_ERROR, TAG_VCD, "[Server INFO] start recording");
2787 if (0 != __start_internal_recognition()) {
2788 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition");
2792 int vcd_server_widget_finalize(int pid)
2794 /* check if pid is valid */
2795 if (false == vcd_client_widget_is_available(pid)) {
2796 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2797 return VCD_ERROR_INVALID_PARAMETER;
2800 /* Remove client information */
2801 if (0 != vcd_client_widget_delete(pid)) {
2802 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
2805 if (0 == vcd_client_get_ref_count()) {
2806 SLOG(LOG_ERROR, TAG_VCD, "[Server] connected client list is empty");
2807 ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
2811 bool is_waiting = false;
2812 if (0 != vcd_client_widget_get_waiting_for_recording(pid, &is_waiting)) {
2813 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to get waiting to recording");
2816 if (true == is_waiting) {
2817 SLOG(LOG_ERROR, TAG_VCD, "[Server INFO] invoke to start recording");
2818 ecore_main_loop_thread_safe_call_async(__vcd_server_widget_start_recording, NULL);
2820 return VCD_ERROR_NONE;
2823 int vcd_server_widget_start_recording(int pid, bool widget_command)
2825 /* check if pid is valid */
2826 if (false == vcd_client_widget_is_available(pid)) {
2827 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2828 return VCD_ERROR_INVALID_PARAMETER;
2832 if (0 != vcd_client_widget_get_waiting_for_recording(pid, &waiting) || false == waiting) {
2833 SLOG(LOG_ERROR, TAG_VCD, "[Server] Server is not waiting for recording, pid(%d), waiting(%d)", pid, waiting);
2837 if (true == widget_command) {
2838 vcd_client_widget_set_command(pid);
2839 SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget command is available");
2841 vcd_client_widget_unset_command(pid);
2842 SLOG(LOG_WARN, TAG_VCD, "[Server] widget command is NOT available");
2845 SLOG(LOG_ERROR, TAG_VCD, "[Server] start internal recognition : %d", widget_command);
2846 int ret = __start_internal_recognition();
2848 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition : %d", ret);
2849 ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
2855 int vcd_server_widget_start(int pid, bool stop_by_silence)
2857 /* check if pid is valid */
2858 int fore_pid = vcd_client_widget_get_foreground_pid();
2859 if (pid != fore_pid) {
2860 SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
2861 return VCD_ERROR_INVALID_PARAMETER;
2864 /* Check current state */
2865 vcd_state_e state = vcd_config_get_service_state();
2867 /* Service state should be ready */
2868 if (VCD_STATE_READY != state) {
2869 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Ready : pid(%d)", pid);
2870 return VCD_ERROR_INVALID_STATE;
2873 vcd_client_set_slience_detection(stop_by_silence);
2875 /* Notify show tooltip */
2876 ecore_timer_add(0, __vcd_request_show_tooltip, (void*)true);
2881 int vcd_server_widget_stop(int pid)
2883 /* check if pid is valid */
2884 int fore_pid = vcd_client_widget_get_foreground_pid();
2885 if (pid != fore_pid) {
2886 SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
2887 return VCD_ERROR_INVALID_PARAMETER;
2891 /* Check current state */
2892 vcd_state_e state = vcd_config_get_service_state();
2894 /* Service state should be recording */
2895 if (VCD_STATE_RECORDING != state) {
2896 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current service state is not Recording : pid(%d)", pid);
2897 return VCD_ERROR_INVALID_STATE;
2900 ret = vcd_server_mgr_stop();
2902 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
2903 return VCD_ERROR_OPERATION_FAILED;
2906 return VCD_ERROR_NONE;
2909 int vcd_server_widget_cancel(int pid)
2911 /* check if pid is valid */
2912 int fore_pid = vcd_client_widget_get_foreground_pid();
2913 if (pid != fore_pid) {
2914 SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
2915 return VCD_ERROR_INVALID_PARAMETER;
2919 /* Check current state */
2920 vcd_state_e state = vcd_config_get_service_state();
2922 /* Service state should be recording or processing */
2923 if (VCD_STATE_RECORDING != state && VCD_STATE_PROCESSING != state) {
2924 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording or Processing : pid(%d)", pid);
2925 return VCD_ERROR_INVALID_STATE;
2928 ret = vcd_server_mgr_cancel();
2930 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to cancel recognition : %d", ret);
2934 return VCD_ERROR_NONE;
2937 int vcd_server_widget_enable_asr_result(int pid, bool enable)
2940 ret = vcd_client_widget_set_asr_result_enabled(pid, enable);
2942 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to enable asr result : %d", ret);
2948 int vcd_server_set_language(const char* language)
2950 int ret = VCD_ERROR_NONE;
2952 ret = vcd_config_set_default_language(language);
2954 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to set language : %d", ret);
2958 ret = vcd_engine_set_current_language(language);
2960 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to set language : %d", ret);
2967 * For engine service
2969 int vcd_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data)
2971 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Get foreach command");
2973 if (NULL == callback) {
2974 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] input parameter is NULL");
2975 return VCD_ERROR_INVALID_PARAMETER;
2979 ret = vcd_engine_agent_get_foreach_command(vce_command, callback, user_data);
2981 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get foreach command : ret(%d)", ret);
2987 int vcd_get_command_count(vce_cmd_h vce_command, int* count)
2989 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Get command count");
2992 ret = vcd_engine_agent_get_command_count(vce_command, count);
2994 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get command count : ret(%d)", ret);
3000 int vcd_get_audio_type(char** audio_type)
3002 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Get audio type");
3005 ret = vcd_engine_agent_get_audio_type(audio_type);
3007 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio type : ret(%d)", ret);
3013 int vcd_set_private_data(const char* key, const char* data)
3015 vcd_state_e state = vcd_config_get_service_state();
3017 if (VCD_STATE_READY != state) {
3018 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state(%d) is NOT 'READY'", state);
3019 return VCD_ERROR_INVALID_STATE;
3022 int ret = vcd_engine_agent_set_private_data(key, data);
3024 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data to the manager client : ret(%d)", ret);
3026 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set private data to the manager client, key(%s), data(%s)", key, data);
3032 int vcd_get_private_data(const char* key, char** data)
3034 vcd_state_e state = vcd_config_get_service_state();
3036 if (VCD_STATE_READY != state) {
3037 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state(%d) is NOT 'READY'", state);
3038 return VCD_ERROR_INVALID_STATE;
3041 int ret = vcd_engine_agent_get_private_data(key, data);
3043 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get private data from the manager client : ret(%d)", ret);
3045 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Get private data from the manager client, key(%s), data(%s)", key, *data);
3051 int vcd_start_recording()
3053 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Start recording");
3056 ret = vcd_engine_agent_start_recording();
3058 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recording : ret(%d)", ret);
3064 int vcd_stop_recording()
3066 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Stop recording");
3069 ret = vcd_engine_agent_stop_recording();
3071 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recording : ret(%d)", ret);
3077 int vcd_set_private_data_set_cb(vce_private_data_set_cb callback_func)
3079 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set private data set cb");
3082 ret = vcd_engine_agent_set_private_data_set_cb(callback_func);
3084 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data set cb : ret(%d)", ret);
3090 int vcd_set_private_data_requested_cb(vce_private_data_requested_cb callback_func)
3092 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set private data requested cb");
3095 ret = vcd_engine_agent_set_private_data_requested_cb(callback_func);
3097 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data requested cb : ret(%d)", ret);
3103 int vcd_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func)
3105 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set nlu base info requested cb");
3108 ret = vcd_engine_agent_set_nlu_base_info_requested_cb(callback_func);
3110 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set nlu base info requested cb : ret(%d)", ret);
3116 int vcd_set_specific_engine_request_cb(vce_specific_engine_request_cb callback_func)
3118 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set specific engine request cb");
3120 ret = vcd_engine_agent_set_specific_engine_request_cb(callback_func);
3122 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set specific engine request cb : ret(%d)", ret);
3128 int vcd_set_request_tts_cb(vce_request_tts_cb callback_func, void* user_data)
3130 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set request tts cb");
3132 ret = vcd_engine_agent_set_request_tts_cb(callback_func, user_data);
3134 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set request tts cb : ret(%d)", ret);
3140 int vcd_set_cancel_tts_cb(vce_cancel_tts_cb callback_func, void* user_data)
3142 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set cancel tts cb");
3144 ret = vcd_engine_agent_set_cancel_tts_cb(callback_func, user_data);
3146 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set cancel tts cb : ret(%d)", ret);
3152 int vcd_set_tts_audio_format_request_cb(vce_tts_audio_format_request_cb callback_func, void* user_data)
3154 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set tts audio format request cb");
3156 ret = vcd_engine_agent_set_get_tts_audio_format_cb(callback_func, user_data);
3158 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set tts audio format request : ret(%d)", ret);