Update the icon service reuqest codes.
authorSung-jae Park <nicesj.park@samsung.com>
Thu, 9 May 2013 04:45:18 +0000 (13:45 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Thu, 9 May 2013 05:31:14 +0000 (14:31 +0900)
APIs are changed.

Change-Id: Icb5343dfcdd3e6ad6a70ed393d977bffab53aca0

lib/include/shortcut.h
lib/src/icon.c
packaging/libshortcut.spec
test/icon.c [new file with mode: 0644]

index 6e0496a..740698e 100644 (file)
@@ -36,6 +36,7 @@ extern "C" {
  *        The others for the application developers who should implement the Add to home feature.
  */
 
+struct shortcut_icon;
 /**
  * @brief This function prototype is used to define a callback function for the add_to_home reqeust.
  *        The homescreen should define a callback as this type and implementing the service code
@@ -70,6 +71,8 @@ typedef int (*request_cb_t)(const char *appid, const char *name, int type, const
  */
 typedef int (*result_cb_t)(int ret, int pid, void *data);
 
+typedef int (*icon_request_cb_t)(struct shortcut_icon *handle, int ret, void *data);
+
 /**
  * @brief Basically, three types of shortcut is defined.
  *        Every homescreen developer should support these types of shortcut.
@@ -274,50 +277,81 @@ extern int add_to_home_remove_livebox(const char *appid, const char *name, resul
  * \note
  * Example)
  *
- * // Initialize the service request
- * int ret;
- *
- * ret = shortcut_icon_init(init_cb, NULL);
- * if (ret < 0) {
- *    ...
+ * static int init_cb(int status, void *data)
+ * {
+ *    printf("Initializer returns: %d\n", status);
+ *    if (status == 0) {
+ *        printf("Succeed to initialize\n");
+ *    } else {
+ *        printf("Failed to initialize: %d\n", status);
+ *    }
  * }
  *
- * // After the init_cb is called, you can use below functions.
- * struct shortcut_icon *handle;
+ * int main(int argc, char *argv[])
+ * {
+ *     // Initialize the service request
+ *     int ret;
  *
- * // Create request for creating shortcut icon.
- * handle = shortcut_icon_create(LIVEBOX_TYPE_1x1, "/opt/usr/apps/org.tizen.cluster-home/data/shortcut/app1.png", NULL, NULL);
- * if (!handle) {
- *    ...
- * }
- * 
- * // Send the request to the shortcut service
- * ret = shortcut_icon_request_and_destroy(handle, result_cb, NULL);
- * if (ret < 0) {
- *    ...
- * }
+ *     // After the init_cb is called, you can use below functions.
+ *     struct shortcut_icon *handle;
  *
- * // Don't finalize the icon service if you don't get result callbacks of all requests
- * ret = shortcut_icon_fini();
- * if (ret < 0) {
- *    ...
- * }
+ *     ret = shortcut_icon_init(init_cb, NULL);
+ *     if (ret < 0) {
+ *        ...
  *
+ *     // Create request for creating shortcut icon.
+ *     handle = shortcut_icon_create();
+ *     if (!handle) {
+ *         ...
+ *     }
+ * 
+ *     // Send the request to the shortcut service
+ *     ret = shortcut_icon_request_set_info(handle, NULL, SHORTCUT_ICON_TYPE_IMAGE, "/usr/share/.../icon.png", NULL, NULL);
+ *     if (ret < 0) {
+ *        ...
+ *     }
+ *
+ *     ret = shortcut_icon_request_set_info(handle, NULL, SHORTCUT_ICON_TYPE_TEXT, "app icon", NULL, NULL);
+ *     if (ret < 0) {
+ *        ...
+ *     }
+ *
+ *     ret = shortcut_icon_request_send(handle, LB_SIZE_TYPE_1x1, NULL, NULL, "/opt/usr/apps/com.samsung.cluster-home/data/out.png", result_cb, NULL);
+ *     if (ret < 0) {
+ *        ...
+ *     }
+ *
+ *     ret = shortcut_icon_request_destroy(handle);
+ *     if (ret < 0) {
+ *        ...
+ *     }
+ *
+ *     // Don't finalize the icon service if you don't get result callbacks of all requests
+ *     ret = shortcut_icon_fini();
+ *     if (ret < 0) {
+ *        ...
+ *     }
+ *
+ *     return 0;
+ * }
  */
 
-struct shortcut_icon;
 #define DEFAULT_ICON_PART              "icon"
 #define DEFAULT_NAME_PART              "name"
 #define SHORTCUT_ICON_TYPE_IMAGE       "image"
 #define SHORTCUT_ICON_TYPE_TEXT                "text"
 #define SHORTCUT_ICON_TYPE_SCRIPT      "script"
-extern int shortcut_icon_service_init(int (*initialized_cb)(int status, void *data), void *data);
+
+extern int shortcut_icon_service_init(int (*init_cb)(int status, void *data), void *data);
 extern int shortcut_icon_service_fini(void);
 
-extern struct shortcut_icon *shortcut_icon_request_create(int size_type, const char *output, const char *layout, const char *group);
+extern struct shortcut_icon *shortcut_icon_request_create(void);
 extern int shortcut_icon_request_set_info(struct shortcut_icon *handle, const char *id, const char *type, const char *part, const char *data, const char *option, const char *subid);
-extern int shortcut_icon_request_send_and_destroy(struct shortcut_icon *handle, result_cb_t result_cb, void *data);
+extern int shortcut_icon_request_send(struct shortcut_icon *handle, int size_type, const char *layout, const char *group, const char *outfile, icon_request_cb_t result_cb, void *data);
+extern int shortcut_icon_request_destroy(struct shortcut_icon *handle);
 
+extern int shortcut_icon_request_set_data(struct shortcut_icon *handle, void *data);
+extern void *shortcut_icon_request_data(struct shortcut_icon *handle);
 
 #ifdef __cplusplus
 }
index 6327544..c29445b 100644 (file)
 
 
 
+#define CREATED        0x00BEEF00
+#define DESTROYED 0x00DEAD00
+
+
 static struct info {
        int fd;
        int (*init_cb)(int status, void *data);
@@ -61,7 +65,8 @@ static struct info {
 
 
 struct request_item {
-       result_cb_t result_cb;
+       struct shortcut_icon *handle;
+       icon_request_cb_t result_cb;
        void *data;
 };
 
@@ -82,27 +87,22 @@ struct block {
        char *data;
        char *option;
        char *id;
-       char *file;
        char *target_id;
 };
 
 
 
 struct shortcut_icon {
+       unsigned int state;
        struct shortcut_desc *desc;
-       char *layout;
-       char *output;
-       char *descfile;
-       char *group;
-       int size_type;
+       int refcnt;
+       void *data;
 };
 
 
 
 struct shortcut_desc {
-       FILE *fp;
        int for_pd;
-       char *filename;
 
        unsigned int last_idx;
 
@@ -111,6 +111,63 @@ struct shortcut_desc {
 
 
 
+static inline void delete_block(struct block *block)
+{
+       DbgPrint("Release block: %p\n", block);
+       free(block->type);
+       free(block->part);
+       free(block->data);
+       free(block->option);
+       free(block->id);
+       free(block->target_id);
+       free(block);
+}
+
+
+
+static inline int shortcut_icon_desc_close(struct shortcut_desc *handle)
+{
+       struct dlist *l;
+       struct dlist *n;
+       struct block *block;
+
+       dlist_foreach_safe(handle->block_list, l, n, block) {
+               handle->block_list = dlist_remove(handle->block_list, l);
+               delete_block(block);
+       }
+
+       free(handle);
+       return 0;
+}
+
+
+
+static inline struct shortcut_icon *shortcut_icon_request_unref(struct shortcut_icon *handle)
+{
+       handle->refcnt--;
+       DbgPrint("Handle: refcnt[%d]\n", handle->refcnt);
+
+       if (handle->refcnt == 0) {
+               handle->state = DESTROYED;
+               shortcut_icon_desc_close(handle->desc);
+               free(handle);
+               handle = NULL;
+       }
+
+       return handle;
+}
+
+
+
+static inline struct shortcut_icon *shortcut_icon_request_ref(struct shortcut_icon *handle)
+{
+       handle->refcnt++;
+       DbgPrint("Handle: refcnt[%d]\n", handle->refcnt);
+       return handle;
+}
+
+
+
 static int disconnected_cb(int handle, void *data)
 {
        if (s_info.fd != handle)
@@ -126,7 +183,7 @@ static int disconnected_cb(int handle, void *data)
 
 
 
-static inline struct shortcut_desc *shortcut_icon_desc_open(const char *filename)
+static inline struct shortcut_desc *shortcut_icon_desc_open(void)
 {
        struct shortcut_desc *handle;
 
@@ -136,128 +193,124 @@ static inline struct shortcut_desc *shortcut_icon_desc_open(const char *filename
                return NULL;
        }
 
-       handle->filename = strdup(filename);
-       if (!handle->filename) {
-               ErrPrint("Heap: %s\n", strerror(errno));
-               free(handle);
-               return NULL;
-       }
-
-       handle->fp = fopen(handle->filename, "w+");
-       if (!handle->fp) {
-               ErrPrint("Failed to open a file: %s\n", strerror(errno));
-               free(handle->filename);
-               free(handle);
-               return NULL;
-       }
-
        return handle;
 }
 
 
 
-static inline int shortcut_icon_desc_close(struct shortcut_desc *handle)
+static inline int shortcut_icon_desc_save(struct shortcut_desc *handle, const char *filename)
 {
        struct dlist *l;
        struct dlist *n;
        struct block *block;
+       FILE *fp;
 
        if (!handle)
                return -EINVAL;
 
+       fp = fopen(filename, "w+t");
+       if (!fp) {
+               ErrPrint("Error: %s\n", strerror(errno));
+               return -EIO;
+       }
+
        DbgPrint("Close and flush\n");
        dlist_foreach_safe(handle->block_list, l, n, block) {
-               handle->block_list = dlist_remove(handle->block_list, l);
-
                DbgPrint("{\n");
-               fprintf(handle->fp, "{\n");
+               fprintf(fp, "{\n");
                if (block->type) {
-                       fprintf(handle->fp, "type=%s\n", block->type);
+                       fprintf(fp, "type=%s\n", block->type);
                        DbgPrint("type=%s\n", block->type);
                }
 
                if (block->part) {
-                       fprintf(handle->fp, "part=%s\n", block->part);
+                       fprintf(fp, "part=%s\n", block->part);
                        DbgPrint("part=%s\n", block->part);
                }
 
                if (block->data) {
-                       fprintf(handle->fp, "data=%s\n", block->data);
+                       fprintf(fp, "data=%s\n", block->data);
                        DbgPrint("data=%s\n", block->data);
                }
 
                if (block->option) {
-                       fprintf(handle->fp, "option=%s\n", block->option);
+                       fprintf(fp, "option=%s\n", block->option);
                        DbgPrint("option=%s\n", block->option);
                }
 
                if (block->id) {
-                       fprintf(handle->fp, "id=%s\n", block->id);
+                       fprintf(fp, "id=%s\n", block->id);
                        DbgPrint("id=%s\n", block->id);
                }
 
                if (block->target_id) {
-                       fprintf(handle->fp, "target=%s\n", block->target_id);
+                       fprintf(fp, "target=%s\n", block->target_id);
                        DbgPrint("target=%s\n", block->target_id);
                }
 
-               fprintf(handle->fp, "}\n");
+               fprintf(fp, "}\n");
                DbgPrint("}\n");
-
-               free(block->type);
-               free(block->part);
-               free(block->data);
-               free(block->option);
-               free(block->id);
-               free(block->target_id);
-               free(block);
        }
 
-       fclose(handle->fp);
-       free(handle->filename);
-       free(handle);
+       fclose(fp);
        return 0;
 }
 
 
 
-static inline int shortcut_icon_desc_set_id(struct shortcut_desc *handle, int idx, const char *id)
+static inline struct block *find_block(struct shortcut_desc *handle, const char *id, const char *part)
 {
-       struct dlist *l;
        struct block *block;
+       struct dlist *l;
 
        dlist_foreach(handle->block_list, l, block) {
-               if (block->idx == idx) {
-                       if (strcasecmp(block->type, SHORTCUT_ICON_TYPE_SCRIPT)) {
-                               ErrPrint("Invalid block is used\n");
-                               return SHORTCUT_ERROR_INVALID;
-                       }
+               if (!strcmp(block->part, part) && !strcmp(block->id, id))
+                       return block;
+       }
+
+       return NULL;
+}
 
-                       free(block->target_id);
-                       block->target_id = NULL;
 
-                       if (!id || !strlen(id))
-                               return SHORTCUT_SUCCESS;
 
-                       block->target_id = strdup(id);
-                       if (!block->target_id) {
-                               ErrPrint("Heap: %s\n", strerror(errno));
-                               return SHORTCUT_ERROR_MEMORY;
-                       }
+static inline int update_block(struct block *block, const char *data, const char *option)
+{
+       char *_data = NULL;
+       char *_option = NULL;
 
-                       return SHORTCUT_SUCCESS;
+       if (data) {
+               _data = strdup(data);
+               if (!_data) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       return -ENOMEM;
                }
        }
 
-       return SHORTCUT_ERROR_INVALID;
+       if (option) {
+               _option = strdup(option);
+               if (!_option) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       return -ENOMEM;
+               }
+       }
+
+       free(block->data);
+       free(block->option);
+
+       block->data = _data;
+       block->option = _option;
+       return 0;
 }
+
+
+
 /*!
  * \return idx
  */
 
 
 
-static inline int shortcut_icon_desc_add_block(struct shortcut_desc *handle, const char *id, const char *type, const char *part, const char *data, const char *option)
+static inline int shortcut_icon_desc_add_block(struct shortcut_desc *handle, const char *id, const char *type, const char *part, const char *data, const char *option, const char *target_id)
 {
        struct block *block;
 
@@ -270,63 +323,96 @@ static inline int shortcut_icon_desc_add_block(struct shortcut_desc *handle, con
        if (!data)
                data = "";
 
-       block = calloc(1, sizeof(*block));
-       if (!block) {
-               ErrPrint("Heap: %s\n", strerror(errno));
-               return SHORTCUT_ERROR_MEMORY;
-       }
-
-       block->type = strdup(type);
-       if (!block->type) {
-               ErrPrint("Heap: %s\n", strerror(errno));
-               free(block);
-               return SHORTCUT_ERROR_MEMORY;
+       if (target_id) {
+               if (strcmp(type, SHORTCUT_ICON_TYPE_SCRIPT)) {
+                       ErrPrint("target id only can be used for script type\n");
+                       return -EINVAL;
+               }
        }
 
-       block->part = strdup(part);
-       if (!block->part) {
-               ErrPrint("Heap: %s\n", strerror(errno));
-               free(block->type);
-               free(block);
-               return SHORTCUT_ERROR_MEMORY;
-       }
+       block = find_block(handle, id, part);
+       if (!block) {
+               block = calloc(1, sizeof(*block));
+               if (!block) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       return SHORTCUT_ERROR_MEMORY;
+               }
 
-       block->data = strdup(data);
-       if (!block->data) {
-               ErrPrint("Heap: %s\n", strerror(errno));
-               free(block->type);
-               free(block->part);
-               free(block);
-               return SHORTCUT_ERROR_MEMORY;
-       }
+               block->type = strdup(type);
+               if (!block->type) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
+                       free(block);
+                       return SHORTCUT_ERROR_MEMORY;
+               }
 
-       if (option) {
-               block->option = strdup(option);
-               if (!block->option) {
+               block->part = strdup(part);
+               if (!block->part) {
                        ErrPrint("Heap: %s\n", strerror(errno));
-                       free(block->data);
                        free(block->type);
-                       free(block->part);
                        free(block);
                        return SHORTCUT_ERROR_MEMORY;
                }
-       }
 
-       if (id) {
-               block->id = strdup(id);
-               if (!block->id) {
+               block->data = strdup(data);
+               if (!block->data) {
                        ErrPrint("Heap: %s\n", strerror(errno));
-                       free(block->option);
-                       free(block->data);
                        free(block->type);
                        free(block->part);
                        free(block);
                        return SHORTCUT_ERROR_MEMORY;
                }
+
+               if (option) {
+                       block->option = strdup(option);
+                       if (!block->option) {
+                               ErrPrint("Heap: %s\n", strerror(errno));
+                               free(block->data);
+                               free(block->type);
+                               free(block->part);
+                               free(block);
+                               return SHORTCUT_ERROR_MEMORY;
+                       }
+               }
+
+               if (id) {
+                       block->id = strdup(id);
+                       if (!block->id) {
+                               ErrPrint("Heap: %s\n", strerror(errno));
+                               free(block->option);
+                               free(block->data);
+                               free(block->type);
+                               free(block->part);
+                               free(block);
+                               return SHORTCUT_ERROR_MEMORY;
+                       }
+               }
+
+               if (target_id) {
+                       block->target_id = strdup(target_id);
+                       if (!block->target_id) {
+                               ErrPrint("Heap: %s\n", strerror(errno));
+                               free(block->id);
+                               free(block->option);
+                               free(block->data);
+                               free(block->type);
+                               free(block->part);
+                               free(block);
+                               return SHORTCUT_ERROR_MEMORY;
+                       }
+               }
+
+               block->idx = handle->last_idx++;
+               handle->block_list = dlist_append(handle->block_list, block);
+       } else {
+               if (strcmp(block->type, type) || strcmp(block->target_id, target_id)) {
+                       ErrPrint("type or target id is not valid (%s, %s) or (%s, %s)\n",
+                                               block->type, type, block->target_id, target_id);
+                       return -EINVAL;
+               }
+
+               update_block(block, data, option);
        }
 
-       block->idx = handle->last_idx++;
-       handle->block_list = dlist_append(handle->block_list, block);
        return block->idx;
 }
 
@@ -348,8 +434,9 @@ static int icon_request_cb(pid_t pid, int handle, const struct packet *packet, v
        }
 
        if (item->result_cb)
-               item->result_cb(ret, pid, item->data);
+               item->result_cb(item->handle, ret, item->data);
 
+       (void)shortcut_icon_request_unref(item->handle);
        free(item);
        return 0;
 }
@@ -388,7 +475,7 @@ static inline int make_connection(void)
                        if (ret < 0) {
                                ErrPrint("ret: %d\n", ret);
                                if (pend->item->result_cb)
-                                       pend->item->result_cb(ret, getpid(), pend->item->data);
+                                       pend->item->result_cb(pend->item->handle, ret, pend->item->data);
                                free(pend->item);
                        }
 
@@ -448,6 +535,10 @@ EAPI int shortcut_icon_service_init(int (*init_cb)(int status, void *data), void
 
 EAPI int shortcut_icon_service_fini(void)
 {
+       struct dlist *l;
+       struct dlist *n;
+       struct pending_item *pend;
+
        if (s_info.initialized) {
                com_core_del_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL);
                s_info.initialized = 0;
@@ -460,25 +551,23 @@ EAPI int shortcut_icon_service_fini(void)
        s_info.init_cb = NULL;
        s_info.cbdata = NULL;
        s_info.fd = -1;
+
+       dlist_foreach_safe(s_info.pending_list, l, n, pend) {
+               s_info.pending_list = dlist_remove(s_info.pending_list, l);
+               packet_unref(pend->packet);
+               if (pend->item->result_cb)
+                       pend->item->result_cb(pend->item->handle, SHORTCUT_ERROR_COMM, pend->item->data);
+               free(pend->item);
+               free(pend);
+       }
        return 0;
 }
 
 
 
-EAPI struct shortcut_icon *shortcut_icon_request_create(int size_type, const char *output, const char *layout, const char *group)
+EAPI struct shortcut_icon *shortcut_icon_request_create(void)
 {
        struct shortcut_icon *handle;
-       int len;
-
-       if (!layout) {
-               DbgPrint("Using default icon layout\n");
-               layout = DEFAULT_ICON_LAYOUT;
-       }
-
-       if (!group) {
-               DbgPrint("Using default icon group\n");
-               group = DEFAULT_ICON_GROUP;
-       }
 
        handle = malloc(sizeof(*handle));
        if (!handle) {
@@ -486,134 +575,162 @@ EAPI struct shortcut_icon *shortcut_icon_request_create(int size_type, const cha
                return NULL;
        }
 
-       len = strlen(output) + strlen(".desc") + 1;
-       handle->descfile = malloc(len);
-       if (!handle->descfile) {
-               ErrPrint("Heap: %s\n", strerror(errno));
+       handle->desc = shortcut_icon_desc_open();
+       if (!handle->desc) {
+               ErrPrint("Uanble to open desc\n");
                free(handle);
                return NULL;
        }
 
-       handle->layout = strdup(layout);
-       if (!handle->layout) {
-               ErrPrint("Heap: %s\n", strerror(errno));
-               free(handle->descfile);
-               free(handle);
-               return NULL;
-       }
+       handle->state = CREATED;
+       handle->refcnt = 1;
+       return handle;
+}
 
-       handle->group = strdup(group);
-       if (!handle->group) {
-               ErrPrint("Heap: %s\n", strerror(errno));
-               free(handle->descfile);
-               free(handle->layout);
-               free(handle);
-               return NULL;
-       }
 
-       handle->output = strdup(output);
-       if (!handle->output) {
-               ErrPrint("Heap: %s\n", strerror(errno));
-               free(handle->group);
-               free(handle->layout);
-               free(handle->descfile);
-               free(handle);
-               return NULL;
+EAPI int shortcut_icon_request_set_data(struct shortcut_icon *handle, void *data)
+{
+       if (!handle || handle->state != CREATED) {
+               ErrPrint("Handle is not valid\n");
+               return -EINVAL;
        }
 
-       snprintf(handle->descfile, len, "%s.desc", output);
+       handle->data = data;
+       return 0;
+}
 
-       handle->desc = shortcut_icon_desc_open(handle->descfile);
-       if (!handle->desc) {
-               ErrPrint("Uanble to open desc\n");
-               free(handle->output);
-               free(handle->group);
-               free(handle->layout);
-               free(handle->descfile);
-               free(handle);
+
+
+EAPI void *shortcut_icon_request_data(struct shortcut_icon *handle)
+{
+       if (!handle || handle->state != CREATED) {
+               ErrPrint("Handle is not valid\n");
                return NULL;
        }
 
-       handle->size_type = size_type;
-       return handle;
+       return handle->data;
 }
 
 
 
 EAPI int shortcut_icon_request_set_info(struct shortcut_icon *handle, const char *id, const char *type, const char *part, const char *data, const char *option, const char *subid)
 {
-       int idx;
+       if (!handle || handle->state != CREATED) {
+               ErrPrint("Handle is not valid\n");
+               return -EINVAL;
+       }
+
+       return shortcut_icon_desc_add_block(handle->desc, id, type, part, data, option, subid);
+}
 
-       idx = shortcut_icon_desc_add_block(handle->desc, id, type, part, data, option);
-       if (subid && idx >= 0)
-               shortcut_icon_desc_set_id(handle->desc, idx, subid);
 
-       return idx;
+
+EAPI int shortcut_icon_request_destroy(struct shortcut_icon *handle)
+{
+       if (!handle || handle->state != CREATED) {
+               ErrPrint("Handle is not valid\n");
+               return -EINVAL;
+       }
+
+       (void)shortcut_icon_request_unref(handle);
+       return 0;
 }
 
 
 
-EAPI int shortcut_icon_request_send_and_destroy(struct shortcut_icon *handle, result_cb_t result_cb, void *data)
+EAPI int shortcut_icon_request_send(struct shortcut_icon *handle, int size_type, const char *layout, const char *group, const char *outfile, icon_request_cb_t result_cb, void *data)
 {
        int ret;
        struct packet *packet;
        struct request_item *item;
+       char *filename;
+       int len;
+
+       if (!handle || handle->state != CREATED) {
+               ErrPrint("Handle is not valid\n");
+               return -EINVAL;
+       }
+
+       if (!layout)
+               layout = DEFAULT_ICON_LAYOUT;
+
+       if (!group)
+               group = DEFAULT_ICON_GROUP;
+
+       len = strlen(outfile) + strlen(".desc") + 1;
+       filename = malloc(len);
+       if (!filename) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return -ENOMEM;
+       }
 
-       DbgPrint("Request and Destroy\n");
-       shortcut_icon_desc_close(handle->desc);
+       snprintf(filename, len, "%s.desc", outfile);
+
+       ret = shortcut_icon_desc_save(handle->desc, filename);
+       if (ret < 0)
+               goto out;
 
        item = malloc(sizeof(*item));
        if (!item) {
                ErrPrint("Heap: %s\n", strerror(errno));
+               if (unlink(filename) < 0)
+                       ErrPrint("Unlink: %s\n", strerror(errno));
                ret = -ENOMEM;
-       } else {
-               item->result_cb = result_cb;
-               item->data = data;
+               goto out;
+       }
+
+       item->result_cb = result_cb;
+       item->data = data;
+       item->handle = shortcut_icon_request_ref(handle);
 
-               packet = packet_create("icon_create", "sssis", handle->layout, handle->group, handle->descfile, handle->size_type, handle->output);
-               if (!packet) {
-                       ErrPrint("Failed to create a packet\n");
+       packet = packet_create("icon_create", "sssis", layout, group, filename, size_type, outfile);
+       if (!packet) {
+               ErrPrint("Failed to create a packet\n");
+               if (unlink(filename) < 0)
+                       ErrPrint("Unlink: %s\n", strerror(errno));
+               free(item);
+               (void)shortcut_icon_request_unref(handle);
+               ret = -EFAULT;
+               goto out;
+       }
+
+       if (s_info.fd >= 0 && !s_info.pending_list) {
+               ret = com_core_packet_async_send(s_info.fd, packet, 0.0f, icon_request_cb, item);
+               packet_destroy(packet);
+               if (ret < 0) {
+                       ErrPrint("ret: %d\n", ret);
+                       if (unlink(filename) < 0)
+                               ErrPrint("Unlink: %s\n", strerror(errno));
                        free(item);
-                       ret = -EFAULT;
-                       goto out;
+                       (void)shortcut_icon_request_unref(handle);
                }
+               DbgPrint("Request is sent\n");
+       } else {
+               struct pending_item *pend;
 
-               if (s_info.fd >= 0 && !s_info.pending_list) {
-                       ret = com_core_packet_async_send(s_info.fd, packet, 0.0f, icon_request_cb, item);
+               pend = malloc(sizeof(*pend));
+               if (!pend) {
+                       ErrPrint("Heap: %s\n", strerror(errno));
                        packet_destroy(packet);
-                       if (ret < 0) {
-                               ErrPrint("ret: %d\n", ret);
-                               free(item);
-                       }
-                       DbgPrint("Request is sent\n");
-               } else {
-                       struct pending_item *pend;
-
-                       pend = malloc(sizeof(*pend));
-                       if (!pend) {
-                               ErrPrint("Heap: %s\n", strerror(errno));
-                               ret = -ENOMEM;
-                               packet_destroy(packet);
-                               free(item);
-                               goto out;
-                       }
+                       free(item);
+                       if (unlink(filename) < 0)
+                               ErrPrint("Unlink: %s\n", strerror(errno));
+                       (void)shortcut_icon_request_unref(handle);
+                       ret = -ENOMEM;
+                       goto out;
+               }
 
-                       pend->packet = packet;
-                       pend->item = item;
+               pend->packet = packet;
+               pend->item = item;
 
-                       s_info.pending_list = dlist_append(s_info.pending_list, pend);
-                       DbgPrint("Request is pended\n");
+               s_info.pending_list = dlist_append(s_info.pending_list, pend);
+               DbgPrint("Request is pended\n");
 
-                       ret = 0;
-               }
+               ret = 0;
        }
 
 out:
-       free(handle->output);
-       free(handle->layout);
-       free(handle->group);
-       free(handle->descfile);
-       free(handle);
+       free(filename);
        return ret;
 }
 
index 39ab350..8e8eebf 100644 (file)
@@ -1,6 +1,6 @@
 Name: libshortcut
 Summary: Shortcut add feature supporting library
-Version: 0.6.0
+Version: 0.6.1
 Release: 0
 Group: HomeTF/Framework
 License: Apache License
diff --git a/test/icon.c b/test/icon.c
new file mode 100644 (file)
index 0000000..3086729
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+#include <Elementary.h>
+#include <shortcut.h>
+
+static int result_cb(struct shortcut_icon *handle, int ret, void *data)
+{
+       printf("Client: Return %d (%p)\n", ret, handle);
+       return 0;
+}
+
+static Eina_Bool test_main(void *data)
+{
+       struct shortcut_icon *handle;
+       static int idx = 0;
+       int ret;
+       char filename[256];
+       int type;
+
+       idx++;
+
+       handle = shortcut_icon_request_create();
+       if (!handle) {
+               printf("Failed to create a request\n");
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       printf("Test: %d\n", idx);
+       ret = shortcut_icon_request_set_info(handle, NULL, SHORTCUT_ICON_TYPE_IMAGE, DEFAULT_ICON_PART, "/usr/share/icons/default/small/com.samsung.music-player.png", NULL, NULL);
+       printf("NAME set_info: %d\n", ret);
+
+       snprintf(filename, sizeof(filename), "App Name %d", idx);
+       ret = shortcut_icon_request_set_info(handle, NULL, SHORTCUT_ICON_TYPE_TEXT, DEFAULT_NAME_PART, filename, NULL, NULL);
+       printf("TEXT set_info: %d\n", ret);
+
+       snprintf(filename, sizeof(filename), "/opt/usr/share/live_magazine/always/out%d.png", idx);
+
+       switch (idx % 7) {
+       case 0: type = LIVEBOX_TYPE_1x1; break;
+       case 1: type = LIVEBOX_TYPE_2x1; break;
+       case 2: type = LIVEBOX_TYPE_2x2; break;
+       case 3: type = LIVEBOX_TYPE_4x1; break;
+       case 4: type = LIVEBOX_TYPE_4x2; break;
+       case 5: type = LIVEBOX_TYPE_4x3; break;
+       case 6: type = LIVEBOX_TYPE_4x4; break;
+       default: type = LIVEBOX_TYPE_1x1; break;
+       }
+
+       ret = shortcut_icon_request_send(handle, type, NULL, NULL, filename, result_cb, NULL);
+       printf("request: %d\n", ret);
+
+       ret = shortcut_icon_request_destroy(handle);
+       printf("destroy: %d\n", ret);
+       return ECORE_CALLBACK_RENEW;
+}
+
+static int initialized_cb(int status, void *data)
+{
+       printf("Hello initializer\n");
+       return 0;
+}
+
+int elm_main(int argc, char *argv[])
+{
+       shortcut_icon_service_init(NULL, NULL);
+
+       ecore_timer_add(5.0f, test_main, NULL);
+
+       elm_run();
+       shortcut_icon_service_fini();
+       elm_shutdown();
+       return 0;
+}
+
+ELM_MAIN()
+/* End of a file */