Rearrange the scope of each temporary variables
[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
21 #include "vc_cmd_db.h"
22 #include "vc_info_parser.h"
23 #include "vcd_main.h"
24 #include "vcd_server.h"
25 #include "vcd_server_data.h"
26 #include "vcd_client_data.h"
27
28 #include "vcd_engine_agent.h"
29 #include "vcd_config.h"
30 #include "vcd_recorder.h"
31 #include "vcd_tidl.h"
32 #include "vce_internal.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 unsigned int g_current_tts_uid = VC_INVALID_TTS_UID;
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 inline int __get_tts_played_pid()
67 {
68         return g_current_tts_uid > VC_INVALID_TTS_UID ? g_current_tts_uid / 1000 : VC_INVALID_TTS_UID;
69 }
70
71 static Eina_Bool __stop_by_silence(void *data)
72 {
73         SLOG(LOG_INFO, TAG_VCD, "@@@ Silence Detected ");
74
75         vcd_server_mgr_stop();
76
77         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Silence Detected DONE");
78         return EINA_FALSE;
79 }
80
81 static Eina_Bool __cancel_by_interrupt(void *data)
82 {
83         SLOG(LOG_INFO, TAG_VCD, "@@@ Cancel by interrupt");
84
85         vcd_server_mgr_cancel();
86
87         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Cancel by interrupt DONE");
88         return EINA_FALSE;
89 }
90
91 static void __cancel_by_error(void *data)
92 {
93         SLOG(LOG_INFO, TAG_VCD, "@@@ Cancel by error");
94
95         vcd_server_mgr_cancel();
96
97         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Cancel by error DONE");
98         return;
99 }
100
101 static Eina_Bool __restart_engine(void *data)
102 {
103         SLOG(LOG_INFO, TAG_VCD, "@@@ Restart by no result");
104
105         g_restart_timer = NULL;
106
107         /* Restart recognition */
108         int ret = vcd_engine_recognize_start(true);
109         if (0 != ret) {
110                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to restart recognition : result(%d)", ret);
111                 return EINA_FALSE;
112         }
113
114         SLOG(LOG_INFO, TAG_VCD, "[Server Success] Start engine");
115
116         vcd_recognition_mode_e mode = vcd_client_get_recognition_mode();
117         if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == mode || VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY == mode) {
118                 vcd_config_set_service_state(VCD_STATE_RECORDING);
119                 vcdc_send_service_state(VCD_STATE_RECORDING);
120         }
121
122         SLOG(LOG_INFO, TAG_VCD, "[Server Success] Restart recognition");
123
124         return EINA_FALSE;
125 }
126
127 static int __server_recorder_callback(const void* data, const unsigned int length)
128 {
129         vcd_state_e state = vcd_config_get_service_state();
130         if (VCD_STATE_READY == state) {
131                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Ready state, but recording");
132         } else if (VCD_STATE_PROCESSING == state) {
133                 return VCD_ERROR_NONE;
134         }
135
136         vce_speech_detect_e speech_detected = VCE_SPEECH_DETECT_NONE;
137         int ret;
138
139         ret = vcd_engine_recognize_audio(data, length, &speech_detected);
140
141         if (0 > ret) {
142                 /* Error */
143                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set recording data to engine(%d)", ret);
144                 ecore_timer_add(0, __cancel_by_interrupt, NULL);
145                 /* Send error cb to manager */
146                 if (VCE_ERROR_OUT_OF_NETWORK == ret) {
147                         vcdc_send_error_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_TIMED_OUT, "voice_framework.error.engine.set_recording_fail");
148                 } else {
149                         vcdc_send_error_to_manager(vcd_client_manager_get_pid(), ret, "voice_framework.error.engine.set_recording_fail");
150                 }
151                 return VCD_ERROR_NONE;
152         }
153
154         if (VCE_SPEECH_DETECT_BEGIN == speech_detected) {
155                 if (-1 != vcd_client_manager_get_pid()) {
156                         /* Manager client is available */
157                         if (0 != vcdc_send_speech_detected(vcd_client_manager_get_pid())) {
158                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send speech detected");
159                         }
160                 }
161         } else if (VCE_SPEECH_DETECT_END == speech_detected) {
162                 if (VCD_RECOGNITION_MODE_STOP_BY_SILENCE == vcd_client_get_recognition_mode()) {
163                         /* silence detected */
164                         ecore_timer_add(0, __stop_by_silence, NULL);
165                 } else if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == vcd_client_get_recognition_mode()) {
166                         /* Stop engine recognition */
167                         int ret = vcd_engine_recognize_stop();
168                         if (0 != ret) {
169                                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
170                         }
171                         vcd_config_set_service_state(VCD_STATE_PROCESSING);
172                         vcdc_send_service_state(VCD_STATE_PROCESSING);
173
174                         SLOG(LOG_INFO, TAG_VCD, "[Server] Stop engine only by silence");
175                 } else if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY == vcd_client_get_recognition_mode()) {
176                         /* Stop engine recognition */
177                         int ret = vcd_engine_recognize_stop();
178                         if (0 != ret) {
179                                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
180                         }
181                 }
182         }
183
184         return VCD_ERROR_NONE;
185 }
186
187 void __server_recorder_interrupt_callback()
188 {
189         SLOG(LOG_INFO, TAG_VCD, "@@@ Cancel by sound interrupt");
190
191         ecore_timer_add(0, __cancel_by_interrupt, NULL);
192
193         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Cancel by sound interrupt DONE");
194 }
195
196 static void __config_lang_changed_cb(const char* current_lang, void* user_data)
197 {
198         SLOG(LOG_INFO, TAG_VCD, "@@@ Change language ");
199
200         /* Current state is recording */
201         vcd_state_e state = vcd_config_get_service_state();
202         if (VCD_STATE_RECORDING == state || VCD_STATE_PROCESSING == state) {
203                 SLOG(LOG_INFO, TAG_VCD, "[Server] Current state is 'Recording'. Cancel recognition");
204                 vcd_server_mgr_cancel();
205         }
206
207         int ret;
208         ret = vcd_engine_set_current_language(current_lang);
209         if (0 != ret) {
210                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set language of engine : %d", ret);
211         }
212
213         SLOG(LOG_INFO, TAG_VCD, "@@@ Change language DONE");
214
215         return;
216 }
217
218 static void __config_foreground_changed_cb(int previous, int current, void* user_data)
219 {
220         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Change foreground");
221
222         SLOG(LOG_INFO, TAG_VCD, "Foreground pid(%d)", current);
223
224         if (VC_NO_FOREGROUND_PID != current) {
225                 /* Foreground app is changed */
226                 vcd_state_e state = vcd_config_get_service_state();
227                 if (VCD_STATE_RECORDING == state) {
228                         SLOG(LOG_INFO, TAG_VCD, "[Server] Foreground pid(%d) is changed. Cancel recognition", current);
229                         ecore_timer_add(0, __cancel_by_interrupt, NULL);
230                 }
231         }
232
233         SLOG(LOG_DEBUG, TAG_VCD, "@@@ Change foreground DONE");
234
235         return;
236 }
237
238 static int __vcd_activate_app_by_appcontrol(const char* appid)
239 {
240         if (NULL == appid) {
241                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
242                 return VCD_ERROR_INVALID_PARAMETER;
243         }
244
245         int ret = -1;
246         app_control_h app_control = NULL;
247         ret = app_control_create(&app_control);
248         if (APP_CONTROL_ERROR_NONE == ret) {
249                 // Set extra data
250                 ret = app_control_add_extra_data(app_control, "voice_launch", "get_result");
251                 if (APP_CONTROL_ERROR_NONE != ret) {
252                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to add extra data, ret(%d)", ret);
253                         app_control_destroy(app_control);
254                         return VCD_ERROR_OPERATION_FAILED;
255                 }
256                 // Set an app ID.
257                 ret = app_control_set_app_id(app_control, appid);
258                 if (APP_CONTROL_ERROR_NONE != ret) {
259                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set app id, ret(%d)", ret);
260                         app_control_destroy(app_control);
261                         return VCD_ERROR_OPERATION_FAILED;
262                 }
263                 // Sent launch request
264                 ret = app_control_send_launch_request(app_control, NULL, NULL);
265                 if (APP_CONTROL_ERROR_NONE != ret) {
266                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send launch request, ret(%d)", ret);
267                         app_control_destroy(app_control);
268                         return VCD_ERROR_OPERATION_FAILED;
269                 }
270                 // Destroy app control
271                 ret = app_control_destroy(app_control);
272                 if (APP_CONTROL_ERROR_NONE != ret) {
273                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to destroy, ret(%d)", ret);
274                         return VCD_ERROR_OPERATION_FAILED;
275                 }
276         }
277         return VCD_ERROR_NONE;
278 }
279
280 static int __vcd_resume_app(const char* appid)
281 {
282         app_context_h app_context = NULL;
283         int ret = app_manager_get_app_context(appid, &app_context);
284         if (APP_MANAGER_ERROR_NONE != ret) {
285                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get app_context, ret(%d), appid(%s)", ret, appid);
286                 return VCD_ERROR_OPERATION_FAILED;
287         }
288
289         ret = app_manager_resume_app(app_context);
290         int destroy_ret = app_context_destroy(app_context);
291         if (APP_MANAGER_ERROR_NONE != destroy_ret) {
292                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to destroy app_context, ret(%d), appid(%s)", destroy_ret, appid);
293         }
294
295         if (APP_MANAGER_ERROR_NONE != ret) {
296                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to resume app, ret(%d), appid(%s)", ret, appid);
297                 return VCD_ERROR_OPERATION_FAILED;
298         }
299
300         return VCD_ERROR_NONE;
301 }
302
303 static bool __vcd_is_package_installed(const char* appid)
304 {
305         app_info_h app_info = NULL;
306         int ret = app_manager_get_app_info(appid, &app_info);
307         if (APP_MANAGER_ERROR_NONE != ret || NULL == app_info)
308                 return false;
309         ret = app_info_destroy(app_info);
310         if (APP_MANAGER_ERROR_NONE != ret)
311                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to destroy app_info, ret(%d)", ret);
312         return true;
313 }
314
315 void __vc_free_deactivated_app(void* data)
316 {
317         vc_deactivated_app_s* d_app = (vc_deactivated_app_s*)data;
318
319         if (NULL != d_app) {
320                 if (NULL != d_app->appid) {
321                         free(d_app->appid);
322                         d_app->appid = NULL;
323                 }
324
325                 free(d_app);
326                 d_app = NULL;
327         }
328 }
329
330 static bool __vcd_launch_app(const char* result)
331 {
332         if (NULL == result) {
333                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter");
334                 return VCD_ERROR_INVALID_PARAMETER;
335         }
336
337         GSList* app_list = NULL;
338         if (0 != vc_db_get_appid_list(result, &app_list)) {
339                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] result text is NULL");
340                 return VCD_ERROR_INVALID_PARAMETER;
341         }
342
343         if (0 != g_slist_length(app_list)) {
344                 /* release data */
345                 GSList *iter = g_slist_nth(app_list, 0);
346                 while (NULL != iter) {
347                         vc_deactivated_app_s *temp_app = iter->data;
348
349                         if (NULL != temp_app && NULL != temp_app->appid) {
350                                 int ret = -1;
351                                 bool running = false;
352                                 ret = app_manager_is_running(temp_app->appid, &running);
353                                 if (APP_MANAGER_ERROR_NONE != ret) {
354                                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to check running with appid(%s)", temp_app->appid);
355                                         g_slist_free_full(iter, __vc_free_deactivated_app);
356                                         return VCD_ERROR_OPERATION_FAILED;
357                                 }
358                                 if (false == running) {
359                                         int tmp_ret = __vcd_is_package_installed(temp_app->appid);
360                                         if (false == tmp_ret) {
361                                                 SLOG(LOG_WARN, TAG_VCD, "[WARNING] app is not installed, appid(%s)", temp_app->appid);
362                                         } else {
363                                                 ret = __vcd_activate_app_by_appcontrol(temp_app->appid);
364                                                 if (0 != ret) {
365                                                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to activate app");
366                                                         g_slist_free_full(iter, __vc_free_deactivated_app);
367                                                         return ret;
368                                                 }
369                                                 SLOG(LOG_ERROR, TAG_VCD, "Launch app: appid(%s) result(%s)", temp_app->appid, result);
370                                         }
371                                 } else {
372                                         ret = __vcd_resume_app(temp_app->appid);
373                                         if (0 != ret) {
374                                                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to resume app");
375                                                 g_slist_free_full(iter, __vc_free_deactivated_app);
376                                                 return ret;
377                                         }
378                                         SLOG(LOG_ERROR, TAG_VCD, "Resume app: appid(%s) result(%s)", temp_app->appid, result);
379                                 }
380                                 __vc_free_deactivated_app((void*)temp_app);
381                                 temp_app = NULL;
382                         }
383                         app_list = g_slist_remove_link(app_list, iter);
384                         g_slist_free(iter);
385                         iter = g_slist_nth(app_list, 0);
386                 }
387                 app_list = NULL;
388         }
389
390         return VCD_ERROR_NONE;
391 }
392
393 static Eina_Bool __vcd_send_selected_result(void *data)
394 {
395         GSList* pid_list = NULL;
396         const char* result = vcd_client_manager_get_result_text();
397
398         if (0 != vc_info_parser_get_result_pid_list(&pid_list, result)) {
399                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to get pid list. No result");
400         } else {
401                 if (0 < g_slist_length(pid_list)) {
402                         int ret = 0;
403                         int pre_pid = -1;
404                         int pre_type = -1;
405
406                         GSList *iter = g_slist_nth(pid_list, 0);
407                         while (NULL != iter) {
408                                 vc_cmd_s *temp_cmd = iter->data;
409
410                                 if (NULL != temp_cmd && (pre_pid != temp_cmd->pid || pre_type == VC_COMMAND_TYPE_WIDGET || temp_cmd->type == VC_COMMAND_TYPE_WIDGET)) {
411                                         /* Launch deactivated several apps that is matched with result */
412                                         ret = __vcd_launch_app(result);
413                                         if (0 != ret) {
414                                                 SLOG(LOG_ERROR, TAG_VCD, "Fail to launch or resume app, ret(%d) result(%s)", ret, result);
415                                         } else {
416                                                 /* send result noti */
417                                                 ret = vcdc_send_result(temp_cmd->pid, vcd_client_manager_get_pid(), temp_cmd->type);
418                                                 if (0 != ret) {
419                                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result, ret(%d)", ret);
420                                                         g_slist_free_full(pid_list, free);
421                                                         pid_list = NULL;
422                                                         break;
423                                                 } else {
424                                                         SLOG(LOG_ERROR, TAG_VCD, "[Server] Send result : pid(%d) type(%d)", temp_cmd->pid, temp_cmd->type);
425                                                         pre_pid = temp_cmd->pid;
426                                                         pre_type = temp_cmd->type;
427                                                 }
428                                         }
429                                         free(temp_cmd);
430                                         temp_cmd = NULL;
431                                 }
432                                 pid_list = g_slist_remove_link(pid_list, iter);
433                                 g_slist_free(iter);
434                                 iter = g_slist_nth(pid_list, 0);
435                         }
436                 }
437         }
438
439         if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY != vcd_client_get_recognition_mode()) {
440                 vcd_config_set_service_state(VCD_STATE_READY);
441                 vcdc_send_service_state(VCD_STATE_READY);
442         }
443
444         return EINA_FALSE;
445 }
446
447 int vcd_send_asr_result(vce_asr_result_event_e event, const char* asr_result, void *user_data)
448 {
449         int ret = __vcd_server_launch_manager_app();
450         if (0 != ret) {
451                 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);
452                 return ret;
453         }
454
455         if (NULL != asr_result) {
456                 SECURE_SLOG(LOG_INFO, TAG_VCD, "[Server] ASR result - Event(%d), Text(%s)", event, asr_result);
457                 ret = vcdc_send_pre_result_to_manager(vcd_client_manager_get_pid(), event, asr_result);
458                 if (0 != ret) {
459                         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);
460                 }
461         }
462
463         return ret;
464 }
465
466 int vcd_send_specific_engine_result(const char* engine_app_id, const char* event, const char* result, void *user_info)
467 {
468         if (NULL != result) {
469                 SLOG(LOG_INFO, TAG_VCD, "[Server] specific engine result - Event(%s), Text(%s)", event, result);
470                 vcdc_send_specific_engine_result_to_manager(vcd_client_manager_get_pid(), engine_app_id, event, result);
471         }
472
473         return VCD_ERROR_NONE;
474 }
475
476 int vcd_send_nlg_result(const char* nlg_result, void *user_data)
477 {
478         int ret = __vcd_server_launch_manager_app();
479         if (0 != ret) {
480                 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);
481                 return ret;
482         }
483
484         SLOG(LOG_ERROR, TAG_VCD, "[Server] send dialog : mgr_pid(%d), nlg_result(%s)", vcd_client_manager_get_pid(), nlg_result);
485         ret = vcdc_send_dialog(vcd_client_manager_get_pid(), -1, nlg_result, NULL, 0); //0: VC_DIALOG_END
486         if (0 != ret)
487                 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);
488         return ret;
489 }
490
491 static void* __recorder_stop(void *data)
492 {
493         vcd_recorder_stop();
494         return NULL;
495 }
496
497 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)
498 {
499         int ret = 0;
500         vcd_recognition_mode_e recognition_mode = vcd_client_get_recognition_mode();
501
502         if (VCD_STATE_PROCESSING != vcd_config_get_service_state()) {
503                 if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY != recognition_mode) {
504                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not 'Processing' and mode is not 'Restart continuously'");
505                         return VCD_ERROR_INVALID_STATE;
506                 }
507         }
508
509         vc_info_parser_unset_result(vcd_client_manager_get_exclusive());
510         vcd_client_manager_set_result_text(all_result);
511
512         SECURE_SLOG(LOG_INFO, TAG_VCD, "[Server] Event(%d), Text(%s) Nonfixed(%s) Msg(%s) Result count(%d)",
513                 event, all_result, non_fixed_result, msg, count);
514
515         SECURE_SLOG(LOG_ERROR, TAG_VCD, "[Server] NLU result(%s)", nlu_result);
516
517 #if 1
518         /* if nlu_result is exist, Add command handle(is_action) into result list */
519         /* Normal result */
520         SLOG(LOG_INFO, TAG_VCD, "[Server] @ Get engine result @");
521
522         vc_cmd_s* temp_cmd = NULL;
523         vc_cmd_list_h vc_cmd_list = NULL;
524
525         if (0 != vc_cmd_list_create(&vc_cmd_list)) {
526                 SLOG(LOG_INFO, TAG_VCD, "[Server] Fail to create command list");
527                 vcd_client_manager_set_exclusive(false);
528                 vcd_config_set_service_state(VCD_STATE_READY);
529                 vcdc_send_service_state(VCD_STATE_READY);
530                 return VCD_ERROR_NONE;
531         }
532
533         /* priority filter */
534         /* system > exclusive > widget > foreground > system_background > widget partial > foreground partial > background */
535         int i = 0;
536         int* filtered_id = (int*)calloc(count, sizeof(int));
537         if (!filtered_id) {
538                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to allocate memory");
539                 vc_cmd_list_destroy(vc_cmd_list, true);
540                 vc_cmd_list = NULL;
541                 return VCD_ERROR_OUT_OF_MEMORY;
542         }
543         int filtered_count = 0;
544         int top_priority = VC_COMMAND_PRIORITY_BACKGROUND;
545         for (i = 0; i < count; i++) {
546                 SLOG(LOG_INFO, TAG_VCD, "[Server]   [%d] Result id(%d)", i, result_id[i]);
547
548                 if (0 > result_id[i]) {
549                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Result ID(%d) is NOT valid", result_id[i]);
550                         continue;
551                 }
552
553                 ret = vcd_client_get_cmd_from_result_id(result_id[i], &temp_cmd);
554                 if (0 == ret && NULL != temp_cmd) {
555                         if (top_priority == temp_cmd->priority) {
556                                 filtered_id[filtered_count] = result_id[i];
557                                 filtered_count++;
558                         } else if (top_priority > temp_cmd->priority) {
559                                 filtered_id[0] = result_id[i];
560                                 filtered_count = 1;
561                                 top_priority = temp_cmd->priority;
562                         }
563                 }
564                 vc_cmd_destroy((vc_cmd_h)temp_cmd);
565                 temp_cmd = NULL;
566         }
567
568         // ASR consume
569         if (top_priority >= VC_COMMAND_PRIORITY_WIDGET) {
570                 int pid = vcd_client_widget_get_foreground_pid();
571                 if (-1 != pid) {
572                         if (NULL != all_result) {
573                                 vc_info_parser_set_result(all_result, event, msg, NULL, false);
574                                 bool enable = false;
575                                 vcd_client_widget_get_asr_result_enabled(pid, &enable);
576                                 if (true == enable) {
577                                         SLOG(LOG_INFO, TAG_VCD, "[Server] Send ASR result to Widget client");
578                                         bool is_consumed = false;
579                                         if (NULL != user_info) {
580                                                 *user_info = 0x00;
581                                         }
582                                         if (0 != vcdc_send_asr_result(pid, event, all_result, VC_COMMAND_TYPE_WIDGET, &is_consumed)) {
583                                                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send asr result");
584                                         } else {
585                                                 SLOG(LOG_INFO, TAG_VCD, "[Server] ASR result is consumed(%d)", is_consumed);
586                                                 if (true == is_consumed) {
587                                                         if (NULL != user_info) {
588                                                                 *user_info = 0x01;
589                                                                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Send whether ASR result is consumed or not (%d)", *user_info);
590                                                         }
591                                                         vcdc_send_show_tooltip(pid, false);
592                                                         if (-1 != vcd_client_manager_get_pid()) {
593                                                                 /* Manager client is available */
594                                                                 vc_info_parser_unset_result(false);
595                                                                 vc_info_parser_set_result(all_result, VC_RESULT_EVENT_RESULT_SUCCESS, msg, NULL, false);
596                                                                 if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION)) {
597                                                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
598                                                                 }
599                                                         }
600
601                                                         // Set state manually, because the result is already handled in ASR result by client.
602                                                         // So, the daemon does not need to send the result to client.
603                                                         vcd_client_manager_set_exclusive(false);
604
605                                                         vcd_config_set_service_state(VCD_STATE_READY);
606                                                         vcdc_send_service_state(VCD_STATE_READY);
607                                                         vc_cmd_list_destroy(vc_cmd_list, true);
608                                                         vc_cmd_list = NULL;
609                                                         if (NULL != filtered_id) {
610                                                                 free(filtered_id);
611                                                                 filtered_id = NULL;
612                                                         }
613                                                         return VCD_ERROR_NONE;
614                                                 }
615                                         }
616                                 }
617                         }
618                 }
619         }
620
621         int is_action = 0;
622         for (i = 0; i < filtered_count; i++) {
623                 SLOG(LOG_INFO, TAG_VCD, "[Server]   [%d] Filtered Result id(%d)", i, filtered_id[i]);
624
625                 if (filtered_id[i] < 0) {
626                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Filtered ID(%d) is NOT valid", filtered_id[i]);
627                         continue;
628                 }
629
630                 ret = vcd_client_get_cmd_from_result_id(filtered_id[i], &temp_cmd);
631                 if (0 == ret && NULL != temp_cmd) {
632                         switch (temp_cmd->format) {
633                         case VC_CMD_FORMAT_FIXED:
634                         case VC_CMD_FORMAT_FIXED_AND_VFIXED:
635                         case VC_CMD_FORMAT_VFIXED_AND_FIXED:
636                         case VC_CMD_FORMAT_PARTIAL:
637                         case VC_CMD_FORMAT_FIXED_AND_NONFIXED:
638                         case VC_CMD_FORMAT_NONFIXED_AND_FIXED:
639                                 break;
640                         case VC_CMD_FORMAT_ACTION:
641                                 is_action = 1;
642                                 break;
643                         default:
644                                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Unknown command type : %d", temp_cmd->type);
645                         }
646
647                         temp_cmd->id = i;
648                         if (0 != vc_cmd_list_add(vc_cmd_list, (vc_cmd_h)temp_cmd)) {
649                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to add command to list");
650                                 vc_cmd_destroy((vc_cmd_h)temp_cmd);
651                                 temp_cmd = NULL;
652                         }
653                 } else {
654                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] NOT found matched result(%d)", filtered_id[i]);
655                 }
656         }
657
658         if (NULL != filtered_id) {
659                 free(filtered_id);
660                 filtered_id = NULL;
661         }
662
663         if (NULL != nlu_result) {
664                 SECURE_SLOG(LOG_INFO, TAG_VCD, "[Server] NLU (%s)", nlu_result);
665                 vc_info_parser_set_nlu_result(nlu_result);
666                 if (0 == is_action) {
667                         vc_cmd_h nlu_cmd;
668                         if (0 != vc_cmd_create(&nlu_cmd)) {
669                                 SLOG(LOG_ERROR, TAG_VCD, "Fail to nlu cmd create");
670                         } else {
671                                 if (0 != vc_cmd_set_type(nlu_cmd, VC_COMMAND_TYPE_SYSTEM)) {
672                                         SLOG(LOG_ERROR, TAG_VCD, "Fail to set type");
673                                 }
674                                 if (0 != vc_cmd_set_pid(nlu_cmd, vcd_client_manager_get_pid())) {
675                                         SLOG(LOG_ERROR, TAG_VCD, "Fail to set pid");
676                                 }
677                                 if (0 != vc_cmd_set_format(nlu_cmd, VC_CMD_FORMAT_ACTION)) {
678                                         SLOG(LOG_ERROR, TAG_VCD, "Fail to set format");
679                                 }
680                                 if (0 != vc_cmd_list_add(vc_cmd_list, nlu_cmd)) {
681                                         SLOG(LOG_ERROR, TAG_VCD, "Fail to add nlu cmd to list");
682                                         vc_cmd_destroy(nlu_cmd);
683                                 }
684                         }
685                 }
686         }
687
688         vc_cmd_print_list(vc_cmd_list);
689
690         SLOG(LOG_INFO, TAG_VCD, "[Server] @@@@");
691
692         int result_count = 0;
693         vc_cmd_list_get_count(vc_cmd_list, &result_count);
694
695         /* Handle the result list */
696         if (0 == result_count) {
697                 /* No result */
698                 vc_cmd_list_h widget_cmd_list = NULL;
699                 vc_cmd_list_h foreground_cmd_list = NULL;
700                 if (NULL != all_result) {
701                         SECURE_SLOG(LOG_INFO, TAG_VCD, "[Server] Engine result is no command : %s", all_result);
702                         int cnt = 0;
703
704                         if (0 != vc_cmd_list_create(&widget_cmd_list)) {
705                                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create widget command list handle");
706                                 vc_cmd_list_destroy(vc_cmd_list, true);
707                                 vc_cmd_list = NULL;
708                                 return VCD_ERROR_OUT_OF_MEMORY;
709                         }
710
711                         /* Get the list of widget type commands */
712                         vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_WIDGET, widget_cmd_list);
713                         vc_cmd_list_get_count(widget_cmd_list, &cnt);
714                         if (0 < cnt) {
715                                 /* Matched with widget command partially */
716                                 vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, vc_cmd_list, VC_SEARCH_NONE_LEVEL);
717                                 vc_cmd_list_get_count(vc_cmd_list, &cnt);
718                                 if (0 < cnt) {
719                                         top_priority = VC_COMMAND_PRIORITY_WIDGET;
720                                         SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched widget command");
721                                 }
722                         } else {
723                                 if (0 != vc_cmd_list_create(&foreground_cmd_list)) {
724                                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create foreground command list handle");
725                                         vc_cmd_list_destroy(vc_cmd_list, true);
726                                         vc_cmd_list = NULL;
727                                         vc_cmd_list_destroy(widget_cmd_list, true);
728                                         widget_cmd_list = NULL;
729                                         return VCD_ERROR_OUT_OF_MEMORY;
730                                 }
731
732                                 /* Get the list of foreground type commands */
733                                 vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_FOREGROUND, foreground_cmd_list);
734                                 vc_cmd_list_get_count(foreground_cmd_list, &cnt);
735                                 if (0 < cnt) {
736                                         /* Matched with foreground command partially */
737                                         vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, vc_cmd_list, VC_SEARCH_NONE_LEVEL);
738                                         vc_cmd_list_get_count(vc_cmd_list, &cnt);
739                                         if (0 < cnt) {
740                                                 top_priority = VC_COMMAND_PRIORITY_FOREGROUND;
741                                                 SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched foreground command");
742                                         }
743                                 }
744                                 vc_cmd_list_destroy(foreground_cmd_list, true);
745                                 foreground_cmd_list = NULL;
746                         }
747                         vc_cmd_list_destroy(widget_cmd_list, true);
748                         widget_cmd_list = NULL;
749                 } else {
750                         SLOG(LOG_INFO, TAG_VCD, "[Server] Engine all result is NULL");
751                 }
752
753                 vc_cmd_list_get_count(vc_cmd_list, &result_count);
754
755                 // After running partial matching algorithm, if there is no result.
756                 if (0 == result_count) {
757                         SLOG(LOG_INFO, TAG_VCD, "[Server] No commands even after partial matching");
758
759                         bool temp = vcd_client_manager_get_exclusive();
760                         vc_info_parser_set_result(all_result, event, msg, NULL, temp);
761
762                         int pid = vcd_client_widget_get_foreground_pid();
763                         if (-1 != pid) {
764                                 SLOG(LOG_INFO, TAG_VCD, "[Server] Request tooltip hide");
765                                 /* Send to hide tooltip */
766                                 vcdc_send_show_tooltip(pid, false);
767                         }
768
769                         if (-1 != vcd_client_manager_get_pid()) {
770                                 /* Manager client is available */
771                                 if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
772                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
773                                 }
774                         }
775
776                         /* set service state ready */
777                         vcd_config_set_service_state(VCD_STATE_READY);
778                         vcdc_send_service_state(VCD_STATE_READY);
779
780                         vcd_client_manager_set_exclusive(false);
781                         vc_cmd_list_destroy(vc_cmd_list, true);
782                         vc_cmd_list = NULL;
783
784                         return VCD_ERROR_NONE;
785                 }
786
787                 // Partial matching algorithm find some commands
788                 event = VC_RESULT_EVENT_RESULT_SUCCESS;
789         }
790
791         // There are more than one result.
792         if (false == vcd_client_manager_get_exclusive()) {
793                 vc_cmd_list_h temp_list = NULL;
794
795                 /* Foreground, Widget, Background, System, System-Background */
796                 if (top_priority >= VC_COMMAND_PRIORITY_BACKGROUND) {
797                         vc_cmd_list_h widget_cmd_list = NULL;
798                         vc_cmd_list_h foreground_cmd_list = NULL;
799                         int cnt = 0;
800
801                         if (0 != vc_cmd_list_create(&temp_list)) {
802                                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create widget command list handle");
803                                 vc_cmd_list_destroy(vc_cmd_list, true);
804                                 vc_cmd_list = NULL;
805                                 return VCD_ERROR_OUT_OF_MEMORY;
806                         }
807
808                         if (0 != vc_cmd_list_create(&widget_cmd_list)) {
809                                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create widget command list handle");
810                                 vc_cmd_list_destroy(vc_cmd_list, true);
811                                 vc_cmd_list = NULL;
812                                 vc_cmd_list_destroy(temp_list, true);
813                                 temp_list = NULL;
814                                 return VCD_ERROR_OUT_OF_MEMORY;
815                         }
816
817                         /* Get the list of widget type commands */
818                         vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_WIDGET, widget_cmd_list);
819                         vc_cmd_list_get_count(widget_cmd_list, &cnt);
820                         if (0 < cnt) {
821                                 /* Matched with widget command partially */
822                                 vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, temp_list, VC_SEARCH_NONE_LEVEL);
823                                 vc_cmd_list_get_count(temp_list, &cnt);
824                                 if (0 < cnt) {
825                                         if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) {
826                                                 SLOG(LOG_WARN, TAG_VCD, "[WARNING] Fail to destroy list");
827                                         }
828                                         vc_cmd_list = temp_list;
829                                         top_priority = VC_COMMAND_PRIORITY_WIDGET;
830                                         event = VC_RESULT_EVENT_RESULT_SUCCESS;
831                                         SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched widget command when background cmd exists");
832                                 }
833                         } else {
834                                 if (0 != vc_cmd_list_create(&foreground_cmd_list)) {
835                                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create foreground command list handle");
836                                         vc_cmd_list_destroy(vc_cmd_list, true);
837                                         vc_cmd_list = NULL;
838                                         vc_cmd_list_destroy(widget_cmd_list, true);
839                                         widget_cmd_list = NULL;
840                                         return VCD_ERROR_OUT_OF_MEMORY;
841                                 }
842
843                                 /* Get the list of foreground type commands */
844                                 vcd_client_append_cmd_from_type(VC_COMMAND_TYPE_FOREGROUND, foreground_cmd_list);
845                                 vc_cmd_list_get_count(foreground_cmd_list, &cnt);
846                                 if (0 < cnt) {
847                                         /* Matched with foreground command partially */
848                                         vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, temp_list, VC_SEARCH_NONE_LEVEL);
849                                         vc_cmd_list_get_count(temp_list, &cnt);
850                                         if (0 < cnt) {
851                                                 if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) {
852                                                         SLOG(LOG_WARN, TAG_VCD, "[WARNING] Fail to destroy list");
853                                                 }
854                                                 vc_cmd_list = temp_list;
855                                                 top_priority = VC_COMMAND_PRIORITY_FOREGROUND;
856                                                 event = VC_RESULT_EVENT_RESULT_SUCCESS;
857                                                 SLOG(LOG_INFO, TAG_VCD, "[INFO] Partially matched foreground command when background cmd exists");
858                                         }
859                                 }
860                                 vc_cmd_list_destroy(foreground_cmd_list, true);
861                                 foreground_cmd_list = NULL;
862                         }
863                         vc_cmd_list_destroy(widget_cmd_list, true);
864                         widget_cmd_list = NULL;
865                 }
866
867                 int pid = vcd_client_widget_get_foreground_pid();
868                 if (-1 != pid) {
869                         SLOG(LOG_INFO, TAG_VCD, "[Server] Request tooltip hide");
870                         vcdc_send_show_tooltip(pid, false);
871                 }
872
873                 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, false);
874                 vc_cmd_list_destroy(vc_cmd_list, true);
875                 vc_cmd_list = NULL;
876
877                 if (-1 != vcd_client_manager_get_pid()) {
878                         /* Manager client is available */
879                         if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
880                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
881                         }
882                 } else {
883                         SLOG(LOG_INFO, TAG_VCD, "[Server] Manager is NOT available. Send result to client directly");
884                         ecore_timer_add(0, __vcd_send_selected_result, NULL);
885                 }
886         } else {
887                 /* exclusive command */
888                 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, true);
889                 vc_cmd_list_destroy(vc_cmd_list, true);
890                 vc_cmd_list = NULL;
891
892                 if (-1 != vcd_client_manager_get_pid()) {
893                         /* Manager client is available */
894                         if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
895                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
896                         }
897                 } else {
898                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Manager is NOT available");
899                 }
900
901                 vcd_client_manager_set_exclusive(false);
902         }
903
904         if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == recognition_mode) {
905                 if (VCE_RESULT_EVENT_REJECTED == event) {
906                         SLOG(LOG_INFO, TAG_VCD, "[Server] Restart by no or rejected result");
907                         /* If no result and restart option is ON */
908                         /* Send reject message */
909                         bool temp = vcd_client_manager_get_exclusive();
910                         vc_info_parser_set_result(all_result, event, msg, NULL, temp);
911                         ret = vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION);
912                         if (0 != ret) {
913                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
914                         }
915
916                         g_restart_timer = ecore_timer_add(0, __restart_engine, NULL);
917                         return ret;
918                 }
919                 SLOG(LOG_INFO, TAG_VCD, "[Server] Stop recorder due to success");
920                 //vcd_recorder_stop();
921                 ecore_main_loop_thread_safe_call_sync(__recorder_stop, NULL);
922         } else if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY == recognition_mode) {
923                 SLOG(LOG_INFO, TAG_VCD, "[Server] Restart continuously");
924                 /* Restart option is ON */
925                 g_restart_timer = ecore_timer_add(0, __restart_engine, NULL);
926                 if (VCE_RESULT_EVENT_REJECTED == event) {
927                         bool temp = vcd_client_manager_get_exclusive();
928                         vc_info_parser_set_result(all_result, event, msg, NULL, temp);
929                         ret = vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION);
930                         if (0 != ret) {
931                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
932                         }
933                         return ret;
934                 }
935         }
936
937         return VCD_ERROR_NONE;
938
939 #else
940         /* No result */
941         if (NULL == result_id) {
942                 /* No result */
943                 if (NULL != all_result) {
944                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Engine result is no command : %s", all_result);
945                         bool temp = vcd_client_manager_get_exclusive();
946                         vc_info_parser_set_result(all_result, event, msg, NULL, temp);
947                 }
948
949                 int pid = vcd_client_widget_get_foreground_pid();
950                 if (-1 != pid) {
951                         if (NULL != all_result) {
952                                 /* Send result text to widget */
953                                 vcdc_send_result(pid, vcd_client_manager_get_pid(), VC_COMMAND_TYPE_WIDGET);
954                         }
955
956                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
957                         /* Send to hide tooltip */
958                         vcdc_send_show_tooltip(pid, false);
959                 }
960
961                 if (-1 != vcd_client_manager_get_pid()) {
962                         /* Manager client is available */
963                         if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
964                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
965                         }
966                 }
967
968                 vcd_client_manager_set_exclusive(false);
969
970                 return;
971         }
972
973         /* Normal result */
974         SLOG(LOG_DEBUG, TAG_VCD, "[Server] @ Get engine result @");
975
976         int ret = -1;
977         vc_cmd_s* temp_cmd = NULL;
978         vc_cmd_list_h vc_cmd_list = NULL;
979
980         if (0 != vc_cmd_list_create(&vc_cmd_list)) {
981                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Fail to create command list");
982                 vcd_client_manager_set_exclusive(false);
983                 vcd_config_set_service_state(VCD_STATE_READY);
984                 vcdc_send_service_state(VCD_STATE_READY);
985                 return;
986         }
987
988         int i = 0;
989         for (i = 0; i < count; i++) {
990                 SLOG(LOG_DEBUG, TAG_VCD, "[Server]   [%d] Result ID(%d)", i, result_id[i]);
991
992                 if (result_id[i] < 0) {
993                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Result ID(%d) is NOT valid", result_id[i]);
994                         continue;
995                 }
996
997                 ret = vcd_client_get_cmd_from_result_id(result_id[i], &temp_cmd);
998                 if (0 == ret && NULL != temp_cmd) {
999                         switch (temp_cmd->format) {
1000                         case VC_CMD_FORMAT_FIXED:
1001                         case VC_CMD_FORMAT_FIXED_AND_VFIXED:
1002                         case VC_CMD_FORMAT_VFIXED_AND_FIXED:
1003                         case VC_CMD_FORMAT_PARTIAL:
1004                                 /* Nonfixed result is NOT valid */
1005                                 break;
1006                         case VC_CMD_FORMAT_FIXED_AND_NONFIXED:
1007                                 if (NULL == temp_cmd->parameter) {
1008                                         if (NULL != non_fixed_result) {
1009                                                 temp_cmd->parameter = strdup(non_fixed_result);
1010                                         }
1011                                 } else {
1012                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Command type is NOT valid. Parameter (%s)", temp_cmd->parameter);
1013                                 }
1014                                 break;
1015                         case VC_CMD_FORMAT_NONFIXED_AND_FIXED:
1016                                 if (NULL == temp_cmd->command) {
1017                                         if (NULL != non_fixed_result) {
1018                                                 temp_cmd->command = strdup(non_fixed_result);
1019                                         }
1020                                 } else {
1021                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Command type is NOT valid. Command (%s)", temp_cmd->command);
1022                                 }
1023
1024                                 break;
1025                         default:
1026                                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Unknown command type : %d", temp_cmd->type);
1027                         }
1028
1029                         temp_cmd->id = i;
1030                         if (0 != vc_cmd_list_add(vc_cmd_list, (vc_cmd_h)temp_cmd)) {
1031                                 SLOG(LOG_DEBUG, TAG_VCD, "Fail to add command to list");
1032                                 vc_cmd_destroy((vc_cmd_h)temp_cmd);
1033                         }
1034                 } else {
1035                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] NOT found matched result(%d)", result_id[i]);
1036                 }
1037         }
1038
1039         vc_cmd_print_list(vc_cmd_list);
1040
1041         SLOG(LOG_DEBUG, TAG_VCD, "[Server] @@@@");
1042
1043         int result_count = 0;
1044         vc_cmd_list_get_count(vc_cmd_list, &result_count);
1045
1046         if (false == vcd_client_manager_get_exclusive()) {
1047                 int pid = vcd_client_widget_get_foreground_pid();
1048                 if (-1 != pid) {
1049                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
1050                         vcdc_send_show_tooltip(pid, false);
1051                 }
1052
1053                 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, false);
1054
1055                 if (-1 != vcd_client_manager_get_pid()) {
1056                         /* Manager client is available */
1057                         if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
1058                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
1059                         }
1060                 } else {
1061                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available. Send result to client directly");
1062                         /* Send result to client */
1063                         ecore_timer_add(0, __vcd_send_selected_result, NULL);
1064                 }
1065         } else {
1066                 /* exclusive command */
1067                 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, true);
1068
1069                 if (-1 != vcd_client_manager_get_pid()) {
1070                         /* Manager client is available */
1071                         if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
1072                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
1073                         }
1074                 } else {
1075                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Manager is NOT available");
1076                 }
1077
1078                 vcd_client_manager_set_exclusive(false);
1079         }
1080
1081         vc_cmd_list_destroy(vc_cmd_list, true);
1082         vc_cmd_list = NULL;
1083
1084         return;
1085 #endif
1086 }
1087
1088 #if 0
1089 static void __vcd_server_nlu_result_cb(vce_result_event_e event, const char* nlu_result, void *user_data)
1090 {
1091         SECURE_SLOG(LOG_DEBUG, TAG_VCD, "[Server] NLU result cb - event(%d)", event);
1092         SECURE_SLOG(LOG_DEBUG, TAG_VCD, "[Server] result (%s)", nlu_result);
1093
1094         int ret = vc_info_parser_set_nlu_result(nlu_result);
1095         if (0 != ret) {
1096                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set nlu result (%d)", ret);
1097         }
1098
1099         return;
1100 }
1101 #endif
1102
1103 int vcd_send_error(vce_error_e error, const char* msg, void *user_data)
1104 {
1105         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Engine Error cb - reason(%d), msg(%s)", error, msg);
1106
1107         char* error_msg = NULL;
1108         if (NULL != msg) {
1109                 error_msg = strdup(msg);
1110                 if (NULL == error_msg) {
1111                         return VCD_ERROR_OUT_OF_MEMORY;
1112                 }
1113         }
1114
1115         int ret = VCD_ERROR_NONE;
1116         if (VCE_ERROR_TTS_FAILED == error) {
1117                 int pid = __get_tts_played_pid();
1118                 ret = vcdc_send_error_signal_to_app(pid, error, error_msg);
1119         } else {
1120                 ret = vcdc_send_error_to_manager(vcd_client_manager_get_pid(), error, error_msg);
1121                 ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
1122         }
1123
1124         if (VCD_ERROR_NONE != ret) {
1125                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send error signal");
1126         }
1127
1128         if (NULL != error_msg) {
1129                 free(error_msg);
1130                 error_msg = NULL;
1131         }
1132
1133         return ret;
1134 }
1135
1136 /* for TTS feedback */
1137 int vcd_send_feedback_audio_format(int rate, vce_audio_channel_e channel, vce_audio_type_e audio_type)
1138 {
1139         SLOG(LOG_INFO, TAG_VCD, "[Server DEBUG] Engine - Send TTS feedback audio format, g_current_tts_uid(%u)", g_current_tts_uid);
1140
1141         /* send TTS feedback audio format to VC manager */
1142         int ret = VCD_ERROR_NONE;
1143         int pid = __get_tts_played_pid();
1144         if (VC_INVALID_TTS_UID == pid || vcd_client_manager_get_pid() == pid) {
1145                 ret = vcdc_send_feedback_audio_format_to_manager(vcd_client_manager_get_pid(), rate, channel, audio_type);
1146                 if (VCD_ERROR_NONE != ret) {
1147                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send TTS feedback audio format to VC manager");
1148                 }
1149         } else {
1150                 SLOG(LOG_INFO, TAG_VCD, "[Server INFO] Do not send TTS feedback audio format to VC manager");
1151         }
1152
1153         return ret;
1154 }
1155
1156 int vcd_send_feedback_streaming(vce_feedback_event_e event, char* buffer, int len)
1157 {
1158         if (VC_INVALID_TTS_UID == g_current_tts_uid && VCE_FEEDBACK_EVENT_START == event) {
1159                 g_current_utt_id = (g_current_utt_id + 1) % 1000;
1160                 g_current_tts_uid = (unsigned int)vcd_client_manager_get_pid() * 1000u + g_current_utt_id;
1161                 SLOG(LOG_INFO, TAG_VCD, "[Server info] set current uid and utt_id as manager pid(%d)", vcd_client_manager_get_pid());
1162         }
1163
1164         int ret = VCD_ERROR_NONE;
1165         int pid = __get_tts_played_pid();
1166         int utt_id = g_current_tts_uid % 1000;
1167
1168         SLOG(LOG_INFO, TAG_VCD, "[Server DEBUG] Engine - Send TTS feedback streaming event(%d), uid(%u), is_mgr_client(%d)", event, g_current_tts_uid, (pid == vcd_client_manager_get_pid() ? true : false));
1169
1170         if (VC_INVALID_TTS_UID == pid || pid == vcd_client_manager_get_pid() || -1 == vcd_client_manager_get_pid()) {
1171                 /* send TTS feedback streaming to manager client */
1172                 ret = vcdc_send_feedback_streaming_to_manager(vcd_client_manager_get_pid(), pid, utt_id, event, buffer, len);
1173                 if (VCD_ERROR_NONE != ret) {
1174                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send TTS feedback streaming to manager client");
1175                 }
1176         } else {
1177                 /* send TTS feedback streaming to client */
1178                 ret = vcdc_send_feedback_streaming(pid, utt_id, event, buffer, len);
1179                 if (VCD_ERROR_NONE != ret) {
1180                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send TTS feedback streaming to client");
1181                 }
1182         }
1183
1184         if (VCE_FEEDBACK_EVENT_FINISH == event) {
1185                 /* reset current uid */
1186                 g_current_tts_uid = VC_INVALID_TTS_UID;
1187
1188                 /* Set service state to ready if state is synthesizing */
1189                 vcd_state_e state = vcd_config_get_service_state();
1190                 if (VCD_STATE_SYNTHESIZING == state) {
1191                         vcd_config_set_service_state(VCD_STATE_READY);
1192                 }
1193                 SLOG(LOG_INFO, TAG_VCD, "[Server info] feedback streaming finish event, reset current uid & service state(%d)", vcd_config_get_service_state());
1194         }
1195         return ret;
1196 }
1197
1198
1199 /*
1200 * vcd server Interfaces
1201 */
1202 static void __vcd_file_clean_up()
1203 {
1204         SLOG(LOG_INFO, TAG_VCD, "== Old file clean up == ");
1205
1206         DIR *dp = NULL;
1207         struct dirent *dirp = NULL;
1208
1209         dp = opendir(VC_RUNTIME_INFO_ROOT);
1210         if (dp == NULL) {
1211                 SLOG(LOG_ERROR, TAG_VCD, "[File message WARN] Fail to open path : %s", VC_RUNTIME_INFO_ROOT);
1212                 return;
1213         }
1214
1215         char remove_path[257] = {0, };
1216         do {
1217                 dirp = readdir(dp);
1218
1219                 if (NULL != dirp) {
1220                         if (!strncmp("vc_", dirp->d_name, strlen("vc_"))) {
1221                                 memset(remove_path, 0, 257);
1222                                 snprintf(remove_path, 257, "%s/%s", VC_RUNTIME_INFO_ROOT, dirp->d_name);
1223
1224                                 /* Clean up code */
1225                                 if (0 != remove(remove_path)) {
1226                                         SLOG(LOG_WARN, TAG_VCD, "[File message WARN] Fail to remove file : %s", remove_path);
1227                                 } else {
1228                                         SLOG(LOG_INFO, TAG_VCD, "[File message] Remove file : %s", remove_path);
1229                                 }
1230                         }
1231                 }
1232         } while (NULL != dirp);
1233
1234         closedir(dp);
1235
1236         return;
1237 }
1238
1239 static int __vcd_db_clean_up()
1240 {
1241         int ret = 0;
1242         int cnt = VC_COMMAND_TYPE_FOREGROUND;
1243         do {
1244                 if (VC_COMMAND_TYPE_BACKGROUND != cnt)
1245                         ret = vc_db_delete_commands(-1, cnt, NULL);
1246         } while (VC_COMMAND_TYPE_EXCLUSIVE >= ++cnt);
1247
1248         return ret;
1249 }
1250
1251 #if 0
1252 static bool __is_default_engine()
1253 {
1254         char* engine = NULL;
1255         engine = vconf_get_str(VCONFKEY_VC_ENGINE_DEFAULT);
1256         if (NULL == engine) {
1257                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get sting for vc engine");
1258                 return FALSE;
1259         }
1260
1261         char appid[1024] = {'\0', };
1262         if (0 != aul_app_get_appid_bypid(getpid(), appid, sizeof(appid) - 1)) {
1263                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get callee appid by pid");
1264         }
1265
1266         SLOG(LOG_DEBUG, TAG_VCD, "[Server] VC Default Engine(%s), appId(%s)", engine, appid);
1267         if (0 == strncmp(engine, appid, strlen(engine))) {
1268                 free(engine);
1269                 return TRUE;
1270         }
1271         free(engine);
1272         return FALSE;
1273 }
1274 #endif
1275
1276 int vcd_initialize(vce_request_callback_s *callback)
1277 {
1278         int ret = 0;
1279
1280         /* Remove old file */
1281         __vcd_file_clean_up();
1282
1283         /* initialize modules */
1284         ret = vcd_config_initialize(__config_lang_changed_cb, __config_foreground_changed_cb, NULL);
1285         if (0 != ret) {
1286                 SLOG(LOG_ERROR, TAG_VCD, "[Server WARNING] Fail to initialize config.");
1287         }
1288
1289         ret = vc_db_initialize_for_daemon();
1290         if (0 != ret) {
1291                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to initialize DB : %d", ret);
1292                 if (TRUE != vcd_finalize()) {
1293                         SLOG(LOG_ERROR, TAG_VCD, "[Server Error] Fail to finalize");
1294                 }
1295                 return ret;
1296         }
1297
1298         /* Remove db data */
1299         ret = __vcd_db_clean_up();
1300         if (0 != ret) {
1301                 SLOG(LOG_ERROR, TAG_VCD, "[Server WARNING] Fail to remove db data");
1302         }
1303
1304         vcd_config_set_service_state(VCD_STATE_NONE);
1305
1306         ret = vcd_engine_agent_init();
1307         if (0 != ret) {
1308                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
1309                 if (TRUE != vcd_finalize()) {
1310                         SLOG(LOG_ERROR, TAG_VCD, "[Server Error] Fail to finalize");
1311                 }
1312                 return ret;
1313         }
1314
1315         if (0 != vcd_recorder_create(__server_recorder_callback, __server_recorder_interrupt_callback)) {
1316                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to create recorder");
1317                 if (TRUE != vcd_finalize()) {
1318                         SLOG(LOG_ERROR, TAG_VCD, "[Server Error] Fail to finalize");
1319                 }
1320                 return VCD_ERROR_OPERATION_FAILED;
1321         }
1322
1323         /* Load engine */
1324         if (0 != vcd_engine_agent_load_current_engine(callback)) {
1325                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to load current engine");
1326                 if (TRUE != vcd_finalize()) {
1327                         SLOG(LOG_ERROR, TAG_VCD, "[Server Error] Fail to finalize");
1328                 }
1329                 return VCD_ERROR_OPERATION_FAILED;
1330         }
1331
1332         /* Initialize manager info */
1333         vcd_client_manager_unset();
1334
1335 //      if (TRUE == __is_default_engine()) {
1336                 /* Open tidl connection */
1337                 if (0 != vcd_tidl_open_connection()) {
1338                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to open tidl connection");
1339                         if (TRUE != vcd_finalize()) {
1340                                 SLOG(LOG_ERROR, TAG_VCD, "[Server Error] Fail to finalize");
1341                         }
1342                         return VCD_ERROR_OPERATION_FAILED;
1343                 }
1344 //      }
1345
1346         vcd_config_set_service_state(VCD_STATE_READY);
1347 //      vcdc_send_service_state(VCD_STATE_READY);
1348
1349         /* Set timer cleanup client all */
1350         g_check_client_timer = ecore_timer_add(CLIENT_CLEAN_UP_TIME, vcd_cleanup_client_all, NULL);
1351         if (NULL == g_check_client_timer) {
1352                 SLOG(LOG_WARN, TAG_VCD, "[Server Warning] Fail to create timer of client check");
1353         }
1354
1355         g_current_tts_uid = VC_INVALID_TTS_UID;
1356         g_current_utt_id = -1;
1357
1358         SLOG(LOG_ERROR, TAG_VCD, "[Server SUCCESS] initialize");
1359
1360         return VCD_ERROR_NONE;
1361 }
1362
1363 bool vcd_finalize()
1364 {
1365         GList *iter = NULL;
1366         if (0 < g_list_length(g_proc_list)) {
1367                 iter = g_list_first(g_proc_list);
1368                 while (NULL != iter) {
1369                         g_proc_list = g_list_delete_link(g_proc_list, iter);
1370                         iter = g_list_first(g_proc_list);
1371                 }
1372         }
1373
1374         if (NULL != g_restart_timer) {
1375                 ecore_timer_del(g_restart_timer);
1376                 g_restart_timer = NULL;
1377         }
1378
1379         if (NULL != g_check_client_timer) {
1380                 ecore_timer_del(g_check_client_timer);
1381                 g_check_client_timer = NULL;
1382         }
1383
1384         vcd_state_e state = vcd_config_get_service_state();
1385         if (VCD_STATE_NONE != state && VCD_STATE_READY != state) {
1386                 if (VCD_STATE_RECORDING == state) {
1387                         vcd_recorder_stop();
1388                 }
1389                 vcd_engine_recognize_cancel();
1390         }
1391
1392         if (0 != vcd_recorder_destroy()) {
1393                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to destroy recorder");
1394                 return false;
1395         } else {
1396                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] destroy recorder");
1397         }
1398
1399         if (0 != vcd_engine_agent_release()) {
1400                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to release engine");
1401                 return false;
1402         } else {
1403                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] release engine");
1404         }
1405
1406         vcd_client_manager_unset_appid();
1407
1408         int ret = vcd_config_finalize();
1409         if (0 != ret) {
1410                 SLOG(LOG_ERROR, TAG_VCD, "[Server WARNING] Fail to finalize config.");
1411         }
1412
1413         ret = vc_db_finalize();
1414         if (0 != ret) {
1415                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to finalize DB : %d", ret);
1416         }
1417
1418         if (VCD_STATE_NONE != state) {
1419                 vcd_config_set_service_state(VCD_STATE_NONE);
1420                 vcdc_send_service_state(VCD_STATE_NONE);
1421         }
1422
1423         /* Close tidl connection */
1424         if (0 != vcd_tidl_close_connection()) {
1425                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to close connection");
1426         }
1427
1428         SLOG(LOG_ERROR, TAG_VCD, "[Server] mode finalize");
1429
1430         return true;
1431 }
1432
1433 static Eina_Bool __finalize_quit_ecore_loop(void *data)
1434 {
1435         bool ret = vcd_finalize();
1436         if (false == ret) {
1437                 return EINA_TRUE;
1438         } else {
1439                 ecore_main_loop_quit();
1440                 return EINA_FALSE;
1441         }
1442 }
1443
1444 static void __read_proc()
1445 {
1446         DIR *dp = NULL;
1447         struct dirent *dirp = NULL;
1448         int tmp;
1449
1450         GList *iter = NULL;
1451         if (0 < g_list_length(g_proc_list)) {
1452                 iter = g_list_first(g_proc_list);
1453                 while (NULL != iter) {
1454                         g_proc_list = g_list_delete_link(g_proc_list, iter);
1455                         iter = g_list_first(g_proc_list);
1456                 }
1457         }
1458
1459         dp = opendir("/proc");
1460         if (NULL == dp) {
1461                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to open proc");
1462         } else {
1463                 do {
1464                         dirp = readdir(dp);
1465
1466                         if (NULL != dirp) {
1467                                 tmp = atoi(dirp->d_name);
1468                                 if (0 >= tmp)   continue;
1469                                 g_proc_list = g_list_append(g_proc_list, GINT_TO_POINTER(tmp));
1470                         }
1471                 } while (NULL != dirp);
1472                 closedir(dp);
1473         }
1474         return;
1475 }
1476
1477 static inline const char *__get_client_type(vcd_client_type_e type)
1478 {
1479         switch (type) {
1480         case VCD_CLIENT_TYPE_NORMAL:
1481                 return "Normal";
1482         case VCD_CLIENT_TYPE_WIDGET:
1483                 return "Widget";
1484         case VCD_CLIENT_TYPE_MANAGER:
1485                 return "Manager";
1486         default:
1487                 return "Invalid";
1488         }
1489 }
1490
1491 static void __vcd_cleanup_client(vcd_client_type_e type)
1492 {
1493         int* client_list = NULL;
1494         int client_count = 0;
1495         int i = 0;
1496         int j = 0;
1497         bool exist = false;
1498         int mgr_pid = -1;
1499         int ret = -1;
1500
1501         if (VCD_CLIENT_TYPE_NORMAL == type) {
1502                 ret = vcd_client_get_list(&client_list, &client_count);
1503         } else if (VCD_CLIENT_TYPE_WIDGET == type) {
1504                 ret = vcd_client_widget_get_list(&client_list, &client_count);
1505         } else if (VCD_CLIENT_TYPE_MANAGER == type) {
1506                 mgr_pid = vcd_client_manager_get_pid();
1507                 client_list = &mgr_pid;
1508                 client_count = 1;
1509                 if (-1 == mgr_pid) {
1510                         SLOG(LOG_WARN, TAG_VCD, "[WARNING] Invalid Manager pid");
1511                         return;
1512                 }
1513         }
1514
1515         if (0 == ret || mgr_pid > 0) {
1516                 SLOG(LOG_INFO, TAG_VCD, "@@@ Clean up %s client ", __get_client_type(type));
1517                 if (NULL != client_list && client_count > 0) {
1518                         for (i = 0; i < client_count; i++) {
1519                                 exist = false;
1520                                 GList *iter = NULL;
1521                                 for (j = 0; j < g_list_length(g_proc_list); j++) {
1522                                         iter = g_list_nth(g_proc_list, j);
1523                                         if (NULL != iter) {
1524                                                 if (*(client_list + i) == GPOINTER_TO_INT(iter->data)) {
1525                                                         SLOG(LOG_INFO, TAG_VCD, "%s pid(%d) is running", __get_client_type(type), *(client_list + i));
1526                                                         exist = true;
1527                                                         break;
1528                                                 }
1529                                         }
1530                                 }
1531
1532                                 if (false == exist) {
1533                                         SLOG(LOG_ERROR, TAG_VCD, "%s pid(%d) should be removed", __get_client_type(type), *(client_list + i));
1534                                         if (VCD_CLIENT_TYPE_NORMAL == type)
1535                                                 vcd_server_finalize(*(client_list + i));
1536                                         else if (VCD_CLIENT_TYPE_WIDGET == type)
1537                                                 vcd_server_widget_finalize(*(client_list + i));
1538                                         else
1539                                                 vcd_server_mgr_finalize(mgr_pid);
1540                                 }
1541                         }
1542                 }
1543                 SLOG(LOG_INFO, TAG_VCD, "@@@");
1544         }
1545         if (NULL != client_list && -1 == mgr_pid) {
1546                 free(client_list);
1547                 client_list = NULL;
1548         }
1549         return;
1550 }
1551
1552 Eina_Bool vcd_cleanup_client_all(void *data)
1553 {
1554         __read_proc();
1555
1556         __vcd_cleanup_client(VCD_CLIENT_TYPE_NORMAL);
1557         __vcd_cleanup_client(VCD_CLIENT_TYPE_WIDGET);
1558         __vcd_cleanup_client(VCD_CLIENT_TYPE_MANAGER);
1559
1560         if (0 == vcd_client_get_ref_count()) {
1561                 SLOG(LOG_INFO, TAG_VCD, "[Server] Connected client list is empty");
1562                 ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
1563         }
1564 #if 0
1565         if (0 == vcd_client_get_list(&client_list, &client_count)) {
1566                 SLOG(LOG_DEBUG, TAG_VCD, "@@@ Clean up client ");
1567                 if (NULL != client_list && client_count > 0) {
1568                         for (i = 0; i < client_count; i++) {
1569                                 exist = false;
1570                                 GList *iter = NULL;
1571                                 for (j = 0; j < g_list_length(g_proc_list); j++) {
1572                                         iter = g_list_nth(g_proc_list, j);
1573                                         if (NULL != iter) {
1574                                                 if (client_list[i] == GPOINTER_TO_INT(iter->data)) {
1575                                                         SLOG(LOG_DEBUG, TAG_VCD, "pid(%d) is running", client_list[i]);
1576                                                         exist = true;
1577                                                         break;
1578                                                 }
1579                                         }
1580                                 }
1581
1582                                 if (false == exist) {
1583                                         SLOG(LOG_ERROR, TAG_VCD, "pid(%d) should be removed", client_list[i]);
1584                                         vcd_server_finalize(client_list[i]);
1585                                 }
1586 #if 0
1587                                 result = vcdc_send_hello(client_list[i], VCD_CLIENT_TYPE_NORMAL);
1588
1589                                 if (0 == result) {
1590                                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] pid(%d) should be removed.", client_list[i]);
1591                                         vcd_server_finalize(client_list[i]);
1592                                 } else if (-1 == result) {
1593                                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Hello result has error");
1594                                 }
1595 #endif
1596                         }
1597                 }
1598                 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
1599         }
1600         if (NULL != client_list) {
1601                 free(client_list);
1602                 client_list = NULL;
1603         }
1604
1605         /* If app is in background state, app cannot response message. */
1606         if (0 == vcd_client_widget_get_list(&client_list, &client_count)) {
1607                 SLOG(LOG_DEBUG, TAG_VCD, "@@@ Clean up widget");
1608                 if (NULL != client_list && client_count > 0) {
1609                         for (i = 0; i < client_count; i++) {
1610                                 exist = false;
1611                                 GList *iter = NULL;
1612                                 for (j = 0; j < g_list_length(g_proc_list); j++) {
1613                                         iter = g_list_nth(g_proc_list, j);
1614                                         if (NULL != iter) {
1615                                                 if (client_list[i] == GPOINTER_TO_INT(iter->data)) {
1616                                                         SLOG(LOG_DEBUG, TAG_VCD, "widget pid(%d) is running", client_list[i]);
1617                                                         exist = true;
1618                                                         break;
1619                                                 }
1620                                         }
1621                                 }
1622
1623                                 if (false == exist) {
1624                                         SLOG(LOG_ERROR, TAG_VCD, "widget pid(%d) should be removed", client_list[i]);
1625                                         vcd_server_widget_finalize(client_list[i]);
1626                                 }
1627 #if 0
1628                                 result = vcdc_send_hello(client_list[i], VCD_CLIENT_TYPE_WIDGET);
1629
1630                                 if (0 == result) {
1631                                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget pid(%d) should be removed.", client_list[i]);
1632                                         vcd_server_widget_finalize(client_list[i]);
1633                                 } else if (-1 == result) {
1634                                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Hello result has error");
1635                                 }
1636 #endif
1637                         }
1638                 }
1639                 SLOG(LOG_DEBUG, TAG_VCD, "@@@");
1640         }
1641
1642         if (NULL != client_list) {
1643                 free(client_list);
1644                 client_list = NULL;
1645         }
1646
1647         /* manager */
1648         exist = false;
1649         GList *iter = NULL;
1650         int mgr_pid = vcd_client_manager_get_pid();
1651         if (0 < mgr_pid) {
1652                 for (j = 0; j < g_list_length(g_proc_list); j++) {
1653                         iter = g_list_nth(g_proc_list, j);
1654                         if (NULL != iter) {
1655                                 if (mgr_pid == GPOINTER_TO_INT(iter->data)) {
1656                                         SLOG(LOG_DEBUG, TAG_VCD, "manager pid(%d) is running", mgr_pid);
1657                                         exist = true;
1658                                         break;
1659                                 }
1660                         }
1661                 }
1662
1663                 if (false == exist) {
1664                         SLOG(LOG_ERROR, TAG_VCD, "manager pid (%d) should be removed", mgr_pid);
1665                         vcd_server_mgr_finalize(mgr_pid);
1666                 }
1667         }
1668 #endif
1669         return EINA_TRUE;
1670 }
1671
1672 int vcd_server_get_service_state()
1673 {
1674         return vcd_config_get_service_state();
1675 }
1676
1677 int vcd_server_get_foreground()
1678 {
1679         int pid;
1680         vcd_config_get_foreground(&pid);
1681         return pid;
1682 }
1683
1684 /*
1685 * API for manager
1686 */
1687 int vcd_server_mgr_initialize(int pid, vcd_audio_streaming_mode_e mode)
1688 {
1689         /* check if pid is valid */
1690         if (false == vcd_client_manager_is_valid(pid)) {
1691                 SLOG(LOG_ERROR, TAG_VCD, "[Server] old manager pid(%d) be removed", vcd_client_manager_get_pid());
1692                 vcd_server_mgr_cancel();
1693                 vcd_client_manager_unset();
1694         }
1695
1696         /* Add client information to client manager */
1697         int ret = vcd_client_manager_set(pid);
1698         if (0 != ret) {
1699                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add manager");
1700                 return VCD_ERROR_OPERATION_FAILED;
1701         }
1702
1703         if (0 != vcdc_send_manager_pid(pid))
1704                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send manager pid");
1705
1706         vcd_recorder_set_audio_streaming_mode(mode);
1707
1708         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Manager initialize : pid(%d)", pid);
1709
1710         return VCD_ERROR_NONE;
1711 }
1712
1713 int vcd_server_mgr_finalize(int pid)
1714 {
1715         /* check if pid is valid */
1716         if (false == vcd_client_manager_is_valid(pid)) {
1717                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1718                 return VCD_ERROR_INVALID_PARAMETER;
1719         }
1720
1721         /* Cancel recognition */
1722         vcd_server_mgr_cancel();
1723
1724         if (0 != vcdc_send_manager_pid(-1))
1725                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send manager pid");
1726
1727         /* Remove manager information */
1728         if (0 != vcd_client_manager_unset()) {
1729                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
1730         }
1731
1732         if (0 == vcd_client_get_ref_count()) {
1733                 SLOG(LOG_INFO, TAG_VCD, "[Server] Connected client list is empty");
1734                 ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
1735         }
1736
1737         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Manager Finalize : pid(%d)", pid);
1738
1739         return VCD_ERROR_NONE;
1740 }
1741
1742 int vcd_server_mgr_set_command(int pid)
1743 {
1744         if (0 != vcd_client_manager_set_command(pid)) {
1745                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1746                 return VCD_ERROR_INVALID_PARAMETER;
1747         }
1748         return VCD_ERROR_NONE;
1749 }
1750
1751 int vcd_server_mgr_unset_command(int pid)
1752 {
1753         if (0 != vcd_client_manager_unset_command(pid)) {
1754                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1755                 return VCD_ERROR_INVALID_PARAMETER;
1756         }
1757         return VCD_ERROR_NONE;
1758 }
1759
1760 int vcd_server_mgr_set_demandable_client(int pid)
1761 {
1762         /* check if pid is valid */
1763         if (false == vcd_client_manager_is_valid(pid)) {
1764                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1765                 return VCD_ERROR_INVALID_PARAMETER;
1766         }
1767
1768         GSList* client_list = NULL;
1769         if (0 != vc_info_parser_get_demandable_clients(&client_list)) {
1770                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get demandable client");
1771                 return VCD_ERROR_OPERATION_FAILED;
1772         }
1773
1774         /* Save client list */
1775         if (0 != vcd_client_manager_set_demandable_client(pid, client_list)) {
1776                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set demandable client list");
1777                 return VCD_ERROR_OPERATION_FAILED;
1778         }
1779
1780         return VCD_ERROR_NONE;
1781 }
1782
1783 int vcd_server_mgr_set_audio_type(int pid, const char* audio_type)
1784 {
1785         /* check if pid is valid */
1786         if (false == vcd_client_manager_is_valid(pid)) {
1787                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1788                 return VCD_ERROR_INVALID_PARAMETER;
1789         }
1790
1791         int ret = 0;
1792         vce_audio_type_e type = VCE_AUDIO_TYPE_PCM_S16_LE;
1793         int rate = 16000;
1794         int channel = 1;
1795
1796         ret = vcd_engine_get_audio_format(audio_type, &type, &rate, &channel);
1797         if (0 != ret) {
1798                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio format : %d", ret);
1799                 return VCD_ERROR_OPERATION_FAILED;
1800         }
1801
1802         ret = vcd_recorder_set(audio_type, type, rate, channel);
1803         if (0 != ret) {
1804                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set audio in type : %d", ret);
1805                 return VCD_ERROR_OPERATION_FAILED;
1806         }
1807
1808         return VCD_ERROR_NONE;
1809 }
1810
1811 int vcd_server_mgr_get_audio_type(int pid, char** audio_type)
1812 {
1813         /* check if pid is valid */
1814         if (false == vcd_client_manager_is_valid(pid)) {
1815                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1816                 return VCD_ERROR_INVALID_PARAMETER;
1817         }
1818
1819         int ret = vcd_recorder_get(audio_type);
1820         if (0 != ret) {
1821                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio in type : %d", ret);
1822                 return VCD_ERROR_OPERATION_FAILED;
1823         }
1824
1825         return VCD_ERROR_NONE;
1826 }
1827
1828 int vcd_server_mgr_set_client_info(int pid)
1829 {
1830         /* check if pid is valid */
1831         if (false == vcd_client_manager_is_valid(pid)) {
1832                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
1833                 return VCD_ERROR_INVALID_PARAMETER;
1834         }
1835
1836         int ret = vcd_client_save_client_info();
1837         if (0 != ret) {
1838                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to save client info : %d", ret);
1839                 return VCD_ERROR_OPERATION_FAILED;
1840         }
1841
1842         return VCD_ERROR_NONE;
1843 }
1844
1845 static int __reset_waiting_for_widget_recording(void)
1846 {
1847         SLOG(LOG_ERROR, TAG_VCD, "[Server] Reset waiting for widget recording");
1848         // Delete timer to check that widget client is terminated
1849         if (g_check_widget_client_timer) {
1850                 ecore_timer_del(g_check_widget_client_timer);
1851                 g_check_widget_client_timer = NULL;
1852         }
1853         // Reset flag to wait for recording from widget client
1854         vcd_client_widget_set_waiting_for_recording(-1, false);
1855         return VCD_ERROR_NONE;
1856 }
1857
1858 #if 0
1859 static Eina_Bool __send_waiting_timeout_error_to_manager(void* data)
1860 {
1861         intptr_t ppid = (intptr_t)data;
1862         int pid = (int)ppid;
1863         SLOG(LOG_ERROR, TAG_VCD, "Widget client didn't send to start recording, pid(%d)", pid);
1864         __reset_waiting_for_widget_recording();
1865
1866         vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail");
1867         return EINA_FALSE;
1868 }
1869 #else
1870 static Eina_Bool __send_waiting_timeout_start_recording(void* data)
1871 {
1872         intptr_t ppid = (intptr_t)data;
1873         int pid = (int)ppid;
1874         SLOG(LOG_ERROR, TAG_VCD, "Widget client didn't send to start recording, pid(%d)", pid);
1875
1876         int ret = __start_internal_recognition();
1877         if (0 != ret) {
1878                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition : %d", ret);
1879                 return ret;
1880         }
1881         return EINA_FALSE;
1882 }
1883 #endif
1884
1885 static int __set_waiting_for_widget_recording(int pid)
1886 {
1887         SLOG(LOG_ERROR, TAG_VCD, "[Server] Set waiting for widget recording, pid(%d)", pid);
1888
1889         // Check if the app included widget client is terminated or not. If it is terminated, vcd_server_widget_finalize() function will be called
1890         // In that function, it will start recording
1891         intptr_t ppid = (intptr_t)pid;
1892         g_check_widget_client_timer = ecore_timer_add(2.0, __send_waiting_timeout_start_recording, (void*)ppid);
1893
1894         // Set flag to wait for recording from widget client
1895         vcd_client_widget_set_waiting_for_recording(pid, true);
1896         return VCD_ERROR_NONE;
1897 }
1898
1899 static int __start_internal_recognition()
1900 {
1901         int ret;
1902         __reset_waiting_for_widget_recording();
1903
1904         if (0 != vcd_client_command_collect_command()) {
1905                 SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to collect command");
1906                 /* Send error cb to manager */
1907                 int pid = vcd_client_widget_get_foreground_pid();
1908                 if (-1 != pid)
1909                         vcdc_send_error_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_framework.error.vcfw.collect_command_fail");
1910                 return VCD_ERROR_OPERATION_FAILED;
1911         }
1912
1913         /* 3. Set command to engine */
1914         ret = vcd_engine_set_commands();
1915         if (0 != ret) {
1916                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set commands : %d", ret);
1917                 /* Send error cb to manager */
1918                 int pid = vcd_client_widget_get_foreground_pid();
1919                 if (-1 != pid)
1920                         vcdc_send_error_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_framework.error.engine.set_commands_fail");
1921                 return VCD_ERROR_OPERATION_FAILED;
1922         }
1923
1924         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Set command");
1925
1926         bool stop_by_silence = true;
1927         if (VCD_RECOGNITION_MODE_MANUAL == vcd_client_get_recognition_mode()) {
1928                 stop_by_silence = false;
1929         }
1930
1931         vcd_client_manager_set_result_text(NULL);
1932
1933         /* 4. start recognition */
1934         ret = vcd_engine_recognize_start(stop_by_silence);
1935         if (0 != ret) {
1936                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1937                 /* Send error cb to manager */
1938                 int pid = vcd_client_widget_get_foreground_pid();
1939                 if (-1 != pid)
1940                         vcdc_send_error_to_manager(vcd_client_manager_get_pid(), ret, "voice_framework.error.engine.start_fail");
1941                 return ret;
1942         }
1943
1944         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Start engine");
1945
1946 #if 1
1947         /* 5. recorder start */
1948         ret = vcd_recorder_start();
1949         if (0 != ret) {
1950                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1951                 vcd_engine_recognize_cancel();
1952                 /* Send error cb to manager */
1953                 int pid = vcd_client_widget_get_foreground_pid();
1954                 if (-1 != pid)
1955                         vcdc_send_error_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_framework.error.vcfw.send_rc_fail");
1956                 return ret;
1957         }
1958 #endif
1959
1960         vcd_config_set_service_state(VCD_STATE_RECORDING);
1961         vcdc_send_service_state(VCD_STATE_RECORDING);
1962
1963         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Start recognition(%d)", stop_by_silence);
1964
1965         return VCD_ERROR_NONE;
1966 }
1967
1968 static Eina_Bool __vcd_request_show_tooltip(void *data)
1969 {
1970         int pid = vcd_client_widget_get_foreground_pid();
1971         if (-1 != pid) {
1972                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Request tooltip show and widget command, show(%d)", (bool)data);
1973                 vcdc_send_show_tooltip(pid, (bool)data);
1974         }
1975
1976         return EINA_FALSE;
1977 }
1978
1979 int vcd_server_mgr_start(vcd_recognition_mode_e recognition_mode, bool exclusive_cmd, bool start_by_client)
1980 {
1981         /* 1. check current state */
1982         vcd_state_e state = vcd_config_get_service_state();
1983
1984         if (VCD_STATE_READY != state && VCD_STATE_SYNTHESIZING != state) {
1985                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready and not synthesizine, state(%d)", state);
1986                 return VCD_ERROR_INVALID_STATE;
1987         }
1988         if (-1 == vcd_client_manager_get_pid()) {
1989                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available.");
1990                 return VCD_ERROR_OPERATION_FAILED;
1991         }
1992         __reset_waiting_for_widget_recording();
1993
1994         SLOG(LOG_ERROR, TAG_VCD, "[Server] set recognition mode = %d", recognition_mode);
1995         vcd_client_set_recognition_mode(recognition_mode);
1996
1997         if (false == exclusive_cmd) {
1998                 vcd_client_update_foreground_pid();
1999                 /* Notify show tooltip */
2000                 if (1 == vcd_config_get_command_type_enabled(VC_COMMAND_TYPE_WIDGET)) {
2001                         int pid = vcd_client_widget_get_foreground_pid();
2002                         if (-1 != pid) {
2003                                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Request tooltip show and widget command");
2004                                 ecore_timer_add(0, __vcd_request_show_tooltip, (void*)true);
2005
2006                                 __set_waiting_for_widget_recording(pid);
2007                                 return VCD_ERROR_NONE;
2008                         }
2009                 }
2010         } else {
2011                 vcd_client_manager_set_exclusive(exclusive_cmd);
2012         }
2013
2014         int fg_pid = -1;
2015         if (true == start_by_client) {
2016                 /* Get foreground pid */
2017                 if (0 != vcd_config_get_foreground(&fg_pid)) {
2018                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get foreground");
2019                 }
2020
2021                 /* Set client exclusive option */
2022                 if (0 != vcd_client_set_exclusive_command(fg_pid)) {
2023                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set exclusive command");
2024                 }
2025         }
2026
2027         SLOG(LOG_ERROR, TAG_VCD, "[Server] start internal recognition");
2028
2029         int ret = __start_internal_recognition();
2030         if (0 != ret) {
2031                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition : %d", ret);
2032                 return ret;
2033         }
2034
2035         if (true == start_by_client) {
2036                 vcd_client_unset_exclusive_command(fg_pid);
2037         }
2038
2039         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] start internal recognition");
2040         return VCD_ERROR_NONE;
2041 }
2042
2043 int vcd_server_mgr_stop()
2044 {
2045         /* 1. Check current state is recording */
2046         if (VCD_STATE_RECORDING != vcd_config_get_service_state()) {
2047                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not recording");
2048                 return VCD_ERROR_INVALID_STATE;
2049         }
2050         if (-1 == vcd_client_manager_get_pid()) {
2051                 SLOG(LOG_INFO, TAG_VCD, "[Server] Manager is NOT available.");
2052                 return VCD_ERROR_OPERATION_FAILED;
2053         }
2054         SLOG(LOG_ERROR, TAG_VCD, "[Server] stop internal recognition");
2055
2056 #if 1
2057         /* 2. Stop recorder */
2058         vcd_recorder_stop();
2059 #endif
2060
2061         /* 3. Stop engine recognition */
2062         int ret = vcd_engine_recognize_stop();
2063         if (0 != ret) {
2064                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
2065         }
2066
2067         /* 4. Set original mode */
2068         vcd_config_set_service_state(VCD_STATE_PROCESSING);
2069         vcdc_send_service_state(VCD_STATE_PROCESSING);
2070
2071         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] stop internal recognition");
2072         return VCD_ERROR_NONE;
2073 }
2074
2075 int vcd_server_mgr_cancel()
2076 {
2077         if (-1 == vcd_client_manager_get_pid()) {
2078                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Manager is NOT available.");
2079                 return VCD_ERROR_OPERATION_FAILED;
2080         }
2081
2082         if (g_restart_timer != NULL) {
2083                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Delete restart engine timer");
2084                 ecore_timer_del(g_restart_timer);
2085                 g_restart_timer = NULL;
2086         }
2087
2088         /* 1. Check current state */
2089         vcd_state_e state = vcd_config_get_service_state();
2090         if (VCD_STATE_READY == state) {
2091                 SLOG(LOG_INFO, TAG_VCD, "[Server] Current state is READY");
2092                 vcd_recorder_stop();
2093
2094                 if (false == vcd_client_manager_get_exclusive()) {
2095                         if (1 == vcd_config_get_command_type_enabled(VC_COMMAND_TYPE_WIDGET)) {
2096                                 int pid = vcd_client_widget_get_foreground_pid();
2097                                 if (-1 != pid) {
2098                                         SLOG(LOG_INFO, TAG_VCD, "[Server] Request tooltip hide");
2099                                         ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
2100                                 }
2101                         }
2102                 }
2103
2104                 vcdc_send_service_state(VCD_STATE_READY);
2105                 return VCD_ERROR_NONE;
2106         }
2107         SLOG(LOG_ERROR, TAG_VCD, "[Server] cancel internal recognition");
2108
2109 #if 1
2110         /* 2. Stop recorder */
2111         vcd_recorder_stop();
2112 #endif
2113
2114         /* 3. Cancel engine */
2115         int ret = vcd_engine_recognize_cancel();
2116         if (0 != ret) {
2117                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to cancel : %d", ret);
2118         }
2119
2120         if (false == vcd_client_manager_get_exclusive()) {
2121                 if (1 == vcd_config_get_command_type_enabled(VC_COMMAND_TYPE_WIDGET)) {
2122                         int pid = vcd_client_widget_get_foreground_pid();
2123                         if (-1 != pid) {
2124                                 SLOG(LOG_INFO, TAG_VCD, "[Server] Request tooltip hide");
2125                                 ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
2126                         }
2127                 }
2128         } else {
2129                 vcd_client_manager_set_exclusive(false);
2130         }
2131
2132         /* 4. Set state */
2133         vcd_config_set_service_state(VCD_STATE_READY);
2134         vcdc_send_service_state(VCD_STATE_READY);
2135
2136         SLOG(LOG_ERROR, TAG_VCD, "[Server Success] cancel internal recognition");
2137         return VCD_ERROR_NONE;
2138 }
2139
2140
2141 int vcd_server_mgr_result_select()
2142 {
2143         __vcd_send_selected_result(NULL);
2144
2145         return VCD_ERROR_NONE;
2146 }
2147
2148 int vcd_server_mgr_set_domain(int pid, const char* domain)
2149 {
2150         /* check if pid is valid */
2151         if (false == vcd_client_manager_is_valid(pid)) {
2152                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
2153                 return VCD_ERROR_INVALID_PARAMETER;
2154         }
2155
2156         vcd_state_e state = vcd_config_get_service_state();
2157         if (VCD_STATE_READY != state) {
2158                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
2159                 return VCD_ERROR_INVALID_STATE;
2160         }
2161
2162         /* Set domain to engine */
2163         int ret = vcd_engine_set_domain(pid, domain);
2164         if (0 != ret) {
2165                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set domain : %d", ret);
2166         } else {
2167                 SLOG(LOG_INFO, TAG_VCD, "[Server SUCCESS] Set domain");
2168         }
2169
2170         return ret;
2171 }
2172
2173 int vcd_server_mgr_set_private_data(int pid, const char* key, const char* data)
2174 {
2175         /* check if pid is valid */
2176         if (false == vcd_client_manager_is_valid(pid)) {
2177                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
2178                 return VCD_ERROR_INVALID_PARAMETER;
2179         }
2180
2181         vcd_state_e state = vcd_config_get_service_state();
2182         if (VCD_STATE_READY != state) {
2183                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
2184                 return VCD_ERROR_INVALID_STATE;
2185         }
2186
2187         /* Set private data to engine */
2188         int ret = vcd_engine_set_private_data(pid, key, data);
2189         if (0 != ret) {
2190                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data : %d", ret);
2191         } else {
2192                 SLOG(LOG_INFO, TAG_VCD, "[Server SUCCESS] Set private data");
2193         }
2194
2195         return ret;
2196 }
2197
2198 int vcd_server_mgr_get_private_data(int pid, const char* key, char** data)
2199 {
2200         /* check if pid is valid */
2201         if (false == vcd_client_manager_is_valid(pid)) {
2202                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
2203                 return VCD_ERROR_INVALID_PARAMETER;
2204         }
2205         vcd_state_e state = vcd_config_get_service_state();
2206         if (VCD_STATE_READY != state) {
2207                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
2208                 return VCD_ERROR_INVALID_STATE;
2209         }
2210
2211         /* Get private data to engine */
2212         int ret = vcd_engine_get_private_data(pid, key, data);
2213         if (0 != ret) {
2214                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get private data : %d", ret);
2215         } else {
2216                 SLOG(LOG_INFO, TAG_VCD, "[Server SUCCESS] Set private data");
2217         }
2218
2219         return ret;
2220 }
2221
2222 int vcd_server_mgr_send_specific_engine_request(int pid, const char* engine_app_id, const char* event, const char* request)
2223 {
2224         /* check if pid is valid */
2225         if (false == vcd_client_manager_is_valid(pid)) {
2226                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
2227                 return VCD_ERROR_INVALID_PARAMETER;
2228         }
2229         vcd_state_e state = vcd_config_get_service_state();
2230         if (VCD_STATE_READY != state && VCD_STATE_SYNTHESIZING != state) {
2231                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready and not synthesizing, state(%d)", state);
2232                 return VCD_ERROR_INVALID_STATE;
2233         }
2234
2235         /* Get private data to engine */
2236         int ret = vcd_engine_send_specific_engine_request(engine_app_id, event, request);
2237         if (0 != ret) {
2238                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set specific engine request : %d", ret);
2239         } else {
2240                 SLOG(LOG_INFO, TAG_VCD, "[Server SUCCESS] Set specific engine request ");
2241         }
2242
2243         return ret;
2244 }
2245
2246 int vcd_server_mgr_do_action(int pid, int type, const char* action)
2247 {
2248         int ret = -1;
2249
2250         /* check if pid is valid */
2251         if (false == vcd_client_manager_is_valid(pid)) {
2252                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
2253                 return VCD_ERROR_INVALID_PARAMETER;
2254         }
2255
2256         vcd_state_e state = vcd_config_get_service_state();
2257         if (VCD_STATE_READY != state && VCD_STATE_SYNTHESIZING != state) {
2258                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready and not synthesizing, state(%d)", state);
2259                 return VCD_ERROR_INVALID_STATE;
2260         }
2261
2262         /* Request do action to engine */
2263         if (VCD_SEND_EVENT_TYPE_TEXT == type)
2264                 ret = vcd_engine_process_text(pid, action);
2265         else if (VCD_SEND_EVENT_TYPE_LIST_EVENT == type)
2266                 ret = vcd_engine_process_list_event(pid, action);
2267         else if (VCD_SEND_EVENT_TYPE_HAPTIC_EVENT == type)
2268                 ret = vcd_engine_process_haptic_event(pid, action);
2269
2270         if (0 != ret) {
2271                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to process do action : %d", ret);
2272         } else {
2273                 vcd_config_set_service_state(VCD_STATE_PROCESSING);
2274                 vcdc_send_service_state(VCD_STATE_PROCESSING);
2275                 SLOG(LOG_INFO, TAG_VCD, "[Server SUCCESS] Process do action");
2276         }
2277
2278         return ret;
2279 }
2280
2281 int vcd_server_mgr_set_disabled_command_type(int pid, int disabled_cmd_type)
2282 {
2283         int ret = -1;
2284
2285         /* check if pid is valid */
2286         if (false == vcd_client_manager_is_valid(pid)) {
2287                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
2288                 return VCD_ERROR_INVALID_PARAMETER;
2289         }
2290
2291         vcd_state_e state = vcd_config_get_service_state();
2292         if (VCD_STATE_READY != state) {
2293                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
2294                 return VCD_ERROR_INVALID_STATE;
2295         }
2296
2297         ret = vcd_config_set_disabled_command_type(disabled_cmd_type);
2298         if (0 != ret) {
2299                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set command type");
2300         } else {
2301                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Set command type(%d)", disabled_cmd_type);
2302         }
2303
2304         return ret;
2305 }
2306
2307
2308 /* for TTS feedback */
2309 int vcd_server_mgr_start_feedback(void)
2310 {
2311         /* check current state */
2312         /* not Recording??? */
2313
2314         if (-1 == vcd_client_manager_get_pid()) {
2315                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Manager is NOT available");
2316                 return VCD_ERROR_OPERATION_FAILED;
2317         }
2318
2319         SLOG(LOG_INFO, TAG_VCD, "[Server] start TTS feedback");
2320
2321         /* check there is TTS buffer to be spoken */
2322
2323         return VCD_ERROR_NONE;
2324 }
2325
2326 int vcd_server_mgr_stop_feedback(void)
2327 {
2328         /* check current state */
2329         /* not Recording??? */
2330
2331         if (-1 == vcd_client_manager_get_pid()) {
2332                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Manager is NOT available");
2333                 return VCD_ERROR_OPERATION_FAILED;
2334         }
2335
2336         SLOG(LOG_INFO, TAG_VCD, "[Server] stop TTS feedback");
2337
2338         return VCD_ERROR_NONE;
2339 }
2340
2341 int vcd_server_mgr_send_audio_streaming(int pid, int event, const char* buffer, unsigned int len)
2342 {
2343         SLOG(LOG_INFO, TAG_VCD, "[DEBUG] Send Audio Streaming from Multi-assistant. event(%d), buffer(%p), len(%d)", event, &buffer, len);
2344
2345         int ret = 0;
2346         if (VCD_AUDIO_STREAMING_EVENT_START == event) {
2347                 ret = vcd_recorder_start_streaming();
2348                 if (0 != ret) {
2349                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to start streaming, ret(%d)", ret);
2350                         return ret;
2351                 }
2352         }
2353
2354         ret = vcd_recorder_send_streaming((const void*)buffer, (const unsigned int)len);
2355         if (0 != ret) {
2356                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to start streaming, ret(%d)", ret);
2357                 return ret;
2358         }
2359
2360         if (VCD_AUDIO_STREAMING_EVENT_FINISH == event) {
2361                 ret = vcd_recorder_stop_streaming();
2362                 if (0 != ret) {
2363                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to stop streaming, ret(%d)", ret);
2364                         return ret;
2365                 }
2366         }
2367
2368         return VCD_ERROR_NONE;
2369 }
2370
2371 int vcd_server_mgr_change_system_volume(int pid, vcd_system_volume_event_e system_volume_event)
2372 {
2373         SLOG(LOG_INFO, TAG_VCD, "[DEBUG] change system volume, system volume event(%d)", system_volume_event);
2374
2375         int ret = 0;
2376         if (VCD_SYSTEM_VOLUME_EVENT_CHANGE == system_volume_event) {
2377                 ret = vcd_recorder_change_system_volume();
2378                 if (0 != ret) {
2379                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to change system volume, ret(%d)", ret);
2380                         return ret;
2381                 }
2382         } else if (VCD_SYSTEM_VOLUME_EVENT_RECOVER == system_volume_event) {
2383                 ret = vcd_recorder_recover_system_volume();
2384                 if (0 != ret) {
2385                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to recover system volume, ret(%d)", ret);
2386                         return ret;
2387                 }
2388         }
2389
2390         return ret;
2391 }
2392
2393
2394 /*
2395 * VC Server Functions for Client
2396 */
2397 int vcd_server_initialize(int pid)
2398 {
2399         if (false == vcd_engine_is_available_engine()) {
2400                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
2401                 return VCD_ERROR_ENGINE_NOT_FOUND;
2402         }
2403
2404         /* check if pid is valid */
2405         if (true == vcd_client_is_available(pid)) {
2406                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] The pid is already exist");
2407                 return VCD_ERROR_NONE;
2408         }
2409
2410         /* Add client information to client manager */
2411         if (0 != vcd_client_add(pid)) {
2412                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add client info");
2413                 return VCD_ERROR_OPERATION_FAILED;
2414         }
2415
2416         SLOG(LOG_INFO, TAG_VCD, "[Server Success] Client Initialize : pid(%d)", pid);
2417
2418         return VCD_ERROR_NONE;
2419 }
2420
2421 int vcd_server_finalize(int pid)
2422 {
2423         /* check if pid is valid */
2424         if (false == vcd_client_is_available(pid)) {
2425                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2426                 return VCD_ERROR_INVALID_PARAMETER;
2427         }
2428
2429         /* Remove client information */
2430         if (0 != vcd_client_delete(pid)) {
2431                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
2432         }
2433
2434         if (0 == vcd_client_get_ref_count()) {
2435                 SLOG(LOG_INFO, TAG_VCD, "[Server] Connected client list is empty");
2436                 ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
2437         }
2438
2439         SLOG(LOG_INFO, TAG_VCD, "[Server Success] Client Finalize : pid(%d)", pid);
2440
2441         return VCD_ERROR_NONE;
2442 }
2443
2444 int vcd_server_set_command(int pid, vc_cmd_type_e cmd_type)
2445 {
2446         /* check if pid is valid */
2447         if (false == vcd_client_is_available(pid)) {
2448                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2449                 return VCD_ERROR_INVALID_PARAMETER;
2450         }
2451
2452         if (0 != vcd_client_set_command_type(pid, cmd_type)) {
2453                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set command type : pid(%d), cmd_type(%d)", pid, cmd_type);
2454                 return VCD_ERROR_OPERATION_FAILED;
2455         }
2456
2457         return VCD_ERROR_NONE;
2458 }
2459
2460 int vcd_server_unset_command(int pid, vc_cmd_type_e cmd_type)
2461 {
2462         /* check if pid is valid */
2463         if (false == vcd_client_is_available(pid)) {
2464                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2465                 return VCD_ERROR_INVALID_PARAMETER;
2466         }
2467
2468         if (0 != vcd_client_unset_command_type(pid, cmd_type)) {
2469                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to unset command type : pid(%d), cmd_type(%d)", pid, cmd_type);
2470                 return VCD_ERROR_OPERATION_FAILED;
2471         }
2472
2473         return VCD_ERROR_NONE;
2474 }
2475
2476 int vcd_server_set_foreground(int pid, bool value)
2477 {
2478         /* check if pid is valid */
2479         if (false == vcd_client_is_available(pid) && false == vcd_client_widget_is_available(pid)) {
2480                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2481                 return VCD_ERROR_INVALID_PARAMETER;
2482         }
2483
2484         if (0 != vcd_config_set_foreground(pid, value)) {
2485                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set foreground : pid(%d), value(%d)", pid, value);
2486                 return VCD_ERROR_OPERATION_FAILED;
2487         }
2488
2489         return VCD_ERROR_NONE;
2490 }
2491
2492 static int __vcd_server_launch_manager_app()
2493 {
2494         int ret = -1;
2495         bool running = false;
2496         char* appid = NULL;
2497
2498         ret = vcd_client_manager_get_appid(&appid);
2499         if (0 != ret || NULL == appid) {
2500                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get manager appid");
2501                 return VCD_ERROR_OPERATION_FAILED;
2502         }
2503         ret = app_manager_is_running(appid, &running);
2504         if (0 != ret) {
2505                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to check running with appid(%s)", appid);
2506                 free(appid);
2507                 appid = NULL;
2508                 return VCD_ERROR_OPERATION_FAILED;
2509         }
2510         if (false == running) {
2511                 int tmp_ret = __vcd_is_package_installed(appid);
2512                 if (false == tmp_ret) {
2513                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] manager app is not installed, appid(%s)", appid);
2514                 } else {
2515                         ret = __vcd_activate_app_by_appcontrol(appid);
2516                         if (0 != ret) {
2517                                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to activate app");
2518                                 free(appid);
2519                                 appid = NULL;
2520                                 return ret;
2521                         }
2522                         SLOG(LOG_ERROR, TAG_VCD, "Launch vc manager app: appid(%s)", appid);
2523                 }
2524         } else {
2525                 ret = __vcd_resume_app(appid);
2526                 if (0 != ret) {
2527                         SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to resume app");
2528                         free(appid);
2529                         appid = NULL;
2530                         return ret;
2531                 }
2532                 SLOG(LOG_ERROR, TAG_VCD, "Resume vc manager app: appid(%s)", appid);
2533         }
2534
2535         free(appid);
2536         appid = NULL;
2537
2538         return VCD_ERROR_NONE;
2539 }
2540
2541 int vcd_server_set_server_dialog(int pid, const char* app_id, const char* credential)
2542 {
2543         /* check if pid is valid */
2544         if (false == vcd_client_is_available(pid)) {
2545                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2546                 return VCD_ERROR_INVALID_PARAMETER;
2547         }
2548
2549         int ret = vcd_engine_set_server_dialog(app_id, credential);
2550         if (0 != ret) {
2551                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set server dialog, pid(%d), app_id(%s), ret(%d)", pid, app_id, ret);
2552                 vcd_client_set_server_dialog(pid, false);
2553                 return ret;
2554         }
2555         SLOG(LOG_ERROR, TAG_VCD, "[Success] Set server dialog, pid(%d), app_id(%s)", pid, app_id);
2556
2557         if (0 != strncmp(credential, "#NULL", strlen(credential))) {
2558                 ret = vcd_client_set_server_dialog(pid, true);
2559                 if (0 != ret)
2560                         SLOG(LOG_INFO, TAG_VCD, "[Server] Set to true for server dialog, app_id(%s)", app_id);
2561         } else {
2562                 ret = vcd_client_set_server_dialog(pid, false);
2563                 if (0 != ret)
2564                         SLOG(LOG_INFO, TAG_VCD, "[Server] Set to false for server dialog, app_id(%s)", app_id);
2565         }
2566
2567         return VCD_ERROR_NONE;
2568 }
2569
2570 int vcd_server_dialog(int pid, const char* disp_text, const char* utt_text, int continuous)
2571 {
2572         /* check if pid is valid */
2573         if (false == vcd_client_is_available(pid) && false == vcd_client_widget_is_available(pid)) {
2574                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2575                 return VCD_ERROR_INVALID_PARAMETER;
2576         }
2577
2578         bool is_server_dialog = false;
2579         int ret = vcd_client_get_server_dialog(pid, &is_server_dialog);
2580         if (0 != ret) {
2581                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get server dialog, pid(%d), ret(%d)", pid, ret);
2582         }
2583
2584         if (true == is_server_dialog) {
2585                 /* ++ Request tts event to engine */
2586
2587                 /* -- Request tts event to engine */
2588         } else {
2589                 ret = __vcd_server_launch_manager_app();
2590                 if (0 != ret) {
2591                         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);
2592                         return ret;
2593                 }
2594
2595                 ret = vcdc_send_dialog(vcd_client_manager_get_pid(), pid, disp_text, utt_text, continuous);
2596                 if (0 != ret) {
2597                         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);
2598                         return ret;
2599                 }
2600         }
2601         return VCD_ERROR_NONE;
2602 }
2603
2604 int vcd_server_is_system_command_valid(int pid, bool* is_sys_cmd_valid)
2605 {
2606         /* check if pid is valid */
2607         if (false == vcd_client_is_available(pid) && false == vcd_client_widget_is_available(pid)) {
2608                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2609                 return VCD_ERROR_INVALID_PARAMETER;
2610         }
2611
2612         /* check if system command is valid */
2613         if (true == vcd_client_manager_is_system_command_valid(vcd_client_manager_get_pid()))
2614                 *is_sys_cmd_valid = true;
2615         else
2616                 *is_sys_cmd_valid = false;
2617
2618         return VCD_ERROR_NONE;
2619 }
2620
2621 static void __start_tts_request_thread(void* data, Ecore_Thread* thread)
2622 {
2623         SLOG(LOG_INFO, TAG_VCD, "[SUCCESS] Start tts request thread");
2624         vc_tts_text_data_s* tts_text_data = NULL;
2625
2626         while (1) {
2627                 int ret = -1;
2628                 int cnt = 0;
2629
2630                 /* Get tts text data */
2631                 ret = vcd_data_get_first_tts_text_data(&tts_text_data);
2632                 if (0 != ret || NULL == tts_text_data) {
2633                         /* empty queue */
2634                         if (0 >= vcd_data_get_tts_text_data_size()) {
2635                                 SLOG(LOG_INFO, TAG_VCD, "[DEBUG] No tts text data");
2636                                 return;
2637                         }
2638                         SLOG(LOG_INFO, TAG_VCD, "[INFO] tts text data is just incoming");
2639                         continue;
2640                 }
2641
2642                 while (1) {
2643                         vcd_state_e state = vcd_config_get_service_state();
2644                         if (VCD_STATE_READY != state) {
2645                                 if (0 == cnt++ % 10)
2646                                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Waiting to request TTS, state(%d)", state);
2647                                 usleep(100000);
2648                                 continue;
2649                         }
2650                         break;
2651                 }
2652
2653                 /* Set service state to synthesizing */
2654                 vcd_config_set_service_state(VCD_STATE_SYNTHESIZING);
2655
2656                 /* Set current uid */
2657                 g_current_tts_uid = tts_text_data->uid;
2658
2659                 /* Request tts to engine */
2660                 ret = vcd_engine_request_tts(tts_text_data->pid, tts_text_data->utt_id, tts_text_data->text, tts_text_data->language);
2661                 if (0 != ret) {
2662                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to request tts : %d", ret);
2663                 } else {
2664                         SLOG(LOG_INFO, TAG_VCD, "[Server SUCCESS] request tts, uid(%u) pid(%d), text(%s), language(%s), utt_id(%d)",
2665                                 tts_text_data->uid, tts_text_data->pid, tts_text_data->text, tts_text_data->language, tts_text_data->utt_id);
2666                 }
2667                 /* clear tts text data after use */
2668                 vcd_data_clear_tts_text_data(&tts_text_data);
2669         }
2670 }
2671
2672 static void __end_tts_request_thread(void* data, Ecore_Thread* thread)
2673 {
2674         SLOG(LOG_INFO, TAG_VCD, "[SUCCESS] End tts request thread");
2675         g_tts_thread = NULL;
2676 }
2677
2678 int vcd_server_request_tts(int pid, const char* text, const char* language, int to_vcm, int* utt_id)
2679 {
2680         /* check if pid is valid */
2681         if (false == vcd_client_is_available(pid)) {
2682                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2683                 return VCD_ERROR_INVALID_PARAMETER;
2684         }
2685
2686         vcd_state_e state = vcd_config_get_service_state();
2687         if (VCD_STATE_READY != state && VCD_STATE_SYNTHESIZING != state) {
2688                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready, state(%d)", state);
2689                 return VCD_ERROR_INVALID_STATE;
2690         }
2691
2692         unsigned int tts_uid = VC_INVALID_TTS_UID;
2693         g_current_utt_id = (g_current_utt_id + 1) % 1000;
2694         *utt_id = g_current_utt_id;
2695         if (0 == to_vcm) {
2696                 tts_uid = (unsigned int)pid * 1000u + (unsigned int)g_current_utt_id;
2697         } else {
2698                 tts_uid = (unsigned int)vcd_client_manager_get_pid() * 1000u + (unsigned int)g_current_utt_id;
2699         }
2700         SLOG(LOG_INFO, TAG_VCD, "[Server INFO] pid(%d), text(%s), language(%s), to_vcm(%d), ", pid, text, language, to_vcm);
2701         SLOG(LOG_INFO, TAG_VCD, "[Server INFO] current_uid(%u), current_utt_id(%d)", tts_uid, g_current_utt_id);
2702
2703         vc_tts_text_data_s* tts_text_data;
2704         tts_text_data = (vc_tts_text_data_s*)calloc(1, sizeof(vc_tts_text_data_s));
2705         if (!tts_text_data) {
2706                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to callocate memory ");
2707                 return VCD_ERROR_OUT_OF_MEMORY;
2708         }
2709         tts_text_data->uid = tts_uid;
2710         tts_text_data->pid = pid;
2711         tts_text_data->utt_id = g_current_utt_id;
2712         tts_text_data->text = strdup(text);
2713         tts_text_data->language = strdup(language);
2714
2715         int ret = vcd_data_add_tts_text_data(tts_text_data);
2716         if (0 != ret) {
2717                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add tts text data : %d", ret);
2718         }
2719
2720         bool is_canceled = ecore_thread_check(g_tts_thread);
2721         if (NULL == g_tts_thread || TRUE == is_canceled) {
2722                 SLOG(LOG_INFO, TAG_VCD, "[Server INFO] ecore thread run : start_tts_request_thread ");
2723                 g_tts_thread = ecore_thread_run(__start_tts_request_thread, __end_tts_request_thread, NULL, NULL);
2724         }
2725
2726         return VCD_ERROR_NONE;
2727 }
2728
2729 int vcd_server_cancel_tts(int pid, int utt_id)
2730 {
2731         /* check if pid is valid */
2732         if (false == vcd_client_is_available(pid)) {
2733                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2734                 return VCD_ERROR_INVALID_PARAMETER;
2735         }
2736
2737         vcd_state_e state = vcd_config_get_service_state();
2738         if (VCD_STATE_READY != state && VCD_STATE_SYNTHESIZING != state) {
2739                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready, state(%d)", state);
2740                 return VCD_ERROR_INVALID_STATE;
2741         }
2742
2743         vc_tts_text_data_s* tts_text_data = NULL;
2744
2745         unsigned int tts_uid = (unsigned int)pid * 1000u + (unsigned int)utt_id;
2746         int ret = vcd_data_get_tts_text_data(tts_uid, &tts_text_data);
2747         if (0 != ret) {
2748                 SLOG(LOG_WARN, TAG_VCD, "[Server WARN] No data in vcd tts text queue");
2749         } else {
2750                 if (tts_text_data) {
2751                         SLOG(LOG_INFO, TAG_VCD, "[Server] Clear tts text data, pid(%d), utt_id(%d), text(%s)", pid, utt_id, tts_text_data->text);
2752                         vcd_data_clear_tts_text_data(&tts_text_data);
2753                         tts_text_data = NULL;
2754                 } else {
2755                         SLOG(LOG_INFO, TAG_VCD, "[Server] Clear tts text data, pid(%d), utt_id(%d), text(nullptr)", pid, utt_id);
2756                 }
2757         }
2758
2759         /* Request tts to engine */
2760         ret = vcd_engine_cancel_tts(pid, utt_id);
2761         if (0 != ret) {
2762                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to cancel tts : %d", ret);
2763         } else {
2764                 SLOG(LOG_INFO, TAG_VCD, "[Server SUCCESS] request tts, pid(%d), utt_id(%d)", pid, utt_id);
2765         }
2766
2767         /* Set service state */
2768         vcd_config_set_service_state(VCD_STATE_READY);
2769
2770         return VCD_ERROR_NONE;
2771 }
2772
2773 int vcd_server_get_tts_audio_format(int pid, int* rate, int* channel, int* audio_type)
2774 {
2775         /* check if pid is valid */
2776         if (false == vcd_client_is_available(pid)) {
2777                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2778                 return VCD_ERROR_INVALID_PARAMETER;
2779         }
2780
2781         vcd_state_e state = vcd_config_get_service_state();
2782         if (VCD_STATE_READY != state && VCD_STATE_SYNTHESIZING != state) {
2783                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready and not synthesizing, state(%d)", state);
2784                 return VCD_ERROR_INVALID_STATE;
2785         }
2786
2787         /* Request tts to engine */
2788         int ret = vcd_engine_get_tts_audio_format(rate, channel, audio_type);
2789         if (0 != ret) {
2790                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get tts audio format : %d", ret);
2791         } else {
2792                 SLOG(LOG_INFO, TAG_VCD, "[Server SUCCESS] get tts audio format, pid(%d), rate(%d), channel(%d), audio_type(%d)", pid, *rate, *channel, *audio_type);
2793         }
2794
2795         return ret;
2796 }
2797
2798 #if 0
2799 int vcd_server_set_exclusive_command(int pid, bool value)
2800 {
2801         /* check if pid is valid */
2802         if (false == vcd_client_is_available(pid)) {
2803                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2804                 return VCD_ERROR_INVALID_PARAMETER;
2805         }
2806
2807         if (true == value) {
2808                 if (0 != vcd_client_set_exclusive_command(pid)) {
2809                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set exclusive command : pid(%d)", pid);
2810                         return VCD_ERROR_OPERATION_FAILED;
2811                 }
2812         } else {
2813                 if (0 != vcd_client_unset_exclusive_command(pid)) {
2814                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to unset exclusive command : pid(%d)", pid);
2815                         return VCD_ERROR_OPERATION_FAILED;
2816                 }
2817         }
2818
2819         return VCD_ERROR_NONE;
2820 }
2821
2822 int vcd_server_request_start(int pid, bool stop_by_silence)
2823 {
2824         /* check if pid is valid */
2825         if (false == vcd_client_is_available(pid)) {
2826                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid(%d) is NOT foreground client", pid);
2827                 return VCD_ERROR_INVALID_PARAMETER;
2828         }
2829
2830         int ret;
2831         /* Check current state */
2832         vcd_state_e state = vcd_config_get_service_state();
2833
2834         /* Service state should be ready */
2835         if (VCD_STATE_READY != state) {
2836                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Ready : pid(%d)", pid);
2837                 return VCD_ERROR_INVALID_STATE;
2838         }
2839
2840         if (-1 != vcd_client_manager_get_pid()) {
2841                 /* Check current pid is valid */
2842                 if (false == vcd_client_manager_check_demandable_client(pid)) {
2843                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
2844                         return VCD_ERROR_INVALID_PARAMETER;
2845                 }
2846         }
2847
2848         ret = vcd_server_mgr_start(stop_by_silence, false);
2849         if (0 != ret) {
2850                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
2851                 return VCD_ERROR_INVALID_PARAMETER;
2852         }
2853
2854         return VCD_ERROR_NONE;
2855 }
2856
2857 int vcd_server_request_stop(int pid)
2858 {
2859         int ret;
2860         /* Check current state */
2861         vcd_state_e state = vcd_config_get_service_state();
2862
2863         /* Service state should be ready */
2864         if (VCD_STATE_RECORDING != state) {
2865                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording : pid(%d)", pid);
2866                 return VCD_ERROR_INVALID_STATE;
2867         }
2868
2869         if (-1 != vcd_client_manager_get_pid()) {
2870                 /* Check current pid is valid */
2871                 if (false == vcd_client_manager_check_demandable_client(pid)) {
2872                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
2873                         return VCD_ERROR_INVALID_PARAMETER;
2874                 }
2875         }
2876
2877         ret = vcd_server_mgr_stop();
2878         if (0 != ret) {
2879                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
2880                 return VCD_ERROR_OPERATION_FAILED;
2881         }
2882
2883         return VCD_ERROR_NONE;
2884 }
2885
2886 int vcd_server_request_cancel(int pid)
2887 {
2888         int ret;
2889         /* Check current state */
2890         vcd_state_e state = vcd_config_get_service_state();
2891
2892         /* Service state should be recording or processing */
2893         if (VCD_STATE_RECORDING != state && VCD_STATE_PROCESSING != state) {
2894                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording or Processing : pid(%d)", pid);
2895                 return VCD_ERROR_INVALID_STATE;
2896         }
2897
2898         if (-1 != vcd_client_manager_get_pid()) {
2899                 /* Check current pid is valid */
2900                 if (false == vcd_client_manager_check_demandable_client(pid)) {
2901                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
2902                         return VCD_ERROR_INVALID_PARAMETER;
2903                 }
2904         }
2905
2906         ret = vcd_server_mgr_cancel();
2907         if (0 != ret) {
2908                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
2909                 return VCD_ERROR_OPERATION_FAILED;
2910         }
2911
2912         return VCD_ERROR_NONE;
2913 }
2914 #endif
2915
2916 /*
2917 * VC Server Functions for Widget lib
2918 */
2919 int vcd_server_widget_initialize(int pid)
2920 {
2921         if (false == vcd_engine_is_available_engine()) {
2922                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
2923                 return VCD_ERROR_ENGINE_NOT_FOUND;
2924         }
2925
2926         /* check if pid is valid */
2927         if (true == vcd_client_widget_is_available(pid)) {
2928                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] The pid is already exist");
2929                 return VCD_ERROR_NONE;
2930         }
2931
2932         /* Add client information to client manager */
2933         if (0 != vcd_client_widget_add(pid)) {
2934                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add client info");
2935                 return VCD_ERROR_OPERATION_FAILED;
2936         }
2937
2938         SLOG(LOG_INFO, TAG_VCD, "[Server Success] Initialize widget : pid(%d)", pid);
2939
2940         return VCD_ERROR_NONE;
2941 }
2942
2943 static void __vcd_server_widget_start_recording(void *data)
2944 {
2945         SLOG(LOG_ERROR, TAG_VCD, "[Server INFO] start recording");
2946
2947         if (0 != __start_internal_recognition()) {
2948                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition");
2949         }
2950 }
2951
2952 int vcd_server_widget_finalize(int pid)
2953 {
2954         /* check if pid is valid */
2955         if (false == vcd_client_widget_is_available(pid)) {
2956                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2957                 if (0 == vcd_client_get_ref_count()) {
2958                         SLOG(LOG_ERROR, TAG_VCD, "[Server] connected client list is empty, vc-service will be terminated");
2959                         ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
2960                         return VCD_ERROR_NONE;
2961                 }
2962                 return VCD_ERROR_INVALID_PARAMETER;
2963         }
2964
2965         /* Remove client information */
2966         if (0 != vcd_client_widget_delete(pid)) {
2967                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
2968         }
2969
2970         if (0 == vcd_client_get_ref_count()) {
2971                 SLOG(LOG_ERROR, TAG_VCD, "[Server] connected client list is empty, vc-service will be terminated");
2972                 ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
2973                 return VCD_ERROR_NONE;
2974         }
2975
2976         bool is_waiting = false;
2977         if (0 != vcd_client_widget_get_waiting_for_recording(pid, &is_waiting)) {
2978                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to get waiting to recording");
2979         }
2980
2981         if (true == is_waiting) {
2982                 SLOG(LOG_ERROR, TAG_VCD, "[Server INFO] invoke to start recording");
2983                 ecore_main_loop_thread_safe_call_async(__vcd_server_widget_start_recording, NULL);
2984         }
2985         return VCD_ERROR_NONE;
2986 }
2987
2988 int vcd_server_widget_start_recording(int pid, bool widget_command)
2989 {
2990         /* check if pid is valid */
2991         if (false == vcd_client_widget_is_available(pid)) {
2992                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
2993                 return VCD_ERROR_INVALID_PARAMETER;
2994         }
2995
2996         bool waiting;
2997         if (0 != vcd_client_widget_get_waiting_for_recording(pid, &waiting) || false == waiting) {
2998                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Server is not waiting for recording, pid(%d), waiting(%d)", pid, waiting);
2999                 return VCD_ERROR_NONE;
3000         }
3001
3002         if (true == widget_command) {
3003                 vcd_client_widget_set_command(pid);
3004                 SLOG(LOG_INFO, TAG_VCD, "[Server] widget command is available");
3005         } else {
3006                 vcd_client_widget_unset_command(pid);
3007                 SLOG(LOG_WARN, TAG_VCD, "[Server] widget command is NOT available");
3008         }
3009
3010         SLOG(LOG_ERROR, TAG_VCD, "[Server] start internal recognition : %d", widget_command);
3011         int ret = __start_internal_recognition();
3012         if (0 != ret) {
3013                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition : %d", ret);
3014                 ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
3015         }
3016
3017         return VCD_ERROR_NONE;
3018 }
3019
3020 int vcd_server_widget_start(int pid, bool stop_by_silence)
3021 {
3022         /* check if pid is valid */
3023         int fore_pid = vcd_client_widget_get_foreground_pid();
3024         if (pid != fore_pid) {
3025                 SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
3026                 return VCD_ERROR_INVALID_PARAMETER;
3027         }
3028
3029         /* Check current state */
3030         vcd_state_e state = vcd_config_get_service_state();
3031
3032         /* Service state should be ready */
3033         if (VCD_STATE_READY != state) {
3034                 SLOG(LOG_INFO, TAG_VCD, "[Server] Current state is not Ready : pid(%d)", pid);
3035                 return VCD_ERROR_INVALID_STATE;
3036         }
3037
3038         vcd_client_set_slience_detection(stop_by_silence);
3039
3040         /* Notify show tooltip */
3041         ecore_timer_add(0, __vcd_request_show_tooltip, (void*)true);
3042
3043         return VCD_ERROR_NONE;
3044 }
3045
3046 int vcd_server_widget_stop(int pid)
3047 {
3048         /* check if pid is valid */
3049         int fore_pid = vcd_client_widget_get_foreground_pid();
3050         if (pid != fore_pid) {
3051                 SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
3052                 return VCD_ERROR_INVALID_PARAMETER;
3053         }
3054
3055         int ret;
3056         /* Check current state */
3057         vcd_state_e state = vcd_config_get_service_state();
3058
3059         /* Service state should be recording */
3060         if (VCD_STATE_RECORDING != state) {
3061                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Current service state is not Recording : pid(%d)", pid);
3062                 return VCD_ERROR_INVALID_STATE;
3063         }
3064
3065         ret = vcd_server_mgr_stop();
3066         if (0 != ret) {
3067                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Fail to start recognition");
3068                 return VCD_ERROR_OPERATION_FAILED;
3069         }
3070
3071         return VCD_ERROR_NONE;
3072 }
3073
3074 int vcd_server_widget_cancel(int pid)
3075 {
3076         /* check if pid is valid */
3077         int fore_pid = vcd_client_widget_get_foreground_pid();
3078         if (pid != fore_pid) {
3079                 SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
3080                 return VCD_ERROR_INVALID_PARAMETER;
3081         }
3082
3083         int ret;
3084         /* Check current state */
3085         vcd_state_e state = vcd_config_get_service_state();
3086
3087         /* Service state should be recording or processing */
3088         if (VCD_STATE_RECORDING != state && VCD_STATE_PROCESSING != state) {
3089                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Current state is not Recording or Processing : pid(%d)", pid);
3090                 return VCD_ERROR_INVALID_STATE;
3091         }
3092
3093         ret = vcd_server_mgr_cancel();
3094         if (0 != ret) {
3095                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Fail to cancel recognition : %d", ret);
3096                 return ret;
3097         }
3098
3099         return VCD_ERROR_NONE;
3100 }
3101
3102 int vcd_server_widget_enable_asr_result(int pid, bool enable)
3103 {
3104         int ret;
3105         ret = vcd_client_widget_set_asr_result_enabled(pid, enable);
3106         if (0 != ret) {
3107                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Fail to enable asr result : %d", ret);
3108         }
3109
3110         return ret;
3111 }
3112
3113 int vcd_server_set_language(const char* language)
3114 {
3115         int ret = VCD_ERROR_NONE;
3116
3117         ret = vcd_config_set_default_language(language);
3118         if (0 != ret) {
3119                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Fail to set language : %d", ret);
3120                 return ret;
3121         }
3122
3123         ret = vcd_engine_set_current_language(language);
3124         if (0 != ret) {
3125                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Fail to set language : %d", ret);
3126                 return ret;
3127         }
3128
3129         return ret;
3130 }
3131 /*
3132 * For engine service
3133 */
3134 int vcd_get_foreach_command(vce_cmd_h vce_command, vce_command_cb callback, void* user_data)
3135 {
3136         SLOG(LOG_INFO, TAG_VCD, "[Server] Get foreach command");
3137
3138         if (NULL == callback) {
3139                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] input parameter is NULL");
3140                 return VCD_ERROR_INVALID_PARAMETER;
3141         }
3142
3143         int ret = 0;
3144         ret = vcd_engine_agent_get_foreach_command(vce_command, callback, user_data);
3145         if (0 != ret) {
3146                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get foreach command : ret(%d)", ret);
3147         }
3148
3149         return ret;
3150 }
3151
3152 int vcd_get_command_count(vce_cmd_h vce_command, int* count)
3153 {
3154         SLOG(LOG_INFO, TAG_VCD, "[Server] Get command count");
3155
3156         int ret = 0;
3157         ret = vcd_engine_agent_get_command_count(vce_command, count);
3158         if (0 != ret) {
3159                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get command count : ret(%d)", ret);
3160         }
3161
3162         return ret;
3163 }
3164
3165 int vcd_get_audio_type(char** audio_type)
3166 {
3167         SLOG(LOG_INFO, TAG_VCD, "[Server] Get audio type");
3168
3169         int ret = 0;
3170         ret = vcd_engine_agent_get_audio_type(audio_type);
3171         if (0 != ret) {
3172                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio type : ret(%d)", ret);
3173         }
3174
3175         return ret;
3176 }
3177
3178 int vcd_set_private_data(const char* key, const char* data)
3179 {
3180         vcd_state_e state = vcd_config_get_service_state();
3181
3182         if (VCD_STATE_READY != state) {
3183                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state(%d) is NOT 'READY'", state);
3184                 return VCD_ERROR_INVALID_STATE;
3185         }
3186
3187         int ret = vcd_engine_agent_set_private_data(key, data);
3188         if (0 != ret) {
3189                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data to the manager client : ret(%d)", ret);
3190         } else {
3191                 SLOG(LOG_INFO, TAG_VCD, "[Server] Set private data to the manager client, key(%s), data(%s)", key, data);
3192         }
3193
3194         return ret;
3195 }
3196
3197 int vcd_get_private_data(const char* key, char** data)
3198 {
3199         vcd_state_e state = vcd_config_get_service_state();
3200
3201         if (VCD_STATE_READY != state) {
3202                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state(%d) is NOT 'READY'", state);
3203                 return VCD_ERROR_INVALID_STATE;
3204         }
3205
3206         int ret = vcd_engine_agent_get_private_data(key, data);
3207         if (0 != ret) {
3208                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get private data from the manager client : ret(%d)", ret);
3209         } else {
3210                 SLOG(LOG_INFO, TAG_VCD, "[Server] Get private data from the manager client, key(%s), data(%s)", key, *data);
3211         }
3212
3213         return ret;
3214 }
3215
3216 int vcd_start_recording()
3217 {
3218         SLOG(LOG_INFO, TAG_VCD, "[Server] Start recording");
3219
3220         int ret = 0;
3221         ret = vcd_engine_agent_start_recording();
3222         if (0 != ret) {
3223                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recording : ret(%d)", ret);
3224         }
3225
3226         return ret;
3227 }
3228
3229 int vcd_stop_recording()
3230 {
3231         SLOG(LOG_INFO, TAG_VCD, "[Server] Stop recording");
3232
3233         int ret = 0;
3234         ret = vcd_engine_agent_stop_recording();
3235         if (0 != ret) {
3236                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recording : ret(%d)", ret);
3237         }
3238
3239         return ret;
3240 }
3241
3242 int vcd_send_update_status(vce_update_event_e update_event, const char* msg)
3243 {
3244         SLOG(LOG_INFO, TAG_VCD, "[Server] update status, update event(%d), msg(%s)", update_event, msg);
3245
3246         int ret = 0;
3247         if (VCE_UPDATE_EVENT_START == update_event) {
3248                 if (VCD_STATE_RECORDING == vcd_config_get_service_state() || VCD_STATE_PROCESSING == vcd_config_get_service_state()) {
3249                         ret = vcd_server_mgr_cancel();
3250                         if (0 != ret) {
3251                                 SLOG(LOG_ERROR, TAG_VCD, "[Server Error] Fail to cancel, ret(%d)", ret);
3252                                 return ret;
3253                         }
3254                 }
3255                 vcd_config_set_service_state(VCD_STATE_UPDATING);
3256                 vcdc_send_service_state(VCD_STATE_UPDATING);
3257
3258         } else if (VCE_UPDATE_EVENT_FINISH == update_event) {
3259                 vcd_config_set_service_state(VCD_STATE_READY);
3260                 vcdc_send_service_state(VCD_STATE_READY);
3261
3262         } else if (VCE_UPDATE_EVENT_FAIL == update_event) {
3263                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Update event : Fail - msg(%s)", msg);
3264         }
3265
3266         return VCD_ERROR_NONE;
3267 }
3268
3269 int vcd_set_private_data_set_cb(vce_private_data_set_cb callback_func)
3270 {
3271         SLOG(LOG_INFO, TAG_VCD, "[Server] Set private data set cb");
3272
3273         int ret = 0;
3274         ret = vcd_engine_agent_set_private_data_set_cb(callback_func);
3275         if (0 != ret) {
3276                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data set cb : ret(%d)", ret);
3277         }
3278
3279         return ret;
3280 }
3281
3282 int vcd_set_private_data_requested_cb(vce_private_data_requested_cb callback_func)
3283 {
3284         SLOG(LOG_INFO, TAG_VCD, "[Server] Set private data requested cb");
3285
3286         int ret = 0;
3287         ret = vcd_engine_agent_set_private_data_requested_cb(callback_func);
3288         if (0 != ret) {
3289                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data requested cb : ret(%d)", ret);
3290         }
3291
3292         return ret;
3293 }
3294
3295 int vcd_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func)
3296 {
3297         SLOG(LOG_INFO, TAG_VCD, "[Server] Set nlu base info requested cb");
3298
3299         int ret = 0;
3300         ret = vcd_engine_agent_set_nlu_base_info_requested_cb(callback_func);
3301         if (0 != ret) {
3302                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set nlu base info requested cb : ret(%d)", ret);
3303         }
3304
3305         return ret;
3306 }
3307
3308 int vcd_set_specific_engine_request_cb(vce_specific_engine_request_cb callback_func)
3309 {
3310         SLOG(LOG_INFO, TAG_VCD, "[Server] Set specific engine request cb");
3311         int ret = 0;
3312         ret = vcd_engine_agent_set_specific_engine_request_cb(callback_func);
3313         if (0 != ret) {
3314                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set specific engine request cb : ret(%d)", ret);
3315         }
3316
3317         return ret;
3318 }
3319
3320 int vcd_set_request_tts_cb(vce_request_tts_cb callback_func, void* user_data)
3321 {
3322         SLOG(LOG_INFO, TAG_VCD, "[Server] Set request tts cb");
3323         int ret = 0;
3324         ret = vcd_engine_agent_set_request_tts_cb(callback_func, user_data);
3325         if (0 != ret) {
3326                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set request tts cb : ret(%d)", ret);
3327         }
3328
3329         return ret;
3330 }
3331
3332 int vcd_set_cancel_tts_cb(vce_cancel_tts_cb callback_func, void* user_data)
3333 {
3334         SLOG(LOG_INFO, TAG_VCD, "[Server] Set cancel tts cb");
3335         int ret = 0;
3336         ret = vcd_engine_agent_set_cancel_tts_cb(callback_func, user_data);
3337         if (0 != ret) {
3338                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set cancel tts cb : ret(%d)", ret);
3339         }
3340
3341         return ret;
3342 }
3343
3344 int vcd_set_tts_audio_format_request_cb(vce_tts_audio_format_request_cb callback_func, void* user_data)
3345 {
3346         SLOG(LOG_INFO, TAG_VCD, "[Server] Set tts audio format request cb");
3347         int ret = 0;
3348         ret = vcd_engine_agent_set_get_tts_audio_format_cb(callback_func, user_data);
3349         if (0 != ret) {
3350                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set tts audio format request : ret(%d)", ret);
3351         }
3352
3353         return ret;
3354 }