Fix the bug of image & script file loader.
authorSung-jae Park <nicesj.park@samsung.com>
Tue, 18 Dec 2012 04:34:45 +0000 (13:34 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Tue, 18 Dec 2012 06:24:24 +0000 (15:24 +0900)
If the image/script file path is not valid, stop to load it.

Change-Id: Ibd042d39cde41c5fed00666f8c723f5a5adf084e

packaging/liblivebox-edje.spec
src/script_port.c

index a9f0e11..f00bc3f 100644 (file)
@@ -1,6 +1,6 @@
 Name: liblivebox-edje
 Summary: EDJE Script loader for the data provider master
-Version: 0.1.14
+Version: 0.1.15
 Release: 1
 Group: main/app
 License: Samsung Proprietary License
index ef1fe56..c1f2b60 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <libgen.h>
 #include <errno.h>
+#include <unistd.h>
 
 #include <Evas.h>
 #include <Edje.h>
@@ -34,6 +35,16 @@ struct info {
        Eina_List *obj_list;
 };
 
+struct child {
+       Evas_Object *obj;
+       char *part;
+};
+
+struct obj_info {
+       char *id;
+       Eina_List *children;
+};
+
 struct {
        Ecore_Event_Handler *property_handler;
        char *font;
@@ -84,20 +95,25 @@ static inline Evas_Object *find_edje(struct info *handle, const char *id)
 {
        Eina_List *l;
        Evas_Object *edje;
-       const char *edje_id;
+       struct obj_info *obj_info;
 
        EINA_LIST_FOREACH(handle->obj_list, l, edje) {
-               edje_id = evas_object_data_get(edje, "edje,id");
+               obj_info = evas_object_data_get(edje, "obj_info");
+               if (!obj_info) {
+                       ErrPrint("Object info is not valid\n");
+                       continue;
+               }
+
                if (!id) {
-                       if (!edje_id)
+                       if (!obj_info->id)
                                return edje;
 
                        continue;
-               } else if (!edje_id) {
+               } else if (!obj_info->id) {
                        continue;
                }
 
-               if (!strcmp(edje_id, id))
+               if (!strcmp(obj_info->id, id))
                        return edje;
        }
 
@@ -130,30 +146,79 @@ int script_update_image(void *_h, Evas *e, const char *id, const char *part, con
        Evas_Object *edje;
        Evas_Object *img;
        Evas_Coord w, h;
+       struct obj_info *obj_info;
+       struct child *child;
 
        edje = find_edje(handle, id);
-       if (!edje)
+       if (!edje) {
+               ErrPrint("No such object: %s\n", id);
                return -ENOENT;
+       }
+
+       obj_info = evas_object_data_get(edje, "obj_info");
+       if (!obj_info) {
+               ErrPrint("Object info is not available\n");
+               return -EFAULT;
+       }
 
        img = edje_object_part_swallow_get(edje, part);
        if (img) {
+               Eina_List *l;
+               Eina_List *n;
+
                edje_object_part_unswallow(edje, img);
+
+               EINA_LIST_FOREACH_SAFE(obj_info->children, l, n, child) {
+                       if (child->obj != img)
+                               continue;
+
+                       obj_info->children = eina_list_remove(obj_info->children, child);
+                       free(child->part);
+                       free(child);
+                       break;
+               }
+
+               DbgPrint("delete object %s %p\n", part, img);
                evas_object_del(img);
        }
 
-       if (!path)
+       if (!path || !strlen(path) || access(path, R_OK) != 0) {
+               DbgPrint("SKIP - Path: [%s]\n", path);
                return 0;
+       }
+
+       child = malloc(sizeof(*child));
+       if (!child) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return -ENOMEM;
+       }
+
+       child->part = strdup(part);
+       if (!child->part) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               free(child);
+               return -ENOMEM;
+       }
 
        img = evas_object_image_filled_add(e);
        if (!img) {
                ErrPrint("Failed to add an image object\n");
+               free(child->part);
+               free(child);
                return -EFAULT;
        }
 
+       child->obj = img;
+
        evas_object_image_file_set(img, path, NULL);
        err = evas_object_image_load_error_get(img);
-       if (err != EVAS_LOAD_ERROR_NONE)
+       if (err != EVAS_LOAD_ERROR_NONE) {
                ErrPrint("Load error: %s\n", evas_load_error_str(err));
+               evas_object_del(img);
+               free(child->part);
+               free(child);
+               return -EIO;
+       }
 
        evas_object_image_size_get(img, &w, &h);
        evas_object_image_fill_set(img, 0, 0, w, h);
@@ -165,7 +230,10 @@ int script_update_image(void *_h, Evas *e, const char *id, const char *part, con
         * \note
         * object will be shown by below statement automatically
         */
+       DbgPrint("%s part swallow image %p\n", part, img);
        edje_object_part_swallow(edje, part, img);
+       obj_info->children = eina_list_append(obj_info->children, child);
+
        return 0;
 }
 
@@ -205,15 +273,31 @@ static void script_signal_cb(void *data, Evas_Object *obj, const char *emission,
 static void edje_del_cb(void *_info, Evas *e, Evas_Object *obj, void *event_info)
 {
        struct info *handle = _info;
-       char *id;
+       struct obj_info *obj_info;
+       struct child *child;
 
        handle->obj_list = eina_list_remove(handle->obj_list, obj);
 
-       id = evas_object_data_del(obj, "edje,id");
-       if (!id)
-               edje_object_signal_callback_del_full(obj, "*", "*", script_signal_cb, handle);
-       else
-               free(id);
+       obj_info = evas_object_data_del(obj, "obj_info");
+       if (!obj_info) {
+               ErrPrint("Object info is not valid\n");
+               return;
+       }
+
+       DbgPrint("delete object %s %p\n", obj_info->id, obj);
+
+       edje_object_signal_callback_del_full(obj, "*", "*", script_signal_cb, handle);
+
+       EINA_LIST_FREE(obj_info->children, child) {
+               DbgPrint("delete object %s %p\n", child->part, child->obj);
+               if (child->obj)
+                       evas_object_del(child->obj);
+               free(child->part);
+               free(child);
+       }
+
+       free(obj_info->id);
+       free(obj_info);
 }
 
 int script_update_script(void *h, Evas *e, const char *src_id, const char *target_id, const char *part, const char *path, const char *group)
@@ -221,22 +305,48 @@ int script_update_script(void *h, Evas *e, const char *src_id, const char *targe
        struct info *handle = h;
        Evas_Object *edje;
        Evas_Object *obj;
-       char *id_str;
+       struct obj_info *obj_info;
+       struct child *child;
 
        DbgPrint("src_id[%s] target_id[%s] part[%s] path[%s] group[%s]\n", src_id, target_id, part, path, group);
 
        edje = find_edje(handle, src_id);
-       if (!edje)
+       if (!edje) {
+               ErrPrint("Edje is not exists\n");
                return -ENOENT;
+       }
+
+       obj_info = evas_object_data_get(edje, "obj_info");
+       if (!obj_info) {
+               ErrPrint("Object info is not valid\n");
+               return -EINVAL;
+       }
 
        obj = edje_object_part_swallow_get(edje, part);
        if (obj) {
+               Eina_List *l;
+               Eina_List *n;
+
                edje_object_part_unswallow(edje, obj);
+
+               EINA_LIST_FOREACH_SAFE(obj_info->children, l, n, child) {
+                       if (child->obj != obj)
+                               continue;
+
+                       obj_info->children = eina_list_remove(obj_info->children, child);
+                       free(child->part);
+                       free(child);
+                       break;
+               }
+
+               DbgPrint("delete object %s %p\n", part, obj);
                evas_object_del(obj);
        }
 
-       if (!path)
+       if (!path || !strlen(path) || access(path, R_OK) != 0) {
+               DbgPrint("SKIP - Path: [%s]\n", path);
                return 0;
+       }
 
        obj = edje_object_add(e);
        if (!obj) {
@@ -258,20 +368,51 @@ int script_update_script(void *h, Evas *e, const char *src_id, const char *targe
 
        evas_object_show(obj);
 
-       id_str = strdup(target_id);
-       if (!id_str) {
+       obj_info = calloc(1, sizeof(*obj_info));
+       if (!obj_info) {
+               ErrPrint("Failed to add a obj_info\n");
+               evas_object_del(obj);
+               return -ENOMEM;
+       }
+
+       obj_info->id = strdup(target_id);
+       if (!obj_info->id) {
+               ErrPrint("Failed to add a obj_info\n");
+               free(obj_info);
+               evas_object_del(obj);
+               return -ENOMEM;
+       }
+
+       child = malloc(sizeof(*child));
+       if (!child) {
+               ErrPrint("Error: %s\n", strerror(errno));
+               free(obj_info->id);
+               free(obj_info);
+               evas_object_del(obj);
+               return -ENOMEM;
+       }
+
+       child->part = strdup(part);
+       if (!child->part) {
                ErrPrint("Error: %s\n", strerror(errno));
+               free(child);
+               free(obj_info->id);
+               free(obj_info);
                evas_object_del(obj);
                return -ENOMEM;
        }
 
-       evas_object_data_set(obj, "edje,id", id_str);
+       child->obj = obj;
+
+       evas_object_data_set(obj, "obj_info", obj_info);
        evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, edje_del_cb, handle);
        edje_object_signal_callback_add(obj, "*", "*", script_signal_cb, handle);
        handle->obj_list = eina_list_append(handle->obj_list, obj);
 
-       DbgPrint("Swallow to %s\n", obj, part);
+       DbgPrint("%s part swallow edje %p\n", part, obj);
        edje_object_part_swallow(edje, part, obj);
+       obj_info = evas_object_data_get(edje, "obj_info");
+       obj_info->children = eina_list_append(obj_info->children, child);
        return 0;
 }
 
@@ -384,9 +525,9 @@ int script_destroy(void *_handle)
 
        handle = _handle;
 
-       EINA_LIST_FREE(handle->obj_list, edje) {
+       edje = eina_list_nth(handle->obj_list, 0);
+       if (edje)
                evas_object_del(edje);
-       }
 
        free(handle->category);
        free(handle->file);
@@ -399,12 +540,20 @@ int script_load(void *_handle, Evas *e, int w, int h)
 {
        struct info *handle;
        Evas_Object *edje;
+       struct obj_info *obj_info;
 
        handle = _handle;
 
+       obj_info = calloc(1, sizeof(*obj_info));
+       if (!obj_info) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return -ENOMEM;
+       }
+
        edje = edje_object_add(e);
        if (!edje) {
                ErrPrint("Failed to create an edje object\n");
+               free(obj_info);
                return -EFAULT;
        }
 
@@ -418,6 +567,7 @@ int script_load(void *_handle, Evas *e, int w, int h)
                errmsg = edje_load_error_str(err);
                ErrPrint("Could not load %s from %s: %s\n", handle->group, handle->file, errmsg);
                evas_object_del(edje);
+               free(obj_info);
                return -EIO;
        }
 
@@ -431,6 +581,7 @@ int script_load(void *_handle, Evas *e, int w, int h)
        evas_object_size_hint_fill_set(edje, EVAS_HINT_FILL, EVAS_HINT_FILL);
        evas_object_resize(edje, handle->w, handle->h);
        evas_object_show(edje);
+       evas_object_data_set(edje, "obj_info", obj_info);
 
        handle->obj_list = eina_list_append(handle->obj_list, edje);
        return 0;
@@ -439,22 +590,14 @@ int script_load(void *_handle, Evas *e, int w, int h)
 int script_unload(void *_handle, Evas *e)
 {
        struct info *handle;
-       Eina_List *l;
-       Eina_List *n;
        Evas_Object *edje;
 
        handle = _handle;
 
        DbgPrint("Unload edje: %s - %s\n", handle->file, handle->group);
-
-       EINA_LIST_FOREACH_SAFE(handle->obj_list, l, n, edje) {
-               /*!
-                * \note
-                * edje_del_cb will remove this node from the list
-                */
+       edje = eina_list_nth(handle->obj_list, 0);
+       if (edje)
                evas_object_del(edje);
-       }
-
        handle->e = NULL;
        return 0;
 }