Load voice-control-elm library in the thread
[platform/core/appfw/app-core.git] / src / efl_base / appcore_efl_base.c
index 9f53902..5280f96 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #include <stdbool.h>
+#include <dlfcn.h>
+#include <glib.h>
 #include <Elementary.h>
 #include <vconf.h>
-#include <voice_control_elm.h>
-#include <voice_control_elm_private.h>
 
 #include "appcore_efl_base_private.h"
 #include "appcore_efl_base.h"
 
-static bool vc_elm_initialized;
+#define PATH_LIB_VC_ELM "/usr/lib/libvc-elm.so.0"
+
+static bool __vc_elm_initialized;
+static void *__vc_elm_handle;
+static int (*__vc_elm_initialize)(void);
+static int (*__vc_elm_deinitialize)(void);
+static int (*__vc_elm_set_auto_register_mode)(int, int);
+static GThread *__vc_elm_thread;
+
+static void __unload_vc_elm(void)
+{
+       if (!__vc_elm_handle)
+               return;
+
+       __vc_elm_initialize = NULL;
+       __vc_elm_deinitialize = NULL;
+       __vc_elm_set_auto_register_mode = NULL;
+
+       dlclose(__vc_elm_handle);
+       __vc_elm_handle = NULL;
+}
+
+static int __load_vc_elm(void)
+{
+       _DBG("Load voice-control-elm");
+
+       if (__vc_elm_handle) {
+               _DBG("Already exists");
+               return 0;
+       }
+
+       if (access(PATH_LIB_VC_ELM, F_OK) != 0) {
+               _ERR("Failed to access %s", PATH_LIB_VC_ELM);
+               return -1;
+       }
+
+       __vc_elm_handle = dlopen(PATH_LIB_VC_ELM, RTLD_LAZY | RTLD_LOCAL);
+       if (!__vc_elm_handle) {
+               _ERR("Failed to open %s", PATH_LIB_VC_ELM);
+               return -1;
+       }
+
+       __vc_elm_initialize = dlsym(__vc_elm_handle, "vc_elm_initialize");
+       if (!__vc_elm_initialize) {
+               _ERR("Failed to load vc_elm_initialize");
+               __unload_vc_elm();
+               return -1;
+       }
+
+       __vc_elm_deinitialize = dlsym(__vc_elm_handle, "vc_elm_deinitialize");
+       if (!__vc_elm_deinitialize) {
+               _ERR("Failed to load vc_elm_deinitialize");
+               __unload_vc_elm();
+               return -1;
+       }
+
+       __vc_elm_set_auto_register_mode = dlsym(__vc_elm_handle,
+                       "vc_elm_set_auto_register_mode");
+       if (!__vc_elm_set_auto_register_mode) {
+               _ERR("Failed to load vc_elm_set_auto_register_mode");
+               __unload_vc_elm();
+               return -1;
+       }
+
+       return 0;
+}
 
 static void __vc_vtauto_changed_cb(keynode_t *key, void *data)
 {
@@ -40,22 +105,74 @@ static void __vc_vtauto_changed_cb(keynode_t *key, void *data)
 
        vt_automode = vconf_keynode_get_bool(key);
        if (vt_automode) {
-               if (!vc_elm_initialized) {
-                       vc_elm_initialize();
-                       vc_elm_initialized = true;
+               if (!__vc_elm_initialized) {
+                       __vc_elm_initialize();
+                       __vc_elm_initialized = true;
                }
-               vc_elm_set_auto_register_mode(2, 0);
+               __vc_elm_set_auto_register_mode(2, 0);
        } else {
-               vc_elm_deinitialize();
-               vc_elm_initialized = false;
+               __vc_elm_deinitialize();
+               __vc_elm_initialized = false;
+       }
+}
+
+static void __vc_elm_init(void)
+{
+       int vt_automode = 0;
+
+       vconf_notify_key_changed(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE,
+                       __vc_vtauto_changed_cb, NULL);
+       vconf_get_bool(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE, &vt_automode);
+       if (vt_automode) {
+               if (!__vc_elm_initialized) {
+                       __vc_elm_initialize();
+                       __vc_elm_initialized = true;
+               }
+               __vc_elm_set_auto_register_mode(2, 0);
        }
 }
 
-static int __efl_app_init(int argc, char **argv, void *data)
+static void __vc_elm_finish(void)
+{
+       vconf_ignore_key_changed(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE,
+                       __vc_vtauto_changed_cb);
+       if (__vc_elm_initialized) {
+               __vc_elm_deinitialize();
+               __vc_elm_initialized = false;
+       }
+}
+
+static gboolean __init_vc_elm(gpointer data)
+{
+       _DBG("Initialize vc-elm");
+       /* Postpone initialization to improve app launching performance */
+       /* VC voice touch setting */
+       __vc_elm_init();
+
+       return G_SOURCE_REMOVE;
+}
+
+static gpointer __vc_elm_loader(gpointer data)
+{
+       int r = 0;
+       int retry_count = 3;
+
+       do {
+               r = __load_vc_elm();
+               if (r == 0) {
+                       g_idle_add(__init_vc_elm, NULL);
+                       break;
+               }
+       } while (retry_count--);
+       LOGW("[vc-elm-loader] Result: %d", r);
+
+       return GINT_TO_POINTER(r);
+}
+
+static void __efl_app_init(int argc, char **argv, void *data)
 {
        int hint;
        const char *hwacc;
-       int vt_automode = 0;
 
        elm_init(argc, argv);
 
@@ -75,28 +192,18 @@ static int __efl_app_init(int argc, char **argv, void *data)
                }
        }
 
-       /* VC voice touch setting */
-       vconf_notify_key_changed(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE,
-                       __vc_vtauto_changed_cb, NULL);
-       vconf_get_bool(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE, &vt_automode);
-       if (vt_automode) {
-               if (!vc_elm_initialized) {
-                       vc_elm_initialize();
-                       vc_elm_initialized = true;
-               }
-               vc_elm_set_auto_register_mode(2, 0);
-       }
-
-       return 0;
+       __vc_elm_thread = g_thread_new("vc-elm-loader", __vc_elm_loader, NULL);
 }
 
 static void __efl_app_finish(void)
 {
-       vconf_ignore_key_changed(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE,
-                       __vc_vtauto_changed_cb);
-       if (vc_elm_initialized) {
-               vc_elm_deinitialize();
-               vc_elm_initialized = false;
+       gpointer r;
+
+       __vc_elm_finish();
+       if (__vc_elm_thread) {
+               r = g_thread_join(__vc_elm_thread);
+               __vc_elm_thread = NULL;
+               _DBG("vc-elm-loader. result(%d)", GPOINTER_TO_INT(r));
        }
 
        elm_shutdown();
@@ -118,6 +225,13 @@ static void __efl_app_exit(void *data)
        elm_exit();
 }
 
+static void __efl_app_trim_memory(void *data)
+{
+       _DBG("Trim memory");
+       elm_cache_all_flush();
+       appcore_base_on_trim_memory();
+}
+
 EXPORT_API int appcore_efl_base_init(appcore_efl_base_ops ops, int argc,
                char **argv, void *data, unsigned int hint)
 {
@@ -140,6 +254,7 @@ EXPORT_API appcore_efl_base_ops appcore_efl_base_get_default_ops(void)
        ops.ui_base.base.finish = __efl_app_finish;
        ops.ui_base.base.run = __efl_app_run;
        ops.ui_base.base.exit = __efl_app_exit;
+       ops.ui_base.base.trim_memory = __efl_app_trim_memory;
 
        return ops;
 }
@@ -174,6 +289,11 @@ EXPORT_API int appcore_efl_base_on_control(bundle *b)
        return appcore_ui_base_on_control(b);
 }
 
+EXPORT_API int appcore_efl_base_on_trim_memory(void)
+{
+       return appcore_ui_base_on_trim_memory();
+}
+
 EXPORT_API void appcore_efl_base_window_on_show(int type, void *event)
 {
        appcore_ui_base_window_on_show(type, event);
@@ -194,6 +314,16 @@ EXPORT_API void appcore_efl_base_window_on_visibility(int type, void *event)
        appcore_ui_base_window_on_visibility(type, event);
 }
 
+EXPORT_API void appcore_efl_base_window_on_pre_visibility(int type, void *event)
+{
+       appcore_ui_base_window_on_pre_visibility(type, event);
+}
+
+EXPORT_API void appcore_efl_base_window_on_aux_message(int type, void *event)
+{
+       appcore_ui_base_window_on_aux_message(type, event);
+}
+
 EXPORT_API void appcore_efl_base_pause(void)
 {
        appcore_ui_base_pause();
@@ -248,3 +378,8 @@ EXPORT_API void appcore_efl_base_set_bg_state(bool bg_state)
 {
        appcore_ui_base_set_bg_state(bg_state);
 }
+
+EXPORT_API void appcore_efl_base_set_system_resource_reclaiming(bool enable)
+{
+       appcore_ui_base_set_system_resource_reclaiming(enable);
+}