From d3b9d79c0f3a36f45b091cf3375c7ccff9950680 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Wed, 8 Mar 2017 09:37:27 +0900 Subject: [PATCH] Fix app meatadata filter foreach Get app list filtered by OR-ed metadata key-value set. Change-Id: Iabfaca493904778926acbc043e9acaa127138906 Signed-off-by: Sangyoon Jang --- include/pkgmgr-info.h | 4 ---- src/pkgmgrinfo_appinfo.c | 51 +++++++++++++++++++++++++++++++++++++----------- src/pkgmgrinfo_pkginfo.c | 12 ++++++++++++ src/pkgmgrinfo_private.c | 35 +++++++++++++++++++++++---------- src/pkgmgrinfo_private.h | 7 +++++++ 5 files changed, 84 insertions(+), 25 deletions(-) diff --git a/include/pkgmgr-info.h b/include/pkgmgr-info.h index b8b6c85..4f2171c 100644 --- a/include/pkgmgr-info.h +++ b/include/pkgmgr-info.h @@ -141,10 +141,6 @@ extern "C" { #define PMINFO_APPINFO_PROP_APP_PACKAGE "PMINFO_APPINFO_PROP_APP_PACKAGE" /** String property for filtering based on app info*/ #define PMINFO_APPINFO_PROP_APP_INSTALLED_STORAGE "PMINFO_APPINFO_PROP_APP_INSTALLED_STORAGE" - /** 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" /** Integer property for filtering app support mode */ #define PMINFO_APPINFO_PROP_APP_SUPPORT_MODE "PMINFO_APPINFO_PROP_APP_SUPPORT_MODE" diff --git a/src/pkgmgrinfo_appinfo.c b/src/pkgmgrinfo_appinfo.c index d4c18ba..a25f671 100644 --- a/src/pkgmgrinfo_appinfo.c +++ b/src/pkgmgrinfo_appinfo.c @@ -91,6 +91,28 @@ static int _get_filtered_query(pkgmgrinfo_filter_x *filter, condition = NULL; } + if (filter->list_metadata) { + len += strlen(" AND ("); + strncat(buf, " AND (", MAX_QUERY_LEN - len - 1); + } + for (list = filter->list_metadata; list; list = list->next) { + joined |= __get_metadata_filter_condition(list->data, + &condition, bind_params); + if (condition == NULL) + continue; + len += strlen(condition); + strncat(buf, condition, sizeof(buf) - len - 1); + free(condition); + condition = NULL; + + len += strlen(" OR "); + strncat(buf, " OR ", MAX_QUERY_LEN - len - 1); + } + if (filter->list_metadata) { + len += strlen("1=0)"); + strncat(buf, "1=0)", MAX_QUERY_LEN - len - 1); + } + if (joined & E_PMINFO_APPINFO_JOIN_LOCALIZED_INFO) { strncat(tmp_query, join_localized_info, MAX_QUERY_LEN - len - 1); len += strlen(join_localized_info); @@ -3059,23 +3081,30 @@ API int pkgmgrinfo_appinfo_metadata_filter_add( pkgmgrinfo_appinfo_metadata_filter_h handle, const char *key, const char *value) { - int ret; - - ret = pkgmgrinfo_appinfo_filter_add_string(handle, - PMINFO_APPINFO_PROP_APP_METADATA_KEY, key); - if (ret != PMINFO_R_OK) - return ret; + pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle; + pkgmgrinfo_metadata_node_x *node; /* value can be NULL. * In that case all apps with specified key should be displayed */ - if (value && strlen(value)) { - ret = pkgmgrinfo_appinfo_filter_add_string(handle, - PMINFO_APPINFO_PROP_APP_METADATA_VALUE, value); - if (ret != PMINFO_R_OK) - return ret; + if (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_metadata = g_slist_append(filter->list_metadata, + (gpointer)node); + return PMINFO_R_OK; } diff --git a/src/pkgmgrinfo_pkginfo.c b/src/pkgmgrinfo_pkginfo.c index ea64f4b..fe4b52a 100644 --- a/src/pkgmgrinfo_pkginfo.c +++ b/src/pkgmgrinfo_pkginfo.c @@ -86,6 +86,16 @@ static void __destroy_each_node(gpointer data, gpointer user_data) node = NULL; } +static void __destroy_metadata_node(gpointer data) +{ + pkgmgrinfo_metadata_node_x *node = (pkgmgrinfo_metadata_node_x *)data; + if (node->key) + free(node->key); + if (node->value) + free(node->value); + free(node); +} + static void __cleanup_pkginfo(pkgmgr_pkginfo_x *data) { ret_if(data == NULL); @@ -1641,6 +1651,8 @@ API int pkgmgrinfo_pkginfo_filter_destroy(pkgmgrinfo_pkginfo_filter_h handle) g_slist_free(filter->list); } + g_slist_free_full(filter->list_metadata, __destroy_metadata_node); + free(filter); return PMINFO_R_OK; diff --git a/src/pkgmgrinfo_private.c b/src/pkgmgrinfo_private.c index d2584a1..5f99d1a 100644 --- a/src/pkgmgrinfo_private.c +++ b/src/pkgmgrinfo_private.c @@ -94,8 +94,6 @@ 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}, {E_PMINFO_APPINFO_PROP_APP_INSTALLED_STORAGE, PMINFO_APPINFO_PROP_APP_INSTALLED_STORAGE} }; @@ -377,14 +375,6 @@ int __get_filter_condition(gpointer data, uid_t uid, char **condition, GList **p case E_PMINFO_APPINFO_PROP_APP_UI_GADGET: snprintf(buf, sizeof(buf), "ai.app_ui_gadget=? COLLATE NOCASE"); break; - case E_PMINFO_APPINFO_PROP_APP_METADATA_KEY: - snprintf(buf, sizeof(buf), "package_app_app_metadata.md_key=?"); - flag = E_PMINFO_APPINFO_JOIN_METADATA; - break; - case E_PMINFO_APPINFO_PROP_APP_METADATA_VALUE: - snprintf(buf, sizeof(buf), "package_app_app_metadata.md_value=?"); - flag = E_PMINFO_APPINFO_JOIN_METADATA; - break; case E_PMINFO_APPINFO_PROP_APP_DISABLE: if (strcasecmp(node->value, "true") == 0) snprintf(buf, MAX_QUERY_LEN, "(ai.app_disable=? COLLATE NOCASE OR " @@ -416,6 +406,31 @@ int __get_filter_condition(gpointer data, uid_t uid, char **condition, GList **p return flag; } +int __get_metadata_filter_condition(gpointer data, char **condition, + GList **params) +{ + pkgmgrinfo_metadata_node_x *node = (pkgmgrinfo_metadata_node_x *)data; + char buf[MAX_QUERY_LEN]; + size_t len = 0; + + len += strlen("(package_app_app_metadata.md_key=?"); + snprintf(buf, sizeof(buf), "(package_app_app_metadata.md_key=?"); + if (node->value) { + len += strlen(" AND package_app_app_metadata.md_value=?"); + strncat(buf, " AND package_app_app_metadata.md_value=?", + sizeof(buf) - len - 1); + } + len += strlen(")"); + strncat(buf, ")", sizeof(buf) - len - 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_APPINFO_JOIN_METADATA; +} + int _add_icon_info_into_list(const char *locale, char *value, GList **icon) { icon_x *info; diff --git a/src/pkgmgrinfo_private.h b/src/pkgmgrinfo_private.h index c0822be..5229f32 100644 --- a/src/pkgmgrinfo_private.h +++ b/src/pkgmgrinfo_private.h @@ -196,6 +196,7 @@ typedef struct _pkgmgr_appinfo_x { typedef struct _pkgmgrinfo_filter_x { uid_t uid; GSList *list; + GSList *list_metadata; } pkgmgrinfo_filter_x; typedef struct _pkgmgrinfo_node_x { @@ -204,6 +205,11 @@ typedef struct _pkgmgrinfo_node_x { char *value; } pkgmgrinfo_node_x; +typedef struct _pkgmgrinfo_metadata_node_x { + char *key; + char *value; +} pkgmgrinfo_metadata_node_x; + typedef struct _pkgmgrinfo_appcontrol_x { int operation_count; int uri_count; @@ -242,6 +248,7 @@ void _save_column_int(sqlite3_stmt *stmt, int idx, int *i); void _save_column_str(sqlite3_stmt *stmt, int idx, char **str); char *_get_system_locale(void); int __get_filter_condition(gpointer data, uid_t uid, 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); int __pkginfo_check_installed_storage(package_x *pkginfo); -- 2.7.4