Merge "Support Multi-Assistant" into tizen
[platform/core/uifw/voice-control.git] / server / vcd_server.c
1 /*
2 * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <app_control.h>
18 #include <app_manager.h>
19 #include <dirent.h>
20 #include <sound_manager.h>
21
22 #include "vc_cmd_db.h"
23 #include "vc_info_parser.h"
24 #include "vcd_main.h"
25 #include "vcd_server.h"
26 #include "vcd_server_data.h"
27 #include "vcd_client_data.h"
28
29 #include "vcd_engine_agent.h"
30 #include "vcd_config.h"
31 #include "vcd_recorder.h"
32 #include "vcd_dbus.h"
33
34 #include "voice_control_command_expand.h"
35 #include "voice_control_common.h"
36
37 #define CLIENT_CLEAN_UP_TIME 500
38 /*
39 * VC Server static variable
40 */
41 static GList *g_proc_list = NULL;
42
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;
46
47 static Ecore_Thread* g_tts_thread = NULL;
48 static int g_current_uid = -1;
49 static int g_current_utt_id = -1;
50
51 /**
52 * @brief Enumerations of send event type.
53 */
54 typedef enum {
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;
59
60 static int __vcd_server_launch_manager_app();
61 static int __start_internal_recognition();
62
63 /*
64 * VC Server Internal Functions
65 */
66 static Eina_Bool __stop_by_silence(void *data)
67 {
68         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Silence Detected ");
69
70         vcd_server_mgr_stop();
71
72         SLOG(LOG_DEBUG, TAG_VCD, "@@@");
73         return EINA_FALSE;
74 }
75
76 static Eina_Bool __cancel_by_interrupt(void *data)
77 {
78         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Cancel by interrupt");
79
80         vcd_server_mgr_cancel();
81
82         SLOG(LOG_DEBUG, TAG_VCD, "@@@");
83         return EINA_FALSE;
84 }
85
86 static void __cancel_by_error(void *data)
87 {
88         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Cancel by error");
89
90         vcd_server_mgr_cancel();
91
92         SLOG(LOG_DEBUG, TAG_VCD, "@@@");
93         return;
94 }
95
96 static Eina_Bool __restart_engine(void *data)
97 {
98         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Restart by no result");
99
100         g_restart_timer = NULL;
101
102         /* Restart recognition */
103         int ret = vcd_engine_recognize_start(true);
104         if (0 != ret) {
105                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to restart recognition : result(%d)", ret);
106                 return EINA_FALSE;
107         }
108
109         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Start engine");
110
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);
115         }
116
117         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Restart recognition");
118
119         SLOG(LOG_DEBUG, TAG_VCD, "@@@");
120         return EINA_FALSE;
121 }
122
123 static int __server_recorder_callback(const void* data, const unsigned int length)
124 {
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) {
129                 return 0;
130         }
131
132         vce_speech_detect_e speech_detected = VCE_SPEECH_DETECT_NONE;
133         int ret;
134
135         ret = vcd_engine_recognize_audio(data, length, &speech_detected);
136
137         if (0 > ret) {
138                 /* Error */
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");
144                 } else {
145                         vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "Engine recognition failed");
146                 }
147                 return 0;
148         }
149
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");
155                         }
156                 }
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();
164                         if (0 != ret) {
165                                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
166                         }
167                         vcd_config_set_service_state(VCD_STATE_PROCESSING);
168                         vcdc_send_service_state(VCD_STATE_PROCESSING);
169
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();
174                         if (0 != ret) {
175                                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
176                         }
177                 }
178         }
179
180         return 0;
181 }
182
183 void __server_recorder_interrupt_callback()
184 {
185         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Cancel by sound interrupt");
186
187         ecore_timer_add(0, __cancel_by_interrupt, NULL);
188
189         SLOG(LOG_DEBUG, TAG_VCD, "@@@");
190 }
191
192 static void __config_lang_changed_cb(const char* current_lang, void* user_data)
193 {
194         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Change language ");
195
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();
201         }
202
203         int ret;
204         ret = vcd_engine_set_current_language(current_lang);
205         if (0 != ret) {
206                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set language of engine : %d", ret);
207         }
208
209         SLOG(LOG_DEBUG, TAG_VCD, "@@@");
210
211         return;
212 }
213
214 static void __config_foreground_changed_cb(int previous, int current, void* user_data)
215 {
216         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Change foreground");
217
218         SLOG(LOG_DEBUG, TAG_VCD, "Foreground pid(%d)", current);
219
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);
226                 }
227         }
228
229         SLOG(LOG_DEBUG, TAG_VCD, "@@@");
230
231         return;
232 }
233
234 static int __vcd_activate_app_by_appcontrol(const char* appid)
235 {
236         if (NULL == appid) {
237                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
238                 return VCD_ERROR_INVALID_PARAMETER;
239         }
240
241         int ret = -1;
242         app_control_h app_control = NULL;
243         ret = app_control_create(&app_control);
244         if (APP_CONTROL_ERROR_NONE == ret) {
245                 // Set extra data
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;
251                 }
252                 // Set an app ID.
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;
258                 }
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;
265                 }
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;
271                 }
272         }
273         return VCD_ERROR_NONE;
274 }
275
276 static int __vcd_resume_app(const char* appid)
277 {
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;
283         }
284
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;
289         }
290         return VCD_ERROR_NONE;
291 }
292
293 static bool __vcd_is_package_installed(const char* appid)
294 {
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)
298                 return false;
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);
302         return true;
303 }
304
305 static bool __vcd_launch_app(const char* result)
306 {
307         if (NULL == result) {
308                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
309                 return VCD_ERROR_INVALID_PARAMETER;
310         }
311
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;
316         }
317
318         if (0 != g_slist_length(app_list)) {
319                 /* release data */
320                 GSList *iter = NULL;
321                 vc_deactivated_app_s* temp_app = NULL;
322                 iter = g_slist_nth(app_list, 0);
323
324                 while (NULL != iter) {
325                         temp_app = iter->data;
326
327                         if (NULL != temp_app) {
328                                 if (NULL != temp_app->appid) {
329                                         int ret = -1;
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;
336                                                 free(temp_app);
337                                                 temp_app = NULL;
338                                                 return VCD_ERROR_OPERATION_FAILED;
339                                         }
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);
344                                                 } else {
345                                                         ret = __vcd_activate_app_by_appcontrol(temp_app->appid);
346                                                         if (0 != ret) {
347                                                                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to activate app");
348                                                                 free(temp_app->appid);
349                                                                 temp_app->appid = NULL;
350                                                                 free(temp_app);
351                                                                 temp_app = NULL;
352                                                                 return ret;
353                                                         }
354                                                         SLOG(LOG_ERROR, TAG_VCD, "Launch app: appid(%s) result(%s)", temp_app->appid, result);
355                                                 }
356                                         } else {
357                                                 ret = __vcd_resume_app(temp_app->appid);
358                                                 if (0 != ret) {
359                                                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to resume app");
360                                                         free(temp_app->appid);
361                                                         temp_app->appid = NULL;
362                                                         free(temp_app);
363                                                         temp_app = NULL;
364                                                         return ret;
365                                                 }
366                                                 SLOG(LOG_ERROR, TAG_VCD, "Resume app: appid(%s) result(%s)", temp_app->appid, result);
367                                         }
368                                         free(temp_app->appid);
369                                         temp_app->appid = NULL;
370                                 }
371                                 free(temp_app);
372                                 temp_app = NULL;
373                         }
374                         iter = g_slist_next(iter);
375                 }
376                 app_list = NULL;
377         }
378
379         return VCD_ERROR_NONE;
380 }
381
382 static Eina_Bool __vcd_send_selected_result(void *data)
383 {
384         GSList* pid_list = NULL;
385         const char* result = vcd_client_manager_get_result_text();
386
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");
389         } else {
390                 if (0 < g_slist_length(pid_list)) {
391                         GSList* iter = NULL;
392                         vc_cmd_s* temp_cmd = NULL;
393                         int ret = 0;
394                         int pre_pid = -1;
395                         int pre_type = -1;
396
397                         iter = g_slist_nth(pid_list, 0);
398                         while (NULL != iter) {
399                                 temp_cmd = iter->data;
400
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);
404                                         if (0 != ret) {
405                                                 SLOG(LOG_ERROR, TAG_VCD, "Fail to launch or resume app, ret(%d) result(%s)", ret, result);
406                                         } else {
407                                                 /* send result noti */
408                                                 ret = vcdc_send_result(temp_cmd->pid, vcd_client_manager_get_pid(), temp_cmd->type);
409                                                 if (0 != ret) {
410                                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result, ret(%d)", ret);
411                                                         break;
412                                                 } else {
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;
416                                                 }
417                                         }
418                                         free(temp_cmd);
419                                         temp_cmd = NULL;
420                                 }
421                                 pid_list = g_slist_remove_link(pid_list, iter);
422                                 iter = g_slist_nth(pid_list, 0);
423                         }
424                 }
425         }
426
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);
430         }
431
432         return EINA_FALSE;
433 }
434
435 int vcd_send_asr_result(vce_asr_result_event_e event, const char* asr_result, void *user_data)
436 {
437         int ret = __vcd_server_launch_manager_app();
438         if (0 != ret) {
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);
440                 return ret;
441         }
442
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);
446                 if (0 != ret) {
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);
448                 }
449         }
450
451         return ret;
452 }
453
454 int vcd_send_specific_engine_result(const char* engine_app_id, const char* event, const char* result, void *user_info)
455 {
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);
459         }
460
461         return VCD_ERROR_NONE;
462 }
463
464 int vcd_send_nlg_result(const char* nlg_result, void *user_data)
465 {
466         int ret = __vcd_server_launch_manager_app();
467         if (0 != ret) {
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);
469                 return ret;
470         }
471
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
474         if (0 != ret)
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);
476         return ret;
477 }
478
479 static void* __recorder_stop(void *data)
480 {
481         vcd_recorder_stop();
482         return NULL;
483 }
484
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)
486 {
487         int ret = 0;
488         vcd_recognition_mode_e recognition_mode = vcd_client_get_recognition_mode();
489
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;
494                 }
495         }
496
497         vc_info_parser_unset_result(vcd_client_manager_get_exclusive());
498         vcd_client_manager_set_result_text(all_result);
499
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);
502
503         SECURE_SLOG(LOG_ERROR, TAG_VCD, "[Server] NLU result(%s)", nlu_result);
504
505 #if 1
506         /* if nlu_result is exist, Add command handle(is_action) into result list */
507         /* Normal result */
508         SLOG(LOG_DEBUG, TAG_VCD, "[Server] @ Get engine result @");
509
510         vc_cmd_s* temp_cmd = NULL;
511         vc_cmd_list_h vc_cmd_list = NULL;
512
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;
519         }
520
521         /* priority filter */
522         /* system > exclusive > widget > foreground > system_background > widget partial > foreground partial > background */
523         int i = 0;
524         int* filtered_id = (int*)calloc(count, sizeof(int));
525         if (!filtered_id) {
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;
529         }
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]);
534
535                 if (0 > result_id[i]) {
536                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Result ID(%d) is NOT valid", result_id[i]);
537                         continue;
538                 }
539
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];
544                                 filtered_count++;
545                         } else if (top_priority > temp_cmd->priority) {
546                                 filtered_id[0] = result_id[i];
547                                 filtered_count = 1;
548                                 top_priority = temp_cmd->priority;
549                         }
550
551                         vc_cmd_destroy((vc_cmd_h)temp_cmd);
552                         temp_cmd = NULL;
553                 }
554         }
555
556         // ASR consume
557         if (top_priority >= VC_COMMAND_PRIORITY_WIDGET) {
558                 int pid = vcd_client_widget_get_foreground_pid();
559                 if (-1 != pid) {
560                         if (NULL != all_result) {
561                                 vc_info_parser_set_result(all_result, event, msg, NULL, false);
562                                 bool enable = 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) {
568                                                 *user_info = 0x00;
569                                         }
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");
572                                         } else {
573                                                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] ASR result is consumed(%d)", is_consumed);
574                                                 if (true == is_consumed) {
575                                                         if (NULL != user_info) {
576                                                                 *user_info = 0x01;
577                                                                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Send whether ASR result is consumed or not (%d)", *user_info);
578                                                         }
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");
586                                                                 }
587                                                         }
588
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);
592
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) {
597                                                                 free(filtered_id);
598                                                                 filtered_id = NULL;
599                                                         }
600                                                         return VCD_ERROR_NONE;
601                                                 }
602                                         }
603                                 }
604                         }
605                 }
606         }
607
608         int is_action = 0;
609         for (i = 0; i < filtered_count; i++) {
610                 SLOG(LOG_INFO, TAG_VCD, "[Server]   [%d] Filtered Result id(%d)", i, filtered_id[i]);
611
612                 if (filtered_id[i] < 0) {
613                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Filtered ID(%d) is NOT valid", filtered_id[i]);
614                         continue;
615                 }
616
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:
626                                 break;
627                         case VC_CMD_FORMAT_ACTION:
628                                 is_action = 1;
629                                 break;
630                         default:
631                                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Unknown command type : %d", temp_cmd->type);
632                         }
633
634                         temp_cmd->id = i;
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);
638                                 temp_cmd = NULL;
639                         }
640                 } else {
641                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] NOT found matched result(%d)", filtered_id[i]);
642                 }
643         }
644
645         if (NULL != filtered_id) {
646                 free(filtered_id);
647                 filtered_id = NULL;
648         }
649
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) {
654                         vc_cmd_h nlu_cmd;
655                         if (0 != vc_cmd_create(&nlu_cmd)) {
656                                 SLOG(LOG_ERROR, TAG_VCD, "Fail to nlu cmd create");
657                         } else {
658                                 if (0 != vc_cmd_set_type(nlu_cmd, VC_COMMAND_TYPE_SYSTEM)) {
659                                         SLOG(LOG_ERROR, TAG_VCD, "Fail to set type");
660                                 }
661                                 if (0 != vc_cmd_set_pid(nlu_cmd, vcd_client_manager_get_pid())) {
662                                         SLOG(LOG_ERROR, TAG_VCD, "Fail to set pid");
663                                 }
664                                 if (0 != vc_cmd_set_format(nlu_cmd, VC_CMD_FORMAT_ACTION)) {
665                                         SLOG(LOG_ERROR, TAG_VCD, "Fail to set format");
666                                 }
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);
670                                 }
671                         }
672                 }
673         }
674
675         vc_cmd_print_list(vc_cmd_list);
676
677         SLOG(LOG_DEBUG, TAG_VCD, "[Server] @@@@");
678
679         int result_count = 0;
680         vc_cmd_list_get_count(vc_cmd_list, &result_count);
681
682         /* Handle the result list */
683         if (0 == result_count) {
684                 /* No result */
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);
689                         int cnt = 0;
690
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;
695                         }
696
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);
700                         if (0 < 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);
704                                 if (0 < cnt) {
705                                         top_priority = VC_COMMAND_PRIORITY_WIDGET;
706                                         SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched widget command");
707                                 }
708                         } else {
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;
714                                 }
715
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);
719                                 if (0 < 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);
723                                         if (0 < cnt) {
724                                                 top_priority = VC_COMMAND_PRIORITY_FOREGROUND;
725                                                 SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched foreground command");
726                                         }
727                                 }
728                                 vc_cmd_list_destroy(foreground_cmd_list, true);
729                         }
730                         vc_cmd_list_destroy(widget_cmd_list, true);
731                 } else {
732                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Engine result is NULL");
733                 }
734
735                 vc_cmd_list_get_count(vc_cmd_list, &result_count);
736
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");
740
741                         bool temp = vcd_client_manager_get_exclusive();
742                         vc_info_parser_set_result(all_result, event, msg, NULL, temp);
743
744                         int pid = vcd_client_widget_get_foreground_pid();
745                         if (-1 != pid) {
746                                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
747                                 /* Send to hide tooltip */
748                                 vcdc_send_show_tooltip(pid, false);
749                         }
750
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");
755                                 }
756                         }
757
758                         vcd_client_manager_set_exclusive(false);
759                         vc_cmd_list_destroy(vc_cmd_list, true);
760
761                         return VCD_ERROR_NONE;
762                 }
763
764                 // Partial matching algorithm find some commands
765                 event = VC_RESULT_EVENT_RESULT_SUCCESS;
766         }
767
768         // There are more than one result.
769         if (false == vcd_client_manager_get_exclusive()) {
770                 vc_cmd_list_h temp_list = NULL;
771
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;
776                         int cnt = 0;
777
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;
782                         }
783
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;
789                         }
790
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);
794                         if (0 < 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);
798                                 if (0 < cnt) {
799                                         if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) {
800                                                 SLOG(LOG_WARN, TAG_VCD, "[WARNING] Fail to destroy list");
801                                         }
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");
806                                 }
807                         } else {
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;
813                                 }
814
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);
818                                 if (0 < 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);
822                                         if (0 < cnt) {
823                                                 if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) {
824                                                         SLOG(LOG_WARN, TAG_VCD, "[WARNING] Fail to destroy list");
825                                                 }
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");
830                                         }
831                                 }
832                                 vc_cmd_list_destroy(foreground_cmd_list, true);
833                         }
834                         vc_cmd_list_destroy(widget_cmd_list, true);
835                 }
836
837                 int pid = vcd_client_widget_get_foreground_pid();
838                 if (-1 != pid) {
839                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
840                         vcdc_send_show_tooltip(pid, false);
841                 }
842
843                 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, false);
844                 vc_cmd_list_destroy(vc_cmd_list, true);
845
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");
850                         }
851                 } else {
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);
854                 }
855         } else {
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);
859
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");
864                         }
865                 } else {
866                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Manager is NOT available");
867                 }
868
869                 vcd_client_manager_set_exclusive(false);
870         }
871
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);
880                         if (0 != ret) {
881                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
882                         }
883
884                         g_restart_timer = ecore_timer_add(0, __restart_engine, NULL);
885                         return ret;
886                 }
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);
898                         if (0 != ret) {
899                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
900                         }
901                         return ret;
902                 }
903         }
904
905         return VCD_ERROR_NONE;
906
907 #else
908         /* No result */
909         if (NULL == result_id) {
910                 /* No result */
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);
915                 }
916
917                 int pid = vcd_client_widget_get_foreground_pid();
918                 if (-1 != 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);
922                         }
923
924                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
925                         /* Send to hide tooltip */
926                         vcdc_send_show_tooltip(pid, false);
927                 }
928
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");
933                         }
934                 }
935
936                 vcd_client_manager_set_exclusive(false);
937
938                 return;
939         }
940
941         /* Normal result */
942         SLOG(LOG_DEBUG, TAG_VCD, "[Server] @ Get engine result @");
943
944         int ret = -1;
945         vc_cmd_s* temp_cmd = NULL;
946         vc_cmd_list_h vc_cmd_list = NULL;
947
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);
953                 return;
954         }
955
956         int i = 0;
957         for (i = 0; i < count; i++) {
958                 SLOG(LOG_DEBUG, TAG_VCD, "[Server]   [%d] Result ID(%d)", i, result_id[i]);
959
960                 if (result_id[i] < 0) {
961                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Result ID(%d) is NOT valid", result_id[i]);
962                         continue;
963                 }
964
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 */
973                                 break;
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);
978                                         }
979                                 } else {
980                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Command type is NOT valid. Parameter (%s)", temp_cmd->parameter);
981                                 }
982                                 break;
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);
987                                         }
988                                 } else {
989                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Command type is NOT valid. Command (%s)", temp_cmd->command);
990                                 }
991
992                                 break;
993                         default:
994                                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Unknown command type : %d", temp_cmd->type);
995                         }
996
997                         temp_cmd->id = i;
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);
1001                         }
1002                 } else {
1003                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] NOT found matched result(%d)", result_id[i]);
1004                 }
1005         }
1006
1007         vc_cmd_print_list(vc_cmd_list);
1008
1009         SLOG(LOG_DEBUG, TAG_VCD, "[Server] @@@@");
1010
1011         int result_count = 0;
1012         vc_cmd_list_get_count(vc_cmd_list, &result_count);
1013
1014         if (false == vcd_client_manager_get_exclusive()) {
1015                 int pid = vcd_client_widget_get_foreground_pid();
1016                 if (-1 != pid) {
1017                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
1018                         vcdc_send_show_tooltip(pid, false);
1019                 }
1020
1021                 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, false);
1022
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");
1027                         }
1028                 } else {
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);
1032                 }
1033         } else {
1034                 /* exclusive command */
1035                 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, true);
1036
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");
1041                         }
1042                 } else {
1043                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Manager is NOT available");
1044                 }
1045
1046                 vcd_client_manager_set_exclusive(false);
1047         }
1048
1049         vc_cmd_list_destroy(vc_cmd_list, true);
1050
1051         return;
1052 #endif
1053 }
1054
1055 #if 0
1056 static void __vcd_server_nlu_result_cb(vce_result_event_e event, const char* nlu_result, void *user_data)
1057 {
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);
1060
1061         int ret = vc_info_parser_set_nlu_result(nlu_result);
1062         if (0 != ret) {
1063                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set nlu result (%d)", ret);
1064         }
1065
1066         return;
1067 }
1068 #endif
1069
1070 int vcd_send_error(vce_error_e error, const char* msg, void *user_data)
1071 {
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);
1074
1075         char* error_msg = NULL;
1076         if (NULL != msg) {
1077                 error_msg = strdup(msg);
1078                 if (NULL == error_msg) {
1079                         return VCD_ERROR_OUT_OF_MEMORY;
1080                 }
1081         }
1082
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");
1087         }
1088
1089         if (NULL != error_msg) {
1090                 free(error_msg);
1091                 error_msg = NULL;
1092         }
1093
1094         return ret;
1095 }
1096
1097 /* for TTS feedback */
1098 int vcd_send_feedback_audio_format(int rate, vce_audio_channel_e channel, vce_audio_type_e audio_type)
1099 {
1100         SLOG(LOG_INFO, TAG_VCD, "[Server DEBUG] Engine - Send TTS feedback audio format");
1101
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");
1109         }
1110         } else {
1111                 SLOG(LOG_INFO, TAG_VCD, "[Server INFO] Do not send TTS feedback audio format to VC manager");
1112         }
1113
1114         return ret;
1115 }
1116
1117 int vcd_send_feedback_streaming(vce_feedback_event_e event, char* buffer, int len)
1118 {
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");
1123         }
1124
1125         int ret = VCD_ERROR_NONE;
1126         int pid = g_current_uid / 1000;
1127         int utt_id = g_current_uid % 1000;
1128
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));
1130
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");
1136                 }
1137         } else {
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");
1142         }
1143         }
1144
1145         if (VCE_FEEDBACK_EVENT_FINISH == event) {
1146                 /* reset current uid */
1147                 g_current_uid = -1;
1148         }
1149         return ret;
1150 }
1151
1152
1153 /*
1154 * vcd server Interfaces
1155 */
1156 static void __vcd_file_clean_up()
1157 {
1158         SLOG(LOG_DEBUG, TAG_VCD, "== Old file clean up == ");
1159
1160         DIR *dp = NULL;
1161         struct dirent *dirp = NULL;
1162
1163         dp = opendir(VC_RUNTIME_INFO_ROOT);
1164         if (dp == NULL) {
1165                 SLOG(LOG_ERROR, TAG_VCD, "[File message WARN] Fail to open path : %s", VC_RUNTIME_INFO_ROOT);
1166                 return;
1167         }
1168
1169         char remove_path[256] = {0, };
1170         do {
1171                 dirp = readdir(dp);
1172
1173                 if (NULL != dirp) {
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);
1177
1178                                 /* Clean up code */
1179                                 if (0 != remove(remove_path)) {
1180                                         SLOG(LOG_WARN, TAG_VCD, "[File message WARN] Fail to remove file : %s", remove_path);
1181                                 } else {
1182                                         SLOG(LOG_DEBUG, TAG_VCD, "[File message] Remove file : %s", remove_path);
1183                                 }
1184                         }
1185                 }
1186         } while (NULL != dirp);
1187
1188         closedir(dp);
1189
1190         return;
1191 }
1192
1193 static int __vcd_db_clean_up()
1194 {
1195         int ret = 0;
1196         int cnt = VC_COMMAND_TYPE_FOREGROUND;
1197         do {
1198                 if (VC_COMMAND_TYPE_BACKGROUND != cnt)
1199                         ret = vc_db_delete_commands(-1, cnt, NULL);
1200         } while (VC_COMMAND_TYPE_EXCLUSIVE >= ++cnt);
1201
1202         return ret;
1203 }
1204
1205 int vcd_initialize(vce_request_callback_s *callback)
1206 {
1207         int ret = 0;
1208
1209         /* Remove old file */
1210         __vcd_file_clean_up();
1211
1212         /* initialize modules */
1213         ret = vcd_config_initialize(__config_lang_changed_cb, __config_foreground_changed_cb, NULL);
1214         if (0 != ret) {
1215                 SLOG(LOG_ERROR, TAG_VCD, "[Server WARNING] Fail to initialize config.");
1216         }
1217
1218         /* Remove db data */
1219         ret = __vcd_db_clean_up();
1220         if (0 != ret) {
1221                 SLOG(LOG_ERROR, TAG_VCD, "[Server WARNING] Fail to remove db data");
1222         }
1223
1224         vcd_config_set_service_state(VCD_STATE_NONE);
1225
1226         ret = vcd_engine_agent_init();
1227         if (0 != ret) {
1228                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
1229                 return ret;
1230         }
1231
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;
1235         }
1236
1237         /* Load engine */
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;
1241         }
1242
1243         /* Initialize manager info */
1244         vcd_client_manager_unset();
1245
1246         vcd_config_set_service_state(VCD_STATE_READY);
1247 //      vcdc_send_service_state(VCD_STATE_READY);
1248
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");
1253         }
1254
1255         g_current_uid = -1;
1256         g_current_utt_id = -1;
1257
1258         SLOG(LOG_ERROR, TAG_VCD, "[Server SUCCESS] initialize");
1259
1260         return 0;
1261 }
1262
1263 bool vcd_finalize()
1264 {
1265         GList *iter = NULL;
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);
1271                 }
1272         }
1273
1274         if (NULL != g_restart_timer) {
1275                 ecore_timer_del(g_restart_timer);
1276                 g_restart_timer = NULL;
1277         }
1278
1279         if (NULL != g_check_client_timer) {
1280                 ecore_timer_del(g_check_client_timer);
1281                 g_check_client_timer = NULL;
1282         }
1283
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();
1288                 }
1289                 vcd_engine_recognize_cancel();
1290         }
1291
1292         if (0 != vcd_recorder_destroy()) {
1293                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to destroy recorder");
1294                 return false;
1295         } else {
1296                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] destroy recorder");
1297         }
1298
1299         if (0 != vcd_engine_agent_release()) {
1300                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to release engine");
1301                 return false;
1302         } else {
1303                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] release engine");
1304         }
1305
1306         vcd_client_manager_unset_appid();
1307
1308         vcd_config_set_service_state(VCD_STATE_NONE);
1309         vcdc_send_service_state(VCD_STATE_NONE);
1310
1311         SLOG(LOG_ERROR, TAG_VCD, "[Server] mode finalize");
1312
1313         return true;
1314 }
1315
1316 static Eina_Bool __finalize_quit_ecore_loop(void *data)
1317 {
1318         bool ret = vcd_finalize();
1319         if (false == ret) {
1320                 return EINA_TRUE;
1321         } else {
1322                 ecore_main_loop_quit();
1323                 return EINA_FALSE;
1324         }
1325 }
1326
1327 static void __read_proc()
1328 {
1329         DIR *dp = NULL;
1330         struct dirent *dirp = NULL;
1331         int tmp;
1332
1333         GList *iter = 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);
1339                 }
1340         }
1341
1342         dp = opendir("/proc");
1343         if (NULL == dp) {
1344                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to open proc");
1345         } else {
1346                 do {
1347                         dirp = readdir(dp);
1348
1349                         if (NULL != dirp) {
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));
1353                         }
1354                 } while (NULL != dirp);
1355                 closedir(dp);
1356         }
1357         return;
1358 }
1359
1360 static void __vcd_cleanup_client(vcd_client_type_e type)
1361 {
1362         int* client_list = NULL;
1363         int client_count = 0;
1364         int i = 0;
1365         int j = 0;
1366         bool exist = false;
1367         int mgr_pid = -1;
1368         int ret = -1;
1369
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;
1377                 client_count = 1;
1378                 if (-1 == mgr_pid) {
1379                         SLOG(LOG_WARN, TAG_VCD, "[WARNING] Invalid Manager pid");
1380                         return;
1381                 }
1382         }
1383
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++) {
1388                                 exist = false;
1389                                 GList *iter = NULL;
1390                                 for (j = 0; j < g_list_length(g_proc_list); j++) {
1391                                         iter = g_list_nth(g_proc_list, j);
1392                                         if (NULL != iter) {
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));
1395                                                         exist = true;
1396                                                         break;
1397                                                 }
1398                                         }
1399                                 }
1400
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));
1407                                         else
1408                                                 vcd_server_mgr_finalize(mgr_pid);
1409                                 }
1410                         }
1411                 }
1412                 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
1413         }
1414         if (NULL != client_list && -1 == mgr_pid) {
1415                 free(client_list);
1416                 client_list = NULL;
1417         }
1418         return;
1419 }
1420
1421 Eina_Bool vcd_cleanup_client_all(void *data)
1422 {
1423         __read_proc();
1424
1425         __vcd_cleanup_client(VCD_CLIENT_TYPE_NORMAL);
1426         __vcd_cleanup_client(VCD_CLIENT_TYPE_WIDGET);
1427         __vcd_cleanup_client(VCD_CLIENT_TYPE_MANAGER);
1428
1429 #if 0
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++) {
1434                                 exist = false;
1435                                 GList *iter = NULL;
1436                                 for (j = 0; j < g_list_length(g_proc_list); j++) {
1437                                         iter = g_list_nth(g_proc_list, j);
1438                                         if (NULL != iter) {
1439                                                 if (client_list[i] == GPOINTER_TO_INT(iter->data)) {
1440                                                         SLOG(LOG_DEBUG, TAG_VCD, "pid(%d) is running", client_list[i]);
1441                                                         exist = true;
1442                                                         break;
1443                                                 }
1444                                         }
1445                                 }
1446
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]);
1450                                 }
1451 #if 0
1452                                 result = vcdc_send_hello(client_list[i], VCD_CLIENT_TYPE_NORMAL);
1453
1454                                 if (0 == result) {
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");
1459                                 }
1460 #endif
1461                         }
1462                 }
1463                 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
1464         }
1465         if (NULL != client_list) {
1466                 free(client_list);
1467                 client_list = NULL;
1468         }
1469
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++) {
1475                                 exist = false;
1476                                 GList *iter = NULL;
1477                                 for (j = 0; j < g_list_length(g_proc_list); j++) {
1478                                         iter = g_list_nth(g_proc_list, j);
1479                                         if (NULL != iter) {
1480                                                 if (client_list[i] == GPOINTER_TO_INT(iter->data)) {
1481                                                         SLOG(LOG_DEBUG, TAG_VCD, "widget pid(%d) is running", client_list[i]);
1482                                                         exist = true;
1483                                                         break;
1484                                                 }
1485                                         }
1486                                 }
1487
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]);
1491                                 }
1492 #if 0
1493                                 result = vcdc_send_hello(client_list[i], VCD_CLIENT_TYPE_WIDGET);
1494
1495                                 if (0 == result) {
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");
1500                                 }
1501 #endif
1502                         }
1503                 }
1504                 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
1505         }
1506
1507         if (NULL != client_list) {
1508                 free(client_list);
1509                 client_list = NULL;
1510         }
1511
1512         /* manager */
1513         exist = false;
1514         GList *iter = NULL;
1515         int mgr_pid = vcd_client_manager_get_pid();
1516         if (0 < mgr_pid) {
1517                 for (j = 0; j < g_list_length(g_proc_list); j++) {
1518                         iter = g_list_nth(g_proc_list, j);
1519                         if (NULL != iter) {
1520                                 if (mgr_pid == GPOINTER_TO_INT(iter->data)) {
1521                                         SLOG(LOG_DEBUG, TAG_VCD, "manager pid(%d) is running", mgr_pid);
1522                                         exist = true;
1523                                         break;
1524                                 }
1525                         }
1526                 }
1527
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);
1531                 }
1532         }
1533 #endif
1534         return EINA_TRUE;
1535 }
1536
1537 int vcd_server_get_service_state()
1538 {
1539         return vcd_config_get_service_state();
1540 }
1541
1542 int vcd_server_get_foreground()
1543 {
1544         int pid;
1545         vcd_config_get_foreground(&pid);
1546         return pid;
1547 }
1548
1549
1550 /*
1551 * API for manager
1552 */
1553 int vcd_server_mgr_initialize(int pid)
1554 {
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();
1560         }
1561
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;
1566         }
1567
1568         if (0 != vcdc_send_manager_pid(pid))
1569                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send manager pid");
1570
1571         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Manager initialize : pid(%d)", pid);
1572
1573         return VCD_ERROR_NONE;
1574 }
1575
1576 int vcd_server_mgr_finalize(int pid)
1577 {
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;
1582         }
1583
1584         /* Cancel recognition */
1585         vcd_server_mgr_cancel();
1586
1587         if (0 != vcdc_send_manager_pid(-1))
1588                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send manager pid");
1589
1590         /* Remove manager information */
1591         if (0 != vcd_client_manager_unset()) {
1592                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
1593         }
1594
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);
1598         }
1599
1600         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Manager Finalize : pid(%d)", pid);
1601
1602         return VCD_ERROR_NONE;
1603 }
1604
1605 int vcd_server_mgr_set_command(int pid)
1606 {
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;
1610         }
1611         return VCD_ERROR_NONE;
1612 }
1613
1614 int vcd_server_mgr_unset_command(int pid)
1615 {
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;
1619         }
1620         return VCD_ERROR_NONE;
1621 }
1622
1623 int vcd_server_mgr_set_demandable_client(int pid)
1624 {
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;
1629         }
1630
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;
1635         }
1636
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;
1641         }
1642
1643         return VCD_ERROR_NONE;
1644 }
1645
1646 int vcd_server_mgr_set_audio_type(int pid, const char* audio_type)
1647 {
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;
1652         }
1653
1654         int ret = 0;
1655         vce_audio_type_e type = VCE_AUDIO_TYPE_PCM_S16_LE;
1656         int rate = 16000;
1657         int channel = 1;
1658
1659         ret = vcd_engine_get_audio_format(audio_type, &type, &rate, &channel);
1660         if (0 != ret) {
1661                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio format : %d", ret);
1662                 return VCD_ERROR_OPERATION_FAILED;
1663         }
1664
1665         ret = vcd_recorder_set(audio_type, type, rate, channel);
1666         if (0 != ret) {
1667                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set audio in type : %d", ret);
1668                 return VCD_ERROR_OPERATION_FAILED;
1669         }
1670
1671         return VCD_ERROR_NONE;
1672 }
1673
1674 int vcd_server_mgr_get_audio_type(int pid, char** audio_type)
1675 {
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;
1680         }
1681
1682         int ret = vcd_recorder_get(audio_type);
1683         if (0 != ret) {
1684                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio in type : %d", ret);
1685                 return VCD_ERROR_OPERATION_FAILED;
1686         }
1687
1688         return VCD_ERROR_NONE;
1689 }
1690
1691 int vcd_server_mgr_set_client_info(int pid)
1692 {
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;
1697         }
1698
1699         int ret = vcd_client_save_client_info();
1700         if (0 != ret) {
1701                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to save client info : %d", ret);
1702                 return VCD_ERROR_OPERATION_FAILED;
1703         }
1704
1705         return VCD_ERROR_NONE;
1706 }
1707
1708 static int __reset_waiting_for_widget_recording(void)
1709 {
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;
1715         }
1716         // Reset flag to wait for recording from widget client
1717         vcd_client_widget_set_waiting_for_recording(-1, false);
1718         return 0;
1719 }
1720
1721 #if 0
1722 static Eina_Bool __send_waiting_timeout_error_to_manager(void* data)
1723 {
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();
1728
1729         vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail");
1730         return EINA_FALSE;
1731 }
1732 #else
1733 static Eina_Bool __send_waiting_timeout_start_recording(void* data)
1734 {
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);
1738
1739         int ret = __start_internal_recognition();
1740         if (0 != ret) {
1741                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition : %d", ret);
1742                 return ret;
1743         }
1744         return EINA_FALSE;
1745 }
1746 #endif
1747
1748 static int __set_waiting_for_widget_recording(int pid)
1749 {
1750         SLOG(LOG_ERROR, TAG_VCD, "[Server] Set waiting for widget recording, pid(%d)", pid);
1751
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);
1756
1757         // Set flag to wait for recording from widget client
1758         vcd_client_widget_set_waiting_for_recording(pid, true);
1759         return 0;
1760 }
1761
1762 static int __start_internal_recognition()
1763 {
1764         int ret;
1765         __reset_waiting_for_widget_recording();
1766
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();
1771                 if (-1 != 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;
1774         }
1775
1776         /* 3. Set command to engine */
1777         ret = vcd_engine_set_commands();
1778         if (0 != ret) {
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();
1782                 if (-1 != 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;
1785         }
1786
1787         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Set command");
1788
1789         bool stop_by_silence = true;
1790         if (VCD_RECOGNITION_MODE_MANUAL == vcd_client_get_recognition_mode()) {
1791                 stop_by_silence = false;
1792         }
1793
1794         vcd_client_manager_set_result_text(NULL);
1795
1796         /* 4. start recognition */
1797         ret = vcd_engine_recognize_start(stop_by_silence);
1798         if (0 != ret) {
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();
1802                 if (-1 != 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;
1805         }
1806
1807         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Start engine");
1808
1809 #if 1
1810         /* 5. recorder start */
1811         ret = vcd_recorder_start();
1812         if (0 != ret) {
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();
1817                 if (-1 != pid)
1818                         vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail");
1819                 return ret;
1820         }
1821 #endif
1822
1823         vcd_config_set_service_state(VCD_STATE_RECORDING);
1824         vcdc_send_service_state(VCD_STATE_RECORDING);
1825
1826         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Start recognition(%d)", stop_by_silence);
1827
1828         return 0;
1829 }
1830
1831 static Eina_Bool __vcd_request_show_tooltip(void *data)
1832 {
1833         int pid = vcd_client_widget_get_foreground_pid();
1834         if (-1 != 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);
1837         }
1838
1839         return EINA_FALSE;
1840 }
1841
1842 int vcd_server_mgr_start(vcd_recognition_mode_e recognition_mode, bool exclusive_cmd, bool start_by_client)
1843 {
1844         /* 1. check current state */
1845         vcd_state_e state = vcd_config_get_service_state();
1846
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;
1850         }
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;
1854         }
1855         __reset_waiting_for_widget_recording();
1856
1857         SLOG(LOG_ERROR, TAG_VCD, "[Server] set recognition mode = %d", recognition_mode);
1858         vcd_client_set_recognition_mode(recognition_mode);
1859
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();
1865                         if (-1 != 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);
1868
1869                                 __set_waiting_for_widget_recording(pid);
1870                                 return 0;
1871                         }
1872                 }
1873         } else {
1874                 vcd_client_manager_set_exclusive(exclusive_cmd);
1875         }
1876
1877         int fg_pid = -1;
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");
1882                 }
1883
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");
1887                 }
1888         }
1889
1890         SLOG(LOG_ERROR, TAG_VCD, "[Server] start internal recognition");
1891
1892         int ret = __start_internal_recognition();
1893         if (0 != ret) {
1894                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition : %d", ret);
1895                 return ret;
1896         }
1897
1898         if (true == start_by_client) {
1899                 vcd_client_unset_exclusive_command(fg_pid);
1900         }
1901
1902         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] start internal recognition");
1903         return VCD_ERROR_NONE;
1904 }
1905
1906 int vcd_server_mgr_stop()
1907 {
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;
1912         }
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;
1916         }
1917         SLOG(LOG_ERROR, TAG_VCD, "[Server] stop internal recognition");
1918
1919 #if 1
1920         /* 2. Stop recorder */
1921         vcd_recorder_stop();
1922 #endif
1923
1924         /* 3. Stop engine recognition */
1925         int ret = vcd_engine_recognize_stop();
1926         if (0 != ret) {
1927                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
1928         }
1929
1930         /* 4. Set original mode */
1931         vcd_config_set_service_state(VCD_STATE_PROCESSING);
1932         vcdc_send_service_state(VCD_STATE_PROCESSING);
1933
1934         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] stop internal recognition");
1935         return VCD_ERROR_NONE;
1936 }
1937
1938 int vcd_server_mgr_cancel()
1939 {
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;
1943         }
1944
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;
1949         }
1950
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();
1956
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();
1960                                 if (-1 != pid) {
1961                                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
1962                                         ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
1963                                 }
1964                         }
1965                 }
1966
1967                 vcdc_send_service_state(VCD_STATE_READY);
1968                 return VCD_ERROR_NONE;
1969         }
1970         SLOG(LOG_ERROR, TAG_VCD, "[Server] cancel internal recognition");
1971
1972 #if 1
1973         /* 2. Stop recorder */
1974         vcd_recorder_stop();
1975 #endif
1976
1977         /* 3. Cancel engine */
1978         int ret = vcd_engine_recognize_cancel();
1979         if (0 != ret) {
1980                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to cancel : %d", ret);
1981         }
1982
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();
1986                         if (-1 != pid) {
1987                                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
1988                                 ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
1989                         }
1990                 }
1991         } else {
1992                 vcd_client_manager_set_exclusive(false);
1993         }
1994
1995         /* 4. Set state */
1996         vcd_config_set_service_state(VCD_STATE_READY);
1997         vcdc_send_service_state(VCD_STATE_READY);
1998
1999         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] cancel internal recognition");
2000         return VCD_ERROR_NONE;
2001 }
2002
2003
2004 int vcd_server_mgr_result_select()
2005 {
2006         __vcd_send_selected_result(NULL);
2007
2008         return VCD_ERROR_NONE;
2009 }
2010
2011 int vcd_server_mgr_set_domain(int pid, const char* domain)
2012 {
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;
2017         }
2018
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;
2023         }
2024
2025         /* Set domain to engine */
2026         int ret = vcd_engine_set_domain(pid, domain);
2027         if (0 != ret) {
2028                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set domain : %d", ret);
2029         } else {
2030                 SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Set domain");
2031         }
2032
2033         return ret;
2034 }
2035
2036 int vcd_server_mgr_set_private_data(int pid, const char* key, const char* data)
2037 {
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;
2042         }
2043
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;
2048         }
2049
2050         /* Set private data to engine */
2051         int ret = vcd_engine_set_private_data(pid, key, data);
2052         if (0 != ret) {
2053                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data : %d", ret);
2054         } else {
2055                 SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Set private data");
2056         }
2057
2058         return ret;
2059 }
2060
2061 int vcd_server_mgr_get_private_data(int pid, const char* key, char** data)
2062 {
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;
2067         }
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;
2072         }
2073
2074         /* Get private data to engine */
2075         int ret = vcd_engine_get_private_data(pid, key, data);
2076         if (0 != ret) {
2077                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get private data : %d", ret);
2078         } else {
2079                 SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Set private data");
2080         }
2081
2082         return ret;
2083 }
2084
2085 int vcd_server_mgr_send_specific_engine_request(int pid, const char* engine_app_id, const char* event, const char* request)
2086 {
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;
2091         }
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;
2096         }
2097
2098         /* Get private data to engine */
2099         int ret = vcd_engine_send_specific_engine_request(engine_app_id, event, request);
2100         if (0 != ret) {
2101                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set specific engine request : %d", ret);
2102         } else {
2103                 SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Set specific engine request ");
2104         }
2105
2106         return ret;
2107 }
2108
2109 int vcd_server_mgr_do_action(int pid, int type, const char* action)
2110 {
2111         int ret = -1;
2112
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;
2117         }
2118
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;
2123         }
2124
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);
2132
2133         if (0 != ret) {
2134                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to process do action : %d", ret);
2135         } else {
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");
2139         }
2140
2141         return ret;
2142 }
2143
2144 int vcd_server_mgr_enable_command_type(int pid, int cmd_type)
2145 {
2146         int ret = -1;
2147
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;
2152         }
2153
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;
2158         }
2159
2160         ret = vcd_config_enable_command_type(cmd_type);
2161         if (0 != ret) {
2162                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to enable command type");
2163         } else {
2164                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Enable command type(%d)", cmd_type);
2165         }
2166
2167         return ret;
2168 }
2169
2170 int vcd_server_mgr_disable_command_type(int pid, int cmd_type)
2171 {
2172         int ret = -1;
2173
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;
2178         }
2179
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;
2184         }
2185
2186         ret = vcd_config_disable_command_type(cmd_type);
2187         if (0 != ret) {
2188                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to disable command type");
2189         } else {
2190                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Disable command type(%d)", cmd_type);
2191         }
2192
2193         return ret;
2194 }
2195
2196 /* for TTS feedback */
2197 int vcd_server_mgr_start_feedback(void)
2198 {
2199         /* check current state */
2200         /* not Recording??? */
2201
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;
2205         }
2206
2207         SLOG(LOG_DEBUG, TAG_VCD, "[Server] start TTS feedback");
2208
2209         /* check there is TTS buffer to be spoken */
2210
2211         return VCD_ERROR_NONE;
2212 }
2213
2214 int vcd_server_mgr_stop_feedback(void)
2215 {
2216         /* check current state */
2217         /* not Recording??? */
2218
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;
2222         }
2223
2224         SLOG(LOG_DEBUG, TAG_VCD, "[Server] stop TTS feedback");
2225
2226         return VCD_ERROR_NONE;
2227 }
2228
2229 int vcd_server_mgr_send_audio_streaming(int pid, int event, unsigned char* buffer, unsigned int len)
2230 {
2231         SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] Send Audio Streaming from Multi-assistant. event(%d), buffer(%p), len(%d)", event, &buffer, len);
2232
2233         int ret = 0;
2234         if (VCD_AUDIO_STREAMING_EVENT_START == event) {
2235                 ret = vcd_recorder_start_streaming();
2236                 if (0 != ret) {
2237                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to start streaming, ret(%d)", ret);
2238                         return ret;
2239                 }
2240         }
2241
2242         ret = vcd_recorder_send_streaming((const void*)buffer, (const unsigned int)len);
2243         if (0 != ret) {
2244                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to start streaming, ret(%d)", ret);
2245                 return ret;
2246         }
2247
2248         if (VCD_AUDIO_STREAMING_EVENT_FINISH == event) {
2249                 ret = vcd_recorder_stop_streaming();
2250                 if (0 != ret) {
2251                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to stop streaming, ret(%d)", ret);
2252                         return ret;
2253                 }
2254         }
2255
2256         return VCD_ERROR_NONE;
2257 }
2258
2259
2260 /*
2261 * VC Server Functions for Client
2262 */
2263 int vcd_server_initialize(int pid)
2264 {
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;
2268         }
2269
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;
2274         }
2275
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;
2280         }
2281
2282         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Client Initialize : pid(%d)", pid);
2283
2284         return VCD_ERROR_NONE;
2285 }
2286
2287 int vcd_server_finalize(int pid)
2288 {
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;
2293         }
2294
2295         /* Remove client information */
2296         if (0 != vcd_client_delete(pid)) {
2297                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
2298         }
2299
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);
2303         }
2304
2305         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Client Finalize : pid(%d)", pid);
2306
2307         return VCD_ERROR_NONE;
2308 }
2309
2310 int vcd_server_set_command(int pid, vc_cmd_type_e cmd_type)
2311 {
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;
2316         }
2317
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;
2321         }
2322
2323         return 0;
2324 }
2325
2326 int vcd_server_unset_command(int pid, vc_cmd_type_e cmd_type)
2327 {
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;
2332         }
2333
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;
2337         }
2338
2339         return 0;
2340 }
2341
2342 int vcd_server_set_foreground(int pid, bool value)
2343 {
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;
2348         }
2349
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;
2353         }
2354
2355         return 0;
2356 }
2357
2358 static int __vcd_server_launch_manager_app()
2359 {
2360         int ret = -1;
2361         bool running = false;
2362         char* appid = NULL;
2363
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;
2368         }
2369         ret = app_manager_is_running(appid, &running);
2370         if (0 != ret) {
2371                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to check running with appid(%s)", appid);
2372                 free(appid);
2373                 appid = NULL;
2374                 return VCD_ERROR_OPERATION_FAILED;
2375         }
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);
2380                 } else {
2381                         ret = __vcd_activate_app_by_appcontrol(appid);
2382                         if (0 != ret) {
2383                                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to activate app");
2384                                 free(appid);
2385                                 appid = NULL;
2386                                 return ret;
2387                         }
2388                         SLOG(LOG_ERROR, TAG_VCD, "Launch vc manager app: appid(%s)", appid);
2389                 }
2390         } else {
2391                 ret = __vcd_resume_app(appid);
2392                 if (0 != ret) {
2393                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to resume app");
2394                         free(appid);
2395                         appid = NULL;
2396                         return ret;
2397                 }
2398                 SLOG(LOG_ERROR, TAG_VCD, "Resume vc manager app: appid(%s)", appid);
2399         }
2400
2401         free(appid);
2402         appid = NULL;
2403
2404         return VCD_ERROR_NONE;
2405 }
2406
2407 int vcd_server_set_server_dialog(int pid, const char* app_id, const char* credential)
2408 {
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;
2413         }
2414
2415         int ret = vcd_engine_set_server_dialog(app_id, credential);
2416         if (0 != ret) {
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);
2419                 return ret;
2420         }
2421         SLOG(LOG_ERROR, TAG_VCD, "[Success] Set server dialog, pid(%d), app_id(%s)", pid, app_id);
2422
2423         if (0 != strncmp(credential, "#NULL", strlen(credential))) {
2424                 ret = vcd_client_set_server_dialog(pid, true);
2425                 if (0 != ret)
2426                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set to true for server dialog, app_id(%s)", app_id);
2427         } else {
2428                 ret = vcd_client_set_server_dialog(pid, false);
2429                 if (0 != ret)
2430                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set to false for server dialog, app_id(%s)", app_id);
2431         }
2432
2433         return 0;
2434 }
2435
2436 int vcd_server_dialog(int pid, const char* disp_text, const char* utt_text, int continuous)
2437 {
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;
2442         }
2443
2444         bool is_server_dialog = false;
2445         int ret = vcd_client_get_server_dialog(pid, &is_server_dialog);
2446         if (0 != ret) {
2447                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get server dialog, pid(%d), ret(%d)", pid, ret);
2448         }
2449
2450         if (true == is_server_dialog) {
2451                 /* ++ Request tts event to engine */
2452
2453                 /* -- Request tts event to engine */
2454         } else {
2455                 ret = __vcd_server_launch_manager_app();
2456                 if (0 != ret) {
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);
2458                         return ret;
2459                 }
2460
2461                 ret = vcdc_send_dialog(vcd_client_manager_get_pid(), pid, disp_text, utt_text, continuous);
2462                 if (0 != ret) {
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);
2464                         return ret;
2465                 }
2466         }
2467         return 0;
2468 }
2469
2470 int vcd_server_is_system_command_valid(int pid, int* is_sys_cmd_valid)
2471 {
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;
2476         }
2477
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;
2481         else
2482                 *is_sys_cmd_valid = false;
2483
2484         return 0;
2485 }
2486
2487 static void __start_tts_request_thread(void* data, Ecore_Thread* thread)
2488 {
2489         SLOG(LOG_DEBUG, TAG_VCD, "[SUCCESS] Start tts request thread");
2490         vc_tts_text_data_s* tts_text_data = NULL;
2491
2492         while (1) {
2493                 int ret = -1;
2494
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) {
2498                         /* empty queue */
2499                         if (0 >= vcd_data_get_tts_text_data_size()) {
2500                                 SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] No tts text data");
2501                                 return;
2502                         }
2503                         SLOG(LOG_INFO, TAG_VCD, "[INFO] tts text data is just incoming");
2504                         continue;
2505                 }
2506
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);
2509                 if (0 != ret) {
2510                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to request tts : %d", ret);
2511                 } else {
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);
2514                 }
2515                 /* clear tts text data after use */
2516                 vcd_data_clear_tts_text_data(&tts_text_data);
2517
2518         }
2519 }
2520
2521 static void __end_tts_request_thread(void* data, Ecore_Thread* thread)
2522 {
2523         SLOG(LOG_DEBUG, TAG_VCD, "[SUCCESS] End tts request thread");
2524         g_tts_thread = NULL;
2525 }
2526
2527 int vcd_server_request_tts(int pid, const char* text, const char* language, int to_vcm, int* utt_id)
2528 {
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;
2533         }
2534
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;
2539         }
2540
2541         g_current_utt_id = (g_current_utt_id + 1) % 1000;
2542         *utt_id = g_current_utt_id;
2543         if (0 == to_vcm) {
2544                 g_current_uid = pid * 1000 + g_current_utt_id;
2545         } else {
2546                 g_current_uid = vcd_client_manager_get_pid() * 1000 + g_current_utt_id;
2547         }
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);
2550
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;
2556         }
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);
2562
2563         int ret = vcd_data_add_tts_text_data(tts_text_data->uid, tts_text_data);
2564         if (0 != ret) {
2565                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add tts text data : %d", ret);
2566         }
2567
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);
2572         }
2573
2574         return 0;
2575 }
2576
2577 int vcd_server_cancel_tts(int pid, int utt_id)
2578 {
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;
2583         }
2584
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;
2589         }
2590
2591         vc_tts_text_data_s* tts_text_data = NULL;
2592
2593         int uid = pid * 1000 + utt_id;
2594         int ret = vcd_data_get_tts_text_data(uid, &tts_text_data);
2595         if (0 != ret) {
2596                 SLOG(LOG_WARN, TAG_VCD, "[Server WARN] No data in vcd tts text queue");
2597         } else {
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);
2600         }
2601
2602         /* Request tts to engine */
2603         ret = vcd_engine_cancel_tts(pid, utt_id);
2604         if (0 != ret) {
2605                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to cancel tts : %d", ret);
2606         } else {
2607                 SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] request tts, pid(%d), utt_id(%d)", pid, utt_id);
2608         }
2609
2610         return 0;
2611 }
2612
2613 int vcd_server_get_tts_audio_format(int pid, int* rate, int* channel, int* audio_type)
2614 {
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;
2619         }
2620
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;
2625         }
2626
2627         /* Request tts to engine */
2628         int ret = vcd_engine_get_tts_audio_format(rate, channel, audio_type);
2629         if (0 != ret) {
2630                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get tts audio format : %d", ret);
2631         } else {
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);
2633         }
2634
2635         return ret;
2636 }
2637
2638 #if 0
2639 int vcd_server_set_exclusive_command(int pid, bool value)
2640 {
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;
2645         }
2646
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;
2651                 }
2652         } else {
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;
2656                 }
2657         }
2658
2659         return 0;
2660 }
2661
2662 int vcd_server_request_start(int pid, bool stop_by_silence)
2663 {
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;
2668         }
2669
2670         int ret;
2671         /* Check current state */
2672         vcd_state_e state = vcd_config_get_service_state();
2673
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;
2678         }
2679
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;
2685                 }
2686         }
2687
2688         ret = vcd_server_mgr_start(stop_by_silence, false);
2689         if (0 != ret) {
2690                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
2691                 return VCD_ERROR_INVALID_PARAMETER;
2692         }
2693
2694         return 0;
2695 }
2696
2697 int vcd_server_request_stop(int pid)
2698 {
2699         int ret;
2700         /* Check current state */
2701         vcd_state_e state = vcd_config_get_service_state();
2702
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;
2707         }
2708
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;
2714                 }
2715         }
2716
2717         ret = vcd_server_mgr_stop();
2718         if (0 != ret) {
2719                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
2720                 return VCD_ERROR_OPERATION_FAILED;
2721         }
2722
2723         return VCD_ERROR_NONE;
2724 }
2725
2726 int vcd_server_request_cancel(int pid)
2727 {
2728         int ret;
2729         /* Check current state */
2730         vcd_state_e state = vcd_config_get_service_state();
2731
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;
2736         }
2737
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;
2743                 }
2744         }
2745
2746         ret = vcd_server_mgr_cancel();
2747         if (0 != ret) {
2748                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
2749                 return VCD_ERROR_OPERATION_FAILED;
2750         }
2751
2752         return VCD_ERROR_NONE;
2753 }
2754 #endif
2755
2756 /*
2757 * VC Server Functions for Widget lib
2758 */
2759 int vcd_server_widget_initialize(int pid)
2760 {
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;
2764         }
2765
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;
2770         }
2771
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;
2776         }
2777
2778         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Initialize widget : pid(%d)", pid);
2779
2780         return VCD_ERROR_NONE;
2781 }
2782
2783 static void __vcd_server_widget_start_recording(void *data)
2784 {
2785         SLOG(LOG_ERROR, TAG_VCD, "[Server INFO] start recording");
2786
2787         if (0 != __start_internal_recognition()) {
2788                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition");
2789         }
2790 }
2791
2792 int vcd_server_widget_finalize(int pid)
2793 {
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;
2798         }
2799
2800         /* Remove client information */
2801         if (0 != vcd_client_widget_delete(pid)) {
2802                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
2803         }
2804
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);
2808                 return 0;
2809         }
2810
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");
2814         }
2815
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);
2819         }
2820         return VCD_ERROR_NONE;
2821 }
2822
2823 int vcd_server_widget_start_recording(int pid, bool widget_command)
2824 {
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;
2829         }
2830
2831         bool waiting;
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);
2834                 return 0;
2835         }
2836
2837         if (true == widget_command) {
2838                 vcd_client_widget_set_command(pid);
2839                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget command is available");
2840         } else {
2841                 vcd_client_widget_unset_command(pid);
2842                 SLOG(LOG_WARN, TAG_VCD, "[Server] widget command is NOT available");
2843         }
2844
2845         SLOG(LOG_ERROR, TAG_VCD, "[Server] start internal recognition : %d", widget_command);
2846         int ret = __start_internal_recognition();
2847         if (0 != ret) {
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);
2850         }
2851
2852         return 0;
2853 }
2854
2855 int vcd_server_widget_start(int pid, bool stop_by_silence)
2856 {
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;
2862         }
2863
2864         /* Check current state */
2865         vcd_state_e state = vcd_config_get_service_state();
2866
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;
2871         }
2872
2873         vcd_client_set_slience_detection(stop_by_silence);
2874
2875         /* Notify show tooltip */
2876         ecore_timer_add(0, __vcd_request_show_tooltip, (void*)true);
2877
2878         return 0;
2879 }
2880
2881 int vcd_server_widget_stop(int pid)
2882 {
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;
2888         }
2889
2890         int ret;
2891         /* Check current state */
2892         vcd_state_e state = vcd_config_get_service_state();
2893
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;
2898         }
2899
2900         ret = vcd_server_mgr_stop();
2901         if (0 != ret) {
2902                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
2903                 return VCD_ERROR_OPERATION_FAILED;
2904         }
2905
2906         return VCD_ERROR_NONE;
2907 }
2908
2909 int vcd_server_widget_cancel(int pid)
2910 {
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;
2916         }
2917
2918         int ret;
2919         /* Check current state */
2920         vcd_state_e state = vcd_config_get_service_state();
2921
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;
2926         }
2927
2928         ret = vcd_server_mgr_cancel();
2929         if (0 != ret) {
2930                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to cancel recognition : %d", ret);
2931                 return ret;
2932         }
2933
2934         return VCD_ERROR_NONE;
2935 }
2936
2937 int vcd_server_widget_enable_asr_result(int pid, bool enable)
2938 {
2939         int ret;
2940         ret = vcd_client_widget_set_asr_result_enabled(pid, enable);
2941         if (0 != ret) {
2942                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to enable asr result : %d", ret);
2943         }
2944
2945         return ret;
2946 }
2947
2948 int vcd_server_set_language(const char* language)
2949 {
2950         int ret = VCD_ERROR_NONE;
2951
2952         ret = vcd_config_set_default_language(language);
2953         if (0 != ret) {
2954                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to set language : %d", ret);
2955                 return ret;
2956         }
2957
2958         ret = vcd_engine_set_current_language(language);
2959         if (0 != ret) {
2960                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to set language : %d", ret);
2961                 return ret;
2962         }
2963
2964         return ret;
2965 }
2966 /*
2967 * For engine service
2968 */
2969 int vcd_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data)
2970 {
2971         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Get foreach command");
2972
2973         if (NULL == callback) {
2974                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] input parameter is NULL");
2975                 return VCD_ERROR_INVALID_PARAMETER;
2976         }
2977
2978         int ret = 0;
2979         ret = vcd_engine_agent_get_foreach_command(vce_command, callback, user_data);
2980         if (0 != ret) {
2981                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get foreach command : ret(%d)", ret);
2982         }
2983
2984         return ret;
2985 }
2986
2987 int vcd_get_command_count(vce_cmd_h vce_command, int* count)
2988 {
2989         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Get command count");
2990
2991         int ret = 0;
2992         ret = vcd_engine_agent_get_command_count(vce_command, count);
2993         if (0 != ret) {
2994                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get command count : ret(%d)", ret);
2995         }
2996
2997         return ret;
2998 }
2999
3000 int vcd_get_audio_type(char** audio_type)
3001 {
3002         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Get audio type");
3003
3004         int ret = 0;
3005         ret = vcd_engine_agent_get_audio_type(audio_type);
3006         if (0 != ret) {
3007                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio type : ret(%d)", ret);
3008         }
3009
3010         return ret;
3011 }
3012
3013 int vcd_set_private_data(const char* key, const char* data)
3014 {
3015         vcd_state_e state = vcd_config_get_service_state();
3016
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;
3020         }
3021
3022         int ret = vcd_engine_agent_set_private_data(key, data);
3023         if (0 != ret) {
3024                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data to the manager client : ret(%d)", ret);
3025         } else {
3026                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set private data to the manager client, key(%s), data(%s)", key, data);
3027         }
3028
3029         return ret;
3030 }
3031
3032 int vcd_get_private_data(const char* key, char** data)
3033 {
3034         vcd_state_e state = vcd_config_get_service_state();
3035
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;
3039         }
3040
3041         int ret = vcd_engine_agent_get_private_data(key, data);
3042         if (0 != ret) {
3043                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get private data from the manager client : ret(%d)", ret);
3044         } else {
3045                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Get private data from the manager client, key(%s), data(%s)", key, *data);
3046         }
3047
3048         return ret;
3049 }
3050
3051 int vcd_start_recording()
3052 {
3053         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Start recording");
3054
3055         int ret = 0;
3056         ret = vcd_engine_agent_start_recording();
3057         if (0 != ret) {
3058                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recording : ret(%d)", ret);
3059         }
3060
3061         return ret;
3062 }
3063
3064 int vcd_stop_recording()
3065 {
3066         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Stop recording");
3067
3068         int ret = 0;
3069         ret = vcd_engine_agent_stop_recording();
3070         if (0 != ret) {
3071                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recording : ret(%d)", ret);
3072         }
3073
3074         return ret;
3075 }
3076
3077 int vcd_set_private_data_set_cb(vce_private_data_set_cb callback_func)
3078 {
3079         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set private data set cb");
3080
3081         int ret = 0;
3082         ret = vcd_engine_agent_set_private_data_set_cb(callback_func);
3083         if (0 != ret) {
3084                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data set cb : ret(%d)", ret);
3085         }
3086
3087         return ret;
3088 }
3089
3090 int vcd_set_private_data_requested_cb(vce_private_data_requested_cb callback_func)
3091 {
3092         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set private data requested cb");
3093
3094         int ret = 0;
3095         ret = vcd_engine_agent_set_private_data_requested_cb(callback_func);
3096         if (0 != ret) {
3097                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data requested cb : ret(%d)", ret);
3098         }
3099
3100         return ret;
3101 }
3102
3103 int vcd_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func)
3104 {
3105         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set nlu base info requested cb");
3106
3107         int ret = 0;
3108         ret = vcd_engine_agent_set_nlu_base_info_requested_cb(callback_func);
3109         if (0 != ret) {
3110                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set nlu base info requested cb : ret(%d)", ret);
3111         }
3112
3113         return ret;
3114 }
3115
3116 int vcd_set_specific_engine_request_cb(vce_specific_engine_request_cb callback_func)
3117 {
3118         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set specific engine request cb");
3119         int ret = 0;
3120         ret = vcd_engine_agent_set_specific_engine_request_cb(callback_func);
3121         if (0 != ret) {
3122                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set specific engine request cb : ret(%d)", ret);
3123         }
3124
3125         return ret;
3126 }
3127
3128 int vcd_set_request_tts_cb(vce_request_tts_cb callback_func, void* user_data)
3129 {
3130         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set request tts cb");
3131         int ret = 0;
3132         ret = vcd_engine_agent_set_request_tts_cb(callback_func, user_data);
3133         if (0 != ret) {
3134                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set request tts cb : ret(%d)", ret);
3135         }
3136
3137         return ret;
3138 }
3139
3140 int vcd_set_cancel_tts_cb(vce_cancel_tts_cb callback_func, void* user_data)
3141 {
3142         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set cancel tts cb");
3143         int ret = 0;
3144         ret = vcd_engine_agent_set_cancel_tts_cb(callback_func, user_data);
3145         if (0 != ret) {
3146                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set cancel tts cb : ret(%d)", ret);
3147         }
3148
3149         return ret;
3150 }
3151
3152 int vcd_set_tts_audio_format_request_cb(vce_tts_audio_format_request_cb callback_func, void* user_data)
3153 {
3154         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set tts audio format request cb");
3155         int ret = 0;
3156         ret = vcd_engine_agent_set_get_tts_audio_format_cb(callback_func, user_data);
3157         if (0 != ret) {
3158                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set tts audio format request : ret(%d)", ret);
3159         }
3160
3161         return ret;
3162 }