From 16b761668dd29109d880d8c119bcad58b70c51cb Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Wed, 29 Mar 2017 21:52:35 +0900 Subject: [PATCH] Add pkg update info features - Provides methods to register, unregister, get update info of certain pkg - Provides methods to clear update infos of all pkgs including global pkgs whether caller is admin user or not. Related changes: [pkgmgr-server] : https://review.tizen.org/gerrit/122067 [slp-pkgmgr] : https://review.tizen.org/gerrit/122068 Change-Id: I70c55bf1ed8878a2ec254e79752d9863daef5511 Signed-off-by: Junghyun Yeon --- include/pkgmgr-info.h | 296 ++++++++++++++++++++++++++++++ include/pkgmgrinfo_basic.h | 6 + include/pkgmgrinfo_type.h | 41 +++++ parser/include/pkgmgr_parser_db.h | 145 +++++++++++++++ parser/src/pkgmgr_parser_db.c | 208 +++++++++++++++++++++ src/pkgmgrinfo_updateinfo.c | 373 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 1069 insertions(+) create mode 100644 src/pkgmgrinfo_updateinfo.c diff --git a/include/pkgmgr-info.h b/include/pkgmgr-info.h index b761663..5bb8bd4 100644 --- a/include/pkgmgr-info.h +++ b/include/pkgmgr-info.h @@ -1053,6 +1053,302 @@ static int get_pkg_installed_time(const char *pkgid) int pkgmgrinfo_pkginfo_get_installed_time(pkgmgrinfo_pkginfo_h handle, int *installed_time); /** + * @fn int pkgmgrinfo_updateinfo_create(pkgmgrinfo_updateinfo_h *update_handle) + * @brief This API creates the update info handle + * + * @par This API is for package-manager client application + * @par Sync (or) Async : Synchronous API + * + * @param[out] handle pointer to package update info handle + * @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 + * @post pkgmgrinfo_updateinfo_destroy() + * @see pkgmgrinfo_updateinfo_set_pkgid() + * @see pkgmgrinfo_updateinfo_set_version() + * @see pkgmgrinfo_updateinfo_set_type() + * @see pkgmgr_client_register_pkg_updateinfo() + * @code +static int updateinfo_handle_create() +{ + int ret = 0; + + pkgmgrinfo_updateinfo_h handle; + ret = pkgmgrinfo_updateinfo_create(&handle); + if (ret != PMINFO_R_OK) + return -1; + pkgmgrinfo_update_infodestroy(handle); + return 0; +} + * @endcode + */ +int pkgmgrinfo_updateinfo_create(pkgmgrinfo_updateinfo_h *update_handle); + +/** + * @fn int pkgmgrinfo_updateinfo_destroy(pkgmgrinfo_updateinfo_h update_handle) + * @brief This API destroy the update info handle + * + * @par This API is for package-manager client application + * @par Sync (or) Async : Synchronous API + * + * @param[in] handle pointer to package update info handle + * @return 0 if success, error code(<0) if fail + * @retval PMINFO_R_OK success + * @retval PMINFO_R_EINVAL invalid argument + * @pre pkgmgrinfo_updateinfo_create() + * @see pkgmgr_client_register_pkg_updateinfo() + * @code +static int updateinfo_handle_destroy(pkgmgrinfo_updateinfo_h handle) +{ + int ret = 0; + + ret = pkgmgrinfo_updateinfo_destroy(handle); + if (ret != PMINFO_R_OK) + return -1; + return 0; +} + * @endcode + */ +int pkgmgrinfo_updateinfo_destroy(pkgmgrinfo_updateinfo_h update_handle); + +/** + * @fn int pkgmgrinfo_updateinfo_get_updateinfo(const char *pkgid, pkgmgrinfo_updateinfo_h *update_handle) + * @brief This API creates the package update information handle from db + * + * @par This API is for package-manager client application + * @par Sync (or) Async : Synchronous API + * + * @param[in] pkgid pointer to package ID + * @param[in] uid the addressee user id of the instruction + * @param[out] update_handle pointer to the package update info handle. + * @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 None + * @post pkgmgrinfo_updateinfo_destroy() + * @see pkgmgrinfo_updateinfo_get_pkgid() + * @see pkgmgrinfo_updateinfo_get_version() + * @see pkgmgrinfo_updateinfo_get_update_type() + * @code +static int get_pkg_update_info(const char *pkgid) +{ + int ret = 0; + char *version; + pkgmgrinfo_updateinfo_h handle; + ret = pkgmgrinfo_updateinfo_get_updateinfo(pkgid, &handle); + if (ret != PMINFO_R_OK) + return -1; + ret = pkgmgrinfo_updateinfo_get_version(handle, &version); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_updateinfo_destroy(handle); + return -1; + } + printf("pkg update version: %s\n", version + pkgmgrinfo_updateinfo_destroy(handle); + return 0; +} + * @endcode + */ +int pkgmgrinfo_updateinfo_get_updateinfo(const char *pkgid, pkgmgrinfo_updateinfo_h *update_handle); +int pkgmgrinfo_updateinfo_get_usr_updateinfo(const char *pkgid, pkgmgrinfo_updateinfo_h *update_handle, uid_t uid); + +/** + * @fn int pkgmgrinfo_updateinfo_set_pkgid(pkgmgrinfo_updateinfo_h updateinfo_handle, const char *pkgid) + * @brief This API sets given pkgid into handle + * + * @par This API is for package-manager client application + * @par Sync (or) Async : Synchronous API + * + * @param[in] handle pointer to package update info handle + * @param[in] pkgid package id + * @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 set_pkgid_to_handle(pkgmgrinfo_updateinfo_h handle, const char *pkgid) +{ + int ret = 0; + + ret = pkgmgrinfo_updateinfo_set_pkgid(handle, pkgid); + if (ret != PMINFO_R_OK) + return -1; + return 0; +} + * @endcode + */ +int pkgmgrinfo_updateinfo_set_pkgid(pkgmgrinfo_updateinfo_h updateinfo_handle, const char *pkgid); + +/** + * @fn int pkgmgrinfo_updateinfo_set_version(pkgmgrinfo_updateinfo_h updateinfo_handle, const char *version) + * @brief This API sets given version into handle + * + * @par This API is for package-manager client application + * @par Sync (or) Async : Synchronous API + * + * @param[in] handle pointer to package update info handle + * @param[in] version update version + * @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 set_version_to_handle(pkgmgrinfo_updateinfo_h handle, const char *version) +{ + int ret = 0; + + ret = pkgmgrinfo_updateinfo_set_version(handle, version); + if (ret != PMINFO_R_OK) + return -1; + return 0; +} + * @endcode + */ +int pkgmgrinfo_updateinfo_set_version(pkgmgrinfo_updateinfo_h updateinfo_handle, const char *version); + +/** + * @fn int pkgmgrinfo_updateinfo_set_type(pkgmgrinfo_updateinfo_h updateinfo_handle, pkgmgrinfo_updateinfo_update_type type) + * @brief This API sets given update type into handle + * + * @par This API is for package-manager client application + * @par Sync (or) Async : Synchronous API + * + * @param[in] handle pointer to package update info handle + * @param[in] type update type + * @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 set_type_to_handle(pkgmgrinfo_updateinfo_h handle, pkgmgrinfo_updateinfo_update_type type) +{ + int ret = 0; + + ret = pkgmgrinfo_updateinfo_set_type(handle, type); + if (ret != PMINFO_R_OK) + return -1; + return 0; +} + * @endcode + */ +int pkgmgrinfo_updateinfo_set_type(pkgmgrinfo_updateinfo_h updateinfo_handle, pkgmgrinfo_updateinfo_update_type type); + +/** + * @fn int pkgmgrinfo_updateinfo_get_pkgid(pkgmgrinfo_updateinfo_h update_handle, char **pkgid) + * @brief This API retrieves the pkgid from given update info + * + * @par This API is for package-manager client application + * @par Sync (or) Async : Synchronous API + * + * @param[in] handle pointer to package update info handle + * @param[out] pkgid package id + * @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 get_pkgid_from_handle(pkgmgrinfo_updateinfo_h handle) +{ + int ret = 0; + char *pkgid; + + ret = pkgmgrinfo_updateinfo_get_pkgid(handle, &pkgid); + if (ret != PMINFO_R_OK) + return -1; + return 0; +} + * @endcode + */ +int pkgmgrinfo_updateinfo_get_pkgid(pkgmgrinfo_updateinfo_h update_handle, char **pkgid); + +/** + * @fn int pkgmgrinfo_updateinfo_get_version(pkgmgrinfo_updateinfo_h updateinfo_handle, char **version) + * @brief This API retrieves the version from given update info + * + * @par This API is for package-manager client application + * @par Sync (or) Async : Synchronous API + * + * @param[in] handle pointer to package update info handle + * @param[out] version update version + * @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 get_version_from_handle(pkgmgrinfo_updateinfo_h handle) +{ + int ret = 0; + char *version; + + ret = pkgmgrinfo_updateinfo_get_version(handle, &version); + if (ret != PMINFO_R_OK) + return -1; + return 0; +} + * @endcode + */ +int pkgmgrinfo_updateinfo_get_version(pkgmgrinfo_updateinfo_h updateinfo_handle, char **version); + +/** + * @fn int pkgmgrinfo_updateinfo_get_update_type(pkgmgrinfo_updateinfo_h updateinfo_handle, pkgmgrinfo_updateinfo_update_type *type) + * @brief This API retrieves the update type from given update info + * + * @par This API is for package-manager client application + * @par Sync (or) Async : Synchronous API + * + * @param[in] handle pointer to package update info handle + * @param[out] type update type + * @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 get_type_from_handle(pkgmgrinfo_updateinfo_h handle) +{ + int ret = 0; + pkgmgrinfo_updateinfo_update_type *type; + + ret = pkgmgrinfo_updateinfo_get_type(handle, &type); + if (ret != PMINFO_R_OK) + return -1; + return 0; +} + * @endcode + */ +int pkgmgrinfo_updateinfo_get_update_type(pkgmgrinfo_updateinfo_h updateinfo_handle, pkgmgrinfo_updateinfo_update_type *type); + + +/** + * @fn int pkgmgrinfo_updateinfo_foreach_updateinfo(pkgmgrinfo_foreach_updateinfo_cb callback, void *user_data) + * @brief This API retrieve the update informations and invoke given callback for it. + * + * @par This API is for package-manager client application + * @par Sync (or) Async : Synchronous API + * + * @param[in] callback callback to be invoked for each retrieved informations + * @param[in] 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_updateinfo(pkgmgrinfo_foreach_updateinfo_cb callback) +{ + int ret = 0; + + ret = pkgmgrinfo_updateinfo_foreach_updateinfo(callback, NULL); + if (ret != PMINFO_R_OK) + return -1; + return 0; +} + * @endcode + */ +int pkgmgrinfo_updateinfo_foreach_updateinfo(pkgmgrinfo_foreach_updateinfo_cb callback, void *user_data); +int pkgmgrinfo_updateinfo_usr_foreach_updateinfo(uid_t uid, pkgmgrinfo_foreach_updateinfo_cb callback, 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 * diff --git a/include/pkgmgrinfo_basic.h b/include/pkgmgrinfo_basic.h index 420b1c0..b5a63cc 100644 --- a/include/pkgmgrinfo_basic.h +++ b/include/pkgmgrinfo_basic.h @@ -211,6 +211,12 @@ typedef struct package_x { GList *deviceprofile; /**< package device profile, element*/ } package_x; +typedef struct updateinfo_x { + char *pkgid; + char *version; + int type; +} updateinfo_x; + typedef struct package_x manifest_x; void pkgmgrinfo_basic_free_application(application_x *application); diff --git a/include/pkgmgrinfo_type.h b/include/pkgmgrinfo_type.h index 4bb96b9..b46e24e 100644 --- a/include/pkgmgrinfo_type.h +++ b/include/pkgmgrinfo_type.h @@ -137,6 +137,27 @@ enum { */ #define PMINFO_PKGINFO_INSTALL_LOCATION_EXTERNAL "LOCATION_EXTERNAL" +/** + * @brief Value to be used when get/set update information + */ +#define PMINFO_UPDATEINFO_TYPE_FORCE "force" + +/** + * @brief Value to be used when get/set update information + */ +#define PMINFO_UPDATEINFO_TYPE_OPTIONAL "optional" + +/** + * @brief Value to be used when get/set update information + */ +#define PMINFO_UPDATEINFO_TYPE_NONE "none" + +typedef enum { + PMINFO_UPDATEINFO_NONE = 0, /**package, mfx->version); + ret = __exec_query(query); + + return ret; +} + /* _PRODUCT_LAUNCHING_ENHANCED_ * app->indicatordisplay, app->portraitimg, app->landscapeimg, app->guestmode_appstatus */ @@ -1769,6 +1794,12 @@ static int __insert_manifest_info_in_db(manifest_x *mfx, uid_t uid) return -1; } + ret = __insert_pkg_updateinfo_in_db(mfx, uid); + if (ret == -1) { + _LOGE("Package Update Info DB Insert Failed\n"); + return -1; + } + /*Insert in the package_privilege_info DB*/ for (tmp = mfx->privileges; tmp; tmp = tmp->next) { pv = (privilege_x *)tmp->data; @@ -1974,6 +2005,16 @@ static int __delete_manifest_info_from_db(manifest_x *mfx, uid_t uid) } memset(query, '\0', MAX_QUERY_LEN); + /*Delete from Package Update Info DB*/ + sqlite3_snprintf(MAX_QUERY_LEN, query, + "DELETE FROM package_update_info WHERE package=%Q", mfx->package); + ret = __exec_query(query); + if (ret == -1) { + _LOGD("Package Update Info DB Delete Failed\n"); + return -1; + } + memset(query, '\0', MAX_QUERY_LEN); + /*Delete from Package Localized Info*/ sqlite3_snprintf(MAX_QUERY_LEN, query, "DELETE FROM package_localized_info WHERE package=%Q", mfx->package); @@ -2264,6 +2305,11 @@ API int pkgmgr_parser_initialize_db(uid_t uid) _LOGD("package app app privilege DB initialization failed\n"); return ret; } + ret = __initialize_db(pkgmgr_parser_db, QUERY_CREATE_TABLE_PACKAGE_UPDATE_INFO); + if (ret == -1) { + _LOGD("package update info DB initialization failed\n"); + return ret; + } ret = __initialize_db(pkgmgr_parser_db, QUERY_CREATE_TABLE_PACKAGE_APP_INFO); if (ret == -1) { _LOGD("package app info DB initialization failed\n"); @@ -2843,6 +2889,168 @@ API int pkgmgr_parser_delete_manifest_info_from_db(manifest_x *mfx) return pkgmgr_parser_delete_manifest_info_from_usr_db(mfx, _getuid()); } +static int _convert_update_type(pkgmgrinfo_updateinfo_update_type type, char **convert_type) +{ + if (type == PMINFO_UPDATEINFO_NONE) + *convert_type = PMINFO_UPDATEINFO_TYPE_NONE; + else if (type == PMINFO_UPDATEINFO_FORCE) + *convert_type = PMINFO_UPDATEINFO_TYPE_FORCE; + else if (type == PMINFO_UPDATEINFO_OPTIONAL) + *convert_type = PMINFO_UPDATEINFO_TYPE_OPTIONAL; + else + return -1; + return 0; +} + +API int pkgmgr_parser_register_pkg_update_info_in_usr_db(pkgmgrinfo_updateinfo_h handle, uid_t uid) +{ + int ret; + updateinfo_x *update_info; + updateinfo_x *prev_update_info; + pkgmgrinfo_updateinfo_h prev_update_handle; + pkgmgrinfo_pkginfo_h pkginfo; + pkgmgrinfo_version_compare_type compare_result; + bool is_global_pkg; + char query[MAX_QUERY_LEN] = {'\0'}; + char *convert_type; + + if (handle == NULL) + return PMINFO_R_EINVAL; + + update_info = (updateinfo_x *)handle; + if (update_info->pkgid == NULL || update_info->version == NULL) + return PMINFO_R_EINVAL; + if (_convert_update_type(update_info->type, &convert_type) != 0) + return PMINFO_R_EINVAL; + + ret = pkgmgrinfo_updateinfo_get_usr_updateinfo(update_info->pkgid, + &prev_update_handle, uid); + if (ret != PMINFO_R_OK) + return PMINFO_R_ERROR; + + prev_update_info = (updateinfo_x *)prev_update_handle; + ret = pkgmgrinfo_compare_package_version(update_info->version, + prev_update_info->version, &compare_result); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_updateinfo_destroy(prev_update_handle); + return PMINFO_R_ERROR; + } + + if (compare_result == PMINFO_VERSION_SAME && + prev_update_info->type == PMINFO_UPDATEINFO_NONE) { + _LOGI("Given update info version[%s] of pkgid[%s] will be ignored", + update_info->version, update_info->pkgid); + pkgmgrinfo_updateinfo_destroy(prev_update_handle); + return PMINFO_R_OK; + } + pkgmgrinfo_updateinfo_destroy(prev_update_handle); + + ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(update_info->pkgid, uid, + &pkginfo); + if (ret != PMINFO_R_OK) + return PMINFO_R_ERROR; + + ret = pkgmgrinfo_pkginfo_is_global(pkginfo, &is_global_pkg); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + return PMINFO_R_ERROR; + } + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + + ret = pkgmgr_parser_check_and_create_db( + (is_global_pkg) ? GLOBAL_USER : uid); + if (ret != PMINFO_R_OK) + return PMINFO_R_ERROR; + + sqlite3_snprintf(MAX_QUERY_LEN, query, + "UPDATE package_update_info SET update_version=%Q, " \ + "update_type=%Q WHERE package=%Q", + update_info->version, + convert_type, + update_info->pkgid); + + ret = __exec_query(query); + pkgmgr_parser_close_db(); + + return ret; +} + +API int pkgmgr_parser_register_pkg_update_info_in_db(pkgmgrinfo_updateinfo_h handle) +{ + return pkgmgr_parser_register_pkg_update_info_in_usr_db(handle, _getuid()); +} + +API int pkgmgr_parser_unregister_pkg_update_info_in_usr_db(const char *pkgid, uid_t uid) +{ + pkgmgrinfo_pkginfo_h pkginfo = NULL; + int ret; + bool is_global_pkg; + char query[MAX_QUERY_LEN] = {'\0'}; + + if (pkgid == NULL) + return PMINFO_R_EINVAL; + + ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &pkginfo); + if (ret != PMINFO_R_OK) + return -1; + + ret = pkgmgrinfo_pkginfo_is_global(pkginfo, &is_global_pkg); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + return PMINFO_R_ERROR; + } + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + ret = pkgmgr_parser_check_and_create_db((is_global_pkg) ? GLOBAL_USER : uid); + if (ret != PMINFO_R_OK) + return ret; + + sqlite3_snprintf(MAX_QUERY_LEN, query, + "UPDATE package_update_info SET update_type='none' " \ + "WHERE package=%Q", pkgid); + + ret = __exec_query(query); + pkgmgr_parser_close_db(); + + return ret; +} + +API int pkgmgr_parser_unregister_pkg_update_info_in_db(const char *pkgid) +{ + return pkgmgr_parser_unregister_pkg_update_info_in_usr_db(pkgid, _getuid()); +} + +API int pkgmgr_parser_unregister_all_pkg_update_info_in_usr_db(uid_t uid) +{ + int ret; + char query[MAX_QUERY_LEN] = {'\0'}; + char *error_message = NULL; + + ret = pkgmgr_parser_check_and_create_db(uid); + if (ret != 0) + return PMINFO_R_ERROR; + + sqlite3_snprintf(MAX_QUERY_LEN, query, + "UPDATE package_update_info SET update_type='none'"); + ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, &error_message); + if (ret != SQLITE_OK) { + _LOGE("Don't execute query = %s error message = %s\n", query, + error_message); + sqlite3_free(error_message); + pkgmgr_parser_close_db(); + return PMINFO_R_ERROR; + } + sqlite3_free(error_message); + error_message = NULL; + pkgmgr_parser_close_db(); + + return PMINFO_R_OK; +} + +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_update_global_app_disable_for_uid_info_in_db(const char *appid, uid_t uid, int is_disable) { int ret = -1; diff --git a/src/pkgmgrinfo_updateinfo.c b/src/pkgmgrinfo_updateinfo.c new file mode 100644 index 0000000..e599b8c --- /dev/null +++ b/src/pkgmgrinfo_updateinfo.c @@ -0,0 +1,373 @@ +/* + * pkgmgr-info + * + * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Junghyun Yeon(jungh.yeon@samsung.com>, + * Jongmyeong Ko(jongmyeong.ko@samsung.com>, Sangyoon Jang(s89.jang@samsung.com> + * + * 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 +#include + +#include "pkgmgrinfo_basic.h" +#include "pkgmgrinfo_private.h" +#include "pkgmgrinfo_debug.h" +#include "pkgmgr-info.h" + +static void __free_update_info(gpointer data) +{ + updateinfo_x *update_info = (updateinfo_x *)data; + if (update_info == NULL) + return; + + if (update_info->pkgid) + free((void *)update_info->pkgid); + if (update_info->version) + free((void *)update_info->version); + free((void *)update_info); + +} + +static int __convert_update_type(const char *type, pkgmgrinfo_updateinfo_update_type *convert_type) +{ + if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_NONE, + strlen(PMINFO_UPDATEINFO_TYPE_NONE)) == 0) + *convert_type = PMINFO_UPDATEINFO_NONE; + else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_FORCE, + strlen(PMINFO_UPDATEINFO_TYPE_FORCE)) == 0) + *convert_type = PMINFO_UPDATEINFO_FORCE; + else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_OPTIONAL, + strlen(PMINFO_UPDATEINFO_TYPE_OPTIONAL)) == 0) + *convert_type = PMINFO_UPDATEINFO_OPTIONAL; + else + return -1; + return 0; +} + +API int pkgmgrinfo_updateinfo_create( + pkgmgrinfo_updateinfo_h *updateinfo_handle) +{ + updateinfo_x *update_info; + + retvm_if(updateinfo_handle == NULL, PMINFO_R_EINVAL, + "Update handle output parameter is NULL\n"); + + update_info = (updateinfo_x *)calloc( + 1, sizeof(updateinfo_x)); + if (update_info == NULL) { + _LOGE("Out of memory"); + return PMINFO_R_ERROR; + } + + *updateinfo_handle = update_info; + + return PMINFO_R_OK; +} + +API int pkgmgrinfo_updateinfo_destroy( + pkgmgrinfo_updateinfo_h updateinfo_handle) +{ + retvm_if(updateinfo_handle == NULL, PMINFO_R_EINVAL, + "Update info handle parameter is NULL\n"); + + __free_update_info(updateinfo_handle); + return PMINFO_R_OK; +} + +API int pkgmgrinfo_updateinfo_set_pkgid( + pkgmgrinfo_updateinfo_h updateinfo_handle, const char *pkgid) +{ + updateinfo_x *updateinfo; + + retvm_if(updateinfo_handle == NULL, PMINFO_R_EINVAL, + "Update info handle parameter is NULL\n"); + retvm_if(pkgid == NULL, PMINFO_R_EINVAL, + "pkgid parameter is NULL\n"); + + updateinfo = (updateinfo_x *)updateinfo_handle; + if (updateinfo->pkgid) + free(updateinfo->pkgid); + + updateinfo->pkgid = strdup(pkgid); + if (updateinfo->pkgid == NULL) { + _LOGE("Out of memory"); + return PMINFO_R_ERROR; + } + + return PMINFO_R_OK; +} + +API int pkgmgrinfo_updateinfo_set_version( + pkgmgrinfo_updateinfo_h updateinfo_handle, const char *version) +{ + updateinfo_x *updateinfo; + + retvm_if(updateinfo_handle == NULL, PMINFO_R_EINVAL, + "Update info handle parameter is NULL\n"); + retvm_if(version == NULL, PMINFO_R_EINVAL, + "pkgid parameter is NULL\n"); + + updateinfo = (updateinfo_x *)updateinfo_handle; + if (updateinfo->version) + free(updateinfo->version); + + updateinfo->version = strdup(version); + if (updateinfo->version == NULL) { + _LOGE("Out of memory"); + return PMINFO_R_ERROR; + } + + return PMINFO_R_OK; +} + +API int pkgmgrinfo_updateinfo_set_type( + pkgmgrinfo_updateinfo_h updateinfo_handle, + pkgmgrinfo_updateinfo_update_type type) +{ + updateinfo_x *updateinfo; + + retvm_if(updateinfo_handle == NULL, PMINFO_R_EINVAL, + "Update info handle parameter is NULL\n"); + + updateinfo = (updateinfo_x *)updateinfo_handle; + updateinfo->type = type; + return PMINFO_R_OK; +} + +API int pkgmgrinfo_updateinfo_get_pkgid( + pkgmgrinfo_updateinfo_h updateinfo_handle, char **pkgid) +{ + updateinfo_x *update_info; + + retvm_if(updateinfo_handle == NULL, PMINFO_R_EINVAL, + "Update info node parameter is NULL\n"); + + update_info = (updateinfo_x *)updateinfo_handle; + if (update_info->pkgid == NULL) + return PMINFO_R_ERROR; + + *pkgid = update_info->pkgid; + return PMINFO_R_OK; +} + +API int pkgmgrinfo_updateinfo_get_version( + pkgmgrinfo_updateinfo_h updateinfo_handle, char **version) +{ + updateinfo_x *update_info; + + retvm_if(updateinfo_handle == NULL, PMINFO_R_EINVAL, + "Update info node parameter is NULL\n"); + + update_info = (updateinfo_x *)updateinfo_handle; + if (update_info->version == NULL) + return PMINFO_R_ERROR; + + *version = update_info->version; + return PMINFO_R_OK; +} + +API int pkgmgrinfo_updateinfo_get_update_type( + pkgmgrinfo_updateinfo_h updateinfo_handle, + pkgmgrinfo_updateinfo_update_type *type) +{ + updateinfo_x *update_info; + + retvm_if(updateinfo_handle == NULL, PMINFO_R_EINVAL, + "Update info node parameter is NULL\n"); + + update_info = (updateinfo_x *)updateinfo_handle; + *type = update_info->type; + + return PMINFO_R_OK; +} + +static int _get_pkg_updateinfo_from_db(const char *pkgid, + GSList **update_info_list, uid_t uid) +{ + char *dbpath; + char *type; + char query[MAX_QUERY_LEN] = { '\0' }; + int ret; + int idx; + sqlite3 *db; + sqlite3_stmt *stmt; + updateinfo_x *update_info = NULL; + pkgmgrinfo_updateinfo_update_type convert_type; + + dbpath = getUserPkgParserDBPathUID(uid); + if (dbpath == NULL) + return PMINFO_R_ERROR; + + ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY); + if (ret != SQLITE_OK) { + _LOGD("failed to open db: %d", ret); + free(dbpath); + return -1; + } + + if (pkgid == NULL) + sqlite3_snprintf(MAX_QUERY_LEN, query, + "SELECT package, update_version, update_type " \ + "FROM package_update_info"); + else + sqlite3_snprintf(MAX_QUERY_LEN, query, + "SELECT package, update_version, update_type " \ + "FROM package_update_info WHERE package=%Q", + pkgid); + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + _LOGE("Don't execute query = %s error message = %s\n", query, + sqlite3_errmsg(db)); + free(dbpath); + return -1; + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + update_info = calloc(1, sizeof(updateinfo_x)); + if (update_info == NULL) { + _LOGE("Out of memory"); + free(dbpath); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return -1; + } + idx = 0; + _save_column_str(stmt, idx++, &update_info->pkgid); + _save_column_str(stmt, idx++, &update_info->version); + _save_column_str(stmt, idx, &type); + ret = __convert_update_type(type, &convert_type); + if (ret != 0) { + __free_update_info(update_info); + free(dbpath); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return -1; + } + update_info->type = convert_type; + *update_info_list = g_slist_append(*update_info_list, update_info); + } + + free(dbpath); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + + return 0; +} + +API int pkgmgrinfo_updateinfo_get_usr_updateinfo(const char *pkgid, + pkgmgrinfo_updateinfo_h *update_handle, uid_t uid) +{ + int ret; + pkgmgrinfo_pkginfo_h pkginfo = NULL; + bool is_global_pkg; + updateinfo_x *update_info; + GSList *info_list = NULL; + + if (update_handle == NULL || pkgid == NULL) + return PMINFO_R_EINVAL; + + update_info = calloc(1, sizeof(updateinfo_x)); + if (update_info == NULL) { + _LOGE("Out of memory"); + return PMINFO_R_ERROR; + } + + ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &pkginfo); + if (ret != PMINFO_R_OK) { + free(update_info); + return ret; + } + ret = pkgmgrinfo_pkginfo_is_global(pkginfo, &is_global_pkg); + if (ret != PMINFO_R_OK) { + free(update_info); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + return ret; + } + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + + ret = _get_pkg_updateinfo_from_db(pkgid, &info_list, + (is_global_pkg) ? GLOBAL_USER : uid); + + if (ret != PMINFO_R_OK) { + g_slist_free_full(info_list, __free_update_info); + return PMINFO_R_ERROR; + } + *update_handle = (pkgmgrinfo_updateinfo_h)info_list->data; + g_slist_free(info_list); + + return ret; +} + +API int pkgmgrinfo_updateinfo_get_updateinfo(const char *pkgid, + pkgmgrinfo_updateinfo_h *update_handle) +{ + return pkgmgrinfo_updateinfo_get_usr_updateinfo(pkgid, update_handle, _getuid()); +} + +API int pkgmgrinfo_updateinfo_usr_foreach_updateinfo(uid_t uid, + pkgmgrinfo_foreach_updateinfo_cb callback, void *user_data) +{ + int ret; + GSList *info_list; + GSList *tmp_list; + + if (callback == NULL) + return PMINFO_R_EINVAL; + + info_list = calloc(1, sizeof(updateinfo_x)); + if (info_list == NULL) { + _LOGE("Out of memory"); + return PMINFO_R_ERROR; + } + + ret = _get_pkg_updateinfo_from_db(NULL, &info_list, uid); + if (ret != 0) { + _LOGE("Failed to get pkg update info for user[%d]", (int)uid); + pkgmgrinfo_updateinfo_destroy(info_list); + return PMINFO_R_ERROR; + } + + ret = _get_pkg_updateinfo_from_db(NULL, &info_list, GLOBAL_USER); + if (ret != 0) { + _LOGE("Failed to get pkg update info for user[%d]", + (int)GLOBAL_USER); + pkgmgrinfo_updateinfo_destroy(info_list); + return PMINFO_R_ERROR; + } + + for (tmp_list = info_list; tmp_list; tmp_list = g_slist_next(tmp_list)) { + ret = callback((pkgmgrinfo_updateinfo_h)tmp_list->data, user_data); + if (ret < 0) + break; + } + + g_slist_free_full(info_list, __free_update_info); + return PMINFO_R_OK; +} + +API int pkgmgrinfo_updateinfo_foreach_updateinfo( + pkgmgrinfo_foreach_updateinfo_cb callback, void *user_data) +{ + return pkgmgrinfo_updateinfo_usr_foreach_updateinfo(_getuid(), + callback, user_data); +} -- 2.7.4