Fix defects from static analysis
[platform/core/uifw/voice-control-elm.git] / src / vc_elm_widget_wrapper.c
1 /*
2  * Copyright (c) 2011-2016 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
18 #include "vc_elm_main.h"
19 #include "vc_elm_widget_wrapper.h"
20 #include "vc_elm_tools.h"
21 #include "vc_elm_core.h"
22
23 #include <voice_control_widget.h>
24
25 struct __voice_control_wrapper_s {
26         bool initialized;
27         vc_cmd_list_h group;
28         char *lang;
29         int (*result_cb)(const char *cmd, const char *param1, const char *param2, void *data);
30         void (*tooltips_cb)(bool);
31         vc_current_language_changed_cb language_changed_cb;
32         void *lang_user_data;
33         void *data;
34 };
35
36 static struct __voice_control_wrapper_s vcw = {0, 0, 0, 0, 0, 0, 0, 0};
37 static Ecore_Timer *g_initialize_timer = NULL;
38 #define INITIALIZE_INTERVAL_TIME 300.0
39
40 static vc_h g_vc_w;
41
42 static void __vc_state_changed_cb(vc_state_e previous, vc_state_e current, void *user_data);
43 static void __vc_service_state_changed_cb(vc_service_state_e previous, vc_service_state_e current, void *user_data);
44 static void __vc_error_cb(vc_error_e reason, void *user_data);
45 static void __vc_result_cb(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char *result, void *user_data);
46 static void __vc_show_tooltip_callback(bool show, void *data);
47 static void __vc_language_changed_cb(const char *previous, const char *current, void *data);
48
49 #define MAX_RETRY_CNT 20
50 #define VC_CMD_ERROR_CHECK_CASE(VALUE)                          \
51         case VALUE:                                             \
52         VC_ELM_LOG_ERR("vc error in (%s) -> %s", msg, #VALUE);  \
53         break;
54
55 #define VC_ERROR_CHECK(args) do {                                                       \
56                 int err = args;                                                         \
57                 const char *msg = # args;                                               \
58                 switch (err) {                                                  \
59                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_OUT_OF_MEMORY);        \
60                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_IO_ERROR);             \
61                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_INVALID_PARAMETER);    \
62                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_TIMED_OUT);            \
63                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_RECORDER_BUSY);        \
64                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_PERMISSION_DENIED);    \
65                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_NOT_SUPPORTED);        \
66                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_INVALID_STATE);        \
67                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_INVALID_LANGUAGE);     \
68                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_ENGINE_NOT_FOUND);     \
69                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_OPERATION_FAILED);     \
70                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_OPERATION_REJECTED);   \
71                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_ITERATION_END);        \
72                         VC_CMD_ERROR_CHECK_CASE(VC_ERROR_EMPTY);                \
73                 case VC_ERROR_NONE:                                     \
74                         break;                                          \
75                 default:                                                \
76                         VC_ELM_LOG_ERR("Unkown error in (%s)", msg);    \
77                 }                                                               \
78         } while (0)
79
80 static void __vc_widget_send_current_command_group_cb(vc_cmd_list_h *vc_group, void *user_data)
81 {
82         (void)user_data;
83         *vc_group = vcw.group;
84
85         VC_ELM_LOG_DBG("SEND CURRENT COMMAND GROUP cb CALLED");
86 }
87
88 static Eina_Bool __vc_elm_widget_wrapper_initialize_timer_cb(void *data)
89 {
90         (void)data;
91
92         char *lang = NULL;
93         if (vcw.initialized) {
94                 VC_ELM_LOG_ERR("already initialized");
95                 g_initialize_timer = NULL;
96                 return EINA_FALSE;
97         }
98
99         int ret = -1;
100         if (0 != (ret = vc_widget_initialize(&g_vc_w))) {
101                 VC_ELM_LOG_ERR("Fail to vc_widet_initialize, ret(%d)", ret);
102                 if ((int)INITIALIZE_INTERVAL_TIME != (int)ecore_timer_interval_get(g_initialize_timer) * 1000) {
103                         VC_ELM_LOG_INFO("Set initializing timer to %f ms", INITIALIZE_INTERVAL_TIME);
104                         ecore_timer_interval_set(g_initialize_timer, INITIALIZE_INTERVAL_TIME / 1000);
105                 }
106                 return EINA_TRUE;
107         }
108
109         VC_ERROR_CHECK(vc_widget_set_error_cb(g_vc_w, &__vc_error_cb, NULL));
110         VC_ERROR_CHECK(vc_widget_set_show_tooltip_cb(g_vc_w, &__vc_show_tooltip_callback, NULL));
111         VC_ERROR_CHECK(vc_widget_set_result_cb(g_vc_w, &__vc_result_cb, NULL));
112         VC_ERROR_CHECK(vc_widget_set_state_changed_cb(g_vc_w, &__vc_state_changed_cb, NULL));
113         VC_ERROR_CHECK(vc_widget_set_service_state_changed_cb(g_vc_w, &__vc_service_state_changed_cb, NULL));
114         VC_ERROR_CHECK(vc_widget_set_current_language_changed_cb(g_vc_w, &__vc_language_changed_cb, NULL));
115         VC_ERROR_CHECK(vc_widget_set_send_current_command_list_cb(g_vc_w, __vc_widget_send_current_command_group_cb, NULL));
116         VC_ERROR_CHECK(vc_widget_prepare(g_vc_w));
117         VC_ELM_LOG_DBG("VC default language used %s", lang);
118         vcw.lang = lang;
119         vcw.initialized = 1;
120
121         g_initialize_timer = NULL;
122         return EINA_FALSE;
123 }
124
125 int _vc_elm_widget_wrapper_initialize()
126 {
127         char *lang = NULL;
128         if (vcw.initialized) {
129                 VC_ELM_LOG_ERR("already initialized");
130                 return 0;
131         }
132
133         int ret = -1;
134         if (0 != (ret = vc_widget_initialize(&g_vc_w))) {
135                 VC_ELM_LOG_ERR("Fail to vc_widet_initialize, ret(%d)", ret);
136                 if (g_initialize_timer)
137                         ecore_timer_del(g_initialize_timer);
138                 g_initialize_timer = ecore_timer_add(0.0, __vc_elm_widget_wrapper_initialize_timer_cb, NULL);
139                 return ret;
140         }
141
142         VC_ERROR_CHECK(vc_widget_set_error_cb(g_vc_w, &__vc_error_cb, NULL));
143         VC_ERROR_CHECK(vc_widget_set_show_tooltip_cb(g_vc_w, &__vc_show_tooltip_callback, NULL));
144         VC_ERROR_CHECK(vc_widget_set_result_cb(g_vc_w, &__vc_result_cb, NULL));
145         VC_ERROR_CHECK(vc_widget_set_state_changed_cb(g_vc_w, &__vc_state_changed_cb, NULL));
146         VC_ERROR_CHECK(vc_widget_set_service_state_changed_cb(g_vc_w, &__vc_service_state_changed_cb, NULL));
147         VC_ERROR_CHECK(vc_widget_set_current_language_changed_cb(g_vc_w, &__vc_language_changed_cb, NULL));
148         VC_ERROR_CHECK(vc_widget_set_send_current_command_list_cb(g_vc_w, __vc_widget_send_current_command_group_cb, NULL));
149         VC_ERROR_CHECK(vc_widget_prepare(g_vc_w));
150         VC_ELM_LOG_DBG("VC default language used %s", lang);
151         vcw.lang = lang;
152         vcw.initialized = 1;
153
154         VC_ELM_LOG_ERR("[SUCCESS] vc elm initialized");
155         return 0;
156 }
157
158 int _vc_elm_widget_wrapper_deinitialize()
159 {
160         if (vcw.group) {
161                 VC_ERROR_CHECK(vc_cmd_list_destroy(vcw.group, true));
162                 vcw.group = NULL;
163         }
164
165         if (vcw.lang) {
166                 free(vcw.lang);
167                 vcw.lang = NULL;
168         }
169
170         VC_ERROR_CHECK(vc_widget_unprepare(g_vc_w));
171         VC_ERROR_CHECK(vc_widget_deinitialize(g_vc_w));
172         vcw.initialized = 0;
173
174         return 0;
175 }
176
177 static bool __cb(vc_cmd_h vc_command, void *user_data)
178 {
179         char *cmd = NULL;
180         int type;
181         (void)user_data;
182
183         vc_cmd_get_format(vc_command, &type);
184         vc_cmd_get_command(vc_command, &cmd);
185         VC_ELM_LOG_DBG("cmd: %s %d", cmd, type);
186
187         if (NULL != cmd) {
188                 free(cmd);
189         }
190         return 1;
191 }
192
193 int _vc_elm_widget_wrapper_commit_commands(vc_elm_widget_wrapper_result_cb callback, void *data)
194 {
195         if (!vcw.group) {
196                 VC_ELM_LOG_WARN("commit 2");
197                 return -1;
198         }
199
200         VC_ELM_LOG_WARN("commit %p", (void*)vcw.group);
201         vc_cmd_list_foreach_commands(vcw.group, &__cb, NULL);
202
203         vcw.result_cb = callback;
204         vcw.data = data;
205         VC_ELM_LOG_WARN("commit ok");
206         return 0;
207 }
208
209 int _vc_elm_widget_wrapper_add_command(const char *cmd, const char *param1)
210 {
211         vc_cmd_h cmdh;
212         size_t len = 1;
213         char* command;
214         if (!vcw.group) {
215                 VC_ERROR_CHECK(vc_cmd_list_create(&vcw.group));
216                 VC_ELM_LOG_WARN("new_command_group %p", (void*)vcw.group);
217         }
218         if (NULL == cmd)
219                 return VC_ELM_ERROR_INVALID_PARAMETER;
220         len += strlen(cmd);
221         if (NULL != param1) {
222                 len = len + strlen(param1) + 1;
223                 command = (char *)calloc(len, sizeof(char));
224                 if (NULL == command) {
225                         VC_ELM_LOG_ERR("Fail to allocate memory");
226                         return -1;
227                 }
228                 snprintf(command, len, "%s %s", cmd, param1);
229         } else {
230                 command = (char *)calloc(len, sizeof(char));
231                 if (NULL == command) {
232                         VC_ELM_LOG_ERR("Fail to allocate memory");
233                         return -1;
234                 }
235                 snprintf(command, len, "%s", cmd);
236         }
237         VC_ERROR_CHECK(vc_cmd_create(&cmdh));
238         VC_ERROR_CHECK(vc_cmd_set_command(cmdh, command));
239         VC_ERROR_CHECK(vc_cmd_set_format(cmdh, VC_CMD_FORMAT_FIXED));
240         VC_ERROR_CHECK(vc_cmd_set_type(cmdh, VC_COMMAND_TYPE_WIDGET));
241         VC_ERROR_CHECK(vc_cmd_list_add(vcw.group, cmdh));
242
243         free(command);
244         return 0;
245 }
246
247 static void __vc_state_changed_cb(vc_state_e previous, vc_state_e current, void *user_data)
248 {
249         (void)user_data;
250
251         VC_ELM_LOG_DBG("VC state changed from %d to %d", previous, current);
252 }
253
254 static void __vc_service_state_changed_cb(vc_service_state_e previous, vc_service_state_e current, void *user_data)
255 {
256         (void)user_data;
257
258         if (previous == VC_SERVICE_STATE_RECORDING)
259                 _vc_elm_core_unregister_view_change_detection();
260         else if (current == VC_SERVICE_STATE_RECORDING)
261                 _vc_elm_core_register_view_change_detection();
262
263
264         if ((VC_SERVICE_STATE_PROCESSING == previous && VC_SERVICE_STATE_READY == current) || (VC_SERVICE_STATE_RECORDING == previous && VC_SERVICE_STATE_READY == current)) {
265                 VC_ELM_LOG_DBG("VC Service processing ends, clear commands");
266                 if (NULL != vcw.group) {
267                         vc_cmd_list_destroy(vcw.group, true);
268                         vcw.group = NULL;
269                 }
270         }
271 }
272
273 static void __vc_error_cb(vc_error_e reason, void *user_data)
274 {
275         (void)user_data;
276         VC_ELM_LOG_ERR("VC Error occurred : %d", reason);
277 }
278
279 static void __vc_result_cb(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char *result, void *user_data)
280 {
281         vc_cmd_h vc_command = NULL;
282         char *cmd_name = NULL;
283         int ret = 0;
284         int type = 0;
285         (void)user_data;
286         (void)result;
287         if (event != VC_RESULT_EVENT_RESULT_SUCCESS)
288                 return;
289
290         vc_cmd_list_first(vc_cmd_list);
291         while (VC_ERROR_ITERATION_END != ret) {
292                 if (0 != vc_cmd_list_get_current(vc_cmd_list, &vc_command)) {
293                         VC_ELM_LOG_ERR("cannot get command from list");
294                         break;
295                 }
296
297                 if (NULL == vc_command)
298                         break;
299
300                 VC_ERROR_CHECK(vc_cmd_get_format(vc_command, &type));
301                 VC_ERROR_CHECK(vc_cmd_get_command(vc_command, &cmd_name));
302
303                 if (vcw.result_cb) {
304                         vcw.result_cb(cmd_name, NULL, NULL, vcw.data);
305                         break;
306                 }
307
308                 ret = vc_cmd_list_next(vc_cmd_list);
309         }
310
311         free(cmd_name);
312 }
313
314 void __vc_show_tooltip_callback(bool show, void *data)
315 {
316         (void)data;
317         VC_ELM_LOG_DBG("show tooltips %d", show);
318
319         if (vcw.tooltips_cb && _vc_elm_core_get_tooltip_show())
320                 vcw.tooltips_cb(show);
321 }
322
323 void _vc_elm_widget_wrapper_set_show_tooltips_callback(vc_elm_widget_wrapper_show_tooltips_callback callback)
324 {
325         vcw.tooltips_cb = callback;
326 }
327
328 static void __vc_language_changed_cb(const char *previous, const char *current, void *data)
329 {
330         (void)previous;
331         (void)current;
332         (void)data;
333
334         VC_ELM_LOG_INFO("Widget language changed from %s to %s", previous, current);
335
336         if (NULL != vcw.language_changed_cb) {
337                 vcw.language_changed_cb(previous, current, vcw.lang_user_data);
338         } else {
339                 VC_ELM_LOG_DBG("Not registered language changed callback");
340         }
341         return;
342 }
343
344 int _vc_elm_widget_wrapper_set_current_language_changed_callback(vc_elm_widget_wrapper_language_changed_callback callback, void *data)
345 {
346         if (NULL == callback) {
347                 VC_ELM_LOG_ERR("Null parameter");
348                 return -1;
349         }
350
351         vcw.language_changed_cb = callback;
352         vcw.lang_user_data = data;
353         return 0;
354
355 }
356
357 int _vc_elm_widget_wrapper_unset_current_language_changed_callback()
358 {
359         if (NULL == vcw.language_changed_cb) {
360                 VC_ELM_LOG_ERR("No registered cb");
361                 return -1;
362         }
363
364         vcw.language_changed_cb = NULL;
365         vcw.lang_user_data = NULL;
366         return 0;
367 }
368
369 void _vc_elm_widget_wrapper_clear_commands()
370 {
371         if (NULL != vcw.group) {
372                 vc_cmd_list_destroy(vcw.group, true);
373                 vcw.group = NULL;
374         }
375 }
376
377 int _vc_elm_widget_wrapper_cancel()
378 {
379         int ret = VC_ELM_ERROR_NONE;
380         VC_ELM_LOG_DBG("===========");
381
382         ret = vc_widget_cancel(g_vc_w);
383         if (VC_ELM_ERROR_NONE != ret) {
384                 VC_ELM_LOG_ERR("Error while widget cancel (%d)", ret);
385         }
386         return ret;
387 }
388
389 int _vc_elm_widget_wrapper_foreach_supported_languages(vc_elm_supported_language_cb callback, void *data)
390 {
391         int ret = VC_ELM_ERROR_NONE;
392         VC_ELM_LOG_DBG("==========");
393
394         ret = vc_widget_foreach_supported_languages(g_vc_w, callback, data);
395         switch (ret) {
396         case VC_ERROR_NONE:
397                 ret = VC_ELM_ERROR_NONE;
398                 break;
399         case VC_ERROR_INVALID_PARAMETER:
400                 ret = VC_ELM_ERROR_INVALID_PARAMETER;
401                 break;
402         case VC_ERROR_INVALID_STATE:
403                 ret = VC_ELM_ERROR_INVALID_STATE;
404                 break;
405         default:
406                 ret = VC_ELM_ERROR_OPERATION_FAILED;
407                 break;
408         }
409
410         if (VC_ELM_ERROR_NONE != ret) {
411                 VC_ELM_LOG_ERR("[ERROR] Fail to foreach supported langauge(%d)", ret);
412         }
413
414         return ret;
415 }
416
417 int _vc_elm_widget_wrapper_get_current_language(char** language)
418 {
419         int ret = VC_ELM_ERROR_NONE;
420         VC_ELM_LOG_DBG("==========");
421
422         ret = vc_widget_get_current_language(g_vc_w, language);
423         switch (ret) {
424         case VC_ERROR_NONE:
425                 ret = VC_ELM_ERROR_NONE;
426                 break;
427         case VC_ERROR_INVALID_PARAMETER:
428                 ret = VC_ELM_ERROR_INVALID_PARAMETER;
429                 break;
430         case VC_ERROR_OUT_OF_MEMORY:
431                 ret = VC_ELM_ERROR_OUT_OF_MEMORY;
432                 break;
433         case VC_ERROR_INVALID_STATE:
434                 ret = VC_ELM_ERROR_INVALID_STATE;
435                 break;
436         default:
437                 ret = VC_ELM_ERROR_OPERATION_FAILED;
438                 break;
439         }
440
441         if (VC_ELM_ERROR_NONE != ret) {
442                 VC_ELM_LOG_ERR("[ERROR] Fail to get current language(%d)", ret);
443         }
444         return ret;
445 }