X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fpackage_manager.c;h=83b789e2042693f7cdf9fc420302fe28c084497b;hb=38624690402c3ce1171857a0b5c6e493cb118a53;hp=a7c56de482a05c3fd088fb5828cd56d2e55ff7a3;hpb=80916eb557c5b74a64a7678a69885a0c562533c5;p=platform%2Fcore%2Fapi%2Fpackage-manager.git diff --git a/src/package_manager.c b/src/package_manager.c index a7c56de..83b789e 100644 --- a/src/package_manager.c +++ b/src/package_manager.c @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -30,19 +31,25 @@ static GHashTable *__cb_table = NULL; #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) -typedef struct _event_info { +typedef struct _request_event_info { int req_id; package_manager_event_type_e event_type; package_manager_event_state_e event_state; - struct _event_info *next; -} event_info; + struct _request_event_info *next; +} request_event_info; + +struct package_manager_event_info { + char *pkg_name; + package_manager_event_type_e event_type; + package_manager_event_state_e event_state; +}; struct package_manager_s { int handle_id; pkgmgr_client_type ctype; pkgmgr_client *pc; pkgmgr_mode mode; - event_info *head; + GHashTable *event_info_table; package_manager_event_cb event_cb; void *user_data; }; @@ -53,8 +60,15 @@ struct package_manager_request_s { pkgmgr_client *pc; char *pkg_type; pkgmgr_mode mode; - event_info *head; + request_event_info *head; package_manager_request_event_cb event_cb; + GHashTable *request_cb_table; + void *user_data; +}; + +struct package_manager_request_cb_info { + int req_id; + package_manager_request_event_cb callback; void *user_data; }; @@ -72,6 +86,11 @@ struct package_manager_filter_s { pkgmgrinfo_pkginfo_filter_h pkgmgrinfo_pkginfo_filter; }; +struct package_updateinfo_request_s { + pkgmgr_client *pc; + pkg_update_info_t *updateinfo_handle; +}; + static int package_manager_request_new_id() { static int request_handle_id = 0; @@ -84,6 +103,92 @@ static int package_manager_new_id() return manager_handle_id++; } +static void __clean_all_event_info(request_event_info *head) +{ + request_event_info *current = head; + request_event_info *prev; + + if (current == NULL) + return; + + while (current) { + prev = current; + current = current->next; + free(prev); + } +} + +static int __insert_event_info(package_manager_h manager, const char *pkg_name, + package_manager_event_type_e event_type, + package_manager_event_state_e event_state) +{ + struct package_manager_event_info *info; + + info = calloc(1, sizeof(struct package_manager_event_info)); + if (info == NULL) + return -1; + info->pkg_name = strdup(pkg_name); + info->event_type = event_type; + info->event_state = event_state; + g_hash_table_insert(manager->event_info_table, info->pkg_name, info); + + return 0; +} + +static void __free_event_info(gpointer data) +{ + struct package_manager_event_info *info = + (struct package_manager_event_info *)data; + + if (!info) + return; + + if (info->pkg_name) + free(info->pkg_name); + free(info); + + _LOGD("event_info removed"); +} + +static void __free_request_cb_info(gpointer data) +{ + int req_id; + struct package_manager_request_cb_info *cb_info = + (struct package_manager_request_cb_info *)data; + + req_id = cb_info->req_id; + free(cb_info); + cb_info = NULL; + + _LOGD("request callback info removed, req_id(%d)", req_id); +} + +static void __initialize_request_cb_table(package_manager_request_h request) +{ + request->request_cb_table = + g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, __free_request_cb_info); +} + +static int __insert_request_cb_info(package_manager_request_h request, int req_id, + package_manager_request_event_cb callback, void *user_data) +{ + struct package_manager_request_cb_info *cb_info; + + if (request->request_cb_table == NULL) + return -1; + + cb_info = calloc(1, sizeof(struct package_manager_request_cb_info)); + if (cb_info == NULL) + return -1; + cb_info->req_id = req_id; + cb_info->callback = callback; + cb_info->user_data = user_data; + _LOGD("insert req_id(%d)", req_id); + g_hash_table_insert(request->request_cb_table, GINT_TO_POINTER(cb_info->req_id), cb_info); + + return 0; +} + API int package_manager_request_create(package_manager_request_h *request) { struct package_manager_request_s *package_manager_request; @@ -142,32 +247,43 @@ API int package_manager_request_destroy(package_manager_request_h request) pkgmgr_client_free(request->pc); request->pc = NULL; free(request->pkg_type); + __clean_all_event_info(request->head); + if (request->request_cb_table) { + g_hash_table_destroy(request->request_cb_table); + request->request_cb_table = NULL; + } free(request); return PACKAGE_MANAGER_ERROR_NONE; } +static int __reset_user_request_callback(package_manager_request_h request, + package_manager_request_event_cb callback, void *user_data) +{ + if (package_manager_client_validate_handle(request)) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + request->event_cb = callback; + request->user_data = user_data; + + return PACKAGE_MANAGER_ERROR_NONE; +} + API int package_manager_request_set_event_cb(package_manager_request_h request, package_manager_request_event_cb callback, void *user_data) { + int ret; - int retval; - retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO); - if (retval != PACKAGE_MANAGER_ERROR_NONE) - return retval; - - if (package_manager_client_validate_handle(request)) { - return - package_manager_error - (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, - NULL); - } + if (package_manager_client_validate_handle(request)) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); - request->event_cb = callback; - request->user_data = user_data; + ret = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO); + if (ret != PACKAGE_MANAGER_ERROR_NONE) + return ret; - return PACKAGE_MANAGER_ERROR_NONE; + return __reset_user_request_callback(request, callback, user_data); } API int package_manager_request_unset_event_cb(package_manager_request_h request) @@ -191,6 +307,8 @@ API int package_manager_request_set_type(package_manager_request_h request, NULL); } + if (request->pkg_type) + free(request->pkg_type); request->pkg_type = strdup(pkg_type); return PACKAGE_MANAGER_ERROR_NONE; @@ -246,27 +364,76 @@ static int package_manager_get_event_type(const char *key, *event_type = PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL; else if (strcasecmp(key, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0) *event_type = PACKAGE_MANAGER_EVENT_TYPE_UPDATE; + else if (strcasecmp(key, PKGMGR_INSTALLER_MOVE_EVENT_STR) == 0) + *event_type = PACKAGE_MANAGER_EVENT_TYPE_MOVE; + else if (strcasecmp(key, PKGMGR_INSTALLER_CLEAR_EVENT_STR) == 0) + *event_type = PACKAGE_MANAGER_EVENT_TYPE_CLEAR; else return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER; return PACKAGE_MANAGER_ERROR_NONE; } -static int __add_event_info(event_info **head, int req_id, +static package_manager_error_e __convert_to_error(const char *val) +{ + int errcode = atoi(val); + + switch (errcode) { + case PKGMGR_INSTALLER_ERRCODE_UNDEFINED_ERROR: + case PKGMGR_INSTALLER_ERRCODE_GLOBALSYMLINK_ERROR: + case PKGMGR_INSTALLER_ERRCODE_GRANT_PERMISSION_ERROR: + case PKGMGR_INSTALLER_ERRCODE_IMAGE_ERROR: + case PKGMGR_INSTALLER_ERRCODE_PARSE_ERROR: + case PKGMGR_INSTALLER_ERRCODE_RECOVERY_ERROR: + case PKGMGR_INSTALLER_ERRCODE_DELTA_ERROR: + case PKGMGR_INSTALLER_ERRCODE_APP_DIR_ERROR: + case PKGMGR_INSTALLER_ERRCODE_CONFIG_ERROR: + case PKGMGR_INSTALLER_ERRCODE_ICON_ERROR: + case PKGMGR_INSTALLER_ERRCODE_MANIFEST_ERROR: + case PKGMGR_INSTALLER_ERRCODE_OUT_OF_SPACE: + case PKGMGR_INSTALLER_ERRCODE_ERROR: + return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR; + case PKGMGR_INSTALLER_ERRCODE_UNZIP_ERROR: + case PKGMGR_INSTALLER_ERRCODE_SECURITY_ERROR: + case PKGMGR_INSTALLER_ERRCODE_REGISTER_ERROR: + case PKGMGR_INSTALLER_ERRCODE_PRIVILEGE_ERROR: + case PKGMGR_INSTALLER_ERRCODE_SIGNATURE_ERROR: + case PKGMGR_INSTALLER_ERRCODE_SIGNATURE_INVALID: + case PKGMGR_INSTALLER_ERRCODE_CERT_ERROR: + case PKGMGR_INSTALLER_ERRCODE_AUTHOR_CERT_NOT_MATCH: + case PKGMGR_INSTALLER_ERRCODE_AUTHOR_CERT_NOT_FOUND: + case PKGMGR_INSTALLER_ERRCODE_ICON_NOT_FOUND: + case PKGMGR_INSTALLER_ERRCODE_MANIFEST_NOT_FOUND: + return PACKAGE_MANAGER_ERROR_IO_ERROR; + case PKGMGR_INSTALLER_ERRCODE_PACKAGE_NOT_FOUND: + return PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE; + case PKGMGR_INSTALLER_ERRCODE_OPERATION_NOT_ALLOWED: + return PACKAGE_MANAGER_ERROR_PERMISSION_DENIED; + case PKGMGR_INSTALLER_ERRCODE_INVALID_VALUE: + return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER; + case PKGMGR_INSTALLER_ERRCODE_OK: + return PACKAGE_MANAGER_ERROR_NONE; + default: + return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR; + } +} + +static int __add_event_info(request_event_info **head, int req_id, package_manager_event_type_e event_type, package_manager_event_state_e event_state) { - event_info *evt_info; - event_info *current; - event_info *prev; + request_event_info *evt_info; + request_event_info *current; + request_event_info *prev; - evt_info = (event_info *) calloc(1, sizeof(event_info)); + evt_info = (request_event_info *) calloc(1, sizeof(request_event_info)); if (evt_info == NULL) { _LOGD("calloc failed"); return -1; } evt_info->req_id = req_id; evt_info->event_type = event_type; + evt_info->event_state = event_state; evt_info->next = NULL; if (*head == NULL) @@ -284,11 +451,11 @@ static int __add_event_info(event_info **head, int req_id, return 0; } -static int __find_event_info(event_info **head, int req_id, +static int __find_event_info(request_event_info **head, int req_id, package_manager_event_type_e *event_type, package_manager_event_state_e *event_state) { - event_info *tmp; + request_event_info *tmp; tmp = *head; @@ -297,11 +464,10 @@ static int __find_event_info(event_info **head, int req_id, return -1; } - _LOGD("tmp->req_id %d, event_type %d", tmp->req_id, event_type); - while (tmp) { if (tmp->req_id == req_id) { *event_type = tmp->event_type; + *event_state = tmp->event_state; return 0; } tmp = tmp->next; @@ -309,13 +475,13 @@ static int __find_event_info(event_info **head, int req_id, return -1; } -static int __update_event_info(event_info **head, int req_id, +static int __update_event_info(request_event_info **head, int req_id, package_manager_event_type_e event_type, package_manager_event_state_e event_state) { package_manager_event_type_e evt_type; package_manager_event_state_e evt_state; - event_info *tmp; + request_event_info *tmp; if (__find_event_info(head, req_id, &evt_type, &evt_state) != 0) __add_event_info(head, req_id, event_type, event_state); @@ -330,6 +496,7 @@ static int __update_event_info(event_info **head, int req_id, while (tmp) { if (tmp->req_id == req_id) { tmp->event_type = event_type; + tmp->event_state = event_state; return 0; } tmp = tmp->next; @@ -339,32 +506,6 @@ static int __update_event_info(event_info **head, int req_id, return -1; } -/* -static int __remove_event_info(event_info **head request, int req_id) -{ - event_info *current; - event_info *tmp; - - if (* == NULL) - return -1; - - current = *head; - while (current) { - if (current->next) { - if (current->next->req_id == req_id) { - tmp = current->next; - current->next = current->next->next; - free(tmp); - return 0; - } - } - tmp = tmp->next; - } - - return -1; -} -*/ - static int request_event_handler(uid_t target_uid, int req_id, const char *pkg_type, const char *pkg_name, const char *key, const char *val, const void *pmsg, void *data) @@ -373,8 +514,6 @@ static int request_event_handler(uid_t target_uid, int req_id, const char *pkg_t package_manager_event_type_e event_type = -1; package_manager_event_state_e event_state = -1; - _LOGD("request_event_handler is called"); - package_manager_request_h request = data; if (strcasecmp(key, "start") == 0) { @@ -409,24 +548,22 @@ static int request_event_handler(uid_t target_uid, int req_id, const char *pkg_t } } else if (strcasecmp(key, "error") == 0) { - if (strcasecmp(key, "0") != 0) { - if (__find_event_info - (&(request->head), req_id, &event_type, - &event_state) == 0) { - __update_event_info(&(request->head), req_id, - event_type, - PACKAGE_MANAGER_EVENT_STATE_FAILED); - } + if (__find_event_info + (&(request->head), req_id, &event_type, + &event_state) == 0) { + __update_event_info(&(request->head), req_id, + event_type, + PACKAGE_MANAGER_EVENT_STATE_FAILED); + } - if (request->event_cb) - request->event_cb(req_id, pkg_type, - pkg_name, event_type, - PACKAGE_MANAGER_EVENT_STATE_FAILED, - 0, - PACKAGE_MANAGER_ERROR_NONE, - request->user_data); + if (request->event_cb) + request->event_cb(req_id, pkg_type, + pkg_name, event_type, + PACKAGE_MANAGER_EVENT_STATE_FAILED, + 0, + __convert_to_error(val), + request->user_data); - } } else if (strcasecmp(key, "end") == 0) { if (__find_event_info (&(request->head), req_id, &event_type, @@ -447,7 +584,7 @@ static int request_event_handler(uid_t target_uid, int req_id, const char *pkg_t pkg_name, event_type, PACKAGE_MANAGER_EVENT_STATE_FAILED, 0, - PACKAGE_MANAGER_ERROR_NONE, + PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, request->user_data); } } @@ -455,10 +592,114 @@ static int request_event_handler(uid_t target_uid, int req_id, const char *pkg_t return PACKAGE_MANAGER_ERROR_NONE; } -API int package_manager_request_install(package_manager_request_h request, - const char *path, int *id) +static int internal_request_callback(uid_t target_uid, int req_id, const char *pkg_type, + const char *pkg_name, const char *key, + const char *val, const void *pmsg, void *data) { + int ret; + package_manager_event_type_e event_type = -1; + package_manager_event_state_e event_state = -1; + struct package_manager_request_cb_info *cb_info; + package_manager_request_event_cb event_cb; + void *user_data = NULL; + + _LOGD("request callback called, req_id[%d]", req_id); + + package_manager_request_h request = data; + + if (request->request_cb_table) + cb_info = g_hash_table_lookup(request->request_cb_table, + GINT_TO_POINTER(req_id)); + else + cb_info = NULL; + + if (!cb_info || (cb_info && !cb_info->callback)) { + _LOGE("no callback info"); + return 0; + } + + if (cb_info->req_id != req_id) { + _LOGE("not matched request id"); + return 0; + } + + event_cb = cb_info->callback; + user_data = cb_info->user_data; + + if (strcasecmp(key, "start") == 0) { + ret = package_manager_get_event_type(val, &event_type); + if (ret != PACKAGE_MANAGER_ERROR_NONE) + return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER; + + __add_event_info(&request->head, req_id, event_type, + PACKAGE_MANAGER_EVENT_STATE_STARTED); + + event_cb(req_id, pkg_type, pkg_name, + event_type, + PACKAGE_MANAGER_EVENT_STATE_STARTED, + 0, PACKAGE_MANAGER_ERROR_NONE, user_data); + } else if (strcasecmp(key, "install_percent") == 0) { + if (__find_event_info(&request->head, req_id, &event_type, + &event_state) == 0) { + __update_event_info(&request->head, req_id, + event_type, + PACKAGE_MANAGER_EVENT_STATE_PROCESSING); + event_cb(req_id, pkg_type, pkg_name, + event_type, + PACKAGE_MANAGER_EVENT_STATE_PROCESSING, + atoi(val), + PACKAGE_MANAGER_ERROR_NONE, + user_data); + } + } else if (strcasecmp(key, "error") == 0) { + if (__find_event_info(&request->head, req_id, &event_type, + &event_state) == 0) { + __update_event_info(&request->head, req_id, + event_type, + PACKAGE_MANAGER_EVENT_STATE_FAILED); + event_cb(req_id, pkg_type, + pkg_name, event_type, + PACKAGE_MANAGER_EVENT_STATE_FAILED, + 0, + __convert_to_error(val), + user_data); + } + } else if (strcasecmp(key, "end") == 0) { + if (__find_event_info(&request->head, req_id, &event_type, + &event_state) == 0) { + if (request->request_cb_table) { + _LOGD("remove item, req_id(%d)", req_id); + g_hash_table_remove(request->request_cb_table, + GINT_TO_POINTER(req_id)); + } + if (event_state != PACKAGE_MANAGER_EVENT_STATE_FAILED) { + if (strcasecmp(val, "ok") == 0) { + event_cb(req_id, pkg_type, + pkg_name, event_type, + PACKAGE_MANAGER_EVENT_STATE_COMPLETED, + 100, + PACKAGE_MANAGER_ERROR_NONE, + user_data); + } else { + event_cb(req_id, pkg_type, + pkg_name, event_type, + PACKAGE_MANAGER_EVENT_STATE_FAILED, + 0, + PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, + user_data); + } + } + } else { + _LOGE("unexpected end event"); + } + } + return 0; +} + +static int __request_install(package_manager_request_h request, + const char *path, pkgmgr_handler event_cb, int *id) +{ int retval; retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); if (retval != PACKAGE_MANAGER_ERROR_NONE) @@ -472,7 +713,7 @@ API int package_manager_request_install(package_manager_request_h request, int request_id = 0; request_id = pkgmgr_client_install(request->pc, request->pkg_type, NULL, - path, NULL, request->mode, request_event_handler, request); + path, NULL, request->mode, event_cb ? event_cb : request_event_handler, request); if (request_id == PKGMGR_R_EINVAL) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); @@ -487,15 +728,15 @@ API int package_manager_request_install(package_manager_request_h request, else if (request_id == PKGMGR_R_ESYSTEM || request_id == PKGMGR_R_ECOMM || request_id == PKGMGR_R_ERROR) return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); - *id = request_id; + if (id) + *id = request_id; return PACKAGE_MANAGER_ERROR_NONE; } -API int package_manager_request_uninstall(package_manager_request_h request, - const char *name, int *id) +static int __request_uninstall(package_manager_request_h request, + const char *name, pkgmgr_handler event_cb, int *id) { - int retval; retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); if (retval != PACKAGE_MANAGER_ERROR_NONE) @@ -509,7 +750,7 @@ API int package_manager_request_uninstall(package_manager_request_h request, int request_id = 0; request_id = pkgmgr_client_uninstall(request->pc, request->pkg_type, - name, request->mode, request_event_handler, request); + name, request->mode, event_cb ? event_cb : request_event_handler, request); if (request_id == PKGMGR_R_EINVAL) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); @@ -524,15 +765,16 @@ API int package_manager_request_uninstall(package_manager_request_h request, else if (request_id == PKGMGR_R_ESYSTEM || request_id == PKGMGR_R_ECOMM || request_id == PKGMGR_R_ERROR) return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); - *id = request_id; + if (id) + *id = request_id; return PACKAGE_MANAGER_ERROR_NONE; } -API int package_manager_request_move(package_manager_request_h request, - const char *name, package_manager_move_type_e move_type) +static int __request_move(package_manager_request_h request, + const char *name, package_manager_move_type_e move_type, + pkgmgr_handler event_cb, int *id) { - int retval; retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); if (retval != PACKAGE_MANAGER_ERROR_NONE) @@ -544,30 +786,190 @@ API int package_manager_request_move(package_manager_request_h request, if (name == NULL) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - int ret = 0; - ret = pkgmgr_client_request_service(PM_REQUEST_MOVE, move_type, + int request_id = 0; + request_id = pkgmgr_client_request_service(PM_REQUEST_MOVE, move_type, request->pc, request->pkg_type, name, - NULL, request_event_handler, NULL); + NULL, event_cb ? event_cb : request_event_handler, request); - if (ret == PKGMGR_R_EINVAL) + if (request_id == PKGMGR_R_EINVAL) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - else if (ret == PKGMGR_R_ENOPKG) + else if (request_id == PKGMGR_R_ENOPKG) return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); - else if (ret == PKGMGR_R_ENOMEM) + else if (request_id == PKGMGR_R_ENOMEM) return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); - else if (ret == PKGMGR_R_EIO) + else if (request_id == PKGMGR_R_EIO) return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); - else if (ret == PKGMGR_R_EPRIV) + else if (request_id == PKGMGR_R_EPRIV) return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL); - else if (ret == PKGMGR_R_ESYSTEM || ret == PKGMGR_R_ECOMM || ret == PKGMGR_R_ERROR) + else if (request_id == PKGMGR_R_ESYSTEM || request_id == PKGMGR_R_ECOMM || request_id == PKGMGR_R_ERROR) return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); + if (id) + *id = request_id; + return PACKAGE_MANAGER_ERROR_NONE; } -API int package_manager_create(package_manager_h *manager) +static int __request_mount_install(package_manager_request_h request, + const char *path, pkgmgr_handler event_cb, int *id) +{ + int retval; + retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); + if (retval != PACKAGE_MANAGER_ERROR_NONE) + return retval; + + if (package_manager_client_validate_handle(request)) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + if (path == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + int request_id = 0; + request_id = pkgmgr_client_mount_install(request->pc, request->pkg_type, NULL, + path, NULL, request->mode, event_cb ? event_cb : request_event_handler, request); + + if (request_id == PKGMGR_R_EINVAL) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + else if (request_id == PKGMGR_R_ENOPKG) + return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); + else if (request_id == PKGMGR_R_ENOMEM) + return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + else if (request_id == PKGMGR_R_EIO) + return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); + else if (request_id == PKGMGR_R_EPRIV) + return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL); + else if (request_id == PKGMGR_R_ESYSTEM || request_id == PKGMGR_R_ECOMM || request_id == PKGMGR_R_ERROR) + return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); + + if (id) + *id = request_id; + + return PACKAGE_MANAGER_ERROR_NONE; +} + + +API int package_manager_request_install(package_manager_request_h request, + const char *path, int *id) +{ + return __request_install(request, path, NULL, id); +} + +API int package_manager_request_install_with_cb(package_manager_request_h request, + const char *path, package_manager_request_event_cb callback, + void *user_data, int *id) +{ + int ret; + int req_id = 0; + + if (request->request_cb_table == NULL) + __initialize_request_cb_table(request); + + ret = __request_install(request, path, internal_request_callback, &req_id); + + if (req_id > 0) { + ret = __insert_request_cb_info(request, req_id, callback, user_data); + if (ret < 0) + return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, + __FUNCTION__, "failed to create request cb info"); + if (id) + *id = req_id; + } + + return ret; +} + +API int package_manager_request_uninstall(package_manager_request_h request, + const char *name, int *id) +{ + return __request_uninstall(request, name, NULL, id); +} + +API int package_manager_request_uninstall_with_cb(package_manager_request_h request, + const char *name, package_manager_request_event_cb callback, + void *user_data, int *id) +{ + int ret; + int req_id = 0; + + if (request->request_cb_table == NULL) + __initialize_request_cb_table(request); + + ret = __request_uninstall(request, name, internal_request_callback, &req_id); + + if (req_id > 0) { + ret = __insert_request_cb_info(request, req_id, callback, user_data); + if (ret < 0) + return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, + __FUNCTION__, "failed to create request cb info"); + if (id) + *id = req_id; + } + + return ret; +} + +API int package_manager_request_move(package_manager_request_h request, + const char *name, package_manager_move_type_e move_type) +{ + return __request_move(request, name, move_type, NULL, NULL); +} + +API int package_manager_request_move_with_cb(package_manager_request_h request, + const char *name, package_manager_move_type_e move_type, + package_manager_request_event_cb callback, void *user_data, int *id) +{ + int ret; + int req_id = 0; + + if (request->request_cb_table == NULL) + __initialize_request_cb_table(request); + + ret = __request_move(request, name, move_type, internal_request_callback, &req_id); + + if (req_id > 0) { + ret = __insert_request_cb_info(request, req_id, callback, user_data); + if (ret < 0) + return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, + __FUNCTION__, "failed to create request cb info"); + if (id) + *id = req_id; + } + + return ret; +} + +API int package_manager_request_mount_install(package_manager_request_h request, + const char *path, int *id) +{ + return __request_mount_install(request, path, NULL, id); +} + +API int package_manager_request_mount_install_with_cb(package_manager_request_h request, + const char *path, package_manager_request_event_cb callback, + void *user_data, int *id) { + int ret; + int req_id = 0; + if (request->request_cb_table == NULL) + __initialize_request_cb_table(request); + + ret = __request_mount_install(request, path, internal_request_callback, &req_id); + + if (req_id > 0) { + ret = __insert_request_cb_info(request, req_id, callback, user_data); + if (ret < 0) + return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, + __FUNCTION__, "failed to create request cb info"); + if (id) + *id = req_id; + } + + return ret; +} + +API int package_manager_create(package_manager_h *manager) +{ int retval; retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO); if (retval != PACKAGE_MANAGER_ERROR_NONE) @@ -625,77 +1027,12 @@ API int package_manager_destroy(package_manager_h manager) } pkgmgr_client_free(manager->pc); - manager->pc = NULL; + g_hash_table_destroy(manager->event_info_table); free(manager); return PACKAGE_MANAGER_ERROR_NONE; } -static int __add_event(event_info **head, int req_id, - package_manager_event_type_e event_type, - package_manager_event_state_e event_state) -{ - event_info *evt_info; - - evt_info = (event_info *) calloc(1, sizeof(event_info)); - if (evt_info == NULL) { - _LOGD("calloc failed"); - return -1; - } - evt_info->req_id = req_id; - evt_info->event_type = event_type; - evt_info->event_state = event_state; - evt_info->next = NULL; - - *head = evt_info; - - return 0; -} - -static int __find_event(event_info **head, int req_id, - package_manager_event_type_e *event_type, - package_manager_event_state_e *event_state) -{ - event_info *tmp; - - tmp = *head; - - if (tmp == NULL) { - _LOGE("tmp is NULL"); - return -1; - } - - *event_type = tmp->event_type; - *event_state = tmp->event_state; - return 0; -} - -static int __update_event(event_info **head, int req_id, - package_manager_event_type_e event_type, - package_manager_event_state_e event_state) -{ - package_manager_event_type_e evt_type; - package_manager_event_state_e evt_state; - event_info *tmp; - - if (__find_event_info(head, req_id, &evt_type, &evt_state) != 0) - __add_event_info(head, req_id, event_type, event_state); - else { - tmp = *head; - - if (tmp == NULL) { - _LOGE("tmp is NULL"); - return -1; - } - - tmp->event_type = event_type; - tmp->event_state = event_state; - return 0; - } - - return -1; -} - /* App Event Listening Policy: * +----------------+------------+---------------+------------------+ * |Listener \ Type |Global Event|My User's Event|Other user's Event| @@ -721,18 +1058,18 @@ static int __validate_event_signal(uid_t target_uid) return -1; } -static int global_event_handler(uid_t target_uid, int req_id, const char *pkg_type, +static int internal_callback(uid_t target_uid, int req_id, const char *pkg_type, const char *pkg_name, const char *key, const char *val, const void *pmsg, void *data) { int ret = -1; package_manager_event_type_e event_type = -1; - package_manager_event_state_e event_state = -1; + struct package_manager_event_info *info = NULL; + package_manager_h manager = data; uid_t uid = target_uid; - _LOGD("global_event_handler is called"); - - package_manager_h manager = data; + _LOGD("req_id(%d), pkg_name(%s), type(%s), key(%s), val(%s)", + req_id, pkg_name, pkg_type, key, val); if (target_uid == GLOBAL_USER) uid = getuid(); @@ -740,91 +1077,129 @@ static int global_event_handler(uid_t target_uid, int req_id, const char *pkg_ty if (__validate_event_signal(uid)) return PACKAGE_MANAGER_ERROR_NONE; + if (manager && manager->event_info_table) { + info = g_hash_table_lookup(manager->event_info_table, pkg_name); + } else { + _LOGE("invalid handle"); + return PACKAGE_MANAGER_ERROR_NONE; + } + + if (!info) { + if (strcasecmp(key, "start") != 0) { + _LOGD("unexpected signal or no info(removed)"); + return PACKAGE_MANAGER_ERROR_NONE; + } + } + if (strcasecmp(key, "start") == 0) { ret = package_manager_get_event_type(val, &event_type); if (ret != PACKAGE_MANAGER_ERROR_NONE) return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER; - __add_event(&(manager->head), req_id, event_type, - PACKAGE_MANAGER_EVENT_STATE_STARTED); + if (!info) { + __insert_event_info(manager, pkg_name, event_type, + PACKAGE_MANAGER_EVENT_STATE_STARTED); - if (manager->event_cb && getuid() == uid) - manager->event_cb(pkg_type, pkg_name, - event_type, - PACKAGE_MANAGER_EVENT_STATE_STARTED, - 0, PACKAGE_MANAGER_ERROR_NONE, manager->user_data); - } else if (strcasecmp(key, "install_percent") == 0 - || strcasecmp(key, "progress_percent") == 0) { - if (__find_event - (&(manager->head), req_id, &event_type, - &event_state) == 0) { - __update_event(&(manager->head), req_id, - event_type, - PACKAGE_MANAGER_EVENT_STATE_PROCESSING); if (manager->event_cb && getuid() == uid) manager->event_cb(pkg_type, pkg_name, - event_type, - PACKAGE_MANAGER_EVENT_STATE_PROCESSING, - atoi(val), - PACKAGE_MANAGER_ERROR_NONE, - manager->user_data); + event_type, + PACKAGE_MANAGER_EVENT_STATE_STARTED, + 0, + PACKAGE_MANAGER_ERROR_NONE, + manager->user_data); + } else { + _LOGE("unexpected start event"); } - + } else if (strcasecmp(key, "install_percent") == 0 + || strcasecmp(key, "progress_percent") == 0) { + info->event_state = PACKAGE_MANAGER_EVENT_STATE_PROCESSING; + if (manager->event_cb && getuid() == uid) + manager->event_cb(pkg_type, pkg_name, + info->event_type, + info->event_state, + atoi(val), + PACKAGE_MANAGER_ERROR_NONE, + manager->user_data); } else if (strcasecmp(key, "error") == 0) { - if (strcasecmp(key, "0") != 0) { - if (__find_event - (&(manager->head), req_id, &event_type, - &event_state) == 0) { - __update_event(&(manager->head), req_id, - event_type, - PACKAGE_MANAGER_EVENT_STATE_FAILED); - } - - if (manager->event_cb && getuid() == uid) - manager->event_cb(pkg_type, - pkg_name, event_type, - PACKAGE_MANAGER_EVENT_STATE_FAILED, - 0, - PACKAGE_MANAGER_ERROR_NONE, - manager->user_data); - } + info->event_state = PACKAGE_MANAGER_EVENT_STATE_FAILED; + if (manager->event_cb && getuid() == uid) + manager->event_cb(pkg_type, pkg_name, + info->event_type, + info->event_state, + 0, + __convert_to_error(val), + manager->user_data); } else if (strcasecmp(key, "end") == 0) { - if (__find_event - (&(manager->head), req_id, &event_type, - &event_state) == 0) { - if (event_state != PACKAGE_MANAGER_EVENT_STATE_FAILED) { - if (manager->event_cb && getuid() == uid) - manager->event_cb(pkg_type, - pkg_name, event_type, - PACKAGE_MANAGER_EVENT_STATE_COMPLETED, - 100, - PACKAGE_MANAGER_ERROR_NONE, - manager->user_data); - } - } else { - if (strcasecmp(key, "ok") != 0) { - if (manager->event_cb && getuid() == uid) - manager->event_cb(pkg_type, - pkg_name, event_type, - PACKAGE_MANAGER_EVENT_STATE_FAILED, - 0, - PACKAGE_MANAGER_ERROR_NONE, - manager->user_data); + if (info->event_state != PACKAGE_MANAGER_EVENT_STATE_FAILED) { + if (manager->event_cb && getuid() == uid) { + if (strcasecmp(val, "ok") == 0) { + manager->event_cb(pkg_type, pkg_name, + info->event_type, + PACKAGE_MANAGER_EVENT_STATE_COMPLETED, + 100, + PACKAGE_MANAGER_ERROR_NONE, + manager->user_data); + } else { + manager->event_cb(pkg_type, pkg_name, + info->event_type, + PACKAGE_MANAGER_EVENT_STATE_FAILED, + 0, + PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, + manager->user_data); + } } } + g_hash_table_remove(manager->event_info_table, info->pkg_name); } return PACKAGE_MANAGER_ERROR_NONE; } +static int __convert_status_type(package_manager_status_type_e status_type) +{ + int type = 0; + + if (status_type == PACKAGE_MANAGER_STATUS_TYPE_ALL) + return PKGMGR_CLIENT_STATUS_ALL; + + if (status_type & PACKAGE_MANAGER_STATUS_TYPE_INSTALL) + type |= PKGMGR_CLIENT_STATUS_INSTALL; + if (status_type & PACKAGE_MANAGER_STATUS_TYPE_UNINSTALL) + type |= PKGMGR_CLIENT_STATUS_UNINSTALL; + if (status_type & PACKAGE_MANAGER_STATUS_TYPE_UPGRADE) + type |= PKGMGR_CLIENT_STATUS_UPGRADE; + if (status_type & PACKAGE_MANAGER_STATUS_TYPE_MOVE) + type |= PKGMGR_CLIENT_STATUS_MOVE; + if (status_type & PACKAGE_MANAGER_STATUS_TYPE_CLEAR_DATA) + type |= PKGMGR_CLIENT_STATUS_CLEAR_DATA; + if (status_type & PACKAGE_MANAGER_STATUS_TYPE_INSTALL_PROGRESS) + type |= PKGMGR_CLIENT_STATUS_INSTALL_PROGRESS; + if (status_type & PACKAGE_MANAGER_STATUS_TYPE_GET_SIZE) + type |= PKGMGR_CLIENT_STATUS_GET_SIZE; + + return type; +} + API int package_manager_set_event_status(package_manager_h manager, int status_type) { int retval; + int type; + int type_all = PACKAGE_MANAGER_STATUS_TYPE_INSTALL | + PACKAGE_MANAGER_STATUS_TYPE_UNINSTALL | + PACKAGE_MANAGER_STATUS_TYPE_UPGRADE | + PACKAGE_MANAGER_STATUS_TYPE_MOVE | + PACKAGE_MANAGER_STATUS_TYPE_CLEAR_DATA | + PACKAGE_MANAGER_STATUS_TYPE_INSTALL_PROGRESS | + PACKAGE_MANAGER_STATUS_TYPE_GET_SIZE; if (manager == NULL) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - retval = pkgmgr_client_set_status_type(manager->pc, status_type); + if (status_type < 0 || status_type > type_all) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + type = __convert_status_type(status_type); + retval = pkgmgr_client_set_status_type(manager->pc, type); if (retval < 0) return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); @@ -836,7 +1211,6 @@ API int package_manager_set_event_cb(package_manager_h manager, package_manager_event_cb callback, void *user_data) { - int retval; retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO); if (retval != PACKAGE_MANAGER_ERROR_NONE) @@ -852,7 +1226,18 @@ API int package_manager_set_event_cb(package_manager_h manager, manager->event_cb = callback; manager->user_data = user_data; - pkgmgr_client_listen_status(manager->pc, global_event_handler, manager); + retval = pkgmgr_client_listen_status(manager->pc, + internal_callback, manager); + if (retval < 0) { + return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, + __FUNCTION__, NULL); + } + + if (!manager->event_info_table) { + manager->event_info_table = + g_hash_table_new_full(g_str_hash, g_str_equal, + NULL, __free_event_info); + } return PACKAGE_MANAGER_ERROR_NONE; } @@ -870,6 +1255,8 @@ API int package_manager_unset_event_cb(package_manager_h manager) manager->event_cb = NULL; manager->user_data = NULL; + g_hash_table_remove_all(manager->event_info_table); + retval = pkgmgr_client_remove_listen_status(manager->pc); if (retval == PKGMGR_R_EINVAL) return @@ -902,8 +1289,10 @@ API int package_manager_get_package_id_by_app_id(const char *app_id, char **pack if (pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo) != PMINFO_R_OK) return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); retval = pkgmgrinfo_appinfo_get_pkgname(pkgmgrinfo_appinfo, &pkg_id); - if (retval != PMINFO_R_OK) + if (retval != PMINFO_R_OK) { + pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo); return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); + } pkg_id_dup = strdup(pkg_id); if (pkg_id_dup == NULL) { @@ -936,7 +1325,6 @@ API int package_manager_get_package_info(const char *package_id, package_info_h API int package_manager_foreach_package_info(package_manager_package_info_cb callback, void *user_data) { - int retval; retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO); if (retval != PACKAGE_MANAGER_ERROR_NONE) @@ -979,7 +1367,6 @@ API int package_manager_compare_app_cert_info(const char *lhs_app_id, const char API int package_manager_is_preload_package_by_app_id(const char *app_id, bool *preload) { - int retval; retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO); if (retval != PACKAGE_MANAGER_ERROR_NONE) @@ -1022,7 +1409,6 @@ API int package_manager_is_preload_package_by_app_id(const char *app_id, bool *p API int package_manager_get_permission_type(const char *app_id, package_manager_permission_type_e *permission_type) { - int retval; retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO); if (retval != PACKAGE_MANAGER_ERROR_NONE) @@ -1033,8 +1419,10 @@ API int package_manager_get_permission_type(const char *app_id, package_manager_ if (pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo) != PMINFO_R_OK) return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); retval = pkgmgrinfo_appinfo_get_permission_type(pkgmgrinfo_appinfo, &permission); - if (retval != PMINFO_R_OK) + if (retval != PMINFO_R_OK) { + pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo); return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); + } if (permission == PMINFO_PERMISSION_NORMAL) *permission_type = PACKAGE_MANAGER_PERMISSION_NORMAL; @@ -1051,7 +1439,6 @@ API int package_manager_get_permission_type(const char *app_id, package_manager_ API int package_manager_clear_cache_dir(const char *package_id) { - int retval; retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_CACHE); if (retval != PACKAGE_MANAGER_ERROR_NONE) @@ -1078,9 +1465,65 @@ API int package_manager_clear_cache_dir(const char *package_id) return PACKAGE_MANAGER_ERROR_NONE; } -API int package_manager_clear_all_cache_dir(void) +API int package_manager_clear_data_dir(const char *package_id) { + int retval; + pkgmgr_client *pc = NULL; + char *pkg_type = NULL; + pkgmgrinfo_pkginfo_h pkginfo = NULL; + + if (package_id == NULL) + return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER; + retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); + if (retval != PACKAGE_MANAGER_ERROR_NONE) + return retval; + + retval = pkgmgrinfo_pkginfo_get_pkginfo(package_id, &pkginfo); + if (retval == PMINFO_R_ENOENT) + return PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE; + else if (retval != PMINFO_R_OK || pkginfo == NULL) + return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR; + + retval = pkgmgrinfo_pkginfo_get_type(pkginfo, &pkg_type); + if (retval != PMINFO_R_OK || pkg_type == NULL) { + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR; + } + + pc = pkgmgr_client_new(PC_REQUEST); + if (pc == NULL) { + _LOGE("Out of memory"); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + return PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY; + } + + retval = pkgmgr_client_clear_user_data(pc, pkg_type, package_id, PM_QUIET); + pkgmgr_client_free(pc); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + + if (retval == PKGMGR_R_EINVAL) { + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } else if (retval == PKGMGR_R_ENOPKG) { + return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); + } else if (retval == PKGMGR_R_ENOMEM) { + return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + } else if (retval == PKGMGR_R_EIO) { + return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); + } else if (retval == PKGMGR_R_EPRIV) { + return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL); + } else if (retval == PKGMGR_R_ESYSTEM || retval == PKGMGR_R_ECOMM || retval == PKGMGR_R_ERROR) { + return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); + } else if (retval != PKGMGR_R_OK) { + _LOGE("Unexpected error"); + return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); + } + + return PACKAGE_MANAGER_ERROR_NONE; +} + +API int package_manager_clear_all_cache_dir(void) +{ int retval; retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); if (retval != PACKAGE_MANAGER_ERROR_NONE) @@ -1188,7 +1631,6 @@ static int _get_pkg_size_info(const char *package_id, void *callback, void *user g_hash_table_insert(__cb_table, pc, callback); - _LOGD("Successful"); return PACKAGE_MANAGER_ERROR_NONE; } @@ -1266,7 +1708,6 @@ API int package_manager_filter_add_bool(package_manager_filter_h handle, API int package_manager_filter_count(package_manager_filter_h handle, int *count) { - int retval; retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO); if (retval != PACKAGE_MANAGER_ERROR_NONE) @@ -1285,7 +1726,6 @@ API int package_manager_filter_count(package_manager_filter_h handle, int *count API int package_manager_filter_foreach_package_info(package_manager_filter_h handle, package_manager_package_info_cb callback, void *user_data) { - int retval; retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO); if (retval != PACKAGE_MANAGER_ERROR_NONE) @@ -1360,3 +1800,182 @@ API int package_size_info_get_external_app_size(package_size_info_h handle, long *ext_app_size = size_info->external_app_size; return PACKAGE_MANAGER_ERROR_NONE; } + +API int package_manager_updateinfo_set_pkgid(package_updateinfo_request_h pkg_updateinfo_req, const char *pkgid) +{ + struct package_updateinfo_request_s *request; + + if (pkg_updateinfo_req == NULL || pkg_updateinfo_req->updateinfo_handle == NULL || pkgid == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + request = (struct package_updateinfo_request_s *)pkg_updateinfo_req; + if (request->updateinfo_handle->pkgid) + free(request->updateinfo_handle->pkgid); + request->updateinfo_handle->pkgid = strdup(pkgid); + if (request->updateinfo_handle->pkgid == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + + return PACKAGE_MANAGER_ERROR_NONE; +} + +API int package_manager_updateinfo_set_version(package_updateinfo_request_h pkg_updateinfo_req, const char *version) +{ + struct package_updateinfo_request_s *request; + + if (pkg_updateinfo_req == NULL || pkg_updateinfo_req->updateinfo_handle == NULL || version == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + request = (struct package_updateinfo_request_s *)pkg_updateinfo_req; + if (request->updateinfo_handle->version) + free(request->updateinfo_handle->version); + request->updateinfo_handle->version = strdup(version); + if (request->updateinfo_handle->version == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + + return PACKAGE_MANAGER_ERROR_NONE; +} + +static int package_manager_updateinfo_convert_property(package_updateinfo_type_e property, pkgmgr_updateinfo_type *converted_property) +{ + if (converted_property == NULL) + return -1; + + if (property == PACKAGE_UPDATEINFO_TYPE_FORCE) + *converted_property = PM_UPDATEINFO_TYPE_FORCE; + else if (property == PACKAGE_UPDATEINFO_TYPE_OPTIONAL) + *converted_property = PM_UPDATEINFO_TYPE_OPTIONAL; + else if (property == PACKAGE_UPDATEINFO_TYPE_NONE) + *converted_property = PM_UPDATEINFO_TYPE_NONE; + else + return -1; + + return 0; +} + +API int package_manager_updateinfo_set_type(package_updateinfo_request_h pkg_updateinfo_req, package_updateinfo_type_e type) +{ + int retval; + pkgmgr_updateinfo_type converted_type; + struct package_updateinfo_request_s *request; + + if (pkg_updateinfo_req == NULL || pkg_updateinfo_req->updateinfo_handle == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + request = (struct package_updateinfo_request_s *)pkg_updateinfo_req; + retval = package_manager_updateinfo_convert_property(type, &converted_type); + if (retval != 0) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + request->updateinfo_handle->type = converted_type; + return PACKAGE_MANAGER_ERROR_NONE; +} + +API int package_manager_updateinfo_request_destroy(package_updateinfo_request_h pkg_updateinfo_req) +{ + struct package_updateinfo_request_s *request; + + if (pkg_updateinfo_req == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + request = (struct package_updateinfo_request_s *)pkg_updateinfo_req; + if (request->pc) + pkgmgr_client_free(request->pc); + + if (request->updateinfo_handle) { + if (request->updateinfo_handle->pkgid) + free(request->updateinfo_handle->pkgid); + if (request->updateinfo_handle->version) + free(request->updateinfo_handle->version); + free(request->updateinfo_handle); + } + free(request); + + return PACKAGE_MANAGER_ERROR_NONE; +} + +API int package_manager_updateinfo_request_create(package_updateinfo_request_h *pkg_updateinfo_req) +{ + struct package_updateinfo_request_s *request; + pkg_update_info_t *update_info; + + if (pkg_updateinfo_req == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + request = calloc(1, sizeof(struct package_updateinfo_request_s)); + if (request == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + + request->pc = pkgmgr_client_new(PC_REQUEST); + if (request->pc == NULL) { + free(request); + return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + } + + update_info = calloc(1, sizeof(pkg_update_info_t)); + if (update_info == NULL) { + pkgmgr_client_free(request->pc); + free(request); + return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + } + request->updateinfo_handle = update_info; + + *pkg_updateinfo_req = request; + return PACKAGE_MANAGER_ERROR_NONE; +} + +API int package_manager_updateinfo_request_register(package_updateinfo_request_h pkg_updateinfo_req) +{ + struct package_updateinfo_request_s *update_info; + int retval; + + if (pkg_updateinfo_req == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + update_info = (struct package_updateinfo_request_s *)pkg_updateinfo_req; + + retval = pkgmgr_client_register_pkg_update_info(update_info->pc, update_info->updateinfo_handle); + if (retval == PKGMGR_R_EINVAL) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + return PACKAGE_MANAGER_ERROR_NONE; +} + +API int package_manager_updateinfo_request_unregister(package_updateinfo_request_h pkg_updateinfo_req, const char *pkgid) +{ + int retval; + struct package_updateinfo_request_s *update_info; + + retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); + if (retval != PACKAGE_MANAGER_ERROR_NONE) + return retval; + + if (pkg_updateinfo_req == NULL || pkgid == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + update_info = (struct package_updateinfo_request_s *)pkg_updateinfo_req; + retval = pkgmgr_client_unregister_pkg_update_info(update_info->pc, pkgid); + if (retval != PMINFO_R_OK) + return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); + + return PACKAGE_MANAGER_ERROR_NONE; +} + +API int package_manager_updateinfo_request_unregister_all(package_updateinfo_request_h pkg_updateinfo_req) +{ + int retval; + struct package_updateinfo_request_s *update_info; + + retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); + if (retval != PACKAGE_MANAGER_ERROR_NONE) + return retval; + + if (pkg_updateinfo_req == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + update_info = (struct package_updateinfo_request_s *)pkg_updateinfo_req; + retval = pkgmgr_client_unregister_all_pkg_update_info(update_info->pc); + + if (retval != PMINFO_R_OK) + return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); + + return PACKAGE_MANAGER_ERROR_NONE; +}