Now metadata is available at package level.
Change-Id: Ic3f561fdb427d2482b1c3945366e6c26d7fe3976
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
int pkgmgrinfo_pkginfo_foreach_plugin(pkgmgrinfo_pkginfo_h handle,
pkgmgrinfo_plugin_list_cb plugin_func, void *user_data);
+/**
+ * @fn int pkgmgrinfo_pkginfo_foreach_metadata(pkgmgrinfo_pkginfo_h handle,
+ pkgmgrinfo_pkg_metadata_list_cb metadata_func, void *user_data);
+ * @brief This API gets the list of metadata 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] metadata_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 metadata_func(const char *key, const char *value, void *user_data)
+{
+ if (strcmp(key, (char *)user_data) == 0) {
+ printf("Value is %s\n", value);
+ return -1;
+ }
+ else
+ return 0;
+}
+
+static int list_metadata(const char *pkgid, char *key)
+{
+ int ret = 0;
+ pkgmgrinfo_pkginfo_h handle;
+ ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
+ if (ret != PMINFO_R_OK)
+ return -1;
+ ret = pkgmgrinfo_pkginfo_foreach_metadata(handle, metadata_func, (void *)key);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ return -1;
+ }
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ return 0;
+}
+ * @endcode
+ */
+int pkgmgrinfo_pkginfo_foreach_metadata(pkgmgrinfo_pkginfo_h handle,
+ pkgmgrinfo_pkg_metadata_list_cb metadata_func, void *user_data);
+
+/**
+ * @fn int pkgmgrinfo_pkginfo_metadata_filter_create(pkgmgrinfo_pkginfo_metadata_filter_h *handle)
+ * @brief This API creates the application's metadata information filter handle from db.
+ *
+ * @par This API is for package-manager client application
+ * @par Sync (or) Async : Synchronous API
+ *
+ * @param[out] handle pointer to the package metadata info filter 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_pkginfo_metadata_filter_destroy()
+ * @see pkgmgrinfo_pkginfo_metadata_filter_foreach()
+ * @code
+int pkg_list_cb(pkgmgrinfo_pkginfo_h handle, void *user_data)
+{
+ char *pkgid = NULL;
+ pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
+ printf("pkgid : %s\n", pkgid);
+ return 0;
+}
+
+static int get_pkg_list(const char *mkey, const char *mvalue)
+{
+ int ret = 0;
+ pkgmgrinfo_pkginfo_metadata_filter_h handle;
+ ret = pkgmgrinfo_pkginfo_metadata_filter_create(&handle);
+ if (ret != PMINFO_R_OK)
+ return -1;
+ ret = pkgmgrinfo_pkginfo_metadata_filter_add(handle, mkey, mvalue);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_metadata_filter_destroy(handle);
+ return -1;
+ }
+ ret = pkgmgrinfo_pkginfo_metadata_filter_foreach(handle, pkg_list_cb, NULL);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_metadata_filter_destroy(handle);
+ return -1;
+ }
+ pkgmgrinfo_pkginfo_metadata_filter_destroy(handle);
+ return 0;
+}
+ * @endcode
+ */
+int pkgmgrinfo_pkginfo_metadata_filter_create(pkgmgrinfo_pkginfo_metadata_filter_h *handle);
+
+/**
+ * @fn int pkgmgrinfo_pkginfo_metadata_filter_destroy(pkgmgrinfo_pkginfo_metadata_filter_h handle)
+ * @brief This API destroys the package's metadata information filter handle.
+ *
+ * @par This API is for package-manager client application
+ * @par Sync (or) Async : Synchronous API
+ *
+ * @param[in] handle pointer to the package metadata info filter 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 pkgmgrinfo_pkginfo_metadata_filter_create()
+ * @post None
+ * @see pkgmgrinfo_pkginfo_metadata_filter_foreach()
+ * @code
+int pkg_list_cb(pkgmgrinfo_pkginfo_h handle, void *user_data)
+{
+ char *pkgid = NULL;
+ pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
+ printf("pkgid : %s\n", pkgid);
+ return 0;
+}
+
+static int get_pkg_list(const char *mkey, const char *mvalue)
+{
+ int ret = 0;
+ pkgmgrinfo_pkginfo_metadata_filter_h handle;
+ ret = pkgmgrinfo_pkginfo_metadata_filter_create(&handle);
+ if (ret != PMINFO_R_OK)
+ return -1;
+ ret = pkgmgrinfo_pkginfo_metadata_filter_add(handle, mkey, mvalue);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_metadata_filter_destroy(handle);
+ return -1;
+ }
+ ret = pkgmgrinfo_pkginfo_metadata_filter_foreach(handle, pkg_list_cb, NULL);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_metadata_filter_destroy(handle);
+ return -1;
+ }
+ pkgmgrinfo_pkginfo_metadata_filter_destroy(handle);
+ return 0;
+}
+ * @endcode
+ */
+int pkgmgrinfo_pkginfo_metadata_filter_destroy(pkgmgrinfo_pkginfo_metadata_filter_h handle);
+
+/**
+ * @fn int pkgmgrinfo_pkginfo_metadata_filter_add(pkgmgrinfo_pkginfo_metadata_filter_h handle, const char *key, const char *value)
+ * @brief This API adds filter condition for the query API. The query will search the entire package metadata information collected from
+ * the manifest file of all the installed packages. You can specify value as NULL to search based on key only.
+ *
+ * @par This API is for package-manager client application
+ * @par Sync (or) Async : Synchronous API
+ *
+ * @param[in] handle pointer to the package metadata info filter handle.
+ * @param[in] key pointer to metadata key
+ * @param[in] value pointer to metadata value
+ * @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_metadata_filter_create()
+ * @post pkgmgrinfo_pkginfo_metadata_filter_foreach(), pkgmgrinfo_pkginfo_metadata_filter_destroy()
+ * @see pkgmgrinfo_pkginfo_metadata_filter_foreach()
+ * @code
+int pkg_list_cb(pkgmgrinfo_pkginfo_h handle, void *user_data)
+{
+ char *pkgid = NULL;
+ pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
+ printf("pkgid : %s\n", pkgid);
+ return 0;
+}
+
+static int get_pkg_list(const char *mkey, const char *mvalue)
+{
+ int ret = 0;
+ pkgmgrinfo_pkginfo_metadata_filter_h handle;
+ ret = pkgmgrinfo_pkginfo_metadata_filter_create(&handle);
+ if (ret != PMINFO_R_OK)
+ return -1;
+ ret = pkgmgrinfo_pkginfo_metadata_filter_add(handle, mkey, mvalue);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_metadata_filter_destroy(handle);
+ return -1;
+ }
+ ret = pkgmgrinfo_pkginfo_metadata_filter_foreach(handle, pkg_list_cb, NULL);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_metadata_filter_destroy(handle);
+ return -1;
+ }
+ pkgmgrinfo_pkginfo_metadata_filter_destroy(handle);
+ return 0;
+}
+ * @endcode
+ */
+int pkgmgrinfo_pkginfo_metadata_filter_add(pkgmgrinfo_pkginfo_metadata_filter_h handle,
+ const char *key, const char *value);
+
+/**
+ * @fn int pkgmgrinfo_pkginfo_metadata_filter_foreach(pkgmgrinfo_pkginfo_metadata_filter_h handle, pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data)
+ * @fn int pkgmgrinfo_pkginfo_usr_metadata_filter_foreach(pkgmgrinfo_pkginfo_metadata_filter_h handle, pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data, uid_t uid)
+ * @brief This API executes the filter query. The query will search the entire package metadata information collected from
+ * the manifest file of all the installed packages. For each package returned by the query, the callback will be called. If callback returns
+ * negative value, no more callbacks will be called and API will return.
+ *
+ * @par This API is for package-manager client application
+ * @par Sync (or) Async : Synchronous API
+ *
+ * @param[in] handle pointer to the package metadata info filter handle.
+ * @param[in] app_cb function pointer to callback
+ * @param[in] user_data pointer to user data
+ * @param[in] uid the addressee user id of the instruction
+ * @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_metadata_filter_create()
+ * @post pkgmgrinfo_pkginfo_metadata_filter_destroy()
+ * @code
+int pkg_list_cb(pkgmgrinfo_pkginfo_h handle, void *user_data)
+{
+ char *pkgid = NULL;
+ pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
+ printf("pkgid : %s\n", pkgid);
+ return 0;
+}
+
+static int get_pkg_list(const char *mkey, const char *mvalue)
+{
+ int ret = 0;
+ pkgmgrinfo_pkginfo_metadata_filter_h handle;
+ ret = pkgmgrinfo_pkginfo_metadata_filter_create(&handle);
+ if (ret != PMINFO_R_OK)
+ return -1;
+ ret = pkgmgrinfo_pkginfo_metadata_filter_add(handle, mkey, mvalue);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_metadata_filter_destroy(handle);
+ return -1;
+ }
+ ret = pkgmgrinfo_pkginfo_metadata_filter_foreach(handle, pkg_list_cb, NULL);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_metadata_filter_destroy(handle);
+ return -1;
+ }
+ pkgmgrinfo_pkginfo_metadata_filter_destroy(handle);
+ return 0;
+}
+ * @endcode
+ */
+int pkgmgrinfo_pkginfo_metadata_filter_foreach(pkgmgrinfo_pkginfo_metadata_filter_h handle,
+ pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data);
+int pkgmgrinfo_pkginfo_usr_metadata_filter_foreach(pkgmgrinfo_pkginfo_metadata_filter_h handle,
+ pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data, uid_t uid);
+
/* TODO: add doxygen comment here */
int pkgmgrinfo_pkginfo_is_for_all_users(pkgmgrinfo_pkginfo_h handle, bool *for_all_users);
* @}
* @}
*/
-
GList *dependencies; /**< package dependencies, element*/
GList *plugin; /**< plugin execution list, no xml part*/
GList *res_allowed_packages; /**< res allowed packages, element*/
+ GList *metadata; /*element*/
} package_x;
typedef struct updateinfo_x {
PMINFO_PKGINFO_GET_APPDEFINED_PRIVILEGE = 0x0040,
PMINFO_PKGINFO_GET_DEPENDENCY = 0x0080,
PMINFO_PKGINFO_GET_RES_INFO = 0x0100,
- PMINFO_PKGINFO_GET_ALL = 0x01FF
+ PMINFO_PKGINFO_GET_METADATA = 0x0200,
+ PMINFO_PKGINFO_GET_ALL = 0x03FF
} pkgmgrinfo_pkginfo_get_option;
/**
typedef void *pkgmgrinfo_pkginfo_filter_h;
/**
+ * @brief A handle to filter package metadata information
+ */
+typedef void *pkgmgrinfo_pkginfo_metadata_filter_h;
+
+/**
* @brief A handle to get/set package update information
*/
typedef void *pkgmgrinfo_updateinfo_h;
void *user_data);
/**
+ * @fn int (*pkgmgrinfo_pkg_metadata_list_cb) (const char *metadata_key, const char *metadata_value, void *user_data)
+ *
+ * @brief Specifies the type of function passed to pkgmgrinfo_pkginfo_foreach_metadata()
+ *
+ * @param[in] metadata_name the name of the metadata
+ * @param[in] metadata_value the value of the metadata
+ * @param[in] user_data user data passed to pkgmgrinfo_pkginfo_foreach_metadata()
+ *
+ * @return 0 if success, negative value(<0) if fail. Callback is not called if return value is negative.\n
+ *
+ * @see pkgmgrinfo_pkginfo_foreach_metadata()
+ */
+typedef int (*pkgmgrinfo_pkg_metadata_list_cb) (const char *metadata_key,
+ const char *metadata_value, 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()
" FOREIGN KEY(package)\n" \
" REFERENCES package_info(package) ON DELETE CASCADE)"
+#define QUERY_CREATE_TABLE_PACKAGE_METADATA \
+ "CREATE TABLE IF NOT EXISTS package_metadata (\n" \
+ " package TEXT NOT NULL,\n" \
+ " md_key TEXT NOT NULL,\n" \
+ " md_value TEXT,\n" \
+ " PRIMARY KEY(package, md_key, md_value)\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" \
"package_app_splash_screen",
"package_dependency_info",
"package_plugin_info",
+ "package_metadata",
NULL,
};
QUERY_CREATE_TABLE_PACKAGE_APP_RES_CONTROL,
QUERY_CREATE_TABLE_PACKAGE_RES_INFO,
QUERY_CREATE_TABLE_PACKAGE_RES_ALLOWED_PACKAGE,
+ QUERY_CREATE_TABLE_PACKAGE_METADATA,
NULL,
};
WritePkgmgrInfoMetadataNode(
parcel, reinterpret_cast<pkgmgrinfo_metadata_node_x*>(list->data));
+ WriteInt(parcel, g_slist_length(filter->list_pkg_metadata));
+ for (GSList* list = filter->list_pkg_metadata; list; list = list->next)
+ WritePkgmgrInfoMetadataNode(
+ parcel, reinterpret_cast<pkgmgrinfo_metadata_node_x*>(list->data));
+
return true;
}
for (int i = 0; i < val; ++i)
filter_->list_metadata = g_slist_append(filter_->list_metadata,
ReadPkgmgrInfoMetadataNode(parcel));
+
+ ReadInt(parcel, &val);
+ for (int i = 0; i < val; ++i)
+ filter_->list_pkg_metadata = g_slist_append(filter_->list_pkg_metadata,
+ ReadPkgmgrInfoMetadataNode(parcel));
}
bool FilterParcelable::WritePkgmgrInfoNode(tizen_base::Parcel* parcel,
}
}
+void PkgInfoParcelable::WriteMetadata(tizen_base::Parcel* parcel,
+ GList* metadata) const {
+ WriteInt(parcel, g_list_length(metadata));
+
+ for (GList* tmp = metadata; tmp; tmp = tmp->next) {
+ metadata_x* ptr = reinterpret_cast<metadata_x*>(tmp->data);
+ WriteString(parcel, ptr->key);
+ WriteString(parcel, ptr->value);
+ }
+}
+
void PkgInfoParcelable::WritePackage(tizen_base::Parcel* parcel,
package_x* package) const {
WriteString(parcel, package->for_all_users);
WriteDependencies(parcel, package->dependencies);
WritePlugin(parcel, package->plugin);
WriteResAllowedPackages(parcel, package->res_allowed_packages);
+ WriteMetadata(parcel, package->metadata);
}
void PkgInfoParcelable::ReadIcon(tizen_base::Parcel* parcel, GList** list) {
}
}
+void PkgInfoParcelable::ReadMetadata(tizen_base::Parcel* parcel, GList** list) {
+ int size = 0;
+ ReadInt(parcel, &size);
+
+ for (int i = 0; i < size; ++i) {
+ metadata_x* metadata =
+ reinterpret_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
+ ReadString(parcel, &metadata->key);
+ ReadString(parcel, &metadata->value);
+
+ *list = g_list_append(*list, metadata);
+ }
+}
+
package_x* PkgInfoParcelable::ReadPackage(tizen_base::Parcel* parcel) {
package_x* package =
reinterpret_cast<package_x*>(calloc(1, sizeof(package_x)));
ReadDependencies(parcel, &package->dependencies);
ReadPlugin(parcel, &package->plugin);
ReadResAllowedPackages(parcel, &package->res_allowed_packages);
+ ReadMetadata(parcel, &package->metadata);
return package;
}
void WritePlugin(tizen_base::Parcel* parcel, GList* plugin) const;
void WriteResAllowedPackages(tizen_base::Parcel* parcel,
GList* plugin) const;
+ void WriteMetadata(tizen_base::Parcel* parcel, GList* metadata) const;
void WritePackage(tizen_base::Parcel* parcel, package_x* package) const;
void ReadIcon(tizen_base::Parcel* parcel, GList** list);
void ReadLabel(tizen_base::Parcel* parcel, GList** list);
void ReadDependencies(tizen_base::Parcel* parcel, GList** list);
void ReadPlugin(tizen_base::Parcel* parcel, GList** list);
void ReadResAllowedPackages(tizen_base::Parcel* parcel, GList** list);
+ void ReadMetadata(tizen_base::Parcel* parcel, GList** list);
package_x* ReadPackage(tizen_base::Parcel* parcel);
std::vector<std::shared_ptr<package_x>> pkg_list_;
g_list_free_full(package->plugin, __ps_free_plugin_info);
/*Free resource allowed packages*/
g_list_free_full(package->res_allowed_packages, __ps_free_res_allowed_packages);
+ /*Free Metadata*/
+ g_list_free_full(package->metadata, __ps_free_metadata);
free((void *)package);
}
if (filter->list_metadata)
g_slist_free_full(filter->list_metadata,
__destroy_metadata_node);
+ if (filter->list_pkg_metadata)
+ g_slist_free_full(filter->list_pkg_metadata,
+ __destroy_metadata_node);
free(filter);
return PMINFO_R_OK;
}
+
+API int pkgmgrinfo_pkginfo_foreach_metadata(pkgmgrinfo_pkginfo_h handle,
+ pkgmgrinfo_pkg_metadata_list_cb metadata_func, void *user_data)
+{
+ retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
+ retvm_if(metadata_func == NULL, PMINFO_R_EINVAL,
+ "Callback function is NULL");
+ int ret = -1;
+ metadata_x *ptr;
+ GList *tmp;
+ pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
+
+ if (info->pkg_info == NULL)
+ return PMINFO_R_ERROR;
+
+ for (tmp = info->pkg_info->metadata; tmp; tmp = tmp->next) {
+ ptr = (metadata_x *)tmp->data;
+ if (ptr == NULL)
+ continue;
+ if (ptr->key) {
+ ret = metadata_func(ptr->key, ptr->value ?
+ ptr->value : "", user_data);
+ if (ret < 0)
+ break;
+ }
+ }
+ return PMINFO_R_OK;
+}
+
+API int pkgmgrinfo_pkginfo_metadata_filter_create(
+ pkgmgrinfo_pkginfo_metadata_filter_h *handle)
+{
+ return pkgmgrinfo_pkginfo_filter_create(handle);
+}
+
+API int pkgmgrinfo_pkginfo_metadata_filter_destroy(
+ pkgmgrinfo_pkginfo_metadata_filter_h handle)
+{
+ return pkgmgrinfo_pkginfo_filter_destroy(handle);
+}
+
+API int pkgmgrinfo_pkginfo_metadata_filter_add(
+ pkgmgrinfo_pkginfo_metadata_filter_h handle,
+ const char *key, const char *value)
+{
+ pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
+ pkgmgrinfo_metadata_node_x *node;
+
+ /* value can be NULL.
+ * In that case all pkgs with specified key should be displayed
+ */
+ if (handle == NULL || key == NULL) {
+ LOGE("invalid parameter");
+ return PMINFO_R_EINVAL;
+ }
+
+ node = calloc(1, sizeof(pkgmgrinfo_metadata_node_x));
+ if (node == NULL) {
+ LOGE("out of memory");
+ return PMINFO_R_ERROR;
+ }
+
+ node->key = strdup(key);
+ if (value && strlen(value))
+ node->value = strdup(value);
+
+ filter->list_pkg_metadata = g_slist_append(filter->list_pkg_metadata,
+ (gpointer)node);
+
+ return PMINFO_R_OK;
+}
+
+API int pkgmgrinfo_pkginfo_usr_metadata_filter_foreach(
+ pkgmgrinfo_pkginfo_metadata_filter_h handle,
+ pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data, uid_t uid)
+{
+ if (handle == NULL || pkg_cb == NULL) {
+ LOGE("invalid parameter");
+ return PMINFO_R_EINVAL;
+ }
+
+ pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
+
+ if (pkgmgrinfo_pkginfo_filter_add_bool(filter,
+ PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false))
+ return PMINFO_R_ERROR;
+
+ return _pkginfo_get_filtered_foreach_pkginfo(uid, handle,
+ PMINFO_PKGINFO_GET_ALL, pkg_cb,
+ user_data);
+}
+
+API int pkgmgrinfo_pkginfo_metadata_filter_foreach(
+ pkgmgrinfo_pkginfo_metadata_filter_h handle,
+ pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data)
+{
+ return pkgmgrinfo_pkginfo_usr_metadata_filter_foreach(handle, pkg_cb,
+ user_data, _getuid());
+}
return flag;
}
+API int __get_pkg_metadata_filter_condition(gpointer data, char **condition,
+ GList **params)
+{
+ pkgmgrinfo_metadata_node_x *node = (pkgmgrinfo_metadata_node_x *)data;
+ char buf[MAX_QUERY_LEN];
+
+ snprintf(buf, sizeof(buf), "(package_metadata.md_key=?");
+ if (node->value)
+ strncat(buf, " AND package_metadata.md_value=?",
+ sizeof(buf) - strlen(buf) - 1);
+ strncat(buf, ")", sizeof(buf) - strlen(buf) - 1);
+
+ *condition = strdup(buf);
+ *params = g_list_append(*params, strdup(node->key));
+ if (node->value)
+ *params = g_list_append(*params, strdup(node->value));
+
+ return E_PMINFO_PKGINFO_JOIN_METADATA;
+}
+
API int __get_metadata_filter_condition(gpointer data, char **condition,
GList **params)
{
E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO = 0x0001,
E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO = 0x0002,
E_PMINFO_PKGINFO_JOIN_RES_INFO = 0x0004,
+ E_PMINFO_PKGINFO_JOIN_METADATA = 0x0008,
} pkgmgrinfo_pkginfo_join_flag;
typedef enum _pkgmgrinfo_appinfo_join_flag {
uid_t uid;
GSList *list;
GSList *list_metadata;
+ GSList *list_pkg_metadata;
bool cache_flag; /* flag for pkginfo-server used to make cache */
} pkgmgrinfo_filter_x;
int _check_create_cert_db(void);
int __get_filter_condition(gpointer data, uid_t uid, char **condition, GList **param);
+int __get_pkg_metadata_filter_condition(gpointer data, char **condition, GList **param);
int __get_metadata_filter_condition(gpointer data, char **condition, GList **param);
int _add_icon_info_into_list(const char *locale, char *value, GList **icon);
int _add_label_info_into_list(const char *locale, char *value, GList **label);
return ret;
}
+inline bool CheckMetadataFilter(GList* metadata_list,
+ const std::unordered_map<std::string, std::string>& metadata_map) {
+ for (auto* it = metadata_list; it != nullptr; it = g_list_next(it)) {
+ auto* node = reinterpret_cast<metadata_x*>(it->data);
+ if (node->key != nullptr) {
+ auto metadata = metadata_map.find(node->key);
+ if (metadata == metadata_map.end())
+ continue;
+
+ if (metadata->second.empty() ||
+ strcmp(node->value ? node->value : "", metadata->second.c_str()) == 0)
+ return true;
+ }
+ }
+ return false;
+}
+
inline bool CheckPkgFilters(pkgmgrinfo_filter_x* filter,
- const std::shared_ptr<package_x>& info) {
+ const std::shared_ptr<package_x>& info,
+ const std::unordered_map<std::string, std::string>& metadata_map) {
for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) {
auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
auto* checker = FilterCheckerProvider::GetInst().
return false;
}
- return true;
+ bool pass = true;
+ if (!metadata_map.empty())
+ pass = CheckMetadataFilter(info->metadata, metadata_map);
+
+ return pass;
}
std::vector<std::shared_ptr<package_x>> DBHandleProvider::GetPackages(
const std::string& package) {
std::vector<std::shared_ptr<package_x>> ret;
+ /* make metadata filter map */
+ std::unordered_map<std::string, std::string> metadata_map;
+ for (auto* it = filter->list_pkg_metadata; it != nullptr;
+ it = g_slist_next(it)) {
+ auto node = reinterpret_cast<pkgmgrinfo_metadata_node_x*>(it->data);
+ if (node->key == nullptr)
+ continue;
+ LOG(ERROR) << "add metadata filter";
+ metadata_map[node->key] = (node->value ? node->value : "");
+ }
+
if (internal::CheckPackageStorageStatus(filter)) {
if (pkgmgrinfo_pkginfo_filter_add_bool(filter,
PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE, true) != PMINFO_R_OK) {
}
if (package.empty()) {
for (auto& info : pkg_map_) {
- if (CheckPkgFilters(filter, info.second))
+ if (CheckPkgFilters(filter, info.second, metadata_map))
ret.push_back(info.second);
}
} else {
auto map_it = pkg_map_.find(package);
- if (map_it != pkg_map_.end() && CheckPkgFilters(filter, map_it->second))
+ if (map_it != pkg_map_.end() && CheckPkgFilters(filter, map_it->second,
+ metadata_map))
ret.push_back(map_it->second);
}
}
inline bool CheckAppFilters(pkgmgrinfo_filter_x* filter,
- const std::shared_ptr<application_x>& info,
- const std::unordered_map<std::string, std::string>& metadata_map) {
- for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) {
- auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
- auto* checker = FilterCheckerProvider::GetInst().
- GetAppFilterChecker(node->prop);
- if (!checker->CheckFilter(node, info.get()))
- return false;
- }
-
- bool pass = true;
- if (!metadata_map.empty()) {
- pass = false;
- for (auto* it = info->metadata; it != nullptr; it = g_list_next(it)) {
- auto* node = reinterpret_cast<metadata_x*>(it->data);
- if (node->key != nullptr) {
- auto metadata = metadata_map.find(node->key);
- if (metadata == metadata_map.end())
- continue;
-
- if (metadata->second.empty() ||
- strcmp(node->value ? node->value : "",
- metadata->second.c_str()) == 0)
- return true;
- }
- }
- }
+ const std::shared_ptr<application_x>& info,
+ const std::unordered_map<std::string, std::string>& metadata_map) {
+ for (auto* it = filter->list; it != nullptr; it = g_slist_next(it)) {
+ auto node = reinterpret_cast<pkgmgrinfo_node_x*>(it->data);
+ auto* checker = FilterCheckerProvider::GetInst().
+ GetAppFilterChecker(node->prop);
+ if (!checker->CheckFilter(node, info.get()))
+ return false;
+ }
- return pass;
+ bool pass = true;
+ if (!metadata_map.empty())
+ pass = CheckMetadataFilter(info->metadata, metadata_map);
+ return pass;
}
std::vector<std::shared_ptr<application_x>> DBHandleProvider::GetApplications(
constexpr const char join_res_info[] =
" LEFT OUTER JOIN package_res_info"
" ON pi.package=package_res_info.package";
+constexpr const char join_metadata[] =
+ " LEFT OUTER JOIN package_metadata"
+ " ON pi.package=package_metadata.package";
char* GetCString(int idx, const tizen_base::Database::Result::Record& rec) {
std::optional<std::string> str = rec.GetString(idx);
return PMINFO_R_OK;
}
+int GetPackageMetadata(const tizen_base::Database& db,
+ const char* pkgid, GList** metadata) {
+ auto q = tizen_base::Database::Sql(
+ "SELECT md_key, md_value "
+ "FROM package_metadata WHERE package=?")
+ .Bind(pkgid);
+
+ auto r = db.Exec(q);
+ if (!r) {
+ _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
+ return PMINFO_R_ERROR;
+ }
+
+ for (const auto& rec : r) {
+ metadata_x* info = static_cast<metadata_x*>(
+ calloc(1, sizeof(metadata_x)));
+ if (info == nullptr) {
+ LOGE("out of memory");
+ return PMINFO_R_ERROR;
+ }
+
+ int idx = 0;
+ info->key = GetCString(idx++, rec);
+ info->value = GetCString(idx++, rec);
+ *metadata = g_list_prepend(*metadata, info);
+ }
+
+ return PMINFO_R_OK;
+}
+
int _get_filtered_query(pkgmgrinfo_filter_x *filter,
const std::string& locale, uid_t uid,
std::string& query, std::vector<std::string>& bind_params) {
if (filter->cache_flag) {
joined = E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO |
E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO |
- E_PMINFO_PKGINFO_JOIN_RES_INFO;
+ E_PMINFO_PKGINFO_JOIN_RES_INFO |
+ E_PMINFO_PKGINFO_JOIN_METADATA;
}
std::string buf = " WHERE 1=1 ";
free(condition);
}
+ if (filter->list_pkg_metadata)
+ buf += " AND (";
+ for (GSList* list = filter->list_pkg_metadata; list; list = list->next) {
+ char* condition = nullptr;
+ joined |= __get_pkg_metadata_filter_condition(list->data,
+ &condition, &tmp_params);
+ if (condition == nullptr)
+ continue;
+ buf += condition;
+ free(condition);
+ buf += " OR ";
+ }
+ if (filter->list_pkg_metadata)
+ buf += " 1=0)";
+
std::string buf2;
if (joined & E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO) {
buf2 += join_localized_info;
buf2 += join_privilege_info;
if (joined & E_PMINFO_PKGINFO_JOIN_RES_INFO)
buf2 += join_res_info;
+ if (joined & E_PMINFO_PKGINFO_JOIN_METADATA)
+ buf2 += join_metadata;
for (GList* l = tmp_params; l != nullptr; l = l->next)
bind_params.push_back(reinterpret_cast<const char*>(l->data));
}
}
+ if (flag & PMINFO_PKGINFO_GET_METADATA) {
+ if (GetPackageMetadata(db, info->package, &info->metadata) < 0)
+ return PMINFO_R_ERROR;
+ }
+
if (is_check_storage && __pkginfo_check_installed_storage(info) !=
PMINFO_R_OK)
continue;
return 0;
}
+int InsertPackageMetadataInfo(const tizen_base::Database& db, manifest_x* mfx) {
+ if (mfx->metadata == nullptr)
+ return 0;
+
+ auto q = tizen_base::Database::Sql(
+ "INSERT INTO package_metadata (package,"
+ " md_key, md_value) VALUES (?, ?, ?)");
+ auto r = db.Prepare(q);
+ if (!r) {
+ _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
+ return -1;
+ }
+
+ for (GList* tmp = mfx->metadata; tmp; tmp = tmp->next) {
+ metadata_x* md = reinterpret_cast<metadata_x*>(tmp->data);
+ if (md == nullptr)
+ continue;
+ q.Reset()
+ .Bind(mfx->package)
+ .Bind(md->key)
+ .Bind(md->value);
+
+ if (!db.Exec(q, r)) {
+ _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
int InsertApplicationInfo(const tizen_base::Database& db, manifest_x *mfx) {
auto q = tizen_base::Database::Sql(
"INSERT INTO package_app_info (app_id, app_component,"
return -1;
if (InsertPackageResInfo(db, mfx))
return -1;
+ if (InsertPackageMetadataInfo(db, mfx))
+ return -1;
return 0;
}