diff options
-rw-r--r-- | include/app_info.h | 32 | ||||
-rw-r--r-- | src/app_info.c | 105 | ||||
-rw-r--r-- | src/app_manager_internal.h | 2 |
3 files changed, 138 insertions, 1 deletions
diff --git a/include/app_info.h b/include/app_info.h index 14c65c1..8125341 100644 --- a/include/app_info.h +++ b/include/app_info.h @@ -114,6 +114,20 @@ typedef bool (*app_info_filter_cb) (app_info_h app_info, void *user_data); typedef bool (*app_info_metadata_cb) (const char *metadata_key, const char *metadata_value, void *user_data); /** + * @brief Called for each application category in app_info_foreach_category(). + * @since_tizen 4.0 + * @remarks @a category will be freed when the application information handle is destroyed + * using app_info_destroy() + * @param[in] category The name of the category + * @param[in] user_data The user data passed to app_info_foreach_category() + * @return @c true to continue with the next iteration of the loop, \n + * otherwise @c false to break out of the loop + * @pre app_info_foreach_category() will invoke this callback. + * @see app_info_foreach_category() + */ +typedef bool (*app_info_category_cb) (const char *category, void *user_data); + +/** * @brief Creates the application information handle. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] app_id The application ID @@ -336,6 +350,24 @@ int app_info_is_preload(app_info_h app_info, bool *preload); int app_info_clone(app_info_h *clone, app_info_h app_info); /** + * @brief Runs a callback for each category which the given application belongs to. + * @since_tizen 4.0 + * @privlevel platform + * @privilege %http://tizen.org/privilege/packagemanager.admin + * @param[in] app_info The application information + * @param[in] callback The callback function + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #APP_MANAGER_ERROR_NONE Successful + * @retval #APP_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #APP_MANAGER_ERROR_IO_ERROR I/O error + * @retval #APP_MANAGER_ERROR_PERMISSION_DENIED Permission denied + * @see app_info_create() + */ +int app_info_foreach_category(app_info_h app_info, app_info_category_cb callback, void *user_data); + +/** * @brief Creates the application information filter handle from DB. * All filter properties will be ANDed. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif diff --git a/src/app_info.c b/src/app_info.c index a70407a..c9967ec 100644 --- a/src/app_info.c +++ b/src/app_info.c @@ -19,10 +19,12 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <fcntl.h> #include <pkgmgr-info.h> #include <package-manager.h> #include <dlog.h> +#include <cynara-client.h> #include "app_info.h" #include "app_manager.h" @@ -34,6 +36,8 @@ #define LOG_TAG "TIZEN_N_APP_MANAGER" +#define SMACK_LABEL_LEN 255 + struct app_info_s { char *app_id; pkgmgrinfo_appinfo_h pkg_app_info; @@ -57,6 +61,11 @@ typedef struct _foreach_metada_context_ { void *user_data; } foreach_metadata_context_s; +typedef struct _foreach_category_ { + app_info_category_cb callback; + void *user_data; +} foreach_category_context_s; + static int app_info_convert_str_property(const char *property, char **converted_property) { if (property == NULL) @@ -85,7 +94,6 @@ static int app_info_convert_bool_property(const char *property, char **converted *converted_property = PMINFO_APPINFO_PROP_APP_NODISPLAY; else if (strcmp(property, PACKAGE_INFO_PROP_APP_TASKMANAGE) == 0) *converted_property = PMINFO_APPINFO_PROP_APP_TASKMANAGE; - else return -1; @@ -158,6 +166,21 @@ static int app_info_foreach_app_metadata_cb(const char *metadata_key, const char return PMINFO_R_ERROR; } +static int app_info_foreach_caregory_cb(const char *category_name, void *user_data) +{ + foreach_category_context_s *foreach_category = user_data; + bool iteration_next = true; + + if (category_name == NULL || foreach_category == NULL) + return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); + + iteration_next = foreach_category->callback(category_name, foreach_category->user_data); + if (iteration_next == true) + return PMINFO_R_OK; + else + return PMINFO_R_ERROR; +} + static int app_info_foreach_app_info_cb(pkgmgrinfo_appinfo_h handle, void *cb_data) { foreach_context_s *foreach_context = cb_data; @@ -211,6 +234,64 @@ int app_info_foreach_app_info(app_manager_app_info_cb callback, void *user_data) return APP_MANAGER_ERROR_NONE; } +static int _check_privilege(char *privilege) +{ + cynara *p_cynara; + int fd; + int ret; + + char client[SMACK_LABEL_LEN + 1] = ""; + char uid[10] = {0,}; + char *client_session = ""; + + if (privilege == NULL) { + LOGE("invalid parameter"); + return APP_MANAGER_ERROR_INVALID_PARAMETER; + } + + ret = cynara_initialize(&p_cynara, NULL); + if (ret != CYNARA_API_SUCCESS) { + LOGE("cynara_initialize [%d] failed!", ret); + return APP_MANAGER_ERROR_IO_ERROR; + } + + fd = open("/proc/self/attr/current", O_RDONLY); + if (fd < 0) { + LOGE("open [%d] failed!", errno); + ret = APP_MANAGER_ERROR_IO_ERROR; + goto out; + } + + ret = read(fd, client, SMACK_LABEL_LEN); + if (ret < 0) { + LOGE("read [%d] failed!", errno); + close(fd); + ret = APP_MANAGER_ERROR_IO_ERROR; + goto out; + } + close(fd); + snprintf(uid, 10, "%d", getuid()); + + ret = cynara_check(p_cynara, client, client_session, uid, privilege); + if (ret != CYNARA_API_ACCESS_ALLOWED) { + LOGE("cynara access check [%d] failed!", ret); + + if (ret == CYNARA_API_ACCESS_DENIED) + ret = APP_MANAGER_ERROR_PERMISSION_DENIED; + else + ret = APP_MANAGER_ERROR_IO_ERROR; + + goto out; + } + ret = APP_MANAGER_ERROR_NONE; + +out: + if (p_cynara) + cynara_finish(p_cynara); + + return ret; +} + API int app_info_create(const char *app_id, app_info_h *app_info) { pkgmgrinfo_pkginfo_h pkginfo = NULL; @@ -552,6 +633,28 @@ API int app_info_clone(app_info_h *clone, app_info_h app_info) return APP_MANAGER_ERROR_NONE; } +API int app_info_foreach_category(app_info_h app_info, app_info_category_cb callback, void *user_data) +{ + int retval; + if (app_info == NULL || callback == NULL) + return app_manager_error(APP_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + retval = _check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN); + if (retval != APP_MANAGER_ERROR_NONE) + return app_manager_error(APP_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL); + + foreach_category_context_s foreach_category = { + .callback = callback, + .user_data = user_data, + }; + + retval = pkgmgrinfo_appinfo_foreach_category(app_info->pkg_app_info, app_info_foreach_caregory_cb, &foreach_category); + if (retval != PMINFO_R_OK) + return app_manager_error(APP_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL); + + return APP_MANAGER_ERROR_NONE; +} + API int app_info_filter_create(app_info_filter_h *handle) { int retval = 0; diff --git a/src/app_manager_internal.h b/src/app_manager_internal.h index 7a6100e..dd76ef8 100644 --- a/src/app_manager_internal.h +++ b/src/app_manager_internal.h @@ -27,6 +27,8 @@ #define API __attribute__ ((visibility("default"))) #endif +#define PRIVILEGE_PACKAGE_MANAGER_ADMIN "http://tizen.org/privilege/packagemanager.admin" + int app_manager_error(app_manager_error_e error, const char *function, const char *description); int app_context_foreach_app_context(app_manager_app_context_cb callback, void *user_data); |