const char *target_version, pkgmgrinfo_version_compare_type *res);
/**
+ * @fn int pkgmgrinfo_pkginfo_foreach_dependency(pkgmgrinfo_pkginfo_h handle,
+ pkgmgrinfo_pkg_dependency_list_cb dependency_cb,
+ void *user_data);
+ * @brief This API gets the list of dependency of 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] dependency_cb 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 dependency_cb(const char *pkgid, const char *type,
+ const char *required_version,void *user_data)
+{
+ printf("this package %s %s", type, pkgid);
+ if (required_version)
+ printf("required version : %s", required_version);
+ return 0;
+}
+
+static int list_dependency(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_dependency(handle, dependency_cb, 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_dependency(pkgmgrinfo_pkginfo_h handle,
+ pkgmgrinfo_pkg_dependency_list_cb dependency_cb,
+ void *user_data);
+
+/**
+ * @fn int pkgmgrinfo_pkginfo_foreach_required_by(pkgmgrinfo_pkginfo_h handle,
+ pkgmgrinfo_pkg_dependency_list_cb dependency_cb,
+ void *user_data);
+ * @brief This API gets the list of packages which has dependency of 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] dependency_cb 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 dependency_cb(const char *pkgid, const char *type,
+ const char *required_version,void *user_data)
+{
+ printf("%s %s this package", pkgid, type);
+ if (required_version)
+ printf("required version : %s", required_version);
+ return 0;
+}
+
+static int list_required_by(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_required_by(handle, dependency_cb, 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_required_by(pkgmgrinfo_pkginfo_h handle,
+ pkgmgrinfo_pkg_dependency_list_cb dependency_cb,
+ void *user_data);
+
+/**
* @brief TEMP
*/
char *license;
} appdefined_privilege_x;
+typedef struct dependency_x {
+ char *depends_on;
+ char *type;
+ char *required_version;
+} dependency_x;
+
typedef struct application_x {
char *appid; /*attr*/
char *exec; /*attr*/
GList *application; /**< package's application, element*/
GList *compatibility; /**< package compatibility, element*/
GList *deviceprofile; /**< package device profile, element*/
+ GList *dependencies; /**< package dependencies, element*/
} package_x;
typedef struct updateinfo_x {
PMINFO_PKGINFO_GET_DESCRIPTION = 0x0010,
PMINFO_PKGINFO_GET_PRIVILEGE = 0x0020,
PMINFO_PKGINFO_GET_APPDEFINED_PRIVILEGE = 0x0040,
- PMINFO_PKGINFO_GET_ALL = 0x007F
+ PMINFO_PKGINFO_GET_DEPENDENCY = 0x0080,
+ PMINFO_PKGINFO_GET_ALL = 0x00FF
} pkgmgrinfo_pkginfo_get_option;
/**
typedef int (*pkgmgrinfo_pkg_appdefined_privilege_list_cb) (const char *privilege_name,
const char *license_path,
void *user_data);
+/**
+ * @fn int (*pkgmgrinfo_pkg_dependency_list_cb) (const char *pkgid, const char *type, const char *required_version, void *user_data)
+ *
+ * @brief Specifies the dependency info of given package passed to pkgmgrinfo_pkginfo_foreach_dependency() or pkgmgrinfo_pkginfo_foreach_required_by()
+ *
+ * @param[in] pkgid the pkgid which has dependency with given package
+ * @param[in] type type of dependency
+ * @param[in] required_version required version of dependency
+ * @param[in] user_data user data passed
+ *
+ * @return 0 if success, negative value(<0) if fail. Callback is not called if return value is negative.\n
+ *
+ * @see pkgmgrinfo_pkginfo_foreach_dependency()
+ * @see pkgmgrinfo_pkginfo_foreach_required_by()
+ */
+typedef int (*pkgmgrinfo_pkg_dependency_list_cb) (const char *pkgid,
+ const char *type, const char *required_version,
+ void *user_data);
/**
* @fn int (*pkgmgrinfo_app_metadata_list_cb) (const char *metadata_key, const char *metadata_value, void *user_data)
QUERY_CREATE_TABLE_PACKAGE_APP_INFO_FOR_UID,
QUERY_CREATE_TRIGGER_UPDATE_PACKAGE_APP_INFO_FOR_UID,
QUERY_CREATE_TABLE_PACKAGE_APP_SPLASH_SCREEN,
+ QUERY_CREATE_TABLE_PACKAGE_DEPENDENCY_INFO,
NULL,
};
return 0;
}
+static int __insert_package_dependency_info(sqlite3 *db, manifest_x *mfx)
+{
+ static const char query[] =
+ "INSERT INTO package_dependency_info"
+ " (package, depends_on, type, required_version) "
+ "VALUES (?, ?, ?, ?)";
+ int ret;
+ sqlite3_stmt *stmt;
+ int idx;
+ GList *tmp;
+ dependency_x *dep;
+
+ 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->dependencies; tmp; tmp = tmp->next) {
+ dep = (dependency_x *)tmp->data;
+ if (dep == NULL)
+ continue;
+
+ idx = 1;
+ __BIND_TEXT(db, stmt, idx++, mfx->package);
+ __BIND_TEXT(db, stmt, idx++, dep->depends_on);
+ __BIND_TEXT(db, stmt, idx++, dep->type);
+ __BIND_TEXT(db, stmt, idx++, dep->required_version);
+
+ 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
return -1;
if (__insert_package_appdefined_privilege_info(db, mfx))
return -1;
+ if (__insert_package_dependency_info(db, mfx))
+ return -1;
return 0;
}
" FOREIGN KEY(app_id)\n" \
" REFERENCES package_app_info(app_id) ON DELETE CASCADE)"
+#define QUERY_CREATE_TABLE_PACKAGE_DEPENDENCY_INFO \
+ "CREATE TABLE IF NOT EXISTS package_dependency_info (\n" \
+ " package TEXT NOT NULL,\n" \
+ " depends_on TEXT NOT NULL,\n" \
+ " type TEXT NOT NULL,\n" \
+ " required_version TEXT,\n" \
+ " PRIMARY KEY(package, depends_on),\n" \
+ " FOREIGN KEY(package)\n" \
+ " REFERENCES package_info(package) ON DELETE CASCADE)"
+
/* FIXME: duplicated at pkgmgrinfo_db.c */
#define QUERY_CREATE_TABLE_PACKAGE_CERT_INDEX_INFO \
"CREATE TABLE IF NOT EXISTS package_cert_index_info (\n" \
free((void *)datacontrol);
}
+static void __ps_free_dependency(gpointer data)
+{
+ dependency_x *dependency = (dependency_x *)data;
+ if (dependency == NULL)
+ return;
+ if (dependency->depends_on)
+ free((void *)dependency->depends_on);
+ if (dependency->type)
+ free((void *)dependency->type);
+ if (dependency->required_version)
+ free((void *)dependency->required_version);
+ free((void *)dependency);
+}
+
static void __ps_free_application(gpointer data)
{
application_x *application = (application_x *)data;
g_list_free_full(package->compatibility, __ps_free_compatibility);
/*Free Device profiles*/
g_list_free_full(package->deviceprofile, free);
+ /*Free Dependencies*/
+ g_list_free_full(package->dependencies, __ps_free_dependency);
free((void *)package);
}
return PMINFO_R_OK;
}
+static int _pkginfo_get_dependency(sqlite3 *db, const char *pkgid,
+ GList **dependencies)
+{
+ static const char query[] =
+ "SELECT DISTINCT depends_on, type, required_version "
+ "FROM package_dependency_info WHERE package=?";
+ int ret;
+ sqlite3_stmt *stmt;
+ dependency_x *dependency;
+
+ ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("prepare failed: %s", sqlite3_errmsg(db));
+ return PMINFO_R_ERROR;
+ }
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ dependency = calloc(1, sizeof(dependency_x));
+ if (!dependency) {
+ LOGE("failed to alloc memory");
+ sqlite3_finalize(stmt);
+ return PMINFO_R_ERROR;
+ }
+ _save_column_str(stmt, 0, &dependency->depends_on);
+ _save_column_str(stmt, 1, &dependency->type);
+ _save_column_str(stmt, 2, &dependency->required_version);
+ *dependencies = g_list_append(*dependencies,
+ (gpointer)dependency);
+ }
+
+ 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"
}
}
+ if (flag & PMINFO_PKGINFO_GET_DEPENDENCY) {
+ if (_pkginfo_get_dependency(db, info->package,
+ &info->dependencies)) {
+ ret = PMINFO_R_ERROR;
+ goto catch;
+ }
+ }
+
if (is_check_storage &&
__pkginfo_check_installed_storage(info) != PMINFO_R_OK) {
ret = PMINFO_R_ERROR;
return PMINFO_R_OK;
}
+API int pkgmgrinfo_pkginfo_foreach_dependency(pkgmgrinfo_pkginfo_h handle,
+ pkgmgrinfo_pkg_dependency_list_cb dependency_cb,
+ void *user_data)
+{
+ int ret;
+ pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
+ GList *tmp;
+ dependency_x *dependency;
+
+ if (handle == NULL || dependency_cb == NULL) {
+ LOGE("invalid parameter");
+ return PMINFO_R_EINVAL;
+ }
+
+ if (info->pkg_info == NULL)
+ return PMINFO_R_ERROR;
+
+ for (tmp = info->pkg_info->dependencies; tmp; tmp = tmp->next) {
+ dependency = (dependency_x *)tmp->data;
+ if (dependency == NULL)
+ continue;
+ ret = dependency_cb(dependency->depends_on, dependency->type,
+ dependency->required_version, user_data);
+ if (ret < 0)
+ break;
+ }
+
+ return PMINFO_R_OK;
+}
+
+struct required_by {
+ char *pkgid;
+ char *type;
+ char *version;
+};
+
+static int _get_required_by(sqlite3 *db, const char *pkgid, GQueue **queue,
+ GHashTable **table, GList **pkg_list)
+{
+ static const char query[] =
+ "SELECT package, type, required_version "
+ "FROM package_dependency_info WHERE depends_on=?";
+ int ret;
+ sqlite3_stmt *stmt;
+ struct required_by *req;
+
+ /* already checked */
+ if (!g_hash_table_insert(*table, strdup(pkgid), GINT_TO_POINTER(1)))
+ return PMINFO_R_OK;
+
+ ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("prepare failed: %s", sqlite3_errmsg(db));
+ return PMINFO_R_ERROR;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
+ if (ret != SQLITE_OK) {
+ LOGE("bind failed: %s", sqlite3_errmsg(db));
+ sqlite3_finalize(stmt);
+ return PMINFO_R_ERROR;
+ }
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ req = calloc(1, sizeof(struct required_by));
+ if (req == NULL) {
+ LOGE("out of memory");
+ sqlite3_finalize(stmt);
+ return PMINFO_R_ERROR;
+ }
+ _save_column_str(stmt, 0, &req->pkgid);
+ _save_column_str(stmt, 1, &req->type);
+ _save_column_str(stmt, 2, &req->version);
+
+ *pkg_list = g_list_append(*pkg_list, req);
+ g_queue_push_tail(*queue, strdup(req->pkgid));
+ }
+
+ sqlite3_finalize(stmt);
+
+ return PMINFO_R_OK;
+}
+
+static int _pkginfo_foreach_required_by(uid_t uid, const char *pkgid,
+ GList **pkg_list)
+{
+ int ret;
+ char *dbpath;
+ sqlite3 *db;
+ GQueue *queue;
+ GHashTable *table;
+ char *item;
+
+ 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(%s): %d", dbpath, ret);
+ free(dbpath);
+ return PMINFO_R_ERROR;
+ }
+ free(dbpath);
+
+ queue = g_queue_new();
+ if (queue == NULL) {
+ LOGE("out of memory");
+ sqlite3_close_v2(db);
+ return PMINFO_R_ERROR;
+ }
+
+ table = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
+
+ g_queue_push_tail(queue, strdup(pkgid));
+ while (!g_queue_is_empty(queue)) {
+ item = g_queue_pop_head(queue);
+ ret = _get_required_by(db, item, &queue, &table, pkg_list);
+ free(item);
+ if (ret != PMINFO_R_OK) {
+ LOGE("failed to get required by pkgs");
+ g_hash_table_destroy(table);
+ g_queue_free_full(queue, free);
+ sqlite3_close_v2(db);
+ return PMINFO_R_ERROR;
+ }
+ }
+
+ g_hash_table_destroy(table);
+ g_queue_free_full(queue, free);
+ sqlite3_close_v2(db);
+
+ return PMINFO_R_OK;
+}
+
+static void __free_required_by(gpointer data)
+{
+ struct required_by *req = (struct required_by *)data;
+
+ free(req->pkgid);
+ free(req->type);
+ free(req->version);
+ free(req);
+}
+
+API int pkgmgrinfo_pkginfo_foreach_required_by(pkgmgrinfo_pkginfo_h handle,
+ pkgmgrinfo_pkg_dependency_list_cb dependency_cb,
+ void *user_data)
+{
+ int ret;
+ pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
+ GList *pkg_list = NULL;
+ GList *l;
+ struct required_by *req;
+
+ if (handle == NULL || dependency_cb == NULL || info->pkg_info == NULL) {
+ LOGE("invalid parameter");
+ return PMINFO_R_EINVAL;
+ }
+
+ ret = _pkginfo_foreach_required_by(info->uid, info->pkg_info->package,
+ &pkg_list);
+ if (ret == PMINFO_R_OK && info->uid != GLOBAL_USER)
+ ret = _pkginfo_foreach_required_by(GLOBAL_USER,
+ info->pkg_info->package, &pkg_list);
+
+ if (ret != PMINFO_R_OK) {
+ g_list_free_full(pkg_list, __free_required_by);
+ return ret;
+ }
+
+ for (l = pkg_list; l != NULL; l = l->next) {
+ req = (struct required_by *)l->data;
+ ret = dependency_cb(req->pkgid, req->type, req->version,
+ user_data);
+ if (ret < 0)
+ break;
+ }
+
+ g_list_free_full(pkg_list, __free_required_by);
+
+ return PMINFO_R_OK;
+}
+
int __compare_package_version(const char *version, int *major,
int *minor, int *macro, int *nano)
{