Init commit from tizen 2.4
[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 <dirent.h>
18 #include <sound_manager.h>
19
20 #include "vc_info_parser.h"
21 #include "vcd_main.h"
22 #include "vcd_server.h"
23 #include "vcd_client_data.h"
24
25 #include "vcd_engine_agent.h"
26 #include "vcd_config.h"
27 #include "vcd_recorder.h"
28 #include "vcd_dbus.h"
29
30 #include "voice_control_command_expand.h"
31
32 /*
33 * VC Server static variable
34 */
35 static bool     g_is_engine;
36
37 /*
38 * VC Server Internal Functions
39 */
40 static Eina_Bool __stop_by_silence(void *data)
41 {
42         SLOG(LOG_DEBUG, TAG_VCD, "===== Silence Detected ");
43
44         vcd_server_mgr_stop();
45
46         SLOG(LOG_DEBUG, TAG_VCD, "=====");
47         SLOG(LOG_DEBUG, TAG_VCD, "  ");
48         return EINA_FALSE;
49 }
50
51 static Eina_Bool __cancel_by_interrupt(void *data)
52 {
53         SLOG(LOG_DEBUG, TAG_VCD, "===== Cancel by interrupt");
54
55         vcd_server_mgr_cancel();
56
57         SLOG(LOG_DEBUG, TAG_VCD, "=====");
58         SLOG(LOG_DEBUG, TAG_VCD, "  ");
59         return EINA_FALSE;
60 }
61
62 static int __server_recorder_callback(const void* data, const unsigned int length)
63 {
64         vcd_state_e state = vcd_config_get_service_state();
65         if (VCD_STATE_RECORDING != state) {
66                 return 0;
67         }
68
69         vcp_speech_detect_e speech_detected = VCP_SPEECH_DETECT_NONE;
70         int ret;
71
72         ret = vcd_engine_recognize_audio(data, length, &speech_detected);
73
74         if (0 > ret) {
75                 /* Error */
76                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set recording data to engine(%d)", ret);
77                 ecore_timer_add(0, __cancel_by_interrupt, NULL);
78                 return 0;
79         }
80
81         if (VCP_SPEECH_DETECT_BEGIN == speech_detected) {
82                 if (-1 != vcd_client_manager_get_pid()) {
83                         /* Manager client is available */
84                         if (0 != vcdc_send_speech_detected(vcd_client_manager_get_pid())) {
85                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send speech detected");
86                         }
87                 }
88         } else if (VCP_SPEECH_DETECT_END == speech_detected && vcd_client_get_slience_detection()) {
89                 /* silence detected */
90                 ecore_timer_add(0, __stop_by_silence, NULL);
91         }
92
93         return 0;
94 }
95
96 void __server_recorder_interrupt_callback()
97 {
98         SLOG(LOG_DEBUG, TAG_VCD, "===== Cancel by sound interrupt");
99
100         ecore_timer_add(0, __cancel_by_interrupt, NULL);
101
102         SLOG(LOG_DEBUG, TAG_VCD, "=====");
103         SLOG(LOG_DEBUG, TAG_VCD, "  ");
104 }
105
106 static void __config_lang_changed_cb(const char* current_lang, void* user_data)
107 {
108         SLOG(LOG_DEBUG, TAG_VCD, "===== Change language ");
109
110         /* Current state is recording */
111         vcd_state_e state = vcd_config_get_service_state();
112         if (VCD_STATE_RECORDING == state || VCD_STATE_PROCESSING == state) {
113                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is 'Recording'. Cancel recognition");
114                 vcd_server_mgr_cancel();
115         }
116
117         int ret;
118         ret = vcd_engine_set_current_language(current_lang);
119         if (0 != ret) {
120                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set language of engine : %d", ret);
121         }
122
123         SLOG(LOG_DEBUG, TAG_VCD, "=====");
124         SLOG(LOG_DEBUG, TAG_VCD, "  ");
125
126         return;
127 }
128
129 static void __config_foreground_changed_cb(int previous, int current, void* user_data)
130 {
131         SLOG(LOG_DEBUG, TAG_VCD, "===== Change foreground");
132
133         SLOG(LOG_DEBUG, TAG_VCD, "Foreground pid(%d)", current);
134         
135         if (VC_NO_FOREGROUND_PID != current) {
136                 /* Foreground app is changed */
137                 vcd_state_e state = vcd_config_get_service_state();
138                 if (VCD_STATE_RECORDING == state) {
139                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Foreground pid(%d) is changed. Cancel recognition", current);
140                         ecore_timer_add(0, __cancel_by_interrupt, NULL);
141                 }
142         }
143
144         SLOG(LOG_DEBUG, TAG_VCD, "=====");
145         SLOG(LOG_DEBUG, TAG_VCD, "  ");
146
147         return;
148 }
149
150 static Eina_Bool __vcd_send_selected_result(void *data)
151 {
152         GSList* pid_list = NULL;
153         if (0 != vc_info_parser_get_result_pid_list(&pid_list)) {
154                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to get pid list. No result");
155         }
156         else {
157                 if (0 < g_slist_length(pid_list)){
158                         GSList* iter = NULL;
159                         vc_cmd_s* temp_cmd = NULL;
160                         int ret = 0;
161                         int count = 0;
162
163                         iter = g_slist_nth(pid_list, 0);
164                         while (NULL != iter) {
165                                 temp_cmd = iter->data;
166
167                                 if (NULL != temp_cmd) {
168                                         count = 0;
169                                         do {
170                                                 /* send result noti */
171                                                 ret = vcdc_send_result(temp_cmd->pid, temp_cmd->type);
172                                                 if (0 != ret) {
173                                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
174                                                         if (VCD_ERROR_TIMED_OUT != ret) {
175                                                                 break;
176                                                         }
177                                                 } else {
178                                                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Send result : pid(%d) type(%d)", temp_cmd->pid, temp_cmd->type);
179                                                 }
180                                                 count++;
181
182                                                 if (100 == count)       break;
183                                                 /* While is retry code */
184                                         } while (0 != ret);
185                                         free(temp_cmd);
186                                 }
187
188                                 pid_list = g_slist_remove_link(pid_list, iter);
189                                 iter = g_slist_nth(pid_list, 0);
190                         }
191                 }
192         }
193
194         vcd_config_set_service_state(VCD_STATE_READY);
195
196         return EINA_FALSE;
197 }
198
199 static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int count, 
200                                    const char* all_result, const char* non_fixed_result, const char* msg, void *user_data)
201 {
202         if (VCD_STATE_PROCESSING != vcd_config_get_service_state()) {
203                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not 'Processing'");
204                 return;
205         }
206
207         vc_info_parser_unset_result(vcd_client_manager_get_exclusive());
208
209         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Event(%d), Text(%s) Nonfixed(%s) Msg(%s) Result count(%d)", event, all_result, non_fixed_result, msg, count);
210
211         /* No result */
212         if (NULL == result_id) {
213                 /* No result */
214                 if (NULL != all_result) {
215                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Engine result is no command : %s", all_result);
216                         bool temp = vcd_client_manager_get_exclusive();
217                         vc_info_parser_set_result(all_result, event, msg, NULL, temp);
218                 }
219
220                 int pid = vcd_client_widget_get_foreground_pid();
221                 if (-1 != pid) {
222                         if (NULL != all_result) {
223                                 /* Send result text to widget */
224                                 vcdc_send_result(pid, VC_COMMAND_TYPE_WIDGET);
225                         }
226
227                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
228                         /* Send to hide tooltip */
229                         vcdc_send_show_tooltip(pid, false);
230                 }
231
232                 if (-1 != vcd_client_manager_get_pid()) {
233                         /* Manager client is available */
234                         if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid())) {
235                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
236                         }
237                 }
238
239                 vcd_client_manager_set_exclusive(false);
240
241                 return;
242         }
243
244         /* Normal result */
245         SLOG(LOG_DEBUG, TAG_VCD, "[Server] === Get engine result ===");
246
247         int ret = -1;
248         vc_cmd_s* temp_cmd = NULL;
249         vc_cmd_list_h vc_cmd_list = NULL;
250
251         if (0 != vc_cmd_list_create(&vc_cmd_list)) {
252                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to create command list");
253                 vcd_client_manager_set_exclusive(false);
254                 vcd_config_set_service_state(VCD_STATE_READY);
255                 return;
256         }
257
258         int i = 0;
259         for (i = 0;i < count;i++) {
260                 SLOG(LOG_DEBUG, TAG_VCD, "[Server]   [%d] Result ID(%d)", i, result_id[i]);
261
262                 if (result_id[i] < 0) {
263                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Result ID(%d) is NOT valid", result_id[i]);
264                         continue;
265                 }
266
267                 ret = vcd_client_get_cmd_from_result_id(result_id[i], &temp_cmd);
268                 if (0 == ret && NULL != temp_cmd) {
269                         switch (temp_cmd->format) {
270                         case VC_CMD_FORMAT_FIXED:
271                                 /* Nonfixed result is NOT valid */
272                                 break;
273                         case VC_CMD_FORMAT_FIXED_AND_EXTRA:
274                                 if (NULL == temp_cmd->parameter) {
275                                         if (NULL != non_fixed_result) {
276                                                 temp_cmd->parameter = strdup(non_fixed_result);
277                                         }
278                                 } else {
279                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Command type is NOT vaild. Parameter (%s)", temp_cmd->parameter);
280                                 }
281                                 break;
282                         case VC_CMD_FORMAT_EXTRA_AND_FIXED:
283                                 if (NULL == temp_cmd->command) {
284                                         if (NULL != non_fixed_result) {
285                                                 temp_cmd->command = strdup(non_fixed_result);
286                                         }
287                                 } else {
288                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Command type is NOT vaild. Command (%s)", temp_cmd->command);
289                                 }
290
291                                 break;
292                         default:
293                                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Unknown command type : %d", temp_cmd->type);
294                         }
295
296                         temp_cmd->id = i;
297                         if (0 != vc_cmd_list_add(vc_cmd_list, (vc_cmd_h)temp_cmd)) {
298                                 SLOG(LOG_DEBUG, TAG_VCD, "Fail to add command to list");
299                                 vc_cmd_destroy((vc_cmd_h)temp_cmd);
300                         }
301                 } else {
302                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] NOT found matached result(%d)", result_id[i]);
303                 }
304         }
305
306         vc_cmd_print_list(vc_cmd_list);
307
308         SLOG(LOG_DEBUG, TAG_VCD, "[Server] =========================");
309
310         int result_count = 0;
311         vc_cmd_list_get_count(vc_cmd_list, &result_count);
312
313         if (false == vcd_client_manager_get_exclusive()) {
314                 int pid = vcd_client_widget_get_foreground_pid();
315                 if (-1 != pid) {
316                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
317                         vcdc_send_show_tooltip(pid, false);
318                 }
319
320                 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, false);
321
322                 if (-1 != vcd_client_manager_get_pid()) {
323                         /* Manager client is available */
324                         if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid())) {
325                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
326                         }
327                 } else {
328                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available. Send result to client directly");
329                         /* Send result to client */
330                         ecore_timer_add(0, __vcd_send_selected_result, NULL);
331                 }
332         } else {
333                 /* exclusive command */
334                 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, true);
335
336                 if (-1 != vcd_client_manager_get_pid()) {
337                         /* Manager client is available */
338                         if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid())) {
339                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
340                         }
341                 } else {
342                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Manager is NOT available");
343                 }
344
345                 vcd_client_manager_set_exclusive(false);
346         }
347
348         vc_cmd_list_destroy(vc_cmd_list, true);
349
350         return;
351 }
352
353 /*
354 * vcd server Interfaces
355 */
356 static void __vcd_file_clean_up()
357 {
358         SLOG(LOG_DEBUG, TAG_VCD, "== Old file clean up == ");
359
360         DIR *dp = NULL;
361         int ret = -1;
362         struct dirent entry;
363         struct dirent *dirp = NULL;
364
365         dp = opendir(VC_RUNTIME_INFO_ROOT);
366         if (dp == NULL) {
367                 SLOG(LOG_ERROR, TAG_VCD, "[File message WARN] Fail to open path : %s", VC_RUNTIME_INFO_ROOT);
368                 return;
369         }
370
371         char remove_path[256] = {0, };
372         do {
373                 ret = readdir_r(dp, &entry, &dirp);
374                 if (0 != ret) {
375                         SLOG(LOG_ERROR, TAG_VCD, "[File ERROR] Fail to read directory");
376                         break;
377                 }
378
379                 if (NULL != dirp) {
380                         if (!strncmp("vc_", dirp->d_name, strlen("vc_"))) {
381                                 memset(remove_path, 0, 256);
382                                 snprintf(remove_path, 256, "%s/%s", VC_RUNTIME_INFO_ROOT, dirp->d_name);
383
384                                 /* Clean up code */
385                                 if (0 != remove(remove_path)) {
386                                         SLOG(LOG_WARN, TAG_VCD, "[File message WARN] Fail to remove file : %s", remove_path);
387                                 } else {
388                                         SLOG(LOG_DEBUG, TAG_VCD, "[File message] Remove file : %s", remove_path);
389                                 }
390                         }
391                 }
392         } while (NULL != dirp);
393
394         closedir(dp);
395
396         return;
397 }
398
399 int vcd_initialize()
400 {
401         int ret = 0;
402
403         /* Remove old file */
404         __vcd_file_clean_up();
405
406         /* initialize modules */
407         ret = vcd_config_initialize(__config_lang_changed_cb, __config_foreground_changed_cb, NULL);
408         if (0 != ret) {
409                 SLOG(LOG_ERROR, TAG_VCD, "[Server WARNING] Fail to initialize config.");
410         }
411
412         vcd_config_set_service_state(VCD_STATE_NONE);
413
414         ret = vcd_engine_agent_init(__vcd_server_result_cb);
415         if (0 != ret) {
416                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
417                 return ret;
418         }
419
420         if (0 != vcd_recorder_create(__server_recorder_callback, __server_recorder_interrupt_callback)) {
421                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to create recorder");
422                 return VCD_ERROR_OPERATION_FAILED;
423         }
424
425         /* Find engine */
426         ret = vcd_engine_agent_initialize_current_engine();
427         if (0 != ret) {
428                 if (VCD_ERROR_ENGINE_NOT_FOUND == ret)
429                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] There is No Voice control engine");
430                 else
431                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to init engine");
432
433                 g_is_engine = false;
434         } else {
435                 g_is_engine = true;
436         }
437
438         /* Load engine */
439         if (0 != vcd_engine_agent_load_current_engine()) {
440                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to load current engine");
441                 return VCD_ERROR_OPERATION_FAILED;
442         }
443
444         /* Initialize manager info */
445         vcd_client_manager_unset();
446
447         vcd_config_set_service_state(VCD_STATE_READY);
448
449         SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] initialize");
450
451         return 0;
452 }
453
454 void vcd_finalize()
455 {
456         vcd_state_e state = vcd_config_get_service_state();
457         if (VCD_STATE_READY != state) {
458                 if (VCD_STATE_RECORDING == state) {
459                         vcd_recorder_stop();
460                 }
461                 vcd_engine_recognize_cancel();
462         }
463         if (0 != vcd_recorder_destroy()) {
464                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to destroy recorder");
465         } else {
466                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] destroy recorder");
467         }
468
469         if (0 != vcd_engine_agent_release()) {
470                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to release engine");
471         } else {
472                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] release engine");
473         }
474
475         vcd_config_set_service_state(VCD_STATE_NONE);
476
477         SLOG(LOG_DEBUG, TAG_VCD, "[Server] mode finalize");
478
479         return;
480 }
481
482 static Eina_Bool __finalize_quit_ecore_loop(void *data)
483 {
484         SLOG(LOG_DEBUG, TAG_VCD, "[Server] quit ecore main loop");
485         ecore_main_loop_quit();
486         return EINA_FALSE;
487 }
488
489 Eina_Bool vcd_cleanup_client(void *data)
490 {
491         int* client_list = NULL;
492         int client_count = 0;
493         int result;
494         int i = 0;
495
496         if (0 == vcd_client_get_list(&client_list, &client_count)) {
497                 SLOG(LOG_DEBUG, TAG_VCD, "===== Clean up client ");
498                 if (NULL != client_list && client_count > 0) {
499                         for (i = 0;i < client_count;i++) {
500                                 result = vcdc_send_hello(client_list[i], VCD_CLIENT_TYPE_NORMAL);
501
502                                 if (0 == result) {
503                                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] pid(%d) should be removed.", client_list[i]);
504                                         vcd_server_finalize(client_list[i]);
505                                 } else if (-1 == result) {
506                                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Hello result has error");
507                                 }
508                         }
509                 }
510                 SLOG(LOG_DEBUG, TAG_VCD, "=====");
511                 SLOG(LOG_DEBUG, TAG_VCD, "  ");
512         }
513         if (NULL != client_list) {
514                 free(client_list);
515                 client_list = NULL;
516         }
517
518         if (0 == vcd_client_widget_get_list(&client_list, &client_count)) {
519                 SLOG(LOG_DEBUG, TAG_VCD, "===== Clean up widget");
520                 if (NULL != client_list && client_count > 0) {
521                         for (i = 0;i < client_count;i++) {
522                                 result = vcdc_send_hello(client_list[i], VCD_CLIENT_TYPE_WIDGET);
523
524                                 if (0 == result) {
525                                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget pid(%d) should be removed.", client_list[i]);
526                                         vcd_server_widget_finalize(client_list[i]);
527                                 } else if (-1 == result) {
528                                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Hello result has error");
529                                 }
530                         }
531                 }
532                 SLOG(LOG_DEBUG, TAG_VCD, "=====");
533                 SLOG(LOG_DEBUG, TAG_VCD, "  ");
534         }
535         if (NULL != client_list) {
536                 free(client_list);
537                 client_list = NULL;
538         }
539
540         /* manager */
541
542         return EINA_TRUE;
543 }
544
545 /*
546 * API for manager
547 */
548 int vcd_server_mgr_initialize(int pid)
549 {
550         if (false == g_is_engine) {
551                 if (0 != vcd_engine_agent_initialize_current_engine()) {
552                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
553                         g_is_engine = false;
554                         return VCD_ERROR_ENGINE_NOT_FOUND;
555                 } else {
556                         g_is_engine = true;
557                 }
558         }
559
560         /* check if pid is valid */
561         if (false == vcd_client_manager_is_valid(pid)) {
562                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The pid(%d) is already exist", pid);
563                 return VCD_ERROR_INVALID_PARAMETER;
564         }
565
566         /* Add client information to client manager */
567         if (0 != vcd_client_manager_set(pid)) {
568                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add manager");
569                 return VCD_ERROR_OPERATION_FAILED;
570         }
571
572         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Manager initialize : pid(%d)", pid);
573
574         return VCD_ERROR_NONE;
575 }
576
577 int vcd_server_mgr_finalize(int pid)
578 {
579         /* check if pid is valid */
580         if (false == vcd_client_manager_is_valid(pid)) {
581                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
582                 return VCD_ERROR_INVALID_PARAMETER;
583         }
584
585         /* Remove manager information */
586         if (0 != vcd_client_manager_unset()) {
587                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
588         }
589
590         if (0 == vcd_client_get_ref_count()) {
591                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Connected client list is empty");
592                 ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
593         }
594
595         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Manager Finalize : pid(%d)", pid);
596
597         return VCD_ERROR_NONE;
598 }
599
600 int vcd_server_mgr_set_command(int pid)
601 {
602         if (0 != vcd_client_manager_set_command(pid)) {
603                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
604                 return VCD_ERROR_INVALID_PARAMETER;
605         }
606         return VCD_ERROR_NONE;
607 }
608
609 int vcd_server_mgr_unset_command(int pid)
610 {
611         if (0 != vcd_client_manager_unset_command(pid)) {
612                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
613                 return VCD_ERROR_INVALID_PARAMETER;
614         }
615         return VCD_ERROR_NONE;
616 }
617
618 int vcd_server_mgr_set_demandable_client(int pid)
619 {
620         /* check if pid is valid */
621         if (false == vcd_client_manager_is_valid(pid)) {
622                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
623                 return VCD_ERROR_INVALID_PARAMETER;
624         }
625
626         GSList* client_list = NULL;
627         if (0 != vc_info_parser_get_demandable_clients(&client_list)) {
628                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get demandable client");
629                 return VCD_ERROR_OPERATION_FAILED;
630         }
631
632         /* Save client list */
633         if (0 != vcd_client_manager_set_demandable_client(pid, client_list)) {
634                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set demandable client list");
635                 return VCD_ERROR_OPERATION_FAILED;
636         }
637
638         return VCD_ERROR_NONE;
639 }
640
641 int vcd_server_mgr_set_audio_type(int pid, const char* audio_type)
642 {
643         /* check if pid is valid */
644         if (false == vcd_client_manager_is_valid(pid)) {
645                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
646                 return VCD_ERROR_INVALID_PARAMETER;
647         }
648         
649         int ret = 0;
650         vcp_audio_type_e type = VCP_AUDIO_TYPE_PCM_S16_LE;
651         int rate = 16000;
652         int channel = 1;
653
654         ret = vcd_engine_get_audio_format(audio_type, &type, &rate, &channel);
655         if (0 != ret) {
656                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio format : %d", ret);
657                 return VCD_ERROR_OPERATION_FAILED;
658         }
659
660         ret = vcd_recorder_set(audio_type, type, rate, channel);
661         if (0 != ret) {
662                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set audio in type : %d", ret);
663                 return VCD_ERROR_OPERATION_FAILED;
664         }
665
666         return VCD_ERROR_NONE;
667 }
668
669 int vcd_server_mgr_get_audio_type(int pid, char** audio_type)
670 {
671         /* check if pid is valid */
672         if (false == vcd_client_manager_is_valid(pid)) {
673                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
674                 return VCD_ERROR_INVALID_PARAMETER;
675         }
676         
677         int ret = vcd_recorder_get(audio_type);
678         if (0 != ret) {
679                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio in type : %d", ret);
680                 return VCD_ERROR_OPERATION_FAILED;
681         }
682
683         return VCD_ERROR_NONE;
684 }
685
686 int vcd_server_mgr_set_client_info(int pid)
687 {
688         /* check if pid is valid */
689         if (false == vcd_client_manager_is_valid(pid)) {
690                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
691                 return VCD_ERROR_INVALID_PARAMETER;
692         }
693
694         int ret = vcd_client_save_client_info();
695         if (0 != ret) {
696                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to save client info : %d", ret);
697                 return VCD_ERROR_OPERATION_FAILED;
698         }
699
700         return VCD_ERROR_NONE;
701 }
702
703 static int __start_internal_recognition()
704 {
705         int ret;
706
707         /* 2. Get commands */
708         ret = vcd_client_command_collect_command();
709         if (0 != ret) {
710                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to collect command : %d", ret);
711                 return VCD_ERROR_OPERATION_FAILED;
712         }
713
714         ret = vcd_client_get_length();
715         if (0 == ret) {
716                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNIING] No current command : %d", ret);
717                 return VCD_ERROR_OPERATION_FAILED;
718         }
719
720         /* 3. Set command to engine */
721         ret = vcd_engine_set_commands();
722         if (0 != ret) {
723                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to collect command : %d", ret);
724                 return VCD_ERROR_OPERATION_FAILED;
725         }
726
727         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Set command");
728
729         /* 4. start recognition */
730         ret = vcd_engine_recognize_start(true);
731         if (0 != ret) {
732                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
733                 return VCD_ERROR_OPERATION_FAILED;
734         }
735
736         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Start engine");
737
738         /* 5. recorder start */
739         ret = vcd_recorder_start();
740         if (0 != ret) {
741                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
742                 vcd_engine_recognize_cancel();
743                 return ret;
744         }
745
746         vcd_config_set_service_state(VCD_STATE_RECORDING);
747
748         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Start recognition");
749
750         return 0;
751 }
752
753 static Eina_Bool __vcd_request_show_tooltip(void *data)
754 {
755         int pid = vcd_client_widget_get_foreground_pid();
756         if (-1 != pid) {
757                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip show and widget command");
758                 vcdc_send_show_tooltip(pid, (bool)data);
759         }
760
761         return EINA_FALSE;
762 }
763
764 int vcd_server_mgr_start(bool stop_by_silence, bool exclusive_cmd, bool start_by_client)
765 {
766         /* 1. check current state */
767         vcd_state_e state = vcd_config_get_service_state();
768         
769         if (VCD_STATE_READY != state) {
770                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
771                 return VCD_ERROR_INVALID_STATE;
772         }
773
774         vcd_client_set_slience_detection(stop_by_silence);
775
776         if (false == exclusive_cmd) {
777                 /* Notify show tooltip */
778                 int pid = vcd_client_widget_get_foreground_pid();
779                 if (-1 != pid) {
780                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip show and widget command");
781                         ecore_timer_add(0, __vcd_request_show_tooltip, (void*)true);
782                         return 0;
783                 }
784         } else {
785                 vcd_client_manager_set_exclusive(exclusive_cmd);
786         }
787
788         int fg_pid = -1;
789         if (true == start_by_client) {
790                 /* Get foreground pid */
791                 if (0 != vcd_config_get_foreground(&fg_pid)) {
792                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get foreground");
793                 }
794                 
795                 /* Set client exclusive option */
796                 if (0 != vcd_client_set_exclusive_command(fg_pid)) {
797                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set exclusive command");
798                 }
799         }
800
801         int ret = __start_internal_recognition();
802         if (0 != ret) {
803                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recongition : %d", ret);
804                 return ret;
805         }
806
807         if (true == start_by_client) {
808                 vcd_client_unset_exclusive_command(fg_pid);
809         }
810
811         return VCD_ERROR_NONE;
812 }
813
814 int vcd_server_mgr_stop()
815 {
816         /* 1. Check current state is recording */
817         if (VCD_STATE_RECORDING != vcd_config_get_service_state()) {
818                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not recording");
819                 return VCD_ERROR_INVALID_STATE;
820         }
821
822         /* 2. Stop recorder */
823         vcd_recorder_stop();
824
825         /* 3. Stop engine recognition */
826         int ret = vcd_engine_recognize_stop();
827         if (0 != ret) {
828                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
829         }
830
831         /* 4. Set original mode */
832         vcd_config_set_service_state(VCD_STATE_PROCESSING);
833
834         return VCD_ERROR_NONE;
835 }
836
837 int vcd_server_mgr_cancel()
838 {
839         /* 1. Check current state */
840         vcd_state_e state = vcd_config_get_service_state();
841         if (VCD_STATE_RECORDING != state && VCD_STATE_PROCESSING != state) {
842                 SLOG(LOG_WARN, TAG_VCD, "[Server ERROR] Current state is not recording or processing");
843                 return VCD_ERROR_INVALID_STATE;
844         }
845
846         /* 2. Stop recorder */
847         vcd_recorder_stop();
848         /* 3. Cancel engine */
849         int ret = vcd_engine_recognize_cancel();
850         if (0 != ret) {
851                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to cancel : %d", ret);
852         }
853
854         if (false == vcd_client_manager_get_exclusive()) {
855                 int pid = vcd_client_widget_get_foreground_pid();
856                 if (-1 != pid) {
857                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
858                         ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
859                 }
860         } else {
861                 vcd_client_manager_set_exclusive(false);
862         }
863
864         /* 4. Set state */
865         vcd_config_set_service_state(VCD_STATE_READY);
866
867         return VCD_ERROR_NONE;
868 }
869
870
871 int vcd_server_mgr_result_select()
872 {
873         ecore_timer_add(0.01, __vcd_send_selected_result, NULL);
874
875         return VCD_ERROR_NONE;
876 }
877
878 /*
879 * VC Server Functions for Client
880 */
881 int vcd_server_initialize(int pid)
882 {
883         if (false == g_is_engine) {
884                 if (0 != vcd_engine_agent_initialize_current_engine()) {
885                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
886                         g_is_engine = false;
887                         return VCD_ERROR_ENGINE_NOT_FOUND;
888                 } else {
889                         g_is_engine = true;
890                 }
891         }
892
893         if (false == vcd_engine_is_available_engine()) {
894                 if (0 != vcd_engine_agent_initialize_current_engine()) {
895                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
896                         return VCD_ERROR_ENGINE_NOT_FOUND;
897                 }
898         }
899
900         /* check if pid is valid */
901         if (true == vcd_client_is_available(pid)) {
902                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The pid is already exist");
903                 return VCD_ERROR_INVALID_PARAMETER;
904         }
905
906         /* Add client information to client manager */
907         if (0 != vcd_client_add(pid)) {
908                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add client info");
909                 return VCD_ERROR_OPERATION_FAILED;
910         }
911
912         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Client Initialize : pid(%d)", pid);
913
914         return VCD_ERROR_NONE;
915 }
916
917 int vcd_server_finalize(int pid)
918 {
919         /* check if pid is valid */
920         if (false == vcd_client_is_available(pid)) {
921                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
922                 return VCD_ERROR_INVALID_PARAMETER;
923         }
924
925         /* Remove client information */
926         if (0 != vcd_client_delete(pid)) {
927                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
928         }
929
930         if (0 == vcd_client_get_ref_count()) {
931                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Connected client list is empty");
932                 ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
933         }
934
935         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Client Finalize : pid(%d)", pid);
936
937         return VCD_ERROR_NONE;
938 }
939
940 int vcd_server_set_command(int pid, vc_cmd_type_e cmd_type)
941 {
942         /* check if pid is valid */
943         if (false == vcd_client_is_available(pid)) {
944                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
945                 return VCD_ERROR_INVALID_PARAMETER;
946         }
947
948         if (0 != vcd_client_set_command_type(pid, cmd_type)) {
949                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set command type : pid(%d), cmd_type(%d)", pid, cmd_type);
950                 return VCD_ERROR_OPERATION_FAILED;
951         }
952
953         return 0;
954 }
955
956 int vcd_server_unset_command(int pid, vc_cmd_type_e cmd_type)
957 {
958         /* check if pid is valid */
959         if (false == vcd_client_is_available(pid)) {
960                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
961                 return VCD_ERROR_INVALID_PARAMETER;
962         }
963
964         if (0 != vcd_client_unset_command_type(pid, cmd_type)) {
965                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to unset command type : pid(%d), cmd_type(%d)", pid, cmd_type);
966                 return VCD_ERROR_OPERATION_FAILED;
967         }
968         
969         return 0;
970 }
971
972 #if 0
973 int vcd_server_set_exclusive_command(int pid, bool value)
974 {
975         /* check if pid is valid */
976         if (false == vcd_client_is_available(pid)) {
977                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
978                 return VCD_ERROR_INVALID_PARAMETER;
979         }
980
981         if (true == value) {
982                 if (0 != vcd_client_set_exclusive_command(pid)) {
983                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set exclusive command : pid(%d)", pid);
984                         return VCD_ERROR_OPERATION_FAILED;
985                 }
986         } else {
987                 if (0 != vcd_client_unset_exclusive_command(pid)) {
988                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to unset exclusive command : pid(%d)", pid);
989                         return VCD_ERROR_OPERATION_FAILED;
990                 }
991         }
992         
993         return 0;
994 }
995
996 int vcd_server_request_start(int pid, bool stop_by_silence)
997 {
998         /* check if pid is valid */
999         if (false == vcd_client_is_available(pid)) {
1000                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid(%d) is NOT forground client", pid);
1001                 return VCD_ERROR_INVALID_PARAMETER;
1002         }
1003
1004         int ret;
1005         /* Check current state */
1006         vcd_state_e state = vcd_config_get_service_state();
1007
1008         /* Service state should be ready */
1009         if (VCD_STATE_READY != state) {
1010                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Ready : pid(%d)", pid);
1011                 return VCD_ERROR_INVALID_STATE;
1012         }
1013
1014         if (-1 != vcd_client_manager_get_pid()) {
1015                 /* Check current pid is valid */
1016                 if (false == vcd_client_manager_check_demandable_client(pid)) {
1017                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
1018                         return VCD_ERROR_INVALID_PARAMETER;
1019                 }
1020         }
1021
1022         ret = vcd_server_mgr_start(stop_by_silence, false);
1023         if (0 != ret) {
1024                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
1025                 return VCD_ERROR_INVALID_PARAMETER;
1026         }
1027
1028         return 0;
1029 }
1030
1031 int vcd_server_request_stop(int pid)
1032 {
1033         int ret;
1034         /* Check current state */
1035         vcd_state_e state = vcd_config_get_service_state();
1036
1037         /* Service state should be ready */
1038         if (VCD_STATE_RECORDING != state) {
1039                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording : pid(%d)", pid);
1040                 return VCD_ERROR_INVALID_STATE;
1041         }
1042
1043         if (-1 != vcd_client_manager_get_pid()) {
1044                 /* Check current pid is valid */
1045                 if (false == vcd_client_manager_check_demandable_client(pid)) {
1046                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
1047                         return VCD_ERROR_INVALID_PARAMETER;
1048                 }
1049         }
1050
1051         ret = vcd_server_mgr_stop();
1052         if (0 != ret) {
1053                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
1054                 return VCD_ERROR_OPERATION_FAILED;
1055         }
1056
1057         return VCD_ERROR_NONE;
1058 }
1059
1060 int vcd_server_request_cancel(int pid)
1061 {
1062         int ret;
1063         /* Check current state */
1064         vcd_state_e state = vcd_config_get_service_state();
1065
1066         /* Service state should be recording or processing */
1067         if (VCD_STATE_RECORDING != state && VCD_STATE_PROCESSING != state) {
1068                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording or Processing : pid(%d)", pid);
1069                 return VCD_ERROR_INVALID_STATE;
1070         }
1071
1072         if (-1 != vcd_client_manager_get_pid()) {
1073                 /* Check current pid is valid */
1074                 if (false == vcd_client_manager_check_demandable_client(pid)) {
1075                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
1076                         return VCD_ERROR_INVALID_PARAMETER;
1077                 }
1078         }
1079
1080         ret = vcd_server_mgr_cancel();
1081         if (0 != ret) {
1082                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
1083                 return VCD_ERROR_OPERATION_FAILED;
1084         }
1085
1086         return VCD_ERROR_NONE;
1087 }
1088 #endif
1089
1090 /*
1091 * VC Server Functions for Widget lib
1092 */
1093 int vcd_server_widget_initialize(int pid)
1094 {
1095         if (false == g_is_engine) {
1096                 if (0 != vcd_engine_agent_initialize_current_engine()) {
1097                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
1098                         g_is_engine = false;
1099                         return VCD_ERROR_ENGINE_NOT_FOUND;
1100                 } else {
1101                         g_is_engine = true;
1102                 }
1103         }
1104
1105         if (false == vcd_engine_is_available_engine()) {
1106                 if (0 != vcd_engine_agent_initialize_current_engine()) {
1107                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
1108                         return VCD_ERROR_ENGINE_NOT_FOUND;
1109                 }
1110         }
1111
1112         /* check if pid is valid */
1113         if (true == vcd_client_widget_is_available(pid)) {
1114                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The pid is already exist");
1115                 return VCD_ERROR_INVALID_PARAMETER;
1116         }
1117
1118         /* Add client information to client manager */
1119         if (0 != vcd_client_widget_add(pid)) {
1120                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add client info");
1121                 return VCD_ERROR_OPERATION_FAILED;
1122         }
1123
1124         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Initialize widget : pid(%d)", pid);
1125
1126         return VCD_ERROR_NONE;
1127 }
1128
1129 int vcd_server_widget_finalize(int pid)
1130 {
1131         /* check if pid is valid */
1132         if (false == vcd_client_widget_is_available(pid)) {
1133                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
1134                 return VCD_ERROR_INVALID_PARAMETER;
1135         }
1136
1137         /* Remove client information */
1138         if (0 != vcd_client_widget_delete(pid)) {
1139                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
1140         }
1141
1142         if (0 == vcd_client_get_ref_count()) {
1143                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] connected client list is empty");
1144                 ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
1145         }
1146
1147         return VCD_ERROR_NONE;
1148 }
1149
1150 int vcd_server_widget_start_recording(int pid, bool widget_command)
1151 {
1152         /* check if pid is valid */
1153         if (false == vcd_client_widget_is_available(pid)) {
1154                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
1155                 return VCD_ERROR_INVALID_PARAMETER;
1156         }
1157
1158         if (true == widget_command) {
1159                 vcd_client_widget_set_command(pid);
1160                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget command is available");
1161         } else {
1162                 vcd_client_widget_unset_command(pid);
1163                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget command is NOT available");
1164         }
1165
1166         int ret = __start_internal_recognition();
1167         if (0 != ret) {
1168                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recongition : %d", ret);
1169                 ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
1170         }
1171
1172         return 0;
1173 }
1174
1175 int vcd_server_widget_start(int pid, bool stop_by_silence)
1176 {
1177         /* check if pid is valid */
1178         int fore_pid = vcd_client_widget_get_foreground_pid();
1179         if (pid != fore_pid) {
1180                 SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
1181                 return VCD_ERROR_INVALID_PARAMETER;
1182         }
1183
1184         /* Check current state */
1185         vcd_state_e state = vcd_config_get_service_state();
1186
1187         /* Service state should be ready */
1188         if (VCD_STATE_READY != state) {
1189                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Ready : pid(%d)", pid);
1190                 return VCD_ERROR_INVALID_STATE;
1191         }
1192
1193         vcd_client_set_slience_detection(stop_by_silence);
1194
1195         /* Notify show tooltip */
1196         ecore_timer_add(0, __vcd_request_show_tooltip, (void*)true);
1197
1198         return 0;
1199 }
1200
1201 int vcd_server_widget_stop(int pid)
1202 {
1203         /* check if pid is valid */
1204         int fore_pid = vcd_client_widget_get_foreground_pid();
1205         if (pid != fore_pid) {
1206                 SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
1207                 return VCD_ERROR_INVALID_PARAMETER;
1208         }
1209
1210         int ret;
1211         /* Check current state */
1212         vcd_state_e state = vcd_config_get_service_state();
1213
1214         /* Service state should be recording */
1215         if (VCD_STATE_RECORDING != state) {
1216                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current service state is not Recording : pid(%d)", pid);
1217                 return VCD_ERROR_INVALID_STATE;
1218         }
1219
1220         ret = vcd_server_mgr_stop();
1221         if (0 != ret) {
1222                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
1223                 return VCD_ERROR_OPERATION_FAILED;
1224         }
1225
1226         return VCD_ERROR_NONE;
1227 }
1228
1229 int vcd_server_widget_cancel(int pid)
1230 {
1231         /* check if pid is valid */
1232         int fore_pid = vcd_client_widget_get_foreground_pid();
1233         if (pid != fore_pid) {
1234                 SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
1235                 return VCD_ERROR_INVALID_PARAMETER;
1236         }
1237
1238         int ret;
1239         /* Check current state */
1240         vcd_state_e state = vcd_config_get_service_state();
1241
1242         /* Service state should be recording or processing */
1243         if (VCD_STATE_RECORDING != state && VCD_STATE_PROCESSING != state) {
1244                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording or Processing : pid(%d)", pid);
1245                 return VCD_ERROR_INVALID_STATE;
1246         }
1247
1248         ret = vcd_server_mgr_cancel();
1249         if (0 != ret) {
1250                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
1251                 return VCD_ERROR_OPERATION_FAILED;
1252         }
1253
1254         return VCD_ERROR_NONE;
1255 }
1256