X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fpackage_manager.c;h=5bf2a4498010c7c07b59a7a2db51af0a9ee2c0b4;hb=17e7746420b816c2467243857db7f43d124193b7;hp=2e532bb72706493bfaab78f3f865df5691589eb8;hpb=d8ff394f8821fcc57ee6a899ff6736145401738e;p=platform%2Fcore%2Fapi%2Fpackage-manager.git diff --git a/src/package_manager.c b/src/package_manager.c index 2e532bb..5bf2a44 100644 --- a/src/package_manager.c +++ b/src/package_manager.c @@ -21,44 +21,60 @@ #include #include +#include #include #include #include "package_manager.h" #include "package_manager_internal.h" -static GHashTable *__cb_table = NULL; - #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) -typedef struct _event_info { +#define USER_HOME tzplatform_getenv(TZ_USER_HOME) + +#define PRIV_SHARED_RES "priv_shared_res" + +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; - client_type ctype; + pkgmgr_client_type ctype; pkgmgr_client *pc; pkgmgr_mode mode; - event_info *head; + GHashTable *event_info_table; package_manager_event_cb event_cb; + package_manager_res_event_cb res_event_cb; void *user_data; + GMutex mutex; }; struct package_manager_request_s { int handle_id; - client_type ctype; + pkgmgr_client_type ctype; pkgmgr_client *pc; - const char *pkg_type; - const char *pkg_path; - const char *pkg_name; - const char *tep_path; + char *pkg_type; pkgmgr_mode mode; - event_info *head; + request_event_info *head; package_manager_request_event_cb event_cb; - bool tep_move; + GHashTable *request_cb_table; + int n_paths; + void *user_data; +}; + +struct package_manager_request_cb_info { + int req_id; + package_manager_request_event_cb callback; + package_manager_request_res_event_cb res_callback; void *user_data; }; @@ -76,6 +92,15 @@ 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; +}; + +struct package_manager_res_event_info_s { + pkgmgr_res_event_info *res_event_info_handle; +}; + static int package_manager_request_new_id() { static int request_handle_id = 0; @@ -88,6 +113,113 @@ 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; +} + +static int __insert_res_request_cb_info(package_manager_request_h request, + int req_id, package_manager_request_res_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->res_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; @@ -145,33 +277,44 @@ API int package_manager_request_destroy(package_manager_request_h request) pkgmgr_client_free(request->pc); request->pc = NULL; - free(request->tep_path); + 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) @@ -195,7 +338,9 @@ API int package_manager_request_set_type(package_manager_request_h request, NULL); } - request->pkg_type = pkg_type; + if (request->pkg_type) + free(request->pkg_type); + request->pkg_type = strdup(pkg_type); return PACKAGE_MANAGER_ERROR_NONE; } @@ -210,10 +355,7 @@ API int package_manager_request_set_mode(package_manager_request_h request, NULL); } - if (mode == PACKAGE_MANAGER_REQUEST_MODE_QUIET) - request->mode = PM_QUIET; - else - request->mode = PM_DEFAULT; + /* request mode is not used anymore */ return PACKAGE_MANAGER_ERROR_NONE; } @@ -230,17 +372,7 @@ API int package_manager_request_set_tep(package_manager_request_h request, NULL); } - retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); - if (retval != PACKAGE_MANAGER_ERROR_NONE) - return retval; - - if (request->tep_path) - free((void *)request->tep_path); - - request->tep_path = strdup(tep_path); - request->tep_move = true; - - if (request->tep_path == NULL) + if (pkgmgr_client_set_tep_path(request->pc, tep_path, true)) return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR; return PACKAGE_MANAGER_ERROR_NONE; @@ -259,27 +391,89 @@ 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 if (strcasecmp(key, PKGMGR_INSTALLER_RES_COPY_EVENT_STR) == 0) + *event_type = PACKAGE_MANAGER_EVENT_TYPE_RES_COPY; + else if (strcasecmp(key, PKGMGR_INSTALLER_RES_CREATE_DIR_EVENT_STR) == 0) + *event_type = PACKAGE_MANAGER_EVENT_TYPE_RES_CREATE_DIR; + else if (strcasecmp(key, PKGMGR_INSTALLER_RES_REMOVE_EVENT_STR) == 0) + *event_type = PACKAGE_MANAGER_EVENT_TYPE_RES_REMOVE; + else if (strcasecmp(key, PKGMGR_INSTALLER_RES_UNINSTALL_EVENT_STR) == 0) + *event_type = PACKAGE_MANAGER_EVENT_TYPE_RES_UNINSTALL; 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(int errcode) +{ + 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 package_manager_error_e __convert_str_to_error(const char *val) +{ + int errcode = atoi(val); + + return __convert_to_error(errcode); +} + +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) @@ -297,11 +491,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; @@ -310,11 +504,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; @@ -322,13 +515,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); @@ -343,6 +536,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; @@ -352,32 +546,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) @@ -386,8 +554,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) { @@ -422,24 +588,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_str_to_error(val), + request->user_data); - } } else if (strcasecmp(key, "end") == 0) { if (__find_event_info (&(request->head), req_id, &event_type, @@ -460,7 +624,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); } } @@ -468,14 +632,181 @@ 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_str_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) { + request->n_paths--; + if (request->n_paths < 1) { + _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 void internal_res_request_callback(uid_t target_uid, int req_id, + const char *pkgid, const char *request_type, const char *status, + pkgmgr_res_event_info *handle, 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_res_event_cb event_cb; + struct package_manager_res_event_info_s event_info; + void *user_data = NULL; + + _LOGD("request callback called, req_id[%d]", req_id); + + package_manager_request_h request = data; + event_info.res_event_info_handle = handle; + + 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->res_callback)) { + _LOGE("no callback info"); + return; + } + + if (cb_info->req_id != req_id) { + _LOGE("not matched request id"); + return; + } + + event_cb = cb_info->res_callback; + user_data = cb_info->user_data; + + ret = package_manager_get_event_type(request_type, &event_type); + if (ret != PACKAGE_MANAGER_ERROR_NONE) + return; + if (strcasecmp(status, "start") == 0) { + event_state = PACKAGE_MANAGER_EVENT_STATE_STARTED; + } else if (strcasecmp(status, "fail") == 0) { + event_state = PACKAGE_MANAGER_EVENT_STATE_FAILED; + _LOGD("remove item, req_id(%d)", req_id); + g_hash_table_remove(request->request_cb_table, + GINT_TO_POINTER(req_id)); + } else if (strcasecmp(status, "ok") == 0) { + event_state = PACKAGE_MANAGER_EVENT_STATE_COMPLETED; + _LOGD("remove item, req_id(%d)", req_id); + g_hash_table_remove(request->request_cb_table, + GINT_TO_POINTER(req_id)); + } else { + _LOGE("unexpected event"); + return; + } + + event_cb(req_id, pkgid, event_type, event_state, + &event_info, user_data); + return; +} + +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) - return retval; if (package_manager_client_validate_handle(request)) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); @@ -484,46 +815,54 @@ API int package_manager_request_install(package_manager_request_h request, return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); int request_id = 0; - request->pkg_path = path; - uid_t uid = getuid(); - if (uid != GLOBAL_USER) - request_id = pkgmgr_client_usr_install(request->pc, request->pkg_type, NULL, - request->pkg_path, NULL, - request->mode, request_event_handler, - request, - uid); - else - request_id = pkgmgr_client_install(request->pc, request->pkg_type, NULL, - request->pkg_path, NULL, - request->mode, 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); + request_id = pkgmgr_client_install(request->pc, request->pkg_type, NULL, + path, NULL, request->mode, event_cb ? event_cb : request_event_handler, request); + if (request_id < 0) { + retval = package_manager_convert_internal_error(request_id); + return package_manager_error(retval, __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_install_packages(package_manager_request_h request, + const char **paths, int n_paths, pkgmgr_handler event_cb, + int *id) { + int retval; + + if (package_manager_client_validate_handle(request)) + return package_manager_error( + PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); + + if (paths == NULL || n_paths < 1) + return package_manager_error( + PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); + request->n_paths = n_paths; + int request_id = 0; + request_id = pkgmgr_client_install_packages(request->pc, paths, + n_paths, event_cb ? event_cb : request_event_handler, + request); + if (request_id < 0) { + retval = package_manager_convert_internal_error(request_id); + return package_manager_error(retval, __FUNCTION__, NULL); + } + + if (id) + *id = request_id; + + return PACKAGE_MANAGER_ERROR_NONE; +} +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) - return retval; if (package_manager_client_validate_handle(request)) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); @@ -532,43 +871,24 @@ API int package_manager_request_uninstall(package_manager_request_h request, return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); int request_id = 0; - request->pkg_name = name; - uid_t uid = getuid(); - if (uid != GLOBAL_USER) - request_id = pkgmgr_client_usr_uninstall(request->pc, request->pkg_type, - request->pkg_name, request->mode, - request_event_handler, request, uid); - else - request_id = pkgmgr_client_uninstall(request->pc, request->pkg_type, - request->pkg_name, request->mode, - 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); + request_id = pkgmgr_client_uninstall(request->pc, request->pkg_type, + name, request->mode, event_cb ? event_cb : request_event_handler, request); + if (request_id < 0) { + retval = package_manager_convert_internal_error(request_id); + return package_manager_error(retval, __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) - return retval; if (package_manager_client_validate_handle(request)) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); @@ -576,41 +896,337 @@ 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; - request->pkg_name = name; - uid_t uid = getuid(); - if (uid != GLOBAL_USER) - ret = pkgmgr_client_usr_request_service(PM_REQUEST_MOVE, move_type, - request->pc, request->pkg_type, request->pkg_name, - uid, NULL, request_event_handler, NULL); - else - ret = pkgmgr_client_request_service(PM_REQUEST_MOVE, move_type, - request->pc, request->pkg_type, request->pkg_name, - NULL, request_event_handler, NULL); - - if (ret == PKGMGR_R_EINVAL) - return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - else if (ret == PKGMGR_R_ENOPKG) - return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); - else if (ret == PKGMGR_R_ENOMEM) - return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); - else if (ret == PKGMGR_R_EIO) - return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); - else if (ret == 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) - return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); + int request_id = 0; + request_id = pkgmgr_client_request_service(PM_REQUEST_MOVE, move_type, + request->pc, request->pkg_type, name, + NULL, event_cb ? event_cb : request_event_handler, request); + if (request_id < 0) { + retval = package_manager_convert_internal_error(request_id); + return package_manager_error(retval, __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_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 (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 < 0) { + retval = package_manager_convert_internal_error(request_id); + return package_manager_error(retval, __FUNCTION__, NULL); + } + + if (id) + *id = request_id; + + return PACKAGE_MANAGER_ERROR_NONE; +} + +static int __request_mount_install_packages(package_manager_request_h request, + const char **paths, int n_paths, pkgmgr_handler event_cb, + int *id) +{ + int retval; + + if (package_manager_client_validate_handle(request)) + return package_manager_error( + PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); + + if (paths == NULL || n_paths < 1) + return package_manager_error( + PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); + request->n_paths = n_paths; + int request_id = 0; + request_id = pkgmgr_client_mount_install_packages(request->pc, paths, + n_paths, event_cb ? event_cb : request_event_handler, + request); + if (request_id < 0) { + retval = package_manager_convert_internal_error(request_id); + return package_manager_error(retval, __FUNCTION__, NULL); + } + + if (id) + *id = request_id; + + return PACKAGE_MANAGER_ERROR_NONE; +} + +static int __request_res_copy(package_manager_request_h request, + pkgmgr_res_handler event_cb, int *id) +{ + int retval; + + if (package_manager_client_validate_handle(request)) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + int request_id = 0; + request_id = pkgmgr_client_res_copy(request->pc, event_cb, request); + if (request_id < 0) { + retval = package_manager_convert_internal_error(request_id); + return package_manager_error(retval, __FUNCTION__, NULL); + } + if (id) + *id = request_id; + + return PACKAGE_MANAGER_ERROR_NONE; +} + +static int __request_res_create_dir(package_manager_request_h request, + pkgmgr_res_handler event_cb, int *id) +{ + int retval; + + if (package_manager_client_validate_handle(request)) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + int request_id = 0; + request_id = pkgmgr_client_res_create_dir(request->pc, event_cb, request); + if (request_id < 0) { + retval = package_manager_convert_internal_error(request_id); + return package_manager_error(retval, __FUNCTION__, NULL); + } + + if (id) + *id = request_id; + + return PACKAGE_MANAGER_ERROR_NONE; +} + +static int __request_res_remove(package_manager_request_h request, + pkgmgr_res_handler event_cb, int *id) +{ + int retval; + + if (package_manager_client_validate_handle(request)) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + int request_id = 0; + request_id = pkgmgr_client_res_remove(request->pc, event_cb, request); + if (request_id < 0) { + retval = package_manager_convert_internal_error(request_id); + return package_manager_error(retval, __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_install_packages( + package_manager_request_h request, const char **paths, + int paths_count, int *id) +{ + return __request_install_packages(request, paths, paths_count, NULL, id); +} + +API int package_manager_request_install_packages_with_cb( + package_manager_request_h request, const char **paths, + int paths_count, 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_packages(request, paths, paths_count, + 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_request_mount_install_packages( + package_manager_request_h request, const char **paths, + int paths_count, int *id) +{ + return __request_mount_install_packages(request, paths, paths_count, NULL, + id); +} + +API int package_manager_request_mount_install_packages_with_cb( + package_manager_request_h request, const char **paths, + int paths_count, 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_packages(request, paths, paths_count, + 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) + return retval; struct package_manager_s *package_manager = NULL; @@ -640,6 +1256,7 @@ API int package_manager_create(package_manager_h *manager) } package_manager->handle_id = package_manager_new_id(); + g_mutex_init(&package_manager->mutex); *manager = package_manager; @@ -663,75 +1280,14 @@ API int package_manager_destroy(package_manager_h manager) NULL); } + g_mutex_clear(&manager->mutex); 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->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; - 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; - return 0; - } - - return -1; -} - /* App Event Listening Policy: * +----------------+------------+---------------+------------------+ * |Listener \ Type |Global Event|My User's Event|Other user's Event| @@ -757,18 +1313,22 @@ 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) { + struct package_manager_event_info *info = NULL; int ret = -1; - package_manager_event_type_e event_type = -1; - package_manager_event_state_e event_state = -1; + package_manager_h manager = data; uid_t uid = target_uid; + bool invoke_callback = false; + package_manager_event_type_e event_type = -1; + package_manager_event_state_e event_state; + int progress = 0; + package_manager_error_e error = PACKAGE_MANAGER_ERROR_NONE; - _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(); @@ -776,91 +1336,203 @@ 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) { + g_mutex_lock(&manager->mutex); + 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)"); + g_mutex_unlock(&manager->mutex); + 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) + if (ret != PACKAGE_MANAGER_ERROR_NONE) { + g_mutex_unlock(&manager->mutex); 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); + event_state = PACKAGE_MANAGER_EVENT_STATE_STARTED; + progress = 0; + error = PACKAGE_MANAGER_ERROR_NONE; + invoke_callback = true; + } else { + _LOGE("unexpected start event"); + } } 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); - } - + info->event_state = PACKAGE_MANAGER_EVENT_STATE_PROCESSING; + event_type = info->event_type; + event_state = info->event_state; + progress = atoi(val); + error = PACKAGE_MANAGER_ERROR_NONE; + invoke_callback = true; } 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; + event_type = info->event_type; + event_state = info->event_state; + progress = 0; + error = __convert_str_to_error(val); + invoke_callback = true; } 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 (strcasecmp(val, "ok") == 0) { + event_type = info->event_type; + event_state = + PACKAGE_MANAGER_EVENT_STATE_COMPLETED; + progress = 100; + error = PACKAGE_MANAGER_ERROR_NONE; + invoke_callback = true; + } else { + event_type = info->event_type; + event_state = + PACKAGE_MANAGER_EVENT_STATE_FAILED; + progress = 0; + error = PACKAGE_MANAGER_ERROR_SYSTEM_ERROR; + invoke_callback = true; } } + g_hash_table_remove(manager->event_info_table, info->pkg_name); + } + g_mutex_unlock(&manager->mutex); + + if (invoke_callback && manager->event_cb && getuid() == uid) { + manager->event_cb(pkg_type, pkg_name, event_type, event_state, + progress, error, manager->user_data); } return PACKAGE_MANAGER_ERROR_NONE; } +static void internal_res_callback(uid_t target_uid, int req_id, + const char *pkgid, const char *request_type, const char *status, + pkgmgr_res_event_info *handle, void *data) +{ + int ret = -1; + package_manager_h manager = data; + uid_t uid = target_uid; + package_manager_event_type_e event_type = -1; + package_manager_event_state_e event_state; + struct package_manager_res_event_info_s event_info; + + event_info.res_event_info_handle = handle; + + _LOGD("req_id(%d), pkg_name(%s), request_type(%s), status(%s)", + req_id, pkgid, request_type, status); + + if (target_uid == GLOBAL_USER) + uid = getuid(); + + if (__validate_event_signal(uid)) + return; + + if (manager) { + g_mutex_lock(&manager->mutex); + } else { + _LOGE("invalid handle"); + return; + } + ret = package_manager_get_event_type(request_type, &event_type); + if (ret != PACKAGE_MANAGER_ERROR_NONE) { + g_mutex_unlock(&manager->mutex); + return; + } + + if (strcasecmp(status, "start") == 0) { + event_state = PACKAGE_MANAGER_EVENT_STATE_STARTED; + } else if (strcasecmp(status, "fail") == 0) { + event_state = PACKAGE_MANAGER_EVENT_STATE_FAILED; + } else if (strcasecmp(status, "ok") == 0) { + event_state = PACKAGE_MANAGER_EVENT_STATE_COMPLETED; + } else { + _LOGE("unexpected event"); + g_mutex_unlock(&manager->mutex); + return; + } + g_mutex_unlock(&manager->mutex); + + if (manager->res_event_cb && getuid() == uid) { + _LOGE("call callback"); + manager->res_event_cb(pkgid, event_type, event_state, + &event_info, manager->user_data); + } else { + if (!manager->res_event_cb) + _LOGE("res_event_cb is null"); + if (getuid() != uid) + _LOGE("getuid : %d, uid : %d", getuid(), uid); + } + + return; +} + +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; + if (status_type & PACKAGE_MANAGER_STATUS_TYPE_RES_COPY) + type |= PKGMGR_CLIENT_STATUS_RES_COPY; + if (status_type & PACKAGE_MANAGER_STATUS_TYPE_RES_CREATE_DIR) + type |= PKGMGR_CLIENT_STATUS_RES_CREATE_DIR; + if (status_type & PACKAGE_MANAGER_STATUS_TYPE_RES_REMOVE) + type |= PKGMGR_CLIENT_STATUS_RES_REMOVE; + if (status_type & PACKAGE_MANAGER_STATUS_TYPE_RES_UNINSTALL) + type |= PKGMGR_CLIENT_STATUS_RES_UNINSTALL; + + 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 | + PACKAGE_MANAGER_STATUS_TYPE_RES_COPY | + PACKAGE_MANAGER_STATUS_TYPE_RES_CREATE_DIR | + PACKAGE_MANAGER_STATUS_TYPE_RES_REMOVE | + PACKAGE_MANAGER_STATUS_TYPE_RES_UNINSTALL; if (manager == NULL) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - retval = pkgmgrinfo_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); @@ -872,7 +1544,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) @@ -888,7 +1559,55 @@ 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_remove_listen_status(manager->pc); + if (retval < 0) { + return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, + __FUNCTION__, NULL); + } + + 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; +} + +API int package_manager_set_res_event_cb(package_manager_h manager, + package_manager_res_event_cb callback, void *user_data) +{ + int retval; + + if (package_manager_validate_handle(manager)) { + return + package_manager_error + (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, + NULL); + } + + manager->res_event_cb = callback; + manager->user_data = user_data; + + retval = pkgmgr_client_remove_listen_status(manager->pc); + if (retval < 0) { + return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, + __FUNCTION__, NULL); + } + + retval = pkgmgr_client_listen_res_status(manager->pc, + internal_res_callback, manager); + if (retval < 0) { + return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, + __FUNCTION__, NULL); + } return PACKAGE_MANAGER_ERROR_NONE; } @@ -904,8 +1623,13 @@ API int package_manager_unset_event_cb(package_manager_h manager) int retval; manager->event_cb = NULL; + manager->res_event_cb = NULL; manager->user_data = NULL; + g_mutex_lock(&manager->mutex); + g_hash_table_remove_all(manager->event_info_table); + g_mutex_unlock(&manager->mutex); + retval = pkgmgr_client_remove_listen_status(manager->pc); if (retval == PKGMGR_R_EINVAL) return @@ -935,17 +1659,13 @@ API int package_manager_get_package_id_by_app_id(const char *app_id, char **pack if (app_id == NULL || package_id == NULL) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - uid_t uid = getuid(); - if (uid != GLOBAL_USER) { - if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id, uid, &pkgmgrinfo_appinfo) != PMINFO_R_OK) - return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); - } else { - if (pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo) != PMINFO_R_OK) - return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); - } + 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) { @@ -978,7 +1698,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) @@ -995,17 +1714,11 @@ API int package_manager_foreach_package_info(package_manager_package_info_cb cal API int package_manager_compare_package_cert_info(const char *lhs_package_id, const char *rhs_package_id, package_manager_compare_result_type_e *compare_result) { pkgmgrinfo_cert_compare_result_type_e result; - uid_t uid = getuid(); if (lhs_package_id == NULL || rhs_package_id == NULL || compare_result == NULL) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - if (uid != GLOBAL_USER) { - if (pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(lhs_package_id, rhs_package_id, uid, &result) != PKGMGR_R_OK) - return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); - } else { - if (pkgmgrinfo_pkginfo_compare_pkg_cert_info(lhs_package_id, rhs_package_id, &result) != PKGMGR_R_OK) - return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); - } + if (pkgmgrinfo_pkginfo_compare_pkg_cert_info(lhs_package_id, rhs_package_id, &result) != PKGMGR_R_OK) + return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); *compare_result = (package_manager_compare_result_type_e)result; return PACKAGE_MANAGER_ERROR_NONE; @@ -1014,17 +1727,11 @@ API int package_manager_compare_package_cert_info(const char *lhs_package_id, co API int package_manager_compare_app_cert_info(const char *lhs_app_id, const char *rhs_app_id, package_manager_compare_result_type_e *compare_result) { pkgmgrinfo_cert_compare_result_type_e result; - uid_t uid = getuid(); if (lhs_app_id == NULL || rhs_app_id == NULL || compare_result == NULL) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - if (uid != GLOBAL_USER) { - if (pkgmgrinfo_pkginfo_compare_usr_app_cert_info(lhs_app_id, rhs_app_id, uid, &result) != PKGMGR_R_OK) - return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); - } else { - if (pkgmgrinfo_pkginfo_compare_app_cert_info(lhs_app_id, rhs_app_id, &result) != PKGMGR_R_OK) - return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); - } + if (pkgmgrinfo_pkginfo_compare_app_cert_info(lhs_app_id, rhs_app_id, &result) != PKGMGR_R_OK) + return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); *compare_result = (package_manager_compare_result_type_e)result; @@ -1033,7 +1740,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) @@ -1044,32 +1750,18 @@ API int package_manager_is_preload_package_by_app_id(const char *app_id, bool *p char *pkg_id = NULL; bool is_preload = 0; - uid_t uid = getuid(); - if (uid != GLOBAL_USER) { - if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id, uid, &pkgmgrinfo_appinfo) != PMINFO_R_OK) - return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); - } else { - if (pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo) != PMINFO_R_OK) - return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); - } + 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) { pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo); return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); } - if (uid != GLOBAL_USER) { - if (pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id, uid, &pkgmgrinfo_pkginfo) != PMINFO_R_OK) { - pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo); - pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo); - return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); - } - } else { - if (pkgmgrinfo_pkginfo_get_pkginfo(pkg_id, &pkgmgrinfo_pkginfo) != PMINFO_R_OK) { - pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo); - pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo); - return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); - } + if (pkgmgrinfo_pkginfo_get_pkginfo(pkg_id, &pkgmgrinfo_pkginfo) != PMINFO_R_OK) { + pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo); + return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); } if (pkgmgrinfo_pkginfo_is_preload(pkgmgrinfo_pkginfo, &is_preload) != PMINFO_R_OK) { pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo); @@ -1090,7 +1782,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) @@ -1098,17 +1789,13 @@ API int package_manager_get_permission_type(const char *app_id, package_manager_ pkgmgrinfo_appinfo_h pkgmgrinfo_appinfo = NULL; pkgmgrinfo_permission_type permission = 0; - uid_t uid = getuid(); - if (uid != GLOBAL_USER) { - if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id, uid, &pkgmgrinfo_appinfo) != PMINFO_R_OK) - return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); - } else { - if (pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo) != PMINFO_R_OK) - return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); - } + 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; @@ -1125,144 +1812,203 @@ 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) - return retval; - int res = pkgmgr_client_usr_clear_cache_dir(package_id, getuid()); - if (res == PKGMGR_R_EINVAL) { - return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } else if (res == PKGMGR_R_ENOPKG) { - return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); - } else if (res == PKGMGR_R_ENOMEM) { - return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); - } else if (res == PKGMGR_R_EIO) { - return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); - } else if (res == PKGMGR_R_EPRIV) { - return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL); - } else if (res == PKGMGR_R_ESYSTEM || res == PKGMGR_R_ECOMM || res == PKGMGR_R_ERROR) { - return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); - } else if (res != PKGMGR_R_OK) { - _LOGE("Unexpected error"); - return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); + int res = pkgmgr_client_clear_cache_dir(package_id); + if (res < 0) { + retval = package_manager_convert_internal_error(res); + return package_manager_error(retval, __FUNCTION__, NULL); } 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 = 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 < 0) { + retval = package_manager_convert_internal_error(retval); + return package_manager_error(retval, __FUNCTION__, NULL); + } + + return PACKAGE_MANAGER_ERROR_NONE; +} + + +API int package_manager_clear_user_data_with_path(const char *package_id, + const char *file_path) +{ int retval; - retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); - if (retval != PACKAGE_MANAGER_ERROR_NONE) - return retval; + pkgmgr_client *pc = NULL; + char *pkg_type = NULL; + pkgmgrinfo_pkginfo_h pkginfo = NULL; + + if (package_id == NULL || file_path == NULL) + return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER; + + retval = pkgmgrinfo_pkginfo_get_pkginfo(package_id, &pkginfo); + if (retval == PMINFO_R_ENOENT) + return PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE; + 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_with_path(pc, pkg_type, + package_id, file_path, PM_QUIET); + pkgmgr_client_free(pc); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + + if (retval < 0) { + retval = package_manager_convert_internal_error(retval); + return package_manager_error(retval, __FUNCTION__, NULL); + } + + return PACKAGE_MANAGER_ERROR_NONE; +} +API int package_manager_clear_all_cache_dir(void) +{ return package_manager_clear_cache_dir(PKG_CLEAR_ALL_CACHE); } -static void __free_client(gpointer data) +struct getsize_cbdata { + pkgmgr_client *pc; + void *cb; + void *user_data; +}; + +static void __free_getsize_cbdata(struct getsize_cbdata *cbdata) { - pkgmgr_client *pc = (pkgmgr_client *)data; - pkgmgr_client_free(pc); + pkgmgr_client_free(cbdata->pc); + free(cbdata); } -static void __initialize_cb_table(void) +static void __copy_size_info(const pkg_size_info_t *src, package_size_info_t *dst) { - __cb_table = g_hash_table_new_full(g_int_hash, g_int_equal, __free_client, NULL); + if (src == NULL || dst == NULL) { + _LOGE("src or dst size info is NULL"); + return; + } + + dst->data_size = src->data_size; + dst->cache_size = src->cache_size; + dst->app_size = src->app_size; + dst->external_data_size = src->ext_data_size; + dst->external_cache_size = src->ext_cache_size; + dst->external_app_size = src->ext_app_size; } static void __result_cb(pkgmgr_client *pc, const char *pkgid, const pkg_size_info_t *result, void *user_data) { - package_manager_size_info_receive_cb callback = g_hash_table_lookup(__cb_table, pc); + struct getsize_cbdata *cbdata = (struct getsize_cbdata *)user_data; + package_manager_size_info_receive_cb callback = cbdata->cb; if (callback == NULL) { _LOGE("callback is null."); - g_hash_table_remove(__cb_table, pc); + __free_getsize_cbdata(cbdata); return; } package_size_info_t size_info; - size_info.data_size = result->data_size; - size_info.cache_size = result->cache_size; - size_info.app_size = result->app_size; - size_info.external_data_size = result->ext_data_size; - size_info.external_cache_size = result->ext_cache_size; - size_info.external_app_size = result->ext_app_size; + __copy_size_info(result, &size_info); - callback(pkgid, (package_size_info_h)&size_info, user_data); + callback(pkgid, (package_size_info_h)&size_info, cbdata->user_data); - g_hash_table_remove(__cb_table, pc); + __free_getsize_cbdata(cbdata); } static void __total_result_cb(pkgmgr_client *pc, const pkg_size_info_t *result, void *user_data) { - package_manager_total_size_info_receive_cb callback = g_hash_table_lookup(__cb_table, pc); + struct getsize_cbdata *cbdata = (struct getsize_cbdata *)user_data; + package_manager_total_size_info_receive_cb callback = cbdata->cb; if (callback == NULL) { _LOGE("callback is null."); - g_hash_table_remove(__cb_table, pc); + __free_getsize_cbdata(cbdata); return; } package_size_info_t size_info; - size_info.data_size = result->data_size; - size_info.cache_size = result->cache_size; - size_info.app_size = result->app_size; - size_info.external_data_size = result->ext_data_size; - size_info.external_cache_size = result->ext_cache_size; - size_info.external_app_size = result->ext_app_size; + __copy_size_info(result, &size_info); - callback((package_size_info_h)&size_info, user_data); + callback((package_size_info_h)&size_info, cbdata->user_data); - g_hash_table_remove(__cb_table, pc); + __free_getsize_cbdata(cbdata); } static int _get_pkg_size_info(const char *package_id, void *callback, void *user_data) { + struct getsize_cbdata *cbdata; + if (package_id == NULL || callback == NULL) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - if (__cb_table == NULL) - __initialize_cb_table(); + cbdata = malloc(sizeof(struct getsize_cbdata)); + if (cbdata == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); pkgmgr_client *pc = pkgmgr_client_new(PC_REQUEST); - if (pc == NULL) + if (pc == NULL) { + free(cbdata); return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); + } + + cbdata->pc = pc; + cbdata->cb = callback; + cbdata->user_data = user_data; int res = 0; if (strcmp(package_id, PKG_SIZE_INFO_TOTAL) != 0) - res = pkgmgr_client_usr_get_package_size_info(pc, package_id, __result_cb, user_data, getuid()); + res = pkgmgr_client_get_package_size_info(pc, package_id, __result_cb, cbdata); else - res = pkgmgr_client_usr_get_total_package_size_info(pc, __total_result_cb, user_data, getuid()); + res = pkgmgr_client_get_total_package_size_info(pc, __total_result_cb, cbdata); - if (res == PKGMGR_R_EINVAL) { - pkgmgr_client_free(pc); - return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - } else if (res == PKGMGR_R_ENOPKG) { - pkgmgr_client_free(pc); - return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL); - } else if (res == PKGMGR_R_ENOMEM) { - pkgmgr_client_free(pc); - return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); - } else if (res == PKGMGR_R_EIO) { - pkgmgr_client_free(pc); - return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); - } else if (res == PKGMGR_R_EPRIV) { - pkgmgr_client_free(pc); - return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL); - } else if (res == PKGMGR_R_ESYSTEM || res == PKGMGR_R_ECOMM || res == PKGMGR_R_ERROR) { - pkgmgr_client_free(pc); - return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); - } else if (res != PKGMGR_R_OK) { - _LOGE("Unexpected error"); - pkgmgr_client_free(pc); - return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); + if (res != PKGMGR_R_OK) { + __free_getsize_cbdata(cbdata); + res = package_manager_convert_internal_error(res); + return package_manager_error(res, __FUNCTION__, NULL); } - g_hash_table_insert(__cb_table, pc, callback); - - _LOGD("Successful"); return PACKAGE_MANAGER_ERROR_NONE; } @@ -1338,9 +2084,27 @@ API int package_manager_filter_add_bool(package_manager_filter_h handle, return PACKAGE_MANAGER_ERROR_NONE; } -API int package_manager_filter_count(package_manager_filter_h handle, int *count) + +API int package_manager_filter_add_string(package_manager_filter_h handle, const char *property, const char *value) { + int retval; + + if ((handle == NULL) || (property == NULL) || (value == NULL)) { + return + package_manager_error + (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, + NULL); + } + retval = pkgmgrinfo_pkginfo_filter_add_string(handle, property, value); + if (retval != PACKAGE_MANAGER_ERROR_NONE) + return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); + + return PACKAGE_MANAGER_ERROR_NONE; +} + +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) @@ -1359,7 +2123,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) @@ -1434,3 +2197,464 @@ 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; + + 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; + + 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; +} + +API int package_manager_request_add_res_copy_path( + package_manager_request_h request, + const char *src_path, const char *dest_path) +{ + int retval = 0; + + if (package_manager_client_validate_handle(request) + || src_path == NULL || dest_path == NULL) { + return + package_manager_error + (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, + NULL); + } + + if (pkgmgr_client_add_res_copy_path(request->pc, src_path, dest_path)) + return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR; + + return PACKAGE_MANAGER_ERROR_NONE; +} + +API int package_manager_request_res_copy_with_cb(package_manager_request_h request, + package_manager_request_res_event_cb callback, + void *user_data, int *id) +{ + int ret; + int req_id = 0; + + if (package_manager_client_validate_handle(request) + || callback == NULL || id == NULL) { + return package_manager_error( + PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (request->request_cb_table == NULL) + __initialize_request_cb_table(request); + + ret = __request_res_copy(request, internal_res_request_callback, &req_id); + + if (req_id > 0) { + ret = __insert_res_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_add_res_create_dir_path( + package_manager_request_h request, const char *dir_path) +{ + int retval = 0; + + if (package_manager_client_validate_handle(request) + || dir_path == NULL) { + return + package_manager_error + (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, + NULL); + } + + if (pkgmgr_client_add_res_create_dir_path(request->pc, dir_path)) + return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR; + + return PACKAGE_MANAGER_ERROR_NONE; +} + +API int package_manager_request_res_create_dir_with_cb( + package_manager_request_h request, + package_manager_request_res_event_cb callback, + void *user_data, int *id) +{ + int ret; + int req_id = 0; + + if (package_manager_client_validate_handle(request) + || callback == NULL || id == NULL) { + return package_manager_error( + PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (request->request_cb_table == NULL) + __initialize_request_cb_table(request); + + ret = __request_res_create_dir(request, internal_res_request_callback, &req_id); + + if (req_id > 0) { + ret = __insert_res_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_add_res_remove_path( + package_manager_request_h request, const char *res_path) +{ + int retval = 0; + + if (package_manager_client_validate_handle(request) + || res_path == NULL) { + return + package_manager_error + (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, + NULL); + } + + if (pkgmgr_client_add_res_remove_path(request->pc, res_path)) + return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR; + + return PACKAGE_MANAGER_ERROR_NONE; +} + +API int package_manager_request_res_remove_with_cb( + package_manager_request_h request, + package_manager_request_res_event_cb callback, + void *user_data, int *id) +{ + int ret; + int req_id = 0; + + if (package_manager_client_validate_handle(request) + || callback == NULL || id == NULL) { + return package_manager_error( + PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + } + + if (request->request_cb_table == NULL) + __initialize_request_cb_table(request); + + ret = __request_res_remove(request, internal_res_request_callback, &req_id); + + if (req_id > 0) { + ret = __insert_res_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_res_event_info_get_error_code( + package_manager_res_event_info_h handle, + package_manager_error_e *error) +{ + int ret; + int error_code = 0; + + ret = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); + if (ret != PACKAGE_MANAGER_ERROR_NONE) + return ret; + + if (handle == NULL || error == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + struct package_manager_res_event_info_s *event_info = + (struct package_manager_res_event_info_s *)handle; + + if (event_info->res_event_info_handle == NULL) + return package_manager_error( + PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); + + if (pkgmgr_res_event_info_get_error_code( + event_info->res_event_info_handle, &error_code)) + return package_manager_error( + PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); + + *error = __convert_to_error(error_code); + + return PACKAGE_MANAGER_ERROR_NONE; +} + +typedef struct _foreach_res_event_path_context_ { + package_manager_res_event_path_cb callback; + void *user_data; +} foreach_res_event_path_context_s; + +static int package_res_event_info_foreach_path_cb(const char *path, + pkgmgr_res_event_path_state state, void *user_data) +{ + foreach_res_event_path_context_s *foreach_context = user_data; + package_manager_res_event_path_state_e path_state = + PACKAGE_MANAGER_RES_EVENT_PATH_STATE_NONE; + bool r = false; + + if (foreach_context == NULL) { + package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); + return -1; + } + + if (state == PM_RES_EVENT_PATH_STATE_NONE) { + path_state = PACKAGE_MANAGER_RES_EVENT_PATH_STATE_NONE; + } else if (state == PM_RES_EVENT_PATH_STATE_OK) { + path_state = PACKAGE_MANAGER_RES_EVENT_PATH_STATE_OK; + } else if (state == PM_RES_EVENT_PATH_STATE_FAILED) { + path_state = PACKAGE_MANAGER_RES_EVENT_PATH_STATE_FAILED; + } else { + package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); + return -1; + } + + r = foreach_context->callback(path, path_state, + foreach_context->user_data); + if (r == false) + return -1; + + return 0; +} + +API int package_manager_res_event_info_foreach_path( + package_manager_res_event_info_h handle, + package_manager_res_event_path_cb callback, void *user_data) +{ + int ret; + foreach_res_event_path_context_s foreach_res_event_path_context = { + .callback = callback, + .user_data = user_data, + }; + + ret = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); + if (ret != PACKAGE_MANAGER_ERROR_NONE) + return ret; + + if (handle == NULL || callback == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + struct package_manager_res_event_info_s *event_info = + (struct package_manager_res_event_info_s *)handle; + + if (event_info->res_event_info_handle == NULL) + return package_manager_error( + PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); + + ret = pkgmgr_res_event_info_foreach_path( + event_info->res_event_info_handle, + package_res_event_info_foreach_path_cb, + &foreach_res_event_path_context); + if (ret != PKGMGR_R_OK) { + return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, + __FUNCTION__, NULL); + } + + return PACKAGE_MANAGER_ERROR_NONE; +} + +API int package_manager_get_priv_shared_res_path(const char *package_id, char **path) +{ + int ret; + char *path_dup; + char buf[PATH_MAX]; + + ret = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); + if (ret != PACKAGE_MANAGER_ERROR_NONE) + return ret; + + if (package_id == NULL || path == NULL) + return package_manager_error( + PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); + + snprintf(buf, sizeof(buf), "%s/%s/%s", USER_HOME, + PRIV_SHARED_RES, package_id); + + path_dup = strdup(buf); + if (path_dup == NULL) + return package_manager_error( + PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, + __FUNCTION__, NULL); + *path = path_dup; + + return PACKAGE_MANAGER_ERROR_NONE; +}