X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fpackage_manager.c;h=5bf2a4498010c7c07b59a7a2db51af0a9ee2c0b4;hb=17e7746420b816c2467243857db7f43d124193b7;hp=3cf4bdee61d481c8d2c51c9692af43aa7e3af435;hpb=aa9b46f86f64451ee1c974b663ef7a1dbf3c97e6;p=platform%2Fcore%2Fapi%2Fpackage-manager.git diff --git a/src/package_manager.c b/src/package_manager.c index 3cf4bde..5bf2a44 100644 --- a/src/package_manager.c +++ b/src/package_manager.c @@ -21,15 +21,18 @@ #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) +#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; @@ -40,6 +43,7 @@ typedef struct _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 { @@ -49,7 +53,9 @@ struct package_manager_s { pkgmgr_mode mode; 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 { @@ -61,12 +67,14 @@ struct package_manager_request_s { request_event_info *head; package_manager_request_event_cb event_cb; 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; }; @@ -89,6 +97,10 @@ struct package_updateinfo_request_s { 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; @@ -117,7 +129,8 @@ static void __clean_all_event_info(request_event_info *head) } static int __insert_event_info(package_manager_h manager, const char *pkg_name, - package_manager_event_type_e event_type) + package_manager_event_type_e event_type, + package_manager_event_state_e event_state) { struct package_manager_event_info *info; @@ -126,6 +139,7 @@ static int __insert_event_info(package_manager_h manager, const char *pkg_name, 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; @@ -185,6 +199,27 @@ static int __insert_request_cb_info(package_manager_request_h request, int req_i 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; @@ -271,6 +306,10 @@ API int package_manager_request_set_event_cb(package_manager_request_h request, { int ret; + if (package_manager_client_validate_handle(request)) + return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); + ret = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO); if (ret != PACKAGE_MANAGER_ERROR_NONE) return ret; @@ -299,6 +338,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; @@ -331,10 +372,6 @@ 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 (pkgmgr_client_set_tep_path(request->pc, tep_path, true)) return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR; @@ -358,12 +395,69 @@ static int package_manager_get_event_type(const char *key, *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 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) @@ -379,6 +473,7 @@ static int __add_event_info(request_event_info **head, int req_id, } 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) @@ -412,6 +507,7 @@ static int __find_event_info(request_event_info **head, int req_id, while (tmp) { if (tmp->req_id == req_id) { *event_type = tmp->event_type; + *event_state = tmp->event_state; return 0; } tmp = tmp->next; @@ -440,6 +536,7 @@ static int __update_event_info(request_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; @@ -491,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, @@ -529,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); } } @@ -606,16 +701,20 @@ static int internal_request_callback(uid_t target_uid, int req_id, const char *p pkg_name, event_type, PACKAGE_MANAGER_EVENT_STATE_FAILED, 0, - PACKAGE_MANAGER_ERROR_NONE, + __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) { - _LOGD("remove item, req_id(%d)", req_id); - g_hash_table_remove(request->request_cb_table, - GINT_TO_POINTER(req_id)); + 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) { @@ -630,7 +729,7 @@ static int internal_request_callback(uid_t target_uid, int req_id, const char *p pkg_name, event_type, PACKAGE_MANAGER_EVENT_STATE_FAILED, 0, - PACKAGE_MANAGER_ERROR_NONE, + PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, user_data); } } @@ -642,13 +741,72 @@ static int internal_request_callback(uid_t target_uid, int req_id, const char *p 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); @@ -659,19 +817,41 @@ static int __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, 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 (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; +} + +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; @@ -683,9 +863,6 @@ 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); @@ -696,19 +873,10 @@ static int __request_uninstall(package_manager_request_h request, int request_id = 0; request_id = pkgmgr_client_uninstall(request->pc, request->pkg_type, 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); - 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 (request_id < 0) { + retval = package_manager_convert_internal_error(request_id); + return package_manager_error(retval, __FUNCTION__, NULL); + } if (id) *id = request_id; @@ -721,9 +889,6 @@ static int __request_move(package_manager_request_h request, 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); @@ -735,19 +900,127 @@ static int __request_move(package_manager_request_h request, 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; +} - if (request_id == PKGMGR_R_EINVAL) +static int __request_mount_install(package_manager_request_h request, + const char *path, 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); - 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 (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; @@ -785,6 +1058,42 @@ API int package_manager_request_install_with_cb(package_manager_request_h reques 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) { @@ -845,21 +1154,88 @@ API int package_manager_request_move_with_cb(package_manager_request_h request, return ret; } -API int package_manager_create(package_manager_h *manager) +API int package_manager_request_mount_install(package_manager_request_h request, + const char *path, int *id) { - int retval; - retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO); - if (retval != PACKAGE_MANAGER_ERROR_NONE) - return retval; + return __request_mount_install(request, path, NULL, id); +} - struct package_manager_s *package_manager = NULL; +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 (manager == 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_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; + + if (manager == NULL) { + return + package_manager_error + (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, + NULL); + } package_manager = calloc(1, sizeof(struct package_manager_s)); if (package_manager == NULL) { @@ -880,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; @@ -903,6 +1280,7 @@ API int package_manager_destroy(package_manager_h manager) NULL); } + g_mutex_clear(&manager->mutex); pkgmgr_client_free(manager->pc); g_hash_table_destroy(manager->event_info_table); free(manager); @@ -939,12 +1317,15 @@ 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; + int ret = -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("req_id(%d), pkg_name(%s), type(%s), key(%s), val(%s)", req_id, pkg_name, pkg_type, key, val); @@ -956,6 +1337,7 @@ static int internal_callback(uid_t target_uid, int req_id, const char *pkg_type, 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"); @@ -965,71 +1347,135 @@ static int internal_callback(uid_t target_uid, int req_id, const char *pkg_type, 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; + } if (!info) { - __insert_event_info(manager, pkg_name, event_type); + __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 (manager->event_cb && getuid() == uid) - manager->event_cb(pkg_type, pkg_name, - info->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 (manager->event_cb && getuid() == uid) - manager->event_cb(pkg_type, pkg_name, - info->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 (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_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; @@ -1051,6 +1497,14 @@ static int __convert_status_type(package_manager_status_type_e status_type) 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; } @@ -1065,7 +1519,11 @@ API int package_manager_set_event_status(package_manager_h manager, int status_t 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_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); @@ -1086,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) @@ -1102,6 +1559,12 @@ API int package_manager_set_event_cb(package_manager_h manager, manager->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_status(manager->pc, internal_callback, manager); if (retval < 0) { @@ -1118,6 +1581,37 @@ API int package_manager_set_event_cb(package_manager_h manager, 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; +} + API int package_manager_unset_event_cb(package_manager_h manager) { if (manager == NULL) { @@ -1129,9 +1623,12 @@ 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) @@ -1165,8 +1662,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) { @@ -1199,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) @@ -1242,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) @@ -1285,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) @@ -1296,8 +1792,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; @@ -1314,28 +1812,12 @@ 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_clear_cache_dir(package_id); - 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); + if (res < 0) { + retval = package_manager_convert_internal_error(res); + return package_manager_error(retval, __FUNCTION__, NULL); } return PACKAGE_MANAGER_ERROR_NONE; @@ -1351,10 +1833,6 @@ API int package_manager_clear_data_dir(const char *package_id) 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; @@ -1378,136 +1856,159 @@ API int package_manager_clear_data_dir(const char *package_id) 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); + 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) -{ +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_direct_hash, g_direct_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_get_package_size_info(pc, package_id, __result_cb, user_data); + res = pkgmgr_client_get_package_size_info(pc, package_id, __result_cb, cbdata); else - res = pkgmgr_client_get_total_package_size_info(pc, __total_result_cb, user_data); + 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); - return PACKAGE_MANAGER_ERROR_NONE; } @@ -1583,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) @@ -1604,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) @@ -1684,7 +2202,7 @@ API int package_manager_updateinfo_set_pkgid(package_updateinfo_request_h pkg_up { struct package_updateinfo_request_s *request; - if (pkg_updateinfo_req == NULL || pkg_updateinfo_req->updateinfo_handle == NULL) + 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; @@ -1701,7 +2219,7 @@ API int package_manager_updateinfo_set_version(package_updateinfo_request_h pkg_ { struct package_updateinfo_request_s *request; - if (pkg_updateinfo_req == NULL || pkg_updateinfo_req->updateinfo_handle == NULL) + 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; @@ -1823,10 +2341,6 @@ API int package_manager_updateinfo_request_unregister(package_updateinfo_request 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); @@ -1843,10 +2357,6 @@ API int package_manager_updateinfo_request_unregister_all(package_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); @@ -1858,3 +2368,293 @@ API int package_manager_updateinfo_request_unregister_all(package_updateinfo_req 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; +}