diff options
Diffstat (limited to 'home/src/add-viewer_pkgmgr.c')
-rwxr-xr-x | home/src/add-viewer_pkgmgr.c | 639 |
1 files changed, 639 insertions, 0 deletions
diff --git a/home/src/add-viewer_pkgmgr.c b/home/src/add-viewer_pkgmgr.c new file mode 100755 index 0000000..b5b5834 --- /dev/null +++ b/home/src/add-viewer_pkgmgr.c @@ -0,0 +1,639 @@ +/* + * Samsung API + * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd. + * + * 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/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 <errno.h> +#include <stdlib.h> + +#include <dlog.h> +#include <package-manager.h> +#include <dynamicbox_errno.h> + +#include <Ecore.h> +#include <Ecore_X.h> /* util.h */ +#include <Evas.h> /* util.h */ + +#include "add-viewer_package.h" /* util.h */ +#include "add-viewer_util.h" +#include "add-viewer_debug.h" +#include "add-viewer_pkgmgr.h" + +#define DbgFree(a) free(a) + +#if defined(LOG_TAG) +#undef LOG_TAG +#endif +#define LOG_TAG "ADD_VIEWER" + +struct item { + char *pkgname; + char *icon; + + enum pkgmgr_event_type type; + enum pkgmgr_status status; +}; + +static struct { + pkgmgr_client *listen_pc; + Eina_List *item_list; + + Eina_List *install_event; + Eina_List *uninstall_event; + Eina_List *update_event; + Eina_List *download_event; + Eina_List *recover_event; +} s_info = { + .listen_pc = NULL, + .item_list = NULL, + + .install_event = NULL, + .uninstall_event = NULL, + .update_event = NULL, + .download_event = NULL, + .recover_event = NULL, +}; + +struct event_item { + int (*cb)(const char *pkgname, enum pkgmgr_status status, double value, void *data); + void *data; +}; + +static inline void invoke_install_event_handler(const char *pkgname, enum pkgmgr_status status, double value) +{ + Eina_List *l; + struct event_item *item; + + EINA_LIST_FOREACH(s_info.install_event, l, item) { + if (item->cb) { + item->cb(pkgname, status, value, item->data); + } + } +} + +static inline void invoke_uninstall_event_handler(const char *pkgname, enum pkgmgr_status status, double value) +{ + Eina_List *l; + struct event_item *item; + + EINA_LIST_FOREACH(s_info.uninstall_event, l, item) { + if (item->cb) { + item->cb(pkgname, status, value, item->data); + } + } +} + +static inline void invoke_update_event_handler(const char *pkgname, enum pkgmgr_status status, double value) +{ + Eina_List *l; + struct event_item *item; + + EINA_LIST_FOREACH(s_info.update_event, l, item) { + if (item->cb) { + item->cb(pkgname, status, value, item->data); + } + } +} + +static inline void invoke_download_event_handler(const char *pkgname, enum pkgmgr_status status, double value) +{ + Eina_List *l; + struct event_item *item; + + EINA_LIST_FOREACH(s_info.download_event, l, item) { + if (item->cb) { + item->cb(pkgname, status, value, item->data); + } + } +} + +static inline void invoke_recover_event_handler(const char *pkgname, enum pkgmgr_status status, double value) +{ + Eina_List *l; + struct event_item *item; + + EINA_LIST_FOREACH(s_info.recover_event, l, item) { + if (item->cb) { + item->cb(pkgname, status, value, item->data); + } + } +} + +static inline void invoke_callback(const char *pkgname, struct item *item, double value) +{ + switch (item->type) { + case PKGMGR_EVENT_DOWNLOAD: + invoke_download_event_handler(pkgname, item->status, value); + break; + case PKGMGR_EVENT_UNINSTALL: + invoke_uninstall_event_handler(pkgname, item->status, value); + break; + case PKGMGR_EVENT_INSTALL: + invoke_install_event_handler(pkgname, item->status, value); + break; + case PKGMGR_EVENT_UPDATE: + invoke_update_event_handler(pkgname, item->status, value); + break; + case PKGMGR_EVENT_RECOVER: + invoke_recover_event_handler(pkgname, item->status, value); + break; + default: + ErrPrint("Unknown type: %d\n", item->type); + break; + } +} + +static inline int is_valid_status(struct item *item, const char *status) +{ + const char *expected_status; + + switch (item->type) { + case PKGMGR_EVENT_DOWNLOAD: + expected_status = "download"; + break; + case PKGMGR_EVENT_UNINSTALL: + expected_status = "uninstall"; + break; + case PKGMGR_EVENT_INSTALL: + expected_status = "install"; + break; + case PKGMGR_EVENT_UPDATE: + expected_status = "update"; + break; + case PKGMGR_EVENT_RECOVER: + expected_status = "recover"; + break; + default: + return 0; + } + + return !strcasecmp(status, expected_status); +} + +static struct item *find_item(const char *pkgname) +{ + Eina_List *l; + struct item *item; + + if (!pkgname) { + ErrPrint("Package name is not valid\n"); + return NULL; + } + + EINA_LIST_FOREACH(s_info.item_list, l, item) { + if (strcmp(item->pkgname, pkgname)) { + continue; + } + + return item; + } + + DbgPrint("Package %s is not found\n", pkgname); + return NULL; +} + +static int start_cb(const char *pkgname, const char *val, void *data) +{ + struct item *item; + + DbgPrint("[%s] %s\n", pkgname, val); + + item = calloc(1, sizeof(*item)); + if (!item) { + ErrPrint("Heap: %s\n", strerror(errno)); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + + item->pkgname = strdup(pkgname); + if (!item->pkgname) { + ErrPrint("Heap: %s\n", strerror(errno)); + DbgFree(item); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + + item->status = PKGMGR_STATUS_START; + + if (!strcasecmp(val, "download")) { + item->type = PKGMGR_EVENT_DOWNLOAD; + } else if (!strcasecmp(val, "uninstall")) { + item->type = PKGMGR_EVENT_UNINSTALL; + } else if (!strcasecmp(val, "install")) { + item->type = PKGMGR_EVENT_INSTALL; + } else if (!strcasecmp(val, "update")) { + item->type = PKGMGR_EVENT_UPDATE; + } else if (!strcasecmp(val, "recover")) { + item->type = PKGMGR_EVENT_RECOVER; + } else { + DbgFree(item->pkgname); + DbgFree(item); + ErrPrint("Invalid val: %s\n", val); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + s_info.item_list = eina_list_append(s_info.item_list, item); + + invoke_callback(pkgname, item, 0.0f); + return DBOX_STATUS_ERROR_NONE; +} + +static int icon_path_cb(const char *pkgname, const char *val, void *data) +{ + struct item *item; + + DbgPrint("[%s] %s\n", pkgname, val); + + item = find_item(pkgname); + if (!item) { + return DBOX_STATUS_ERROR_NOT_EXIST; + } + + if (item->icon) { + DbgFree(item->icon); + } + + item->icon = strdup(val); + if (!item->icon) { + ErrPrint("Heap: %s\n", strerror(errno)); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + + return DBOX_STATUS_ERROR_NONE; +} + +static int command_cb(const char *pkgname, const char *val, void *data) +{ + struct item *item; + + DbgPrint("[%s] %s\n", pkgname, val); + + item = find_item(pkgname); + if (!item) { + return DBOX_STATUS_ERROR_NOT_EXIST; + } + + if (!is_valid_status(item, val)) { + DbgPrint("Invalid status: %d, %s\n", item->type, val); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + item->status = PKGMGR_STATUS_COMMAND; + invoke_callback(pkgname, item, 0.0f); + return DBOX_STATUS_ERROR_NONE; +} + +static int error_cb(const char *pkgname, const char *val, void *data) +{ + /* val = error */ + struct item *item; + + DbgPrint("[%s] %s\n", pkgname, val); + + item = find_item(pkgname); + if (!item) { + return DBOX_STATUS_ERROR_NOT_EXIST; + } + + item->status = PKGMGR_STATUS_ERROR; + invoke_callback(pkgname, item, 0.0f); + return DBOX_STATUS_ERROR_NONE; +} + +static int change_pkgname_cb(const char *pkgname, const char *val, void *data) +{ + struct item *item; + char *new_pkgname; + + DbgPrint("[%s] %s\n", pkgname, val); + + item = find_item(pkgname); + if (!item) { + return DBOX_STATUS_ERROR_NOT_EXIST; + } + + new_pkgname = strdup(val); + if (!new_pkgname) { + ErrPrint("Heap: %s\n", strerror(errno)); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + + DbgFree(item->pkgname); + item->pkgname = new_pkgname; + return DBOX_STATUS_ERROR_NONE; +} + +static int download_cb(const char *pkgname, const char *val, void *data) +{ + /* val = integer */ + struct item *item; + double value; + + DbgPrint("[%s] %s\n", pkgname, val); + + item = find_item(pkgname); + if (!item) { + DbgPrint("ITEM is not started from the start_cb\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (item->type != PKGMGR_EVENT_DOWNLOAD) { + DbgPrint("TYPE is not \"download\" : %d\n", item->type); + item->type = PKGMGR_EVENT_DOWNLOAD; + } + + switch (item->status) { + case PKGMGR_STATUS_START: + case PKGMGR_STATUS_COMMAND: + item->status = PKGMGR_STATUS_PROCESSING; + case PKGMGR_STATUS_PROCESSING: + break; + default: + ErrPrint("Invalid state [%s, %s]\n", pkgname, val); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (val) { + if (sscanf(val, "%lf", &value) != 1) { + value = (double)DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + } else { + value = (double)DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + invoke_download_event_handler(pkgname, item->status, value); + return DBOX_STATUS_ERROR_NONE; +} + +static int progress_cb(const char *pkgname, const char *val, void *data) +{ + /* val = integer */ + struct item *item; + double value; + + DbgPrint("[%s] %s\n", pkgname, val); + + item = find_item(pkgname); + if (!item) { + ErrPrint("ITEM is not started from the start_cb\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + switch (item->status) { + case PKGMGR_STATUS_START: + case PKGMGR_STATUS_COMMAND: + item->status = PKGMGR_STATUS_PROCESSING; + case PKGMGR_STATUS_PROCESSING: + break; + default: + ErrPrint("Invalid state [%s, %s]\n", pkgname, val); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (val) { + if (sscanf(val, "%lf", &value) != 1) { + value = (double)DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + } else { + value = (double)DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + invoke_callback(pkgname, item, value); + return DBOX_STATUS_ERROR_NONE; +} + +static int end_cb(const char *pkgname, const char *val, void *data) +{ + struct item *item; + + DbgPrint("[%s] %s\n", pkgname, val); + + item = find_item(pkgname); + if (!item) { + return DBOX_STATUS_ERROR_NOT_EXIST; + } + + item->status = !strcasecmp(val, "ok") ? PKGMGR_STATUS_END : PKGMGR_STATUS_ERROR; + + invoke_callback(pkgname, item, 0.0f); + + s_info.item_list = eina_list_remove(s_info.item_list, item); + DbgFree(item->icon); + DbgFree(item->pkgname); + DbgFree(item); + return DBOX_STATUS_ERROR_NONE; +} + +static struct pkgmgr_handler { + const char *key; + int (*func)(const char *package, const char *val, void *data); +} handler[] = { + { "install_percent", progress_cb }, + { "download_percent", download_cb }, + { "start", start_cb }, + { "end", end_cb }, + { "change_pkg_name", change_pkgname_cb }, + { "icon_path", icon_path_cb }, + { "command", command_cb }, + { "error", error_cb }, + { NULL, NULL }, +}; + +static int pkgmgr_cb(int req_id, const char *type, const char *pkgname, const char *key, const char *val, const void *pmsg, void *data) +{ + register int i; + int ret; + + for (i = 0; handler[i].key; i++) { + if (strcasecmp(key, handler[i].key)) { + continue; + } + + ret = handler[i].func(pkgname, val, data); + if (ret < 0) { + DbgPrint("REQ[%d] pkgname[%s], type[%s], key[%s], val[%s], ret = %d\n", + req_id, pkgname, type, key, val, ret); + } + } + + return DBOX_STATUS_ERROR_NONE; +} + +HAPI int add_viewer_pkgmgr_init(void) +{ + if (s_info.listen_pc) { + return DBOX_STATUS_ERROR_ALREADY; + } + + s_info.listen_pc = pkgmgr_client_new(PC_LISTENING); + if (!s_info.listen_pc) { + ErrPrint("Failed to client_new\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + if (pkgmgr_client_listen_status(s_info.listen_pc, pkgmgr_cb, NULL) != PKGMGR_R_OK) { + ErrPrint("Failed to add listener\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + return DBOX_STATUS_ERROR_NONE; +} + +HAPI int add_viewer_pkgmgr_fini(void) +{ + struct event_item *item; + struct item *ctx; + + if (!s_info.listen_pc) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (pkgmgr_client_free(s_info.listen_pc) != PKGMGR_R_OK) { + return DBOX_STATUS_ERROR_FAULT; + } + + s_info.listen_pc = NULL; + + EINA_LIST_FREE(s_info.download_event, item) { + DbgFree(item); + } + + EINA_LIST_FREE(s_info.uninstall_event, item) { + DbgFree(item); + } + + EINA_LIST_FREE(s_info.install_event, item) { + DbgFree(item); + } + + EINA_LIST_FREE(s_info.update_event, item) { + DbgFree(item); + } + + EINA_LIST_FREE(s_info.recover_event, item) { + DbgFree(item); + } + + EINA_LIST_FREE(s_info.item_list, ctx) { + DbgFree(ctx->pkgname); + DbgFree(ctx->icon); + DbgFree(ctx); + } + + return DBOX_STATUS_ERROR_NONE; +} + +HAPI int add_viewer_pkgmgr_add_event_callback(enum pkgmgr_event_type type, int (*cb)(const char *pkgname, enum pkgmgr_status status, double value, void *data), void *data) +{ + struct event_item *item; + + item = calloc(1, sizeof(*item)); + if (!item) { + ErrPrint("Heap: %s\n", strerror(errno)); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + + item->cb = cb; + item->data = data; + + switch (type) { + case PKGMGR_EVENT_DOWNLOAD: + s_info.download_event = eina_list_prepend(s_info.download_event, item); + break; + case PKGMGR_EVENT_UNINSTALL: + s_info.uninstall_event = eina_list_prepend(s_info.uninstall_event, item); + break; + case PKGMGR_EVENT_INSTALL: + s_info.install_event = eina_list_prepend(s_info.install_event, item); + break; + case PKGMGR_EVENT_UPDATE: + s_info.update_event = eina_list_prepend(s_info.update_event, item); + break; + case PKGMGR_EVENT_RECOVER: + s_info.recover_event = eina_list_prepend(s_info.recover_event, item); + break; + default: + DbgFree(item); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return DBOX_STATUS_ERROR_NONE; +} + +HAPI void *add_viewer_pkgmgr_del_event_callback(enum pkgmgr_event_type type, int (*cb)(const char *pkgname, enum pkgmgr_status status, double value, void *data), void *data) +{ + struct event_item *item; + Eina_List *l; + void *cbdata = NULL; + + switch (type) { + case PKGMGR_EVENT_DOWNLOAD: + EINA_LIST_FOREACH(s_info.download_event, l, item) { + if (item->cb == cb && item->data == data) { + s_info.download_event = eina_list_remove(s_info.download_event, item); + cbdata = item->data; + DbgFree(item); + break; + } + } + break; + case PKGMGR_EVENT_UNINSTALL: + EINA_LIST_FOREACH(s_info.uninstall_event, l, item) { + if (item->cb == cb && item->data == data) { + s_info.uninstall_event = eina_list_remove(s_info.uninstall_event, item); + cbdata = item->data; + DbgFree(item); + break; + } + } + break; + case PKGMGR_EVENT_INSTALL: + EINA_LIST_FOREACH(s_info.install_event, l, item) { + if (item->cb == cb && item->data == data) { + s_info.install_event = eina_list_remove(s_info.install_event, item); + cbdata = item->data; + DbgFree(item); + break; + } + } + break; + case PKGMGR_EVENT_UPDATE: + EINA_LIST_FOREACH(s_info.update_event, l, item) { + if (item->cb == cb && item->data == data) { + s_info.update_event = eina_list_remove(s_info.update_event, item); + cbdata = item->data; + DbgFree(item); + break; + } + } + break; + case PKGMGR_EVENT_RECOVER: + EINA_LIST_FOREACH(s_info.recover_event, l, item) { + if (item->cb == cb && item->data == data) { + s_info.recover_event = eina_list_remove(s_info.recover_event, item); + cbdata = item->data; + DbgFree(item); + break; + } + } + break; + default: + ErrPrint("Invalid type\n"); + break; + } + + return cbdata; +} + +/* End of a file */ |