summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/app_info.h32
-rw-r--r--src/app_info.c105
-rw-r--r--src/app_manager_internal.h2
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);