diff options
author | Sung-jae Park <nicesj.park@samsung.com> | 2013-05-15 11:13:11 +0900 |
---|---|---|
committer | Sung-jae Park <nicesj.park@samsung.com> | 2013-05-15 11:13:11 +0900 |
commit | 73841e54e490d5b718922726fd1fa2c7f753dacc (patch) | |
tree | 37ae6f6f58c70527800d7fe40c0573608ae8297b | |
parent | 67ab9f9a537d7e55e7824d602e0191a26a8e5b4a (diff) | |
download | shortcut-tizen_2.1.tar.gz shortcut-tizen_2.1.tar.bz2 shortcut-tizen_2.1.zip |
Icon service API is introduced.submit/tizen_2.1/20130516.045513submit/tizen/20130517.044820accepted/tizen/20130520.100932tizen_2.1
Patch 2
Update the icon service reuqest codes.
APIs are changed.
Patch 1
Update shortcut service library.
Icon service API is implemented.
Default layout & group should be "" (zero length string)
The icon provider will choose the default layout and group when it get zero length string.
Change-Id: I2d47a1dbdeb8281c20f3a352fd3bcaf4ffe10a4e
-rw-r--r-- | lib/CMakeLists.txt | 2 | ||||
-rw-r--r-- | lib/include/dlist.h | 43 | ||||
-rw-r--r-- | lib/include/shortcut.h | 85 | ||||
-rw-r--r-- | lib/include/shortcut_internal.h | 37 | ||||
-rw-r--r-- | lib/src/dlist.c | 180 | ||||
-rw-r--r-- | lib/src/icon.c | 738 | ||||
-rw-r--r-- | lib/src/main.c | 17 | ||||
-rw-r--r-- | packaging/libshortcut.spec | 4 | ||||
-rw-r--r-- | test/icon.c | 91 |
9 files changed, 1179 insertions, 18 deletions
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 9f2f2a7..f02c651 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -31,6 +31,8 @@ ADD_DEFINITIONS("-DLOG_TAG=\"SHORTCUT\"") ADD_LIBRARY(${PROJECT_NAME} SHARED src/main.c + src/icon.c + src/dlist.c ) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${svc_pkgs_LDFLAGS}) diff --git a/lib/include/dlist.h b/lib/include/dlist.h new file mode 100644 index 0000000..cd1a421 --- /dev/null +++ b/lib/include/dlist.h @@ -0,0 +1,43 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * 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. + */ + +#define dlist_remove_data(list, data) do { \ + struct dlist *l; \ + l = dlist_find_data(list, data); \ + list = dlist_remove(list, l); \ +} while (0) + +#define dlist_foreach(list, l, data) \ + for ((l) = (list); (l) && ((data) = dlist_data(l)); (l) = dlist_next(l)) + +#define dlist_foreach_safe(list, l, n, data) \ + for ((l) = (list), (n) = dlist_next(l); \ + (l) && ((data) = dlist_data(l)); \ + (l) = (n), (n) = dlist_next(l)) + +struct dlist; + +extern struct dlist *dlist_append(struct dlist *list, void *data); +extern struct dlist *dlist_prepend(struct dlist *list, void *data); +extern struct dlist *dlist_remove(struct dlist *list, struct dlist *l); +extern struct dlist *dlist_find_data(struct dlist *list, void *data); +extern void *dlist_data(struct dlist *l); +extern struct dlist *dlist_next(struct dlist *l); +extern struct dlist *dlist_prev(struct dlist *l); +extern int dlist_count(struct dlist *l); +extern struct dlist *dlist_nth(struct dlist *l, int nth); + +/* End of a file */ diff --git a/lib/include/shortcut.h b/lib/include/shortcut.h index 3bae74f..b2cd25e 100644 --- a/lib/include/shortcut.h +++ b/lib/include/shortcut.h @@ -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. @@ -268,6 +271,88 @@ extern int add_to_home_remove_shortcut(const char *appid, const char *name, cons extern int add_to_home_remove_livebox(const char *appid, const char *name, result_cb_t result_cb, void *data); + + +/*! + * \note + * Example) + * + * 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); + * } + * } + * + * int main(int argc, char *argv[]) + * { + * // Initialize the service request + * int ret; + * + * // After the init_cb is called, you can use below functions. + * struct shortcut_icon *handle; + * + * 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; + * } + */ + +#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 (*init_cb)(int status, void *data), void *data); +extern int shortcut_icon_service_fini(void); + +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(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 } #endif diff --git a/lib/include/shortcut_internal.h b/lib/include/shortcut_internal.h new file mode 100644 index 0000000..5009ba2 --- /dev/null +++ b/lib/include/shortcut_internal.h @@ -0,0 +1,37 @@ +/* + * 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. + * +*/ + +#if !defined(FLOG) +#define DbgPrint(format, arg...) LOGD("[[32m%s/%s[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg) +#define ErrPrint(format, arg...) LOGE("[[32m%s/%s[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg) +#else +extern FILE *__file_log_fp; +#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [[32m%s/%s[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) + +#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [[32m%s/%s[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) +#endif + +#define EAPI __attribute__((visibility("default"))) + +#if !defined(VCONFKEY_MASTER_STARTED) +#define VCONFKEY_MASTER_STARTED "memory/data-provider-master/started" +#endif + +#define DEFAULT_ICON_LAYOUT "" +#define DEFAULT_ICON_GROUP "" + +/* End of a file */ diff --git a/lib/src/dlist.c b/lib/src/dlist.c new file mode 100644 index 0000000..fa3082a --- /dev/null +++ b/lib/src/dlist.c @@ -0,0 +1,180 @@ +/* + * Copyright 2013 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * 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 <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#include "dlist.h" + +/*! + * \brief + * This dlist is called Modified Doubly Linked List. + * + * Noramlly, The dobule linked list contains address of previous and next element. + * This dlist also contains them, but the tail element only contains prev address. + * + * The head element's prev pointer indicates the last element. + * But the last element's next pointer indicates NIL. + * + * So we can find the last element while crawling this DList + * But we have to remember the address of the head element. + */ + +struct dlist { + struct dlist *next; + struct dlist *prev; + void *data; +}; + +struct dlist *dlist_append(struct dlist *list, void *data) +{ + struct dlist *item; + + item = malloc(sizeof(*item)); + if (!item) + return NULL; + + item->next = NULL; + item->data = data; + + if (!list) { + item->prev = item; + + list = item; + } else { + item->prev = list->prev; + item->prev->next = item; + list->prev = item; + } + + assert(!list->prev->next && "item NEXT"); + + return list; +} + +struct dlist *dlist_prepend(struct dlist *list, void *data) +{ + struct dlist *item; + + item = malloc(sizeof(*item)); + if (!item) + return NULL; + + item->data = data; + + if (!list) { + item->prev = item; + item->next = NULL; + } else { + if (list->prev->next) + list->prev->next = item; + + item->prev = list->prev; + item->next = list; + + list->prev = item; + + } + + return item; +} + +struct dlist *dlist_remove(struct dlist *list, struct dlist *l) +{ + if (!list || !l) + return NULL; + + if (l == list) + list = l->next; + else + l->prev->next = l->next; + + if (l->next) + l->next->prev = l->prev; + /*! + * \note + * If the removed entry 'l' has no next element, it is the last element. + * In this case, check the existence of the list first, + * and if the list is not empty, update the 'prev' of the list (which is a head element of the list) + * + * If we didn't care about this, the head element(list) can indicates the invalid element. + */ + else if (list) + list->prev = l->prev; + + free(l); + return list; +} + +struct dlist *dlist_find_data(struct dlist *list, void *data) +{ + struct dlist *l; + void *_data; + + dlist_foreach(list, l, _data) { + if (data == _data) + return l; + } + + return NULL; +} + +void *dlist_data(struct dlist *l) +{ + return l ? l->data : NULL; +} + +struct dlist *dlist_next(struct dlist *l) +{ + return l ? l->next : NULL; +} + +struct dlist *dlist_prev(struct dlist *l) +{ + return l ? l->prev : NULL; +} + +int dlist_count(struct dlist *l) +{ + register int i; + struct dlist *n; + void *data; + + i = 0; + dlist_foreach(l, n, data) { + i++; + } + + return i; +} + +struct dlist *dlist_nth(struct dlist *l, int nth) +{ + register int i; + struct dlist *n; + + i = 0; + for (n = l; n; n = n->next) { + if (i == nth) + return n; + i++; + } + + return NULL; +} + +/* End of a file */ diff --git a/lib/src/icon.c b/lib/src/icon.c new file mode 100644 index 0000000..c29445b --- /dev/null +++ b/lib/src/icon.c @@ -0,0 +1,738 @@ +/* + * 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 <stdlib.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <libgen.h> + +#include <dlog.h> +#include <glib.h> +#include <db-util.h> +#include <vconf.h> +#include <vconf-keys.h> + +#include <packet.h> +#include <com-core.h> +#include <com-core_packet.h> + +#include "shortcut_internal.h" +#include "shortcut.h" +#include "dlist.h" + + + +#define CREATED 0x00BEEF00 +#define DESTROYED 0x00DEAD00 + + +static struct info { + int fd; + int (*init_cb)(int status, void *data); + void *cbdata; + int initialized; + + const char *utility_socket; + + struct dlist *pending_list; +} s_info = { + .fd = -1, + .init_cb = NULL, + .cbdata = NULL, + .initialized = 0, + + .utility_socket = "/tmp/.utility.service", + .pending_list = NULL, +}; + + + +struct request_item { + struct shortcut_icon *handle; + icon_request_cb_t result_cb; + void *data; +}; + + + +struct pending_item { + struct request_item *item; + struct packet *packet; +}; + + + +struct block { + unsigned int idx; + + char *type; + char *part; + char *data; + char *option; + char *id; + char *target_id; +}; + + + +struct shortcut_icon { + unsigned int state; + struct shortcut_desc *desc; + int refcnt; + void *data; +}; + + + +struct shortcut_desc { + int for_pd; + + unsigned int last_idx; + + struct dlist *block_list; +}; + + + +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) + return 0; + + ErrPrint("Disconnected\n"); + s_info.fd = -1; + s_info.init_cb = NULL; + s_info.cbdata = NULL; + s_info.initialized = 0; + return 0; +} + + + +static inline struct shortcut_desc *shortcut_icon_desc_open(void) +{ + struct shortcut_desc *handle; + + handle = calloc(1, sizeof(*handle)); + if (!handle) { + ErrPrint("Error: %s\n", strerror(errno)); + return NULL; + } + + return 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) { + DbgPrint("{\n"); + fprintf(fp, "{\n"); + if (block->type) { + fprintf(fp, "type=%s\n", block->type); + DbgPrint("type=%s\n", block->type); + } + + if (block->part) { + fprintf(fp, "part=%s\n", block->part); + DbgPrint("part=%s\n", block->part); + } + + if (block->data) { + fprintf(fp, "data=%s\n", block->data); + DbgPrint("data=%s\n", block->data); + } + + if (block->option) { + fprintf(fp, "option=%s\n", block->option); + DbgPrint("option=%s\n", block->option); + } + + if (block->id) { + fprintf(fp, "id=%s\n", block->id); + DbgPrint("id=%s\n", block->id); + } + + if (block->target_id) { + fprintf(fp, "target=%s\n", block->target_id); + DbgPrint("target=%s\n", block->target_id); + } + + fprintf(fp, "}\n"); + DbgPrint("}\n"); + } + + fclose(fp); + return 0; +} + + + +static inline struct block *find_block(struct shortcut_desc *handle, const char *id, const char *part) +{ + struct block *block; + struct dlist *l; + + dlist_foreach(handle->block_list, l, block) { + if (!strcmp(block->part, part) && !strcmp(block->id, id)) + return block; + } + + return NULL; +} + + + +static inline int update_block(struct block *block, const char *data, const char *option) +{ + char *_data = NULL; + char *_option = NULL; + + if (data) { + _data = strdup(data); + if (!_data) { + ErrPrint("Heap: %s\n", strerror(errno)); + return -ENOMEM; + } + } + + 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, const char *target_id) +{ + struct block *block; + + if (!handle || !type) + return SHORTCUT_ERROR_INVALID; + + if (!part) + part = ""; + + if (!data) + data = ""; + + if (target_id) { + if (strcmp(type, SHORTCUT_ICON_TYPE_SCRIPT)) { + ErrPrint("target id only can be used for script type\n"); + return -EINVAL; + } + } + + 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->type = strdup(type); + if (!block->type) { + ErrPrint("Heap: %s\n", strerror(errno)); + free(block); + return SHORTCUT_ERROR_MEMORY; + } + + block->part = strdup(part); + if (!block->part) { + ErrPrint("Heap: %s\n", strerror(errno)); + free(block->type); + free(block); + 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; + } + + 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); + } + + return block->idx; +} + + + +static int icon_request_cb(pid_t pid, int handle, const struct packet *packet, void *data) +{ + struct request_item *item = data; + int ret; + + if (!packet) { + ret = -EFAULT; + DbgPrint("Disconnected?\n"); + } else { + if (packet_get(packet, "i", &ret) != 1) { + DbgPrint("Invalid packet\n"); + ret = -EINVAL; + } + } + + if (item->result_cb) + item->result_cb(item->handle, ret, item->data); + + (void)shortcut_icon_request_unref(item->handle); + free(item); + return 0; +} + + + +static inline int make_connection(void) +{ + int ret; + static struct method service_table[] = { + { + .cmd = NULL, + .handler = NULL, + }, + }; + + s_info.fd = com_core_packet_client_init(s_info.utility_socket, 0, service_table); + if (s_info.fd < 0) { + ret = SHORTCUT_ERROR_COMM; + + if (s_info.init_cb) + s_info.init_cb(ret, s_info.cbdata); + } else { + struct dlist *l; + struct dlist *n; + struct pending_item *pend; + + if (s_info.init_cb) + s_info.init_cb(SHORTCUT_SUCCESS, s_info.cbdata); + + dlist_foreach_safe(s_info.pending_list, l, n, pend) { + s_info.pending_list = dlist_remove(s_info.pending_list, l); + + ret = com_core_packet_async_send(s_info.fd, pend->packet, 0.0f, icon_request_cb, pend->item); + packet_destroy(pend->packet); + if (ret < 0) { + ErrPrint("ret: %d\n", ret); + if (pend->item->result_cb) + pend->item->result_cb(pend->item->handle, ret, pend->item->data); + free(pend->item); + } + + free(pend); + } + + ret = SHORTCUT_SUCCESS; + } + + return ret; +} + + + +static void master_started_cb(keynode_t *node, void *user_data) +{ + int state = 0; + + if (vconf_get_bool(VCONFKEY_MASTER_STARTED, &state) < 0) + ErrPrint("Unable to get \"%s\"\n", VCONFKEY_MASTER_STARTED); + + if (state == 1 && make_connection() == SHORTCUT_SUCCESS) { + int ret; + ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb); + DbgPrint("Ignore VCONF [%d]\n", ret); + } +} + + + +EAPI int shortcut_icon_service_init(int (*init_cb)(int status, void *data), void *data) +{ + int ret; + + if (s_info.fd >= 0) + return -EALREADY; + + if (s_info.initialized) { + s_info.initialized = 1; + com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL); + } + + s_info.init_cb = init_cb; + s_info.cbdata = data; + + ret = vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL); + if (ret < 0) + ErrPrint("Failed to add vconf for service state [%d]\n", ret); + else + DbgPrint("vconf is registered\n"); + + master_started_cb(NULL, NULL); + return 0; +} + + + +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; + } + + if (s_info.fd < 0) + return -EINVAL; + + com_core_packet_client_fini(s_info.fd); + 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(void) +{ + struct shortcut_icon *handle; + + handle = malloc(sizeof(*handle)); + if (!handle) { + ErrPrint("Heap: %s\n", strerror(errno)); + return NULL; + } + + handle->desc = shortcut_icon_desc_open(); + if (!handle->desc) { + ErrPrint("Uanble to open desc\n"); + free(handle); + return NULL; + } + + handle->state = CREATED; + handle->refcnt = 1; + return handle; +} + + +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; + } + + handle->data = data; + return 0; +} + + + +EAPI void *shortcut_icon_request_data(struct shortcut_icon *handle) +{ + if (!handle || handle->state != CREATED) { + ErrPrint("Handle is not valid\n"); + return NULL; + } + + 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) +{ + 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); +} + + + +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(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; + } + + 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; + goto out; + } + + item->result_cb = result_cb; + item->data = data; + item->handle = shortcut_icon_request_ref(handle); + + 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); + (void)shortcut_icon_request_unref(handle); + } + DbgPrint("Request is sent\n"); + } else { + struct pending_item *pend; + + pend = malloc(sizeof(*pend)); + if (!pend) { + ErrPrint("Heap: %s\n", strerror(errno)); + packet_destroy(packet); + 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; + + s_info.pending_list = dlist_append(s_info.pending_list, pend); + DbgPrint("Request is pended\n"); + + ret = 0; + } + +out: + free(filename); + return ret; +} + + +/* End of a file */ diff --git a/lib/src/main.c b/lib/src/main.c index 2410fb2..0a27aa3 100644 --- a/lib/src/main.c +++ b/lib/src/main.c @@ -35,22 +35,7 @@ #include <com-core_packet.h> #include "shortcut.h" - -#if !defined(FLOG) -#define DbgPrint(format, arg...) LOGD("[[32m%s/%s[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg) -#define ErrPrint(format, arg...) LOGE("[[32m%s/%s[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg) -#else -extern FILE *__file_log_fp; -#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [[32m%s/%s[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) - -#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [[32m%s/%s[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) -#endif - -#define EAPI __attribute__((visibility("default"))) - -#if !defined(VCONFKEY_MASTER_STARTED) -#define VCONFKEY_MASTER_STARTED "memory/data-provider-master/started" -#endif +#include "shortcut_internal.h" int errno; diff --git a/packaging/libshortcut.spec b/packaging/libshortcut.spec index 334a59c..54d12f3 100644 --- a/packaging/libshortcut.spec +++ b/packaging/libshortcut.spec @@ -1,6 +1,6 @@ Name: libshortcut -Summary: Shortcut add/remove request function supporting library -Version: 0.5.1 +Summary: Shortcut add feature supporting library +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 index 0000000..3086729 --- /dev/null +++ b/test/icon.c @@ -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 */ |