From f0100a47e20fb502006161bc91554de45bde67ca Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Wed, 5 Jul 2017 19:39:47 +0900 Subject: [PATCH] Add appdefined privilege feature Change-Id: I4d7a285919873b9e7aa8af53d316503f19626727 Signed-off-by: jongmyeongko --- include/pkgmgr-info.h | 46 ++++++++++++++++++++ include/pkgmgrinfo_basic.h | 8 ++++ include/pkgmgrinfo_type.h | 20 ++++++++- parser/manifest.xsd.in | 16 +++++++ parser/manifest.xsd.ref | 16 +++++++ parser/src/pkgmgr_parser_db.c | 47 ++++++++++++++++++++ parser/src/pkgmgr_parser_db_queries.h | 10 +++++ src/pkgmgrinfo_basic.c | 20 +++++++++ src/pkgmgrinfo_db.c | 1 + src/pkgmgrinfo_pkginfo.c | 80 +++++++++++++++++++++++++++++++++++ 10 files changed, 263 insertions(+), 1 deletion(-) diff --git a/include/pkgmgr-info.h b/include/pkgmgr-info.h index cb63b9f..9c3dbb6 100644 --- a/include/pkgmgr-info.h +++ b/include/pkgmgr-info.h @@ -2393,6 +2393,7 @@ static int get_tpk_pkg_count() */ int pkgmgrinfo_pkginfo_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count); int pkgmgrinfo_pkginfo_usr_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count, uid_t uid); + /** * @fn int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_pkg_privilege_list_cb privilege_func, void *user_data); @@ -2438,6 +2439,51 @@ static int list_privilege(const char *package, char *privilege) int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_pkg_privilege_list_cb privilege_func, void *user_data); +/** + * @fn int pkgmgrinfo_pkginfo_foreach_appdefined_privilege(pkgmgrinfo_pkginfo_h handle, + pkgmgrinfo_pkg_appdefined_privilege_list_cb privilege_func, void *user_data); + * @brief This API gets the list of appdefined privilege for a particular package + * + * @par This API is for package-manager client application + * @par Sync (or) Async : Synchronous API + * @param[in] handle pointer to the package info handle. + * @param[in] privilege_func callback function for list + * @param[in] user_data user data to be passed to callback function + * @return 0 if success, error code(<0) if fail + * @retval PMINFO_R_OK success + * @retval PMINFO_R_EINVAL invalid argument + * @retval PMINFO_R_ERROR internal error + * @pre pkgmgrinfo_pkginfo_get_pkginfo() + * @post pkgmgrinfo_pkginfo_destroy_pkginfo() + * @code +int privilege_func(const char *name, const char *license_path, void *user_data) +{ + printf("appdefined privilege : %s", name); + if (license_path) + printf("licensed privilege, lecense path : %s", license_path); + return 0; +} + +static int list_appdefined_privilege(const char *package) +{ + int ret = 0; + pkgmgrinfo_pkginfo_h handle; + ret = pkgmgrinfo_pkginfo_get_pkginfo(package, &handle); + if (ret != PMINFO_R_OK) + return -1; + ret = pkgmgrinfo_pkginfo_foreach_appdefined_privilege(handle, privilege_func, NULL); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return -1; + } + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return 0; +} + * @endcode + */ +int pkgmgrinfo_pkginfo_foreach_appdefined_privilege(pkgmgrinfo_pkginfo_h handle, + pkgmgrinfo_pkg_appdefined_privilege_list_cb privilege_func, void *user_data); + /* TODO: add doxygen comment here */ int pkgmgrinfo_pkginfo_is_for_all_users(pkgmgrinfo_pkginfo_h handle, bool *for_all_users); diff --git a/include/pkgmgrinfo_basic.h b/include/pkgmgrinfo_basic.h index e78fd61..5fa1918 100644 --- a/include/pkgmgrinfo_basic.h +++ b/include/pkgmgrinfo_basic.h @@ -108,6 +108,12 @@ typedef struct privilege_x { char *value; } privilege_x; +typedef struct appdefined_privilege_x { + char *type; + char *value; + char *license; +} appdefined_privilege_x; + typedef struct application_x { char *appid; /*attr*/ char *exec; /*attr*/ @@ -208,6 +214,8 @@ typedef struct package_x { GList *description; /**< package description, element*/ GList *license; /**< package license, no xml part*/ GList *privileges; /**< package privileges, element*/ + GList *appdefined_privileges; /** + @@ -234,6 +235,21 @@ + + + + + + + + + + + + + + + diff --git a/parser/manifest.xsd.ref b/parser/manifest.xsd.ref index e894a76..a5eaa8e 100644 --- a/parser/manifest.xsd.ref +++ b/parser/manifest.xsd.ref @@ -265,6 +265,7 @@ + @@ -274,6 +275,21 @@ + + + + + + + + + + + + + + + diff --git a/parser/src/pkgmgr_parser_db.c b/parser/src/pkgmgr_parser_db.c index 5a079b9..0163fae 100644 --- a/parser/src/pkgmgr_parser_db.c +++ b/parser/src/pkgmgr_parser_db.c @@ -298,6 +298,7 @@ static const char *parser_init_queries[] = { QUERY_CREATE_TABLE_PACKAGE_INFO, QUERY_CREATE_TABLE_PACKAGE_LOCALIZED_INFO, QUERY_CREATE_TABLE_PACKAGE_PRIVILEGE_INFO, + QUERY_CREATE_TABLE_PACKAGE_APPDEFINED_PRIVILEGE_INFO, QUERY_CREATE_TABLE_PACKAGE_UPDATE_INFO, QUERY_CREATE_TABLE_PACKAGE_APP_INFO, QUERY_CREATE_TABLE_PACKAGE_APP_LOCALIZED_INFO, @@ -1560,6 +1561,50 @@ static int __insert_package_privilege_info(sqlite3 *db, manifest_x *mfx) return 0; } +static int __insert_package_appdefined_privilege_info(sqlite3 *db, + manifest_x *mfx) +{ + static const char query[] = + "INSERT INTO package_appdefined_privilege_info " + "(package, privilege, license, type) " + "VALUES (?, ?, ?, ?)"; + int ret; + sqlite3_stmt *stmt; + int idx; + GList *tmp; + appdefined_privilege_x *priv; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + _LOGE("prepare failed: %s", sqlite3_errmsg(db)); + return -1; + } + + for (tmp = mfx->appdefined_privileges; tmp; tmp = tmp->next) { + priv = (appdefined_privilege_x *)tmp->data; + if (priv == NULL) + continue; + + idx = 1; + __BIND_TEXT(db, stmt, idx++, mfx->package); + __BIND_TEXT(db, stmt, idx++, priv->value); + __BIND_TEXT(db, stmt, idx++, priv->license); + __BIND_TEXT(db, stmt, idx++, priv->type); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + _LOGE("step failed: %s", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + return -1; + } + sqlite3_reset(stmt); + } + + sqlite3_finalize(stmt); + + return 0; +} + /* _PRODUCT_LAUNCHING_ENHANCED_ * app->indicatordisplay, app->portraitimg, app->landscapeimg, * app->guestmode_appstatus @@ -1896,6 +1941,8 @@ static int __insert_package_info(sqlite3 *db, manifest_x *mfx) return -1; if (__insert_package_privilege_info(db, mfx)) return -1; + if (__insert_package_appdefined_privilege_info(db, mfx)) + return -1; return 0; } diff --git a/parser/src/pkgmgr_parser_db_queries.h b/parser/src/pkgmgr_parser_db_queries.h index b0051a0..924f8ac 100644 --- a/parser/src/pkgmgr_parser_db_queries.h +++ b/parser/src/pkgmgr_parser_db_queries.h @@ -74,6 +74,16 @@ " FOREIGN KEY(package)\n" \ " REFERENCES package_info(package) ON DELETE CASCADE)" +#define QUERY_CREATE_TABLE_PACKAGE_APPDEFINED_PRIVILEGE_INFO \ + "CREATE TABLE IF NOT EXISTS package_appdefined_privilege_info (\n" \ + " package TEXT NOT NULL,\n" \ + " privilege TEXT NOT NULL,\n" \ + " license TEXT,\n" \ + " type TEXT NOT NULL,\n" \ + " PRIMARY KEY(package, privilege, type)\n" \ + " FOREIGN KEY(package)\n" \ + " REFERENCES package_info(package) ON DELETE CASCADE)" + #define QUERY_CREATE_TABLE_PACKAGE_UPDATE_INFO \ "CREATE TABLE IF NOT EXISTS package_update_info (\n" \ " package TEXT NOT NULL,\n" \ diff --git a/src/pkgmgrinfo_basic.c b/src/pkgmgrinfo_basic.c index f18a359..7724e87 100644 --- a/src/pkgmgrinfo_basic.c +++ b/src/pkgmgrinfo_basic.c @@ -221,6 +221,20 @@ static void __ps_free_privilege(gpointer data) free((void *)privilege); } +static void __ps_free_appdefined_privilege(gpointer data) +{ + appdefined_privilege_x *privilege = (appdefined_privilege_x *)data; + if (privilege == NULL) + return; + if (privilege->type) + free((void *)privilege->type); + if (privilege->value) + free((void *)privilege->value); + if (privilege->license) + free((void *)privilege->license); + free((void *)privilege); +} + static void __ps_free_datacontrol(gpointer data) { datacontrol_x *datacontrol = (datacontrol_x *)data; @@ -450,6 +464,12 @@ API void pkgmgrinfo_basic_free_package(package_x *package) g_list_free_full(package->license, __ps_free_license); /*Free Privileges*/ g_list_free_full(package->privileges, __ps_free_privilege); + /*Free AppDefined Privileges*/ + g_list_free_full(package->appdefined_privileges, + __ps_free_appdefined_privilege); + /*Free Providing AppDefined Privileges*/ + g_list_free_full(package->provides_appdefined_privileges, + __ps_free_appdefined_privilege); /*Free Application*/ g_list_free_full(package->application, __ps_free_application); /*Free Compatibility*/ diff --git a/src/pkgmgrinfo_db.c b/src/pkgmgrinfo_db.c index f468368..fc19d5c 100644 --- a/src/pkgmgrinfo_db.c +++ b/src/pkgmgrinfo_db.c @@ -301,6 +301,7 @@ static const char *parserdb_tables[] = { "package_app_data_control", "package_localized_info", "package_privilege_info", + "package_appdefined_privilege_info", "package_app_data_control_privilege", NULL }; diff --git a/src/pkgmgrinfo_pkginfo.c b/src/pkgmgrinfo_pkginfo.c index 1ddc766..98c5d89 100644 --- a/src/pkgmgrinfo_pkginfo.c +++ b/src/pkgmgrinfo_pkginfo.c @@ -219,6 +219,49 @@ static int _pkginfo_get_privilege(sqlite3 *db, const char *pkgid, return PMINFO_R_OK; } +static int _pkginfo_get_appdefined_privilege(sqlite3 *db, const char *pkgid, + GList **privileges) +{ + static const char query_raw[] = + "SELECT DISTINCT privilege, license, type FROM " + "package_appdefined_privilege_info WHERE package=%Q"; + int ret; + char *query; + sqlite3_stmt *stmt; + appdefined_privilege_x *privilege; + + query = sqlite3_mprintf(query_raw, pkgid); + if (query == NULL) { + LOGE("out of memory"); + return PMINFO_R_ERROR; + } + + ret = sqlite3_prepare_v2(db, query, strlen(query), + &stmt, NULL); + sqlite3_free(query); + if (ret != SQLITE_OK) { + LOGE("prepare failed: %s", sqlite3_errmsg(db)); + return PMINFO_R_ERROR; + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + privilege = calloc(1, sizeof(appdefined_privilege_x)); + if (!privilege) { + LOGE("failed to alloc memory"); + return PMINFO_R_ERROR; + } + _save_column_str(stmt, 0, &privilege->value); + _save_column_str(stmt, 1, &privilege->license); + _save_column_str(stmt, 2, &privilege->type); + *privileges = g_list_append(*privileges, + (gpointer)privilege); + } + + sqlite3_finalize(stmt); + + return PMINFO_R_OK; +} + static const char join_localized_info[] = " LEFT OUTER JOIN package_localized_info" " ON pi.package=package_localized_info.package" @@ -527,6 +570,14 @@ static int _pkginfo_get_packages(uid_t uid, const char *locale, } } + if (flag & PMINFO_PKGINFO_GET_APPDEFINED_PRIVILEGE) { + if (_pkginfo_get_appdefined_privilege(db, info->package, + &info->appdefined_privileges)) { + ret = PMINFO_R_ERROR; + goto catch; + } + } + if (is_check_storage && __pkginfo_check_installed_storage(info) != PMINFO_R_OK) { ret = PMINFO_R_ERROR; @@ -1901,6 +1952,35 @@ API int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle, return PMINFO_R_OK; } +API int pkgmgrinfo_pkginfo_foreach_appdefined_privilege( + pkgmgrinfo_pkginfo_h handle, + pkgmgrinfo_pkg_appdefined_privilege_list_cb privilege_func, + void *user_data) +{ + retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL"); + retvm_if(privilege_func == NULL, PMINFO_R_EINVAL, + "Callback function is NULL"); + int ret; + appdefined_privilege_x *privilege; + GList *tmp; + pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle; + + if (info->pkg_info == NULL) + return PMINFO_R_ERROR; + + for (tmp = info->pkg_info->appdefined_privileges; tmp; + tmp = tmp->next) { + privilege = (appdefined_privilege_x *)tmp->data; + if (privilege == NULL) + continue; + ret = privilege_func(privilege->value, privilege->license, + user_data); + if (ret < 0) + break; + } + return PMINFO_R_OK; +} + int __compare_package_version(const char *version, int *major, int *minor, int *macro, int *nano) { -- 2.7.4