From ce6457aa70a05445a040c2e8f011176f1bb3024c Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Thu, 20 Aug 2015 15:05:28 +0900 Subject: [PATCH] Fix pkgmgrinfo_appinfo_metadata_filter_foreach add filter prop for metadata key, value Change-Id: Ib94612054f5a46c3e362174300e4e09b58a0fca8 Signed-off-by: Sangyoon Jang --- include/pkgmgr-info.h | 4 + include/pkgmgrinfo_private.h | 4 +- src/pkgmgrinfo_appinfo.c | 180 ++++++------------------------------------- src/pkgmgrinfo_private.c | 88 +++++++++++---------- 4 files changed, 79 insertions(+), 197 deletions(-) diff --git a/include/pkgmgr-info.h b/include/pkgmgr-info.h index 42f5909..c500956 100644 --- a/include/pkgmgr-info.h +++ b/include/pkgmgr-info.h @@ -133,6 +133,10 @@ extern "C" { #define PMINFO_APPINFO_PROP_APP_SCREENREADER "PMINFO_APPINFO_PROP_APP_SCREENREADER" /** String property for filtering based on app info*/ #define PMINFO_APPINFO_PROP_APP_PACKAGE "PMINFO_APPINFO_PROP_APP_PACKAGE" + /** String property for filtering based on app info*/ +#define PMINFO_APPINFO_PROP_APP_METADATA_KEY "PMINFO_APPINFO_PROP_APP_METADATA_KEY" + /** String property for filtering based on app info*/ +#define PMINFO_APPINFO_PROP_APP_METADATA_VALUE "PMINFO_APPINFO_PROP_APP_METADATA_VALUE" /** Boolean property for filtering based on app info*/ #define PMINFO_APPINFO_PROP_APP_NODISPLAY "PMINFO_APPINFO_PROP_APP_NODISPLAY" diff --git a/include/pkgmgrinfo_private.h b/include/pkgmgrinfo_private.h index a7f8cf9..e661e42 100644 --- a/include/pkgmgrinfo_private.h +++ b/include/pkgmgrinfo_private.h @@ -123,7 +123,9 @@ typedef enum _pkgmgrinfo_appinfo_filter_prop_str { E_PMINFO_APPINFO_PROP_APP_CATEGORY, E_PMINFO_APPINFO_PROP_APP_SCREENREADER, E_PMINFO_APPINFO_PROP_APP_PACKAGE, - E_PMINFO_APPINFO_PROP_APP_MAX_STR = E_PMINFO_APPINFO_PROP_APP_PACKAGE + E_PMINFO_APPINFO_PROP_APP_METADATA_KEY, + E_PMINFO_APPINFO_PROP_APP_METADATA_VALUE, + E_PMINFO_APPINFO_PROP_APP_MAX_STR = E_PMINFO_APPINFO_PROP_APP_METADATA_VALUE } pkgmgrinfo_appinfo_filter_prop_str; /*Boolean properties for filtering based on app info*/ diff --git a/src/pkgmgrinfo_appinfo.c b/src/pkgmgrinfo_appinfo.c index 678c3b0..148f84d 100644 --- a/src/pkgmgrinfo_appinfo.c +++ b/src/pkgmgrinfo_appinfo.c @@ -99,7 +99,9 @@ static GSList *_appinfo_get_filtered_list(const char *locale, " LEFT OUTER JOIN package_app_app_category" " ON package_app_info.app_id=package_app_app_category.app_id" " LEFT OUTER JOIN package_app_app_svc" - " ON package_app_info.app_id=package_app_app_svc.app_id "; + " ON package_app_info.app_id=package_app_app_svc.app_id " + " LEFT OUTER JOIN package_app_app_metadata" + " ON package_app_info.app_id=package_app_app_metadata.app_id "; int ret; char *query; char *query_localized; @@ -1946,183 +1948,49 @@ API int pkgmgrinfo_appinfo_metadata_filter_destroy(pkgmgrinfo_appinfo_metadata_f return (pkgmgrinfo_pkginfo_filter_destroy(handle)); } -API int pkgmgrinfo_appinfo_metadata_filter_add(pkgmgrinfo_appinfo_metadata_filter_h handle, +API int pkgmgrinfo_appinfo_metadata_filter_add( + pkgmgrinfo_appinfo_metadata_filter_h handle, const char *key, const char *value) { - retvm_if(handle == NULL, PMINFO_R_EINVAL, "filter handle is NULL\n"); - retvm_if(key == NULL, PMINFO_R_EINVAL, "metadata key supplied is NULL\n"); - /*value can be NULL. In that case all apps with specified key should be displayed*/ - int ret = 0; - char *k = NULL; - char *v = NULL; - pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x*)handle; - pkgmgrinfo_node_x *node = (pkgmgrinfo_node_x*)calloc(1, sizeof(pkgmgrinfo_node_x)); - retvm_if(node == NULL, PMINFO_R_ERROR, "Out of Memory!!!\n"); - k = strdup(key); - tryvm_if(k == NULL, ret = PMINFO_R_ERROR, "Out of Memory!!!\n"); - node->key = k; - if (value) { - v = strdup(value); - tryvm_if(v == NULL, ret = PMINFO_R_ERROR, "Out of Memory!!!\n"); - } - node->value = v; - /*If API is called multiple times, we should OR all conditions.*/ - filter->list = g_slist_append(filter->list, (gpointer)node); - /*All memory will be freed in destroy API*/ - return PMINFO_R_OK; -catch: - if (node) { - if (node->key) { - free(node->key); - node->key = NULL; - } - if (node->value) { - free(node->value); - node->value = NULL; - } - free(node); - node = NULL; - } - return ret; -} - -static void __get_metadata_filter_condition(gpointer data, char **condition) -{ - pkgmgrinfo_node_x *node = (pkgmgrinfo_node_x*)data; - char key[MAX_QUERY_LEN] = {'\0'}; - char value[MAX_QUERY_LEN] = {'\0'}; - if (node->key) { - snprintf(key, MAX_QUERY_LEN, "(package_app_app_metadata.md_key='%s'", node->key); - } - if (node->value) { - snprintf(value, MAX_QUERY_LEN, " AND package_app_app_metadata.md_value='%s')", node->value); - strcat(key, value); - } else { - strcat(key, ")"); - } - *condition = strdup(key); - return; -} - -static char *_get_metadata_filtered_query(const char *query_raw, - pkgmgrinfo_filter_x *filter) -{ - char buf[MAX_QUERY_LEN] = { 0, }; - char *condition; - size_t len; - GSList *list; - GSList *head = NULL; - - if (filter) - head = filter->list; - - strncat(buf, query_raw, MAX_QUERY_LEN - 1); - len = strlen(buf); - for (list = head; list; list = list->next) { - /* TODO: revise condition getter function */ - __get_metadata_filter_condition(list->data, &condition); - if (condition == NULL) - continue; - if (buf[strlen(query_raw)] == '\0') { - len += strlen(" WHERE "); - strncat(buf, " WHERE ", MAX_QUERY_LEN - len - 1); - } else { - len += strlen(" AND "); - strncat(buf, " AND ", MAX_QUERY_LEN -len - 1); - } - len += strlen(condition); - strncat(buf, condition, sizeof(buf) - len - 1); - free(condition); - condition = NULL; - } - - return strdup(buf); -} - -static GSList *_appinfo_get_metadata_filtered_list(pkgmgrinfo_filter_x *filter) -{ - static const char query_raw[] = - "SELECT app_id FROM package_app_app_metadata"; int ret; - char *query; - sqlite3_stmt *stmt; - GSList *list = NULL; - char *appid; - query = _get_metadata_filtered_query(query_raw, filter); - if (query == NULL) { - LOGE("out of memory"); - return NULL; - } + ret = pkgmgrinfo_appinfo_filter_add_string(handle, + PMINFO_APPINFO_PROP_APP_METADATA_KEY, key); + if (ret != PMINFO_R_OK) + return ret; - ret = sqlite3_prepare_v2(GET_DB(manifest_db), query, strlen(query), - &stmt, NULL); - free(query); - if (ret != SQLITE_OK) { - LOGE("prepare failed: %s", sqlite3_errmsg(GET_DB(manifest_db))); - return NULL; - } - - while (sqlite3_step(stmt) == SQLITE_ROW) { - _save_column_str(stmt, 0, (const char **)&appid); - list = g_slist_append(list, appid); + /* value can be NULL. + * In that case all apps with specified key should be displayed + */ + if (value) { + ret = pkgmgrinfo_appinfo_filter_add_string(handle, + PMINFO_APPINFO_PROP_APP_METADATA_VALUE, value); + if (ret != PMINFO_R_OK) + return ret; } - sqlite3_finalize(stmt); - - return list; + return PMINFO_R_OK; } API int pkgmgrinfo_appinfo_usr_metadata_filter_foreach( pkgmgrinfo_appinfo_metadata_filter_h handle, pkgmgrinfo_app_list_cb app_cb, void *user_data, uid_t uid) { - GSList *list; - GSList *tmp; - char *appid; - pkgmgrinfo_appinfo_h info; - int stop = 0; - if (handle == NULL || app_cb == NULL) { LOGE("invalid parameter"); return PMINFO_R_EINVAL; } - if (__open_manifest_db(uid, true) < 0) - return PMINFO_R_ERROR; - - list = _appinfo_get_metadata_filtered_list(handle); - if (list == NULL) { - LOGE("no result"); - __close_manifest_db(); - return PMINFO_R_OK; - } - - for (tmp = list; tmp; tmp = tmp->next) { - appid = (char *)tmp->data; - if (stop == 0) { - if (pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, - &info)) { - free(appid); - continue; - } - if (app_cb(info, user_data) < 0) - stop = 1; - pkgmgrinfo_appinfo_destroy_appinfo(info); - } - free(appid); - } - - g_slist_free(list); - __close_manifest_db(); - - return PMINFO_R_OK; + return _appinfo_get_filtered_foreach_appinfo(uid, handle, app_cb, + user_data); } -API int pkgmgrinfo_appinfo_metadata_filter_foreach(pkgmgrinfo_appinfo_metadata_filter_h handle, +API int pkgmgrinfo_appinfo_metadata_filter_foreach( + pkgmgrinfo_appinfo_metadata_filter_h handle, pkgmgrinfo_app_list_cb app_cb, void *user_data) { - return pkgmgrinfo_appinfo_usr_metadata_filter_foreach(handle, app_cb, user_data, GLOBAL_USER); + return pkgmgrinfo_appinfo_usr_metadata_filter_foreach(handle, app_cb, + user_data, GLOBAL_USER); } API int pkgmgrinfo_appinfo_is_guestmode_visibility(pkgmgrinfo_appinfo_h handle, bool *status) diff --git a/src/pkgmgrinfo_private.c b/src/pkgmgrinfo_private.c index 9c1cd11..5f70ed7 100644 --- a/src/pkgmgrinfo_private.c +++ b/src/pkgmgrinfo_private.c @@ -91,6 +91,8 @@ static struct _appinfo_str_map_t appinfo_str_prop_map[] = { {E_PMINFO_APPINFO_PROP_APP_CATEGORY, PMINFO_APPINFO_PROP_APP_CATEGORY}, {E_PMINFO_APPINFO_PROP_APP_HWACCELERATION, PMINFO_APPINFO_PROP_APP_HWACCELERATION}, {E_PMINFO_APPINFO_PROP_APP_SCREENREADER, PMINFO_APPINFO_PROP_APP_SCREENREADER}, + {E_PMINFO_APPINFO_PROP_APP_METADATA_KEY, PMINFO_APPINFO_PROP_APP_METADATA_KEY}, + {E_PMINFO_APPINFO_PROP_APP_METADATA_VALUE, PMINFO_APPINFO_PROP_APP_METADATA_VALUE}, {E_PMINFO_APPINFO_PROP_APP_PACKAGE, PMINFO_APPINFO_PROP_APP_PACKAGE} }; @@ -229,118 +231,124 @@ inline pkgmgrinfo_appinfo_filter_prop_bool _pminfo_appinfo_convert_to_prop_bool( void __get_filter_condition(gpointer data, char **condition) { pkgmgrinfo_node_x *node = (pkgmgrinfo_node_x*)data; - char buf[MAX_QUERY_LEN + 1] = {'\0'}; + char buf[MAX_QUERY_LEN] = {'\0'}; char temp[PKG_STRING_LEN_MAX] = {'\0'}; switch (node->prop) { case E_PMINFO_PKGINFO_PROP_PACKAGE_ID: - snprintf(buf, MAX_QUERY_LEN, "package_info.package='%s'", node->value); + snprintf(buf, sizeof(buf), "package_info.package='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_TYPE: - snprintf(buf, MAX_QUERY_LEN, "package_info.package_type='%s'", node->value); + snprintf(buf, sizeof(buf), "package_info.package_type='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_VERSION: - snprintf(buf, MAX_QUERY_LEN, "package_info.package_version='%s'", node->value); + snprintf(buf, sizeof(buf), "package_info.package_version='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_INSTALL_LOCATION: - snprintf(buf, MAX_QUERY_LEN, "package_info.install_location='%s'", node->value); + snprintf(buf, sizeof(buf), "package_info.install_location='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_INSTALLED_STORAGE: - snprintf(buf, MAX_QUERY_LEN, "package_info.installed_storage='%s'", node->value); + snprintf(buf, sizeof(buf), "package_info.installed_storage='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_AUTHOR_NAME: - snprintf(buf, MAX_QUERY_LEN, "package_info.author_name='%s'", node->value); + snprintf(buf, sizeof(buf), "package_info.author_name='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_AUTHOR_HREF: - snprintf(buf, MAX_QUERY_LEN, "package_info.author_href='%s'", node->value); + snprintf(buf, sizeof(buf), "package_info.author_href='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_AUTHOR_EMAIL: - snprintf(buf, MAX_QUERY_LEN, "package_info.author_email='%s'", node->value); + snprintf(buf, sizeof(buf), "package_info.author_email='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_PRIVILEGE: - snprintf(buf, MAX_QUERY_LEN, "package_privilege_info.privilege='%s'", node->value); + snprintf(buf, sizeof(buf), "package_privilege_info.privilege='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_SIZE: - snprintf(buf, MAX_QUERY_LEN, "package_info.package_size='%s'", node->value); + snprintf(buf, sizeof(buf), "package_info.package_size='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_REMOVABLE: - snprintf(buf, MAX_QUERY_LEN, "package_info.package_removable IN %s", node->value); + snprintf(buf, sizeof(buf), "package_info.package_removable IN %s", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_PRELOAD: - snprintf(buf, MAX_QUERY_LEN, "package_info.package_preload IN %s", node->value); + snprintf(buf, sizeof(buf), "package_info.package_preload IN %s", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_READONLY: - snprintf(buf, MAX_QUERY_LEN, "package_info.package_readonly IN %s", node->value); + snprintf(buf, sizeof(buf), "package_info.package_readonly IN %s", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_UPDATE: - snprintf(buf, MAX_QUERY_LEN, "package_info.package_update IN %s", node->value); + snprintf(buf, sizeof(buf), "package_info.package_update IN %s", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_APPSETTING: - snprintf(buf, MAX_QUERY_LEN, "package_info.package_appsetting IN %s", node->value); + snprintf(buf, sizeof(buf), "package_info.package_appsetting IN %s", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_NODISPLAY_SETTING: - snprintf(buf, MAX_QUERY_LEN, "package_info.package_nodisplay IN %s", node->value); + snprintf(buf, sizeof(buf), "package_info.package_nodisplay IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_ID: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_id='%s'", node->value); + snprintf(buf, sizeof(buf), "package_app_info.app_id='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_COMPONENT: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_component='%s'", node->value); + snprintf(buf, sizeof(buf), "package_app_info.app_component='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_EXEC: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_exec='%s'", node->value); + snprintf(buf, sizeof(buf), "package_app_info.app_exec='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_ICON: - snprintf(buf, MAX_QUERY_LEN, "package_app_localized_info.app_icon='%s'", node->value); + snprintf(buf, sizeof(buf), "package_app_localized_info.app_icon='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_TYPE: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_type='%s'", node->value); + snprintf(buf, sizeof(buf), "package_app_info.app_type='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_OPERATION: - snprintf(temp, PKG_STRING_LEN_MAX, "(%s)", node->value); - snprintf(buf, MAX_QUERY_LEN, "package_app_app_svc.operation IN %s", temp); + snprintf(temp, sizeof(temp), "(%s)", node->value); + snprintf(buf, sizeof(buf), "package_app_app_svc.operation IN %s", temp); break; case E_PMINFO_APPINFO_PROP_APP_URI: - snprintf(temp, PKG_STRING_LEN_MAX, "(%s)", node->value); - snprintf(buf, MAX_QUERY_LEN, "package_app_app_svc.uri_scheme IN %s", temp); + snprintf(temp, sizeof(temp), "(%s)", node->value); + snprintf(buf, sizeof(buf), "package_app_app_svc.uri_scheme IN %s", temp); break; case E_PMINFO_APPINFO_PROP_APP_MIME: - snprintf(temp, PKG_STRING_LEN_MAX, "(%s)", node->value); - snprintf(buf, MAX_QUERY_LEN, "package_app_app_svc.mime_type IN %s", temp); + snprintf(temp, sizeof(temp), "(%s)", node->value); + snprintf(buf, sizeof(buf), "package_app_app_svc.mime_type IN %s", temp); break; case E_PMINFO_APPINFO_PROP_APP_CATEGORY: - snprintf(temp, PKG_STRING_LEN_MAX, "(%s)", node->value); - snprintf(buf, MAX_QUERY_LEN, "package_app_app_category.category IN %s", temp); + snprintf(temp, sizeof(temp), "(%s)", node->value); + snprintf(buf, sizeof(buf), "package_app_app_category.category IN %s", temp); break; case E_PMINFO_APPINFO_PROP_APP_NODISPLAY: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_nodisplay IN %s", node->value); + snprintf(buf, sizeof(buf), "package_app_info.app_nodisplay IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_MULTIPLE: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_multiple IN %s", node->value); + snprintf(buf, sizeof(buf), "package_app_info.app_multiple IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_ONBOOT: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_onboot IN %s", node->value); + snprintf(buf, sizeof(buf), "package_app_info.app_onboot IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_AUTORESTART: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_autorestart IN %s", node->value); + snprintf(buf, sizeof(buf), "package_app_info.app_autorestart IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_TASKMANAGE: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_taskmanage IN %s", node->value); + snprintf(buf, sizeof(buf), "package_app_info.app_taskmanage IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_HWACCELERATION: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_hwacceleration='%s'", node->value); + snprintf(buf, sizeof(buf), "package_app_info.app_hwacceleration='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_SCREENREADER: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_screenreader='%s'", node->value); + snprintf(buf, sizeof(buf), "package_app_info.app_screenreader='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_LAUNCHCONDITION: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_launchcondition IN %s", node->value); + snprintf(buf, sizeof(buf), "package_app_info.app_launchcondition IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_PACKAGE: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.package='%s'", node->value); + snprintf(buf, sizeof(buf), "package_app_info.package='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_UI_GADGET: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_ui_gadget IN %s", node->value); + snprintf(buf, sizeof(buf), "package_app_info.app_ui_gadget IN %s", node->value); + break; + case E_PMINFO_APPINFO_PROP_APP_METADATA_KEY: + snprintf(buf, sizeof(buf), "package_app_app_metadata.md_key='%s'", node->value); + break; + case E_PMINFO_APPINFO_PROP_APP_METADATA_VALUE: + snprintf(buf, sizeof(buf), "package_app_app_metadata.md_value='%s'", node->value); break; default: _LOGE("Invalid Property Type\n"); -- 2.7.4