Supporting the OSP livebox(CPP)
authorSung-jae Park <nicesj.park@samsung.com>
Thu, 24 May 2012 08:09:52 +0000 (17:09 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Thu, 24 May 2012 14:04:46 +0000 (23:04 +0900)
Change-Id: I4df77500371c6e0e5b722bce4a879c6726953e49

include/livebox.h
include/so_handler.h
src/dbus.c
src/livebox.c
src/so_handler.c

index 93c12b9..95c88eb 100644 (file)
@@ -1,7 +1,7 @@
 extern int livebox_init(void);
 extern int livebox_fini(void);
 
-extern int livebox_create(const char *pkgname, const char *filename, const char *content_info, int timeout, int has_livebox_script, double period, const char *cluster, const char *category, int *w, int *h, double *priority, int pinup, int skip_need_to_create);
+extern int livebox_create(const char *pkgname, const char *filename, const char *content_info, int timeout, int has_livebox_script, double period, const char *cluster, const char *category, int *w, int *h, double *priority, int pinup, int skip_need_to_create, const char *abi);
 extern int livebox_destroy(const char *pkgname, const char *filename);
 
 extern int livebox_pinup(const char *pkgname, const char *filename, int pinup);
index f3c1494..d405f23 100644 (file)
@@ -24,9 +24,23 @@ typedef int (*resize_t)(const char *filename, int width, int height);
 typedef int (*create_needed_t)(const char *cluster, const char *category);
 typedef int (*change_group_t)(const char *filename, const char *cluster, const char *category);
 typedef int (*get_output_info_t)(const char *filename, int *w, int *h, double *priority);
-typedef int (*initialize_t)(void);
+typedef int (*initialize_t)(const char *pkgname);
 typedef int (*finalize_t)(void);
 
+typedef int (*adaptor_create_t)(const char *pkgname, const char *filename, const char *content, const char *cluster, const char *category);
+typedef int (*adaptor_destroy_t)(const char *pkgname, const char *filename);
+typedef int (*adaptor_is_updated_t)(const char *pkgname, const char *filename);
+typedef int (*adaptor_need_to_destroy_t)(const char *pkgname, const char *filename);
+typedef int (*adaptor_update_content_t)(const char *pkgname, const char *filename);
+typedef int (*adaptor_clicked_t)(const char *pkgname, const char *filename, const char *event, double timestamp, double x, double y);
+typedef int (*adaptor_script_t)(const char *pkgname, const char *filename, const char *emission, const char *source, struct event_info *event_info);
+typedef int (*adaptor_resize_t)(const char *pkgname, const char *filename, int width, int height);
+typedef int (*adaptor_create_needed_t)(const char *pkgname, const char *cluster, const char *category);
+typedef int (*adaptor_change_group_t)(const char *pkgname, const char *filename, const char *cluster, const char *category);
+typedef int (*adaptor_get_output_info_t)(const char *pkgname, const char *filename, int *w, int *h, double *priority);
+typedef int (*adaptor_initialize_t)(const char *pkgname);
+typedef int (*adaptor_finalize_t)(const char *pkgname);
+
 extern const int DONE;
 extern const int NEED_TO_SCHEDULE;
 extern const int OUTPUT_UPDATED;
@@ -54,23 +68,41 @@ struct so_item {
 
        Eina_List *inst_list;
 
-       initialize_t initialize;
-       finalize_t finalize;
-       create_t create;
-       destroy_t destroy;
-       is_updated_t is_updated;
-       update_content_t update_content;
-       clicked_t clicked;
-       script_t script_event;
-       resize_t resize;
-       create_needed_t create_needed;
-       change_group_t change_group;
-       get_output_info_t get_output_info;
-       need_to_destroy_t need_to_destroy;
+       struct {
+               initialize_t initialize;
+               finalize_t finalize;
+               create_t create;
+               destroy_t destroy;
+               is_updated_t is_updated;
+               update_content_t update_content;
+               clicked_t clicked;
+               script_t script_event;
+               resize_t resize;
+               create_needed_t create_needed;
+               change_group_t change_group;
+               get_output_info_t get_output_info;
+               need_to_destroy_t need_to_destroy;
+       } livebox;
+
+       struct {
+               adaptor_initialize_t initialize;
+               adaptor_finalize_t finalize;
+               adaptor_create_t create;
+               adaptor_destroy_t destroy;
+               adaptor_is_updated_t is_updated;
+               adaptor_update_content_t update_content;
+               adaptor_clicked_t clicked;
+               adaptor_script_t script_event;
+               adaptor_resize_t resize;
+               adaptor_create_needed_t create_needed;
+               adaptor_change_group_t change_group;
+               adaptor_get_output_info_t get_output_info;
+               adaptor_need_to_destroy_t need_to_destroy;
+       } adaptor;
 };
 
 extern struct instance *so_find_instance(const char *pkgname, const char *filename);
-extern int so_create(const char *pkgname, const char *filename, const char *content_info, int timeout, int has_livebox_script, const char *cluster, const char *category, struct instance **inst);
+extern int so_create(const char *pkgname, const char *filename, const char *content_info, int timeout, int has_livebox_script, const char *cluster, const char *category, const char *abi, struct instance **inst);
 extern int so_is_updated(struct instance *inst);
 extern int so_need_to_destroy(struct instance *inst);
 extern int so_update(struct instance *inst);
@@ -78,7 +110,7 @@ extern int so_destroy(struct instance *inst);
 extern int so_clicked(struct instance *inst, const char *event, double timestamp, double x, double y);
 extern int so_script_event(struct instance *inst, const char *emission, const char *source, struct event_info *event_info);
 extern int so_resize(struct instance *inst, int w, int h);
-extern int so_create_needed(const char *pkgname, const char *cluster, const char *category);
+extern int so_create_needed(const char *pkgname, const char *cluster, const char *category, const char *abi);
 extern int so_change_group(struct instance *inst, const char *cluster, const char *category);
 extern int so_get_output_info(struct instance *inst, int *w, int *h, double *priority);
 
index 02ee370..906e3b8 100644 (file)
@@ -89,6 +89,7 @@ static struct info {
        "  <arg type='i' name='pinup' direction='in' />"
        "  <arg type='i' name='width' direction='in' />"
        "  <arg type='i' name='height' direction='in' />"
+       "  <arg type='i' name='abi' direction='in' />"
        "  <arg type='i' name='ret' direction='out' />"
        " </method>"
        " <method name='new'>"
@@ -102,6 +103,7 @@ static struct info {
        "  <arg type='s' name='category' direction='in' />"
        "  <arg type='i' name='pinup' direction='in' />"
        "  <arg type='i' name='skip_need_to_create' direction='in' />"
+       "  <arg type='s' name='abi' direction='in' />"
        "  <arg type='i' name='result' direction='out' />"
        "  <arg type='i' name='width' direction='out' />"
        "  <arg type='i' name='height' direction='out' />"
@@ -343,6 +345,7 @@ static void method_renew(GDBusMethodInvocation *inv, GVariant *param)
        const char *content;
        const char *cluster;
        const char *category;
+       const char *abi;
        int timeout;
        int has_livebox_script;
        double period;
@@ -354,11 +357,11 @@ static void method_renew(GDBusMethodInvocation *inv, GVariant *param)
        double priority;
        int pinup;
 
-       g_variant_get(param, "(&s&s&siid&s&siii)", &pkgname, &filename,
+       g_variant_get(param, "(&s&s&siid&s&siiis)", &pkgname, &filename,
                                &content, &timeout, &has_livebox_script,
-                               &period, &cluster, &category, &pinup, &w, &h);
+                               &period, &cluster, &category, &pinup, &w, &h, &abi);
 
-       ret = livebox_create(pkgname, filename, content, timeout, has_livebox_script, period, cluster, category, &lw, &lh, &priority, pinup, 1);
+       ret = livebox_create(pkgname, filename, content, timeout, has_livebox_script, period, cluster, category, &lw, &lh, &priority, pinup, 1, abi);
        if (ret == 0) {
                if (lw != w || lh != h) {
                        int tmp;
@@ -382,6 +385,7 @@ static void method_new(GDBusMethodInvocation *inv, GVariant *param)
        const char *content;
        const char *cluster;
        const char *category;
+       const char *abi;
        int timeout;
        int has_livebox_script;
        double period;
@@ -392,14 +396,14 @@ static void method_new(GDBusMethodInvocation *inv, GVariant *param)
        int pinup;
        int skip_need_to_create;
 
-       g_variant_get(param, "(&s&s&siid&s&sii)", &pkgname, &filename,
+       g_variant_get(param, "(&s&s&siid&s&sii&s)", &pkgname, &filename,
                                &content, &timeout, &has_livebox_script,
-                               &period, &cluster, &category, &pinup, &skip_need_to_create);
+                               &period, &cluster, &category, &pinup, &skip_need_to_create, &abi);
 
        /* TODO: timeout, livebox_script, period */
-       ret = livebox_create(pkgname, filename, content, timeout, has_livebox_script, period, cluster, category, &w, &h, &priority, pinup, skip_need_to_create);
-       DbgPrint("Create livebox: pkgname[%s], filename[%s], content[%s], timeout[%d], has_livebox_script[%d], period[%lf], cluster[%s], category[%s], w[%d], h[%d], priority[%lf], pinup[%d], skip_need_to_create[%d]\n",
-               pkgname, filename, content, timeout, has_livebox_script, period, cluster, category, w, h, priority, pinup, skip_need_to_create);
+       ret = livebox_create(pkgname, filename, content, timeout, has_livebox_script, period, cluster, category, &w, &h, &priority, pinup, skip_need_to_create, abi);
+       DbgPrint("Create livebox: pkgname[%s], filename[%s], content[%s], timeout[%d], has_livebox_script[%d], period[%lf], cluster[%s], category[%s], w[%d], h[%d], priority[%lf], pinup[%d], skip_need_to_create[%d], abi[%s]\n",
+               pkgname, filename, content, timeout, has_livebox_script, period, cluster, category, w, h, priority, pinup, skip_need_to_create, abi);
 
        param = g_variant_new("(iiid)", ret, w, h, priority);
        if (!param)
index 3c61c73..abc5ad8 100644 (file)
@@ -333,7 +333,7 @@ int livebox_fini(void)
        return 0;
 }
 
-int livebox_create(const char *pkgname, const char *filename, const char *content_info, int timeout, int has_livebox_script, double period, const char *cluster, const char *category, int *w, int *h, double *priority, int pinup, int skip_need_to_create)
+int livebox_create(const char *pkgname, const char *filename, const char *content_info, int timeout, int has_livebox_script, double period, const char *cluster, const char *category, int *w, int *h, double *priority, int pinup, int skip_need_to_create, const char *abi)
 {
        struct instance *inst;
        struct item *item;
@@ -348,7 +348,7 @@ int livebox_create(const char *pkgname, const char *filename, const char *conten
                return 0;
 
        if (!skip_need_to_create) {
-               ret = so_create_needed(pkgname, cluster, category);
+               ret = so_create_needed(pkgname, cluster, category, abi);
                if (ret != NEED_TO_CREATE)
                        return -EPERM;
 
@@ -365,7 +365,7 @@ int livebox_create(const char *pkgname, const char *filename, const char *conten
        item->monitor_cnt = 0;
        item->deleteme = 0;
 
-       create_ret = so_create(pkgname, filename, content_info, timeout, has_livebox_script, cluster, category, &inst);
+       create_ret = so_create(pkgname, filename, content_info, timeout, has_livebox_script, cluster, category, abi, &inst);
        if (create_ret < 0) {
                free(item);
 
index 3a5ce65..b448e02 100644 (file)
@@ -41,6 +41,13 @@ static inline struct so_item *find_livebox(const char *pkgname)
        return NULL;
 }
 
+static inline char *so_adaptor_alloc(const char *abi)
+{
+       /* TODO: Implement me */
+       DbgPrint("ABI[%s] loads %s\n", abi, "/usr/lib/liblivebox-cpp.so");
+       return strdup("/usr/lib/liblivebox-cpp.so");
+}
+
 static inline char *so_path_alloc(const char *pkgname)
 {
        char *path;
@@ -66,10 +73,17 @@ static inline char *so_path_alloc(const char *pkgname)
 
 static void delete_livebox(struct so_item *item)
 {
-       if (item->finalize) {
+       if (item->adaptor.finalize) {
                int ret;
                fault_mark_call(item->pkgname, "finalize", __func__);
-               ret = item->finalize();
+               ret = item->adaptor.finalize(item->pkgname);
+               fault_unmark_call(item->pkgname, "finalize", __func__);
+
+               ErrPrint("Package %s, finalize returns %d\n", item->pkgname, ret);
+       } else if (item->livebox.finalize) {
+               int ret;
+               fault_mark_call(item->pkgname, "finalize", __func__);
+               ret = item->livebox.finalize();
                fault_unmark_call(item->pkgname, "finalize", __func__);
 
                ErrPrint("Package %s, finalize returns %d\n", item->pkgname, ret);
@@ -80,12 +94,134 @@ static void delete_livebox(struct so_item *item)
        free(item);
 }
 
+static struct so_item *new_adaptor(const char *pkgname, const char *abi)
+{
+       struct so_item *item;
+       char *livebox_path;
+
+       item = calloc(1, sizeof(*item));
+       if (!item) {
+               ErrPrint("Memory: %s\n", strerror(errno));
+               return NULL;
+       }
+
+       item->pkgname = strdup(pkgname);
+       if (!item->pkgname) {
+               ErrPrint("Memory: %s\n", strerror(errno));
+               free(item);
+               return NULL;
+       }
+
+       /*! \TODO:
+        * item->timeout
+        */
+
+       /*! \TODO
+        * item->has_livbox_script
+        */
+
+       item->inst_list = NULL;
+
+       livebox_path = so_adaptor_alloc(abi);
+       if (!livebox_path) {
+               free(item->pkgname);
+               free(item);
+               return NULL;
+       }
+
+       fault_mark_call(pkgname, __func__, __func__);
+       item->handle = dlopen(livebox_path, RTLD_LOCAL | RTLD_LAZY);
+       if (!item->handle) {
+               fault_unmark_call(pkgname, __func__, __func__);
+               ErrPrint("dlopen: %s - %s\n", dlerror(), livebox_path);
+               free(livebox_path);
+               free(item->pkgname);
+               free(item);
+               return NULL;
+       }
+       fault_unmark_call(pkgname, __func__, __func__);
+       free(livebox_path);
+
+       item->adaptor.create = (adaptor_create_t)dlsym(item->handle, "livebox_create");
+       if (!item->adaptor.create) {
+               ErrPrint("symbol: livebox_create - %s\n", dlerror());
+               delete_livebox(item);
+               return NULL;
+       }
+
+       item->adaptor.destroy = (adaptor_destroy_t)dlsym(item->handle, "livebox_destroy");
+       if (!item->adaptor.destroy) {
+               ErrPrint("symbol: livebox_destroy - %s\n", dlerror());
+               delete_livebox(item);
+               return NULL;
+       }
+
+       item->adaptor.is_updated = (adaptor_is_updated_t)dlsym(item->handle, "livebox_need_to_update");
+       if (!item->adaptor.is_updated)
+               ErrPrint("symbol: livebox_need_to_update - %s\n", dlerror());
+
+       item->adaptor.update_content = (adaptor_update_content_t)dlsym(item->handle, "livebox_update_content");
+       if (!item->adaptor.update_content)
+               ErrPrint("symbol: livebox_update_content - %s\n", dlerror());
+
+       item->adaptor.clicked = (adaptor_clicked_t)dlsym(item->handle, "livebox_clicked");
+       if (!item->adaptor.clicked)
+               ErrPrint("symbol: livebox_clicked - %s\n", dlerror());
+
+       item->adaptor.script_event = (adaptor_script_t)dlsym(item->handle, "livebox_content_event");
+       if (!item->adaptor.script_event)
+               ErrPrint("symbol: livebox_content_event - %s\n", dlerror());
+
+       item->adaptor.resize = (adaptor_resize_t)dlsym(item->handle, "livebox_resize");
+       if (!item->adaptor.resize)
+               ErrPrint("symbol: livebox_resize - %s\n", dlerror());
+
+       item->adaptor.create_needed = (adaptor_create_needed_t)dlsym(item->handle, "livebox_need_to_create");
+       if (!item->adaptor.create_needed)
+               ErrPrint("symbol: livebox_need_to_create - %s\n", dlerror());
+
+       item->adaptor.change_group = (adaptor_change_group_t)dlsym(item->handle, "livebox_change_group");
+       if (!item->adaptor.change_group)
+               ErrPrint("symbol: livebox_change_group - %s\n", dlerror());
+
+       item->adaptor.get_output_info = (adaptor_get_output_info_t)dlsym(item->handle, "livebox_get_info");
+       if (!item->adaptor.get_output_info)
+               ErrPrint("symbol: livebox_get_info - %s\n", dlerror());
+
+       item->adaptor.initialize = (adaptor_initialize_t)dlsym(item->handle, "livebox_initialize");
+       if (!item->adaptor.initialize)
+               ErrPrint("symbol: livebox_initialize - %s\n", dlerror());
+
+       item->adaptor.finalize = (adaptor_finalize_t)dlsym(item->handle, "livebox_finalize");
+       if (!item->adaptor.finalize)
+               ErrPrint("symbol: livebox_finalize - %s\n", dlerror());
+
+       item->adaptor.need_to_destroy = (adaptor_need_to_destroy_t)dlsym(item->handle, "livebox_need_to_destroy");
+       if (!item->adaptor.need_to_destroy)
+               ErrPrint("symbol: livebox_need_to_destroy - %s\n", dlerror());
+
+       if (item->adaptor.initialize) {
+               int ret;
+               fault_mark_call(pkgname, "initialize", __func__);
+               ret = item->adaptor.initialize(pkgname);
+               fault_unmark_call(pkgname, "initialize", __func__);
+               if (ret < 0) {
+                       ErrPrint("Failed to initialize package %s\n", pkgname);
+                       delete_livebox(item);
+                       return NULL;
+               }
+       }
+
+       s_info.livebox_list = eina_list_append(s_info.livebox_list, item);
+       return item;
+}
+
 static struct so_item *new_livebox(const char *pkgname)
 {
        struct so_item *item;
        char *livebox_path;
 
-       item = malloc(sizeof(*item));
+       item = calloc(1, sizeof(*item));
        if (!item) {
                ErrPrint("Memory: %s\n", strerror(errno));
                return NULL;
@@ -128,68 +264,68 @@ static struct so_item *new_livebox(const char *pkgname)
        fault_unmark_call(pkgname, __func__, __func__);
        free(livebox_path);
 
-       item->create = (create_t)dlsym(item->handle, "livebox_create");
-       if (!item->create) {
+       item->livebox.create = (create_t)dlsym(item->handle, "livebox_create");
+       if (!item->livebox.create) {
                ErrPrint("symbol: livebox_create - %s\n", dlerror());
                delete_livebox(item);
                return NULL;
        }
 
-       item->destroy = (destroy_t)dlsym(item->handle, "livebox_destroy");
-       if (!item->destroy) {
+       item->livebox.destroy = (destroy_t)dlsym(item->handle, "livebox_destroy");
+       if (!item->livebox.destroy) {
                ErrPrint("symbol: livebox_destroy - %s\n", dlerror());
                delete_livebox(item);
                return NULL;
        }
 
-       item->is_updated = (is_updated_t)dlsym(item->handle, "livebox_need_to_update");
-       if (!item->is_updated)
+       item->livebox.is_updated = (is_updated_t)dlsym(item->handle, "livebox_need_to_update");
+       if (!item->livebox.is_updated)
                ErrPrint("symbol: livebox_need_to_update - %s\n", dlerror());
 
-       item->update_content = (update_content_t)dlsym(item->handle, "livebox_update_content");
-       if (!item->update_content)
+       item->livebox.update_content = (update_content_t)dlsym(item->handle, "livebox_update_content");
+       if (!item->livebox.update_content)
                ErrPrint("symbol: livebox_update_content - %s\n", dlerror());
 
-       item->clicked = (clicked_t)dlsym(item->handle, "livebox_clicked");
-       if (!item->clicked)
+       item->livebox.clicked = (clicked_t)dlsym(item->handle, "livebox_clicked");
+       if (!item->livebox.clicked)
                ErrPrint("symbol: livebox_clicked - %s\n", dlerror());
 
-       item->script_event = (script_t)dlsym(item->handle, "livebox_content_event");
-       if (!item->script_event)
+       item->livebox.script_event = (script_t)dlsym(item->handle, "livebox_content_event");
+       if (!item->livebox.script_event)
                ErrPrint("symbol: livebox_content_event - %s\n", dlerror());
 
-       item->resize = (resize_t)dlsym(item->handle, "livebox_resize");
-       if (!item->resize)
+       item->livebox.resize = (resize_t)dlsym(item->handle, "livebox_resize");
+       if (!item->livebox.resize)
                ErrPrint("symbol: livebox_resize - %s\n", dlerror());
 
-       item->create_needed = (create_needed_t)dlsym(item->handle, "livebox_need_to_create");
-       if (!item->create_needed)
+       item->livebox.create_needed = (create_needed_t)dlsym(item->handle, "livebox_need_to_create");
+       if (!item->livebox.create_needed)
                ErrPrint("symbol: livebox_need_to_create - %s\n", dlerror());
 
-       item->change_group = (change_group_t)dlsym(item->handle, "livebox_change_group");
-       if (!item->change_group)
+       item->livebox.change_group = (change_group_t)dlsym(item->handle, "livebox_change_group");
+       if (!item->livebox.change_group)
                ErrPrint("symbol: livebox_change_group - %s\n", dlerror());
 
-       item->get_output_info = (get_output_info_t)dlsym(item->handle, "livebox_get_info");
-       if (!item->get_output_info)
+       item->livebox.get_output_info = (get_output_info_t)dlsym(item->handle, "livebox_get_info");
+       if (!item->livebox.get_output_info)
                ErrPrint("symbol: livebox_get_info - %s\n", dlerror());
 
-       item->initialize = (initialize_t)dlsym(item->handle, "livebox_initialize");
-       if (!item->initialize)
+       item->livebox.initialize = (initialize_t)dlsym(item->handle, "livebox_initialize");
+       if (!item->livebox.initialize)
                ErrPrint("symbol: livebox_initialize - %s\n", dlerror());
 
-       item->finalize = (finalize_t)dlsym(item->handle, "livebox_finalize");
-       if (!item->finalize)
+       item->livebox.finalize = (finalize_t)dlsym(item->handle, "livebox_finalize");
+       if (!item->livebox.finalize)
                ErrPrint("symbol: livebox_finalize - %s\n", dlerror());
 
-       item->need_to_destroy = (need_to_destroy_t)dlsym(item->handle, "livebox_need_to_destroy");
-       if (!item->need_to_destroy)
+       item->livebox.need_to_destroy = (need_to_destroy_t)dlsym(item->handle, "livebox_need_to_destroy");
+       if (!item->livebox.need_to_destroy)
                ErrPrint("symbol: livebox_need_to_destroy - %s\n", dlerror());
 
-       if (item->initialize) {
+       if (item->livebox.initialize) {
                int ret;
                fault_mark_call(pkgname, "initialize", __func__);
-               ret = item->initialize();
+               ret = item->livebox.initialize(pkgname);
                fault_unmark_call(pkgname, "initialize", __func__);
                if (ret < 0) {
                        ErrPrint("Failed to initialize package %s\n", pkgname);
@@ -297,7 +433,7 @@ struct instance *so_find_instance(const char *pkgname, const char *filename)
        return find_instance(item, filename);
 }
 
-int so_create(const char *pkgname, const char *filename, const char *content_info, int timeout, int has_livebox_script, const char *cluster, const char *category, struct instance **out)
+int so_create(const char *pkgname, const char *filename, const char *content_info, int timeout, int has_livebox_script, const char *cluster, const char *category, const char *abi, struct instance **out)
 {
        struct so_item *item;
        struct instance *inst;
@@ -311,7 +447,10 @@ int so_create(const char *pkgname, const char *filename, const char *content_inf
                        return -EEXIST;
                }
        } else {
-               item = new_livebox(pkgname);
+               if (!strcasecmp(abi, "c"))
+                       item = new_livebox(pkgname);
+               else
+                       item = new_adaptor(pkgname, abi);
                if (!item)
                        return -EFAULT;
        }
@@ -333,7 +472,14 @@ int so_create(const char *pkgname, const char *filename, const char *content_inf
 
        fault_mark_call(pkgname, filename, __func__);
        heap_hook(item->heap);
-       ret = item->create(filename, content_info, cluster, category);
+       if (item->adaptor.create) {
+               ret = item->adaptor.create(pkgname, filename, content_info, cluster, category);
+       } else if (item->livebox.create) {
+               ret = item->livebox.create(filename, content_info, cluster, category);
+       } else {
+               /*! \NOTE: This is not possible, but for the exceptional handling */
+               ret = -ENOSYS;
+       }
        heap_unhook(item->heap);
        fault_unmark_call(pkgname, filename, __func__);
        DbgPrint("%s create returns %d\n", pkgname, ret);
@@ -366,7 +512,13 @@ int so_destroy(struct instance *inst)
 
        fault_mark_call(item->pkgname, inst->filename, __func__);
        heap_hook(item->heap);
-       ret = item->destroy(inst->filename);
+       if (item->adaptor.destroy) {
+               ret = item->adaptor.destroy(item->pkgname, inst->filename);
+       } else if (item->livebox.destroy) {
+               ret = item->livebox.destroy(inst->filename);
+       } else {
+               ret = -ENOSYS;
+       }
        heap_unhook(item->heap);
        fault_unmark_call(item->pkgname, inst->filename, __func__);
        DbgPrint("%s destroy retusn %d [HEAP: %lu]\n", item->pkgname, ret, heap_usage(item->heap));
@@ -394,12 +546,15 @@ int so_is_updated(struct instance *inst)
        if (!item)
                return -EINVAL;
 
-       if (!item->is_updated)
-               return -ENOSYS;
-
        fault_mark_call(item->pkgname, inst->filename, __func__);
        heap_hook(item->heap);
-       ret = item->is_updated(inst->filename);
+       if (item->adaptor.is_updated) {
+               ret = item->adaptor.is_updated(item->pkgname, inst->filename);
+       } else if (item->livebox.is_updated) {
+               ret = item->livebox.is_updated(inst->filename);
+       } else {
+               ret = -ENOSYS;
+       }
        heap_unhook(item->heap);
        fault_unmark_call(item->pkgname, inst->filename, __func__);
        DbgPrint("%s is_updated returns %d\n", item->pkgname, ret);
@@ -416,12 +571,15 @@ int so_need_to_destroy(struct instance *inst)
        if (!item)
                return -EINVAL;
 
-       if (!item->need_to_destroy)
-               return -ENOSYS;
-
        fault_mark_call(item->pkgname, inst->filename, __func__);
        heap_hook(item->heap);
-       ret = item->need_to_destroy(inst->filename);
+       if (item->adaptor.need_to_destroy) {
+               ret = item->adaptor.need_to_destroy(item->pkgname, inst->filename);
+       } else if (item->livebox.need_to_destroy) {
+               ret = item->livebox.need_to_destroy(inst->filename);
+       } else {
+               ret = -ENOSYS;
+       }
        heap_unhook(item->heap);
        fault_unmark_call(item->pkgname, inst->filename, __func__);
        DbgPrint("%s need_to_destroy returns %d\n", item->pkgname, ret);
@@ -438,11 +596,14 @@ int so_update(struct instance *inst)
        if (!item)
                return -EINVAL;
 
-       if (!item->update_content)
-               return -ENOSYS;
-
        fault_mark_call(item->pkgname, inst->filename, __func__);
-       ret = item->update_content(inst->filename);
+       if (item->adaptor.update_content) {
+               ret = item->adaptor.update_content(item->pkgname, inst->filename);
+       } else if (item->livebox.update_content) {
+               ret = item->livebox.update_content(inst->filename);
+       } else {
+               ret = -ENOSYS;
+       }
        fault_unmark_call(item->pkgname, inst->filename, __func__);
        DbgPrint("%s update_content returns %d\n", item->pkgname, ret);
 
@@ -458,12 +619,15 @@ int so_clicked(struct instance *inst, const char *event, double timestamp, doubl
        if (!item)
                return -EINVAL;
 
-       if (!item->clicked)
-               return -ENOSYS;
-
        fault_mark_call(item->pkgname, inst->filename, __func__);
        heap_hook(item->heap);
-       ret = item->clicked(inst->filename, event, timestamp, x, y);
+       if (item->adaptor.clicked) {
+               ret = item->adaptor.clicked(item->pkgname, inst->filename, event, timestamp, x, y);
+       } else if (item->livebox.clicked) {
+               ret = item->livebox.clicked(inst->filename, event, timestamp, x, y);
+       } else {
+               ret = -ENOSYS;
+       }
        heap_unhook(item->heap);
        fault_unmark_call(item->pkgname, inst->filename, __func__);
        DbgPrint("%s clicked returns %d\n", item->pkgname, ret);
@@ -480,13 +644,16 @@ int so_script_event(struct instance *inst, const char *emission, const char *sou
        if (!item)
                return -EINVAL;
 
-       if (!item->script_event)
-               return -ENOSYS;
-
        DbgPrint("event_info: %p\n", event_info);
        fault_mark_call(item->pkgname, inst->filename, __func__);
        heap_hook(item->heap);
-       ret = item->script_event(inst->filename, emission, source, event_info);
+       if (item->adaptor.script_event) {
+               ret = item->adaptor.script_event(item->pkgname, inst->filename, emission, source, event_info);
+       } else if (item->livebox.script_event) {
+               ret = item->livebox.script_event(inst->filename, emission, source, event_info);
+       } else {
+               ret = -ENOSYS;
+       }
        heap_unhook(item->heap);
        fault_unmark_call(item->pkgname, inst->filename, __func__);
        DbgPrint("%s script_event returns %d\n", item->pkgname, ret);
@@ -503,12 +670,15 @@ int so_resize(struct instance *inst, int w, int h)
        if (!item)
                return -EINVAL;
 
-       if (!item->resize)
-               return -ENOSYS;
-       
        fault_mark_call(item->pkgname, inst->filename, __func__);
        heap_hook(item->heap);
-       ret = item->resize(inst->filename, w, h);
+       if (item->adaptor.resize) {
+               ret = item->adaptor.resize(item->pkgname, inst->filename, w, h);
+       } else if (item->livebox.resize) {
+               ret = item->livebox.resize(inst->filename, w, h);
+       } else {
+               ret = -ENOSYS;
+       }
        heap_unhook(item->heap);
        fault_unmark_call(item->pkgname, inst->filename, __func__);
        DbgPrint("%s resize returns %d\n", item->pkgname, ret);
@@ -516,24 +686,30 @@ int so_resize(struct instance *inst, int w, int h)
        return ret;
 }
 
-int so_create_needed(const char *pkgname, const char *cluster, const char *category)
+int so_create_needed(const char *pkgname, const char *cluster, const char *category, const char *abi)
 {
        struct so_item *item;
        int ret;
 
        item = find_livebox(pkgname);
        if (!item) {
-               item = new_livebox(pkgname);
+               if (!strcasecmp(abi, "c"))
+                       item = new_livebox(pkgname);
+               else
+                       item = new_adaptor(pkgname, abi);
                if (!item)
                        return -EFAULT;
        }
 
-       if (!item->create_needed)
-               return -ENOSYS;
-
        fault_mark_call(item->pkgname, __func__, __func__);
        heap_hook(item->heap);
-       ret = item->create_needed(cluster, category);
+       if (item->adaptor.create_needed) {
+               ret = item->adaptor.create_needed(pkgname, cluster, category);
+       } else if (item->livebox.create_needed) {
+               ret = item->livebox.create_needed(cluster, category);
+       } else {
+               ret = -ENOSYS;
+       }
        heap_unhook(item->heap);
        fault_unmark_call(item->pkgname, __func__, __func__);
        DbgPrint("%s create_needed returns %d\n", pkgname, ret);
@@ -552,9 +728,6 @@ int so_change_group(struct instance *inst, const char *cluster, const char *cate
        if (!item)
                return -EINVAL;
 
-       if (!item->change_group)
-               return -ENOSYS;
-
        tmp_cluster = strdup(cluster);
        if (!tmp_cluster)
                return -ENOMEM;
@@ -567,7 +740,13 @@ int so_change_group(struct instance *inst, const char *cluster, const char *cate
 
        fault_mark_call(item->pkgname, inst->filename, __func__);
        heap_hook(item->heap);
-       ret = item->change_group(inst->filename, cluster, category);
+       if (item->adaptor.change_group) {
+               ret = item->adaptor.change_group(item->pkgname, inst->filename, cluster, category);
+       } else if (item->livebox.change_group) {
+               ret = item->livebox.change_group(inst->filename, cluster, category);
+       } else {
+               ret = -ENOSYS;
+       }
        heap_unhook(item->heap);
        fault_unmark_call(item->pkgname, inst->filename, __func__);
        DbgPrint("%s change group returns %d\n", item->pkgname, ret);
@@ -594,12 +773,15 @@ int so_get_output_info(struct instance *inst, int *w, int *h, double *priority)
        if (!item)
                return -EINVAL;
 
-       if (!item->get_output_info)
-               return -ENOSYS;
-
        fault_mark_call(item->pkgname, inst->filename, __func__);
        heap_hook(item->heap);
-       ret = item->get_output_info(inst->filename, w, h, priority);
+       if (item->adaptor.get_output_info) {
+               ret = item->adaptor.get_output_info(item->pkgname, inst->filename, w, h, priority);
+       } else if (item->livebox.get_output_info) {
+               ret = item->livebox.get_output_info(inst->filename, w, h, priority);
+       } else {
+               ret = -ENOSYS;
+       }
        heap_unhook(item->heap);
        fault_unmark_call(item->pkgname, inst->filename, __func__);
        DbgPrint("%s get_output_info returns %d\n", item->pkgname, ret);