tizen 2.4 release
[framework/uifw/voice/voice-control-panel.git] / src / voice_control_panel_vc.c
1 /*
2 *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved 
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <stdbool.h>
17
18 #include <dlog.h>
19 #include <Elementary.h>
20
21 #include <voice_control_command.h>
22 #include <voice_control_common.h>
23 #include <voice_control_manager.h>
24
25 #include "voice_control_panel_action.h"
26 #include "voice_control_panel_command.h"
27 #include "voice_control_panel_main.h"
28 #include "voice_control_panel_vc.h"
29 #include "voice_control_panel_view.h"
30
31 static vc_cmd_list_h g_cmd_list_1st;
32 static vc_cmd_list_h g_cmd_list_2nd[NUM_COMMAND_1ST];
33
34 #define TIMEOUT 5
35 static Ecore_Timer *g_timeout_timer = NULL;
36 static Ecore_Timer *g_restart_timer = NULL;
37
38 static bool __current_command_cb(vc_cmd_h vc_command, void* user_data)
39 {
40         appdata *ad = (appdata *)user_data;
41
42         int type;
43         if (0 != vc_cmd_get_type(vc_command, &type)) {
44                 LOGE("[ERROR] Fail to get type");
45                 return false;
46         }
47
48         if (VC_COMMAND_TYPE_FOREGROUND == type || VC_COMMAND_TYPE_BACKGROUND == type) {
49                 char *cmd = NULL;
50                 if (0 != vc_cmd_get_command(vc_command, &cmd)) {
51                         LOGE("[ERROR] Fail to get command");
52                         return false;
53                 }
54
55                 if (NULL != cmd) {
56                         ad->cmd_list = g_list_append(ad->cmd_list, strdup(cmd));
57                         LOGD("Add command List (%s)", cmd);
58                         free(cmd);
59                         cmd = NULL;
60                 }
61         }
62
63         return true;
64 }
65
66 static int __vc_panel_vc_get_current_commands(void *data)
67 {
68         appdata *ad = (appdata *)data;
69
70         LOGD("==== Get current commands ====");
71         if (0 < g_list_length(ad->cmd_list)) {
72                 GList *iter = NULL;
73                 iter = g_list_first(ad->cmd_list);
74
75                 while (NULL != iter) {
76                         char *cmd = iter->data;
77                         if (NULL != cmd) {
78                                 free(cmd);
79                                 cmd = NULL;
80                         }
81
82                         ad->cmd_list = g_list_remove_link(ad->cmd_list, iter);
83                         iter = g_list_first(ad->cmd_list);
84                 }
85         }
86         
87         vc_cmd_list_h vc_cmd_list;
88         if (0 != vc_mgr_get_current_commands(&vc_cmd_list)) {
89                 LOGE("[ERROR] Fail to get current commands");
90                 if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) {
91                         LOGE("[WARNING] Fail to cmd list destroy");
92                 }
93                 return -1;
94         }
95
96         if (0 != vc_cmd_list_foreach_commands(vc_cmd_list, __current_command_cb, ad)) {
97                 LOGE("[ERROR] Fail to get current commands");
98                 if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) {
99                         LOGE("[WARNING] Fail to cmd list destroy");
100                 }
101                 return -1;
102         }
103
104         if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) {
105                 LOGE("[WARNING] Fail to cmd list destroy");
106         }
107
108         return 0;
109 }
110
111 static void __vc_panel_vc_destroy_command_list()
112 {
113         LOGD( "==== Destroy Command List ====");
114
115         if (0 != vc_cmd_list_destroy(g_cmd_list_1st, true)) {
116                 LOGE("[WARNING] Fail to destroy list");
117         }
118
119         int i;
120         for (i = 0; i < NUM_COMMAND_1ST; i++) {
121                 if (0 != vc_cmd_list_destroy(g_cmd_list_2nd[i], true)) {
122                         LOGE("[WARNING] Fail to destroy list");
123                 }
124         }
125         
126         LOGD( "====");
127         LOGD( " ");
128 }
129
130 static int __vc_panel_vc_create_command_list()
131 {
132         LOGD( "==== Create Command List ====");
133
134         /* 1st depth */
135         if (0 != vc_cmd_list_create(&g_cmd_list_1st)) {
136                 LOGE( "[ERROR] Fail to cmd list create");
137                 return -1;
138         }
139
140         int i;
141         for (i = 0; i < NUM_COMMAND_1ST; i++) {
142                 vc_cmd_h cmd;
143                 if (0 != vc_cmd_create(&cmd)) {
144                         LOGE( "[ERROR] Fail to cmd create");
145                         return -1;
146                 }
147                 if (0 != vc_cmd_set_command(cmd, _(g_command_1st[i]))) {
148                         LOGE( "[ERROR] Fail to set command");
149                         vc_cmd_destroy(cmd);
150                         return -1;
151                 }
152                 if (0 != vc_cmd_set_type(cmd, VC_COMMAND_TYPE_SYSTEM)) {
153                         LOGE( "[ERROR] Fail to set type");
154                         vc_cmd_destroy(cmd);
155                         return -1;
156                 }
157                 if (0 != vc_cmd_set_format(cmd, VC_CMD_FORMAT_FIXED)) {
158                         LOGE( "[ERROR] Fail to set format");
159                         vc_cmd_destroy(cmd);
160                         return -1;
161                 }
162                 if (0 != vc_cmd_list_add(g_cmd_list_1st, cmd)) {
163                         LOGE( "[ERROR] Fail to list add");
164                         vc_cmd_destroy(cmd);
165                         return -1;
166                 }
167         }
168
169         /* 2nd depth */
170         for (i = 0; i < NUM_COMMAND_1ST; i++) {
171                 if (0 != vc_cmd_list_create(&g_cmd_list_2nd[i])) {
172                         LOGE( "[ERROR] Fail to list create");
173                         return -1;
174                 }
175
176                 int j;
177                 for (j = 0; j < NUM_COMMAND_2ND; j++) {
178                         if (NULL != g_command_2nd[i][j]) {
179                                 vc_cmd_h cmd;
180                                 if (0 != vc_cmd_create(&cmd)) {
181                                         LOGE( "[ERROR] Fail to cmd create");
182                                         return -1;
183                                 }
184                                 if (0 != vc_cmd_set_command(cmd, _(g_command_2nd[i][j]))) {
185                                         LOGE( "[ERROR] Fail to set command");
186                                         vc_cmd_destroy(cmd);
187                                         return -1;
188                                 }
189                                 if (0 != vc_cmd_set_type(cmd, VC_COMMAND_TYPE_SYSTEM)) {
190                                         LOGE( "[ERROR] Fail to set type");
191                                         vc_cmd_destroy(cmd);
192                                         return -1;
193                                 }
194                                 if (0 != vc_cmd_set_format(cmd, VC_CMD_FORMAT_FIXED)) {
195                                         LOGE( "[ERROR] Fail to set format");
196                                         vc_cmd_destroy(cmd);
197                                         return -1;
198                                 }
199                                 if (0 != vc_cmd_list_add(g_cmd_list_2nd[i], cmd)) {
200                                         LOGE( "[ERROR] Fail to list add");
201                                         vc_cmd_destroy(cmd);
202                                         return -1;
203                                 }
204                         }
205                 }
206         }
207
208         return 0;
209 }
210
211 static Eina_Bool __start_cb(void *data)
212 {
213         appdata *ad = (appdata *)data;
214
215         vc_service_state_e state;
216         if (0 != vc_mgr_get_service_state(&state)) {
217             LOGE("[ERROR] Fail to get service state");
218             return EINA_FALSE;
219         }
220
221         if (VC_SERVICE_STATE_READY != state) {
222             LOGD("[WARNING] Wait for service state ready");
223             return EINA_TRUE;
224         }
225
226         if (0 != vc_mgr_set_recognition_mode(VC_RECOGNITION_MODE_RESTART_AFTER_REJECT)) {
227                 LOGE( "[ERROR] Fail to set recognition mode");
228         }
229         if (0 != vc_mgr_set_command_list(g_cmd_list_1st)) {
230                 LOGE( "[ERROR] Fail to set command list");
231         }
232
233         if (0 != __vc_panel_vc_get_current_commands(ad)) {
234                 LOGE("[ERROR] Fail to get current commands");
235         }
236
237         if (0 != vc_mgr_start(false)) {
238                 LOGE( "[ERROR] Fail to start");
239         }
240
241         return EINA_FALSE;
242 }
243
244 static void __vc_panel_vc_state_changed_cb(vc_state_e previous, vc_state_e current, void *user_data)
245 {
246         LOGD( "==== State is changed ====");
247         LOGD( "Previous(%d) -> Current(%d)", previous, current);
248 }
249
250 static void __vc_panel_vc_reset(void *data)
251 {
252         appdata *ad = (appdata *)data;
253
254         ad->current_depth = 1;
255         ad->current_path[0] = -1;
256         ad->current_path[1] = -1;
257
258         if (0 != vc_mgr_set_command_list(g_cmd_list_1st)) {
259                 LOGE( "[ERROR] Fail to set command list");
260         }
261 }
262
263 static Eina_Bool __vc_panel_finalize(void *data)
264 {
265         LOGD("=== Finalize ===");
266         if (g_timeout_timer != NULL) {
267                 ecore_timer_del(g_timeout_timer);
268                 g_timeout_timer = NULL;
269         }
270         ui_app_exit();
271         return EINA_FALSE;
272 }
273
274 static Eina_Bool __vc_panel_vc_restart(void *data)
275 {
276         LOGD( "==== Restart ====");
277
278         appdata *ad = (appdata *)data;
279
280         vc_service_state_e state;
281         if (0 != vc_mgr_get_service_state(&state)) {
282             LOGE("[ERROR] Fail to get service state");
283             return EINA_FALSE;
284         }
285
286         if (VC_SERVICE_STATE_READY != state) {
287             LOGD("[WARNING] Wait for service state ready");
288             return EINA_TRUE;
289         }
290
291         /* set current command list */
292         if (1 == ad->current_depth) {
293                 if (0 != vc_mgr_set_command_list(g_cmd_list_1st)) {
294                         LOGE( "[ERROR] Fail to set command list");
295                 }
296         } else if (2 == ad->current_depth) {
297                 if (0 != vc_mgr_set_command_list(g_cmd_list_2nd[ad->current_path[0]])) {
298                         LOGE( "[ERROR] Fail to set command list");
299                 }
300         }
301
302         vc_panel_view_show(ad);
303
304         if (0 != __vc_panel_vc_get_current_commands(ad)) {
305                 LOGE("[ERROR] Fail to get current commands");
306         }
307
308         if (0 != vc_mgr_start(false)) {
309                 LOGE( "[ERROR] Fail to start");
310         }
311
312         LOGD( "====");
313         LOGD( " ");
314
315         return EINA_FALSE;
316 }
317
318 static void __vc_panel_vc_service_state_changed_cb(vc_service_state_e previous, vc_service_state_e current, void *user_data)
319 {
320         LOGD( "==== Service state is changed ====");
321         LOGD( "Previous(%d) -> Current(%d)", previous, current);
322         
323         appdata *ad = (appdata *)user_data;
324
325         if (VC_SERVICE_STATE_READY == previous && VC_SERVICE_STATE_RECORDING == current) {
326                 LOGD( "==== Show by recording ====");
327                 vc_panel_view_show(ad);
328                 if (NULL != g_timeout_timer) {
329                         ecore_timer_reset(g_timeout_timer);
330                 }
331         } else if ((VC_SERVICE_STATE_RECORDING == previous || VC_SERVICE_STATE_PROCESSING == previous) && VC_SERVICE_STATE_READY == current) {
332                 if (APP_STATE_SERVICE == ad->app_state) {
333                         LOGD("==== Restart ====");
334                         if (NULL != g_restart_timer) {
335                                 ecore_timer_del(g_restart_timer);
336                         }
337                         g_restart_timer = ecore_timer_add(0.5, __vc_panel_vc_restart, user_data);
338                 } else {
339                         LOGD("==== Hide ====");
340                         __vc_panel_vc_reset(ad);
341                 }
342         }
343
344         if (VC_SERVICE_STATE_RECORDING == current) {
345                 if (NULL != g_timeout_timer) {
346                         ecore_timer_reset(g_timeout_timer);
347                 }
348         }
349 }
350
351 static Eina_Bool __hide_result(void *data)
352 {
353         LOGD("");
354         vc_panel_view_show(data);
355
356         return EINA_FALSE;
357 }
358
359 static bool __vc_panel_vc_all_result_cb(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char* result, const char* msg, void *user_data)
360 {
361         LOGD( "==== All result cb ====");
362
363         if (VC_RESULT_EVENT_REJECTED == event) {
364                 LOGD("Rejected event");
365                 vc_panel_view_show_result(user_data, _("IDS_SORRY"));
366                 ecore_timer_add(0.5, __hide_result, user_data);
367         } else {
368                 if (NULL != result) {
369                         LOGD( "Result Text - %s", result);
370                         vc_panel_view_show_result(user_data, result);
371                 
372                 if (strcmp(result, _("IDS_HELP"))) {
373                         vc_panel_view_hide_help(user_data);
374                 }
375         }
376         }
377
378         return true;
379 }
380
381 static void __vc_panel_vc_result_cb(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char* result, void *user_data)
382 {
383         LOGD( "==== Result cb ====");
384
385         if (NULL != result) {
386                 LOGD( "Result Text - %s", result);
387
388                 bool ret;
389                 ret = vc_panel_action(result, user_data);
390                 if (true != ret) {
391                         ecore_idler_add(__vc_panel_finalize, user_data);
392                 }
393         }
394 }
395
396 static void __vc_panel_vc_speech_detected_cb(void *user_data)
397 {
398         LOGD("==== Speech detected ====");
399         if (NULL != g_timeout_timer)
400                 ecore_timer_reset(g_timeout_timer);
401 }
402
403 static void __vc_panel_vc_language_changed_cb(const char* previous, const char* current, void* user_data)
404 {
405         LOGD("Language is changed (%s) to (%s)", previous, current);
406
407         char loc[64] = {'\0', };
408         snprintf(loc, 64, "%s.UTF-8", current);
409
410         setlocale(LC_ALL, loc);
411
412         __vc_panel_vc_destroy_command_list();
413         if (0 != __vc_panel_vc_create_command_list()) {
414                 LOGE("[ERROR] Fail to create command list");
415         }
416 }
417
418 int vc_panel_vc_start(void *data)
419 {
420         if (NULL != g_timeout_timer)
421                 ecore_timer_reset(g_timeout_timer);
422
423         ecore_timer_add(0, __start_cb, data);
424         return 0;
425 }
426
427 int vc_panel_vc_cancel(void *data)
428 {
429         vc_service_state_e service_state;
430
431         if (0 != vc_mgr_get_service_state(&service_state)) {
432                 LOGE( "[ERROR] Fail to get service state");
433                 return -1;
434         }
435
436         if ((VC_SERVICE_STATE_RECORDING == service_state) || (VC_SERVICE_STATE_PROCESSING == service_state)) {
437                 LOGD( "==== service state (%d)", service_state);
438
439                 if (0 != vc_mgr_cancel()) {
440                         LOGE( "[ERROR] Fail to cancel");
441                         return -1;
442                 }
443         }
444
445         return 0;
446 }
447
448 int vc_panel_vc_init(void *data)
449 {
450         LOGD( "==== Initialze Voice control ====");
451
452         if (0 != vc_mgr_initialize()) {
453                 LOGE( "[ERROR] Fail to initialize");
454                 return -1;
455         }
456
457         if (0 != vc_mgr_set_state_changed_cb(__vc_panel_vc_state_changed_cb, data)) {
458                 LOGE( "[ERROR] Fail to set state changed cb");
459                 return -1;
460         }
461
462         if (0 != vc_mgr_set_service_state_changed_cb(__vc_panel_vc_service_state_changed_cb, data)) {
463                 LOGE( "[ERROR] Fail to set service state changed cb");
464                 return -1;
465         }
466
467         if (0 != vc_mgr_set_all_result_cb(__vc_panel_vc_all_result_cb, data)) {
468                 LOGE( "[ERROR] Fail to set all result cb");
469                 return -1;
470         }
471
472         if (0 != vc_mgr_set_result_cb(__vc_panel_vc_result_cb, data)) {
473                 LOGE( "[ERROR] Fail to set result cb");
474                 return -1;
475         }
476
477         if (0 != vc_mgr_set_speech_detected_cb(__vc_panel_vc_speech_detected_cb, data)) {
478                 LOGE("[ERROR] Fail to set speech detected cb");
479                 return -1;
480         }
481
482         if (0 != vc_mgr_set_current_language_changed_cb(__vc_panel_vc_language_changed_cb, data)) {
483                 LOGE("[ERROR] Fail to set language changed cb");
484                 return -1;
485         }
486
487         if (0 != vc_mgr_prepare()) {
488                 LOGE( "[ERROR] Fail to prepare");
489                 return -1;
490         }
491
492         if (0 != __vc_panel_vc_create_command_list()) {
493                 LOGE( "[ERROR] Fail to create command list");
494                 return -1;
495         }
496
497         if (NULL == g_timeout_timer) {
498                 g_timeout_timer = ecore_timer_add(TIMEOUT, __vc_panel_finalize, NULL);
499         }
500
501         LOGD( "====");
502         LOGD( " ");
503
504         return 0;
505 }
506
507 int vc_panel_vc_deinit(void *data)
508 {
509         LOGD( "==== De-initialize Voice control ====");
510
511         appdata *ad = (appdata *)data;
512
513         if (g_restart_timer != NULL) {
514                 ecore_timer_del(g_restart_timer);
515                 g_restart_timer = NULL;
516         }
517
518         if (g_timeout_timer != NULL) {
519                 ecore_timer_del(g_timeout_timer);
520                 g_timeout_timer = NULL;
521         }
522
523         if (0 < g_list_length(ad->cmd_list)) {
524                 GList *iter = NULL;
525                 iter = g_list_first(ad->cmd_list);
526
527                 while (NULL != iter) {
528                         char *cmd = iter->data;
529                         if (NULL != cmd) {
530                                 free(cmd);
531                                 cmd = NULL;
532                         }
533
534                         ad->cmd_list = g_list_remove_link(ad->cmd_list, iter);
535                         iter = g_list_first(ad->cmd_list);
536                 }
537         }
538
539         __vc_panel_vc_destroy_command_list();
540
541         if (0 != vc_mgr_deinitialize()) {
542                 LOGE( "[ERROR] Fail to deinitialize");
543                 return -1;
544         }
545
546         LOGD( "====");
547         LOGD( " ");
548
549         return 0;
550 }
551
552 /*
553 vi:ts=4:ai:nowrap:expandtab
554 */