Refactor pkgmgr-info 66/269166/3
authorjh9216.park <jh9216.park@samsung.com>
Tue, 11 Jan 2022 01:08:02 +0000 (20:08 -0500)
committerJunghoon Park <jh9216.park@samsung.com>
Wed, 12 Jan 2022 01:37:09 +0000 (01:37 +0000)
- Use std::vector instead of GHashTable to move application_x data
- Change c code to cpp code

Change-Id: Ibdccf3a216a611266e8c4e7d02f539f92c9b5c4e
Signed-off-by: jh9216.park <jh9216.park@samsung.com>
src/server/appinfo_internal.c [deleted file]
src/server/appinfo_internal.cc [new file with mode: 0644]
src/server/database/appinfo_db_handler.cc
src/server/database/db_handle_provider.cc
src/server/database/db_handle_provider.hh
src/server/pkgmgrinfo_internal.h
src/server/pkgmgrinfo_internal.hh [new file with mode: 0644]

diff --git a/src/server/appinfo_internal.c b/src/server/appinfo_internal.c
deleted file mode 100644 (file)
index d4f8b24..0000000
+++ /dev/null
@@ -1,797 +0,0 @@
-/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <dlfcn.h>
-
-#include <sqlite3.h>
-#include <glib.h>
-
-#include "pkgmgr-info.h"
-#include "pkgmgrinfo_debug.h"
-#include "pkgmgrinfo_private.h"
-#include "pkgmgr_parser.h"
-#include "pkgmgrinfo_internal.h"
-
-static void __parse_appcontrol(GList **appcontrol,
-               char *appcontrol_str, char *visibility, char *id)
-{
-       char *dup;
-       char *token;
-       char *ptr = NULL;
-       appcontrol_x *ac;
-
-       if (appcontrol_str == NULL)
-               return;
-
-       dup = strdup(appcontrol_str);
-       if (dup == NULL) {
-               _LOGE("out of memory");
-               return;
-       }
-
-       do {
-               ac = calloc(1, sizeof(appcontrol_x));
-               if (ac == NULL) {
-                       _LOGE("out of memory");
-                       break;
-               }
-               token = strtok_r(dup, "|", &ptr);
-               if (token && strcmp(token, "NULL"))
-                       ac->operation = strdup(token);
-               token = strtok_r(NULL, "|", &ptr);
-               if (token && strcmp(token, "NULL"))
-                       ac->uri = strdup(token);
-               token = strtok_r(NULL, "|", &ptr);
-               if (token && strcmp(token, "NULL"))
-                       ac->mime = strdup(token);
-               ac->visibility = strdup(visibility);
-               ac->id = strdup(id);
-               *appcontrol = g_list_prepend(*appcontrol, ac);
-       } while ((token = strtok_r(NULL, ";", &ptr)));
-
-       free(dup);
-}
-
-static int _appinfo_get_splashscreens(sqlite3 *db,
-               const char *appid, GList **splashscreens)
-{
-       static const char query_raw[] =
-                       "SELECT src, type, orientation, indicatordisplay, "
-                       "operation, color_depth "
-                       "FROM package_app_splash_screen WHERE app_id=%Q";
-       int ret;
-       char *query;
-       sqlite3_stmt *stmt;
-       int idx;
-       splashscreen_x *info;
-
-       query = sqlite3_mprintf(query_raw, appid);
-       if (query == NULL) {
-               LOGE("out of memory");
-               return PMINFO_R_ERROR;
-       }
-
-       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-       sqlite3_free(query);
-       if (ret != SQLITE_OK) {
-               LOGE("prepare failed: %s", sqlite3_errmsg(db));
-               return PMINFO_R_ERROR;
-       }
-
-       while (sqlite3_step(stmt) == SQLITE_ROW) {
-               info = calloc(1, sizeof(splashscreen_x));
-               if (info == NULL) {
-                       LOGE("out of memory");
-                       sqlite3_finalize(stmt);
-                       return PMINFO_R_ERROR;
-               }
-               idx = 0;
-               _save_column_str(stmt, idx++, &info->src);
-               _save_column_str(stmt, idx++, &info->type);
-               _save_column_str(stmt, idx++, &info->orientation);
-               _save_column_str(stmt, idx++, &info->indicatordisplay);
-               _save_column_str(stmt, idx++, &info->operation);
-               _save_column_str(stmt, idx++, &info->color_depth);
-               *splashscreens = g_list_prepend(*splashscreens, info);
-       }
-
-       sqlite3_finalize(stmt);
-
-       return PMINFO_R_OK;
-}
-
-static int _appinfo_get_metadata(sqlite3 *db,
-               const char *appid, GList **metadata)
-{
-       static const char query_raw[] =
-                       "SELECT md_key, md_value "
-                       "FROM package_app_app_metadata WHERE app_id=%Q";
-       int ret;
-       char *query;
-       sqlite3_stmt *stmt;
-       int idx;
-       metadata_x *info;
-
-       query = sqlite3_mprintf(query_raw, appid);
-       if (query == NULL) {
-               LOGE("out of memory");
-               return PMINFO_R_ERROR;
-       }
-
-       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-       sqlite3_free(query);
-       if (ret != SQLITE_OK) {
-               LOGE("prepare failed: %s", sqlite3_errmsg(db));
-               return PMINFO_R_ERROR;
-       }
-
-       while (sqlite3_step(stmt) == SQLITE_ROW) {
-               info = calloc(1, sizeof(metadata_x));
-               if (info == NULL) {
-                       LOGE("out of memory");
-                       sqlite3_finalize(stmt);
-                       return PMINFO_R_ERROR;
-               }
-               idx = 0;
-               _save_column_str(stmt, idx++, &info->key);
-               _save_column_str(stmt, idx++, &info->value);
-               *metadata = g_list_prepend(*metadata, info);
-       }
-
-       sqlite3_finalize(stmt);
-
-       return PMINFO_R_OK;
-}
-
-static int _appinfo_get_app_control(sqlite3 *db,
-               const char *appid, GList **appcontrol)
-{
-       static const char query_raw[] =
-                       "SELECT app_control, visibility, app_control_id "
-                       "FROM package_app_app_control WHERE app_id=%Q";
-       int ret;
-       int idx;
-       char *query;
-       sqlite3_stmt *stmt;
-       char *str;
-       char *visibility;
-       char *id;
-
-       query = sqlite3_mprintf(query_raw, appid);
-       if (query == NULL) {
-               LOGE("out of memory");
-               return PMINFO_R_ERROR;
-       }
-
-       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-       sqlite3_free(query);
-       if (ret != SQLITE_OK) {
-               LOGE("prepare failed: %s", sqlite3_errmsg(db));
-               return PMINFO_R_ERROR;
-       }
-
-       while (sqlite3_step(stmt) == SQLITE_ROW) {
-               str = NULL;
-               visibility = NULL;
-               id = NULL;
-               idx = 0;
-               _save_column_str(stmt, idx++, &str);
-               _save_column_str(stmt, idx++, &visibility);
-               _save_column_str(stmt, idx++, &id);
-               /* TODO: revise */
-               __parse_appcontrol(appcontrol, str, visibility, id);
-               free(str);
-               free(visibility);
-               free(id);
-       }
-
-       sqlite3_finalize(stmt);
-
-       return PMINFO_R_OK;
-}
-
-static int _appinfo_get_category(sqlite3 *db,
-               const char *appid, GList **category)
-{
-       static const char query_raw[] =
-                       "SELECT category "
-                       "FROM package_app_app_category WHERE app_id=%Q";
-       int ret;
-       char *query;
-       sqlite3_stmt *stmt;
-       char *val;
-
-       query = sqlite3_mprintf(query_raw, appid);
-       if (query == NULL) {
-               LOGE("out of memory");
-               return PMINFO_R_ERROR;
-       }
-
-       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-       sqlite3_free(query);
-       if (ret != SQLITE_OK) {
-               LOGE("prepare failed: %s", sqlite3_errmsg(db));
-               return PMINFO_R_ERROR;
-       }
-
-       while (sqlite3_step(stmt) == SQLITE_ROW) {
-               val = NULL;
-               _save_column_str(stmt, 0, &val);
-               if (val)
-                       *category = g_list_prepend(*category, (gpointer)val);
-       }
-
-       sqlite3_finalize(stmt);
-
-       return PMINFO_R_OK;
-}
-
-static int _appinfo_get_res_control(sqlite3 *db, const char *appid,
-               GList **res_control)
-{
-       static const char query_raw[] =
-               "SELECT res_type, min_res_version, max_res_version, auto_close "
-               "FROM package_app_res_control WHERE app_id=%Q";
-       int ret;
-       char *query;
-       sqlite3_stmt *stmt;
-       int idx;
-       res_control_x *info;
-
-       query = sqlite3_mprintf(query_raw, appid);
-       if (query == NULL) {
-               LOGE("out of memory");
-               return PMINFO_R_ERROR;
-       }
-
-       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-       sqlite3_free(query);
-       if (ret != SQLITE_OK) {
-               LOGE("prepare failed: %s", sqlite3_errmsg(db));
-               return PMINFO_R_ERROR;
-       }
-
-       while (sqlite3_step(stmt) == SQLITE_ROW) {
-               info = calloc(1, sizeof(res_control_x));
-               if (info == NULL) {
-                       LOGE("out of memory");
-                       sqlite3_finalize(stmt);
-                       return PMINFO_R_ERROR;
-               }
-               idx = 0;
-               _save_column_str(stmt, idx++, &info->res_type);
-               _save_column_str(stmt, idx++, &info->min_res_version);
-               _save_column_str(stmt, idx++, &info->max_res_version);
-               _save_column_str(stmt, idx++, &info->auto_close);
-               *res_control = g_list_prepend(*res_control, info);
-       }
-
-       sqlite3_finalize(stmt);
-
-       return PMINFO_R_OK;
-}
-
-static GList *__get_background_category(const char *value)
-{
-       GList *category_list = NULL;
-       int convert_value = 0;
-
-       if (!value || strlen(value) == 0)
-               return NULL;
-
-       convert_value = atoi(value);
-       if (convert_value < 0)
-               return NULL;
-
-       if (convert_value & APP_BG_CATEGORY_USER_DISABLE_TRUE_VAL)
-               category_list = g_list_prepend(category_list,
-                               strdup(APP_BG_CATEGORY_USER_DISABLE_TRUE_STR));
-       else
-               category_list = g_list_prepend(category_list,
-                               strdup(APP_BG_CATEGORY_USER_DISABLE_FALSE_STR));
-
-       if (convert_value & APP_BG_CATEGORY_MEDIA_VAL)
-               category_list = g_list_prepend(category_list,
-                               strdup(APP_BG_CATEGORY_MEDIA_STR));
-
-       if (convert_value & APP_BG_CATEGORY_DOWNLOAD_VAL)
-               category_list = g_list_prepend(category_list,
-                               strdup(APP_BG_CATEGORY_DOWNLOAD_STR));
-
-       if (convert_value & APP_BG_CATEGORY_BGNETWORK_VAL)
-               category_list = g_list_prepend(category_list,
-                               strdup(APP_BG_CATEGORY_BGNETWORK_STR));
-
-       if (convert_value & APP_BG_CATEGORY_LOCATION_VAL)
-               category_list = g_list_prepend(category_list,
-                               strdup(APP_BG_CATEGORY_LOCATION_STR));
-
-       if (convert_value & APP_BG_CATEGORY_SENSOR_VAL)
-               category_list = g_list_prepend(category_list,
-                               strdup(APP_BG_CATEGORY_SENSOR_STR));
-
-       if (convert_value & APP_BG_CATEGORY_IOTCOMM_VAL)
-               category_list = g_list_prepend(category_list,
-                               strdup(APP_BG_CATEGORY_IOTCOMM_STR));
-
-       if (convert_value & APP_BG_CATEGORY_SYSTEM_VAL)
-               category_list = g_list_prepend(category_list,
-                               strdup(APP_BG_CATEGORY_SYSTEM));
-
-       return category_list;
-}
-
-static int __bind_params(sqlite3_stmt *stmt, GList *params)
-{
-       GList *tmp_list = NULL;
-       int idx = 0;
-       int ret;
-
-       if (stmt == NULL || params == NULL)
-               return PMINFO_R_EINVAL;
-
-       tmp_list = params;
-       while (tmp_list) {
-               ret = sqlite3_bind_text(stmt, ++idx,
-                               (char *)tmp_list->data, -1, SQLITE_STATIC);
-               if (ret != SQLITE_OK)
-                       return PMINFO_R_ERROR;
-               tmp_list = tmp_list->next;
-       }
-
-       return PMINFO_R_OK;
-}
-
-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 const char join_privilege[] =
-               " LEFT OUTER JOIN package_privilege_info"
-               " ON ai.package=package_privilege_info.package ";
-
-static int _get_filtered_query(pkgmgrinfo_filter_x *filter, const char *locale,
-               uid_t uid, char **query, GList **bind_params)
-{
-       int joined = 0;
-       int size;
-       char *condition = NULL;
-       char buf[MAX_QUERY_LEN] = {'\0'};
-       char tmp_query[MAX_QUERY_LEN] = {'\0'};
-       GSList *list;
-
-       if (!filter)
-               return PMINFO_R_OK;
-
-       if (g_slist_length(filter->list) == 0) {
-               joined = E_PMINFO_APPINFO_JOIN_LOCALIZED_INFO |
-                       E_PMINFO_APPINFO_JOIN_CATEGORY |
-                       E_PMINFO_APPINFO_JOIN_APP_CONTROL |
-                       E_PMINFO_APPINFO_JOIN_METADATA |
-                       E_PMINFO_APPINFO_JOIN_PRIVILEGE;
-       }
-
-       strncat(buf, " WHERE 1=1", sizeof(buf) - strlen(buf) - 1);
-
-       for (list = filter->list; list; list = list->next) {
-               joined |= __get_filter_condition(list->data,
-                               uid, &condition, bind_params);
-               if (condition == NULL)
-                       continue;
-
-               strncat(buf, " AND ", sizeof(buf) - strlen(buf) - 1);
-
-               strncat(buf, condition, sizeof(buf) - strlen(buf) - 1);
-               free(condition);
-               condition = NULL;
-       }
-
-       if (filter->list_metadata)
-               strncat(buf, " AND (", sizeof(buf) - strlen(buf) - 1);
-       for (list = filter->list_metadata; list; list = list->next) {
-               joined |= __get_metadata_filter_condition(list->data,
-                               &condition, bind_params);
-               if (condition == NULL)
-                       continue;
-               strncat(buf, condition, sizeof(buf) - strlen(buf) - 1);
-               free(condition);
-               condition = NULL;
-
-               strncat(buf, " OR ", sizeof(buf) - strlen(buf) - 1);
-       }
-       if (filter->list_metadata)
-               strncat(buf, "1=0)", sizeof(buf) - strlen(buf) - 1);
-
-       if (joined & E_PMINFO_APPINFO_JOIN_LOCALIZED_INFO) {
-               strncat(tmp_query, join_localized_info,
-                               sizeof(tmp_query) - strlen(tmp_query) - 1);
-               *bind_params = g_list_append(*bind_params, strdup(locale));
-       }
-       if (joined & E_PMINFO_APPINFO_JOIN_CATEGORY)
-               strncat(tmp_query, join_category,
-                               sizeof(tmp_query) - strlen(tmp_query) - 1);
-       if (joined & E_PMINFO_APPINFO_JOIN_APP_CONTROL)
-               strncat(tmp_query, join_app_control,
-                               sizeof(tmp_query) - strlen(tmp_query) - 1);
-       if (joined & E_PMINFO_APPINFO_JOIN_METADATA)
-               strncat(tmp_query, join_metadata,
-                               sizeof(tmp_query) - strlen(tmp_query) - 1);
-       if (joined & E_PMINFO_APPINFO_JOIN_PRIVILEGE)
-               strncat(tmp_query, join_privilege,
-                               sizeof(tmp_query) - strlen(tmp_query) - 1);
-
-       size = strlen(tmp_query) + strlen(buf) + 1;
-       *query = (char *)calloc(1, size);
-       if (*query == NULL)
-               return PMINFO_R_ERROR;
-       snprintf(*query, size, "%s%s", tmp_query, buf);
-
-       return PMINFO_R_OK;
-}
-
-static bool __check_app_storage_status(pkgmgrinfo_filter_x *tmp_filter)
-{
-       GSList *tmp_list = NULL;
-       pkgmgrinfo_node_x *tmp_node = NULL;
-       int property = -1;
-
-       if (tmp_filter == NULL)
-               return true;
-
-       property = _pminfo_appinfo_convert_to_prop_bool(
-                       PMINFO_APPINFO_PROP_APP_CHECK_STORAGE);
-       for (tmp_list = tmp_filter->list; tmp_list != NULL;
-                        tmp_list = g_slist_next(tmp_list)) {
-               tmp_node = (pkgmgrinfo_node_x *)tmp_list->data;
-               if (property == tmp_node->prop) {
-                       if (strcmp(tmp_node->value, "true") == 0)
-                               return true;
-                       else
-                               return false;
-               }
-       }
-
-       return true;
-}
-
-static int _appinfo_get_applications(sqlite3 *db, uid_t db_uid, uid_t uid,
-               const char *locale, pkgmgrinfo_filter_x *filter, int flag,
-               GHashTable *applications)
-{
-       static const char query_raw[] =
-                       "SELECT DISTINCT ai.app_id, ai.app_installed_storage, "
-                       "ai.app_external_path";
-       static const char query_basic[] =
-                       ", 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_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_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.app_tep_name, "
-                       "ai.app_zip_mount_file, ai.component_type, ai.package, "
-                       "ai.app_package_system, ai.app_removable, "
-                       "ai.app_package_installed_time, ai.app_support_mode, "
-                       "ai.app_support_ambient, ai.app_setup_appid";
-       static const char query_uid_info[] =
-                       ", ui.is_disabled, ui.is_splash_screen_enabled";
-       static const char query_label[] =
-                       ", COALESCE("
-                       "(SELECT app_label FROM package_app_localized_info WHERE "
-                       "ai.app_id=app_id AND app_locale=?), "
-                       "(SELECT app_label FROM package_app_localized_info WHERE "
-                       "ai.app_id=app_id AND app_locale='No Locale'))";
-       static const char query_icon[] =
-                       ", COALESCE("
-                       "(SELECT app_icon FROM package_app_localized_info WHERE ai.app_id=app_id "
-                       "AND app_locale=?), "
-                       "(SELECT app_icon FROM package_app_localized_info WHERE ai.app_id=app_id "
-                       "AND app_locale='No Locale'))";
-       static const char query_from_clause[] = " FROM package_app_info as ai";
-       static const char query_uid_info_clause[] =
-                       " LEFT OUTER JOIN package_app_info_for_uid AS ui "
-                       "ON (ai.app_id=ui.app_id AND ui.uid=?)";
-       int ret = PMINFO_R_ERROR;
-       int idx;
-       char *bg_category_str = NULL;
-       char *constraint = NULL;
-       char *tmp_record = NULL;
-       char query[MAX_QUERY_LEN] = {'\0'};
-       char buf[BUFSIZE] = {'\0'};
-       application_x *info = NULL;
-       GList *bind_params = NULL;
-       sqlite3_stmt *stmt = NULL;
-       bool is_check_storage = true;
-       const uid_t global_user_uid = GLOBAL_USER;
-
-       snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
-
-       if (flag & PMINFO_APPINFO_GET_BASICINFO) {
-               strncat(query, query_basic, sizeof(query) - strlen(query) - 1);
-               strncat(query, query_uid_info,
-                               sizeof(query) - strlen(query) - 1);
-       }
-       if (flag & PMINFO_APPINFO_GET_LABEL) {
-               strncat(query, query_label, sizeof(query) - strlen(query) - 1);
-               bind_params = g_list_append(bind_params, strdup(locale));
-       }
-       if (flag & PMINFO_APPINFO_GET_ICON) {
-               strncat(query, query_icon, sizeof(query) - strlen(query) - 1);
-               bind_params = g_list_append(bind_params, strdup(locale));
-       }
-
-       snprintf(buf, MAX_QUERY_LEN - 1, "%d", uid);
-       bind_params = g_list_append(bind_params, strdup(buf));
-
-       is_check_storage = __check_app_storage_status(filter);
-
-       ret = _get_filtered_query(filter, locale,
-                       uid, &constraint, &bind_params);
-       if (ret != PMINFO_R_OK) {
-               LOGE("Failed to get WHERE clause");
-               goto catch;
-       }
-       strncat(query, query_from_clause, sizeof(query) - strlen(query) - 1);
-
-       strncat(query, query_uid_info_clause,
-                       sizeof(query) - strlen(query) - 1);
-
-       if (constraint)
-               strncat(query, constraint, sizeof(query) - strlen(query) - 1);
-
-       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_list_length(bind_params) != 0) {
-               ret = __bind_params(stmt, bind_params);
-               if (ret != SQLITE_OK) {
-                       LOGE("Failed to bind parameters");
-                       goto catch;
-               }
-       }
-
-       while (sqlite3_step(stmt) == SQLITE_ROW) {
-               info = calloc(1, sizeof(application_x));
-               if (info == NULL) {
-                       LOGE("out of memory");
-                       ret = PMINFO_R_ERROR;
-                       goto catch;
-               }
-               info->locale = strdup(locale);
-               if (info->locale == NULL) {
-                       LOGE("Out of memory");
-                       ret = PMINFO_R_ERROR;
-                       goto catch;
-               }
-
-               idx = 0;
-               _save_column_str(stmt, idx++, &info->appid);
-               _save_column_str(stmt, idx++, &info->installed_storage);
-               _save_column_str(stmt, idx++, &info->external_path);
-
-               if (flag & PMINFO_APPINFO_GET_BASICINFO) {
-                       _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->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++, &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->tep_name);
-                       _save_column_str(stmt, idx++, &info->zip_mount_file);
-                       _save_column_str(stmt, idx++, &info->component_type);
-                       _save_column_str(stmt, idx++, &info->package);
-                       _save_column_str(stmt, idx++, &info->package_system);
-                       _save_column_str(stmt, idx++, &info->removable);
-                       _save_column_str(stmt, idx++,
-                                       &info->package_installed_time);
-                       _save_column_str(stmt, idx++, &info->support_mode);
-                       _save_column_str(stmt, idx++, &info->support_ambient);
-                       _save_column_str(stmt, idx++, &info->setup_appid);
-                       info->background_category = __get_background_category(
-                                               bg_category_str);
-                       free(bg_category_str);
-                       bg_category_str = NULL;
-               }
-
-               info->for_all_users =
-                               strdup((db_uid != global_user_uid) ?
-                                               "false" : "true");
-
-               if (db_uid != global_user_uid) {
-                       idx = idx + 2;
-               } else {
-                       tmp_record = NULL;
-                       _save_column_str(stmt, idx++, &tmp_record);
-                       if (tmp_record != NULL) {
-                               if (strcasecmp(info->is_disabled, "false") == 0 &&
-                                               strcasecmp(tmp_record, "false") == 0) {
-                                       free(info->is_disabled);
-                                       info->is_disabled = tmp_record;
-                               } else {
-                                       free(tmp_record);
-                               }
-                       }
-                       tmp_record = NULL;
-                       _save_column_str(stmt, idx++, &tmp_record);
-                       if (tmp_record != NULL) {
-                               if (strcasecmp(info->splash_screen_display, "false") == 0 &&
-                                               strcasecmp(tmp_record, "false") == 0) {
-                                       free(info->splash_screen_display);
-                                       info->splash_screen_display = tmp_record;
-                               } else {
-                                       free(tmp_record);
-                               }
-                       }
-               }
-
-               if (flag & PMINFO_APPINFO_GET_LABEL) {
-                       tmp_record = NULL;
-                       _save_column_str(stmt, idx++, &tmp_record);
-                       if (_add_label_info_into_list(locale, tmp_record,
-                                       &info->label)) {
-                               ret = PMINFO_R_ERROR;
-                               goto catch;
-                       }
-               }
-
-               if (flag & PMINFO_APPINFO_GET_ICON) {
-                       tmp_record = NULL;
-                       _save_column_str(stmt, idx++, &tmp_record);
-                       if (_add_icon_info_into_list(locale, tmp_record,
-                                       &info->icon)) {
-                               ret = PMINFO_R_ERROR;
-                               goto catch;
-                       }
-               }
-
-               if (flag & PMINFO_APPINFO_GET_CATEGORY) {
-                       if (_appinfo_get_category(db, info->appid,
-                                       &info->category)) {
-                               ret = PMINFO_R_ERROR;
-                               goto catch;
-                       }
-               }
-
-               if (flag & PMINFO_APPINFO_GET_APP_CONTROL) {
-                       if (_appinfo_get_app_control(db, info->appid,
-                                       &info->appcontrol)) {
-                               ret = PMINFO_R_ERROR;
-                               goto catch;
-                       }
-               }
-
-               if (flag & PMINFO_APPINFO_GET_METADATA) {
-                       if (_appinfo_get_metadata(db, info->appid,
-                                       &info->metadata)) {
-                               ret = PMINFO_R_ERROR;
-                               goto catch;
-                       }
-               }
-
-               if (flag & PMINFO_APPINFO_GET_SPLASH_SCREEN) {
-                       if (_appinfo_get_splashscreens(db, info->appid,
-                                       &info->splashscreens)) {
-                               ret = PMINFO_R_ERROR;
-                               goto catch;
-                       }
-               }
-
-               if (flag & PMINFO_APPINFO_GET_RES_CONTROL) {
-                       if (_appinfo_get_res_control(db, info->appid,
-                                       &info->res_control)) {
-                               ret = PMINFO_R_ERROR;
-                               goto catch;
-                       }
-               }
-
-               if (is_check_storage &&
-                               __appinfo_check_installed_storage(info) !=
-                                               PMINFO_R_OK) {
-                       ret = PMINFO_R_ERROR;
-                       pkgmgrinfo_basic_free_application(info);
-                       info = NULL;
-                       continue;
-               }
-
-               g_hash_table_insert(applications, (gpointer)info->appid,
-                               (gpointer)info);
-       }
-
-       ret = PMINFO_R_OK;
-
-catch:
-       sqlite3_finalize(stmt);
-
-       if (constraint)
-               free(constraint);
-
-       if (ret != PMINFO_R_OK && info != NULL)
-               pkgmgrinfo_basic_free_application(info);
-
-       g_list_free_full(bind_params, free);
-
-       return ret;
-}
-
-API int appinfo_internal_filter_get_list(sqlite3 *db,
-               pkgmgrinfo_appinfo_filter_h filter, uid_t db_uid, uid_t uid,
-               const char *locale, GHashTable *appinfo_list)
-{
-       int ret;
-
-       if (db == NULL || filter == NULL || appinfo_list == NULL) {
-               LOGE("Invalid argument");
-               return PMINFO_R_EINVAL;
-       }
-
-       ret = _appinfo_get_applications(db, db_uid, uid, locale, filter,
-                       PMINFO_APPINFO_GET_ALL, appinfo_list);
-       return ret;
-}
diff --git a/src/server/appinfo_internal.cc b/src/server/appinfo_internal.cc
new file mode 100644 (file)
index 0000000..44559ee
--- /dev/null
@@ -0,0 +1,795 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <dlfcn.h>
+#include <sqlite3.h>
+#include <glib.h>
+
+#include <memory>
+#include <vector>
+
+#include "pkgmgr-info.h"
+#include "pkgmgrinfo_debug.h"
+#include "pkgmgrinfo_private.h"
+#include "pkgmgr_parser.h"
+#include "pkgmgrinfo_internal.h"
+
+namespace {
+
+void __parse_appcontrol(GList** appcontrol,
+    char* appcontrol_str, char* visibility, char* id) {
+  char* dup;
+  char* token;
+  char* ptr = nullptr;
+  appcontrol_x* ac;
+
+  if (appcontrol_str == nullptr)
+    return;
+
+  dup = strdup(appcontrol_str);
+  if (dup == nullptr) {
+    _LOGE("out of memory");
+    return;
+  }
+
+  do {
+    ac = static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
+    if (ac == nullptr) {
+      _LOGE("out of memory");
+      break;
+    }
+    token = strtok_r(dup, "|", &ptr);
+    if (token && strcmp(token, "NULL"))
+      ac->operation = strdup(token);
+    token = strtok_r(nullptr, "|", &ptr);
+    if (token && strcmp(token, "NULL"))
+      ac->uri = strdup(token);
+    token = strtok_r(nullptr, "|", &ptr);
+    if (token && strcmp(token, "NULL"))
+      ac->mime = strdup(token);
+    ac->visibility = strdup(visibility);
+    ac->id = strdup(id);
+    *appcontrol = g_list_prepend(*appcontrol, ac);
+  } while ((token = strtok_r(nullptr, ";", &ptr)));
+
+  free(dup);
+}
+
+int _appinfo_get_splashscreens(sqlite3* db,
+    const char* appid, GList** splashscreens) {
+  static const char query_raw[] =
+      "SELECT src, type, orientation, indicatordisplay, "
+      "operation, color_depth "
+      "FROM package_app_splash_screen WHERE app_id=%Q";
+  int ret;
+  char* query;
+  sqlite3_stmt* stmt;
+  int idx;
+  splashscreen_x* info;
+
+  query = sqlite3_mprintf(query_raw, appid);
+  if (query == nullptr) {
+    LOGE("out of memory");
+    return PMINFO_R_ERROR;
+  }
+
+  ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, nullptr);
+  sqlite3_free(query);
+  if (ret != SQLITE_OK) {
+    LOGE("prepare failed: %s", sqlite3_errmsg(db));
+    return PMINFO_R_ERROR;
+  }
+
+  while (sqlite3_step(stmt) == SQLITE_ROW) {
+    info = static_cast<splashscreen_x*>(calloc(1, sizeof(splashscreen_x)));
+    if (info == nullptr) {
+      LOGE("out of memory");
+      sqlite3_finalize(stmt);
+      return PMINFO_R_ERROR;
+    }
+    idx = 0;
+    _save_column_str(stmt, idx++, &info->src);
+    _save_column_str(stmt, idx++, &info->type);
+    _save_column_str(stmt, idx++, &info->orientation);
+    _save_column_str(stmt, idx++, &info->indicatordisplay);
+    _save_column_str(stmt, idx++, &info->operation);
+    _save_column_str(stmt, idx++, &info->color_depth);
+    *splashscreens = g_list_prepend(*splashscreens, info);
+  }
+
+  sqlite3_finalize(stmt);
+
+  return PMINFO_R_OK;
+}
+
+int _appinfo_get_metadata(sqlite3* db,
+    const char* appid, GList** metadata) {
+  static const char query_raw[] =
+      "SELECT md_key, md_value "
+      "FROM package_app_app_metadata WHERE app_id=%Q";
+  int ret;
+  char* query;
+  sqlite3_stmt* stmt;
+  int idx;
+  metadata_x* info;
+
+  query = sqlite3_mprintf(query_raw, appid);
+  if (query == nullptr) {
+    LOGE("out of memory");
+    return PMINFO_R_ERROR;
+  }
+
+  ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, nullptr);
+  sqlite3_free(query);
+  if (ret != SQLITE_OK) {
+    LOGE("prepare failed: %s", sqlite3_errmsg(db));
+    return PMINFO_R_ERROR;
+  }
+
+  while (sqlite3_step(stmt) == SQLITE_ROW) {
+    info = static_cast<metadata_x*>(calloc(1, sizeof(metadata_x)));
+    if (info == nullptr) {
+      LOGE("out of memory");
+      sqlite3_finalize(stmt);
+      return PMINFO_R_ERROR;
+    }
+    idx = 0;
+    _save_column_str(stmt, idx++, &info->key);
+    _save_column_str(stmt, idx++, &info->value);
+    *metadata = g_list_prepend(*metadata, info);
+  }
+
+  sqlite3_finalize(stmt);
+
+  return PMINFO_R_OK;
+}
+
+int _appinfo_get_app_control(sqlite3* db,
+    const char* appid, GList** appcontrol) {
+  static const char query_raw[] =
+      "SELECT app_control, visibility, app_control_id "
+      "FROM package_app_app_control WHERE app_id=%Q";
+  int ret;
+  int idx;
+  char *query;
+  sqlite3_stmt *stmt;
+  char *str;
+  char *visibility;
+  char *id;
+
+  query = sqlite3_mprintf(query_raw, appid);
+  if (query == nullptr) {
+    LOGE("out of memory");
+    return PMINFO_R_ERROR;
+  }
+
+  ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, nullptr);
+  sqlite3_free(query);
+  if (ret != SQLITE_OK) {
+    LOGE("prepare failed: %s", sqlite3_errmsg(db));
+    return PMINFO_R_ERROR;
+  }
+
+  while (sqlite3_step(stmt) == SQLITE_ROW) {
+    str = nullptr;
+    visibility = nullptr;
+    id = nullptr;
+    idx = 0;
+    _save_column_str(stmt, idx++, &str);
+    _save_column_str(stmt, idx++, &visibility);
+    _save_column_str(stmt, idx++, &id);
+    /* TODO: revise */
+    __parse_appcontrol(appcontrol, str, visibility, id);
+    free(str);
+    free(visibility);
+    free(id);
+  }
+
+  sqlite3_finalize(stmt);
+
+  return PMINFO_R_OK;
+}
+
+int _appinfo_get_category(sqlite3* db,
+    const char* appid, GList** category) {
+  static const char query_raw[] =
+      "SELECT category "
+      "FROM package_app_app_category WHERE app_id=%Q";
+  int ret;
+  char* query;
+  sqlite3_stmt* stmt;
+  char* val;
+
+  query = sqlite3_mprintf(query_raw, appid);
+  if (query == nullptr) {
+    LOGE("out of memory");
+    return PMINFO_R_ERROR;
+  }
+
+  ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, nullptr);
+  sqlite3_free(query);
+  if (ret != SQLITE_OK) {
+    LOGE("prepare failed: %s", sqlite3_errmsg(db));
+    return PMINFO_R_ERROR;
+  }
+
+  while (sqlite3_step(stmt) == SQLITE_ROW) {
+    val = nullptr;
+    _save_column_str(stmt, 0, &val);
+    if (val)
+      *category = g_list_prepend(*category, (gpointer)val);
+  }
+
+  sqlite3_finalize(stmt);
+
+  return PMINFO_R_OK;
+}
+
+int _appinfo_get_res_control(sqlite3* db, const char* appid,
+    GList** res_control) {
+  static const char query_raw[] =
+    "SELECT res_type, min_res_version, max_res_version, auto_close "
+    "FROM package_app_res_control WHERE app_id=%Q";
+  int ret;
+  char* query;
+  sqlite3_stmt* stmt;
+  int idx;
+  res_control_x* info;
+
+  query = sqlite3_mprintf(query_raw, appid);
+  if (query == nullptr) {
+    LOGE("out of memory");
+    return PMINFO_R_ERROR;
+  }
+
+  ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, nullptr);
+  sqlite3_free(query);
+  if (ret != SQLITE_OK) {
+    LOGE("prepare failed: %s", sqlite3_errmsg(db));
+    return PMINFO_R_ERROR;
+  }
+
+  while (sqlite3_step(stmt) == SQLITE_ROW) {
+    info = static_cast<res_control_x*>(calloc(1, sizeof(res_control_x)));
+    if (info == nullptr) {
+      LOGE("out of memory");
+      sqlite3_finalize(stmt);
+      return PMINFO_R_ERROR;
+    }
+    idx = 0;
+    _save_column_str(stmt, idx++, &info->res_type);
+    _save_column_str(stmt, idx++, &info->min_res_version);
+    _save_column_str(stmt, idx++, &info->max_res_version);
+    _save_column_str(stmt, idx++, &info->auto_close);
+    *res_control = g_list_prepend(*res_control, info);
+  }
+
+  sqlite3_finalize(stmt);
+
+  return PMINFO_R_OK;
+}
+
+GList* __get_background_category(const char* value) {
+  GList* category_list = nullptr;
+  int convert_value = 0;
+
+  if (!value || strlen(value) == 0)
+    return nullptr;
+
+  convert_value = atoi(value);
+  if (convert_value < 0)
+    return nullptr;
+
+  if (convert_value & APP_BG_CATEGORY_USER_DISABLE_TRUE_VAL)
+    category_list = g_list_prepend(category_list,
+        strdup(APP_BG_CATEGORY_USER_DISABLE_TRUE_STR));
+  else
+    category_list = g_list_prepend(category_list,
+        strdup(APP_BG_CATEGORY_USER_DISABLE_FALSE_STR));
+
+  if (convert_value & APP_BG_CATEGORY_MEDIA_VAL)
+    category_list = g_list_prepend(category_list,
+        strdup(APP_BG_CATEGORY_MEDIA_STR));
+
+  if (convert_value & APP_BG_CATEGORY_DOWNLOAD_VAL)
+    category_list = g_list_prepend(category_list,
+        strdup(APP_BG_CATEGORY_DOWNLOAD_STR));
+
+  if (convert_value & APP_BG_CATEGORY_BGNETWORK_VAL)
+    category_list = g_list_prepend(category_list,
+        strdup(APP_BG_CATEGORY_BGNETWORK_STR));
+
+  if (convert_value & APP_BG_CATEGORY_LOCATION_VAL)
+    category_list = g_list_prepend(category_list,
+        strdup(APP_BG_CATEGORY_LOCATION_STR));
+
+  if (convert_value & APP_BG_CATEGORY_SENSOR_VAL)
+    category_list = g_list_prepend(category_list,
+        strdup(APP_BG_CATEGORY_SENSOR_STR));
+
+  if (convert_value & APP_BG_CATEGORY_IOTCOMM_VAL)
+    category_list = g_list_prepend(category_list,
+        strdup(APP_BG_CATEGORY_IOTCOMM_STR));
+
+  if (convert_value & APP_BG_CATEGORY_SYSTEM_VAL)
+    category_list = g_list_prepend(category_list,
+        strdup(APP_BG_CATEGORY_SYSTEM));
+
+  return category_list;
+}
+
+int __bind_params(sqlite3_stmt* stmt, GList* params) {
+  GList* tmp_list = nullptr;
+  int idx = 0;
+  int ret;
+
+  if (stmt == nullptr || params == nullptr)
+    return PMINFO_R_EINVAL;
+
+  tmp_list = params;
+  while (tmp_list) {
+    ret = sqlite3_bind_text(stmt, ++idx,
+        (char*)tmp_list->data, -1, SQLITE_STATIC);
+    if (ret != SQLITE_OK)
+      return PMINFO_R_ERROR;
+    tmp_list = tmp_list->next;
+  }
+
+  return PMINFO_R_OK;
+}
+
+constexpr 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=?";
+constexpr const char join_category[] =
+    " LEFT OUTER JOIN package_app_app_category"
+    " ON ai.app_id=package_app_app_category.app_id";
+constexpr const char join_app_control[] =
+    " LEFT OUTER JOIN package_app_app_control"
+    " ON ai.app_id=package_app_app_control.app_id";
+constexpr const char join_metadata[] =
+    " LEFT OUTER JOIN package_app_app_metadata"
+    " ON ai.app_id=package_app_app_metadata.app_id ";
+constexpr const char join_privilege[] =
+    " LEFT OUTER JOIN package_privilege_info"
+    " ON ai.package=package_privilege_info.package ";
+
+int _get_filtered_query(pkgmgrinfo_filter_x* filter, const char* locale,
+    uid_t uid, char** query, GList** bind_params) {
+  int joined = 0;
+  int size;
+  char* condition = nullptr;
+  char buf[MAX_QUERY_LEN] = {'\0'};
+  char tmp_query[MAX_QUERY_LEN] = {'\0'};
+  GSList* list;
+
+  if (!filter)
+    return PMINFO_R_OK;
+
+  if (g_slist_length(filter->list) == 0) {
+    joined = E_PMINFO_APPINFO_JOIN_LOCALIZED_INFO |
+      E_PMINFO_APPINFO_JOIN_CATEGORY |
+      E_PMINFO_APPINFO_JOIN_APP_CONTROL |
+      E_PMINFO_APPINFO_JOIN_METADATA |
+      E_PMINFO_APPINFO_JOIN_PRIVILEGE;
+  }
+
+  strncat(buf, " WHERE 1=1", sizeof(buf) - strlen(buf) - 1);
+
+  for (list = filter->list; list; list = list->next) {
+    joined |= __get_filter_condition(list->data,
+        uid, &condition, bind_params);
+    if (condition == nullptr)
+      continue;
+
+    strncat(buf, " AND ", sizeof(buf) - strlen(buf) - 1);
+
+    strncat(buf, condition, sizeof(buf) - strlen(buf) - 1);
+    free(condition);
+    condition = nullptr;
+  }
+
+  if (filter->list_metadata)
+    strncat(buf, " AND (", sizeof(buf) - strlen(buf) - 1);
+  for (list = filter->list_metadata; list; list = list->next) {
+    joined |= __get_metadata_filter_condition(list->data,
+        &condition, bind_params);
+    if (condition == nullptr)
+      continue;
+    strncat(buf, condition, sizeof(buf) - strlen(buf) - 1);
+    free(condition);
+    condition = nullptr;
+
+    strncat(buf, " OR ", sizeof(buf) - strlen(buf) - 1);
+  }
+  if (filter->list_metadata)
+    strncat(buf, "1=0)", sizeof(buf) - strlen(buf) - 1);
+
+  if (joined & E_PMINFO_APPINFO_JOIN_LOCALIZED_INFO) {
+    strncat(tmp_query, join_localized_info,
+        sizeof(tmp_query) - strlen(tmp_query) - 1);
+    *bind_params = g_list_append(*bind_params, strdup(locale));
+  }
+  if (joined & E_PMINFO_APPINFO_JOIN_CATEGORY)
+    strncat(tmp_query, join_category,
+        sizeof(tmp_query) - strlen(tmp_query) - 1);
+  if (joined & E_PMINFO_APPINFO_JOIN_APP_CONTROL)
+    strncat(tmp_query, join_app_control,
+        sizeof(tmp_query) - strlen(tmp_query) - 1);
+  if (joined & E_PMINFO_APPINFO_JOIN_METADATA)
+    strncat(tmp_query, join_metadata,
+        sizeof(tmp_query) - strlen(tmp_query) - 1);
+  if (joined & E_PMINFO_APPINFO_JOIN_PRIVILEGE)
+    strncat(tmp_query, join_privilege,
+        sizeof(tmp_query) - strlen(tmp_query) - 1);
+
+  size = strlen(tmp_query) + strlen(buf) + 1;
+  *query = static_cast<char*>(calloc(1, size));
+  if (*query == nullptr)
+    return PMINFO_R_ERROR;
+  snprintf(*query, size, "%s%s", tmp_query, buf);
+
+  return PMINFO_R_OK;
+}
+
+bool __check_app_storage_status(pkgmgrinfo_filter_x* tmp_filter) {
+  GSList* tmp_list = nullptr;
+  pkgmgrinfo_node_x* tmp_node = nullptr;
+  int property = -1;
+
+  if (tmp_filter == nullptr)
+    return true;
+
+  property = _pminfo_appinfo_convert_to_prop_bool(
+      PMINFO_APPINFO_PROP_APP_CHECK_STORAGE);
+  for (tmp_list = tmp_filter->list; tmp_list != nullptr;
+      tmp_list = g_slist_next(tmp_list)) {
+    tmp_node = (pkgmgrinfo_node_x *)tmp_list->data;
+    if (property == tmp_node->prop) {
+      if (strcmp(tmp_node->value, "true") == 0)
+        return true;
+      else
+        return false;
+    }
+  }
+
+  return true;
+}
+
+int _appinfo_get_applications(sqlite3* db, uid_t db_uid, uid_t uid,
+    const char* locale, pkgmgrinfo_filter_x* filter, int flag,
+    std::vector<std::shared_ptr<application_x>>& applications) {
+  static const char query_raw[] =
+      "SELECT DISTINCT ai.app_id, ai.app_installed_storage, "
+      "ai.app_external_path";
+  static const char query_basic[] =
+      ", 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_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_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.app_tep_name, "
+      "ai.app_zip_mount_file, ai.component_type, ai.package, "
+      "ai.app_package_system, ai.app_removable, "
+      "ai.app_package_installed_time, ai.app_support_mode, "
+      "ai.app_support_ambient, ai.app_setup_appid";
+  static const char query_uid_info[] =
+      ", ui.is_disabled, ui.is_splash_screen_enabled";
+  static const char query_label[] =
+      ", COALESCE("
+      "(SELECT app_label FROM package_app_localized_info WHERE "
+      "ai.app_id=app_id AND app_locale=?), "
+      "(SELECT app_label FROM package_app_localized_info WHERE "
+      "ai.app_id=app_id AND app_locale='No Locale'))";
+  static const char query_icon[] =
+      ", COALESCE("
+      "(SELECT app_icon FROM package_app_localized_info WHERE ai.app_id=app_id "
+      "AND app_locale=?), "
+      "(SELECT app_icon FROM package_app_localized_info WHERE ai.app_id=app_id "
+      "AND app_locale='No Locale'))";
+  static const char query_from_clause[] = " FROM package_app_info as ai";
+  static const char query_uid_info_clause[] =
+      " LEFT OUTER JOIN package_app_info_for_uid AS ui "
+      "ON (ai.app_id=ui.app_id AND ui.uid=?)";
+  int ret = PMINFO_R_ERROR;
+  int idx;
+  char* bg_category_str = nullptr;
+  char* constraint = nullptr;
+  char* tmp_record = nullptr;
+  char query[MAX_QUERY_LEN] = {'\0'};
+  char buf[BUFSIZE] = {'\0'};
+  application_x* info = nullptr;
+  GList* bind_params = nullptr;
+  sqlite3_stmt* stmt = nullptr;
+  bool is_check_storage = true;
+  const uid_t global_user_uid = GLOBAL_USER;
+
+  snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
+
+  if (flag & PMINFO_APPINFO_GET_BASICINFO) {
+    strncat(query, query_basic, sizeof(query) - strlen(query) - 1);
+    strncat(query, query_uid_info,
+        sizeof(query) - strlen(query) - 1);
+  }
+  if (flag & PMINFO_APPINFO_GET_LABEL) {
+    strncat(query, query_label, sizeof(query) - strlen(query) - 1);
+    bind_params = g_list_append(bind_params, strdup(locale));
+  }
+  if (flag & PMINFO_APPINFO_GET_ICON) {
+    strncat(query, query_icon, sizeof(query) - strlen(query) - 1);
+    bind_params = g_list_append(bind_params, strdup(locale));
+  }
+
+  snprintf(buf, MAX_QUERY_LEN - 1, "%d", uid);
+  bind_params = g_list_append(bind_params, strdup(buf));
+
+  is_check_storage = __check_app_storage_status(filter);
+
+  ret = _get_filtered_query(filter, locale,
+      uid, &constraint, &bind_params);
+  if (ret != PMINFO_R_OK) {
+    LOGE("Failed to get WHERE clause");
+    goto __catch;
+  }
+  strncat(query, query_from_clause, sizeof(query) - strlen(query) - 1);
+
+  strncat(query, query_uid_info_clause,
+      sizeof(query) - strlen(query) - 1);
+
+  if (constraint)
+    strncat(query, constraint, sizeof(query) - strlen(query) - 1);
+
+  ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, nullptr);
+  if (ret != SQLITE_OK) {
+    LOGE("prepare failed: %s", sqlite3_errmsg(db));
+    ret = PMINFO_R_ERROR;
+    goto __catch;
+  }
+
+  if (g_list_length(bind_params) != 0) {
+    ret = __bind_params(stmt, bind_params);
+    if (ret != SQLITE_OK) {
+      LOGE("Failed to bind parameters");
+      goto __catch;
+    }
+  }
+
+  while (sqlite3_step(stmt) == SQLITE_ROW) {
+    info = static_cast<application_x*>(calloc(1, sizeof(application_x)));
+    if (info == nullptr) {
+      LOGE("out of memory");
+      ret = PMINFO_R_ERROR;
+      goto __catch;
+    }
+    info->locale = strdup(locale);
+    if (info->locale == nullptr) {
+      LOGE("Out of memory");
+      ret = PMINFO_R_ERROR;
+      goto __catch;
+    }
+
+    idx = 0;
+    _save_column_str(stmt, idx++, &info->appid);
+    _save_column_str(stmt, idx++, &info->installed_storage);
+    _save_column_str(stmt, idx++, &info->external_path);
+
+    if (flag & PMINFO_APPINFO_GET_BASICINFO) {
+      _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->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++, &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->tep_name);
+      _save_column_str(stmt, idx++, &info->zip_mount_file);
+      _save_column_str(stmt, idx++, &info->component_type);
+      _save_column_str(stmt, idx++, &info->package);
+      _save_column_str(stmt, idx++, &info->package_system);
+      _save_column_str(stmt, idx++, &info->removable);
+      _save_column_str(stmt, idx++,
+          &info->package_installed_time);
+      _save_column_str(stmt, idx++, &info->support_mode);
+      _save_column_str(stmt, idx++, &info->support_ambient);
+      _save_column_str(stmt, idx++, &info->setup_appid);
+      info->background_category = __get_background_category(
+            bg_category_str);
+      free(bg_category_str);
+      bg_category_str = nullptr;
+    }
+
+    info->for_all_users =
+        strdup((db_uid != global_user_uid) ?
+            "false" : "true");
+
+    if (db_uid != global_user_uid) {
+      idx = idx + 2;
+    } else {
+      tmp_record = nullptr;
+      _save_column_str(stmt, idx++, &tmp_record);
+      if (tmp_record != nullptr) {
+        if (strcasecmp(info->is_disabled, "false") == 0 &&
+            strcasecmp(tmp_record, "false") == 0) {
+          free(info->is_disabled);
+          info->is_disabled = tmp_record;
+        } else {
+          free(tmp_record);
+        }
+      }
+      tmp_record = nullptr;
+      _save_column_str(stmt, idx++, &tmp_record);
+      if (tmp_record != nullptr) {
+        if (strcasecmp(info->splash_screen_display, "false") == 0 &&
+            strcasecmp(tmp_record, "false") == 0) {
+          free(info->splash_screen_display);
+          info->splash_screen_display = tmp_record;
+        } else {
+          free(tmp_record);
+        }
+      }
+    }
+
+    if (flag & PMINFO_APPINFO_GET_LABEL) {
+      tmp_record = nullptr;
+      _save_column_str(stmt, idx++, &tmp_record);
+      if (_add_label_info_into_list(locale, tmp_record,
+          &info->label)) {
+        ret = PMINFO_R_ERROR;
+        goto __catch;
+      }
+    }
+
+    if (flag & PMINFO_APPINFO_GET_ICON) {
+      tmp_record = nullptr;
+      _save_column_str(stmt, idx++, &tmp_record);
+      if (_add_icon_info_into_list(locale, tmp_record,
+          &info->icon)) {
+        ret = PMINFO_R_ERROR;
+        goto __catch;
+      }
+    }
+
+    if (flag & PMINFO_APPINFO_GET_CATEGORY) {
+      if (_appinfo_get_category(db, info->appid,
+          &info->category)) {
+        ret = PMINFO_R_ERROR;
+        goto __catch;
+      }
+    }
+
+    if (flag & PMINFO_APPINFO_GET_APP_CONTROL) {
+      if (_appinfo_get_app_control(db, info->appid,
+          &info->appcontrol)) {
+        ret = PMINFO_R_ERROR;
+        goto __catch;
+      }
+    }
+
+    if (flag & PMINFO_APPINFO_GET_METADATA) {
+      if (_appinfo_get_metadata(db, info->appid,
+          &info->metadata)) {
+        ret = PMINFO_R_ERROR;
+        goto __catch;
+      }
+    }
+
+    if (flag & PMINFO_APPINFO_GET_SPLASH_SCREEN) {
+      if (_appinfo_get_splashscreens(db, info->appid,
+          &info->splashscreens)) {
+        ret = PMINFO_R_ERROR;
+        goto __catch;
+      }
+    }
+
+    if (flag & PMINFO_APPINFO_GET_RES_CONTROL) {
+      if (_appinfo_get_res_control(db, info->appid,
+          &info->res_control)) {
+        ret = PMINFO_R_ERROR;
+        goto __catch;
+      }
+    }
+
+    if (is_check_storage &&
+        __appinfo_check_installed_storage(info) !=
+            PMINFO_R_OK) {
+      ret = PMINFO_R_ERROR;
+      pkgmgrinfo_basic_free_application(info);
+      info = nullptr;
+      continue;
+    }
+
+    applications.emplace_back(info, pkgmgrinfo_basic_free_application);
+  }
+
+  ret = PMINFO_R_OK;
+
+__catch:
+  sqlite3_finalize(stmt);
+
+  if (constraint)
+    free(constraint);
+
+  if (ret != PMINFO_R_OK && info != nullptr)
+    pkgmgrinfo_basic_free_application(info);
+
+  g_list_free_full(bind_params, free);
+
+  return ret;
+}
+
+}  // namespace
+
+namespace pkgmgr_server {
+namespace internal {
+
+API int appinfo_internal_filter_get_list(sqlite3* db,
+    pkgmgrinfo_appinfo_filter_h filter, uid_t db_uid, uid_t uid,
+    const char* locale,
+    std::vector<std::shared_ptr<application_x>>& appinfo_list) {
+  if (db == nullptr || filter == nullptr) {
+    LOGE("Invalid argument");
+    return PMINFO_R_EINVAL;
+  }
+
+  return ::_appinfo_get_applications(db, db_uid, uid, locale,
+      static_cast<pkgmgrinfo_filter_x*>(filter), PMINFO_APPINFO_GET_ALL,
+      appinfo_list);
+}
+
+}  // namesapce internal
+}  // namesapce pkgmgr_server
\ No newline at end of file
index 42195af..31039ef 100644 (file)
 
 #include "pkgmgrinfo_basic.h"
 #include "pkgmgrinfo_internal.h"
-
-namespace {
-
-gboolean _move_func(gpointer key, gpointer value, gpointer user_data) {
-  application_x* info = static_cast<application_x*>(value);
-  std::vector<std::shared_ptr<application_x>>* app_list =
-      static_cast<std::vector<std::shared_ptr<application_x>>*>(user_data);
-  app_list->push_back(
-      std::shared_ptr<application_x>(info, pkgmgrinfo_basic_free_application));
-
-  return true;
-}
-
-}  // namespace
+#include "pkgmgrinfo_internal.hh"
 
 namespace pkgmgr_server {
 namespace database {
@@ -58,25 +45,23 @@ void AppInfoDBHandler::SetFilter(pkgmgrinfo_filter_x* filter) {
 
 int AppInfoDBHandler::GetHandleFromDB(
     std::vector<std::pair<sqlite3*, uid_t>>& conn_list) {
-  GHashTable* list =
-      g_hash_table_new_full(g_str_hash, g_str_equal, nullptr, nullptr);
+  std::vector<std::shared_ptr<application_x>> list;
   int ret = PMINFO_R_OK;
   for (auto& conn : conn_list) {
-    ret = appinfo_internal_filter_get_list(conn.first, filter_, conn.second,
-        uid_, GetLocale().c_str(), list);
+    ret = pkgmgr_server::internal::appinfo_internal_filter_get_list(conn.first,
+        filter_, conn.second, uid_, GetLocale().c_str(), list);
     if (ret == PMINFO_R_ERROR) {
       LOG(DEBUG) << "Failed to appinfo_internal_filter_get_list: " << ret;
       break;
     }
   }
 
-  if (g_hash_table_size(list) == 0)
+  if (list.empty())
     ret = PMINFO_R_ENOENT;
 
   if (ret == PMINFO_R_OK)
-    g_hash_table_foreach_steal(list, _move_func, &handle_list_);
+    handle_list_ = std::move(list);
 
-  g_hash_table_destroy(list);
   return ret;
 }
 
index 39b5150..5b6f7f7 100644 (file)
@@ -32,6 +32,7 @@
 #include "pkgmgr-info.h"
 #include "pkgmgrinfo_debug.h"
 #include "pkgmgrinfo_internal.h"
+#include "pkgmgrinfo_internal.hh"
 #include "pkgmgrinfo_private.h"
 
 #ifdef LOG_TAG
@@ -352,21 +353,16 @@ int DBHandleProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write,
     return ret;
   }
 
-  list = g_hash_table_new(g_str_hash, g_str_equal);
-  ret = appinfo_internal_filter_get_list(db, tmp_filter, uid_, uid,
-                                         locale.c_str(), list);
+  std::vector<std::shared_ptr<application_x>> app_list;
+  ret = pkgmgr_server::internal::appinfo_internal_filter_get_list(db,
+      tmp_filter, uid_, uid, locale.c_str(), app_list);
   free(tmp_filter);
   if (ret == PMINFO_R_OK) {
-    GHashTableIter iter;
-    gpointer value;
-    g_hash_table_iter_init(&iter, list);
-    while (g_hash_table_iter_next(&iter, nullptr, &value)) {
-      auto* app = reinterpret_cast<application_x*>(value);
+    for (auto& app : app_list) {
       app->privileges = pkg_map_[app->package].front()->privileges;
-      AddApplication(app->appid, app);
+      AddApplication(app->appid, std::move(app));
     }
   }
-  g_hash_table_destroy(list);
   released_ = false;
 
   return ret;
@@ -450,11 +446,9 @@ std::vector<std::shared_ptr<application_x>> DBHandleProvider::GetApplications(
   return ret;
 }
 
-void DBHandleProvider::AddApplication(std::string app, application_x* info) {
-  auto ptr =
-      std::shared_ptr<application_x>(info, pkgmgrinfo_basic_free_application);
-  app_map_[app].push_back(ptr);
-  app_map_[""].push_back(std::move(ptr));
+void DBHandleProvider::AddApplication(std::string app, std::shared_ptr<application_x> info) {
+  app_map_[app].push_back(info);
+  app_map_[""].push_back(std::move(info));
 }
 
 void DBHandleProvider::InsertPID(pid_t pid) {
index 9631cf5..7795732 100644 (file)
@@ -68,7 +68,7 @@ class EXPORT_API DBHandleProvider {
   bool IsMemoryDBActive(pid_t pid, bool write);
   void ReleaseCache();
   void AddPackage(std::string package, package_x* info);
-  void AddApplication(std::string app, application_x* info);
+  void AddApplication(std::string app, std::shared_ptr<application_x> info);
   void InsertPID(pid_t pid);
   bool ErasePID(pid_t pid);
 
index f8ddd75..7038cbc 100644 (file)
@@ -89,7 +89,6 @@ do {                                                                           \
 } while (0)
 
 int pkginfo_internal_filter_get_list(sqlite3 *db, pkgmgrinfo_pkginfo_filter_h filter, uid_t uid, const char *locale, GHashTable *list);
-int appinfo_internal_filter_get_list(sqlite3 *db, pkgmgrinfo_appinfo_filter_h filter, uid_t db_uid, uid_t uid, const char *locale, GHashTable *list);
 int certinfo_internal_get(sqlite3 *db, const char *pkgid, uid_t uid, pkgmgrinfo_certinfo_h certinfo);
 int certinfo_internal_set(sqlite3 *db, const char *pkgid, pkgmgrinfo_instcertinfo_h handle, uid_t uid);
 int get_query_result(sqlite3 *db, const char *query, GList *param, GList **list, int *row, int *col);
diff --git a/src/server/pkgmgrinfo_internal.hh b/src/server/pkgmgrinfo_internal.hh
new file mode 100644 (file)
index 0000000..c3cfdd2
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __PKGMGRINFO_INTERNAL_HH__
+#define __PKGMGRINFO_INTERNAL_HH__
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sqlite3.h>
+
+#include <memory>
+#include <vector>
+
+#include "pkgmgr_parser.h"
+#include "pkgmgrinfo_type.h"
+#include "pkgmgr-info.h"
+
+namespace pkgmgr_server {
+namespace internal {
+
+extern API int appinfo_internal_filter_get_list(sqlite3* db,
+    pkgmgrinfo_appinfo_filter_h filter, uid_t db_uid, uid_t uid,
+    const char* locale,
+    std::vector<std::shared_ptr<application_x>>& appinfo_list);
+
+}  // namespace internal
+}  // namespace pkgmgr_server
+
+#endif // __PKGMGRINFO_INTERNAL_HH__