From: Sangyoon Jang Date: Mon, 7 Mar 2016 06:29:05 +0000 (+0900) Subject: Improve query performance X-Git-Tag: submit/tizen/20160524.073932^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F76%2F61276%2F26;p=platform%2Fcore%2Fappfw%2Fpkgmgr-info.git Improve query performance Add api: - pkgmgrinfo_appinfo_get_installed_list_full - pkgmgrinfo_appinfo_get_usr_installed_list_full - pkgmgrinfo_pkginfo_get_list_full - pkgmgrinfo_pkginfo_get_usr_list_full Removed: - pkgmgrinfo_appinfo_get_applist_for_amd - pkgmgrinfo_appinfo_get_usr_applist_for_amd Modify existing apis and added new expandable apis for improve performance without redundant api. Change-Id: I7575b36f33ef3ebfd647438f4fc6ebe1ce67d68f Signed-off-by: Sangyoon Jang --- diff --git a/include/pkgmgr-info.h b/include/pkgmgr-info.h index f2777b7..c2cae9e 100644 --- a/include/pkgmgr-info.h +++ b/include/pkgmgr-info.h @@ -158,6 +158,8 @@ extern "C" { /** Boolean property for filtering based on app info*/ #define PMINFO_APPINFO_PROP_APP_UI_GADGET "PMINFO_APPINFO_PROP_APP_UI_GADGET" /** Boolean property for filtering based on app info*/ +#define PMINFO_APPINFO_PROP_APP_DISABLE "PMINFO_APPINFO_PROP_APP_DISABLE" + /** Boolean property for filtering based on app info*/ #define PMINFO_APPINFO_PROP_APP_SUPPORT_DISABLE "PMINFO_APPINFO_PROP_APP_SUPPORT_DISABLE" /** will be updated*/ @@ -5602,6 +5604,20 @@ int pkgmgrinfo_client_listen_status(pkgmgrinfo_client *pc, pkgmgrinfo_handler ev int pkgmgrinfo_client_free(pkgmgrinfo_client *pc); int pkgmgrinfo_client_request_enable_external_pkg(char *pkgid); +/** + * @brief TEMP + */ + + +int pkgmgrinfo_pkginfo_get_usr_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb, + int flag, void *user_data, uid_t uid); +int pkgmgrinfo_pkginfo_get_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb, + int flag, void *user_data); +int pkgmgrinfo_appinfo_get_usr_installed_list_full( + pkgmgrinfo_app_list_cb app_func, uid_t uid, int flag, + void *user_data); +int pkgmgrinfo_appinfo_get_installed_list_full( + pkgmgrinfo_app_list_cb app_func, int flag, void *user_data); /** * @pkgmgrinfo client API end diff --git a/include/pkgmgrinfo_private.h b/include/pkgmgrinfo_private.h index 3c915eb..6804a74 100644 --- a/include/pkgmgrinfo_private.h +++ b/include/pkgmgrinfo_private.h @@ -139,6 +139,7 @@ typedef enum _pkgmgrinfo_appinfo_filter_prop_bool { E_PMINFO_APPINFO_PROP_APP_TASKMANAGE, E_PMINFO_APPINFO_PROP_APP_LAUNCHCONDITION, E_PMINFO_APPINFO_PROP_APP_UI_GADGET, + E_PMINFO_APPINFO_PROP_APP_DISABLE, E_PMINFO_APPINFO_PROP_APP_SUPPORT_DISABLE, E_PMINFO_APPINFO_PROP_APP_MAX_BOOL = E_PMINFO_APPINFO_PROP_APP_SUPPORT_DISABLE } pkgmgrinfo_appinfo_filter_prop_bool; @@ -159,6 +160,18 @@ typedef enum _pkgmgrinfo_pkginfo_filter_prop_range { E_PMINFO_PKGINFO_PROP_RANGE_MAX_INT = E_PMINFO_PKGINFO_PROP_RANGE_BASIC } pkgmgrinfo_pkginfo_filter_prop_range; +typedef enum _pkgmgrinfo_pkginfo_join_flag { + E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO = 0x0001, + E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO = 0x0002, +} pkgmgrinfo_pkginfo_join_flag; + +typedef enum _pkgmgrinfo_appinfo_join_flag { + E_PMINFO_APPINFO_JOIN_LOCALIZED_INFO = 0x0001, + E_PMINFO_APPINFO_JOIN_CATEGORY = 0x0002, + E_PMINFO_APPINFO_JOIN_APP_CONTROL = 0x0004, + E_PMINFO_APPINFO_JOIN_METADATA = 0x0008, +} pkgmgrinfo_appinfo_join_flag; + typedef struct _pkgmgr_pkginfo_x { uid_t uid; package_x *pkg_info; @@ -221,7 +234,7 @@ int __open_cert_db(uid_t uid, bool readonly); 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); -void __get_filter_condition(gpointer data, char **condition); +int __get_filter_condition(gpointer data, char **condition); #define REGULAR_USER 5000 static inline uid_t _getuid(void) diff --git a/include/pkgmgrinfo_type.h b/include/pkgmgrinfo_type.h index e7f5ad5..8cab293 100644 --- a/include/pkgmgrinfo_type.h +++ b/include/pkgmgrinfo_type.h @@ -82,6 +82,26 @@ typedef enum { PMINFO_CERT_COMPARE_ERROR, } pkgmgrinfo_cert_compare_result_type_e; +typedef enum { + PMINFO_APPINFO_GET_LABEL = 0x0001, + PMINFO_APPINFO_GET_ICON = 0x0002, + PMINFO_APPINFO_GET_CATEGORY = 0x0004, + PMINFO_APPINFO_GET_APP_CONTROL = 0x0008, + PMINFO_APPINFO_GET_DATA_CONTROL = 0x0010, + PMINFO_APPINFO_GET_METADATA = 0x0020, + PMINFO_APPINFO_GET_SPLASH_SCREEN = 0x0040, + PMINFO_APPINFO_GET_ALL = 0x007F +} pkgmgrinfo_appinfo_get_option; + +typedef enum { + PMINFO_PKGINFO_GET_LABEL = 0x0001, + PMINFO_PKGINFO_GET_ICON = 0x0002, + PMINFO_PKGINFO_GET_AUTHOR = 0x0004, + PMINFO_PKGINFO_GET_DESCRIPTION = 0x0008, + PMINFO_PKGINFO_GET_PRIVILEGE = 0x0010, + PMINFO_PKGINFO_GET_ALL = 0x001F +} pkgmgrinfo_pkginfo_get_option; + /** * @brief API return values */ diff --git a/src/pkgmgrinfo_appinfo.c b/src/pkgmgrinfo_appinfo.c index 11d3796..ca444e5 100644 --- a/src/pkgmgrinfo_appinfo.c +++ b/src/pkgmgrinfo_appinfo.c @@ -41,37 +41,45 @@ static void __cleanup_appinfo(pkgmgr_appinfo_x *data) return; } -static void __free_appinfo_list(gpointer data) -{ - pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)data; - __cleanup_appinfo(info); -} +static const char join_localized_info[] = + " LEFT OUTER JOIN package_app_localized_info" + " ON ai.app_id=package_app_localized_info.app_id" + " AND package_app_localized_info.app_locale=?"; +static const char join_category[] = + " LEFT OUTER JOIN package_app_app_category" + " ON ai.app_id=package_app_app_category.app_id"; +static const char join_app_control[] = + " LEFT OUTER JOIN package_app_app_control" + " ON ai.app_id=package_app_app_control.app_id"; +static const char join_metadata[] = + " LEFT OUTER JOIN package_app_app_metadata" + " ON ai.app_id=package_app_app_metadata.app_id "; static char *_get_filtered_query(const char *query_raw, pkgmgrinfo_filter_x *filter) { char buf[MAX_QUERY_LEN] = { 0, }; + char query[MAX_QUERY_LEN]; char *condition; - size_t len; + size_t len = 0; GSList *list; GSList *head = NULL; + int joined = 0; 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_filter_condition(list->data, &condition); + joined |= __get_filter_condition(list->data, &condition); if (condition == NULL) continue; - if (buf[strlen(query_raw)] == '\0') { + if (buf[0] == '\0') { len += strlen(" WHERE "); strncat(buf, " WHERE ", MAX_QUERY_LEN - len - 1); } else { len += strlen(" AND "); - strncat(buf, " AND ", MAX_QUERY_LEN -len - 1); + strncat(buf, " AND ", MAX_QUERY_LEN - len - 1); } len += strlen(condition); strncat(buf, condition, sizeof(buf) - len - 1); @@ -79,137 +87,27 @@ static char *_get_filtered_query(const char *query_raw, condition = NULL; } - return strdup(buf); -} - -static gint __list_strcmp(gconstpointer a, gconstpointer b) -{ - return strcmp((char *)a, (char *)b); -} - -static gint _appinfo_get_list(sqlite3 *db, const char *locale, - pkgmgrinfo_filter_x *filter, GList **list) -{ - static const char query_raw[] = - "SELECT DISTINCT package_app_info.app_id FROM package_app_info" - " LEFT OUTER JOIN package_app_localized_info" - " ON package_app_info.app_id=package_app_localized_info.app_id" - " AND package_app_localized_info.app_locale=%Q" - " 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_control" - " ON package_app_info.app_id=package_app_app_control.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; - sqlite3_stmt *stmt; - char *appid = NULL; - - query = _get_filtered_query(query_raw, filter); - if (query == NULL) - return PMINFO_R_ERROR; - query_localized = sqlite3_mprintf(query, locale); - free(query); - if (query_localized == NULL) - return PMINFO_R_ERROR; - - ret = sqlite3_prepare_v2(db, query_localized, - strlen(query_localized), &stmt, NULL); - sqlite3_free(query_localized); - if (ret != SQLITE_OK) { - LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return PMINFO_R_ERROR; - } - - while (sqlite3_step(stmt) == SQLITE_ROW) { - _save_column_str(stmt, 0, &appid); - if (appid != NULL) - *list = g_list_insert_sorted(*list, appid, - __list_strcmp); - } - - sqlite3_finalize(stmt); - - return PMINFO_R_OK; -} - -static int _appinfo_get_filtered_list(pkgmgrinfo_filter_x *filter, uid_t uid, - GList **list) -{ - int ret; - sqlite3 *db; - const char *dbpath; - char *locale; - GList *tmp; - GList *tmp2; - - locale = _get_system_locale(); - if (locale == NULL) - return PMINFO_R_ERROR; - - dbpath = getUserPkgParserDBPathUID(uid); - if (dbpath == NULL) { - free(locale); - return PMINFO_R_ERROR; - } - - ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL); - if (ret != SQLITE_OK) { - _LOGE("failed to open db: %d", ret); - free(locale); - return PMINFO_R_ERROR; - } - - if (_appinfo_get_list(db, locale, filter, list)) { - free(locale); - sqlite3_close_v2(db); - return PMINFO_R_ERROR; - } - sqlite3_close_v2(db); - - if (uid == GLOBAL_USER) { - free(locale); - return PMINFO_R_OK; - } - - /* search again from global */ - dbpath = getUserPkgParserDBPathUID(GLOBAL_USER); - if (dbpath == NULL) { - free(locale); - return PMINFO_R_ERROR; + snprintf(query, sizeof(query), "%s", query_raw); + len = strlen(query); + if (joined & E_PMINFO_APPINFO_JOIN_LOCALIZED_INFO) { + strncat(query, join_localized_info, MAX_QUERY_LEN - len - 1); + len += strlen(join_localized_info); } - - ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL); - if (ret != SQLITE_OK) { - _LOGE("failed to open db: %d", ret); - free(locale); - return PMINFO_R_ERROR; + if (joined & E_PMINFO_APPINFO_JOIN_CATEGORY) { + strncat(query, join_category, MAX_QUERY_LEN - len - 1); + len += strlen(join_category); } - - if (_appinfo_get_list(db, locale, filter, list)) { - free(locale); - sqlite3_close_v2(db); - return PMINFO_R_ERROR; + if (joined & E_PMINFO_APPINFO_JOIN_APP_CONTROL) { + strncat(query, join_app_control, MAX_QUERY_LEN - len - 1); + len += strlen(join_app_control); } - sqlite3_close_v2(db); - - /* remove duplicate element: - * since the list is sorted, we can remove duplicates in linear time - */ - for (tmp = *list, tmp2 = g_list_next(tmp); tmp; - tmp = tmp2, tmp2 = g_list_next(tmp)) { - if (tmp->prev == NULL || tmp->data == NULL) - continue; - if (strcmp((const char *)tmp->prev->data, - (const char *)tmp->data) == 0) - *list = g_list_delete_link(*list, tmp); + if (joined & E_PMINFO_APPINFO_JOIN_METADATA) { + strncat(query, join_metadata, MAX_QUERY_LEN - len - 1); + len += strlen(join_metadata); } + strncat(query, buf, MAX_QUERY_LEN - len -1); - free(locale); - - return PMINFO_R_OK; + return strdup(query); } static int _appinfo_get_label(sqlite3 *db, const char *appid, @@ -612,379 +510,383 @@ static void __get_splash_screen_display(sqlite3 *db, const char *appid, uid_t ui sqlite3_finalize(stmt); } -static int _appinfo_get_application(sqlite3 *db, const char *appid, - const char *locale, application_x **application, bool is_disabled, uid_t db_uid, uid_t target_uid) +static void __free_applications(gpointer data) +{ + pkgmgrinfo_basic_free_application((application_x *)data); +} + +static int _appinfo_get_applications(uid_t db_uid, uid_t uid, + const char *locale, pkgmgrinfo_filter_x *filter, int flag, + GHashTable *applications) { static const char query_raw[] = - "SELECT app_id, app_component, app_exec, app_nodisplay, " - "app_type, app_onboot, app_multiple, app_autorestart, " - "app_taskmanage, app_enabled, app_hwacceleration, " - "app_screenreader, app_mainapp, app_recentimage, " - "app_launchcondition, app_indicatordisplay, app_portraitimg, " - "app_landscapeimg, app_guestmodevisibility, " - "app_permissiontype, app_preload, app_submode, " - "app_submode_mainid, app_launch_mode, app_ui_gadget, " - "app_support_disable, " - "component_type, package, app_tep_name, app_zip_mount_file, app_process_pool, " - "app_installed_storage, app_background_category, " - "app_package_type, app_root_path, app_api_version, " - "app_effective_appid, app_disable, app_splash_screen_display " - "FROM package_app_info WHERE app_id='%s' " - "AND (app_disable='%s' " - "%s app_id %s IN " - "(SELECT app_id from package_app_info_for_uid WHERE uid='%d' AND is_disabled='true'))"; + "SELECT DISTINCT ai.app_id, ai.app_component, ai.app_exec, " + "ai.app_nodisplay, ai.app_type, ai.app_onboot, " + "ai.app_multiple, ai.app_autorestart, ai.app_taskmanage, " + "ai.app_enabled, ai.app_hwacceleration, ai.app_screenreader, " + "ai.app_mainapp, ai.app_recentimage, ai.app_launchcondition, " + "ai.app_indicatordisplay, ai.app_portraitimg, " + "ai.app_landscapeimg, ai.app_guestmodevisibility, " + "ai.app_permissiontype, ai.app_preload, ai.app_submode, " + "ai.app_submode_mainid, ai.app_launch_mode, ai.app_ui_gadget, " + "ai.app_support_disable, ai.app_process_pool, " + "ai.app_installed_storage, ai.app_background_category, " + "ai.app_package_type, ai.app_root_path, ai.app_api_version, " + "ai.app_effective_appid, ai.app_disable, " + "ai.app_splash_screen_display, " + "ai.component_type, ai.package " + "FROM package_app_info as ai"; int ret; - char query[MAX_QUERY_LEN] = { '\0' }; + char *query; + const char *dbpath; + sqlite3 *db; sqlite3_stmt *stmt; int idx; application_x *info; char *bg_category_str = NULL; - snprintf(query, MAX_QUERY_LEN - 1, query_raw, - appid, - is_disabled ? "true" : "false", - is_disabled ? "OR" : "AND", - is_disabled ? "" : "NOT", - (int)target_uid); - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - LOGE("prepare failed: %s", sqlite3_errmsg(db)); + dbpath = getUserPkgParserDBPathUID(db_uid); + if (dbpath == NULL) return PMINFO_R_ERROR; - } - ret = sqlite3_step(stmt); - if (ret == SQLITE_DONE) { - sqlite3_finalize(stmt); - return PMINFO_R_ENOENT; - } else if (ret != SQLITE_ROW) { - LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); + ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL); + if (ret != SQLITE_OK) { + _LOGE("failed to open db: %d", ret); return PMINFO_R_ERROR; } - info = calloc(1, sizeof(application_x)); - if (info == NULL) { + query = _get_filtered_query(query_raw, filter); + if (query == NULL) { LOGE("out of memory"); - sqlite3_finalize(stmt); + sqlite3_close_v2(db); return PMINFO_R_ERROR; } - idx = 0; - _save_column_str(stmt, idx++, &info->appid); - _save_column_str(stmt, idx++, &info->component); - _save_column_str(stmt, idx++, &info->exec); - _save_column_str(stmt, idx++, &info->nodisplay); - _save_column_str(stmt, idx++, &info->type); - _save_column_str(stmt, idx++, &info->onboot); - _save_column_str(stmt, idx++, &info->multiple); - _save_column_str(stmt, idx++, &info->autorestart); - _save_column_str(stmt, idx++, &info->taskmanage); - _save_column_str(stmt, idx++, &info->enabled); - _save_column_str(stmt, idx++, &info->hwacceleration); - _save_column_str(stmt, idx++, &info->screenreader); - _save_column_str(stmt, idx++, &info->mainapp); - _save_column_str(stmt, idx++, &info->recentimage); - _save_column_str(stmt, idx++, &info->launchcondition); - _save_column_str(stmt, idx++, &info->indicatordisplay); - _save_column_str(stmt, idx++, &info->portraitimg); - _save_column_str(stmt, idx++, &info->landscapeimg); - _save_column_str(stmt, idx++, &info->guestmode_visibility); - _save_column_str(stmt, idx++, &info->permission_type); - _save_column_str(stmt, idx++, &info->preload); - _save_column_str(stmt, idx++, &info->submode); - _save_column_str(stmt, idx++, &info->submode_mainid); - _save_column_str(stmt, idx++, &info->launch_mode); - _save_column_str(stmt, idx++, &info->ui_gadget); - _save_column_str(stmt, idx++, &info->support_disable); - _save_column_str(stmt, idx++, &info->component_type); - _save_column_str(stmt, idx++, &info->package); - _save_column_str(stmt, idx++, &info->tep_name); - _save_column_str(stmt, idx++, &info->zip_mount_file); - _save_column_str(stmt, idx++, &info->process_pool); - _save_column_str(stmt, idx++, &info->installed_storage); - _save_column_str(stmt, idx++, &bg_category_str); - _save_column_str(stmt, idx++, &info->package_type); - _save_column_str(stmt, idx++, &info->root_path); - _save_column_str(stmt, idx++, &info->api_version); - _save_column_str(stmt, idx++, &info->effective_appid); - _save_column_str(stmt, idx++, &info->is_disabled); - _save_column_str(stmt, idx++, &info->splash_screen_display); - if (db_uid == GLOBAL_USER) - __get_splash_screen_display(db, info->appid, db_uid, - &info->splash_screen_display); - - info->background_category = __get_background_category(bg_category_str); - free(bg_category_str); - - if (_appinfo_get_label(db, info->appid, locale, &info->label)) { - pkgmgrinfo_basic_free_application(info); - sqlite3_finalize(stmt); + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + free(query); + if (ret != SQLITE_OK) { + LOGE("prepare failed: %s", sqlite3_errmsg(db)); + sqlite3_close_v2(db); return PMINFO_R_ERROR; } - if (_appinfo_get_icon(db, info->appid, locale, &info->icon)) { - pkgmgrinfo_basic_free_application(info); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } + while (sqlite3_step(stmt) == SQLITE_ROW) { + info = calloc(1, sizeof(application_x)); + if (info == NULL) { + LOGE("out of memory"); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + idx = 0; + _save_column_str(stmt, idx++, &info->appid); + if (g_hash_table_contains(applications, + (gconstpointer)info->appid)) { + free(info->appid); + free(info); + continue; + } + _save_column_str(stmt, idx++, &info->component); + _save_column_str(stmt, idx++, &info->exec); + _save_column_str(stmt, idx++, &info->nodisplay); + _save_column_str(stmt, idx++, &info->type); + _save_column_str(stmt, idx++, &info->onboot); + _save_column_str(stmt, idx++, &info->multiple); + _save_column_str(stmt, idx++, &info->autorestart); + _save_column_str(stmt, idx++, &info->taskmanage); + _save_column_str(stmt, idx++, &info->enabled); + _save_column_str(stmt, idx++, &info->hwacceleration); + _save_column_str(stmt, idx++, &info->screenreader); + _save_column_str(stmt, idx++, &info->mainapp); + _save_column_str(stmt, idx++, &info->recentimage); + _save_column_str(stmt, idx++, &info->launchcondition); + _save_column_str(stmt, idx++, &info->indicatordisplay); + _save_column_str(stmt, idx++, &info->portraitimg); + _save_column_str(stmt, idx++, &info->landscapeimg); + _save_column_str(stmt, idx++, &info->guestmode_visibility); + _save_column_str(stmt, idx++, &info->permission_type); + _save_column_str(stmt, idx++, &info->preload); + _save_column_str(stmt, idx++, &info->submode); + _save_column_str(stmt, idx++, &info->submode_mainid); + _save_column_str(stmt, idx++, &info->launch_mode); + _save_column_str(stmt, idx++, &info->ui_gadget); + _save_column_str(stmt, idx++, &info->support_disable); + _save_column_str(stmt, idx++, &info->process_pool); + _save_column_str(stmt, idx++, &info->installed_storage); + _save_column_str(stmt, idx++, &bg_category_str); + _save_column_str(stmt, idx++, &info->package_type); + _save_column_str(stmt, idx++, &info->root_path); + _save_column_str(stmt, idx++, &info->api_version); + _save_column_str(stmt, idx++, &info->effective_appid); + _save_column_str(stmt, idx++, &info->is_disabled); + _save_column_str(stmt, idx++, &info->splash_screen_display); + _save_column_str(stmt, idx++, &info->component_type); + _save_column_str(stmt, idx++, &info->package); + info->for_all_users = + strdup((uid != GLOBAL_USER) ? "false" : "true"); + + if (db_uid == GLOBAL_USER) + __get_splash_screen_display(db, info->appid, db_uid, + &info->splash_screen_display); + + info->background_category = __get_background_category( + bg_category_str); + free(bg_category_str); - if (_appinfo_get_category(db, info->appid, &info->category)) { - pkgmgrinfo_basic_free_application(info); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } + if (flag & PMINFO_APPINFO_GET_LABEL) { + if (_appinfo_get_label(db, info->appid, locale, + &info->label)) { + pkgmgrinfo_basic_free_application(info); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + } - if (_appinfo_get_app_control(db, info->appid, &info->appcontrol)) { - pkgmgrinfo_basic_free_application(info); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } + if (flag & PMINFO_APPINFO_GET_ICON) { + if (_appinfo_get_icon(db, info->appid, locale, + &info->icon)) { + pkgmgrinfo_basic_free_application(info); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + } - if (_appinfo_get_data_control(db, info->appid, &info->datacontrol)) { - pkgmgrinfo_basic_free_application(info); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } + if (flag & PMINFO_APPINFO_GET_CATEGORY) { + if (_appinfo_get_category(db, info->appid, + &info->category)) { + pkgmgrinfo_basic_free_application(info); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + } - if (_appinfo_get_metadata(db, info->appid, &info->metadata)) { - pkgmgrinfo_basic_free_application(info); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } + if (flag & PMINFO_APPINFO_GET_APP_CONTROL) { + if (_appinfo_get_app_control(db, info->appid, + &info->appcontrol)) { + pkgmgrinfo_basic_free_application(info); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + } - if (_appinfo_get_splashscreens(db, info->appid, &info->splashscreens)) { - pkgmgrinfo_basic_free_application(info); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } + if (flag & PMINFO_APPINFO_GET_DATA_CONTROL) { + if (_appinfo_get_data_control(db, info->appid, + &info->datacontrol)) { + pkgmgrinfo_basic_free_application(info); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + } + + if (flag & PMINFO_APPINFO_GET_METADATA) { + if (_appinfo_get_metadata(db, info->appid, + &info->metadata)) { + pkgmgrinfo_basic_free_application(info); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + } - info->for_all_users = strdup((db_uid != GLOBAL_USER) ? "false" : "true"); + if (flag & PMINFO_APPINFO_GET_SPLASH_SCREEN) { + if (_appinfo_get_splashscreens(db, info->appid, + &info->splashscreens)) { + pkgmgrinfo_basic_free_application(info); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + } - *application = info; + g_hash_table_insert(applications, (gpointer)info->appid, + (gpointer)info); + } sqlite3_finalize(stmt); + sqlite3_close_v2(db); return PMINFO_R_OK; } -static int _appinfo_get_appinfo(const char *appid, uid_t db_uid, - uid_t target_uid, bool is_disabled, pkgmgr_appinfo_x **appinfo) +API int pkgmgrinfo_appinfo_get_usr_disabled_appinfo(const char *appid, uid_t uid, + pkgmgrinfo_appinfo_h *handle) { int ret; - sqlite3 *db; - const char *dbpath; char *locale; + GHashTable *list; + pkgmgrinfo_appinfo_filter_h filter; pkgmgr_appinfo_x *info; - dbpath = getUserPkgParserDBPathUID(db_uid); - if (dbpath == NULL) - return PMINFO_R_ERROR; + if (appid == NULL || handle == NULL) { + LOGE("invalid parameter"); + return PMINFO_R_EINVAL; + } locale = _get_system_locale(); if (locale == NULL) return PMINFO_R_ERROR; - ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL); - if (ret != SQLITE_OK) { - _LOGE("failed to open db: %d", ret); + ret = pkgmgrinfo_appinfo_filter_create(&filter); + if (ret != PMINFO_R_OK) { free(locale); - return PMINFO_R_ERROR; + return ret; } - info = calloc(1, sizeof(pkgmgr_appinfo_x)); - if (info == NULL) { - _LOGE("out of memory"); + ret = pkgmgrinfo_appinfo_filter_add_string(filter, + PMINFO_APPINFO_PROP_APP_ID, appid); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_appinfo_filter_destroy(filter); free(locale); - sqlite3_close_v2(db); return PMINFO_R_ERROR; } - ret = _appinfo_get_application(db, appid, locale, &info->app_info, is_disabled, db_uid, target_uid); + ret = pkgmgrinfo_appinfo_filter_add_bool(filter, + PMINFO_APPINFO_PROP_APP_DISABLE, true); if (ret != PMINFO_R_OK) { - free(info); + pkgmgrinfo_appinfo_filter_destroy(filter); free(locale); - sqlite3_close_v2(db); - return ret; + return PMINFO_R_ERROR; } - info->locale = locale; - info->package = strdup(info->app_info->package); - - *appinfo = info; - - sqlite3_close_v2(db); - - return ret; -} - -int _appinfo_get_applist(uid_t uid, const char *locale, GHashTable **appinfo_table) -{ - int ret = PMINFO_R_ERROR; - int idx = 0; - const char *dbpath; - char *query = NULL; - char *bg_category_str = NULL; - char *key = NULL; - sqlite3 *db; - sqlite3_stmt *stmt = NULL; - pkgmgr_appinfo_x *info = NULL; - application_x *appinfo = NULL; - - dbpath = getUserPkgParserDBPathUID(uid); - if (dbpath == NULL) + list = g_hash_table_new(g_str_hash, g_str_equal); + if (list == NULL) { + pkgmgrinfo_appinfo_filter_destroy(filter); + free(locale); return PMINFO_R_ERROR; + } - ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL); - if (ret != SQLITE_OK) { - _LOGE("failed to open db: %d", ret); - ret = PMINFO_R_ERROR; - goto catch; - } - - query = sqlite3_mprintf("SELECT app_id, app_exec, app_type, " - "app_onboot, app_multiple, app_autorestart, app_taskmanage, " - "app_hwacceleration, app_permissiontype, app_preload, " - "app_installed_storage, app_process_pool, app_launch_mode, " - "app_package_type, component_type, package, app_tep_name, app_zip_mount_file, " - "app_background_category, app_root_path, app_api_version, " - "app_effective_appid, app_disable, app_splash_screen_display, " - "(CASE WHEN A.app_disable='true' THEN 'true' " - "ELSE (CASE WHEN (SELECT app_id FROM package_app_info_for_uid " - "WHERE app_id=A.app_id AND uid='%d' AND is_disabled='true') IS NULL " - "THEN 'false' ELSE 'true' END) END) AS app_disable " - "FROM package_app_info A", (int)getuid()); + ret = _appinfo_get_applications(uid, uid, locale, filter, + PMINFO_APPINFO_GET_ALL, list); + if (!g_hash_table_size(list) && uid != GLOBAL_USER) + ret = _appinfo_get_applications(GLOBAL_USER, uid, locale, + filter, PMINFO_APPINFO_GET_ALL, list); - if (query == NULL) { - _LOGE("Out of memory"); - goto catch; + pkgmgrinfo_appinfo_filter_destroy(filter); + if (ret != PMINFO_R_OK) { + g_hash_table_destroy(list); + free(locale); + return ret; } - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - LOGE("prepare failed: %s", sqlite3_errmsg(db)); - ret = PMINFO_R_ERROR; - goto catch; + if (!g_hash_table_size(list)) { + _LOGI("Appinfo for [%s] is not existed for user [%d]", + appid, uid); + g_hash_table_destroy(list); + free(locale); + return PMINFO_R_ENOENT; } - while (sqlite3_step(stmt) == SQLITE_ROW) { - info = calloc(1, sizeof(pkgmgr_appinfo_x)); - appinfo = calloc(1, sizeof(application_x)); - if (info == NULL || appinfo == NULL) { - LOGE("calloc failed"); - ret = PMINFO_R_ERROR; - goto catch; - } - - idx = 0; - _save_column_str(stmt, idx++, &appinfo->appid); - _save_column_str(stmt, idx++, &appinfo->exec); - _save_column_str(stmt, idx++, &appinfo->type); - - _save_column_str(stmt, idx++, &appinfo->onboot); - _save_column_str(stmt, idx++, &appinfo->multiple); - _save_column_str(stmt, idx++, &appinfo->autorestart); - _save_column_str(stmt, idx++, &appinfo->taskmanage); - - _save_column_str(stmt, idx++, &appinfo->hwacceleration); - _save_column_str(stmt, idx++, &appinfo->permission_type); - _save_column_str(stmt, idx++, &appinfo->preload); - - _save_column_str(stmt, idx++, &appinfo->installed_storage); - _save_column_str(stmt, idx++, &appinfo->process_pool); - _save_column_str(stmt, idx++, &appinfo->launch_mode); - - _save_column_str(stmt, idx++, &appinfo->package_type); - _save_column_str(stmt, idx++, &appinfo->component_type); - _save_column_str(stmt, idx++, &appinfo->package); - _save_column_str(stmt, idx++, &appinfo->tep_name); - _save_column_str(stmt, idx++, &appinfo->zip_mount_file); - - _save_column_str(stmt, idx++, &bg_category_str); - _save_column_str(stmt, idx++, &appinfo->root_path); - _save_column_str(stmt, idx++, &appinfo->api_version); - - _save_column_str(stmt, idx++, &appinfo->effective_appid); - _save_column_str(stmt, idx++, &appinfo->is_disabled); - _save_column_str(stmt, idx++, &appinfo->splash_screen_display); - - if (uid == GLOBAL_USER) - __get_splash_screen_display(db, appinfo->appid, uid, - &appinfo->splash_screen_display); - - appinfo->background_category = __get_background_category(bg_category_str); - free(bg_category_str); - - if (_appinfo_get_splashscreens(db, appinfo->appid, &appinfo->splashscreens)) { - pkgmgrinfo_basic_free_application(appinfo); - ret = PMINFO_R_ERROR; - goto catch; - } - - info->locale = strdup(locale); - info->package = strdup(appinfo->package); - appinfo->for_all_users = strdup((uid != GLOBAL_USER) ? "false" : "true"); - info->app_info = appinfo; - key = strdup(info->app_info->appid); - - if (!g_hash_table_contains(*appinfo_table, (gconstpointer)key)) - g_hash_table_insert(*appinfo_table, (gpointer)key, (gpointer)info); - else - __cleanup_appinfo(info); + info = calloc(1, sizeof(pkgmgr_appinfo_x)); + if (info == NULL) { + _LOGE("out of memory"); + free(locale); + return PMINFO_R_ERROR; } - ret = PMINFO_R_OK; + info->app_info = (application_x *)g_hash_table_lookup(list, appid); + info->locale = locale; + info->package = strdup(info->app_info->package); -catch: + /* just free list only */ + g_hash_table_destroy(list); - sqlite3_finalize(stmt); - sqlite3_free(query); - sqlite3_close(db); + *handle = info; return ret; } -API int pkgmgrinfo_appinfo_get_usr_disabled_appinfo(const char *appid, uid_t uid, +API int pkgmgrinfo_appinfo_get_disabled_appinfo(const char *appid, pkgmgrinfo_appinfo_h *handle) +{ + return pkgmgrinfo_appinfo_get_usr_disabled_appinfo(appid, _getuid(), handle); +} + +API int pkgmgrinfo_appinfo_get_usr_appinfo(const char *appid, uid_t uid, pkgmgrinfo_appinfo_h *handle) { int ret; + char *locale; + GHashTable *list; + pkgmgrinfo_appinfo_filter_h filter; + pkgmgr_appinfo_x *info; if (appid == NULL || handle == NULL) { LOGE("invalid parameter"); return PMINFO_R_EINVAL; } - ret = _appinfo_get_appinfo(appid, uid, uid, true, (pkgmgr_appinfo_x **)handle); - if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER) - ret = _appinfo_get_appinfo(appid, GLOBAL_USER, uid, true, - (pkgmgr_appinfo_x **)handle); + locale = _get_system_locale(); + if (locale == NULL) + return PMINFO_R_ERROR; - if (ret != PMINFO_R_OK) - _LOGI("Appinfo for [%s] is not existed for user [%d]", appid, uid); + ret = pkgmgrinfo_appinfo_filter_create(&filter); + if (ret != PMINFO_R_OK) { + free(locale); + return ret; + } - return ret; -} + ret = pkgmgrinfo_appinfo_filter_add_string(filter, + PMINFO_APPINFO_PROP_APP_ID, appid); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_appinfo_filter_destroy(filter); + free(locale); + return PMINFO_R_ERROR; + } -API int pkgmgrinfo_appinfo_get_disabled_appinfo(const char *appid, pkgmgrinfo_appinfo_h *handle) -{ - return pkgmgrinfo_appinfo_get_usr_disabled_appinfo(appid, _getuid(), handle); -} + ret = pkgmgrinfo_appinfo_filter_add_bool(filter, + PMINFO_APPINFO_PROP_APP_DISABLE, false); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_appinfo_filter_destroy(filter); + free(locale); + return PMINFO_R_ERROR; + } -API int pkgmgrinfo_appinfo_get_usr_appinfo(const char *appid, uid_t uid, - pkgmgrinfo_appinfo_h *handle) -{ - int ret; + list = g_hash_table_new(g_str_hash, g_str_equal); + if (list == NULL) { + pkgmgrinfo_appinfo_filter_destroy(filter); + free(locale); + return PMINFO_R_ERROR; + } - if (appid == NULL || handle == NULL) { - LOGE("invalid parameter"); - return PMINFO_R_EINVAL; + ret = _appinfo_get_applications(uid, uid, locale, filter, + PMINFO_APPINFO_GET_ALL, list); + if (!g_hash_table_size(list) && uid != GLOBAL_USER) + ret = _appinfo_get_applications(GLOBAL_USER, uid, locale, + filter, PMINFO_APPINFO_GET_ALL, list); + + pkgmgrinfo_appinfo_filter_destroy(filter); + if (ret != PMINFO_R_OK) { + g_hash_table_destroy(list); + free(locale); + return ret; } - ret = _appinfo_get_appinfo(appid, uid, uid, false, (pkgmgr_appinfo_x **)handle); - if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER) - ret = _appinfo_get_appinfo(appid, GLOBAL_USER, uid, false, - (pkgmgr_appinfo_x **)handle); - if (ret != PMINFO_R_OK) + if (!g_hash_table_size(list)) { _LOGI("Appinfo for [%s] is not existed for user [%d]", appid, uid); + g_hash_table_destroy(list); + free(locale); + return PMINFO_R_ENOENT; + } + + info = calloc(1, sizeof(pkgmgr_appinfo_x)); + if (info == NULL) { + _LOGE("out of memory"); + free(locale); + return PMINFO_R_ERROR; + } + + info->app_info = (application_x *)g_hash_table_lookup(list, appid); + info->locale = locale; + info->package = strdup(info->app_info->package); + + /* just free list only */ + g_hash_table_destroy(list); + + *handle = info; return ret; } @@ -1337,39 +1239,50 @@ API int pkgmgrinfo_appinfo_clone_appinfo(pkgmgrinfo_appinfo_h handle, } static int _appinfo_get_filtered_foreach_appinfo(uid_t uid, - pkgmgrinfo_filter_x *filter, pkgmgrinfo_app_list_cb app_list_cb, + pkgmgrinfo_filter_x *filter, int flag, pkgmgrinfo_app_list_cb app_list_cb, void *user_data) { int ret; - pkgmgr_appinfo_x *info; - GList *list = NULL; - GList *tmp; - char *appid; - int stop = 0; + char *locale; + application_x *app; + pkgmgr_appinfo_x info; + GHashTable *list; + GHashTableIter iter; + gpointer value; - ret = _appinfo_get_filtered_list(filter, uid, &list); - if (ret != PMINFO_R_OK) + locale = _get_system_locale(); + if (locale == NULL) return PMINFO_R_ERROR; - for (tmp = list; tmp; tmp = tmp->next) { - appid = (char *)tmp->data; - if (stop == 0) { - ret = _appinfo_get_appinfo(appid, uid, uid, false, &info); - if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER) - ret = _appinfo_get_appinfo(appid, GLOBAL_USER, uid, false, - &info); - if (ret != PMINFO_R_OK) { - free(appid); - continue; - } - if (app_list_cb(info, user_data) < 0) - stop = 1; - pkgmgrinfo_appinfo_destroy_appinfo(info); - } - free(appid); + list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, + __free_applications); + if (list == NULL) { + free(locale); + return PMINFO_R_ERROR; + } + + ret = _appinfo_get_applications(uid, uid, locale, filter, flag, list); + if (ret == PMINFO_R_OK && uid != GLOBAL_USER) + ret = _appinfo_get_applications(GLOBAL_USER, uid, locale, + filter, flag, list); + + if (ret != PMINFO_R_OK) { + g_hash_table_destroy(list); + free(locale); + return ret; } - g_list_free(list); + g_hash_table_iter_init(&iter, list); + while (g_hash_table_iter_next(&iter, NULL, &value)) { + app = (application_x *)value; + info.app_info = app; + info.locale = locale; + info.package = app->package; + if (app_list_cb(&info, user_data) < 0) + break; + } + g_hash_table_destroy(list); + free(locale); return PMINFO_R_OK; } @@ -1406,7 +1319,8 @@ API int pkgmgrinfo_appinfo_get_usr_list(pkgmgrinfo_pkginfo_h handle, if (uid == GLOBAL_USER) { if (pkgmgrinfo_appinfo_filter_add_int(filter, - PMINFO_APPINFO_PROP_APP_DISABLE_FOR_USER, (int)getuid())) { + PMINFO_APPINFO_PROP_APP_DISABLE_FOR_USER, + (int)getuid())) { pkgmgrinfo_appinfo_filter_destroy(filter); return PMINFO_R_ERROR; } @@ -1423,92 +1337,98 @@ API int pkgmgrinfo_appinfo_get_usr_list(pkgmgrinfo_pkginfo_h handle, } } - ret = _appinfo_get_filtered_foreach_appinfo(uid, filter, app_func, - user_data); + ret = _appinfo_get_filtered_foreach_appinfo(uid, filter, + PMINFO_APPINFO_GET_ALL, app_func, user_data); pkgmgrinfo_appinfo_filter_destroy(filter); return ret; } -API int pkgmgrinfo_appinfo_get_list(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_app_component component, - pkgmgrinfo_app_list_cb app_func, void *user_data) +API int pkgmgrinfo_appinfo_get_list(pkgmgrinfo_pkginfo_h handle, + pkgmgrinfo_app_component component, + pkgmgrinfo_app_list_cb app_func, void *user_data) { return pkgmgrinfo_appinfo_get_usr_list(handle, component, app_func, user_data, _getuid()); } -API int pkgmgrinfo_appinfo_get_usr_applist_for_amd(pkgmgrinfo_app_list_cb app_func, uid_t uid, void *user_data) +API int pkgmgrinfo_appinfo_get_usr_installed_list_full( + pkgmgrinfo_app_list_cb app_func, uid_t uid, int flag, + void *user_data) { - int ret = PMINFO_R_ERROR; - char *locale = NULL; - GHashTable *appinfo_table; - GHashTableIter iter; - char *key; - pkgmgr_appinfo_x *val; - - locale = _get_system_locale(); - if (locale == NULL) - return PMINFO_R_ERROR; + int ret; + pkgmgrinfo_appinfo_filter_h filter; - appinfo_table = g_hash_table_new_full(g_str_hash, g_str_equal, - free, __free_appinfo_list); - if (appinfo_table == NULL) { - ret = -1; - goto catch; + if (app_func == NULL) { + LOGE("invalid parameter"); + return PMINFO_R_EINVAL; } - ret = _appinfo_get_applist(uid, locale, &appinfo_table); - if (ret != PMINFO_R_OK) { - LOGE("failed get applist[%d]", (int)uid); - goto catch; + if (pkgmgrinfo_appinfo_filter_create(&filter)) { + return PMINFO_R_ERROR; } - if (uid != GLOBAL_USER) { - ret = _appinfo_get_applist(GLOBAL_USER, locale, &appinfo_table); - if (ret != PMINFO_R_OK) { - LOGE("failed get applist[%d]", GLOBAL_USER); - goto catch; - } + if (pkgmgrinfo_appinfo_filter_add_bool(filter, + PMINFO_APPINFO_PROP_APP_DISABLE, false)) { + pkgmgrinfo_appinfo_filter_destroy(filter); + return PMINFO_R_ERROR; } - g_hash_table_iter_init(&iter, appinfo_table); - while (g_hash_table_iter_next(&iter, (gpointer)&key, (gpointer)&val)) { - ret = app_func((void *)val, user_data); - if (ret != PMINFO_R_OK) { - LOGE("callback is stopped"); - goto catch; + if (uid == GLOBAL_USER) { + if (pkgmgrinfo_appinfo_filter_add_int(filter, + PMINFO_APPINFO_PROP_APP_DISABLE_FOR_USER, + (int)getuid())) { + pkgmgrinfo_appinfo_filter_destroy(filter); + return PMINFO_R_ERROR; } } -catch: - if (locale) - free(locale); + ret = _appinfo_get_filtered_foreach_appinfo(uid, filter, flag, app_func, + user_data); - if (appinfo_table) - g_hash_table_destroy(appinfo_table); + pkgmgrinfo_appinfo_filter_destroy(filter); return ret; } -API int pkgmgrinfo_appinfo_get_applist_for_amd(pkgmgrinfo_app_list_cb app_func, void *user_data) +API int pkgmgrinfo_appinfo_get_installed_list_full( + pkgmgrinfo_app_list_cb app_func, int flag, void *user_data) { - return pkgmgrinfo_appinfo_get_usr_applist_for_amd(app_func, _getuid(), user_data); + return pkgmgrinfo_appinfo_get_usr_installed_list_full(app_func, + _getuid(), flag, user_data); } -API int pkgmgrinfo_appinfo_get_usr_installed_list(pkgmgrinfo_app_list_cb app_func, uid_t uid, void *user_data) +API int pkgmgrinfo_appinfo_get_usr_install_list(pkgmgrinfo_app_list_cb app_func, + uid_t uid, void *user_data) +{ + return pkgmgrinfo_appinfo_get_usr_installed_list_full(app_func, + uid, PMINFO_APPINFO_GET_ALL, user_data); +} + +API int pkgmgrinfo_appinfo_get_install_list(pkgmgrinfo_app_list_cb app_func, + void *user_data) +{ + return pkgmgrinfo_appinfo_get_usr_installed_list_full(app_func, + _getuid(), PMINFO_APPINFO_GET_ALL, user_data); +} + +API int pkgmgrinfo_appinfo_get_usr_installed_list( + pkgmgrinfo_app_list_cb app_func, uid_t uid, void *user_data) { if (app_func == NULL) { LOGE("invalid parameter"); return PMINFO_R_EINVAL; } - return _appinfo_get_filtered_foreach_appinfo(uid, NULL, app_func, - user_data); + return _appinfo_get_filtered_foreach_appinfo(uid, NULL, + PMINFO_APPINFO_GET_ALL, app_func, user_data); } -API int pkgmgrinfo_appinfo_get_installed_list(pkgmgrinfo_app_list_cb app_func, void *user_data) +API int pkgmgrinfo_appinfo_get_installed_list(pkgmgrinfo_app_list_cb app_func, + void *user_data) { - return pkgmgrinfo_appinfo_get_usr_installed_list(app_func, _getuid(), user_data); + return pkgmgrinfo_appinfo_get_usr_installed_list(app_func, _getuid(), + user_data); } API int pkgmgrinfo_appinfo_get_appid(pkgmgrinfo_appinfo_h handle, char **appid) @@ -2926,20 +2846,39 @@ API int pkgmgrinfo_appinfo_filter_add_string(pkgmgrinfo_appinfo_filter_h handle, API int pkgmgrinfo_appinfo_usr_filter_count(pkgmgrinfo_appinfo_filter_h handle, int *count, uid_t uid) { int ret; - GList *list = NULL; + char *locale; + GHashTable *list; if (handle == NULL || count == NULL) { _LOGE("invalid parameter"); return PMINFO_R_EINVAL; } - ret = _appinfo_get_filtered_list(handle, uid, &list); - if (ret != PMINFO_R_OK) + locale = _get_system_locale(); + if (locale == NULL) + return PMINFO_R_ERROR; + + list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, + __free_applications); + if (list == NULL) { + free(locale); return PMINFO_R_ERROR; + } - *count = g_list_length(list); + ret = _appinfo_get_applications(uid, uid, locale, handle, 0, list); + if (ret == PMINFO_R_OK && uid != GLOBAL_USER) + ret = _appinfo_get_applications(GLOBAL_USER, uid, locale, + handle, 0, list); - g_list_free_full(list, free); + if (ret != PMINFO_R_OK) { + g_hash_table_destroy(list); + free(locale); + return PMINFO_R_ERROR; + } + + *count = g_hash_table_size(list); + g_hash_table_destroy(list); + free(locale); return PMINFO_R_OK; } @@ -2958,7 +2897,7 @@ API int pkgmgrinfo_appinfo_usr_filter_foreach_appinfo( return PMINFO_R_EINVAL; } - return _appinfo_get_filtered_foreach_appinfo(uid, handle, app_cb, + return _appinfo_get_filtered_foreach_appinfo(uid, handle, PMINFO_APPINFO_GET_ALL, app_cb, user_data); } @@ -3011,7 +2950,7 @@ API int pkgmgrinfo_appinfo_usr_metadata_filter_foreach( return PMINFO_R_EINVAL; } - return _appinfo_get_filtered_foreach_appinfo(uid, handle, app_cb, + return _appinfo_get_filtered_foreach_appinfo(uid, handle, PMINFO_APPINFO_GET_ALL, app_cb, user_data); } diff --git a/src/pkgmgrinfo_pkginfo.c b/src/pkgmgrinfo_pkginfo.c index f835077..81b9203 100644 --- a/src/pkgmgrinfo_pkginfo.c +++ b/src/pkgmgrinfo_pkginfo.c @@ -46,8 +46,6 @@ #include "pkgmgr_parser_db.h" #include "pkgmgr_parser_internal.h" -static int _pkginfo_get_pkginfo(const char *pkgid, uid_t uid, - pkgmgr_pkginfo_x **pkginfo); static char *_get_filtered_query(const char *query_raw, pkgmgrinfo_filter_x *filter); @@ -191,187 +189,6 @@ long long _pkgmgr_calculate_dir_size(char *dirname) } -static gint __list_strcmp(gconstpointer a, gconstpointer b) -{ - return strcmp((char *)a, (char *)b); -} - -static int _pkginfo_get_list(sqlite3 *db, const char *locale, - pkgmgrinfo_filter_x *filter, GList **list) -{ - static const char query_raw[] = - "SELECT DISTINCT package_info.package FROM package_info" - " LEFT OUTER JOIN package_localized_info" - " ON package_info.package=package_localized_info.package" - " AND package_localized_info.package_locale=%Q " - " LEFT OUTER JOIN package_privilege_info" - " ON package_info.package=package_privilege_info.package"; - int ret; - char *query; - char *query_localized; - sqlite3_stmt *stmt; - char *pkgid = NULL; - - query = _get_filtered_query(query_raw, filter); - if (query == NULL) - return -1; - query_localized = sqlite3_mprintf(query, locale); - free(query); - if (query_localized == NULL) - return -1; - - ret = sqlite3_prepare_v2(db, query_localized, - strlen(query_localized), &stmt, NULL); - sqlite3_free(query_localized); - if (ret != SQLITE_OK) { - LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - while (sqlite3_step(stmt) == SQLITE_ROW) { - _save_column_str(stmt, 0, &pkgid); - if (pkgid != NULL) - *list = g_list_insert_sorted(*list, pkgid, - __list_strcmp); - } - - sqlite3_finalize(stmt); - - return 0; -} - -static int _pkginfo_get_filtered_list(pkgmgrinfo_filter_x *filter, uid_t uid, - GList **list) -{ - int ret; - sqlite3 *db; - const char *dbpath; - char *locale; - GList *tmp; - GList *tmp2; - - locale = _get_system_locale(); - if (locale == NULL) - return PMINFO_R_ERROR; - - dbpath = getUserPkgParserDBPathUID(uid); - if (dbpath == NULL) { - free(locale); - return PMINFO_R_ERROR; - } - - ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL); - if (ret != SQLITE_OK) { - _LOGE("failed to open db: %d", ret); - free(locale); - return PMINFO_R_ERROR; - } - - if (_pkginfo_get_list(db, locale, filter, list)) { - free(locale); - sqlite3_close_v2(db); - return PMINFO_R_ERROR; - } - sqlite3_close_v2(db); - - if (uid == GLOBAL_USER) { - free(locale); - return PMINFO_R_OK; - } - - /* search again from global */ - dbpath = getUserPkgParserDBPathUID(GLOBAL_USER); - if (dbpath == NULL) { - free(locale); - return PMINFO_R_ERROR; - } - - ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL); - if (ret != SQLITE_OK) { - _LOGE("failed to open db: %d", ret); - free(locale); - return PMINFO_R_ERROR; - } - - if (_pkginfo_get_list(db, locale, filter, list)) { - free(locale); - sqlite3_close_v2(db); - return PMINFO_R_ERROR; - } - sqlite3_close_v2(db); - - /* remove duplicate element: - * since the list is sorted, we can remove duplicates in linear time - */ - for (tmp = *list, tmp2 = g_list_next(tmp); tmp; - tmp = tmp2, tmp2 = g_list_next(tmp)) { - if (tmp->prev == NULL || tmp->data == NULL) - continue; - if (strcmp((const char *)tmp->prev->data, - (const char *)tmp->data) == 0) - *list = g_list_delete_link(*list, tmp); - } - - free(locale); - - return PMINFO_R_OK; -} - - -static int _pkginfo_get_filtered_foreach_pkginfo(pkgmgrinfo_filter_x *filter, - pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data, uid_t uid) -{ - int ret; - pkgmgr_pkginfo_x *info; - GList *list = NULL; - GList *tmp; - char *pkgid; - int stop = 0; - - ret = _pkginfo_get_filtered_list(filter, uid, &list); - if (ret != PMINFO_R_OK) - return PMINFO_R_ERROR; - - for (tmp = list; tmp; tmp = tmp->next) { - pkgid = (char *)tmp->data; - if (stop == 0) { - ret = _pkginfo_get_pkginfo(pkgid, uid, &info); - if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER) - ret = _pkginfo_get_pkginfo(pkgid, GLOBAL_USER, - &info); - if (ret != PMINFO_R_OK) { - free(pkgid); - continue; - } - if (pkg_list_cb(info, user_data) < 0) - stop = 1; - pkgmgrinfo_pkginfo_destroy_pkginfo(info); - } - free(pkgid); - } - - g_list_free(list); - - return PMINFO_R_OK; -} - -API int pkgmgrinfo_pkginfo_get_usr_list(pkgmgrinfo_pkg_list_cb pkg_list_cb, - void *user_data, uid_t uid) -{ - if (pkg_list_cb == NULL) { - LOGE("invalid parameter"); - return PMINFO_R_EINVAL; - } - - return _pkginfo_get_filtered_foreach_pkginfo(NULL, pkg_list_cb, - user_data, uid); -} - -API int pkgmgrinfo_pkginfo_get_list(pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data) -{ - return pkgmgrinfo_pkginfo_get_usr_list(pkg_list_cb, user_data, _getuid()); -} - static int _pkginfo_get_author(sqlite3 *db, const char *pkgid, GList **author) { @@ -631,192 +448,332 @@ static char *_get_filtered_query(const char *query_raw, return strdup(buf); } -static int _pkginfo_get_package(sqlite3 *db, const char *pkgid, - const char *locale, package_x **package) +static void __free_packages(gpointer data) +{ + pkgmgrinfo_basic_free_package((package_x *)data); +} + +static int _pkginfo_get_packages(uid_t uid, const char *locale, + pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) { static const char query_raw[] = - "SELECT package, package_version, " - "install_location, package_removable, package_preload, " - "package_readonly, package_update, package_appsetting, " - "package_system, package_type, package_size, installed_time, " - "installed_storage, storeclient_id, mainapp_id, package_url, " - "root_path, csc_path, package_nodisplay, package_api_version, " - "package_support_disable, package_tep_name, package_zip_mount_file " - "FROM package_info WHERE package=%Q AND package_disable='false'"; + "SELECT DISTINCT pi.package, pi.package_version, " + "pi.install_location, pi.package_removable, " + "pi.package_preload, pi.package_readonly, pi.package_update, " + "pi.package_appsetting, pi.package_system, pi.package_type, " + "pi.package_size, pi.installed_time, pi.installed_storage, " + "pi.storeclient_id, pi.mainapp_id, pi.package_url, " + "pi.root_path, pi.csc_path, pi.package_nodisplay, " + "pi.package_api_version, pi.package_support_disable, " + "pi.package_tep_name, pi.package_zip_mount_file " + "FROM package_info as pi " + "WHERE pi.package_disable='false'"; int ret; char *query; + const char *dbpath; + sqlite3 *db; sqlite3_stmt *stmt; int idx; package_x *info; - query = sqlite3_mprintf(query_raw, pkgid); - if (query == NULL) { - LOGE("out of memory"); + dbpath = getUserPkgParserDBPathUID(uid); + if (dbpath == NULL) return PMINFO_R_ERROR; - } - ret = sqlite3_prepare_v2(db, query, strlen(query), - &stmt, NULL); - sqlite3_free(query); + ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL); if (ret != SQLITE_OK) { - LOGE("prepare failed: %s", sqlite3_errmsg(db)); + _LOGE("failed to open db: %d", ret); return PMINFO_R_ERROR; } - ret = sqlite3_step(stmt); - if (ret == SQLITE_DONE) { - sqlite3_finalize(stmt); - return PMINFO_R_ENOENT; - } else if (ret != SQLITE_ROW) { - LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); + query = _get_filtered_query(query_raw, filter); + if (query == NULL) { + LOGE("out of memory"); + sqlite3_close_v2(db); return PMINFO_R_ERROR; } - info = calloc(1, sizeof(package_x)); - if (info == NULL) { - LOGE("out of memory"); - sqlite3_finalize(stmt); + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + free(query); + if (ret != SQLITE_OK) { + LOGE("prepare failed: %s", sqlite3_errmsg(db)); + sqlite3_close_v2(db); return PMINFO_R_ERROR; } - idx = 0; - _save_column_str(stmt, idx++, &info->package); - _save_column_str(stmt, idx++, &info->version); - _save_column_str(stmt, idx++, &info->installlocation); - _save_column_str(stmt, idx++, &info->removable); - _save_column_str(stmt, idx++, &info->preload); - _save_column_str(stmt, idx++, &info->readonly); - _save_column_str(stmt, idx++, &info->update); - _save_column_str(stmt, idx++, &info->appsetting); - _save_column_str(stmt, idx++, &info->system); - _save_column_str(stmt, idx++, &info->type); - _save_column_str(stmt, idx++, &info->package_size); - _save_column_str(stmt, idx++, &info->installed_time); - _save_column_str(stmt, idx++, &info->installed_storage); - _save_column_str(stmt, idx++, &info->storeclient_id); - _save_column_str(stmt, idx++, &info->mainapp_id); - _save_column_str(stmt, idx++, &info->package_url); - _save_column_str(stmt, idx++, &info->root_path); - _save_column_str(stmt, idx++, &info->csc_path); - _save_column_str(stmt, idx++, &info->nodisplay_setting); - _save_column_str(stmt, idx++, &info->api_version); - _save_column_str(stmt, idx++, &info->support_disable); - _save_column_str(stmt, idx++, &info->tep_name); - _save_column_str(stmt, idx++, &info->zip_mount_file); - - if (_pkginfo_get_author(db, info->package, &info->author)) { - pkgmgrinfo_basic_free_package(info); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; + + while (sqlite3_step(stmt) == SQLITE_ROW) { + info = calloc(1, sizeof(package_x)); + if (info == NULL) { + LOGE("out of memory"); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + idx = 0; + _save_column_str(stmt, idx++, &info->package); + if (g_hash_table_contains(packages, + (gconstpointer)info->package)) { + free(info->package); + free(info); + continue; + } + _save_column_str(stmt, idx++, &info->version); + _save_column_str(stmt, idx++, &info->installlocation); + _save_column_str(stmt, idx++, &info->removable); + _save_column_str(stmt, idx++, &info->preload); + _save_column_str(stmt, idx++, &info->readonly); + _save_column_str(stmt, idx++, &info->update); + _save_column_str(stmt, idx++, &info->appsetting); + _save_column_str(stmt, idx++, &info->system); + _save_column_str(stmt, idx++, &info->type); + _save_column_str(stmt, idx++, &info->package_size); + _save_column_str(stmt, idx++, &info->installed_time); + _save_column_str(stmt, idx++, &info->installed_storage); + _save_column_str(stmt, idx++, &info->storeclient_id); + _save_column_str(stmt, idx++, &info->mainapp_id); + _save_column_str(stmt, idx++, &info->package_url); + _save_column_str(stmt, idx++, &info->root_path); + _save_column_str(stmt, idx++, &info->csc_path); + _save_column_str(stmt, idx++, &info->nodisplay_setting); + _save_column_str(stmt, idx++, &info->api_version); + _save_column_str(stmt, idx++, &info->support_disable); + _save_column_str(stmt, idx++, &info->tep_name); + _save_column_str(stmt, idx++, &info->zip_mount_file); + info->for_all_users = + strdup((uid != GLOBAL_USER) ? "false" : "true"); + + if (flag & PMINFO_PKGINFO_GET_AUTHOR) { + if (_pkginfo_get_author(db, info->package, + &info->author)) { + pkgmgrinfo_basic_free_package(info); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + } + + if (flag & PMINFO_PKGINFO_GET_LABEL) { + if (_pkginfo_get_label(db, info->package, locale, + &info->label)) { + pkgmgrinfo_basic_free_package(info); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + } + + if (flag & PMINFO_PKGINFO_GET_ICON) { + if (_pkginfo_get_icon(db, info->package, locale, + &info->icon)) { + pkgmgrinfo_basic_free_package(info); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + } + + if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) { + if (_pkginfo_get_description(db, info->package, locale, + &info->description)) { + pkgmgrinfo_basic_free_package(info); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + } + + if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) { + if (_pkginfo_get_privilege(db, info->package, + &info->privileges)) { + pkgmgrinfo_basic_free_package(info); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + return PMINFO_R_ERROR; + } + } + + g_hash_table_insert(packages, (gpointer)info->package, + (gpointer)info); } - if (_pkginfo_get_label(db, info->package, locale, &info->label)) { - pkgmgrinfo_basic_free_package(info); - sqlite3_finalize(stmt); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + + return PMINFO_R_OK; +} + +static int _pkginfo_get_filtered_foreach_pkginfo(uid_t uid, + pkgmgrinfo_filter_x *filter, int flag, + pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data) +{ + int ret; + char *locale; + package_x *pkg; + pkgmgr_pkginfo_x info; + GHashTable *list; + GHashTableIter iter; + gpointer value; + + locale = _get_system_locale(); + if (locale == NULL) return PMINFO_R_ERROR; - } - if (_pkginfo_get_icon(db, info->package, locale, &info->icon)) { - pkgmgrinfo_basic_free_package(info); - sqlite3_finalize(stmt); + list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, + __free_packages); + if (list == NULL) { + free(locale); return PMINFO_R_ERROR; } - if (_pkginfo_get_description(db, info->package, locale, - &info->description)) { - pkgmgrinfo_basic_free_package(info); - sqlite3_finalize(stmt); + ret = _pkginfo_get_packages(uid, locale, filter, flag, list); + if (ret == PMINFO_R_OK && uid != GLOBAL_USER) + ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter, + flag, list); + + if (ret != PMINFO_R_OK) { + g_hash_table_destroy(list); + free(locale); return PMINFO_R_ERROR; } - if (_pkginfo_get_privilege(db, info->package, &info->privileges)) { - pkgmgrinfo_basic_free_package(info); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; + g_hash_table_iter_init(&iter, list); + while (g_hash_table_iter_next(&iter, NULL, &value)) { + pkg = (package_x *)value; + info.uid = uid; + info.pkg_info = pkg; + info.locale = locale; + if (pkg_list_cb(&info, user_data) < 0) + break; } - *package = info; - sqlite3_finalize(stmt); + g_hash_table_destroy(list); + free(locale); return PMINFO_R_OK; } -static int _pkginfo_get_pkginfo(const char *pkgid, uid_t uid, - pkgmgr_pkginfo_x **pkginfo) +API int pkgmgrinfo_pkginfo_get_usr_pkginfo(const char *pkgid, uid_t uid, + pkgmgrinfo_pkginfo_h *handle) { int ret; - sqlite3 *db; - const char *dbpath; char *locale; + GHashTable *list; + pkgmgrinfo_pkginfo_filter_h filter; pkgmgr_pkginfo_x *info; - dbpath = getUserPkgParserDBPathUID(uid); - if (dbpath == NULL) - return PMINFO_R_ERROR; + if (pkgid == NULL || handle == NULL) { + LOGE("invalid parameter"); + return PMINFO_R_EINVAL; + } locale = _get_system_locale(); if (locale == NULL) return PMINFO_R_ERROR; - ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL); - if (ret != SQLITE_OK) { - _LOGE("failed to open db: %d", ret); + ret = pkgmgrinfo_pkginfo_filter_create(&filter); + if (ret != PMINFO_R_OK) { + free(locale); + return ret; + } + + ret = pkgmgrinfo_pkginfo_filter_add_string(filter, + PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_pkginfo_filter_destroy(filter); free(locale); return PMINFO_R_ERROR; } - info = calloc(1, sizeof(pkgmgr_pkginfo_x)); - if (info == NULL) { - _LOGE("out of memory"); + list = g_hash_table_new(g_str_hash, g_str_equal); + if (list == NULL) { + pkgmgrinfo_pkginfo_filter_destroy(filter); free(locale); - sqlite3_close_v2(db); return PMINFO_R_ERROR; } - ret = _pkginfo_get_package(db, pkgid, locale, &info->pkg_info); + ret = _pkginfo_get_packages(uid, locale, NULL, + PMINFO_PKGINFO_GET_ALL, list); + if (!g_hash_table_size(list) && uid != GLOBAL_USER) + ret = _pkginfo_get_packages(GLOBAL_USER, locale, NULL, + PMINFO_PKGINFO_GET_ALL, list); + + pkgmgrinfo_pkginfo_filter_destroy(filter); if (ret != PMINFO_R_OK) { - free(info); + g_hash_table_destroy(list); free(locale); - sqlite3_close_v2(db); return ret; } - info->locale = locale; + if (!g_hash_table_size(list)) { + _LOGI("pkginfo for [%s] is not existed for user [%d]", + pkgid, uid); + g_hash_table_destroy(list); + free(locale); + return PMINFO_R_ENOENT; + } + + info = calloc(1, sizeof(pkgmgr_pkginfo_x)); + if (info == NULL) { + _LOGE("out of memory"); + g_hash_table_destroy(list); + free(locale); + return PMINFO_R_ERROR; + } + info->uid = uid; - info->pkg_info->for_all_users = strdup( - uid != GLOBAL_USER ? "false" : "true"); + info->pkg_info = (package_x *)g_hash_table_lookup(list, pkgid); + info->locale = locale; - *pkginfo = info; + /* just free list only */ + g_hash_table_destroy(list); - sqlite3_close_v2(db); + *handle = info; return ret; } -API int pkgmgrinfo_pkginfo_get_usr_pkginfo(const char *pkgid, uid_t uid, +API int pkgmgrinfo_pkginfo_get_pkginfo(const char *pkgid, pkgmgrinfo_pkginfo_h *handle) { - int ret; + return pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, _getuid(), handle); +} - if (pkgid == NULL || handle == NULL) { +API int pkgmgrinfo_pkginfo_get_usr_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb, + int flag, void *user_data, uid_t uid) +{ + if (pkg_list_cb == NULL) { LOGE("invalid parameter"); return PMINFO_R_EINVAL; } - ret = _pkginfo_get_pkginfo(pkgid, uid, (pkgmgr_pkginfo_x **)handle); - if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER) - ret = _pkginfo_get_pkginfo(pkgid, GLOBAL_USER, - (pkgmgr_pkginfo_x **)handle); + return _pkginfo_get_filtered_foreach_pkginfo(uid, NULL, flag, + pkg_list_cb, user_data); +} - if (ret != PMINFO_R_OK) - _LOGI("pkginfo for [%s] is not existed for user [%d]", pkgid, uid); +API int pkgmgrinfo_pkginfo_get_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb, + int flag, void *user_data) +{ + return pkgmgrinfo_pkginfo_get_usr_list_full(pkg_list_cb, flag, + user_data, _getuid()); +} - return ret; +API int pkgmgrinfo_pkginfo_get_usr_list(pkgmgrinfo_pkg_list_cb pkg_list_cb, + void *user_data, uid_t uid) +{ + if (pkg_list_cb == NULL) { + LOGE("invalid parameter"); + return PMINFO_R_EINVAL; + } + + return _pkginfo_get_filtered_foreach_pkginfo(uid, NULL, + PMINFO_PKGINFO_GET_ALL, pkg_list_cb, user_data); } -API int pkgmgrinfo_pkginfo_get_pkginfo(const char *pkgid, pkgmgrinfo_pkginfo_h *handle) +API int pkgmgrinfo_pkginfo_get_list(pkgmgrinfo_pkg_list_cb pkg_list_cb, + void *user_data) { - return pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, _getuid(), handle); + return pkgmgrinfo_pkginfo_get_usr_list(pkg_list_cb, user_data, + _getuid()); } API int pkgmgrinfo_pkginfo_get_pkgname(pkgmgrinfo_pkginfo_h handle, char **pkg_name) @@ -1892,20 +1849,41 @@ API int pkgmgrinfo_pkginfo_filter_add_string(pkgmgrinfo_pkginfo_filter_h handle, API int pkgmgrinfo_pkginfo_usr_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count, uid_t uid) { int ret; - GList *list = NULL; + char *locale; + GHashTable *list = NULL; if (handle == NULL || count == NULL) { _LOGE("invalid parameter"); return PMINFO_R_EINVAL; } - ret = _pkginfo_get_filtered_list((pkgmgrinfo_filter_x *)handle, uid, &list); - if (ret != PMINFO_R_OK) + locale = _get_system_locale(); + if (locale == NULL) return PMINFO_R_ERROR; - *count = g_list_length(list); + list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, + __free_packages); + if (list == NULL) { + free(locale); + return PMINFO_R_ERROR; + } - g_list_free_full(list, free); + ret = _pkginfo_get_packages(uid, locale, + (pkgmgrinfo_filter_x *)handle, 0, list); + if (ret == PMINFO_R_OK && uid != GLOBAL_USER) + ret = _pkginfo_get_packages(GLOBAL_USER, locale, handle, 0, + list); + + if (ret != PMINFO_R_OK) { + g_hash_table_destroy(list); + free(locale); + return PMINFO_R_ERROR; + } + + *count = g_hash_table_size(list); + + g_hash_table_destroy(list); + free(locale); return PMINFO_R_OK; } @@ -1924,8 +1902,8 @@ API int pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo( return PMINFO_R_EINVAL; } - return _pkginfo_get_filtered_foreach_pkginfo(handle, pkg_cb, user_data, - uid); + return _pkginfo_get_filtered_foreach_pkginfo(uid, handle, + PMINFO_PKGINFO_GET_ALL, pkg_cb, user_data); } API int pkgmgrinfo_pkginfo_filter_foreach_pkginfo(pkgmgrinfo_pkginfo_filter_h handle, diff --git a/src/pkgmgrinfo_private.c b/src/pkgmgrinfo_private.c index c00e0cc..4825227 100644 --- a/src/pkgmgrinfo_private.c +++ b/src/pkgmgrinfo_private.c @@ -119,7 +119,8 @@ static struct _appinfo_bool_map_t appinfo_bool_prop_map[] = { {E_PMINFO_APPINFO_PROP_APP_TASKMANAGE, PMINFO_APPINFO_PROP_APP_TASKMANAGE}, {E_PMINFO_APPINFO_PROP_APP_LAUNCHCONDITION, PMINFO_APPINFO_PROP_APP_LAUNCHCONDITION}, {E_PMINFO_APPINFO_PROP_APP_UI_GADGET, PMINFO_APPINFO_PROP_APP_UI_GADGET}, - {E_PMINFO_APPINFO_PROP_APP_SUPPORT_DISABLE, PMINFO_APPINFO_PROP_APP_SUPPORT_DISABLE} + {E_PMINFO_APPINFO_PROP_APP_SUPPORT_DISABLE, PMINFO_APPINFO_PROP_APP_SUPPORT_DISABLE}, + {E_PMINFO_APPINFO_PROP_APP_DISABLE, PMINFO_APPINFO_PROP_APP_DISABLE} }; inline pkgmgrinfo_pkginfo_filter_prop_str _pminfo_pkginfo_convert_to_prop_str(const char *property) @@ -230,143 +231,155 @@ inline pkgmgrinfo_appinfo_filter_prop_bool _pminfo_appinfo_convert_to_prop_bool( return prop; } -void __get_filter_condition(gpointer data, char **condition) +int __get_filter_condition(gpointer data, char **condition) { pkgmgrinfo_node_x *node = (pkgmgrinfo_node_x*)data; char buf[MAX_QUERY_LEN] = {'\0'}; char temp[PKG_STRING_LEN_MAX] = {'\0'}; + int flag = 0; switch (node->prop) { case E_PMINFO_PKGINFO_PROP_PACKAGE_ID: - snprintf(buf, sizeof(buf), "package_info.package='%s'", node->value); + snprintf(buf, sizeof(buf), "pi.package='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_TYPE: - snprintf(buf, sizeof(buf), "package_info.package_type='%s'", node->value); + snprintf(buf, sizeof(buf), "pi.package_type='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_VERSION: - snprintf(buf, sizeof(buf), "package_info.package_version='%s'", node->value); + snprintf(buf, sizeof(buf), "pi.package_version='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_INSTALL_LOCATION: - snprintf(buf, sizeof(buf), "package_info.install_location='%s'", node->value); + snprintf(buf, sizeof(buf), "pi.install_location='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_INSTALLED_STORAGE: - snprintf(buf, sizeof(buf), "package_info.installed_storage='%s'", node->value); + snprintf(buf, sizeof(buf), "pi.installed_storage='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_AUTHOR_NAME: - snprintf(buf, sizeof(buf), "package_info.author_name='%s'", node->value); + snprintf(buf, sizeof(buf), "pi.author_name='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_AUTHOR_HREF: - snprintf(buf, sizeof(buf), "package_info.author_href='%s'", node->value); + snprintf(buf, sizeof(buf), "pi.author_href='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_AUTHOR_EMAIL: - snprintf(buf, sizeof(buf), "package_info.author_email='%s'", node->value); + snprintf(buf, sizeof(buf), "pi.author_email='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_PRIVILEGE: - snprintf(buf, sizeof(buf), "package_privilege_info.privilege='%s'", node->value); + snprintf(buf, sizeof(buf), "pi.privilege='%s'", node->value); + flag = E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO; break; case E_PMINFO_PKGINFO_PROP_PACKAGE_SIZE: - snprintf(buf, sizeof(buf), "package_info.package_size='%s'", node->value); + snprintf(buf, sizeof(buf), "pi.package_size='%s'", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_REMOVABLE: - snprintf(buf, sizeof(buf), "package_info.package_removable IN %s", node->value); + snprintf(buf, sizeof(buf), "pi.package_removable IN %s", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_PRELOAD: - snprintf(buf, sizeof(buf), "package_info.package_preload IN %s", node->value); + snprintf(buf, sizeof(buf), "pi.package_preload IN %s", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_READONLY: - snprintf(buf, sizeof(buf), "package_info.package_readonly IN %s", node->value); + snprintf(buf, sizeof(buf), "pi.package_readonly IN %s", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_UPDATE: - snprintf(buf, sizeof(buf), "package_info.package_update IN %s", node->value); + snprintf(buf, sizeof(buf), "pi.package_update IN %s", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_APPSETTING: - snprintf(buf, sizeof(buf), "package_info.package_appsetting IN %s", node->value); + snprintf(buf, sizeof(buf), "pi.package_appsetting IN %s", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_NODISPLAY_SETTING: - snprintf(buf, sizeof(buf), "package_info.package_nodisplay IN %s", node->value); + snprintf(buf, sizeof(buf), "pi.package_nodisplay IN %s", node->value); break; case E_PMINFO_PKGINFO_PROP_PACKAGE_SUPPORT_DISABLE: - snprintf(buf, sizeof(buf), "package_info.package_support_disable IN %s", node->value); + snprintf(buf, sizeof(buf), "pi.package_support_disable IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_ID: - snprintf(buf, sizeof(buf), "package_app_info.app_id='%s'", node->value); + snprintf(buf, sizeof(buf), "ai.app_id='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_COMPONENT: - snprintf(buf, sizeof(buf), "package_app_info.app_component='%s'", node->value); + snprintf(buf, sizeof(buf), "ai.app_component='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_EXEC: - snprintf(buf, sizeof(buf), "package_app_info.app_exec='%s'", node->value); + snprintf(buf, sizeof(buf), "ai.app_exec='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_ICON: snprintf(buf, sizeof(buf), "package_app_localized_info.app_icon='%s'", node->value); + flag = E_PMINFO_APPINFO_JOIN_LOCALIZED_INFO; break; case E_PMINFO_APPINFO_PROP_APP_TYPE: - snprintf(buf, sizeof(buf), "package_app_info.app_type='%s'", node->value); + snprintf(buf, sizeof(buf), "ai.app_type='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_OPERATION: snprintf(buf, sizeof(buf), "package_app_app_control.app_control LIKE '%s|%%%%|%%%%'", node->value); + flag = E_PMINFO_APPINFO_JOIN_APP_CONTROL; break; case E_PMINFO_APPINFO_PROP_APP_URI: snprintf(buf, sizeof(buf), "package_app_app_control.app_control LIKE '%%%%|%s|%%%%'", node->value); + flag = E_PMINFO_APPINFO_JOIN_APP_CONTROL; break; case E_PMINFO_APPINFO_PROP_APP_MIME: snprintf(buf, sizeof(buf), "package_app_app_control.app_control LIKE '%%%%|%%%%|%s'", node->value); + flag = E_PMINFO_APPINFO_JOIN_APP_CONTROL; break; case E_PMINFO_APPINFO_PROP_APP_CATEGORY: snprintf(temp, sizeof(temp), "(%s)", node->value); snprintf(buf, sizeof(buf), "package_app_app_category.category IN %s", temp); + flag = E_PMINFO_APPINFO_JOIN_APP_CONTROL; break; case E_PMINFO_APPINFO_PROP_APP_NODISPLAY: - snprintf(buf, sizeof(buf), "package_app_info.app_nodisplay IN %s", node->value); + snprintf(buf, sizeof(buf), "ai.app_nodisplay IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_MULTIPLE: - snprintf(buf, sizeof(buf), "package_app_info.app_multiple IN %s", node->value); + snprintf(buf, sizeof(buf), "ai.app_multiple IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_ONBOOT: - snprintf(buf, sizeof(buf), "package_app_info.app_onboot IN %s", node->value); + snprintf(buf, sizeof(buf), "ai.app_onboot IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_AUTORESTART: - snprintf(buf, sizeof(buf), "package_app_info.app_autorestart IN %s", node->value); + snprintf(buf, sizeof(buf), "ai.app_autorestart IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_TASKMANAGE: - snprintf(buf, sizeof(buf), "package_app_info.app_taskmanage IN %s", node->value); + snprintf(buf, sizeof(buf), "ai.app_taskmanage IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_HWACCELERATION: - snprintf(buf, sizeof(buf), "package_app_info.app_hwacceleration='%s'", node->value); + snprintf(buf, sizeof(buf), "ai.app_hwacceleration='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_SCREENREADER: - snprintf(buf, sizeof(buf), "package_app_info.app_screenreader='%s'", node->value); + snprintf(buf, sizeof(buf), "ai.app_screenreader='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_LAUNCHCONDITION: - snprintf(buf, sizeof(buf), "package_app_info.app_launchcondition IN %s", node->value); + snprintf(buf, sizeof(buf), "ai.app_launchcondition IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_PACKAGE: - snprintf(buf, sizeof(buf), "package_app_info.package='%s'", node->value); + snprintf(buf, sizeof(buf), "ai.package='%s'", node->value); break; case E_PMINFO_APPINFO_PROP_APP_UI_GADGET: - snprintf(buf, sizeof(buf), "package_app_info.app_ui_gadget IN %s", node->value); + snprintf(buf, sizeof(buf), "ai.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); + 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='%s'", node->value); + flag = E_PMINFO_APPINFO_JOIN_METADATA; + break; + case E_PMINFO_APPINFO_PROP_APP_DISABLE: + snprintf(buf, MAX_QUERY_LEN, "ai.app_disable IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_SUPPORT_DISABLE: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_support_disable IN %s", node->value); + snprintf(buf, MAX_QUERY_LEN, "ai.app_support_disable IN %s", node->value); break; case E_PMINFO_APPINFO_PROP_APP_DISABLE_FOR_USER: - snprintf(buf, MAX_QUERY_LEN, "package_app_info.app_id NOT IN " + snprintf(buf, MAX_QUERY_LEN, "ai.app_id NOT IN " "(SELECT app_id from package_app_info_for_uid WHERE uid='%s' " \ "AND is_disabled='true')", node->value); break; default: _LOGE("Invalid Property Type\n"); *condition = NULL; - return; + return 0; } *condition = strdup(buf); - return; + return flag; } char *_get_system_locale(void)