Load voice-control-elm library in the thread
[platform/core/appfw/app-core.git] / src / efl_base / appcore_efl_base.c
1 /*
2  * Copyright (c) 2017 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 #define _GNU_SOURCE
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <stdbool.h>
22 #include <dlfcn.h>
23 #include <glib.h>
24 #include <Elementary.h>
25 #include <vconf.h>
26
27 #include "appcore_efl_base_private.h"
28 #include "appcore_efl_base.h"
29
30 #define PATH_LIB_VC_ELM "/usr/lib/libvc-elm.so.0"
31
32 static bool __vc_elm_initialized;
33 static void *__vc_elm_handle;
34 static int (*__vc_elm_initialize)(void);
35 static int (*__vc_elm_deinitialize)(void);
36 static int (*__vc_elm_set_auto_register_mode)(int, int);
37 static GThread *__vc_elm_thread;
38
39 static void __unload_vc_elm(void)
40 {
41         if (!__vc_elm_handle)
42                 return;
43
44         __vc_elm_initialize = NULL;
45         __vc_elm_deinitialize = NULL;
46         __vc_elm_set_auto_register_mode = NULL;
47
48         dlclose(__vc_elm_handle);
49         __vc_elm_handle = NULL;
50 }
51
52 static int __load_vc_elm(void)
53 {
54         _DBG("Load voice-control-elm");
55
56         if (__vc_elm_handle) {
57                 _DBG("Already exists");
58                 return 0;
59         }
60
61         if (access(PATH_LIB_VC_ELM, F_OK) != 0) {
62                 _ERR("Failed to access %s", PATH_LIB_VC_ELM);
63                 return -1;
64         }
65
66         __vc_elm_handle = dlopen(PATH_LIB_VC_ELM, RTLD_LAZY | RTLD_LOCAL);
67         if (!__vc_elm_handle) {
68                 _ERR("Failed to open %s", PATH_LIB_VC_ELM);
69                 return -1;
70         }
71
72         __vc_elm_initialize = dlsym(__vc_elm_handle, "vc_elm_initialize");
73         if (!__vc_elm_initialize) {
74                 _ERR("Failed to load vc_elm_initialize");
75                 __unload_vc_elm();
76                 return -1;
77         }
78
79         __vc_elm_deinitialize = dlsym(__vc_elm_handle, "vc_elm_deinitialize");
80         if (!__vc_elm_deinitialize) {
81                 _ERR("Failed to load vc_elm_deinitialize");
82                 __unload_vc_elm();
83                 return -1;
84         }
85
86         __vc_elm_set_auto_register_mode = dlsym(__vc_elm_handle,
87                         "vc_elm_set_auto_register_mode");
88         if (!__vc_elm_set_auto_register_mode) {
89                 _ERR("Failed to load vc_elm_set_auto_register_mode");
90                 __unload_vc_elm();
91                 return -1;
92         }
93
94         return 0;
95 }
96
97 static void __vc_vtauto_changed_cb(keynode_t *key, void *data)
98 {
99         const char *name;
100         int vt_automode;
101
102         name = vconf_keynode_get_name(key);
103         if (!name || strcmp(name, VCONFKEY_VC_VOICE_TOUCH_AUTOMODE) != 0)
104                 return;
105
106         vt_automode = vconf_keynode_get_bool(key);
107         if (vt_automode) {
108                 if (!__vc_elm_initialized) {
109                         __vc_elm_initialize();
110                         __vc_elm_initialized = true;
111                 }
112                 __vc_elm_set_auto_register_mode(2, 0);
113         } else {
114                 __vc_elm_deinitialize();
115                 __vc_elm_initialized = false;
116         }
117 }
118
119 static void __vc_elm_init(void)
120 {
121         int vt_automode = 0;
122
123         vconf_notify_key_changed(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE,
124                         __vc_vtauto_changed_cb, NULL);
125         vconf_get_bool(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE, &vt_automode);
126         if (vt_automode) {
127                 if (!__vc_elm_initialized) {
128                         __vc_elm_initialize();
129                         __vc_elm_initialized = true;
130                 }
131                 __vc_elm_set_auto_register_mode(2, 0);
132         }
133 }
134
135 static void __vc_elm_finish(void)
136 {
137         vconf_ignore_key_changed(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE,
138                         __vc_vtauto_changed_cb);
139         if (__vc_elm_initialized) {
140                 __vc_elm_deinitialize();
141                 __vc_elm_initialized = false;
142         }
143 }
144
145 static gboolean __init_vc_elm(gpointer data)
146 {
147         _DBG("Initialize vc-elm");
148         /* Postpone initialization to improve app launching performance */
149         /* VC voice touch setting */
150         __vc_elm_init();
151
152         return G_SOURCE_REMOVE;
153 }
154
155 static gpointer __vc_elm_loader(gpointer data)
156 {
157         int r = 0;
158         int retry_count = 3;
159
160         do {
161                 r = __load_vc_elm();
162                 if (r == 0) {
163                         g_idle_add(__init_vc_elm, NULL);
164                         break;
165                 }
166         } while (retry_count--);
167         LOGW("[vc-elm-loader] Result: %d", r);
168
169         return GINT_TO_POINTER(r);
170 }
171
172 static void __efl_app_init(int argc, char **argv, void *data)
173 {
174         int hint;
175         const char *hwacc;
176
177         elm_init(argc, argv);
178
179         hint = appcore_efl_base_get_hint();
180         if (hint & APPCORE_EFL_BASE_HINT_HW_ACC_CONTROL) {
181                 hwacc = getenv("HWACC");
182                 if (hwacc == NULL) {
183                         _DBG("elm_config_accel_preference_set is not called");
184                 } else if (strcmp(hwacc, "USE") == 0) {
185                         elm_config_accel_preference_set("hw");
186                         _DBG("elm_config_accel_preference_set : hw");
187                 } else if (strcmp(hwacc, "NOT_USE") == 0) {
188                         elm_config_accel_preference_set("none");
189                         _DBG("elm_config_accel_preference_set : none");
190                 } else {
191                         _DBG("elm_config_accel_preference_set is not called");
192                 }
193         }
194
195         __vc_elm_thread = g_thread_new("vc-elm-loader", __vc_elm_loader, NULL);
196 }
197
198 static void __efl_app_finish(void)
199 {
200         gpointer r;
201
202         __vc_elm_finish();
203         if (__vc_elm_thread) {
204                 r = g_thread_join(__vc_elm_thread);
205                 __vc_elm_thread = NULL;
206                 _DBG("vc-elm-loader. result(%d)", GPOINTER_TO_INT(r));
207         }
208
209         elm_shutdown();
210
211         /* Check loader case */
212         if (getenv("AUL_LOADER_INIT")) {
213                 unsetenv("AUL_LOADER_INIT");
214                 elm_shutdown();
215         }
216 }
217
218 static void __efl_app_run(void *data)
219 {
220         elm_run();
221 }
222
223 static void __efl_app_exit(void *data)
224 {
225         elm_exit();
226 }
227
228 static void __efl_app_trim_memory(void *data)
229 {
230         _DBG("Trim memory");
231         elm_cache_all_flush();
232         appcore_base_on_trim_memory();
233 }
234
235 EXPORT_API int appcore_efl_base_init(appcore_efl_base_ops ops, int argc,
236                 char **argv, void *data, unsigned int hint)
237 {
238         return appcore_ui_base_init(ops.ui_base, argc, argv, data, hint);
239 }
240
241 EXPORT_API void appcore_efl_base_fini(void)
242 {
243         appcore_ui_base_fini();
244 }
245
246 EXPORT_API appcore_efl_base_ops appcore_efl_base_get_default_ops(void)
247 {
248         appcore_efl_base_ops ops;
249
250         ops.ui_base = appcore_ui_base_get_default_ops();
251
252         /* override methods */
253         ops.ui_base.base.init = __efl_app_init;
254         ops.ui_base.base.finish = __efl_app_finish;
255         ops.ui_base.base.run = __efl_app_run;
256         ops.ui_base.base.exit = __efl_app_exit;
257         ops.ui_base.base.trim_memory = __efl_app_trim_memory;
258
259         return ops;
260 }
261
262 EXPORT_API int appcore_efl_base_on_receive(aul_type type, bundle *b)
263 {
264         return appcore_ui_base_on_receive(type, b);
265 }
266
267 EXPORT_API int appcore_efl_base_on_create(void)
268 {
269         return appcore_ui_base_on_create();
270 }
271
272 EXPORT_API int appcore_efl_base_on_terminate(void)
273 {
274         return appcore_ui_base_on_terminate();
275 }
276
277 EXPORT_API int appcore_efl_base_on_pause(void)
278 {
279         return appcore_ui_base_on_pause();
280 }
281
282 EXPORT_API int appcore_efl_base_on_resume(void)
283 {
284         return appcore_ui_base_on_resume();
285 }
286
287 EXPORT_API int appcore_efl_base_on_control(bundle *b)
288 {
289         return appcore_ui_base_on_control(b);
290 }
291
292 EXPORT_API int appcore_efl_base_on_trim_memory(void)
293 {
294         return appcore_ui_base_on_trim_memory();
295 }
296
297 EXPORT_API void appcore_efl_base_window_on_show(int type, void *event)
298 {
299         appcore_ui_base_window_on_show(type, event);
300 }
301
302 EXPORT_API void appcore_efl_base_window_on_hide(int type, void *event)
303 {
304         appcore_ui_base_window_on_hide(type, event);
305 }
306
307 EXPORT_API void appcore_efl_base_window_on_lower(int type, void *event)
308 {
309         appcore_ui_base_window_on_lower(type, event);
310 }
311
312 EXPORT_API void appcore_efl_base_window_on_visibility(int type, void *event)
313 {
314         appcore_ui_base_window_on_visibility(type, event);
315 }
316
317 EXPORT_API void appcore_efl_base_window_on_pre_visibility(int type, void *event)
318 {
319         appcore_ui_base_window_on_pre_visibility(type, event);
320 }
321
322 EXPORT_API void appcore_efl_base_window_on_aux_message(int type, void *event)
323 {
324         appcore_ui_base_window_on_aux_message(type, event);
325 }
326
327 EXPORT_API void appcore_efl_base_pause(void)
328 {
329         appcore_ui_base_pause();
330 }
331
332 EXPORT_API void appcore_efl_base_resume(void)
333 {
334         appcore_ui_base_resume();
335 }
336
337 EXPORT_API bool appcore_efl_base_is_resumed(void)
338 {
339         return appcore_ui_base_is_resumed();
340 }
341
342 EXPORT_API void appcore_efl_base_exit(void)
343 {
344         appcore_ui_base_exit();
345 }
346
347 EXPORT_API void appcore_efl_base_group_add(void)
348 {
349         appcore_ui_base_group_add();
350 }
351
352 EXPORT_API void appcore_efl_base_group_remove(void)
353 {
354         appcore_ui_base_group_remove();
355 }
356
357 EXPORT_API unsigned int appcore_efl_base_get_main_window(void)
358 {
359         return appcore_ui_base_get_main_window();
360 }
361
362 EXPORT_API unsigned int appcore_efl_base_get_main_surface(void)
363 {
364         return appcore_ui_base_get_main_surface();
365 }
366
367 EXPORT_API int appcore_efl_base_get_hint(void)
368 {
369         return appcore_ui_base_get_hint();
370 }
371
372 EXPORT_API bool appcore_efl_base_get_bg_state(void)
373 {
374         return appcore_ui_base_get_bg_state();
375 }
376
377 EXPORT_API void appcore_efl_base_set_bg_state(bool bg_state)
378 {
379         appcore_ui_base_set_bg_state(bg_state);
380 }
381
382 EXPORT_API void appcore_efl_base_set_system_resource_reclaiming(bool enable)
383 {
384         appcore_ui_base_set_system_resource_reclaiming(enable);
385 }