From aa88d97f98ae9093f07947ec8397e15e07e1dac3 Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Thu, 13 Dec 2018 19:10:17 +0900 Subject: [PATCH] Implement pkgmgr plugin execution info Change-Id: I091818b5e368542a5e44d6a61d58ef6cd5d9dee0 Signed-off-by: Junghyun Yeon --- include/pkgmgr-info.h | 111 +++++++++++++++++++++++ include/pkgmgrinfo_basic.h | 8 ++ include/pkgmgrinfo_type.h | 19 ++++ parser/include/pkgmgr_parser_db.h | 75 ++++++++++++++++ parser/src/pkgmgr_parser_db.c | 165 ++++++++++++++++++++++++++++++++++ parser/src/pkgmgr_parser_db_queries.h | 7 ++ src/pkgmgrinfo_basic.c | 18 ++++ src/pkgmgrinfo_pkginfo.c | 77 ++++++++++++++++ src/pkgmgrinfo_plugininfo.c | 136 ++++++++++++++++++++++++++++ 9 files changed, 616 insertions(+) create mode 100644 src/pkgmgrinfo_plugininfo.c diff --git a/include/pkgmgr-info.h b/include/pkgmgr-info.h index 89f2ed6..9ba8de8 100644 --- a/include/pkgmgr-info.h +++ b/include/pkgmgr-info.h @@ -1354,6 +1354,71 @@ int pkgmgrinfo_updateinfo_foreach_updateinfo(pkgmgrinfo_foreach_updateinfo_cb ca int pkgmgrinfo_updateinfo_usr_foreach_updateinfo(uid_t uid, pkgmgrinfo_foreach_updateinfo_cb callback, void *user_data); /** + * @fn int pkgmgrinfo_plugininfo_is_executed(const char *pkgid, const char *appid, const char *plugin_type, const char *plugin_name, bool *is_executed); + * @brief This API checkes whether given plugin had been executed with given package ID and application ID or not. + * + * @par This API is for package-manager client application + * @par Sync (or) Async : Synchronous API + * + * @param[in] pkgid package ID + * @param[in] appid application ID + * @param[in] plugin_type plugin type to be checked + * @param[in] plugin_name plugin name to be checked + * @param[out] is_executed check result + * @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 + * @code +static bool check_execute_info(const char *pkgid, const char *appid, const char *plugin_type, const char *plugin_name) +{ + int ret = 0; + bool is_executed; + + ret = pkgmgrinfo_plugininfo_is_executed(pkgid, appid, plugin_type, plugin_name, &is_executed); + if (ret != PMINFO_R_OK) + return -1; + printf("is checked is [%d]\n", is_executed); + return 0; +} + * @endcode + */ +int pkgmgrinfo_plugininfo_is_executed(const char *pkgid, const char *appid, + const char *plugin_type, const char *plugin_name, bool *is_executed); + +/** + * @fn int pkgmgrinfo_plugininfo_foreach_plugininfo(const char *pkgid, const char *plugin_type, const char *plugin_name, pkgmgrinfo_plugin_list_cb plugin_list_cb, void *user_data); + * @brief This API retrieve the previous plugin execution info and invoke callbacks each of it. + * + * @par This API is for package-manager client application + * @par Sync (or) Async : Synchronous API + * + * @param[in] pkgid package ID + * @param[in] plugin_type type of plugin + * @param[in] plugin_name name of plugin + * @param[in] plugin_list_cb callback to be invoked for each plugin execution info + * @param[out] user_data user data to be passed to callback + * @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 + * @code +static int foreach_pkg_plugininfo(const char *pkgid, const char *plugin_type, const char *plugin_name, pkgmgrinfo_plugin_list_cb callback) +{ + int ret = 0; + + ret = pkgmgrinfo_plugininfo_foreach_plugininfo(pkgid, plugin_type, plugin_name, callback, NULL); + if (ret != PMINFO_R_OK) + return -1; + return 0; +} + * @endcode + */ +int pkgmgrinfo_plugininfo_foreach_plugininfo(const char *pkgid, + const char *plugin_type, const char *plugin_name, + pkgmgrinfo_plugin_list_cb plugin_list_cb, void *user_data); + +/** * @fn int pkgmgrinfo_appinfo_get_launch_mode(pkgmgrinfo_appinfo_h handle, char **mode) * @brief This API gets the launch mode of package from the package ID * @@ -2487,6 +2552,52 @@ static int list_appdefined_privilege(const char *package) int pkgmgrinfo_pkginfo_foreach_appdefined_privilege(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_pkg_appdefined_privilege_list_cb privilege_func, void *user_data); +/** + * @fn int pkgmgrinfo_pkginfo_foreach_plugin(pkgmgrinfo_pkginfo_h handle, + pkgmgrinfo_plugin_list_cb plugin_func, void *user_data); + * @brief This API gets the list of plugin execution info 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] plugin_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 plugin_func(const char *pkgid, const char *appid, + const char *plugin_type, const char *plugin_name, + void *user_data) +{ + printf("appid : %s, type : %s, name : %s\n", appid, plugin_type, plugin_name); + + return 0; +} + +static int list_plugin(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_plugin(handle, plugin_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_plugin(pkgmgrinfo_pkginfo_h handle, + pkgmgrinfo_plugin_list_cb plugin_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 87b6109..974d9b8 100644 --- a/include/pkgmgrinfo_basic.h +++ b/include/pkgmgrinfo_basic.h @@ -91,6 +91,13 @@ typedef struct compatibility_x { char *text; } compatibility_x; +typedef struct plugin_x { + char *pkgid; + char *appid; + char *plugin_type; + char *plugin_name; +} plugin_x; + typedef struct datacontrol_x { char *providerid; char *access; @@ -233,6 +240,7 @@ typedef struct package_x { GList *compatibility; /**< package compatibility, element*/ GList *deviceprofile; /**< package device profile, element*/ GList *dependencies; /**< package dependencies, element*/ + GList *plugin; /**< plugin execution list, no xml part*/ } package_x; typedef struct updateinfo_x { diff --git a/include/pkgmgrinfo_type.h b/include/pkgmgrinfo_type.h index 283878c..870d376 100644 --- a/include/pkgmgrinfo_type.h +++ b/include/pkgmgrinfo_type.h @@ -343,6 +343,25 @@ typedef int (*pkgmgrinfo_pkg_dependency_list_cb) (const char *pkgid, void *user_data); /** + * @fn int (*pkgmgrinfo_plugin_list_cb) (const char *pkgid, const char *appid, const char *plugin_type, const char *plugin_name, void *user_data); + * + * @brief Specifies the type of function passed to pkgmgrinfo_plugininfo_foreach_plugininfo() + * + * @param[in] pkgid the name of the package + * @param[in] appid the name of the application + * @param[in] plugin_type the type of the executed plugin + * @param[in] plugin_name the name of the executed plugin + * @param[in] user_data user data passed to pkgmgrinfo_plugininfo_foreach_plugininfo() + * + * @return 0 if success, negative value(<0) if fail. Callback is not called if return value is negative.\n + * + * @see pkgmgrinfo_plugininfo_foreach_plugininfo() + */ +typedef int (*pkgmgrinfo_plugin_list_cb) (const char *pkgid, const char *appid, + const char *plugin_type, const char *plugin_name, + void *user_data); + +/** * @fn int (*pkgmgrinfo_app_metadata_list_cb) (const char *metadata_key, const char *metadata_value, void *user_data) * * @brief Specifies the type of function passed to pkgmgrinfo_appinfo_foreach_metadata() diff --git a/parser/include/pkgmgr_parser_db.h b/parser/include/pkgmgr_parser_db.h index 0e91f62..2e84101 100644 --- a/parser/include/pkgmgr_parser_db.h +++ b/parser/include/pkgmgr_parser_db.h @@ -503,6 +503,81 @@ static int unregister_all_pkg_update_info(void) */ int pkgmgr_parser_unregister_all_pkg_update_info_in_db(void); +/** + * @fn int pkgmgr_parser_register_pkg_plugin_info_in_usr_db(manifest_x *mfx, uid_t uid) + * @brief This API registers package plugin execution information + * + * @par This API is only for internal usage + * @par Sync (or) Async : Synchronous API + * + * @param[in] mfx manifest structure pointer which contains plugin execution info + * @return 0 if success, error code(<0) if fail + * @pre None + * @post None + * @code +static int register_pkg_plugin_info(manifest_x *mfx) +{ + int ret = 0; + ret = pkgmgr_parser_register_pkg_plugin_info_in_db(mfx); + if (ret < 0) + return -1; + return 0; +} + * @endcode + */ +int pkgmgr_parser_register_pkg_plugin_info_in_db(manifest_x *mfx); +int pkgmgr_parser_register_pkg_plugin_info_in_usr_db(manifest_x *mfx, uid_t uid); + +/** + * @fn int pkgmgr_parser_update_pkg_plugin_info_in_usr_db(manifest_x *mfx, uid_t uid) + * @brief This API updates package plugin execution information + * + * @par This API is only for internal usage + * @par Sync (or) Async : Synchronous API + * + * @param[in] mfx manifest structure pointer which contains plugin execution info + * @return 0 if success, error code(<0) if fail + * @pre None + * @post None + * @code +static int update_pkg_plugin_info(manifest_x *mfx) +{ + int ret = 0; + ret = pkgmgr_parser_update_pkg_plugin_info_in_db(mfx); + if (ret < 0) + return -1; + return 0; +} + * @endcode + */ +int pkgmgr_parser_update_pkg_plugin_info_in_db(manifest_x *mfx); +int pkgmgr_parser_update_pkg_plugin_info_in_usr_db(manifest_x *mfx, uid_t uid); + +/** + * @fn int pkgmgr_parser_unregister_pkg_plugin_info_in_usr_db(const char *pkgid, uid_t uid) + * @brief This API unregisters package plugin execution information + * + * @par This API is only for internal usage + * @par Sync (or) Async : Synchronous API + * + * @param[in] pkgid package ID + * @return 0 if success, error code(<0) if fail + * @pre None + * @post None + * @code +static int unregister_pkg_plugin_info(const char *pkgid) +{ + int ret = 0; + ret = pkgmgr_parser_unregister_pkg_plugin_info_in_db(pkgid); + if (ret < 0) + return -1; + return 0; +} + * @endcode + */ +int pkgmgr_parser_unregister_pkg_plugin_info_in_db(const char *pkgid); +int pkgmgr_parser_unregister_pkg_plugin_info_in_usr_db(const char *pkgid, uid_t uid); + int pkgmgr_parser_create_and_initialize_db(uid_t uid); int pkgmgr_parser_initialize_parser_db(uid_t uid); int pkgmgr_parser_initialize_cert_db(void); diff --git a/parser/src/pkgmgr_parser_db.c b/parser/src/pkgmgr_parser_db.c index 8f4c854..b6db523 100644 --- a/parser/src/pkgmgr_parser_db.c +++ b/parser/src/pkgmgr_parser_db.c @@ -330,6 +330,7 @@ static const char *parser_init_queries[] = { QUERY_CREATE_TRIGGER_UPDATE_PACKAGE_APP_INFO_FOR_UID, QUERY_CREATE_TABLE_PACKAGE_APP_SPLASH_SCREEN, QUERY_CREATE_TABLE_PACKAGE_DEPENDENCY_INFO, + QUERY_CREATE_TABLE_PACKAGE_PLUGIN_INFO, NULL, }; @@ -1713,6 +1714,81 @@ static int __insert_package_privilege_info(sqlite3 *db, manifest_x *mfx) return 0; } +static int __insert_package_plugin_execution_info(sqlite3 *db, + manifest_x *mfx) +{ + static const char query[] = + "INSERT INTO package_plugin_info " + "(pkgid, appid, plugin_type, plugin_name) " + "VALUES (?, ?, ?, ?)"; + int ret; + sqlite3_stmt *stmt; + int idx; + GList *tmp; + plugin_x *plugin; + + if (!mfx->plugin) + return 0; + + 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->plugin; tmp; tmp = tmp->next) { + plugin = (plugin_x *)tmp->data; + if (plugin == NULL) + continue; + + idx = 1; + __BIND_TEXT(db, stmt, idx++, plugin->pkgid); + __BIND_TEXT(db, stmt, idx++, plugin->appid); + __BIND_TEXT(db, stmt, idx++, plugin->plugin_type); + __BIND_TEXT(db, stmt, idx++, plugin->plugin_name); + + 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; +} + +static int __delete_package_plugin_execution_info(sqlite3 *db, + const char *pkgid) +{ + static const char query[] = + "DELETE FROM package_plugin_info WHERE pkgid=?"; + int ret; + sqlite3_stmt *stmt; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + _LOGE("prepare failed: %s", sqlite3_errmsg(db)); + return -1; + } + + __BIND_TEXT(db, stmt, 1, pkgid); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + _LOGE("step failed: %s", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + return -1; + } + + sqlite3_finalize(stmt); + + return 0; +} + static int __insert_package_appdefined_privilege_info(sqlite3 *db, manifest_x *mfx) { @@ -3067,3 +3143,92 @@ API int pkgmgr_parser_unregister_all_pkg_update_info_in_db(void) return pkgmgr_parser_unregister_all_pkg_update_info_in_usr_db( __getuid()); } + +API int pkgmgr_parser_register_pkg_plugin_info_in_usr_db( + manifest_x *mfx, uid_t uid) +{ + int ret; + const char *dbpath; + sqlite3 *db; + + if (!mfx) + return PM_PARSER_R_EINVAL; + dbpath = __get_parser_db_path(uid); + ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE); + if (ret != SQLITE_OK) { + _LOGE("open db failed: %d", ret); + return PM_PARSER_R_ERROR; + } + + __BEGIN_TRANSACTION(db); + __DO_TRANSACTION(db, __insert_package_plugin_execution_info(db, mfx)); + __END_TRANSACTION(db); + + sqlite3_close_v2(db); + + return PM_PARSER_R_OK; +} + +API int pkgmgr_parser_register_pkg_plugin_info_in_db(manifest_x *mfx) +{ + return pkgmgr_parser_register_pkg_plugin_info_in_usr_db(mfx, __getuid()); +} + +API int pkgmgr_parser_update_pkg_plugin_info_in_usr_db( + manifest_x *mfx, uid_t uid) +{ + int ret; + const char *dbpath; + sqlite3 *db; + + if (!mfx) + return PM_PARSER_R_EINVAL; + dbpath = __get_parser_db_path(uid); + ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE); + if (ret != SQLITE_OK) { + _LOGE("open db failed: %d", ret); + return PM_PARSER_R_ERROR; + } + + __BEGIN_TRANSACTION(db); + __DO_TRANSACTION(db, __delete_package_plugin_execution_info(db, mfx->package)); + __DO_TRANSACTION(db, __insert_package_plugin_execution_info(db, mfx)); + __END_TRANSACTION(db); + + sqlite3_close_v2(db); + + return PM_PARSER_R_OK; +} + +API int pkgmgr_parser_update_pkg_plugin_info_in_db(manifest_x *mfx) +{ + return pkgmgr_parser_update_pkg_plugin_info_in_usr_db(mfx, __getuid()); +} + +API int pkgmgr_parser_unregister_pkg_plugin_info_in_usr_db( + const char *pkgid, uid_t uid) +{ + int ret; + const char *dbpath; + sqlite3 *db; + + dbpath = __get_parser_db_path(uid); + ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE); + if (ret != SQLITE_OK) { + _LOGE("open db failed: %d", ret); + return PM_PARSER_R_ERROR; + } + + __BEGIN_TRANSACTION(db); + __DO_TRANSACTION(db, __delete_package_plugin_execution_info(db, pkgid)); + __END_TRANSACTION(db); + + sqlite3_close_v2(db); + + return PM_PARSER_R_OK; +} + +API int pkgmgr_parser_unregister_pkg_plugin_info_in_db(const char *pkgid) +{ + return pkgmgr_parser_unregister_pkg_plugin_info_in_usr_db(pkgid, __getuid()); +} \ No newline at end of file diff --git a/parser/src/pkgmgr_parser_db_queries.h b/parser/src/pkgmgr_parser_db_queries.h index 69ba61e..d444f4c 100644 --- a/parser/src/pkgmgr_parser_db_queries.h +++ b/parser/src/pkgmgr_parser_db_queries.h @@ -250,6 +250,13 @@ " FOREIGN KEY(package)\n" \ " REFERENCES package_info(package) ON DELETE CASCADE)" +#define QUERY_CREATE_TABLE_PACKAGE_PLUGIN_INFO \ + "CREATE TABLE IF NOT EXISTS package_plugin_info (\n" \ + " pkgid TEXT NOT NULL,\n" \ + " appid TEXT,\n" \ + " plugin_type TEXT NOT NULL,\n" \ + " plugin_name TEXT NOT NULL)" + /* FIXME: duplicated at pkgmgrinfo_db.c */ #define QUERY_CREATE_TABLE_PACKAGE_CERT_INDEX_INFO \ "CREATE TABLE IF NOT EXISTS package_cert_index_info (\n" \ diff --git a/src/pkgmgrinfo_basic.c b/src/pkgmgrinfo_basic.c index 7f0f30c..381c0ac 100644 --- a/src/pkgmgrinfo_basic.c +++ b/src/pkgmgrinfo_basic.c @@ -85,6 +85,22 @@ static void __ps_free_compatibility(gpointer data) free((void *)compatibility); } +static void __ps_free_plugin_info(gpointer data) +{ + plugin_x *plugin = (plugin_x *)data; + if (plugin == NULL) + return; + if (plugin->pkgid) + free((void *)plugin->pkgid); + if (plugin->appid) + free((void *)plugin->appid); + if (plugin->plugin_type) + free((void *)plugin->plugin_type); + if (plugin->plugin_name) + free((void *)plugin->plugin_name); + free((void *)plugin); +} + static void __ps_free_appcontrol(gpointer data) { appcontrol_x *appcontrol = (appcontrol_x *)data; @@ -501,6 +517,8 @@ API void pkgmgrinfo_basic_free_package(package_x *package) g_list_free_full(package->deviceprofile, free); /*Free Dependencies*/ g_list_free_full(package->dependencies, __ps_free_dependency); + /*Free Plugin execution history*/ + g_list_free_full(package->plugin, __ps_free_plugin_info); free((void *)package); } diff --git a/src/pkgmgrinfo_pkginfo.c b/src/pkgmgrinfo_pkginfo.c index d800064..d7a6a52 100644 --- a/src/pkgmgrinfo_pkginfo.c +++ b/src/pkgmgrinfo_pkginfo.c @@ -181,6 +181,51 @@ static int _pkginfo_add_description_info_into_list(const char *locale, return PMINFO_R_OK; } +static int _pkginfo_get_plugin_execution_info(sqlite3 *db, const char *pkgid, + GList **plugins) +{ + static const char query_raw[] = + "SELECT appid, plugin_type, plugin_name FROM package_plugin_info " + "WHERE pkgid=%Q"; + int ret; + char *query; + sqlite3_stmt *stmt; + plugin_x *plugin; + + 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) { + plugin = calloc(1, sizeof(plugin_x)); + if (!plugin) { + LOGE("out of memory"); + sqlite3_finalize(stmt); + return PMINFO_R_ERROR; + } + plugin->pkgid = strdup(pkgid); + _save_column_str(stmt, 0, &plugin->appid); + _save_column_str(stmt, 1, &plugin->plugin_type); + _save_column_str(stmt, 2, &plugin->plugin_name); + *plugins = g_list_append(*plugins, + (gpointer)plugin); + } + + sqlite3_finalize(stmt); + + return PMINFO_R_OK; +} + static int _pkginfo_get_privilege(sqlite3 *db, const char *pkgid, GList **privileges) { @@ -556,6 +601,11 @@ static int _pkginfo_get_packages(uid_t uid, const char *locale, info->for_all_users = strdup((uid != global_user_uid) ? "false" : "true"); + if (_pkginfo_get_plugin_execution_info(db, info->package, &info->plugin)) { + ret = PMINFO_R_ERROR; + goto catch; + } + if (flag & PMINFO_PKGINFO_GET_AUTHOR) { /* TODO : author should be retrieved at package_localized_info */ author = calloc(1, sizeof(author_x)); @@ -2027,6 +2077,33 @@ API int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle, return PMINFO_R_OK; } +API int pkgmgrinfo_pkginfo_foreach_plugin(pkgmgrinfo_pkginfo_h handle, + pkgmgrinfo_plugin_list_cb plugin_func, void *user_data) +{ + retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL"); + retvm_if(plugin_func == NULL, PMINFO_R_EINVAL, + "Callback function is NULL"); + int ret; + plugin_x *plugin; + GList *tmp; + pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle; + + if (info->pkg_info == NULL) + return PMINFO_R_ERROR; + + for (tmp = info->pkg_info->plugin; tmp; tmp = tmp->next) { + plugin = (plugin_x *)tmp->data; + if (plugin == NULL) + continue; + ret = plugin_func(plugin->pkgid, plugin->appid, + plugin->plugin_type, plugin->plugin_name, user_data); + if (ret < 0) + return PMINFO_R_OK; + } + + return PMINFO_R_OK; +} + API int pkgmgrinfo_pkginfo_foreach_appdefined_privilege( pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_pkg_appdefined_privilege_list_cb privilege_func, diff --git a/src/pkgmgrinfo_plugininfo.c b/src/pkgmgrinfo_plugininfo.c new file mode 100644 index 0000000..01ff505 --- /dev/null +++ b/src/pkgmgrinfo_plugininfo.c @@ -0,0 +1,136 @@ +/* + * pkgmgr-info + * + * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Junghyun Yeon , Sangyoon Jang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#define _GNU_SOURCE + +#include +#include +#include + +#include "pkgmgrinfo_private.h" +#include "pkgmgrinfo_debug.h" +#include "pkgmgr-info.h" + +static void _free_plugin(gpointer data) +{ + plugin_x *plugin = (plugin_x *)data; + if (plugin == NULL) + return; + if (plugin->appid) + free((void *)plugin->appid); + free((void *)plugin); +} + +API int pkgmgrinfo_plugininfo_foreach_plugininfo(const char *pkgid, + const char *plugin_type, const char *plugin_name, + pkgmgrinfo_plugin_list_cb plugin_list_cb, void *user_data) +{ + int ret; + int idx = 0; + char *dbpath; + const char *appid; + sqlite3 *db; + sqlite3_stmt *stmt = NULL; + plugin_x *plugin; + GList *plugin_list = NULL; + GList *tmp_list; + + static const char query[] = + "SELECT appid FROM " + "package_plugin_info WHERE pkgid=? AND " + "plugin_type=? AND plugin_name=?"; + + if (!pkgid || !plugin_type || !plugin_name || !plugin_list_cb) { + _LOGE("Invalid parameter"); + return PMINFO_R_EINVAL; + } + + dbpath = getUserPkgParserDBPathUID(_getuid()); + if (dbpath == NULL) { + _LOGE("Failed to get db path"); + return PMINFO_R_ERROR; + } + + ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY); + if (ret != SQLITE_OK) { + _LOGD("failed to open db(%s): %d", dbpath, ret); + free(dbpath); + return PMINFO_R_ERROR; + } + free(dbpath); + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("prepare failed: %s", sqlite3_errmsg(db)); + ret = PMINFO_R_ERROR; + goto catch; + } + + ret = sqlite3_bind_text(stmt, ++idx, pkgid, -1, SQLITE_STATIC); + if (ret != SQLITE_OK) { + ret = PMINFO_R_ERROR; + goto catch; + } + + ret = sqlite3_bind_text(stmt, ++idx, plugin_type, -1, SQLITE_STATIC); + if (ret != SQLITE_OK) { + ret = PMINFO_R_ERROR; + goto catch; + } + ret = sqlite3_bind_text(stmt, ++idx, plugin_name, -1, SQLITE_STATIC); + if (ret != SQLITE_OK) { + ret = PMINFO_R_ERROR; + goto catch; + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + plugin = calloc(1, sizeof(plugin_x)); + if (plugin == NULL) { + _LOGE("out of memory"); + ret = PMINFO_R_ERROR; + goto catch; + } + idx = 0; + appid = (const char *)sqlite3_column_text(stmt, idx++); + if (appid) { + plugin->appid = strdup(appid); + } + plugin_list = g_list_append(plugin_list, plugin); + } + + for (tmp_list = plugin_list; tmp_list != NULL; tmp_list = tmp_list->next) { + plugin = (plugin_x *)tmp_list->data; + if (!plugin) + continue; + ret = plugin_list_cb(pkgid, plugin->appid, plugin_type, + plugin_name, user_data); + if (ret != 0) + break; + } + g_list_free_full(plugin_list, _free_plugin); + +catch: + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + + return ret; + +} \ No newline at end of file -- 2.7.4