Merge "Apply command priority Add api for filtering command by type" into tizen
[platform/core/uifw/voice-control.git] / server / vcd_server.c
1 /*
2 * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <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 static GList *g_proc_list = NULL;
38
39 /*
40 * VC Server Internal Functions
41 */
42 static Eina_Bool __stop_by_silence(void *data)
43 {
44         SLOG(LOG_DEBUG, TAG_VCD, "===== Silence Detected ");
45
46         vcd_server_mgr_stop();
47
48         SLOG(LOG_DEBUG, TAG_VCD, "=====");
49         SLOG(LOG_DEBUG, TAG_VCD, "  ");
50         return EINA_FALSE;
51 }
52
53 static Eina_Bool __cancel_by_interrupt(void *data)
54 {
55         SLOG(LOG_DEBUG, TAG_VCD, "===== Cancel by interrupt");
56
57         vcd_server_mgr_cancel();
58
59         SLOG(LOG_DEBUG, TAG_VCD, "=====");
60         SLOG(LOG_DEBUG, TAG_VCD, "  ");
61         return EINA_FALSE;
62 }
63
64 static Eina_Bool __restart_engine(void *data)
65 {
66         SLOG(LOG_DEBUG, TAG_VCD, "===== Restart by no result");
67
68         /* Restart recognition */
69         int ret = vcd_engine_recognize_start(true);
70         if (0 != ret) {
71                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to restart recognition : result(%d)", ret);
72                 return EINA_FALSE;
73         }
74
75         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Start engine");
76
77         if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == vcd_client_get_recognition_mode()) {
78                 vcd_config_set_service_state(VCD_STATE_RECORDING);
79                 vcdc_send_service_state(VCD_STATE_RECORDING);
80         }
81
82         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Restart recognition");
83
84         SLOG(LOG_DEBUG, TAG_VCD, "=====");
85         SLOG(LOG_DEBUG, TAG_VCD, "  ");
86         return EINA_FALSE;
87 }
88
89 static int __server_recorder_callback(const void* data, const unsigned int length)
90 {
91         vcd_state_e state = vcd_config_get_service_state();
92         if (VCD_STATE_RECORDING != state) {
93                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Skip by engine processing");
94                 return 0;
95         }
96
97         vcp_speech_detect_e speech_detected = VCP_SPEECH_DETECT_NONE;
98         int ret;
99
100         ret = vcd_engine_recognize_audio(data, length, &speech_detected);
101
102         if (0 > ret) {
103                 /* Error */
104                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set recording data to engine(%d)", ret);
105                 ecore_timer_add(0, __cancel_by_interrupt, NULL);
106                 return 0;
107         }
108
109         if (VCP_SPEECH_DETECT_BEGIN == speech_detected) {
110                 if (-1 != vcd_client_manager_get_pid()) {
111                         /* Manager client is available */
112                         if (0 != vcdc_send_speech_detected(vcd_client_manager_get_pid())) {
113                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send speech detected");
114                         }
115                 }
116         } else if (VCP_SPEECH_DETECT_END == speech_detected) {
117                 if (VCD_RECOGNITION_MODE_STOP_BY_SILENCE == vcd_client_get_recognition_mode()) {
118                         /* silence detected */
119                         ecore_timer_add(0, __stop_by_silence, NULL);
120                 } else if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == vcd_client_get_recognition_mode()) {
121                         /* Stop engine recognition */
122                         int ret = vcd_engine_recognize_stop();
123                         if (0 != ret) {
124                                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
125                         }
126                         vcd_config_set_service_state(VCD_STATE_PROCESSING);
127                         vcdc_send_service_state(VCD_STATE_PROCESSING);
128
129                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Stop engine only by silence");
130                 } else if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY == vcd_client_get_recognition_mode()) {
131                         /* Stop engine recognition */
132                         int ret = vcd_engine_recognize_stop();
133                         if (0 != ret) {
134                                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
135                         }
136                 }
137         }
138
139         return 0;
140 }
141
142 void __server_recorder_interrupt_callback()
143 {
144         SLOG(LOG_DEBUG, TAG_VCD, "===== Cancel by sound interrupt");
145
146         ecore_timer_add(0, __cancel_by_interrupt, NULL);
147
148         SLOG(LOG_DEBUG, TAG_VCD, "=====");
149         SLOG(LOG_DEBUG, TAG_VCD, "  ");
150 }
151
152 static void __config_lang_changed_cb(const char* current_lang, void* user_data)
153 {
154         SLOG(LOG_DEBUG, TAG_VCD, "===== Change language ");
155
156         /* Current state is recording */
157         vcd_state_e state = vcd_config_get_service_state();
158         if (VCD_STATE_RECORDING == state || VCD_STATE_PROCESSING == state) {
159                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is 'Recording'. Cancel recognition");
160                 vcd_server_mgr_cancel();
161         }
162
163         int ret;
164         ret = vcd_engine_set_current_language(current_lang);
165         if (0 != ret) {
166                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set language of engine : %d", ret);
167         }
168
169         SLOG(LOG_DEBUG, TAG_VCD, "=====");
170         SLOG(LOG_DEBUG, TAG_VCD, "  ");
171
172         return;
173 }
174
175 static void __config_foreground_changed_cb(int previous, int current, void* user_data)
176 {
177         SLOG(LOG_DEBUG, TAG_VCD, "===== Change foreground");
178
179         SLOG(LOG_DEBUG, TAG_VCD, "Foreground pid(%d)", current);
180
181         if (VC_NO_FOREGROUND_PID != current) {
182                 /* Foreground app is changed */
183                 vcd_state_e state = vcd_config_get_service_state();
184                 if (VCD_STATE_RECORDING == state) {
185                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Foreground pid(%d) is changed. Cancel recognition", current);
186                         ecore_timer_add(0, __cancel_by_interrupt, NULL);
187                 }
188         }
189
190         SLOG(LOG_DEBUG, TAG_VCD, "=====");
191         SLOG(LOG_DEBUG, TAG_VCD, "  ");
192
193         return;
194 }
195
196 static Eina_Bool __vcd_send_selected_result(void *data)
197 {
198         GSList* pid_list = NULL;
199         if (0 != vc_info_parser_get_result_pid_list(&pid_list)) {
200                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to get pid list. No result");
201         } else {
202                 if (0 < g_slist_length(pid_list)) {
203                         GSList* iter = NULL;
204                         vc_cmd_s* temp_cmd = NULL;
205                         int ret = 0;
206                         int count = 0;
207
208                         iter = g_slist_nth(pid_list, 0);
209                         while (NULL != iter) {
210                                 temp_cmd = iter->data;
211
212                                 if (NULL != temp_cmd) {
213                                         count = 0;
214                                         do {
215                                                 /* send result noti */
216                                                 ret = vcdc_send_result(temp_cmd->pid, temp_cmd->type);
217                                                 if (0 != ret) {
218                                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
219                                                         if (VCD_ERROR_TIMED_OUT != ret) {
220                                                                 break;
221                                                         }
222                                                 } else {
223                                                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Send result : pid(%d) type(%d)", temp_cmd->pid, temp_cmd->type);
224                                                 }
225                                                 count++;
226
227                                                 if (100 == count)       break;
228                                                 /* While is retry code */
229                                         } while (0 != ret);
230                                         free(temp_cmd);
231                                 }
232
233                                 pid_list = g_slist_remove_link(pid_list, iter);
234                                 iter = g_slist_nth(pid_list, 0);
235                         }
236                 }
237         }
238
239         if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY != vcd_client_get_recognition_mode()) {
240                 vcd_config_set_service_state(VCD_STATE_READY);
241                 vcdc_send_service_state(VCD_STATE_READY);
242         }
243
244         return EINA_FALSE;
245 }
246
247 static int __convert_type_to_priority(vc_cmd_type_e type)
248 {
249         switch (type) {
250                 case VC_COMMAND_TYPE_NONE:              return 0; break;
251                 case VC_COMMAND_TYPE_BACKGROUND:        return 1; break;
252                 case VC_COMMAND_TYPE_FOREGROUND:        return 2; break;
253                 case VC_COMMAND_TYPE_WIDGET:            return 2; break;
254                 case VC_COMMAND_TYPE_SYSTEM:            return 3; break;
255                 case VC_COMMAND_TYPE_EXCLUSIVE:         return 3; break;
256                 default:                                return 0; break;
257         }
258 }
259
260 static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int count, const char* all_result,
261                                                                    const char* non_fixed_result, const char* msg, void *user_data)
262 {
263         if (VCD_STATE_PROCESSING != vcd_config_get_service_state()) {
264                 if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY != vcd_client_get_recognition_mode()) {
265                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not 'Processing' and mode is not 'Restart continuously'");
266                         return;
267                 }
268         }
269
270         vc_info_parser_unset_result(vcd_client_manager_get_exclusive());
271
272         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Event(%d), Text(%s) Nonfixed(%s) Msg(%s) Result count(%d)", 
273                 event, all_result, non_fixed_result, msg, count);
274
275         if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == vcd_client_get_recognition_mode()) {
276                 if (VCP_RESULT_EVENT_REJECTED == event) {
277                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Restart by no or rejected result");
278                         /* If no result and restart option is ON */
279                         /* Send reject message */
280                         bool temp = vcd_client_manager_get_exclusive();
281                         vc_info_parser_set_result(all_result, event, msg, NULL, temp);
282                         if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION)) {
283                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
284                         }
285
286                         ecore_timer_add(0, __restart_engine, NULL);
287                         return;
288                 }
289                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Stop recorder due to success");
290                 vcd_recorder_stop();
291         } else if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY == vcd_client_get_recognition_mode()) {
292                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Restart continuously");
293                 /* Restart option is ON */
294                 ecore_timer_add(0, __restart_engine, NULL);
295                 if (VCP_RESULT_EVENT_REJECTED == event) {
296                         bool temp = vcd_client_manager_get_exclusive();
297                         vc_info_parser_set_result(all_result, event, msg, NULL, temp);
298                         if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NOTIFICATION)) {
299                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
300                         }
301                         return;
302                 }
303         }
304
305         /* No result */
306         if (NULL == result_id) {
307                 /* No result */
308                 if (NULL != all_result) {
309                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Engine result is no command : %s", all_result);
310                         bool temp = vcd_client_manager_get_exclusive();
311                         vc_info_parser_set_result(all_result, event, msg, NULL, temp);
312                 }
313
314                 int pid = vcd_client_widget_get_foreground_pid();
315                 if (-1 != pid) {
316                         if (NULL != all_result) {
317                                 /* Send result text to widget */
318                                 vcdc_send_result(pid, VC_COMMAND_TYPE_WIDGET);
319                         }
320
321                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
322                         /* Send to hide tooltip */
323                         vcdc_send_show_tooltip(pid, false);
324                 }
325
326                 if (-1 != vcd_client_manager_get_pid()) {
327                         /* Manager client is available */
328                         if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
329                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
330                         }
331                 }
332
333                 vcd_client_manager_set_exclusive(false);
334
335                 return;
336         }
337
338         /* Normal result */
339         SLOG(LOG_DEBUG, TAG_VCD, "[Server] === Get engine result ===");
340
341         int ret = -1;
342         vc_cmd_s* temp_cmd = NULL;
343         vc_cmd_list_h vc_cmd_list = NULL;
344
345         if (0 != vc_cmd_list_create(&vc_cmd_list)) {
346                 SLOG(LOG_ERROR, TAG_VCD, "[Server] Fail to create command list");
347                 vcd_client_manager_set_exclusive(false);
348                 vcd_config_set_service_state(VCD_STATE_READY);
349                 vcdc_send_service_state(VCD_STATE_READY);
350                 return;
351         }
352
353         int i = 0;
354         int priority = 0;
355         for (i = 0; i < count; i++) {
356                 SLOG(LOG_DEBUG, TAG_VCD, "[Server]   [%d] Result ID(%d)", i, result_id[i]);
357
358                 if (result_id[i] < 0) {
359                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Result ID(%d) is NOT valid", result_id[i]);
360                         continue;
361                 }
362
363                 ret = vcd_client_get_cmd_from_result_id(result_id[i], &temp_cmd);
364                 if (0 == ret && NULL != temp_cmd) {
365                         /* Add priority filter */
366                         int temp_priority = __convert_type_to_priority(temp_cmd->type);
367                         if (priority > temp_priority) {
368                                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Ignore result by priority");
369                                 continue;
370                         } else if (priority < temp_priority) {
371                                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] High priority result!!");
372                                 priority = temp_priority;
373
374                                 if (0 != vc_cmd_list_remove_all(vc_cmd_list, true)) {
375                                         SLOG(LOG_ERROR, TAG_VCD, "[Server] Fail to list remove all");
376                                 }
377                         }
378
379                         switch (temp_cmd->format) {
380                         case VC_CMD_FORMAT_FIXED:
381                                 /* Nonfixed result is NOT valid */
382                                 break;
383                         case VC_CMD_FORMAT_FIXED_AND_EXTRA:
384                                 if (NULL == temp_cmd->parameter) {
385                                         if (NULL != non_fixed_result) {
386                                                 temp_cmd->parameter = strdup(non_fixed_result);
387                                         }
388                                 } else {
389                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Command type is NOT vaild. Parameter (%s)", temp_cmd->parameter);
390                                 }
391                                 break;
392                         case VC_CMD_FORMAT_EXTRA_AND_FIXED:
393                                 if (NULL == temp_cmd->command) {
394                                         if (NULL != non_fixed_result) {
395                                                 temp_cmd->command = strdup(non_fixed_result);
396                                         }
397                                 } else {
398                                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Command type is NOT vaild. Command (%s)", temp_cmd->command);
399                                 }
400
401                                 break;
402                         default:
403                                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Unknown command type : %d", temp_cmd->type);
404                         }
405
406                         temp_cmd->id = i;
407                         if (0 != vc_cmd_list_add(vc_cmd_list, (vc_cmd_h)temp_cmd)) {
408                                 SLOG(LOG_DEBUG, TAG_VCD, "Fail to add command to list");
409                                 vc_cmd_destroy((vc_cmd_h)temp_cmd);
410                         }
411                 } else {
412                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] NOT found matached result(%d)", result_id[i]);
413                 }
414         }
415
416         vc_cmd_print_list(vc_cmd_list);
417
418         SLOG(LOG_DEBUG, TAG_VCD, "[Server] =========================");
419
420         int result_count = 0;
421         vc_cmd_list_get_count(vc_cmd_list, &result_count);
422
423         if (false == vcd_client_manager_get_exclusive()) {
424                 int pid = vcd_client_widget_get_foreground_pid();
425                 if (-1 != pid) {
426                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
427                         vcdc_send_show_tooltip(pid, false);
428                 }
429
430                 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, false);
431
432                 if (-1 != vcd_client_manager_get_pid()) {
433                         /* Manager client is available */
434                         if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
435                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
436                         }
437                 } else {
438                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available. Send result to client directly");
439                         /* Send result to client */
440                         ecore_timer_add(0, __vcd_send_selected_result, NULL);
441                 }
442         } else {
443                 /* exclusive command */
444                 vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, true);
445
446                 if (-1 != vcd_client_manager_get_pid()) {
447                         /* Manager client is available */
448                         if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) {
449                                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
450                         }
451                 } else {
452                         SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Manager is NOT available");
453                 }
454
455                 vcd_client_manager_set_exclusive(false);
456         }
457
458         vc_cmd_list_destroy(vc_cmd_list, true);
459
460         return;
461 }
462
463 /*
464 * vcd server Interfaces
465 */
466 static void __vcd_file_clean_up()
467 {
468         SLOG(LOG_DEBUG, TAG_VCD, "== Old file clean up == ");
469
470         DIR *dp = NULL;
471         int ret = -1;
472         struct dirent entry;
473         struct dirent *dirp = NULL;
474
475         dp = opendir(VC_RUNTIME_INFO_ROOT);
476         if (dp == NULL) {
477                 SLOG(LOG_ERROR, TAG_VCD, "[File message WARN] Fail to open path : %s", VC_RUNTIME_INFO_ROOT);
478                 return;
479         }
480
481         char remove_path[256] = {0, };
482         do {
483                 ret = readdir_r(dp, &entry, &dirp);
484                 if (0 != ret) {
485                         SLOG(LOG_ERROR, TAG_VCD, "[File ERROR] Fail to read directory");
486                         break;
487                 }
488
489                 if (NULL != dirp) {
490                         if (!strncmp("vc_", dirp->d_name, strlen("vc_"))) {
491                                 memset(remove_path, 0, 256);
492                                 snprintf(remove_path, 256, "%s/%s", VC_RUNTIME_INFO_ROOT, dirp->d_name);
493
494                                 /* Clean up code */
495                                 if (0 != remove(remove_path)) {
496                                         SLOG(LOG_WARN, TAG_VCD, "[File message WARN] Fail to remove file : %s", remove_path);
497                                 } else {
498                                         SLOG(LOG_DEBUG, TAG_VCD, "[File message] Remove file : %s", remove_path);
499                                 }
500                         }
501                 }
502         } while (NULL != dirp);
503
504         closedir(dp);
505
506         return;
507 }
508
509 int vcd_initialize()
510 {
511         int ret = 0;
512
513         /* Remove old file */
514         __vcd_file_clean_up();
515
516         /* initialize modules */
517         ret = vcd_config_initialize(__config_lang_changed_cb, __config_foreground_changed_cb, NULL);
518         if (0 != ret) {
519                 SLOG(LOG_ERROR, TAG_VCD, "[Server WARNING] Fail to initialize config.");
520         }
521
522         vcd_config_set_service_state(VCD_STATE_NONE);
523
524         ret = vcd_engine_agent_init(__vcd_server_result_cb);
525         if (0 != ret) {
526                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
527                 return ret;
528         }
529
530         if (0 != vcd_recorder_create(__server_recorder_callback, __server_recorder_interrupt_callback)) {
531                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to create recorder");
532                 return VCD_ERROR_OPERATION_FAILED;
533         }
534
535         /* Find engine */
536         ret = vcd_engine_agent_initialize_current_engine();
537         if (0 != ret) {
538                 if (VCD_ERROR_ENGINE_NOT_FOUND == ret)
539                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] There is No Voice control engine");
540                 else
541                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to init engine");
542
543                 g_is_engine = false;
544         } else {
545                 g_is_engine = true;
546         }
547
548         /* Load engine */
549         if (0 != vcd_engine_agent_load_current_engine()) {
550                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to load current engine");
551                 return VCD_ERROR_OPERATION_FAILED;
552         }
553
554         /* Initialize manager info */
555         vcd_client_manager_unset();
556
557         vcd_config_set_service_state(VCD_STATE_READY);
558         vcdc_send_service_state(VCD_STATE_READY);
559
560         SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] initialize");
561
562         return 0;
563 }
564
565 void vcd_finalize()
566 {
567         GList *iter = NULL;
568         if (0 < g_list_length(g_proc_list)) {
569                 iter = g_list_first(g_proc_list);
570                 while (NULL != iter) {
571                         g_proc_list = g_list_remove_link(g_proc_list, iter);
572                         iter = g_list_first(g_proc_list);
573                 }
574         }
575
576         vcd_state_e state = vcd_config_get_service_state();
577         if (VCD_STATE_READY != state) {
578                 if (VCD_STATE_RECORDING == state) {
579                         vcd_recorder_stop();
580                 }
581                 vcd_engine_recognize_cancel();
582         }
583         if (0 != vcd_recorder_destroy()) {
584                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to destroy recorder");
585         } else {
586                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] destroy recorder");
587         }
588
589         if (0 != vcd_engine_agent_release()) {
590                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to release engine");
591         } else {
592                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] release engine");
593         }
594
595         vcd_config_set_service_state(VCD_STATE_NONE);
596         vcdc_send_service_state(VCD_STATE_NONE);
597
598         SLOG(LOG_DEBUG, TAG_VCD, "[Server] mode finalize");
599
600         return;
601 }
602
603 static Eina_Bool __finalize_quit_ecore_loop(void *data)
604 {
605         SLOG(LOG_DEBUG, TAG_VCD, "[Server] quit ecore main loop");
606         ecore_main_loop_quit();
607         return EINA_FALSE;
608 }
609
610 static void __read_proc()
611 {
612         DIR *dp = NULL;
613         struct dirent entry;
614         struct dirent *dirp = NULL;
615         int ret = -1;
616         int tmp;
617
618         GList *iter = NULL;
619         if (0 < g_list_length(g_proc_list)) {
620                 iter = g_list_first(g_proc_list);
621                 while (NULL != iter) {
622                         g_proc_list = g_list_remove_link(g_proc_list, iter);
623                         iter = g_list_first(g_proc_list);
624                 }
625         }
626
627         dp = opendir("/proc");
628         if (NULL == dp) {
629                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to open proc");
630         } else {
631                 do {
632                         ret = readdir_r(dp, &entry, &dirp);
633                         if (0 != ret) {
634                                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to readdir");
635                                 break;
636                         }
637
638                         if (NULL != dirp) {
639                                 tmp = atoi(dirp->d_name);
640                                 if (0 >= tmp)   continue;
641                                 g_proc_list = g_list_append(g_proc_list, GINT_TO_POINTER(tmp));
642                         }
643                 } while (NULL != dirp);
644                 closedir(dp);
645         }
646         return;
647 }
648
649 static void __vcd_cleanup_client(vcd_client_type_e type)
650 {
651         int* client_list = NULL;
652         int client_count = 0;
653         int i = 0;
654         int j = 0;
655         bool exist = false;
656         int mgr_pid = -1;
657         int ret = -1;
658
659         if (VCD_CLIENT_TYPE_NORMAL == type) {
660                 ret = vcd_client_get_list(&client_list, &client_count);
661         } else if (VCD_CLIENT_TYPE_WIDGET == type) {
662                 ret = vcd_client_widget_get_list(&client_list, &client_count);
663         } else if (VCD_CLIENT_TYPE_MANAGER == type) {
664                 mgr_pid = vcd_client_manager_get_pid();
665                 client_list = &mgr_pid;
666                 client_count = 1;
667         }
668
669         if (0 == ret || mgr_pid > 0) {
670                 SLOG(LOG_DEBUG, TAG_VCD, "===== Clean up %s client ", type ? (type == 1) ? "Widget" : "Manager" : "Normal");
671                 if (NULL != client_list && client_count > 0) {
672                         for (i = 0; i < client_count; i++) {
673                                 exist = false;
674                                 GList *iter = NULL;
675                                 for (j = 0; j < g_list_length(g_proc_list); j++) {
676                                         iter = g_list_nth(g_proc_list, j);
677                                         if (NULL != iter) {
678                                                 if (client_list[i] == GPOINTER_TO_INT(iter->data)) {
679                                                         SLOG(LOG_DEBUG, TAG_VCD, "%s pid(%d) is running", type ? (type == 1) ? "Widget" : "Manager" : "Normal", client_list[i]);
680                                                         exist = true;
681                                                         break;
682                                                 }
683                                         }
684                                 }
685
686                                 if (false == exist) {
687                                         SLOG(LOG_ERROR, TAG_VCD, "%s pid(%d) should be removed", type ? (type == 1) ? "Widget" : "Manager" : "Normal", client_list[i]);
688                                         if (VCD_CLIENT_TYPE_NORMAL == type)
689                                                 vcd_server_finalize(client_list[i]);
690                                         else if (VCD_CLIENT_TYPE_WIDGET == type)
691                                                 vcd_server_widget_finalize(client_list[i]);
692                                         else
693                                                 vcd_server_mgr_finalize(mgr_pid);
694                                 }
695                         }
696                 }
697                 SLOG(LOG_DEBUG, TAG_VCD, "=====");
698                 SLOG(LOG_DEBUG, TAG_VCD, "  ");
699         }
700         if (NULL != client_list && -1 == mgr_pid) {
701                 free(client_list);
702                 client_list = NULL;
703         }
704         return;
705 }
706
707 Eina_Bool vcd_cleanup_client_all(void *data)
708 {
709         __read_proc();
710         
711         __vcd_cleanup_client(VCD_CLIENT_TYPE_NORMAL);
712         __vcd_cleanup_client(VCD_CLIENT_TYPE_WIDGET);
713         __vcd_cleanup_client(VCD_CLIENT_TYPE_MANAGER);
714
715 #if 0
716         if (0 == vcd_client_get_list(&client_list, &client_count)) {
717                 SLOG(LOG_DEBUG, TAG_VCD, "===== Clean up client ");
718                 if (NULL != client_list && client_count > 0) {
719                         for (i = 0; i < client_count; i++) {
720                                 exist = false;
721                                 GList *iter = NULL;
722                                 for (j = 0; j < g_list_length(g_proc_list); j++) {
723                                         iter = g_list_nth(g_proc_list, j);
724                                         if (NULL != iter) {
725                                                 if (client_list[i] == GPOINTER_TO_INT(iter->data)) {
726                                                         SLOG(LOG_DEBUG, TAG_VCD, "pid(%d) is running", client_list[i]);
727                                                         exist = true;
728                                                         break;
729                                                 }
730                                         }
731                                 }
732
733                                 if (false == exist) {
734                                         SLOG(LOG_ERROR, TAG_VCD, "pid(%d) should be removed", client_list[i]);
735                                         vcd_server_finalize(client_list[i]);
736                                 }
737 #if 0
738                                 result = vcdc_send_hello(client_list[i], VCD_CLIENT_TYPE_NORMAL);
739
740                                 if (0 == result) {
741                                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] pid(%d) should be removed.", client_list[i]);
742                                         vcd_server_finalize(client_list[i]);
743                                 } else if (-1 == result) {
744                                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Hello result has error");
745                                 }
746 #endif
747                         }
748                 }
749                 SLOG(LOG_DEBUG, TAG_VCD, "=====");
750                 SLOG(LOG_DEBUG, TAG_VCD, "  ");
751         }
752         if (NULL != client_list) {
753                 free(client_list);
754                 client_list = NULL;
755         }
756
757         /* If app is in background state, app cannot response message. */
758         if (0 == vcd_client_widget_get_list(&client_list, &client_count)) {
759                 SLOG(LOG_DEBUG, TAG_VCD, "===== Clean up widget");
760                 if (NULL != client_list && client_count > 0) {
761                         for (i = 0; i < client_count; i++) {
762                                 exist = false;
763                                 GList *iter = NULL;
764                                 for (j = 0; j < g_list_length(g_proc_list); j++) {
765                                         iter = g_list_nth(g_proc_list, j);
766                                         if (NULL != iter) {
767                                                 if (client_list[i] == GPOINTER_TO_INT(iter->data)) {
768                                                         SLOG(LOG_DEBUG, TAG_VCD, "widget pid(%d) is running", client_list[i]);
769                                                         exist = true;
770                                                         break;
771                                                 }
772                                         }
773                                 }
774
775                                 if (false == exist) {
776                                         SLOG(LOG_ERROR, TAG_VCD, "widget pid(%d) should be removed", client_list[i]);
777                                         vcd_server_widget_finalize(client_list[i]);
778                                 }
779 #if 0
780                                 result = vcdc_send_hello(client_list[i], VCD_CLIENT_TYPE_WIDGET);
781
782                                 if (0 == result) {
783                                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget pid(%d) should be removed.", client_list[i]);
784                                         vcd_server_widget_finalize(client_list[i]);
785                                 } else if (-1 == result) {
786                                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Hello result has error");
787                                 }
788 #endif
789                         }
790                 }
791                 SLOG(LOG_DEBUG, TAG_VCD, "=====");
792                 SLOG(LOG_DEBUG, TAG_VCD, "  ");
793         }
794
795         if (NULL != client_list) {
796                 free(client_list);
797                 client_list = NULL;
798         }
799
800         /* manager */
801         exist = false;
802         GList *iter = NULL;
803         int mgr_pid = vcd_client_manager_get_pid();
804         if (0 < mgr_pid) {
805                 for (j = 0; j < g_list_length(g_proc_list); j++) {
806                         iter = g_list_nth(g_proc_list, j);
807                         if (NULL != iter) {
808                                 if (mgr_pid == GPOINTER_TO_INT(iter->data)) {
809                                         SLOG(LOG_DEBUG, TAG_VCD, "manager pid(%d) is running", mgr_pid);
810                                         exist = true;
811                                         break;
812                                 }
813                         }
814                 }
815
816                 if (false == exist) {
817                         SLOG(LOG_ERROR, TAG_VCD, "manager pid (%d) should be removed", mgr_pid);
818                         vcd_server_mgr_finalize(mgr_pid);
819                 }
820         }
821 #endif
822         return EINA_TRUE;
823 }
824
825 int vcd_server_get_service_state()
826 {
827         return vcd_config_get_service_state();
828 }
829
830 int vcd_server_get_foreground()
831 {
832         int pid;
833         vcd_config_get_foreground(&pid);
834         return pid;
835 }
836
837
838 /*
839 * API for manager
840 */
841 int vcd_server_mgr_initialize(int pid)
842 {
843         if (false == g_is_engine) {
844                 if (0 != vcd_engine_agent_initialize_current_engine()) {
845                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
846                         g_is_engine = false;
847                         return VCD_ERROR_ENGINE_NOT_FOUND;
848                 } else {
849                         g_is_engine = true;
850                 }
851         }
852
853         /* check if pid is valid */
854         if (false == vcd_client_manager_is_valid(pid)) {
855                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The pid(%d) is already exist", pid);
856                 return VCD_ERROR_INVALID_PARAMETER;
857         }
858
859         /* Add client information to client manager */
860         if (0 != vcd_client_manager_set(pid)) {
861                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add manager");
862                 return VCD_ERROR_OPERATION_FAILED;
863         }
864
865         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Manager initialize : pid(%d)", pid);
866
867         return VCD_ERROR_NONE;
868 }
869
870 int vcd_server_mgr_finalize(int pid)
871 {
872         /* check if pid is valid */
873         if (false == vcd_client_manager_is_valid(pid)) {
874                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
875                 return VCD_ERROR_INVALID_PARAMETER;
876         }
877
878         /* Cancel recognition */
879         vcd_server_mgr_cancel();
880
881         /* Remove manager information */
882         if (0 != vcd_client_manager_unset()) {
883                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
884         }
885
886         if (0 == vcd_client_get_ref_count()) {
887                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Connected client list is empty");
888                 ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
889         }
890
891         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Manager Finalize : pid(%d)", pid);
892
893         return VCD_ERROR_NONE;
894 }
895
896 int vcd_server_mgr_set_command(int pid)
897 {
898         if (0 != vcd_client_manager_set_command(pid)) {
899                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
900                 return VCD_ERROR_INVALID_PARAMETER;
901         }
902         return VCD_ERROR_NONE;
903 }
904
905 int vcd_server_mgr_unset_command(int pid)
906 {
907         if (0 != vcd_client_manager_unset_command(pid)) {
908                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
909                 return VCD_ERROR_INVALID_PARAMETER;
910         }
911         return VCD_ERROR_NONE;
912 }
913
914 int vcd_server_mgr_set_demandable_client(int pid)
915 {
916         /* check if pid is valid */
917         if (false == vcd_client_manager_is_valid(pid)) {
918                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
919                 return VCD_ERROR_INVALID_PARAMETER;
920         }
921
922         GSList* client_list = NULL;
923         if (0 != vc_info_parser_get_demandable_clients(&client_list)) {
924                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get demandable client");
925                 return VCD_ERROR_OPERATION_FAILED;
926         }
927
928         /* Save client list */
929         if (0 != vcd_client_manager_set_demandable_client(pid, client_list)) {
930                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set demandable client list");
931                 return VCD_ERROR_OPERATION_FAILED;
932         }
933
934         return VCD_ERROR_NONE;
935 }
936
937 int vcd_server_mgr_set_audio_type(int pid, const char* audio_type)
938 {
939         /* check if pid is valid */
940         if (false == vcd_client_manager_is_valid(pid)) {
941                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
942                 return VCD_ERROR_INVALID_PARAMETER;
943         }
944
945         int ret = 0;
946         vcp_audio_type_e type = VCP_AUDIO_TYPE_PCM_S16_LE;
947         int rate = 16000;
948         int channel = 1;
949
950         ret = vcd_engine_get_audio_format(audio_type, &type, &rate, &channel);
951         if (0 != ret) {
952                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio format : %d", ret);
953                 return VCD_ERROR_OPERATION_FAILED;
954         }
955
956         ret = vcd_recorder_set(audio_type, type, rate, channel);
957         if (0 != ret) {
958                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set audio in type : %d", ret);
959                 return VCD_ERROR_OPERATION_FAILED;
960         }
961
962         return VCD_ERROR_NONE;
963 }
964
965 int vcd_server_mgr_get_audio_type(int pid, char** audio_type)
966 {
967         /* check if pid is valid */
968         if (false == vcd_client_manager_is_valid(pid)) {
969                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
970                 return VCD_ERROR_INVALID_PARAMETER;
971         }
972
973         int ret = vcd_recorder_get(audio_type);
974         if (0 != ret) {
975                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio in type : %d", ret);
976                 return VCD_ERROR_OPERATION_FAILED;
977         }
978
979         return VCD_ERROR_NONE;
980 }
981
982 int vcd_server_mgr_set_client_info(int pid)
983 {
984         /* check if pid is valid */
985         if (false == vcd_client_manager_is_valid(pid)) {
986                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
987                 return VCD_ERROR_INVALID_PARAMETER;
988         }
989
990         int ret = vcd_client_save_client_info();
991         if (0 != ret) {
992                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to save client info : %d", ret);
993                 return VCD_ERROR_OPERATION_FAILED;
994         }
995
996         return VCD_ERROR_NONE;
997 }
998
999 static int __start_internal_recognition()
1000 {
1001         int ret;
1002
1003         /* 2. Get commands */
1004         ret = vcd_client_command_collect_command();
1005         if (0 != ret) {
1006                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to collect command : %d", ret);
1007                 return VCD_ERROR_OPERATION_FAILED;
1008         }
1009
1010         ret = vcd_client_get_length();
1011         if (0 == ret) {
1012                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNIING] No current command : %d", ret);
1013                 return VCD_ERROR_OPERATION_FAILED;
1014         }
1015
1016         /* 3. Set command to engine */
1017         ret = vcd_engine_set_commands();
1018         if (0 != ret) {
1019                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to collect command : %d", ret);
1020                 return VCD_ERROR_OPERATION_FAILED;
1021         }
1022
1023         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Set command");
1024
1025         bool stop_by_silence = true;
1026         if (VCD_RECOGNITION_MODE_MANUAL == vcd_client_get_recognition_mode()) {
1027                 stop_by_silence = false;
1028         }
1029
1030         /* 4. start recognition */
1031         ret = vcd_engine_recognize_start(stop_by_silence);
1032         if (0 != ret) {
1033                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1034                 return VCD_ERROR_OPERATION_FAILED;
1035         }
1036
1037         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Start engine");
1038
1039         /* 5. recorder start */
1040         ret = vcd_recorder_start();
1041         if (0 != ret) {
1042                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1043                 vcd_engine_recognize_cancel();
1044                 return ret;
1045         }
1046
1047         vcd_config_set_service_state(VCD_STATE_RECORDING);
1048         vcdc_send_service_state(VCD_STATE_RECORDING);
1049
1050         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Start recognition(%d)", stop_by_silence);
1051
1052         return 0;
1053 }
1054
1055 static Eina_Bool __vcd_request_show_tooltip(void *data)
1056 {
1057         int pid = vcd_client_widget_get_foreground_pid();
1058         if (-1 != pid) {
1059                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip show and widget command");
1060                 vcdc_send_show_tooltip(pid, (bool)data);
1061         }
1062
1063         return EINA_FALSE;
1064 }
1065
1066 int vcd_server_mgr_start(vcd_recognition_mode_e recognition_mode, bool exclusive_cmd, bool start_by_client)
1067 {
1068         /* 1. check current state */
1069         vcd_state_e state = vcd_config_get_service_state();
1070
1071         if (VCD_STATE_READY != state) {
1072                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
1073                 return VCD_ERROR_INVALID_STATE;
1074         }
1075
1076         SLOG(LOG_DEBUG, TAG_VCD, "[Server] set recognition mode = %d", recognition_mode);
1077         vcd_client_set_recognition_mode(recognition_mode);
1078
1079         if (false == exclusive_cmd) {
1080                 /* Notify show tooltip */
1081                 int pid = vcd_client_widget_get_foreground_pid();
1082                 if (-1 != pid) {
1083                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip show and widget command");
1084                         ecore_timer_add(0, __vcd_request_show_tooltip, (void*)true);
1085                         return 0;
1086                 }
1087         } else {
1088                 vcd_client_manager_set_exclusive(exclusive_cmd);
1089         }
1090
1091         int fg_pid = -1;
1092         if (true == start_by_client) {
1093                 /* Get foreground pid */
1094                 if (0 != vcd_config_get_foreground(&fg_pid)) {
1095                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get foreground");
1096                 }
1097
1098                 /* Set client exclusive option */
1099                 if (0 != vcd_client_set_exclusive_command(fg_pid)) {
1100                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set exclusive command");
1101                 }
1102         }
1103
1104         int ret = __start_internal_recognition();
1105         if (0 != ret) {
1106                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recongition : %d", ret);
1107                 return ret;
1108         }
1109
1110         if (true == start_by_client) {
1111                 vcd_client_unset_exclusive_command(fg_pid);
1112         }
1113
1114         return VCD_ERROR_NONE;
1115 }
1116
1117 int vcd_server_mgr_stop()
1118 {
1119         /* 1. Check current state is recording */
1120         if (VCD_STATE_RECORDING != vcd_config_get_service_state()) {
1121                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not recording");
1122                 return VCD_ERROR_INVALID_STATE;
1123         }
1124
1125         /* 2. Stop recorder */
1126         vcd_recorder_stop();
1127
1128         /* 3. Stop engine recognition */
1129         int ret = vcd_engine_recognize_stop();
1130         if (0 != ret) {
1131                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
1132         }
1133
1134         /* 4. Set original mode */
1135         vcd_config_set_service_state(VCD_STATE_PROCESSING);
1136         vcdc_send_service_state(VCD_STATE_PROCESSING);
1137
1138         return VCD_ERROR_NONE;
1139 }
1140
1141 int vcd_server_mgr_cancel()
1142 {
1143         /* 1. Check current state */
1144         vcd_state_e state = vcd_config_get_service_state();
1145         if (VCD_STATE_RECORDING != state && VCD_STATE_PROCESSING != state) {
1146                 SLOG(LOG_WARN, TAG_VCD, "[Server ERROR] Current state is not recording or processing");
1147                 return VCD_ERROR_INVALID_STATE;
1148         }
1149
1150         /* 2. Stop recorder */
1151         vcd_recorder_stop();
1152         /* 3. Cancel engine */
1153         int ret = vcd_engine_recognize_cancel();
1154         if (0 != ret) {
1155                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to cancel : %d", ret);
1156         }
1157
1158         if (false == vcd_client_manager_get_exclusive()) {
1159                 int pid = vcd_client_widget_get_foreground_pid();
1160                 if (-1 != pid) {
1161                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
1162                         ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
1163                 }
1164         } else {
1165                 vcd_client_manager_set_exclusive(false);
1166         }
1167
1168         /* 4. Set state */
1169         vcd_config_set_service_state(VCD_STATE_READY);
1170         vcdc_send_service_state(VCD_STATE_READY);
1171
1172         return VCD_ERROR_NONE;
1173 }
1174
1175
1176 int vcd_server_mgr_result_select()
1177 {
1178         __vcd_send_selected_result(NULL);
1179
1180         return VCD_ERROR_NONE;
1181 }
1182
1183 /*
1184 * VC Server Functions for Client
1185 */
1186 int vcd_server_initialize(int pid)
1187 {
1188         if (false == g_is_engine) {
1189                 if (0 != vcd_engine_agent_initialize_current_engine()) {
1190                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
1191                         g_is_engine = false;
1192                         return VCD_ERROR_ENGINE_NOT_FOUND;
1193                 } else {
1194                         g_is_engine = true;
1195                 }
1196         }
1197
1198         if (false == vcd_engine_is_available_engine()) {
1199                 if (0 != vcd_engine_agent_initialize_current_engine()) {
1200                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
1201                         return VCD_ERROR_ENGINE_NOT_FOUND;
1202                 }
1203         }
1204
1205         /* check if pid is valid */
1206         if (true == vcd_client_is_available(pid)) {
1207                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The pid is already exist");
1208                 return VCD_ERROR_INVALID_PARAMETER;
1209         }
1210
1211         /* Add client information to client manager */
1212         if (0 != vcd_client_add(pid)) {
1213                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add client info");
1214                 return VCD_ERROR_OPERATION_FAILED;
1215         }
1216
1217         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Client Initialize : pid(%d)", pid);
1218
1219         return VCD_ERROR_NONE;
1220 }
1221
1222 int vcd_server_finalize(int pid)
1223 {
1224         /* check if pid is valid */
1225         if (false == vcd_client_is_available(pid)) {
1226                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
1227                 return VCD_ERROR_INVALID_PARAMETER;
1228         }
1229
1230         /* Remove client information */
1231         if (0 != vcd_client_delete(pid)) {
1232                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
1233         }
1234
1235         if (0 == vcd_client_get_ref_count()) {
1236                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Connected client list is empty");
1237                 ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
1238         }
1239
1240         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Client Finalize : pid(%d)", pid);
1241
1242         return VCD_ERROR_NONE;
1243 }
1244
1245 int vcd_server_set_command(int pid, vc_cmd_type_e cmd_type)
1246 {
1247         /* check if pid is valid */
1248         if (false == vcd_client_is_available(pid)) {
1249                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
1250                 return VCD_ERROR_INVALID_PARAMETER;
1251         }
1252
1253         if (0 != vcd_client_set_command_type(pid, cmd_type)) {
1254                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set command type : pid(%d), cmd_type(%d)", pid, cmd_type);
1255                 return VCD_ERROR_OPERATION_FAILED;
1256         }
1257
1258         return 0;
1259 }
1260
1261 int vcd_server_unset_command(int pid, vc_cmd_type_e cmd_type)
1262 {
1263         /* check if pid is valid */
1264         if (false == vcd_client_is_available(pid)) {
1265                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
1266                 return VCD_ERROR_INVALID_PARAMETER;
1267         }
1268
1269         if (0 != vcd_client_unset_command_type(pid, cmd_type)) {
1270                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to unset command type : pid(%d), cmd_type(%d)", pid, cmd_type);
1271                 return VCD_ERROR_OPERATION_FAILED;
1272         }
1273
1274         return 0;
1275 }
1276
1277 int vcd_server_set_foreground(int pid, bool value)
1278 {
1279         /* check if pid is valid */
1280         if (false == vcd_client_is_available(pid) && false == vcd_client_widget_is_available(pid)) {
1281                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
1282                 return VCD_ERROR_INVALID_PARAMETER;
1283         }
1284
1285         if (0 != vcd_config_set_foreground(pid, value)) {
1286                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set foreground : pid(%d), value(%d)", pid, value);
1287                 return VCD_ERROR_OPERATION_FAILED;
1288         }
1289
1290         return 0;
1291 }
1292
1293 #if 0
1294 int vcd_server_set_exclusive_command(int pid, bool value)
1295 {
1296         /* check if pid is valid */
1297         if (false == vcd_client_is_available(pid)) {
1298                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
1299                 return VCD_ERROR_INVALID_PARAMETER;
1300         }
1301
1302         if (true == value) {
1303                 if (0 != vcd_client_set_exclusive_command(pid)) {
1304                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set exclusive command : pid(%d)", pid);
1305                         return VCD_ERROR_OPERATION_FAILED;
1306                 }
1307         } else {
1308                 if (0 != vcd_client_unset_exclusive_command(pid)) {
1309                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to unset exclusive command : pid(%d)", pid);
1310                         return VCD_ERROR_OPERATION_FAILED;
1311                 }
1312         }
1313
1314         return 0;
1315 }
1316
1317 int vcd_server_request_start(int pid, bool stop_by_silence)
1318 {
1319         /* check if pid is valid */
1320         if (false == vcd_client_is_available(pid)) {
1321                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid(%d) is NOT forground client", pid);
1322                 return VCD_ERROR_INVALID_PARAMETER;
1323         }
1324
1325         int ret;
1326         /* Check current state */
1327         vcd_state_e state = vcd_config_get_service_state();
1328
1329         /* Service state should be ready */
1330         if (VCD_STATE_READY != state) {
1331                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Ready : pid(%d)", pid);
1332                 return VCD_ERROR_INVALID_STATE;
1333         }
1334
1335         if (-1 != vcd_client_manager_get_pid()) {
1336                 /* Check current pid is valid */
1337                 if (false == vcd_client_manager_check_demandable_client(pid)) {
1338                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
1339                         return VCD_ERROR_INVALID_PARAMETER;
1340                 }
1341         }
1342
1343         ret = vcd_server_mgr_start(stop_by_silence, false);
1344         if (0 != ret) {
1345                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
1346                 return VCD_ERROR_INVALID_PARAMETER;
1347         }
1348
1349         return 0;
1350 }
1351
1352 int vcd_server_request_stop(int pid)
1353 {
1354         int ret;
1355         /* Check current state */
1356         vcd_state_e state = vcd_config_get_service_state();
1357
1358         /* Service state should be ready */
1359         if (VCD_STATE_RECORDING != state) {
1360                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording : pid(%d)", pid);
1361                 return VCD_ERROR_INVALID_STATE;
1362         }
1363
1364         if (-1 != vcd_client_manager_get_pid()) {
1365                 /* Check current pid is valid */
1366                 if (false == vcd_client_manager_check_demandable_client(pid)) {
1367                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
1368                         return VCD_ERROR_INVALID_PARAMETER;
1369                 }
1370         }
1371
1372         ret = vcd_server_mgr_stop();
1373         if (0 != ret) {
1374                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
1375                 return VCD_ERROR_OPERATION_FAILED;
1376         }
1377
1378         return VCD_ERROR_NONE;
1379 }
1380
1381 int vcd_server_request_cancel(int pid)
1382 {
1383         int ret;
1384         /* Check current state */
1385         vcd_state_e state = vcd_config_get_service_state();
1386
1387         /* Service state should be recording or processing */
1388         if (VCD_STATE_RECORDING != state && VCD_STATE_PROCESSING != state) {
1389                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording or Processing : pid(%d)", pid);
1390                 return VCD_ERROR_INVALID_STATE;
1391         }
1392
1393         if (-1 != vcd_client_manager_get_pid()) {
1394                 /* Check current pid is valid */
1395                 if (false == vcd_client_manager_check_demandable_client(pid)) {
1396                         SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
1397                         return VCD_ERROR_INVALID_PARAMETER;
1398                 }
1399         }
1400
1401         ret = vcd_server_mgr_cancel();
1402         if (0 != ret) {
1403                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
1404                 return VCD_ERROR_OPERATION_FAILED;
1405         }
1406
1407         return VCD_ERROR_NONE;
1408 }
1409 #endif
1410
1411 /*
1412 * VC Server Functions for Widget lib
1413 */
1414 int vcd_server_widget_initialize(int pid)
1415 {
1416         if (false == g_is_engine) {
1417                 if (0 != vcd_engine_agent_initialize_current_engine()) {
1418                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
1419                         g_is_engine = false;
1420                         return VCD_ERROR_ENGINE_NOT_FOUND;
1421                 } else {
1422                         g_is_engine = true;
1423                 }
1424         }
1425
1426         if (false == vcd_engine_is_available_engine()) {
1427                 if (0 != vcd_engine_agent_initialize_current_engine()) {
1428                         SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
1429                         return VCD_ERROR_ENGINE_NOT_FOUND;
1430                 }
1431         }
1432
1433         /* check if pid is valid */
1434         if (true == vcd_client_widget_is_available(pid)) {
1435                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The pid is already exist");
1436                 return VCD_ERROR_INVALID_PARAMETER;
1437         }
1438
1439         /* Add client information to client manager */
1440         if (0 != vcd_client_widget_add(pid)) {
1441                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add client info");
1442                 return VCD_ERROR_OPERATION_FAILED;
1443         }
1444
1445         SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Initialize widget : pid(%d)", pid);
1446
1447         return VCD_ERROR_NONE;
1448 }
1449
1450 int vcd_server_widget_finalize(int pid)
1451 {
1452         /* check if pid is valid */
1453         if (false == vcd_client_widget_is_available(pid)) {
1454                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
1455                 return VCD_ERROR_INVALID_PARAMETER;
1456         }
1457
1458         /* Remove client information */
1459         if (0 != vcd_client_widget_delete(pid)) {
1460                 SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
1461         }
1462
1463         if (0 == vcd_client_get_ref_count()) {
1464                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] connected client list is empty");
1465                 ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
1466         }
1467
1468         return VCD_ERROR_NONE;
1469 }
1470
1471 int vcd_server_widget_start_recording(int pid, bool widget_command)
1472 {
1473         /* check if pid is valid */
1474         if (false == vcd_client_widget_is_available(pid)) {
1475                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
1476                 return VCD_ERROR_INVALID_PARAMETER;
1477         }
1478
1479         if (true == widget_command) {
1480                 vcd_client_widget_set_command(pid);
1481                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget command is available");
1482         } else {
1483                 vcd_client_widget_unset_command(pid);
1484                 SLOG(LOG_WARN, TAG_VCD, "[Server] widget command is NOT available");
1485         }
1486
1487         int ret = __start_internal_recognition();
1488         if (0 != ret) {
1489                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recongition : %d", ret);
1490                 ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
1491         }
1492
1493         return 0;
1494 }
1495
1496 int vcd_server_widget_start(int pid, bool stop_by_silence)
1497 {
1498         /* check if pid is valid */
1499         int fore_pid = vcd_client_widget_get_foreground_pid();
1500         if (pid != fore_pid) {
1501                 SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
1502                 return VCD_ERROR_INVALID_PARAMETER;
1503         }
1504
1505         /* Check current state */
1506         vcd_state_e state = vcd_config_get_service_state();
1507
1508         /* Service state should be ready */
1509         if (VCD_STATE_READY != state) {
1510                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Ready : pid(%d)", pid);
1511                 return VCD_ERROR_INVALID_STATE;
1512         }
1513
1514         vcd_client_set_slience_detection(stop_by_silence);
1515
1516         /* Notify show tooltip */
1517         ecore_timer_add(0, __vcd_request_show_tooltip, (void*)true);
1518
1519         return 0;
1520 }
1521
1522 int vcd_server_widget_stop(int pid)
1523 {
1524         /* check if pid is valid */
1525         int fore_pid = vcd_client_widget_get_foreground_pid();
1526         if (pid != fore_pid) {
1527                 SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
1528                 return VCD_ERROR_INVALID_PARAMETER;
1529         }
1530
1531         int ret;
1532         /* Check current state */
1533         vcd_state_e state = vcd_config_get_service_state();
1534
1535         /* Service state should be recording */
1536         if (VCD_STATE_RECORDING != state) {
1537                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current service state is not Recording : pid(%d)", pid);
1538                 return VCD_ERROR_INVALID_STATE;
1539         }
1540
1541         ret = vcd_server_mgr_stop();
1542         if (0 != ret) {
1543                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
1544                 return VCD_ERROR_OPERATION_FAILED;
1545         }
1546
1547         return VCD_ERROR_NONE;
1548 }
1549
1550 int vcd_server_widget_cancel(int pid)
1551 {
1552         /* check if pid is valid */
1553         int fore_pid = vcd_client_widget_get_foreground_pid();
1554         if (pid != fore_pid) {
1555                 SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
1556                 return VCD_ERROR_INVALID_PARAMETER;
1557         }
1558
1559         int ret;
1560         /* Check current state */
1561         vcd_state_e state = vcd_config_get_service_state();
1562
1563         /* Service state should be recording or processing */
1564         if (VCD_STATE_RECORDING != state && VCD_STATE_PROCESSING != state) {
1565                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording or Processing : pid(%d)", pid);
1566                 return VCD_ERROR_INVALID_STATE;
1567         }
1568
1569         ret = vcd_server_mgr_cancel();
1570         if (0 != ret) {
1571                 SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to cancel recognition : %d", ret);
1572                 return ret;
1573         }
1574
1575         return VCD_ERROR_NONE;
1576 }
1577