From c55816f64e12a6032e037523673aaf802dfdee55 Mon Sep 17 00:00:00 2001 From: "jh9216.park" Date: Thu, 29 Dec 2022 21:29:38 -0500 Subject: [PATCH] Refactor pkgmgr-info - Use tizen_base::Database - C -> C++ Change-Id: I77ffd89f16f4386cc85ff1031034f42c1a22498d Signed-off-by: jh9216.park --- CMakeLists.txt | 1 + packaging/pkgmgr-info.spec | 1 + src/server/appinfo_internal.cc | 570 ++--- src/server/certinfo_internal.c | 367 ---- src/server/certinfo_internal.cc | 252 +++ src/server/database/abstract_db_handler.cc | 153 +- src/server/database/abstract_db_handler.hh | 7 +- src/server/database/appinfo_db_handler.cc | 10 +- src/server/database/cache_db_handler.cc | 9 +- src/server/database/cert_get_db_handler.cc | 4 +- src/server/database/cert_set_db_handler.cc | 4 +- src/server/database/create_db_handler.cc | 14 +- src/server/database/db_handle_provider.cc | 130 +- src/server/database/db_handle_provider.hh | 23 +- src/server/database/depinfo_db_handler.cc | 15 +- src/server/database/pkg_get_db_handler.cc | 31 +- src/server/database/pkg_set_db_handler.cc | 9 +- src/server/database/query_handler.cc | 79 +- src/server/database/query_handler.hh | 6 +- src/server/database/remove_cache_db_handler.cc | 19 +- src/server/initialize_db_internal.c | 239 --- src/server/initialize_db_internal.cc | 226 ++ src/server/pkginfo_internal.c | 2715 ------------------------ src/server/pkginfo_internal.cc | 2160 +++++++++++++++++++ src/server/pkgmgrinfo_internal.h | 148 +- src/server/pkgmgrinfo_internal.hh | 44 - src/server/sqlite_util_internal.c | 35 - test/unit_tests/CMakeLists.txt | 2 +- test/unit_tests/main.cc | 15 + test/unit_tests/mock/file_mock.c | 62 - test/unit_tests/mock/file_mock.h | 32 - test/unit_tests/test_cert_db_handlers.cc | 56 +- test/unit_tests/test_parcel.cc | 8 +- test/unit_tests/test_parser_db_handlers.cc | 83 +- test/unit_tests/test_query_db_handlers.cc | 69 +- 35 files changed, 3177 insertions(+), 4421 deletions(-) delete mode 100644 src/server/certinfo_internal.c create mode 100644 src/server/certinfo_internal.cc delete mode 100644 src/server/initialize_db_internal.c create mode 100644 src/server/initialize_db_internal.cc delete mode 100644 src/server/pkginfo_internal.c create mode 100644 src/server/pkginfo_internal.cc delete mode 100644 src/server/pkgmgrinfo_internal.hh delete mode 100644 src/server/sqlite_util_internal.c delete mode 100644 test/unit_tests/mock/file_mock.c delete mode 100644 test/unit_tests/mock/file_mock.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ab7f4e3..16a168f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,7 @@ pkg_check_modules(libpkgs_server REQUIRED cynara-session cynara-creds-socket capi-system-resource + tizen-database ) FOREACH(flag ${libpkgs_server_CFLAGS}) diff --git a/packaging/pkgmgr-info.spec b/packaging/pkgmgr-info.spec index b0e1878..87b61ad 100755 --- a/packaging/pkgmgr-info.spec +++ b/packaging/pkgmgr-info.spec @@ -28,6 +28,7 @@ BuildRequires: pkgconfig(cynara-client-async) BuildRequires: pkgconfig(cynara-session) BuildRequires: pkgconfig(cynara-creds-socket) BuildRequires: pkgconfig(capi-system-resource) +BuildRequires: pkgconfig(tizen-database) %if 0%{?gcov:1} BuildRequires: lcov diff --git a/src/server/appinfo_internal.cc b/src/server/appinfo_internal.cc index 488e623..7469b75 100644 --- a/src/server/appinfo_internal.cc +++ b/src/server/appinfo_internal.cc @@ -36,8 +36,16 @@ namespace { -void __parse_appcontrol(GList** appcontrol, - char* appcontrol_str, char* visibility, char* id) { +char* GetCString(int idx, const tizen_base::Database::Result::Record& rec) { + std::optional str = rec.GetString(idx); + if (!str) + return nullptr; + + return strdup(str->c_str()); +} + +void ParseAppControl(GList** appcontrol, + const char* appcontrol_str, const char* visibility, const char* id) { char* dup; char* token; char* ptr = nullptr; @@ -75,217 +83,142 @@ void __parse_appcontrol(GList** appcontrol, free(dup); } -int _appinfo_get_splashscreens(sqlite3* db, +int GetSplashScreens(const tizen_base::Database& db, const char* appid, GList** splashscreens) { - static const char query_raw[] = + auto q = tizen_base::Database::Sql( "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; - } + "FROM package_app_splash_screen WHERE app_id=?") + .Bind(appid); - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, nullptr); - sqlite3_free(query); - if (ret != SQLITE_OK) { - LOGE("prepare failed: %s", sqlite3_errmsg(db)); + auto r = db.Exec(q); + if (!r) { + _LOGE("db.Exec() failed: %s", static_cast(r)); return PMINFO_R_ERROR; } - while (sqlite3_step(stmt) == SQLITE_ROW) { - info = static_cast(calloc(1, sizeof(splashscreen_x))); + for (const auto& rec : r) { + splashscreen_x* info = static_cast( + 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); + + int idx = 0; + info->src = GetCString(idx++, rec); + info->type = GetCString(idx++, rec); + info->orientation = GetCString(idx++, rec); + info->indicatordisplay = GetCString(idx++, rec); + info->operation = GetCString(idx++, rec); + info->color_depth = GetCString(idx++, rec); *splashscreens = g_list_prepend(*splashscreens, info); } - sqlite3_finalize(stmt); - return PMINFO_R_OK; } -int _appinfo_get_metadata(sqlite3* db, +int GetMetadata(const tizen_base::Database& db, const char* appid, GList** metadata) { - static const char query_raw[] = + auto q = tizen_base::Database::Sql( "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; - } + "FROM package_app_app_metadata WHERE app_id=?") + .Bind(appid); - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, nullptr); - sqlite3_free(query); - if (ret != SQLITE_OK) { - LOGE("prepare failed: %s", sqlite3_errmsg(db)); + auto r = db.Exec(q); + if (!r) { + _LOGE("db.Exec() failed: %s", static_cast(r)); return PMINFO_R_ERROR; } - while (sqlite3_step(stmt) == SQLITE_ROW) { - info = static_cast(calloc(1, sizeof(metadata_x))); + for (const auto& rec : r) { + metadata_x* info = static_cast( + 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); + + int idx = 0; + info->key = GetCString(idx++, rec); + info->value = GetCString(idx++, rec); *metadata = g_list_prepend(*metadata, info); } - sqlite3_finalize(stmt); - return PMINFO_R_OK; } -int _appinfo_get_app_control(sqlite3* db, +int GetAppControl(const tizen_base::Database& db, const char* appid, GList** appcontrol) { - static const char query_raw[] = + auto q = tizen_base::Database::Sql( "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; - } + "FROM package_app_app_control WHERE app_id=?") + .Bind(appid); - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, nullptr); - sqlite3_free(query); - if (ret != SQLITE_OK) { - LOGE("prepare failed: %s", sqlite3_errmsg(db)); + auto r = db.Exec(q); + if (!r) { + _LOGE("db.Exec() failed: %s", static_cast(r)); 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); + for (const auto& rec : r) { + ParseAppControl(appcontrol, rec.GetString(0)->c_str(), + rec.GetString(1)->c_str(), rec.GetString(2)->c_str()); } - sqlite3_finalize(stmt); - return PMINFO_R_OK; } -int _appinfo_get_category(sqlite3* db, +int GetCategory(const tizen_base::Database& db, const char* appid, GList** category) { - static const char query_raw[] = + auto q = tizen_base::Database::Sql( "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)); + "FROM package_app_app_category WHERE app_id=?") + .Bind(appid); + auto r = db.Exec(q); + if (!r) { + _LOGE("db.Exec() failed: %s", static_cast(r)); return PMINFO_R_ERROR; } - while (sqlite3_step(stmt) == SQLITE_ROW) { - val = nullptr; - _save_column_str(stmt, 0, &val); + for (const auto& rec : r) { + char* val = GetCString(0, rec); 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, +int GetResControl(const tizen_base::Database& 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"); + auto q = tizen_base::Database::Sql( + "SELECT res_type, min_res_version, max_res_version, auto_close " + "FROM package_app_res_control WHERE app_id=?") + .Bind(appid); + + auto r = db.Exec(q); + if (!r) { + _LOGE("db.Exec() failed: %s", static_cast(r)); 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(calloc(1, sizeof(res_control_x))); + for (const auto& rec : r) { + res_control_x* info = static_cast( + 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); + + int idx = 0; + info->res_type = GetCString(idx++, rec); + info->min_res_version = GetCString(idx++, rec); + info->max_res_version = GetCString(idx++, rec); + info->auto_close = GetCString(idx++, rec); *res_control = g_list_prepend(*res_control, info); } - sqlite3_finalize(stmt); - return PMINFO_R_OK; } @@ -338,26 +271,6 @@ GList* __get_background_category(const char* value) { 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" @@ -375,15 +288,10 @@ 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 GetFilteredQuery(pkgmgrinfo_filter_x* filter, const char* locale, + uid_t uid, std::string& query, std::list& bind_params) { int joined = 0; - int size; char* condition = nullptr; - char buf[MAX_QUERY_LEN] = {'\0'}; - char tmp_query[MAX_QUERY_LEN] = {'\0'}; - GList* tmp_params = NULL; - GSList* list; if (!filter) return PMINFO_R_OK; @@ -396,61 +304,56 @@ int _get_filtered_query(pkgmgrinfo_filter_x* filter, const char* locale, E_PMINFO_APPINFO_JOIN_PRIVILEGE; } - strncat(buf, " WHERE 1=1", sizeof(buf) - strlen(buf) - 1); - - for (list = filter->list; list; list = list->next) { + std::string buf = " WHERE 1=1"; + GList* tmp_params = nullptr; + for (GSList* list = filter->list; list; list = list->next) { joined |= __get_filter_condition(list->data, uid, &condition, &tmp_params); if (condition == nullptr) continue; - strncat(buf, " AND ", sizeof(buf) - strlen(buf) - 1); - - strncat(buf, condition, sizeof(buf) - strlen(buf) - 1); + buf += " AND "; + buf += condition; 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) { + buf += " AND ("; + for (GSList* list = filter->list_metadata; list; list = list->next) { joined |= __get_metadata_filter_condition(list->data, &condition, &tmp_params); if (condition == nullptr) continue; - strncat(buf, condition, sizeof(buf) - strlen(buf) - 1); + buf += condition; free(condition); condition = nullptr; - - strncat(buf, " OR ", sizeof(buf) - strlen(buf) - 1); + buf += " OR "; } + if (filter->list_metadata) - strncat(buf, "1=0)", sizeof(buf) - strlen(buf) - 1); + buf += "1=0)"; + std::string tmp_query; 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)); + tmp_query += join_localized_info; + bind_params.push_back(locale); } + if (joined & E_PMINFO_APPINFO_JOIN_CATEGORY) - strncat(tmp_query, join_category, - sizeof(tmp_query) - strlen(tmp_query) - 1); + tmp_query += join_category; if (joined & E_PMINFO_APPINFO_JOIN_APP_CONTROL) - strncat(tmp_query, join_app_control, - sizeof(tmp_query) - strlen(tmp_query) - 1); + tmp_query += join_app_control; if (joined & E_PMINFO_APPINFO_JOIN_METADATA) - strncat(tmp_query, join_metadata, - sizeof(tmp_query) - strlen(tmp_query) - 1); + tmp_query += join_metadata; if (joined & E_PMINFO_APPINFO_JOIN_PRIVILEGE) - strncat(tmp_query, join_privilege, - sizeof(tmp_query) - strlen(tmp_query) - 1); + tmp_query += join_privilege; - *bind_params = g_list_concat(*bind_params, tmp_params); - size = strlen(tmp_query) + strlen(buf) + 1; - *query = static_cast(calloc(1, size)); - if (*query == nullptr) - return PMINFO_R_ERROR; - snprintf(*query, size, "%s%s", tmp_query, buf); + for (GList* l = tmp_params; l != nullptr; l = l->next) + bind_params.push_back(reinterpret_cast(l->data)); + + query = tmp_query + buf; + g_list_free_full(tmp_params, free); return PMINFO_R_OK; } @@ -482,7 +385,7 @@ bool __check_app_storage_status(pkgmgrinfo_filter_x* tmp_filter) { return true; } -int _appinfo_get_applications(sqlite3* db, uid_t db_uid, uid_t uid, +int DoGetAppInfo(const tizen_base::Database& db, uid_t db_uid, uid_t uid, const char* locale, pkgmgrinfo_filter_x* filter, int flag, std::vector>& applications) { static const char query_raw[] = @@ -524,139 +427,121 @@ int _appinfo_get_applications(sqlite3* db, uid_t db_uid, uid_t uid, 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; + std::list bind_params; bool is_check_storage = true; const uid_t global_user_uid = GLOBAL_USER; - - snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw); + std::string query = 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); + query += query_basic; + query += query_uid_info; } + if (flag & PMINFO_APPINFO_GET_LABEL) { - strncat(query, query_label, sizeof(query) - strlen(query) - 1); - bind_params = g_list_append(bind_params, strdup(locale)); + query += query_label; + bind_params.push_back(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)); + query += query_icon; + bind_params.push_back(locale); } - snprintf(buf, MAX_QUERY_LEN - 1, "%d", uid); - bind_params = g_list_append(bind_params, strdup(buf)); - + bind_params.push_back(std::to_string(uid)); is_check_storage = __check_app_storage_status(filter); - ret = _get_filtered_query(filter, locale, - uid, &constraint, &bind_params); + std::string constraint; + int ret = GetFilteredQuery(filter, locale, uid, constraint, bind_params); if (ret != PMINFO_R_OK) { LOGE("Failed to get WHERE clause"); - goto __catch; + return PMINFO_R_ERROR; } - strncat(query, query_from_clause, sizeof(query) - strlen(query) - 1); - strncat(query, query_uid_info_clause, - sizeof(query) - strlen(query) - 1); + query += query_from_clause; + query += query_uid_info_clause; - if (constraint) - strncat(query, constraint, sizeof(query) - strlen(query) - 1); + if (!constraint.empty()) + query += constraint; - 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; - } + auto q = tizen_base::Database::Sql(query); + for (auto& i : bind_params) + q.Bind(std::move(i)); - if (g_list_length(bind_params) != 0) { - ret = __bind_params(stmt, bind_params); - if (ret != SQLITE_OK) { - LOGE("Failed to bind parameters"); - goto __catch; - } + auto r = db.Exec(q); + if (!r) { + _LOGE("db.Exec() failed: %s", static_cast(r)); + return PMINFO_R_ERROR; } - while (sqlite3_step(stmt) == SQLITE_ROW) { - info = static_cast(calloc(1, sizeof(application_x))); + for (const auto& rec : r) { + application_x* info = static_cast( + calloc(1, sizeof(application_x))); if (info == nullptr) { LOGE("out of memory"); - ret = PMINFO_R_ERROR; - goto __catch; + return PMINFO_R_ERROR; } + std::shared_ptr info_auto(info, + pkgmgrinfo_basic_free_application); + info->locale = strdup(locale); if (info->locale == nullptr) { LOGE("Out of memory"); - ret = PMINFO_R_ERROR; - goto __catch; + return PMINFO_R_ERROR; } - 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); - + int idx = 0; + info->appid = GetCString(idx++, rec); + info->installed_storage = GetCString(idx++, rec); + info->external_path = GetCString(idx++, rec); 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); - _save_column_str(stmt, idx++, &info->light_user_switch_mode); + info->component = GetCString(idx++, rec); + info->exec = GetCString(idx++, rec); + info->nodisplay = GetCString(idx++, rec); + info->type = GetCString(idx++, rec); + info->onboot = GetCString(idx++, rec); + info->multiple = GetCString(idx++, rec); + info->autorestart = GetCString(idx++, rec); + info->taskmanage = GetCString(idx++, rec); + info->hwacceleration = GetCString(idx++, rec); + info->screenreader = GetCString(idx++, rec); + info->mainapp = GetCString(idx++, rec); + info->recentimage = GetCString(idx++, rec); + info->launchcondition = GetCString(idx++, rec); + info->indicatordisplay = GetCString(idx++, rec); + info->portraitimg = GetCString(idx++, rec); + info->landscapeimg = GetCString(idx++, rec); + info->guestmode_visibility = GetCString(idx++, rec); + info->permission_type = GetCString(idx++, rec); + info->preload = GetCString(idx++, rec); + info->submode = GetCString(idx++, rec); + info->submode_mainid = GetCString(idx++, rec); + info->launch_mode = GetCString(idx++, rec); + info->ui_gadget = GetCString(idx++, rec); + info->support_disable = GetCString(idx++, rec); + info->process_pool = GetCString(idx++, rec); + bg_category_str = GetCString(idx++, rec); + info->package_type = GetCString(idx++, rec); + info->root_path = GetCString(idx++, rec); + info->api_version = GetCString(idx++, rec); + info->effective_appid = GetCString(idx++, rec); + info->is_disabled = GetCString(idx++, rec); + info->splash_screen_display = GetCString(idx++, rec); + info->tep_name = GetCString(idx++, rec); + info->zip_mount_file = GetCString(idx++, rec); + info->component_type = GetCString(idx++, rec); + info->package = GetCString(idx++, rec); + info->package_system = GetCString(idx++, rec); + info->removable = GetCString(idx++, rec); + info->package_installed_time = GetCString(idx++, rec); + info->support_mode = GetCString(idx++, rec); + info->support_ambient = GetCString(idx++, rec); + info->setup_appid = GetCString(idx++, rec); + info->light_user_switch_mode = GetCString(idx++, rec); info->background_category = __get_background_category( bg_category_str); free(bg_category_str); - bg_category_str = nullptr; } info->for_all_users = @@ -666,8 +551,7 @@ int _appinfo_get_applications(sqlite3* db, uid_t db_uid, uid_t uid, if (db_uid != global_user_uid) { idx = idx + 2; } else { - tmp_record = nullptr; - _save_column_str(stmt, idx++, &tmp_record); + tmp_record = GetCString(idx++, rec); if (tmp_record != nullptr) { if (strcasecmp(info->is_disabled, "false") == 0 && strcasecmp(tmp_record, "false") == 0) { @@ -677,8 +561,7 @@ int _appinfo_get_applications(sqlite3* db, uid_t db_uid, uid_t uid, free(tmp_record); } } - tmp_record = nullptr; - _save_column_str(stmt, idx++, &tmp_record); + tmp_record = GetCString(idx++, rec); if (tmp_record != nullptr) { if (strcasecmp(info->splash_screen_display, "false") == 0 && strcasecmp(tmp_record, "false") == 0) { @@ -691,91 +574,56 @@ int _appinfo_get_applications(sqlite3* db, uid_t db_uid, uid_t uid, } if (flag & PMINFO_APPINFO_GET_LABEL) { - tmp_record = nullptr; - _save_column_str(stmt, idx++, &tmp_record); + tmp_record = GetCString(idx++, rec); if (_add_label_info_into_list(locale, tmp_record, &info->label)) { - ret = PMINFO_R_ERROR; - goto __catch; + return PMINFO_R_ERROR; } } if (flag & PMINFO_APPINFO_GET_ICON) { - tmp_record = nullptr; - _save_column_str(stmt, idx++, &tmp_record); + tmp_record = GetCString(idx++, rec); if (_add_icon_info_into_list(locale, tmp_record, &info->icon)) { - ret = PMINFO_R_ERROR; - goto __catch; + return PMINFO_R_ERROR; } } if (flag & PMINFO_APPINFO_GET_CATEGORY) { - if (_appinfo_get_category(db, info->appid, - &info->category)) { - ret = PMINFO_R_ERROR; - goto __catch; - } + if (GetCategory(db, info->appid, &info->category)) + return PMINFO_R_ERROR; } if (flag & PMINFO_APPINFO_GET_APP_CONTROL) { - if (_appinfo_get_app_control(db, info->appid, - &info->appcontrol)) { - ret = PMINFO_R_ERROR; - goto __catch; - } + if (GetAppControl(db, info->appid, &info->appcontrol)) + return PMINFO_R_ERROR; } if (flag & PMINFO_APPINFO_GET_METADATA) { - if (_appinfo_get_metadata(db, info->appid, - &info->metadata)) { - ret = PMINFO_R_ERROR; - goto __catch; - } + if (GetMetadata(db, info->appid, &info->metadata)) + return PMINFO_R_ERROR; } if (flag & PMINFO_APPINFO_GET_SPLASH_SCREEN) { - if (_appinfo_get_splashscreens(db, info->appid, - &info->splashscreens)) { - ret = PMINFO_R_ERROR; - goto __catch; - } + if (GetSplashScreens(db, info->appid, &info->splashscreens)) + return PMINFO_R_ERROR; } 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 (GetResControl(db, info->appid, &info->res_control)) + return PMINFO_R_ERROR; } 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); + applications.push_back(std::move(info_auto)); } - 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; + return PMINFO_R_OK; } } // namespace @@ -783,20 +631,20 @@ __catch: namespace pkgmgr_server { namespace internal { -API bool check_app_storage_status(pkgmgrinfo_filter_x* tmp_filter) { +API bool CheckAppStorageStatus(pkgmgrinfo_filter_x* tmp_filter) { return ::__check_app_storage_status(tmp_filter); } -API int appinfo_internal_filter_get_list(sqlite3* db, +API int GetAppInfo(const tizen_base::Database& db, pkgmgrinfo_appinfo_filter_h filter, uid_t db_uid, uid_t uid, - const char* locale, + const std::string& locale, std::vector>& appinfo_list) { - if (db == nullptr || filter == nullptr) { + if (!static_cast(db) || filter == nullptr) { LOGE("Invalid argument"); return PMINFO_R_EINVAL; } - return ::_appinfo_get_applications(db, db_uid, uid, locale, + return ::DoGetAppInfo(db, db_uid, uid, locale.c_str(), static_cast(filter), PMINFO_APPINFO_GET_ALL, appinfo_list); } diff --git a/src/server/certinfo_internal.c b/src/server/certinfo_internal.c deleted file mode 100644 index 549f39b..0000000 --- a/src/server/certinfo_internal.c +++ /dev/null @@ -1,367 +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. - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "pkgmgrinfo_basic.h" -#include "pkgmgrinfo_private.h" -#include "pkgmgrinfo_internal.h" -#include "pkgmgrinfo_debug.h" -#include "pkgmgr-info.h" - -static int _pkginfo_get_cert(sqlite3 *db, int cert_id[], char *cert_info[]) -{ - static const char query[] = - "SELECT cert_info " - "FROM package_cert_index_info WHERE cert_id=?"; - int ret; - sqlite3_stmt *stmt; - int i; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return PMINFO_R_ERROR; - } - - for (i = 0; i < MAX_CERT_TYPE; i++) { - ret = sqlite3_bind_int(stmt, 1, cert_id[i]); - if (ret != SQLITE_OK) { - sqlite3_finalize(stmt); - _LOGE("bind failed: %s", sqlite3_errmsg(db)); - return PMINFO_R_ERROR; - } - - ret = sqlite3_step(stmt); - if (ret == SQLITE_DONE) { - sqlite3_reset(stmt); - sqlite3_clear_bindings(stmt); - continue; - } else if (ret != SQLITE_ROW) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - - _save_column_str(stmt, 0, &cert_info[i]); - sqlite3_reset(stmt); - sqlite3_clear_bindings(stmt); - } - - sqlite3_finalize(stmt); - - return PMINFO_R_OK; -} - -static int _pkginfo_get_certid(sqlite3 *db, const char *pkgid, int cert_id[]) -{ - static const char query[] = - "SELECT author_root_cert, author_im_cert, " - "author_signer_cert, dist_root_cert, " - "dist_im_cert, dist_signer_cert, dist2_root_cert, " - "dist2_im_cert, dist2_signer_cert " - "FROM package_cert_info WHERE package=?"; - int ret; - sqlite3_stmt *stmt; - int idx; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return PMINFO_R_ERROR; - } - - ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC); - if (ret != SQLITE_OK) { - _LOGE("bind failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - 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); - return PMINFO_R_ERROR; - } - - idx = 0; - _save_column_int(stmt, idx++, &cert_id[PMINFO_AUTHOR_ROOT_CERT]); - _save_column_int(stmt, idx++, - &cert_id[PMINFO_AUTHOR_INTERMEDIATE_CERT]); - _save_column_int(stmt, idx++, &cert_id[PMINFO_AUTHOR_SIGNER_CERT]); - _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR_ROOT_CERT]); - _save_column_int(stmt, idx++, - &cert_id[PMINFO_DISTRIBUTOR_INTERMEDIATE_CERT]); - _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR_SIGNER_CERT]); - _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR2_ROOT_CERT]); - _save_column_int(stmt, idx++, - &cert_id[PMINFO_DISTRIBUTOR2_INTERMEDIATE_CERT]); - _save_column_int(stmt, idx++, - &cert_id[PMINFO_DISTRIBUTOR2_SIGNER_CERT]); - - sqlite3_finalize(stmt); - - return PMINFO_R_OK; -} - -static int _pkginfo_get_certinfo(sqlite3 *db, - const char *pkgid, pkgmgr_certinfo_x *info) -{ - int ret; - - ret = _pkginfo_get_certid(db, pkgid, info->cert_id); - if (ret != PMINFO_R_OK) - return ret; - - ret = _pkginfo_get_cert(db, info->cert_id, info->cert_info); - if (ret != PMINFO_R_OK) - return ret; - - return PMINFO_R_OK; -} - -API int certinfo_internal_get(sqlite3 *db, const char *pkgid, uid_t uid, - pkgmgrinfo_certinfo_h certinfo) -{ - int ret; - pkgmgr_certinfo_x *info = (pkgmgr_certinfo_x *)certinfo; - - if (db == NULL || pkgid == NULL || certinfo == NULL) - return PMINFO_R_EINVAL; - ret = _pkginfo_get_certinfo(db, pkgid, info); - if (ret != PMINFO_R_OK) - _LOGE("failed to get certinfo of %s ", pkgid); - - return ret; -} - -static int _pkginfo_save_cert_index_info(sqlite3 *db, char *cert_info[]) -{ - static const char query[] = - "INSERT OR REPLACE INTO package_cert_index_info " - "(cert_info, cert_id, cert_ref_count) " - "VALUES ( " - " ?, " - " (SELECT cert_id FROM package_cert_index_info " - " WHERE cert_info=?), " - " COALESCE( " - " ((SELECT cert_ref_count FROM package_cert_index_info " - " WHERE cert_info=?) + 1), 1))"; - int ret; - sqlite3_stmt *stmt; - int i; - int idx; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare error: %s", sqlite3_errmsg(db)); - return PMINFO_R_ERROR; - } - - for (i = 0; i < MAX_CERT_TYPE; i++) { - if (cert_info[i] == NULL) - continue; - idx = 1; - ret = sqlite3_bind_text(stmt, idx++, - cert_info[i], -1, SQLITE_STATIC); - if (ret != SQLITE_OK) { - _LOGE("bind failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - ret = sqlite3_bind_text(stmt, idx++, - cert_info[i], -1, SQLITE_STATIC); - if (ret != SQLITE_OK) { - _LOGE("bind failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - ret = sqlite3_bind_text(stmt, idx++, - cert_info[i], -1, SQLITE_STATIC); - if (ret != SQLITE_OK) { - _LOGE("bind failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - - sqlite3_reset(stmt); - sqlite3_clear_bindings(stmt); - } - - sqlite3_finalize(stmt); - - return PMINFO_R_OK; -} - -static int _pkginfo_save_cert_info(sqlite3 *db, - const char *pkgid, char *cert_info[]) -{ - static const char query_insert[] = - "INSERT INTO package_cert_info (package, package_count," - " author_root_cert, author_im_cert, author_signer_cert," - " dist_root_cert, dist_im_cert, dist_signer_cert," - " dist2_root_cert, dist2_im_cert, dist2_signer_cert) " - "VALUES(?, 1," - " (SELECT cert_id FROM package_cert_index_info" - " WHERE cert_info=?)," - " (SELECT cert_id FROM package_cert_index_info" - " WHERE cert_info=?)," - " (SELECT cert_id FROM package_cert_index_info" - " WHERE cert_info=?)," - " (SELECT cert_id FROM package_cert_index_info" - " WHERE cert_info=?)," - " (SELECT cert_id FROM package_cert_index_info" - " WHERE cert_info=?)," - " (SELECT cert_id FROM package_cert_index_info" - " WHERE cert_info=?)," - " (SELECT cert_id FROM package_cert_index_info" - " WHERE cert_info=?)," - " (SELECT cert_id FROM package_cert_index_info" - " WHERE cert_info=?)," - " (SELECT cert_id FROM package_cert_index_info" - " WHERE cert_info=?))"; - static const char query_update[] = - "UPDATE package_cert_info " - "SET package_count = package_count + 1 " - "WHERE package=?"; - int ret; - sqlite3_stmt *stmt; - int i; - int idx; - - ret = sqlite3_prepare_v2(db, query_insert, - strlen(query_insert), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare error: %s", sqlite3_errmsg(db)); - return PMINFO_R_ERROR; - } - - idx = 1; - ret = sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_STATIC); - if (ret != SQLITE_OK) { - _LOGE("bind failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - - for (i = 0; i < MAX_CERT_TYPE; i++) { - if (sqlite3_bind_text(stmt, idx++, - cert_info[i], -1, SQLITE_STATIC)) { - _LOGE("bind error: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - } - - ret = sqlite3_step(stmt); - sqlite3_finalize(stmt); - if (ret == SQLITE_CONSTRAINT) { - ret = sqlite3_prepare_v2(db, query_update, - strlen(query_update), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare error: %s", sqlite3_errmsg(db)); - return PMINFO_R_ERROR; - } - - if (sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC)) { - _LOGE("bind error: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - - ret = sqlite3_step(stmt); - sqlite3_finalize(stmt); - } - - if (ret != SQLITE_DONE) { - _LOGE("step error: %s", sqlite3_errmsg(db)); - return PMINFO_R_ERROR; - } - - return PMINFO_R_OK; -} - -API int certinfo_internal_set(sqlite3 *db, const char *pkgid, - pkgmgrinfo_instcertinfo_h handle, uid_t uid) -{ - int ret; - pkgmgr_certinfo_x *info = (pkgmgr_certinfo_x *)handle; - - if (db == NULL || pkgid == NULL || handle == NULL) { - _LOGE("invalid parameter"); - return PMINFO_R_EINVAL; - } - - ret = sqlite3_exec(db, "BEGIN DEFERRED", NULL, NULL, NULL); - if (ret != SQLITE_OK) { - _LOGE("failed to begin transaction"); - return PMINFO_R_ERROR; - } - - if (_pkginfo_save_cert_index_info(db, info->cert_info)) { - _LOGE("failed to save cert index info, rollback now"); - ret = sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL); - if (ret != SQLITE_OK) - LOGE("Rollback is failed. error(%s)", - sqlite3_errmsg(db)); - return PMINFO_R_ERROR; - } - - if (_pkginfo_save_cert_info(db, pkgid, info->cert_info)) { - _LOGE("failed to save cert info, rollback now"); - ret = sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL); - if (ret != SQLITE_OK) - LOGE("Rollback is failed. error(%s)", - sqlite3_errmsg(db)); - return PMINFO_R_ERROR; - } - - ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL); - if (ret != SQLITE_OK) { - _LOGE("failed to commit transaction, rollback now"); - ret = sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL); - if (ret != SQLITE_OK) - LOGE("Rollback is failed. error(%s)", - sqlite3_errmsg(db)); - return PMINFO_R_ERROR; - } - - - return PMINFO_R_OK; -} diff --git a/src/server/certinfo_internal.cc b/src/server/certinfo_internal.cc new file mode 100644 index 0000000..833e126 --- /dev/null +++ b/src/server/certinfo_internal.cc @@ -0,0 +1,252 @@ +/* +* Copyright (c) 2023 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "pkgmgrinfo_basic.h" +#include "pkgmgrinfo_private.h" +#include "pkgmgrinfo_internal.h" +#include "pkgmgrinfo_debug.h" +#include "pkgmgr-info.h" + +namespace { + +int GetCertInfo(const tizen_base::Database& db, int cert_id[], + char* cert_info[]) { + auto q = tizen_base::Database::Sql( + "SELECT cert_info " + "FROM package_cert_index_info WHERE cert_id=?"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return PMINFO_R_ERROR; + } + + for (int i = 0; i < MAX_CERT_TYPE; i++) { + q.Reset().Bind(cert_id[i]); + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed: %s", static_cast(r)); + return PMINFO_R_ERROR; + } + + auto rec = r.GetFirstRecord(); + if (!rec) + continue; + std::string str = static_cast(rec->Get(0)); + cert_info[i] = strdup(str.c_str()); + } + + return PMINFO_R_OK; +} + +int GetCertId(const tizen_base::Database& db, + std::string_view pkgid, int (&cert_id)[MAX_CERT_TYPE]) { + auto q = tizen_base::Database::Sql( + "SELECT author_root_cert, author_im_cert, " + "author_signer_cert, dist_root_cert, " + "dist_im_cert, dist_signer_cert, dist2_root_cert, " + "dist2_im_cert, dist2_signer_cert " + "FROM package_cert_info WHERE package=?") + .Bind(std::string(pkgid)); + + auto r = db.Exec(q); + if (!r) { + _LOGE("Exec failed: %s", static_cast(r)); + return PMINFO_R_ERROR; + } + + auto rec = r.GetFirstRecord(); + if (!rec) + return PMINFO_R_ERROR; + + for (int i = 0; i < MAX_CERT_TYPE; i++) { + std::optional id = rec->Get(i); + if (!id) + cert_id[i] = 0; + else + cert_id[i] = *id; + } + + return PMINFO_R_OK; +} + +int GetCert(const tizen_base::Database& db, + std::string_view pkgid, pkgmgr_certinfo_x* info) { + int ret; + + ret = GetCertId(db, pkgid, info->cert_id); + if (ret != PMINFO_R_OK) + return ret; + + ret = GetCertInfo(db, info->cert_id, info->cert_info); + if (ret != PMINFO_R_OK) + return ret; + + return PMINFO_R_OK; +} + +int SaveCertIndex(const tizen_base::Database& db, + char* cert_info[]) { + auto q = tizen_base::Database::Sql( + "INSERT OR REPLACE INTO package_cert_index_info " + "(cert_info, cert_id, cert_ref_count) " + "VALUES ( " + " ?, " + " (SELECT cert_id FROM package_cert_index_info " + " WHERE cert_info=?), " + " COALESCE( " + " ((SELECT cert_ref_count FROM package_cert_index_info " + " WHERE cert_info=?) + 1), 1))"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return PMINFO_R_ERROR; + } + + for (int i = 0; i < MAX_CERT_TYPE; i++) { + if (cert_info[i] == nullptr) + continue; + q.Reset() + .Bind(cert_info[i]) + .Bind(cert_info[i]) + .Bind(cert_info[i]); + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed: %s", static_cast(r)); + return PMINFO_R_ERROR; + } + } + + return PMINFO_R_OK; +} + +int SaveCertInfo(const tizen_base::Database& db, + std::string_view pkgid, char* cert_info[]) { + auto q_insert = tizen_base::Database::Sql( + "INSERT INTO package_cert_info (package, package_count," + " author_root_cert, author_im_cert, author_signer_cert," + " dist_root_cert, dist_im_cert, dist_signer_cert," + " dist2_root_cert, dist2_im_cert, dist2_signer_cert) " + "VALUES(?, 1," + " (SELECT cert_id FROM package_cert_index_info" + " WHERE cert_info=?)," + " (SELECT cert_id FROM package_cert_index_info" + " WHERE cert_info=?)," + " (SELECT cert_id FROM package_cert_index_info" + " WHERE cert_info=?)," + " (SELECT cert_id FROM package_cert_index_info" + " WHERE cert_info=?)," + " (SELECT cert_id FROM package_cert_index_info" + " WHERE cert_info=?)," + " (SELECT cert_id FROM package_cert_index_info" + " WHERE cert_info=?)," + " (SELECT cert_id FROM package_cert_index_info" + " WHERE cert_info=?)," + " (SELECT cert_id FROM package_cert_index_info" + " WHERE cert_info=?)," + " (SELECT cert_id FROM package_cert_index_info" + " WHERE cert_info=?))") + .Bind(std::string(pkgid)); + + for (int i = 0; i < MAX_CERT_TYPE; i++) + q_insert.Bind(cert_info[i]); + + int code = static_cast(db.Exec(q_insert)); + if (code == SQLITE_CONSTRAINT) { + auto q_update = tizen_base::Database::Sql( + "UPDATE package_cert_info " + "SET package_count = package_count + 1 " + "WHERE package=?") + .Bind(std::string(pkgid)); + auto r = db.Exec(q_update); + if (!r) { + _LOGE("error: %s", static_cast(r)); + return PMINFO_R_ERROR; + } + } else if (code != SQLITE_DONE) { + return PMINFO_R_ERROR; + } + + return PMINFO_R_OK; +} + +} // namespace + +namespace pkgmgr_server::internal { + +int CertInfoGet(const tizen_base::Database& db, + std::string_view pkgid, uid_t uid, pkgmgrinfo_certinfo_h certinfo) { + pkgmgr_certinfo_x* info = static_cast(certinfo); + + if (pkgid.empty() || certinfo == nullptr) + return PMINFO_R_EINVAL; + + int ret; + try { + ret = GetCert(db, pkgid, info); + if (ret != PMINFO_R_OK) + _LOGE("failed to get certinfo of %s ", pkgid.data()); + } catch (const tizen_base::DbException& e) { + _LOGE("Exception: %s", e.msg()); + return PMINFO_R_ERROR; + } + + return ret; +} + +int CertInfoSet(const tizen_base::Database& db, + std::string_view pkgid, pkgmgrinfo_instcertinfo_h handle, uid_t uid) { + pkgmgr_certinfo_x* info = static_cast(handle); + + if (pkgid.empty() || handle == nullptr) { + _LOGE("invalid parameter"); + return PMINFO_R_EINVAL; + } + + try { + auto guard = db.CreateTransactionGuard(); + + if (SaveCertIndex(db, info->cert_info)) { + _LOGE("failed to save cert index info, rollback now"); + return PMINFO_R_ERROR; + } + + if (SaveCertInfo(db, pkgid, info->cert_info)) { + _LOGE("failed to save cert info, rollback now"); + return PMINFO_R_ERROR; + } + + guard.Commit(); + } catch (const tizen_base::DbException& e) { + _LOGE("Exception: %s", e.msg()); + return PMINFO_R_ERROR; + } + + return PMINFO_R_OK; +} + +} // namespace pkgmgr_server::internal diff --git a/src/server/database/abstract_db_handler.cc b/src/server/database/abstract_db_handler.cc index 05500cd..92b96c5 100644 --- a/src/server/database/abstract_db_handler.cc +++ b/src/server/database/abstract_db_handler.cc @@ -26,6 +26,7 @@ #include #include +#include #include "db_handle_provider.hh" #include "utils/logging.hh" @@ -38,34 +39,20 @@ namespace { constexpr useconds_t BUSY_WAITING_USEC = (1000000 / 10 / 2); /* 0.05 sec */ constexpr int BUSY_WAITING_MAX = 100; /* wait for max 5 sec */ -int __readdb_busy_handler(void *data, int count) { +bool ReadDbBusyHandler(int count) { if (count < BUSY_WAITING_MAX) { usleep(BUSY_WAITING_USEC); - return 1; + return true; } else { - /* sqlite3_prepare_v2 will return SQLITE_BUSY */ - return 0; + return false; } } -int __open_read_db(const char *path, sqlite3 **db) { - int ret; - - ret = sqlite3_open_v2(path, db, - SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, NULL); - if (ret != SQLITE_OK) { - sqlite3_close_v2(*db); - return ret; - } - - ret = sqlite3_busy_handler(*db, __readdb_busy_handler, NULL); - if (ret != SQLITE_OK) { - LOG(ERROR) << "failed to register busy handler:" << sqlite3_errmsg(*db); - sqlite3_close_v2(*db); - return ret; - } +tizen_base::Database OpenReadDb(const std::string& path) { + tizen_base::Database db(path.c_str(), SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, + ReadDbBusyHandler); - return ret; + return db; } constexpr const char RESOURCED_BUS_NAME[] = "org.tizen.resourced"; @@ -73,73 +60,36 @@ constexpr const char RESOURCED_PROC_PATH[] = "/Org/Tizen/ResourceD/Process"; constexpr const char RESOURCED_PROC_INTERFACE[] = "org.tizen.resourced.process"; constexpr const char RESOURCED_PROC_METHOD[] = "ProcExclude"; -int __writedb_busy_handler(void *data, int count) { +bool WriteDbBusyHandler(int count) { if (count < (BUSY_WAITING_MAX / 2)) { usleep(BUSY_WAITING_USEC); - return 1; + return true; } else if (count < BUSY_WAITING_MAX) { usleep(BUSY_WAITING_USEC); - return 1; + return true; } else { - /* sqlite3_prepare_v2 will return SQLITE_BUSY */ - return 0; + return false; } } -int __open_write_db(uid_t uid, const char* path, - sqlite3** db) { - int ret; - - ret = sqlite3_open_v2(path, db, SQLITE_OPEN_READWRITE, NULL); - if (ret != SQLITE_OK) { - sqlite3_close_v2(*db); - return ret; - } - - ret = sqlite3_busy_handler(*db, __writedb_busy_handler, - reinterpret_cast(const_cast(path))); - if (ret != SQLITE_OK) { - LOG(ERROR) << "failed to register busy handler:" << sqlite3_errmsg(*db); - sqlite3_close_v2(*db); - return ret; - } - - ret = sqlite3_exec(*db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL); - if (ret != SQLITE_OK) { - LOG(ERROR) << "failed to enable foreign key support:" - << sqlite3_errmsg(*db); - sqlite3_close_v2(*db); - return ret; - } +tizen_base::Database OpenWriteDb(uid_t uid, const std::string& path) { + tizen_base::Database db(path.c_str(), SQLITE_OPEN_READWRITE, + WriteDbBusyHandler); + db.OneStepExec({ "PRAGMA foreign_keys=ON" }); - return ret; + return db; } -int __open_create_db(uid_t uid, const char* path, - sqlite3** db) { - int ret; +tizen_base::Database OpenCreateDb(uid_t uid, const std::string& path) { + tizen_base::Database db(path.c_str(), SQLITE_OPEN_READWRITE | + SQLITE_OPEN_CREATE, WriteDbBusyHandler); - ret = sqlite3_open_v2(path, db, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); - if (ret != SQLITE_OK) { - sqlite3_close_v2(*db); - return ret; - } - - ret = sqlite3_busy_handler(*db, __writedb_busy_handler, - reinterpret_cast(const_cast(path))); - if (ret != SQLITE_OK) { - LOG(ERROR) << "failed to register busy handler:" << sqlite3_errmsg(*db); - sqlite3_close_v2(*db); - return ret; - } - - return ret; + return db; } -static uid_t globaluser_uid = -1; - uid_t ConvertUID(uid_t uid) { + static uid_t globaluser_uid = -1; + if (uid < REGULAR_USER) { if (globaluser_uid == (uid_t)-1) globaluser_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); @@ -157,10 +107,7 @@ namespace database { std::shared_mutex AbstractDBHandler::lock_; -AbstractDBHandler::~AbstractDBHandler() { - for (auto& db_handle : db_handle_list_) - sqlite3_close_v2(db_handle.first); -} +AbstractDBHandler::~AbstractDBHandler() = default; std::vector> AbstractDBHandler::GetDBPath() { std::vector> db_path; @@ -184,44 +131,42 @@ bool AbstractDBHandler::Connect() { } auto dbpath_list = GetDBPath(); - sqlite3* db; - for (auto& dbpath : dbpath_list) { - int ret = 0; - if (op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_READ) { - ret = __open_read_db(dbpath.first.c_str(), &db); - } else if ( - op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE) { - if (ConvertUID(dbpath.second) != ConvertUID(uid_)) - continue; - ret = __open_write_db(uid_, dbpath.first.c_str(), &db); - } else { - if (ConvertUID(dbpath.second) != ConvertUID(uid_)) - continue; - - if (access(dbpath.first.c_str(), F_OK) != -1) { - LOG(ERROR) << "Database for user " << uid_ << " is already exists"; - return false; + + try { + for (const auto& [path, uid] : dbpath_list) { + if (op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_READ) { + db_handle_list_.emplace_back(OpenReadDb(path), uid); + } else if ( + op_type_ == pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE) { + if (ConvertUID(uid) != ConvertUID(uid_)) + continue; + db_handle_list_.emplace_back(OpenWriteDb(uid_, path), uid); + } else { + if (ConvertUID(uid) != ConvertUID(uid_)) + continue; + + if (access(path.c_str(), F_OK) != -1) { + LOG(ERROR) << "Database for user " << uid_ << " is already exists"; + return false; + } + + db_handle_list_.emplace_back(OpenCreateDb(uid_, path), uid); } - ret = __open_create_db(uid_, dbpath.first.c_str(), &db); } - - if (ret != SQLITE_OK) - return false; - - db_handle_list_.emplace_back(std::make_pair(db, dbpath.second)); + } catch (const tizen_base::DbException& e) { + LOG(ERROR) << e.msg(); + return false; } return true; } void AbstractDBHandler::ClearDBHandle() { - for (const auto& db_handle : db_handle_list_) - sqlite3_close_v2(db_handle.first); - db_handle_list_.clear(); } -std::vector> AbstractDBHandler::GetConnection() { +const std::vector>& + AbstractDBHandler::GetConnection() { return db_handle_list_; } diff --git a/src/server/database/abstract_db_handler.hh b/src/server/database/abstract_db_handler.hh index 6377b52..c9d2680 100644 --- a/src/server/database/abstract_db_handler.hh +++ b/src/server/database/abstract_db_handler.hh @@ -24,6 +24,7 @@ #include #include +#include #include "db_type.hh" #include "query_parcelable.hh" @@ -49,14 +50,16 @@ class EXPORT_API AbstractDBHandler { protected: virtual bool Connect(); + virtual const std::vector>& + GetConnection(); int GetPID(); uid_t GetUID(); std::vector> GetDBPath(); - virtual std::vector> GetConnection(); void ClearDBHandle(); const std::string& GetLocale(); static uid_t GetDefaultUser(); + protected: static std::shared_mutex lock_; private: @@ -65,7 +68,7 @@ class EXPORT_API AbstractDBHandler { uid_t uid_; pid_t pid_; std::string locale_; - std::vector> db_handle_list_; + std::vector> db_handle_list_; }; } // namespace database diff --git a/src/server/database/appinfo_db_handler.cc b/src/server/database/appinfo_db_handler.cc index de4dcb3..d6b373e 100644 --- a/src/server/database/appinfo_db_handler.cc +++ b/src/server/database/appinfo_db_handler.cc @@ -25,7 +25,6 @@ #include "pkgmgrinfo_basic.h" #include "pkgmgrinfo_internal.h" -#include "pkgmgrinfo_internal.hh" namespace { @@ -62,14 +61,13 @@ int AppInfoDBHandler::GetHandleFromDB() { return PMINFO_R_ERROR; } - std::vector> conn_list = GetConnection(); + const auto& conn_list = GetConnection(); std::vector> list; int ret = PMINFO_R_OK; - for (auto& conn : conn_list) { - ret = pkgmgr_server::internal::appinfo_internal_filter_get_list(conn.first, - filter_, conn.second, uid_, GetLocale().c_str(), list); + for (const auto& [db, uid] : conn_list) { + ret = internal::GetAppInfo(db, filter_, uid, uid_, GetLocale(), list); if (ret == PMINFO_R_ERROR) { - LOG(DEBUG) << "Failed to appinfo_internal_filter_get_list: " << ret; + LOG(DEBUG) << "Failed to GetAppInfo: " << ret; break; } } diff --git a/src/server/database/cache_db_handler.cc b/src/server/database/cache_db_handler.cc index aacdbd5..af61c81 100644 --- a/src/server/database/cache_db_handler.cc +++ b/src/server/database/cache_db_handler.cc @@ -36,18 +36,17 @@ int CacheDBHandler::Execute() { SetOpType(pkgmgr_common::DBOperationType::OPERATION_TYPE_READ); SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB); - std::vector> conn_list; if (!Connect()) { CacheFlag::SetStatus(CacheFlag::Status::UNPREPARED); return PMINFO_R_ERROR; } - conn_list = GetConnection(); + const auto& conn_list = GetConnection(); auto lock = CacheFlag::GetWriterLock(); int ret = PMINFO_R_OK; - for (auto& conn : conn_list) { - ret = DBHandleProvider::GetInst(conn.second) - .UpdateCache(conn.first, GetPID(), uid_, false, GetLocale()); + for (const auto& [db, uid] : conn_list) { + ret = DBHandleProvider::GetInst(uid) + .UpdateCache(db, GetPID(), uid_, false, GetLocale()); if (ret != PMINFO_R_OK) { LOG(ERROR) << "Failed to update pkginfo cache : " << ret; break; diff --git a/src/server/database/cert_get_db_handler.cc b/src/server/database/cert_get_db_handler.cc index 881b84c..397795f 100644 --- a/src/server/database/cert_get_db_handler.cc +++ b/src/server/database/cert_get_db_handler.cc @@ -57,9 +57,9 @@ int CertGetDBHandler::Execute() { return ret; handle_ = reinterpret_cast(handle); - sqlite3* conn = GetConnection().front().first; + const auto& db = GetConnection().front().first; - return certinfo_internal_get(conn, pkgid_.c_str(), uid_, handle_); + return internal::CertInfoGet(db, pkgid_, uid_, handle_); } } // namespace database diff --git a/src/server/database/cert_set_db_handler.cc b/src/server/database/cert_set_db_handler.cc index 97babdf..bd0144c 100644 --- a/src/server/database/cert_set_db_handler.cc +++ b/src/server/database/cert_set_db_handler.cc @@ -46,9 +46,9 @@ int CertSetDBHandler::Execute() { if (!is_offline_) DBHandleProvider::GetInst(uid_).SetMemoryMode(GetPID()); - sqlite3* conn = GetConnection().front().first; + const auto& db = GetConnection().front().first; - return certinfo_internal_set(conn, handle_->pkgid, handle_, uid_); + return internal::CertInfoSet(db, handle_->pkgid, handle_, uid_); } } // namespace database diff --git a/src/server/database/create_db_handler.cc b/src/server/database/create_db_handler.cc index 1e9a657..7ef265e 100644 --- a/src/server/database/create_db_handler.cc +++ b/src/server/database/create_db_handler.cc @@ -66,11 +66,8 @@ int CreateDBHandler::CreateParserDB() { if (!Connect()) return PMINFO_R_ERROR; - std::vector> conn_list = GetConnection(); - sqlite3* conn = conn_list.front().first; - uid_t uid = conn_list.front().second; - - return pkgmgr_parser_internal_initialize_db(conn, uid); + const auto& [db, uid] = GetConnection().front(); + return internal::InitializeDb(db, uid); } int CreateDBHandler::CreateCertDB() { @@ -83,11 +80,8 @@ int CreateDBHandler::CreateCertDB() { if (!Connect()) return PMINFO_R_ERROR; - std::vector> conn_list = GetConnection(); - sqlite3* conn = conn_list.front().first; - uid_t uid = conn_list.front().second; - - return pkgmgr_parser_internal_initialize_db(conn, uid); + const auto& [db, uid] = GetConnection().front(); + return internal::InitializeDb(db, uid); } } // namespace database diff --git a/src/server/database/db_handle_provider.cc b/src/server/database/db_handle_provider.cc index 79a0312..0ee999d 100644 --- a/src/server/database/db_handle_provider.cc +++ b/src/server/database/db_handle_provider.cc @@ -33,7 +33,6 @@ #include "pkgmgr-info.h" #include "pkgmgrinfo_debug.h" #include "pkgmgrinfo_internal.h" -#include "pkgmgrinfo_internal.hh" #include "pkgmgrinfo_private.h" #ifdef LOG_TAG @@ -337,14 +336,14 @@ bool DBHandleProvider::IsWriter(pid_t pid) { return writer_pid_list_.find(pid) != writer_pid_list_.end(); } -int DBHandleProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write, - const std::string& locale) { +int DBHandleProvider::UpdateCache(const tizen_base::Database& db, pid_t pid, + uid_t uid, bool write, const std::string& locale) { pkg_map_.clear(); app_map_.clear(); pending_pkg_.clear(); pkg_app_map_.clear(); - const char* dbpath = sqlite3_db_filename(db, "main"); + const char* dbpath = sqlite3_db_filename(db.GetRaw(), "main"); bool is_inmemory_db = false; if (dbpath == nullptr || strlen(dbpath) == 0) { LOG(INFO) << "database is inmemory db"; @@ -356,31 +355,15 @@ int DBHandleProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write, if (!is_inmemory_db && !GetModifiedTime(dbpath, &start_time)) return PMINFO_R_ERROR; - GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal); - if (list == nullptr) { - LOG(ERROR) << "Out of memory"; - return PMINFO_R_ERROR; - } - pkgmgrinfo_filter_x tmp_filter = { 0, }; tmp_filter.cache_flag = true; - int ret = pkginfo_internal_filter_get_list(db, &tmp_filter, uid_, - locale.c_str(), list); + std::map> pkgs; + int ret = internal::GetPkgInfo(db, &tmp_filter, uid_, locale, pkgs); 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* pkg = reinterpret_cast(value); - std::string pkgid = pkg->package; - AddPackage(std::move(pkgid), pkg); - } + for (auto& [key, val] : pkgs) + AddPackage(std::move(key), std::move(val)); } - g_hash_table_destroy(list); - if (ret == PMINFO_R_ERROR) - return ret; - if (!is_inmemory_db && !GetModifiedTime(dbpath, &end_time)) return PMINFO_R_ERROR; @@ -391,8 +374,7 @@ int DBHandleProvider::UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write, } std::vector> app_list; - ret = pkgmgr_server::internal::appinfo_internal_filter_get_list(db, - &tmp_filter, uid_, uid, locale.c_str(), app_list); + ret = internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, app_list); if (!is_inmemory_db && !GetModifiedTime(dbpath, &end_time)) return PMINFO_R_ERROR; @@ -440,7 +422,7 @@ std::vector> DBHandleProvider::GetPackages( const std::string& package) { std::vector> ret; - if (__check_package_storage_status(filter)) { + if (internal::CheckPackageStorageStatus(filter)) { if (pkgmgrinfo_pkginfo_filter_add_bool(filter, PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE, true) != PMINFO_R_OK) { LOG(ERROR) << "Fail to add check storage value to filter"; @@ -461,9 +443,9 @@ std::vector> DBHandleProvider::GetPackages( return ret; } -void DBHandleProvider::AddPackage(std::string package, package_x* info) { - auto ptr = std::shared_ptr(info, pkgmgrinfo_basic_free_package); - pkg_map_[package] = std::move(ptr); +void DBHandleProvider::AddPackage(std::string package, + std::shared_ptr info) { + pkg_map_[package] = std::move(info); } inline bool CheckAppFilters(pkgmgrinfo_filter_x* filter, @@ -512,7 +494,7 @@ std::vector> DBHandleProvider::GetApplications( } std::vector> ret; - if (pkgmgr_server::internal::check_app_storage_status(filter)) { + if (internal::CheckAppStorageStatus(filter)) { if (pkgmgrinfo_appinfo_filter_add_bool(filter, PMINFO_APPINFO_PROP_APP_CHECK_STORAGE, true) != PMINFO_R_OK) { LOG(ERROR) << "Fail to add check storage value to filter"; @@ -560,20 +542,15 @@ void DBHandleProvider::RegisterPendingPackageInfo(package_x* info) { pending_pkg_.emplace(info->package); } -bool DBHandleProvider::UpdatePendingPackageInfo(sqlite3* db, +void DBHandleProvider::UpdatePendingPackageInfo(const tizen_base::Database& db, pid_t pid, uid_t uid, const std::string& locale) { - GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal); - if (list == nullptr) { - LOG(ERROR) << "Out of memory"; - return false; - } - pkgmgrinfo_filter_x tmp_filter = { 0, }; pkgmgrinfo_node_x node = { .prop = E_PMINFO_PKGINFO_PROP_PACKAGE_ID }; tmp_filter.cache_flag = true; tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node); + std::map> pkgs; for (const auto& pkg : pending_pkg_) { pkg_map_.erase(pkg); for (auto& appid : pkg_app_map_[pkg]) { @@ -582,49 +559,31 @@ bool DBHandleProvider::UpdatePendingPackageInfo(sqlite3* db, pkg_app_map_.erase(pkg); node.value = const_cast(pkg.c_str()); - pkginfo_internal_filter_get_list(db, &tmp_filter, - uid_, locale.c_str(), list); + internal::GetPkgInfo(db, &tmp_filter, uid_, locale, pkgs); } - GHashTableIter iter; - gpointer value; - g_hash_table_iter_init(&iter, list); - while (g_hash_table_iter_next(&iter, nullptr, &value)) { - auto* pkg = reinterpret_cast(value); - std::string pkgid = pkg->package; - AddPackage(std::move(pkgid), pkg); - } + for (auto& [key, val] : pkgs) + AddPackage(key, val); - g_hash_table_iter_init(&iter, list); node.prop = E_PMINFO_APPINFO_PROP_APP_PACKAGE; - while (g_hash_table_iter_next(&iter, nullptr, &value)) { - auto* pkg = reinterpret_cast(value); - node.value = pkg->package; + for (auto& [key, val] : pkgs) { + node.value = val->package; std::vector> app_list; - pkgmgr_server::internal::appinfo_internal_filter_get_list( - db, &tmp_filter, uid_, uid, locale.c_str(), app_list); + internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, app_list); for (auto& app : app_list) { - app->privileges = pkg->privileges; + app->privileges = val->privileges; std::string appid = app->appid; AddApplication(std::move(appid), std::move(app)); } } - g_hash_table_destroy(list); g_slist_free(tmp_filter.list); pending_pkg_.clear(); - return true; } -bool DBHandleProvider::UpdateCachePkg(sqlite3* db, uid_t uid, +bool DBHandleProvider::UpdateCachePkg(const tizen_base::Database& db, uid_t uid, const std::string& pkgid, const std::string& locale) { - GHashTable* list = g_hash_table_new(g_str_hash, g_str_equal); - if (list == nullptr) { - LOG(ERROR) << "Out of memory"; - return false; - } - pkgmgrinfo_filter_x tmp_filter = { 0, }; pkgmgrinfo_node_x node = { .prop = E_PMINFO_PKGINFO_PROP_PACKAGE_ID, @@ -632,43 +591,30 @@ bool DBHandleProvider::UpdateCachePkg(sqlite3* db, uid_t uid, }; tmp_filter.cache_flag = true; tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node); - pkginfo_internal_filter_get_list(db, &tmp_filter, - uid_, locale.c_str(), list); - - GHashTableIter iter; - gpointer value; - g_hash_table_iter_init(&iter, list); - while (g_hash_table_iter_next(&iter, nullptr, &value)) { - auto* pkg = reinterpret_cast(value); - std::string pkgid = pkg->package; - AddPackage(pkgid, pkg); - - for (auto& appid : pkg_app_map_[pkgid]) { + std::map> pkgs; + internal::GetPkgInfo(db, &tmp_filter, uid_, locale, pkgs); + for (auto& [key, val] : pkgs) { + AddPackage(key, val); + for (auto& appid : pkg_app_map_[key]) { app_map_.erase(appid); } - pkg_app_map_.erase(pkgid); - + pkg_app_map_.erase(key); std::vector> app_list; node.prop = E_PMINFO_APPINFO_PROP_APP_PACKAGE; - node.value = const_cast(pkgid.c_str()); - - pkgmgr_server::internal::appinfo_internal_filter_get_list( - db, &tmp_filter, uid_, uid, locale.c_str(), app_list); - + node.value = const_cast(key.c_str()); + internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, app_list); for (auto& app : app_list) { - app->privileges = pkg->privileges; + app->privileges = val->privileges; std::string appid = app->appid; AddApplication(std::move(appid), std::move(app)); } } - g_hash_table_destroy(list); - g_slist_free(tmp_filter.list); return true; } -bool DBHandleProvider::UpdateCacheApp(sqlite3* db, uid_t uid, +bool DBHandleProvider::UpdateCacheApp(const tizen_base::Database& db, uid_t uid, const std::string& appid, const std::string& locale) { pkgmgrinfo_filter_x tmp_filter = { 0, }; pkgmgrinfo_node_x node = { @@ -680,8 +626,7 @@ bool DBHandleProvider::UpdateCacheApp(sqlite3* db, uid_t uid, std::vector> app_list; app_map_.erase(appid); - pkgmgr_server::internal::appinfo_internal_filter_get_list(db, - &tmp_filter, uid_, uid, locale.c_str(), app_list); + internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, app_list); g_slist_free(tmp_filter.list); for (auto& app : app_list) { @@ -700,8 +645,8 @@ bool DBHandleProvider::UpdateCacheApp(sqlite3* db, uid_t uid, return true; } -bool DBHandleProvider::UpdateCacheAppByPkgid(sqlite3* db, uid_t uid, - const std::string& pkgid, const std::string& locale) { +bool DBHandleProvider::UpdateCacheAppByPkgid(const tizen_base::Database& db, + uid_t uid, const std::string& pkgid, const std::string& locale) { auto it = pkg_map_.find(pkgid); if (it == pkg_map_.end()) { LOG(ERROR) << "Can not find package from pkg_map"; @@ -719,8 +664,7 @@ bool DBHandleProvider::UpdateCacheAppByPkgid(sqlite3* db, uid_t uid, tmp_filter.list = g_slist_append(tmp_filter.list, (gpointer)&node); std::vector> app_list; - pkgmgr_server::internal::appinfo_internal_filter_get_list( - db, &tmp_filter, uid_, uid, locale.c_str(), app_list); + internal::GetAppInfo(db, &tmp_filter, uid_, uid, locale, app_list); for (auto& appid : pkg_app_map_[pkgid]) { app_map_.erase(appid); diff --git a/src/server/database/db_handle_provider.hh b/src/server/database/db_handle_provider.hh index e165e05..324f23c 100644 --- a/src/server/database/db_handle_provider.hh +++ b/src/server/database/db_handle_provider.hh @@ -28,6 +28,7 @@ #include #include +#include #include "filter_checker_provider.hh" #include "pkgmgrinfo_basic.h" #include "pkgmgrinfo_private.h" @@ -51,8 +52,8 @@ class EXPORT_API DBHandleProvider { std::string GetCertDBPath(int pid, bool write); void SetMemoryMode(pid_t pid); void UnsetMemoryMode(pid_t pid); - int UpdateCache(sqlite3* db, pid_t pid, uid_t uid, bool write, - const std::string& locale); + int UpdateCache(const tizen_base::Database& db, pid_t pid, uid_t uid, + bool write, const std::string& locale); std::vector> GetPackages( pid_t pid, pkgmgrinfo_filter_x* filter, const std::string& package); @@ -61,22 +62,22 @@ class EXPORT_API DBHandleProvider { const std::string& app); void TrimCache(); void RegisterPendingPackageInfo(package_x* info); - bool UpdatePendingPackageInfo(sqlite3* db, + void UpdatePendingPackageInfo(const tizen_base::Database& db, pid_t pid, uid_t uid, const std::string& locale); - bool UpdateCachePkg(sqlite3* db, uid_t uid, const std::string& pkgid, - const std::string& locale); - bool UpdateCacheApp(sqlite3* db, uid_t uid, const std::string& appid, - const std::string& locale); - bool UpdateCacheAppByPkgid(sqlite3* db, uid_t uid, const std::string& pkgid, - const std::string& locale); + bool UpdateCachePkg(const tizen_base::Database& db, uid_t uid, + const std::string& pkgid, const std::string& locale); + bool UpdateCacheApp(const tizen_base::Database& db, uid_t uid, + const std::string& appid, const std::string& locale); + bool UpdateCacheAppByPkgid(const tizen_base::Database& db, uid_t uid, + const std::string& pkgid, const std::string& locale); private: explicit DBHandleProvider(uid_t uid); sqlite3* CreateMemoryDBHandle(const std::string& filedb_path, - const std::string& memorydb_path); + const std::string& memorydb_path); bool IsMemoryDBActive(pid_t pid, bool write); void ReleaseCache(); - void AddPackage(std::string package, package_x* info); + void AddPackage(std::string package, std::shared_ptr info); void AddApplication(std::string app, std::shared_ptr info); void InsertPID(pid_t pid); bool ErasePID(pid_t pid); diff --git a/src/server/database/depinfo_db_handler.cc b/src/server/database/depinfo_db_handler.cc index 3362a19..6cbb03a 100644 --- a/src/server/database/depinfo_db_handler.cc +++ b/src/server/database/depinfo_db_handler.cc @@ -49,21 +49,16 @@ int DepInfoGetDBHandler::Execute() { LOG(ERROR) << "Failed to connect database"; return PMINFO_R_ERROR; } - GList* list = nullptr; - std::vector> conn_list = GetConnection(); + + const auto& conn_list = GetConnection(); int ret = PMINFO_R_OK; - for (auto& conn : conn_list) { - ret = pkginfo_internal_filter_get_depends_on( - conn.first, pkgid_.c_str(), &list); + dependency_list_.clear(); + for (const auto& conn : conn_list) { + ret = internal::GetDependsOn(conn.first, pkgid_, dependency_list_); if (ret == PMINFO_R_ERROR) break; } - for (GList* tmp = list; tmp; tmp = tmp->next) - dependency_list_.emplace_back(reinterpret_cast(tmp->data)); - - g_list_free(list); - return ret; } diff --git a/src/server/database/pkg_get_db_handler.cc b/src/server/database/pkg_get_db_handler.cc index 78cd3da..bcff4d1 100644 --- a/src/server/database/pkg_get_db_handler.cc +++ b/src/server/database/pkg_get_db_handler.cc @@ -28,15 +28,6 @@ namespace { -gboolean _move_func(gpointer key, gpointer value, gpointer user_data) { - package_x* info = static_cast(value); - std::vector>* app_list = - static_cast>*>(user_data); - app_list->emplace_back(info, pkgmgrinfo_basic_free_package); - - return true; -} - uid_t globaluser_uid = -1; uid_t GetGlobalUID() { @@ -70,28 +61,24 @@ int PkgGetDBHandler::GetHandleFromDB() { return PMINFO_R_ERROR; } - std::vector> conn_list = GetConnection(); - GHashTable* list = - g_hash_table_new_full(g_str_hash, g_str_equal, nullptr, nullptr); + const auto& conn_list = GetConnection(); int ret = PMINFO_R_OK; - for (auto& conn : conn_list) { - ret = pkginfo_internal_filter_get_list(conn.first, filter_, conn.second, - GetLocale().c_str(), list); + std::map> pkgs; + for (const auto& [db, uid] : conn_list) { + ret = internal::GetPkgInfo(db, filter_, uid, GetLocale(), pkgs); if (ret == PMINFO_R_ERROR) { LOG(ERROR) << "Failed to pkginfo_internal_filter_get_list : " << ret; break; } } - if (g_hash_table_size(list) == 0) - ret = PMINFO_R_ENOENT; - - if (ret == PMINFO_R_OK) - g_hash_table_foreach_steal(list, _move_func, &handle_list_); + if (pkgs.empty()) + return PMINFO_R_ENOENT; - g_hash_table_destroy(list); + for (auto& [key, val] : pkgs) + handle_list_.push_back(std::move(val)); - return ret; + return PMINFO_R_OK; } void PkgGetDBHandler::GetPackageFromCache(uid_t uid, diff --git a/src/server/database/pkg_set_db_handler.cc b/src/server/database/pkg_set_db_handler.cc index 639949f..1379ebe 100644 --- a/src/server/database/pkg_set_db_handler.cc +++ b/src/server/database/pkg_set_db_handler.cc @@ -60,16 +60,15 @@ int PkgSetDBHandler::Execute() { if (!is_offline_) DBHandleProvider::GetInst(uid_).SetMemoryMode(GetPID()); - std::vector> conn_list = GetConnection(); - sqlite3* conn = conn_list.front().first; + const auto& db = GetConnection().front().first; int ret = 0; if (write_type_ == pkgmgr_common::PkgWriteType::Insert) - ret = pkgmgr_parser_insert_pkg_info(conn, package_, uid_); + ret = pkgmgr_server::internal::InsertPkgInfo(db, package_, uid_); else if (write_type_ == pkgmgr_common::PkgWriteType::Update) - ret = pkgmgr_parser_update_pkg_info(conn, package_, uid_); + ret = pkgmgr_server::internal::UpdatePkgInfo(db, package_, uid_); else if (write_type_ == pkgmgr_common::PkgWriteType::Delete) - ret = pkgmgr_parser_delete_pkg_info(conn, package_->package, uid_); + ret = pkgmgr_server::internal::DeletePkgInfo(db, package_->package, uid_); else LOG(ERROR) << "Unknown db write type"; diff --git a/src/server/database/query_handler.cc b/src/server/database/query_handler.cc index b34a2dc..1d481e3 100644 --- a/src/server/database/query_handler.cc +++ b/src/server/database/query_handler.cc @@ -188,17 +188,6 @@ class QueryMaker { QueryMaker __query_maker; -void __free_argument(gpointer data) { - query_args* args = reinterpret_cast(data); - g_list_free(args->argument); - free(args); -} - -void __free_query_list(GList* queries, GList* args_list) { - g_list_free(queries); - g_list_free_full(args_list, __free_argument); -} - } // namespace namespace pkgmgr_server { @@ -222,50 +211,37 @@ std::vector QueryHandler::GetResult() { return std::move(result_); } -int QueryHandler::ExecuteReadQuery(GList* queries, GList* args_list) { +int QueryHandler::ExecuteReadQuery(const std::vector& queries, + const std::vector>>& args_list) { std::shared_lock s(lock_); if (!Connect()) { LOG(ERROR) << "Failed to connect database"; return PMINFO_R_ERROR; } - std::vector> conn_list = GetConnection(); + const auto& conn_list = GetConnection(); int ret = PMINFO_R_ERROR; - for (auto& conn : conn_list) { - for (GList* it = args_list; it; it = it->next) { - GList* list = nullptr; - int row = 0; - int col = 0; - - query_args* params = reinterpret_cast(it->data); - ret = get_query_result(conn.first, (const char *)queries->data, - params->argument, &list, &row, &col); + for (const auto& conn : conn_list) { + int i = 0; + for (auto& q : queries) { + std::vector>> result; + ret = internal::GetQueryResult(conn.first, q, args_list[i++], result); if (ret == PMINFO_R_ERROR) { LOG(ERROR) << "Failed to execute query"; return ret; } - GList* tmp = list; - for (int i = 0; i < row; ++i) { - pkgmgr_common::parcel::StrArgs vt; - for (int j = 0; j < col; ++j) { - if (!tmp->data) - vt.emplace_back(std::nullopt); - else - vt.emplace_back(reinterpret_cast(tmp->data)); - tmp = tmp->next; - } - result_.emplace_back(std::move(vt)); + for (auto& r : result) { + result_.push_back(std::move(r)); } - - g_list_free_full(list, free); } } return ret; } -int QueryHandler::ExecuteWriteQuery(GList* queries, GList* args_list, +int QueryHandler::ExecuteWriteQuery(const std::vector& queries, + const std::vector>>& args_list, const std::vector>& changes) { std::unique_lock u(lock_); if (!Connect()) { @@ -273,11 +249,11 @@ int QueryHandler::ExecuteWriteQuery(GList* queries, GList* args_list, return PMINFO_R_ERROR; } - std::vector> conn_list = GetConnection(); + const auto& conn_list = GetConnection(); int ret = PMINFO_R_ERROR; bool is_writer = DBHandleProvider::IsWriter(GetPID()); - for (auto& conn : conn_list) { - ret = execute_write_queries(conn.first, queries, args_list); + for (const auto& conn : conn_list) { + ret = internal::ExecuteWriteQueries(conn.first, queries, args_list); if (ret != PMINFO_R_OK) { LOG(ERROR) << "Failed to execute"; break; @@ -329,33 +305,19 @@ int QueryHandler::ExecuteWriteQuery(GList* queries, GList* args_list, } int QueryHandler::Execute() { - GList* queries = nullptr; - GList* args_list = nullptr; + std::vector queries; + std::vector>> args_list; std::vector> changes; for (auto& [queryIndex, args] : query_args_) { const auto& query_info = __query_maker.GetQueryInfo(queryIndex); const char* query = std::get<0>(query_info); if (query == nullptr) { LOG(ERROR) << "Failed to get query"; - __free_query_list(queries, args_list); return PMINFO_R_ERROR; } - queries = g_list_append(queries, (gpointer)query); - query_args* arg = reinterpret_cast( - calloc(1, sizeof(query_args))); - if (arg == nullptr) { - LOG(ERROR) << "Out of memory"; - __free_query_list(queries, args_list); - return PMINFO_R_ERROR; - } - arg->len = args.size(); - for (auto& argument : args) { - arg->argument = g_list_append(arg->argument, - gpointer(argument ? (*argument).c_str() : nullptr)); - } - - args_list = g_list_append(args_list, arg); + queries.push_back(query); + args_list.push_back(args); if (GetOpType() == pkgmgr_common::DBOperationType::OPERATION_TYPE_READ) continue; @@ -368,7 +330,6 @@ int QueryHandler::Execute() { unsigned int idx = std::get<2>(query_info); if (args.size() <= idx) { LOG(ERROR) << "Invalid query argument"; - __free_query_list(queries, args_list); return PMINFO_R_ERROR; } @@ -380,11 +341,9 @@ int QueryHandler::Execute() { if (GetOpType() == pkgmgr_common::DBOperationType::OPERATION_TYPE_READ) { int ret = ExecuteReadQuery(queries, args_list); - __free_query_list(queries, args_list); return ret; } else { int ret = ExecuteWriteQuery(queries, args_list, changes); - __free_query_list(queries, args_list); return ret; } } diff --git a/src/server/database/query_handler.hh b/src/server/database/query_handler.hh index 9ba3738..c58fbd1 100644 --- a/src/server/database/query_handler.hh +++ b/src/server/database/query_handler.hh @@ -56,8 +56,10 @@ class EXPORT_API QueryHandler : public AbstractDBHandler { std::vector GetResult(); private: - int ExecuteReadQuery(GList* queries, GList* args_list); - int ExecuteWriteQuery(GList* queries, GList* args_list, + int ExecuteReadQuery(const std::vector& queries, + const std::vector>>& args_list); + int ExecuteWriteQuery(const std::vector& queries, + const std::vector>>& args_list, const std::vector>& changes); uid_t uid_; diff --git a/src/server/database/remove_cache_db_handler.cc b/src/server/database/remove_cache_db_handler.cc index f12cb48..20e542b 100644 --- a/src/server/database/remove_cache_db_handler.cc +++ b/src/server/database/remove_cache_db_handler.cc @@ -37,23 +37,18 @@ int RemoveCacheDBHandler::Execute() { return PMINFO_R_ERROR; } - std::vector> conn_list = GetConnection(); + const auto& conn_list = GetConnection(); auto lock = CacheFlag::GetWriterLock(); if (CacheFlag::GetStatus() != CacheFlag::Status::PREPARED) return PMINFO_R_OK; + CacheFlag::SetStatus(CacheFlag::Status::PREPARING); - bool success = true; - for (auto& conn : conn_list) { - auto& provider = database::DBHandleProvider::GetInst(conn.second); - success = provider.UpdatePendingPackageInfo(conn.first, - GetPID(), uid_, GetLocale()); - if (!success) { - provider.TrimCache(); - break; - } + for (const auto& [db, uid] : conn_list) { + auto& provider = database::DBHandleProvider::GetInst(uid); + provider.UpdatePendingPackageInfo(db, GetPID(), uid_, GetLocale()); } - CacheFlag::SetStatus(success ? - CacheFlag::Status::PREPARED : CacheFlag::Status::UNPREPARED); + + CacheFlag::SetStatus(CacheFlag::Status::PREPARED); return PMINFO_R_OK; } diff --git a/src/server/initialize_db_internal.c b/src/server/initialize_db_internal.c deleted file mode 100644 index c272c23..0000000 --- a/src/server/initialize_db_internal.c +++ /dev/null @@ -1,239 +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. - */ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "pkgmgrinfo_internal.h" -#include "pkgmgrinfo_private.h" -#include "pkgmgrinfo_debug.h" - - -#ifndef OWNER_ROOT -#define OWNER_ROOT 0 -#endif -#ifndef APPFW_USER -#define APPFW_USER "app_fw" -#endif - -/* TODO: Do not labeling directly */ -#define DB_LABEL "User::Home" -#define SET_SMACK_LABEL(x) \ -do { \ - if (smack_setlabel((x), DB_LABEL, SMACK_LABEL_ACCESS)) \ - _LOGE("failed chsmack -a %s %s", DB_LABEL, x); \ - else \ - _LOGD("chsmack -a %s %s", DB_LABEL, x); \ -} while (0) - -#define DB_VERSION_PATH SYSCONFDIR "/package-manager/pkg_db_version.txt" - -static const char *__get_cert_db_path(void) -{ - return tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_cert.db"); -} - -static int __set_db_permission(const char *path, uid_t uid) -{ - int fd; - const char *files[2]; - char journal_file[BUFSIZE]; - struct stat sb; - mode_t mode; - struct passwd pwd; - struct passwd *result; - char buf[BUFSIZE]; - int ret; - int i; - - if (getuid() != OWNER_ROOT) - return 0; - - if (uid == OWNER_ROOT || uid == GLOBAL_USER) { - ret = getpwnam_r(APPFW_USER, &pwd, buf, sizeof(buf), &result); - if (result == NULL) { - if (ret == 0) - _LOGE("no such user: %d", uid); - else - _LOGE("getpwuid_r failed: %d", errno); - return -1; - } - uid = pwd.pw_uid; - } - - snprintf(journal_file, sizeof(journal_file), "%s-journal", path); - files[0] = path; - files[1] = journal_file; - - ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result); - if (result == NULL) { - if (ret == 0) - _LOGE("no such user: %d", uid); - else - _LOGE("getpwuid_r failed: %d", errno); - return -1; - } - - for (i = 0; i < 2; i++) { - fd = open(files[i], O_RDONLY); - if (fd == -1) { - _LOGE("open %s failed: %d", files[i], errno); - return -1; - } - ret = fstat(fd, &sb); - if (ret == -1) { - _LOGE("stat %s failed: %d", files[i], errno); - close(fd); - return -1; - } - if (S_ISLNK(sb.st_mode)) { - _LOGE("%s is symlink!", files[i]); - close(fd); - return -1; - } - ret = fchown(fd, uid, pwd.pw_gid); - if (ret == -1) { - _LOGE("fchown %s failed: %d", files[i], errno); - close(fd); - return -1; - } - - mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; - if (!strcmp(path, __get_cert_db_path())) - mode |= S_IWOTH; - ret = fchmod(fd, mode); - if (ret == -1) { - _LOGD("fchmod %s failed: %d", files[i], errno); - close(fd); - return -1; - } - close(fd); - SET_SMACK_LABEL(files[i]); - } - - return 0; -} - -static int __set_db_version(sqlite3 *db) { - static const char query_raw[] = "PRAGMA user_version=%Q"; - int ret; - FILE *fp = NULL; - sqlite3_stmt *stmt; - char version[PKG_STRING_LEN_MAX] = { 0 }; - char *query = NULL; - - fp = fopen(DB_VERSION_PATH, "r"); - if (fp == NULL) { - _LOGE("Failed to open db version file"); - return -1; - } - - if (fgets(version, sizeof(version), fp) == NULL) { - _LOGE("Failed to get version information"); - fclose(fp); - return -1; - } - fclose(fp); - - query = sqlite3_mprintf(query_raw, version); - if (!query) { - _LOGE("Out of memory"); - return -1; - } - - 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 -1; - } - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("sqlite3_step failed: %d", ret); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_finalize(stmt); - - return 0; -} - -static int __create_tables(sqlite3 *db, const char **queries) -{ - int ret; - int i; - for (i = 0; queries[i] != NULL; i++) { - ret = sqlite3_exec(db, queries[i], NULL, NULL, NULL); - if (ret != SQLITE_OK) { - _LOGE("exec failed: %s", sqlite3_errmsg(db)); - return -1; - } - } - return 0; -} - -static int __initialize_db(sqlite3 *db, const char *dbpath, uid_t uid) -{ - const char **queries; - - if (__set_db_version(db)) - return -1; - - if (strstr(dbpath, ".pkgmgr_parser.db")) { - queries = PARSER_INIT_QUERIES; - } else if (strstr(dbpath, ".pkgmgr_cert.db")) { - queries = CERT_INIT_QUERIES; - } else { - _LOGE("unexpected dbpath: %s", dbpath); - return -1; - } - - __BEGIN_TRANSACTION(db); - __DO_TRANSACTION(db, __create_tables(db, queries)); - __END_TRANSACTION(db); - - if (__set_db_permission(dbpath, uid)) - _LOGE("failed to set db permission"); - - return 0; -} - -API int pkgmgr_parser_internal_initialize_db(sqlite3 *db, uid_t uid) -{ - const char *dbpath; - - dbpath = sqlite3_db_filename(db, "main"); - if (dbpath == NULL) { - _LOGE("Fail to get db filename"); - return -1; - } - - return __initialize_db(db, dbpath, uid); -} diff --git a/src/server/initialize_db_internal.cc b/src/server/initialize_db_internal.cc new file mode 100644 index 0000000..dac61ec --- /dev/null +++ b/src/server/initialize_db_internal.cc @@ -0,0 +1,226 @@ +/* +* Copyright (c) 2023 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "pkgmgrinfo_internal.h" +#include "pkgmgrinfo_private.h" +#include "pkgmgrinfo_debug.h" + +namespace { + +constexpr const char DB_LABEL[] = "User::Home"; +constexpr const char APPFW_USER[] = "app_fw"; +constexpr const int OWNER_ROOT = 0; +constexpr const char DB_VERSION_PATH[] = + SYSCONFDIR "/package-manager/pkg_db_version.txt"; +constexpr const char DB_VERSION_PATH_UNIT_TEST[] = + "./pkg_db_version.txt"; +bool IsUnitTest; + +void SetSmackLabel(const char* x) { + if (smack_setlabel(x, DB_LABEL, SMACK_LABEL_ACCESS)) + _LOGE("failed chsmack -a %s %s", DB_LABEL, x); + else + _LOGD("chsmack -a %s %s", DB_LABEL, x); +} + +const char* GetVersionPath() { + if (IsUnitTest) + return DB_VERSION_PATH_UNIT_TEST; + return DB_VERSION_PATH; +} + +const char* GetCertDbPath() { + return tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_cert.db"); +} + +int SetDbPermission(const char* path, uid_t uid) { + int fd; + const char *files[2]; + char journal_file[BUFSIZE]; + struct stat sb; + mode_t mode; + struct passwd pwd; + struct passwd *result; + char buf[BUFSIZE]; + int ret; + int i; + + if (getuid() != OWNER_ROOT) + return 0; + + if (uid == OWNER_ROOT || uid == GLOBAL_USER) { + ret = getpwnam_r(APPFW_USER, &pwd, buf, sizeof(buf), &result); + if (result == NULL) { + if (ret == 0) + _LOGE("no such user: %d", uid); + else + _LOGE("getpwuid_r failed: %d", errno); + return -1; + } + uid = pwd.pw_uid; + } + + snprintf(journal_file, sizeof(journal_file), "%s-journal", path); + files[0] = path; + files[1] = journal_file; + + ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result); + if (result == NULL) { + if (ret == 0) + _LOGE("no such user: %d", uid); + else + _LOGE("getpwuid_r failed: %d", errno); + return -1; + } + + for (i = 0; i < 2; i++) { + fd = open(files[i], O_RDONLY); + if (fd == -1) { + _LOGE("open %s failed: %d", files[i], errno); + return -1; + } + ret = fstat(fd, &sb); + if (ret == -1) { + _LOGE("stat %s failed: %d", files[i], errno); + close(fd); + return -1; + } + if (S_ISLNK(sb.st_mode)) { + _LOGE("%s is symlink!", files[i]); + close(fd); + return -1; + } + ret = fchown(fd, uid, pwd.pw_gid); + if (ret == -1) { + _LOGE("fchown %s failed: %d", files[i], errno); + close(fd); + return -1; + } + + mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; + if (!strcmp(path, GetCertDbPath())) + mode |= S_IWOTH; + ret = fchmod(fd, mode); + if (ret == -1) { + _LOGD("fchmod %s failed: %d", files[i], errno); + close(fd); + return -1; + } + close(fd); + SetSmackLabel(files[i]); + } + + return 0; +} + +int SetDbVersion(const tizen_base::Database& db) { + std::ifstream file(GetVersionPath(), std::fstream::in); + if (!static_cast(file)) { + _LOGE("Failed to open db version file: %s", GetVersionPath()); + return -1; + } + + std::string version; + std::getline(file, version); + if (version.empty()) { + _LOGE("Failed to get version information"); + return -1; + } + + std::string sql = "PRAGMA user_version=" + version; + try { + db.OneStepExec({ sql }); + } catch (const tizen_base::DbException& e) { + _LOGE("OneStepExec failed: %s", e.msg()); + return -1; + } + + return 0; +} + +int CreateTables(const tizen_base::Database& db, const char** queries) { + try { + for (int i = 0; queries[i] != nullptr; i++) + db.OneStepExec({ queries[i] }); + } catch (const tizen_base::DbException& e) { + _LOGE("OneStepExec failed: %s", e.msg()); + return -1; + } + + return 0; +} + +int InitDb(const tizen_base::Database& db, std::string_view dbpath, + uid_t uid) { + const char** queries; + + if (SetDbVersion(db)) + return -1; + + if (dbpath.rfind(".pkgmgr_parser.db") != std::string::npos) { + queries = PARSER_INIT_QUERIES; + } else if (dbpath.rfind(".pkgmgr_cert.db") != std::string::npos) { + queries = CERT_INIT_QUERIES; + } else { + _LOGE("unexpected dbpath: %s", dbpath.data()); + return -1; + } + + auto guard = db.CreateTransactionGuard(); + + if (CreateTables(db, queries) != 0) + return -1; + + guard.Commit(); + if (SetDbPermission(dbpath.data(), uid)) + _LOGE("failed to set db permission"); + + return 0; +} + +} // namespace + +namespace pkgmgr_server::internal { + +void SetEnableUnitTest(bool enable) { + IsUnitTest = enable; +} + +int InitializeDb(const tizen_base::Database& db, uid_t uid) { + const char* dbpath = sqlite3_db_filename(db.GetRaw(), "main"); + if (dbpath == nullptr) { + _LOGE("Fail to get db filename"); + return -1; + } + + return InitDb(db, dbpath, uid); +} + +} // namespace pkgmgr_server::internal diff --git a/src/server/pkginfo_internal.c b/src/server/pkginfo_internal.c deleted file mode 100644 index d2c5a8a..0000000 --- a/src/server/pkginfo_internal.c +++ /dev/null @@ -1,2715 +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. - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "pkgmgr_parser.h" -#include "pkgmgrinfo_basic.h" -#include "pkgmgrinfo_internal.h" -#include "pkgmgrinfo_private.h" -#include "pkgmgrinfo_debug.h" -#include "pkgmgr-info.h" - -#define LDPI "ldpi" -#define MDPI "mdpi" -#define HDPI "hdpi" -#define XHDPI "xhdpi" -#define XXHDPI "xxhdpi" - -#define LDPI_MIN 0 -#define LDPI_MAX 240 -#define MDPI_MIN 241 -#define MDPI_MAX 300 -#define HDPI_MIN 301 -#define HDPI_MAX 380 -#define XHDPI_MIN 381 -#define XHDPI_MAX 480 -#define XXHDPI_MIN 481 -#define XXHDPI_MAX 600 - -static const char join_localized_info[] = - " LEFT OUTER JOIN package_localized_info" - " ON pi.package=package_localized_info.package" - " AND package_localized_info.package_locale=?"; -static const char join_privilege_info[] = - " LEFT OUTER JOIN package_privilege_info" - " ON pi.package=package_privilege_info.package"; -static const char join_res_info[] = - " LEFT OUTER JOIN package_res_info" - " ON pi.package=package_res_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 buf[MAX_QUERY_LEN] = { '\0' }; - char buf2[MAX_QUERY_LEN] = { '\0' }; - char *condition = NULL; - GList *tmp_params = NULL; - GSList *list = NULL; - - if (!filter) - return PMINFO_R_OK; - - if (filter->cache_flag) { - joined = E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO | - E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO | - E_PMINFO_PKGINFO_JOIN_RES_INFO; - } - - snprintf(buf, sizeof(buf), "%s", " WHERE 1=1 "); - for (list = filter->list; list; list = list->next) { - joined |= __get_filter_condition(list->data, uid, &condition, - &tmp_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 (joined & E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO) { - strncat(buf2, join_localized_info, - sizeof(buf2) - strlen(buf2) - 1); - *bind_params = g_list_append(*bind_params, strdup(locale)); - } - if (joined & E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO) - strncat(buf2, join_privilege_info, - sizeof(buf2) - strlen(buf2) - 1); - if (joined & E_PMINFO_PKGINFO_JOIN_RES_INFO) - strncat(buf2, join_res_info, - sizeof(buf2) - strlen(buf2) - 1); - - *bind_params = g_list_concat(*bind_params, tmp_params); - size = strlen(buf2) + strlen(buf) + 1; - *query = (char *)calloc(1, size); - if (*query == NULL) - return PMINFO_R_ERROR; - snprintf(*query, size, "%s%s", buf2, buf); - - return PMINFO_R_OK; -} - -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; -} - -bool __check_package_storage_status(pkgmgrinfo_filter_x *tmp_filter) -{ - GSList *tmp_list = NULL; - pkgmgrinfo_node_x *tmp_node = NULL; - int property = -1; - - if (tmp_filter->cache_flag) - return false; - - property = _pminfo_pkginfo_convert_to_prop_bool( - PMINFO_PKGINFO_PROP_PACKAGE_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 _pkginfo_add_description_info_into_list(const char *locale, - char *record, GList **description) -{ - description_x *info; - - info = calloc(1, sizeof(description_x)); - if (info == NULL) { - LOGE("out of memory"); - return PMINFO_R_ERROR; - } - info->lang = strdup(locale); - info->text = record; - *description = g_list_prepend(*description, info); - - return PMINFO_R_OK; -} - -static int _pkginfo_get_plugin_execution_info(sqlite3 *db, const char *pkgid, - GList **plugins) -{ - static const char query_raw[] = - "SELECT appid, plugin_type, plugin_name FROM package_plugin_info " - "WHERE pkgid=%Q"; - int ret; - char *query; - sqlite3_stmt *stmt; - plugin_x *plugin; - - query = sqlite3_mprintf(query_raw, pkgid); - 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) { - plugin = calloc(1, sizeof(plugin_x)); - if (!plugin) { - LOGE("out of memory"); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - plugin->pkgid = strdup(pkgid); - _save_column_str(stmt, 0, &plugin->appid); - _save_column_str(stmt, 1, &plugin->plugin_type); - _save_column_str(stmt, 2, &plugin->plugin_name); - *plugins = g_list_prepend(*plugins, - (gpointer)plugin); - } - - sqlite3_finalize(stmt); - - return PMINFO_R_OK; -} - -static int _pkginfo_get_privilege(sqlite3 *db, const char *pkgid, - GList **privileges) -{ - static const char query_raw[] = - "SELECT DISTINCT privilege, type FROM package_privilege_info " - "WHERE package=%Q"; - int ret; - char *query; - sqlite3_stmt *stmt; - privilege_x *privilege; - - query = sqlite3_mprintf(query_raw, pkgid); - 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) { - privilege = calloc(1, sizeof(privilege_x)); - if (!privilege) { - LOGE("failed to alloc memory"); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - _save_column_str(stmt, 0, &privilege->value); - _save_column_str(stmt, 1, &privilege->type); - *privileges = g_list_prepend(*privileges, - (gpointer)privilege); - } - - sqlite3_finalize(stmt); - - return PMINFO_R_OK; -} - -static int _pkginfo_get_appdefined_privilege(sqlite3 *db, const char *pkgid, - GList **privileges) -{ - static const char query_raw[] = - "SELECT DISTINCT privilege, license, type FROM " - "package_appdefined_privilege_info WHERE package=%Q"; - int ret; - char *query; - sqlite3_stmt *stmt; - appdefined_privilege_x *privilege; - - query = sqlite3_mprintf(query_raw, pkgid); - 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) { - privilege = calloc(1, sizeof(appdefined_privilege_x)); - if (!privilege) { - LOGE("failed to alloc memory"); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - _save_column_str(stmt, 0, &privilege->value); - _save_column_str(stmt, 1, &privilege->license); - _save_column_str(stmt, 2, &privilege->type); - *privileges = g_list_prepend(*privileges, - (gpointer)privilege); - } - - sqlite3_finalize(stmt); - - return PMINFO_R_OK; -} - -static int _pkginfo_get_dependency(sqlite3 *db, const char *pkgid, - GList **dependencies) -{ - static const char query_raw[] = - "SELECT DISTINCT depends_on, type, required_version " - "FROM package_dependency_info WHERE package=%Q"; - int ret; - char *query; - sqlite3_stmt *stmt; - dependency_x *dependency; - - query = sqlite3_mprintf(query_raw, pkgid); - 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) { - dependency = calloc(1, sizeof(dependency_x)); - if (!dependency) { - LOGE("failed to alloc memory"); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - _save_column_str(stmt, 0, &dependency->depends_on); - _save_column_str(stmt, 1, &dependency->type); - _save_column_str(stmt, 2, &dependency->required_version); - *dependencies = g_list_prepend(*dependencies, - (gpointer)dependency); - } - - sqlite3_finalize(stmt); - - return PMINFO_R_OK; -} - -static int _pkginfo_get_res_allowed_packages(sqlite3 *db, const char *pkgid, - GList **allowed_packages) -{ - static const char query_raw[] = - "SELECT DISTINCT allowed_package, required_privilege " - "FROM package_res_allowed_package WHERE package=%Q"; - int ret; - char *query; - char *package; - char *privilege; - sqlite3_stmt *stmt; - res_allowed_package_x *allowed_package_x; - GList *l; - - query = sqlite3_mprintf(query_raw, pkgid); - 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) { - allowed_package_x = NULL; - package = NULL; - privilege = NULL; - - _save_column_str(stmt, 0, &package); - if (!package) - continue; - - for (l = *allowed_packages; l; l = l->next) { - allowed_package_x = (res_allowed_package_x *)l->data; - if (!strcmp(package, (char *)l->data)) - break; - allowed_package_x = NULL; - } - - if (allowed_package_x) { - free(package); - } else { - allowed_package_x = calloc(1, - sizeof(res_allowed_package_x)); - if (allowed_package_x == NULL) { - LOGE("failed to alloc memory"); - sqlite3_finalize(stmt); - free(package); - return PMINFO_R_ERROR; - } - allowed_package_x->allowed_package = package; - *allowed_packages = g_list_prepend(*allowed_packages, - (gpointer)allowed_package_x); - } - - _save_column_str(stmt, 1, &privilege); - if (!privilege) - continue; - - allowed_package_x->required_privileges = g_list_prepend( - allowed_package_x->required_privileges, - privilege); - } - - sqlite3_finalize(stmt); - - return PMINFO_R_OK; -} - -static int _pkginfo_get_res_info(sqlite3 *db, const char *pkgid, - char **res_type, char **res_version, - GList **res_allowed_packages) -{ - static const char query_raw[] = - "SELECT DISTINCT res_type, res_version " - "FROM package_res_info WHERE package=%Q"; - int ret; - char *query; - sqlite3_stmt *stmt; - - query = sqlite3_mprintf(query_raw, pkgid); - 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; - } - - if (sqlite3_step(stmt) != SQLITE_ROW) { - sqlite3_finalize(stmt); - return PMINFO_R_OK; - } - - _save_column_str(stmt, 0, res_type); - _save_column_str(stmt, 1, res_version); - - if (_pkginfo_get_res_allowed_packages(db, pkgid, - res_allowed_packages) != PMINFO_R_OK) { - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - - sqlite3_finalize(stmt); - - return PMINFO_R_OK; -} - -static int _pkginfo_get_packages(sqlite3 *db, uid_t uid, const char *locale, - pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) -{ - static const char query_raw[] = - "SELECT DISTINCT pi.package, pi.installed_storage, pi.external_path"; - static const char query_basic[] = - ", 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.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, pi.package_support_mode, pi.package_disable, " - "pi.light_user_switch_mode"; - static const char query_author[] = - ", pi.author_name, pi.author_email, pi.author_href"; - static const char query_label[] = - ", COALESCE(" - "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale=?), " - "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))"; - static const char query_icon[] = - ", COALESCE(" - "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale=?), " - "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))"; - static const char query_description[] = - ", COALESCE(" - "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale=?), " - "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))"; - static const char query_res_type[] = - ", (SELECT res_type FROM package_res_info WHERE pi.package=package)"; - static const char query_res_version[] = - ", (SELECT res_version FROM package_res_info WHERE pi.package=package)"; - static const char query_from_clause[] = " FROM package_info as pi"; - int ret = PMINFO_R_ERROR; - int idx = 0; - char *tmp_record = NULL; - char *constraints = NULL; - char query[MAX_QUERY_LEN] = { '\0' }; - package_x *info = NULL; - author_x *author = NULL; - GList *bind_params = NULL; - sqlite3_stmt *stmt = NULL; - bool is_check_storage = true; - const uid_t global_user_uid = GLOBAL_USER; - - if (db == NULL || locale == NULL || filter == NULL) { - LOGE("Invalid parameter"); - return PMINFO_R_EINVAL; - } - - is_check_storage = __check_package_storage_status(filter); - - snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw); - if (flag & PMINFO_APPINFO_GET_BASICINFO) - strncat(query, query_basic, sizeof(query) - strlen(query) - 1); - if (flag & PMINFO_PKGINFO_GET_AUTHOR) - strncat(query, query_author, sizeof(query) - strlen(query) - 1); - if (flag & PMINFO_PKGINFO_GET_LABEL) { - strncat(query, query_label, sizeof(query) - strlen(query) - 1); - bind_params = g_list_append(bind_params, strdup(locale)); - } - if (flag & PMINFO_PKGINFO_GET_ICON) { - strncat(query, query_icon, sizeof(query) - strlen(query) - 1); - bind_params = g_list_append(bind_params, strdup(locale)); - } - if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) { - strncat(query, query_description, - sizeof(query) - strlen(query) - 1); - bind_params = g_list_append(bind_params, strdup(locale)); - } - if (flag & PMINFO_PKGINFO_GET_RES_INFO) { - strncat(query, query_res_type, - sizeof(query) - strlen(query) - 1); - strncat(query, query_res_version, - sizeof(query) - strlen(query) - 1); - } - - strncat(query, query_from_clause, sizeof(query) - strlen(query) - 1); - - ret = _get_filtered_query(filter, locale, uid, - &constraints, &bind_params); - if (ret != PMINFO_R_OK) { - LOGE("Failed to get WHERE clause"); - goto catch; - } - - if (constraints) - strncat(query, constraints, 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; - } - - 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(package_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->package); - _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->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->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); - _save_column_str(stmt, idx++, &info->support_mode); - _save_column_str(stmt, idx++, &info->is_disabled); - _save_column_str(stmt, idx++, &info->light_user_switch_mode); - } - - info->for_all_users = - strdup((uid != global_user_uid) ? "false" : "true"); - - if (_pkginfo_get_plugin_execution_info(db, - info->package, &info->plugin)) { - ret = PMINFO_R_ERROR; - goto catch; - } - - if (flag & PMINFO_PKGINFO_GET_AUTHOR) { - /* TODO : author should be retrieved at package_localized_info */ - author = calloc(1, sizeof(author_x)); - if (author == NULL) { - ret = PMINFO_R_ERROR; - goto catch; - } - _save_column_str(stmt, idx++, &author->text); - _save_column_str(stmt, idx++, &author->email); - _save_column_str(stmt, idx++, &author->href); - info->author = g_list_prepend(info->author, author); - } - - if (flag & PMINFO_PKGINFO_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_PKGINFO_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_PKGINFO_GET_DESCRIPTION) { - tmp_record = NULL; - _save_column_str(stmt, idx++, &tmp_record); - if (_pkginfo_add_description_info_into_list(locale, - tmp_record, &info->description)) { - ret = PMINFO_R_ERROR; - goto catch; - } - } - - if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) { - if (_pkginfo_get_privilege(db, info->package, - &info->privileges)) { - ret = PMINFO_R_ERROR; - goto catch; - } - } - - if (flag & PMINFO_PKGINFO_GET_APPDEFINED_PRIVILEGE) { - if (_pkginfo_get_appdefined_privilege(db, info->package, - &info->appdefined_privileges)) { - ret = PMINFO_R_ERROR; - goto catch; - } - } - - if (flag & PMINFO_PKGINFO_GET_DEPENDENCY) { - if (_pkginfo_get_dependency(db, info->package, - &info->dependencies)) { - ret = PMINFO_R_ERROR; - goto catch; - } - } - - if (flag & PMINFO_PKGINFO_GET_RES_INFO) { - if (_pkginfo_get_res_info(db, info->package, - &info->res_type, - &info->res_version, - &info->res_allowed_packages) < 0) { - ret = PMINFO_R_ERROR; - goto catch; - } - } - - if (is_check_storage && - __pkginfo_check_installed_storage(info) != - PMINFO_R_OK) { - ret = PMINFO_R_ERROR; - pkgmgrinfo_basic_free_package(info); - info = NULL; - continue; - } - - g_hash_table_insert(packages, (gpointer)info->package, - (gpointer)info); - } - - ret = PMINFO_R_OK; - -catch: - sqlite3_finalize(stmt); - - if (constraints) - free(constraints); - - if (ret != PMINFO_R_OK && info != NULL) - pkgmgrinfo_basic_free_package(info); - - g_list_free_full(bind_params, free); - - return ret; -} - -API int pkginfo_internal_filter_get_list( - sqlite3 *db, pkgmgrinfo_pkginfo_filter_h filter, - uid_t uid, const char *locale, GHashTable *pkginfo_list) -{ - int ret; - - if (filter == NULL || pkginfo_list == NULL) { - LOGE("Invalid argument"); - return PMINFO_R_EINVAL; - } - - ret = _pkginfo_get_packages(db, uid, locale, filter, - PMINFO_PKGINFO_GET_ALL, pkginfo_list); - return ret; -} - -API int get_query_result(sqlite3 *db, const char *query, GList *param, - GList **list, int *row, int *col) -{ - int ret = 0; - int col_cnt = 0; - int row_cnt = 0; - int idx = 0; - sqlite3_stmt *stmt = NULL; - char *result = NULL; - - if (db == NULL || query == NULL) { - LOGE("Invalid parameter"); - return PMINFO_R_EINVAL; - } - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return PMINFO_R_ERROR; - } - - if (g_list_length(param) != 0) { - ret = __bind_params(stmt, param); - if (ret != PMINFO_R_OK) { - LOGE("failed to bind parameters: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return ret; - } - } - - col_cnt = sqlite3_column_count(stmt); - - while (sqlite3_step(stmt) == SQLITE_ROW) { - row_cnt++; - for (idx = 0; idx < col_cnt; ++idx) { - _save_column_str(stmt, idx, &result); - *list = g_list_append(*list, result); - result = NULL; - } - } - - *row = row_cnt; - *col = col_cnt; - - sqlite3_finalize(stmt); - - return PMINFO_R_OK; -} - -static int _get_depends_on(sqlite3 *db, const char *pkgid, GQueue **queue, - GHashTable **table, GList **pkg_list) -{ - static const char query[] = - "SELECT package, depends_on, type, required_version " - "FROM package_dependency_info WHERE depends_on=?"; - int ret; - sqlite3_stmt *stmt; - dependency_x *req; - - /* already checked */ - if (!g_hash_table_insert(*table, strdup(pkgid), GINT_TO_POINTER(1))) - return PMINFO_R_OK; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return PMINFO_R_ERROR; - } - - ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC); - if (ret != SQLITE_OK) { - LOGE("bind failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - - while (sqlite3_step(stmt) == SQLITE_ROW) { - req = calloc(1, sizeof(dependency_x)); - if (req == NULL) { - LOGE("out of memory"); - sqlite3_finalize(stmt); - return PMINFO_R_ERROR; - } - _save_column_str(stmt, 0, &req->pkgid); - _save_column_str(stmt, 1, &req->depends_on); - _save_column_str(stmt, 2, &req->type); - _save_column_str(stmt, 3, &req->required_version); - - *pkg_list = g_list_prepend(*pkg_list, req); - g_queue_push_tail(*queue, strdup(req->pkgid)); - } - - sqlite3_finalize(stmt); - - return PMINFO_R_OK; -} - -static void __free_depends_on(gpointer data) -{ - struct dependency_x *dep = (struct dependency_x *)data; - - free(dep->pkgid); - free(dep->depends_on); - free(dep->type); - free(dep->required_version); - free(dep); -} - -API int pkginfo_internal_filter_get_depends_on(sqlite3 *db, const char *pkgid, - GList **list) -{ - GQueue *queue; - GHashTable *table; - char *item; - int ret; - - if (db == NULL || pkgid == NULL) { - LOGE("Invalid parameter"); - return PMINFO_R_EINVAL; - } - - queue = g_queue_new(); - if (queue == NULL) { - LOGE("out of memory"); - return PMINFO_R_ERROR; - } - table = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL); - - g_queue_push_tail(queue, strdup(pkgid)); - while (!g_queue_is_empty(queue)) { - item = g_queue_pop_head(queue); - ret = _get_depends_on(db, item, &queue, &table, list); - free(item); - if (ret != PMINFO_R_OK) { - LOGE("failed to get pkgs depends on %s", pkgid); - g_hash_table_destroy(table); - g_list_free_full(*list, __free_depends_on); - g_queue_free_full(queue, free); - return PMINFO_R_ERROR; - } - } - - g_hash_table_destroy(table); - g_queue_free_full(queue, free); - return PMINFO_R_OK; -} - -static int __execute_query(sqlite3 *db, const char *query, GList *param) -{ - int ret = 0; - sqlite3_stmt *stmt = NULL; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - if (g_list_length(param) != 0) { - ret = __bind_params(stmt, param); - if (ret != PMINFO_R_OK) { - LOGE("failed to bind parameters: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return ret; - } - } - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE && ret != SQLITE_OK) { - LOGE("step failed:%d %s", ret, sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_finalize(stmt); - - return PMINFO_R_OK; -} - -API int execute_write_queries(sqlite3 *db, GList *queries, GList *params_list) -{ - int i; - query_args *tmp_ptr = NULL; - - if (db == NULL || queries == NULL) { - _LOGE("Invalid parameter"); - return PMINFO_R_EINVAL; - } - - __BEGIN_TRANSACTION(db); - for (i = 0; i < g_list_length(queries); ++i) { - tmp_ptr = (query_args *)g_list_nth_data(params_list, i); - if (tmp_ptr == NULL) { - _LOGE("Failed to get parameter list"); - sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL); - return PMINFO_R_ERROR; - } - - __DO_TRANSACTION(db, - __execute_query(db, g_list_nth_data(queries, i), - tmp_ptr->argument)); - } - __END_TRANSACTION(db); - - return PMINFO_R_OK; -} - -static int __check_dpi(const char *dpi_char, int dpi_int) -{ - if (dpi_char == NULL) - return -1; - - if (strcasecmp(dpi_char, LDPI) == 0) { - if (dpi_int >= LDPI_MIN && dpi_int <= LDPI_MAX) - return 0; - else - return -1; - } else if (strcasecmp(dpi_char, MDPI) == 0) { - if (dpi_int >= MDPI_MIN && dpi_int <= MDPI_MAX) - return 0; - else - return -1; - } else if (strcasecmp(dpi_char, HDPI) == 0) { - if (dpi_int >= HDPI_MIN && dpi_int <= HDPI_MAX) - return 0; - else - return -1; - } else if (strcasecmp(dpi_char, XHDPI) == 0) { - if (dpi_int >= XHDPI_MIN && dpi_int <= XHDPI_MAX) - return 0; - else - return -1; - } else if (strcasecmp(dpi_char, XXHDPI) == 0) { - if (dpi_int >= XXHDPI_MIN && dpi_int <= XXHDPI_MAX) - return 0; - else - return -1; - } else - return -1; -} - -static void __find_appcontrol_splashscreen_with_dpi(gpointer data, - gpointer user_data) -{ - splashscreen_x *ss = (splashscreen_x *)data; - GList **list = (GList **)user_data; - int dpi = -1; - int ret; - - if (ss->operation == NULL || ss->dpi == NULL) - return; - - ret = system_info_get_platform_int( - "http://tizen.org/feature/screen.dpi", &dpi); - if (ret != SYSTEM_INFO_ERROR_NONE) - return; - - if (__check_dpi(ss->dpi, dpi) != 0) - return; - - *list = g_list_prepend(*list, ss); -} - -static void __find_appcontrol_splashscreen(gpointer data, gpointer user_data) -{ - splashscreen_x *ss = (splashscreen_x *)data; - GList **list = (GList **)user_data; - splashscreen_x *ss_tmp; - GList *tmp; - - if (ss->operation == NULL || ss->dpi) - return; - - for (tmp = *list; tmp; tmp = tmp->next) { - ss_tmp = (splashscreen_x *)tmp->data; - if (ss_tmp->operation - && strcmp(ss_tmp->operation, ss->operation) == 0 - && strcmp(ss_tmp->orientation, ss->orientation) == 0) - return; - } - - *list = g_list_prepend(*list, ss); -} - -static gint __compare_splashscreen_with_orientation_dpi(gconstpointer a, - gconstpointer b) -{ - splashscreen_x *ss = (splashscreen_x *)a; - const char *orientation = (const char *)b; - int dpi = -1; - int ret; - - if (ss->operation || ss->dpi == NULL) - return -1; - - ret = system_info_get_platform_int( - "http://tizen.org/feature/screen.dpi", &dpi); - if (ret != SYSTEM_INFO_ERROR_NONE) - return -1; - - if (strcasecmp(ss->orientation, orientation) == 0 && - __check_dpi(ss->dpi, dpi) == 0) - return 0; - - return -1; -} - -static gint __compare_splashscreen_with_orientation(gconstpointer a, - gconstpointer b) -{ - splashscreen_x *ss = (splashscreen_x *)a; - const char *orientation = (const char *)b; - - if (ss->operation || ss->dpi) - return -1; - - if (strcasecmp(ss->orientation, orientation) == 0) - return 0; - - return -1; -} - -static splashscreen_x *__find_default_splashscreen(GList *splashscreens, - const char *orientation) -{ - GList *tmp; - - tmp = g_list_find_custom(splashscreens, orientation, - (GCompareFunc) - __compare_splashscreen_with_orientation_dpi); - if (tmp) - return (splashscreen_x *)tmp->data; - - tmp = g_list_find_custom(splashscreens, orientation, - (GCompareFunc)__compare_splashscreen_with_orientation); - if (tmp) - return (splashscreen_x *)tmp->data; - - return NULL; -} - -static GList *__find_splashscreens(GList *splashscreens) -{ - GList *list = NULL; - splashscreen_x *ss; - - if (splashscreens == NULL) - return NULL; - - g_list_foreach(splashscreens, - __find_appcontrol_splashscreen_with_dpi, &list); - g_list_foreach(splashscreens, - __find_appcontrol_splashscreen, &list); - - ss = __find_default_splashscreen(splashscreens, "portrait"); - if (ss) - list = g_list_prepend(list, ss); - ss = __find_default_splashscreen(splashscreens, "landscape"); - if (ss) - list = g_list_prepend(list, ss); - - return list; -} - -static int __insert_splashscreen_info(sqlite3 *db, application_x *app, - GList *ss_list) -{ - static const char query[] = - "INSERT INTO package_app_splash_screen (app_id, src, type," - " orientation, indicatordisplay, operation, color_depth) " - "VALUES (?, ?, ?, ?, ?, ?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - GList *tmp; - splashscreen_x *ss; - - if (app->splashscreens == NULL) - return 0; - - if (ss_list == NULL) - return 0; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - for (tmp = ss_list; tmp; tmp = tmp->next) { - ss = (splashscreen_x *)tmp->data; - if (ss == NULL) - continue; - idx = 1; - __BIND_TEXT(db, stmt, idx++, app->appid); - __BIND_TEXT(db, stmt, idx++, ss->src); - __BIND_TEXT(db, stmt, idx++, ss->type); - __BIND_TEXT(db, stmt, idx++, ss->orientation); - __BIND_TEXT(db, stmt, idx++, ss->indicatordisplay); - __BIND_TEXT(db, stmt, idx++, ss->operation); - __BIND_TEXT(db, stmt, idx++, ss->color_depth); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_reset(stmt); - } - - sqlite3_finalize(stmt); - - return 0; -} - -static void __trimfunc(GList *trim_list) -{ - char *trim_data; - char *prev = NULL; - GList *list = g_list_first(trim_list); - - while (list) { - trim_data = (char *)list->data; - if (trim_data) { - if (prev) { - if (strcmp(trim_data, prev) == 0) { - trim_list = g_list_remove(trim_list, - trim_data); - list = g_list_first(trim_list); - prev = NULL; - continue; - } else - prev = trim_data; - } else { - prev = trim_data; - } - } - list = g_list_next(list); - } -} - -static int __insert_package_appdefined_privilege_info(sqlite3 *db, - manifest_x *mfx) -{ - static const char query[] = - "INSERT INTO package_appdefined_privilege_info " - "(package, privilege, license, type) " - "VALUES (?, ?, ?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - GList *tmp; - appdefined_privilege_x *priv; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - for (tmp = mfx->appdefined_privileges; tmp; tmp = tmp->next) { - priv = (appdefined_privilege_x *)tmp->data; - if (priv == NULL) - continue; - - idx = 1; - __BIND_TEXT(db, stmt, idx++, mfx->package); - __BIND_TEXT(db, stmt, idx++, priv->value); - __BIND_TEXT(db, stmt, idx++, priv->license); - __BIND_TEXT(db, stmt, idx++, priv->type); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - sqlite3_reset(stmt); - } - - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_package_dependency_info(sqlite3 *db, manifest_x *mfx) -{ - static const char query[] = - "INSERT INTO package_dependency_info" - " (package, depends_on, type, required_version) " - "VALUES (?, ?, ?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - GList *tmp; - dependency_x *dep; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - for (tmp = mfx->dependencies; tmp; tmp = tmp->next) { - dep = (dependency_x *)tmp->data; - if (dep == NULL) - continue; - - idx = 1; - __BIND_TEXT(db, stmt, idx++, mfx->package); - __BIND_TEXT(db, stmt, idx++, dep->depends_on); - __BIND_TEXT(db, stmt, idx++, dep->type); - __BIND_TEXT(db, stmt, idx++, dep->required_version); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - sqlite3_reset(stmt); - } - - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_mainapp_localized_info(sqlite3 *db, application_x *app, - const char *locale, const char *label, const char *icon) -{ - static const char query[] = - "INSERT OR REPLACE INTO package_localized_info (" - " package, package_locale, package_label, package_icon," - " package_description, package_license, package_author) " - "VALUES (?, ?," - " COALESCE((SELECT package_label FROM package_localized_info" - " WHERE package=? AND package_locale=?), ?)," - " COALESCE((SELECT package_icon FROM package_localized_info" - " WHERE package=? AND package_icon=?), ?)," - " (SELECT package_description FROM package_localized_info" - " WHERE package=? AND package_locale=?)," - " (SELECT package_description FROM package_localized_info" - " WHERE package=? AND package_locale=?)," - " (SELECT package_description FROM package_localized_info" - " WHERE package=? AND package_locale=?))"; - int ret; - sqlite3_stmt *stmt; - int idx = 1; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - __BIND_TEXT(db, stmt, idx++, app->package); - __BIND_TEXT(db, stmt, idx++, locale); - __BIND_TEXT(db, stmt, idx++, app->package); - __BIND_TEXT(db, stmt, idx++, locale); - __BIND_TEXT(db, stmt, idx++, label); - __BIND_TEXT(db, stmt, idx++, app->package); - __BIND_TEXT(db, stmt, idx++, locale); - __BIND_TEXT(db, stmt, idx++, icon); - __BIND_TEXT(db, stmt, idx++, app->package); - __BIND_TEXT(db, stmt, idx++, locale); - __BIND_TEXT(db, stmt, idx++, app->package); - __BIND_TEXT(db, stmt, idx++, locale); - __BIND_TEXT(db, stmt, idx++, app->package); - __BIND_TEXT(db, stmt, idx++, locale); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_finalize(stmt); - - return 0; -} - -static gint __comparefunc(gconstpointer a, gconstpointer b, gpointer userdata) -{ - if (a == NULL || b == NULL) - return 0; - if (strcmp((char *)a, (char *)b) == 0) - return 0; - if (strcmp((char *)a, (char *)b) < 0) - return -1; - if (strcmp((char *)a, (char *)b) > 0) - return 1; - return 0; -} - -static GList *__create_locale_list(GList *lbls, GList *lcns, GList *icns, - GList *dcns, GList *aths) -{ - GList *locale = NULL; - GList *tmp; - label_x *lbl; - license_x *lcn; - icon_x *icn; - description_x *dcn; - author_x *ath; - - for (tmp = lbls; tmp; tmp = tmp->next) { - lbl = (label_x *)tmp->data; - if (lbl == NULL) - continue; - if (lbl->lang) - locale = g_list_insert_sorted_with_data( - locale, (gpointer)lbl->lang, - __comparefunc, NULL); - } - for (tmp = lcns; tmp; tmp = tmp->next) { - lcn = (license_x *)tmp->data; - if (lcn == NULL) - continue; - if (lcn->lang) - locale = g_list_insert_sorted_with_data( - locale, (gpointer)lcn->lang, - __comparefunc, NULL); - } - for (tmp = icns; tmp; tmp = tmp->next) { - icn = (icon_x *)tmp->data; - if (icn == NULL) - continue; - if (icn->lang) - locale = g_list_insert_sorted_with_data( - locale, (gpointer)icn->lang, - __comparefunc, NULL); - } - for (tmp = dcns; tmp; tmp = tmp->next) { - dcn = (description_x *)tmp->data; - if (dcn == NULL) - continue; - if (dcn->lang) - locale = g_list_insert_sorted_with_data( - locale, (gpointer)dcn->lang, - __comparefunc, NULL); - } - for (tmp = aths; tmp; tmp = tmp->next) { - ath = (author_x *)tmp->data; - if (ath == NULL) - continue; - if (ath->lang) - locale = g_list_insert_sorted_with_data( - locale, (gpointer)ath->lang, - __comparefunc, NULL); - } - __trimfunc(locale); - return locale; -} - -static gint __check_icon_resolution(const char *orig_icon_path, - char **new_icon_path) -{ - int ret; - char *dpi_path[2]; - char *icon_filename; - char modified_iconpath[BUFSIZE]; - char icon_path[BUFSIZE]; - int i; - int dpi = -1; - - if (orig_icon_path == NULL) - return -1; - - ret = system_info_get_platform_int( - "http://tizen.org/feature/screen.dpi", &dpi); - if (ret != SYSTEM_INFO_ERROR_NONE) - return -1; - - if (dpi >= LDPI_MIN && dpi <= LDPI_MAX) { - dpi_path[0] = "LDPI"; - dpi_path[1] = "ldpi"; - } else if (dpi >= MDPI_MIN && dpi <= MDPI_MAX) { - dpi_path[0] = "MDPI"; - dpi_path[1] = "mdpi"; - } else if (dpi >= HDPI_MIN && dpi <= HDPI_MAX) { - dpi_path[0] = "HDPI"; - dpi_path[1] = "hdpi"; - } else if (dpi >= XHDPI_MIN && dpi <= XHDPI_MAX) { - dpi_path[0] = "XHDPI"; - dpi_path[1] = "xhdpi"; - } else if (dpi >= XXHDPI_MIN && dpi <= XXHDPI_MAX) { - dpi_path[0] = "XXHDPI"; - dpi_path[1] = "xxhdpi"; - } else { - _LOGE("Unidentified dpi[%d]", dpi); - return -1; - } - - icon_filename = strrchr(orig_icon_path, '/'); - if (icon_filename == NULL) - return -1; - - snprintf(icon_path, - strlen(orig_icon_path) - (strlen(icon_filename) - 1), - "%s", orig_icon_path); - for (i = 0; i < 2; i++) { - ret = snprintf(modified_iconpath, BUFSIZE - 1, "%s/%s%s", - icon_path, dpi_path[i], icon_filename); - if (ret < 0 || ret > BUFSIZE - 1) { - _LOGE("snprintf fail"); - return -1; - } - if (access(modified_iconpath, F_OK) != -1) { - /* if exists, return modified icon path */ - *new_icon_path = strdup(modified_iconpath); - return 0; - } - } - - return -1; -} - -static gint __compare_icon(gconstpointer a, gconstpointer b) -{ - icon_x *icon = (icon_x *)a; - char *icon_path; - - if (icon->lang != NULL && strcasecmp(icon->lang, DEFAULT_LOCALE) != 0) - return -1; - - if (icon->dpi != NULL) - return -1; - - if (__check_icon_resolution(icon->text, &icon_path) == 0) { - free(icon->text); - icon->text = icon_path; - } - - return 0; -} - -static gint __compare_icon_with_lang(gconstpointer a, gconstpointer b) -{ - icon_x *icon = (icon_x *)a; - char *lang = (char *)b; - char *icon_path; - - if (icon->dpi != NULL) - return -1; - - if (strcasecmp(icon->lang, lang) == 0) { - if (strcasecmp(icon->lang, DEFAULT_LOCALE) == 0) { - /* icon for no locale. check existance of - * folder-hierachied default icons - */ - if (__check_icon_resolution(icon->text, - &icon_path) == 0) { - free(icon->text); - icon->text = icon_path; - } - } - return 0; - } - - return -1; -} - -static gint __compare_icon_with_dpi(gconstpointer a, gconstpointer b) -{ - icon_x *icon = (icon_x *)a; - int dpi = GPOINTER_TO_INT(b); - - if (icon->lang != NULL && strcasecmp(icon->lang, DEFAULT_LOCALE) != 0) - return -1; - - if (icon->dpi == NULL) - return -1; - - if (__check_dpi(icon->dpi, dpi) == 0) - return 0; - - return -1; -} - -static gint __compare_icon_with_lang_dpi(gconstpointer a, gconstpointer b) -{ - int ret; - icon_x *icon = (icon_x *)a; - char *lang = (char *)b; - int dpi = -1; - - ret = system_info_get_platform_int( - "http://tizen.org/feature/screen.dpi", &dpi); - if (ret != SYSTEM_INFO_ERROR_NONE) - return -1; - - if (strcasecmp(icon->lang, lang) == 0 && - __check_dpi(icon->dpi, dpi) == 0) - return 0; - - return -1; -} - -static char *__find_icon(GList *icons, const char *lang) -{ - GList *tmp; - icon_x *icon; - int dpi = 0; - int ret; - - /* first, find icon whose locale and dpi with given lang and - * system's dpi has matched - */ - tmp = g_list_find_custom(icons, lang, - (GCompareFunc)__compare_icon_with_lang_dpi); - if (tmp != NULL) { - icon = (icon_x *)tmp->data; - return (char *)icon->text; - } - - /* if first has failed, find icon whose locale has matched */ - tmp = g_list_find_custom(icons, lang, - (GCompareFunc)__compare_icon_with_lang); - if (tmp != NULL) { - icon = (icon_x *)tmp->data; - return (char *)icon->text; - } - - /* if second has failed, find icon whose dpi has matched with - * system's dpi - */ - ret = system_info_get_platform_int( - "http://tizen.org/feature/screen.dpi", &dpi); - if (ret == SYSTEM_INFO_ERROR_NONE) { - tmp = g_list_find_custom(icons, GINT_TO_POINTER(dpi), - (GCompareFunc)__compare_icon_with_dpi); - if (tmp != NULL) { - icon = (icon_x *)tmp->data; - return (char *)icon->text; - } - } - - /* last, find default icon marked as "No Locale" */ - tmp = g_list_find_custom(icons, NULL, (GCompareFunc)__compare_icon); - if (tmp != NULL) { - icon = (icon_x *)tmp->data; - return (char *)icon->text; - } - - return NULL; -} - -static void __extract_data(const char *locale, GList *lbls, GList *lcns, - GList *icns, GList *dcns, GList *aths, char **label, - char **license, char **icon, char **description, char **author) -{ - GList *tmp; - label_x *lbl; - license_x *lcn; - description_x *dcn; - author_x *ath; - - for (tmp = lbls; tmp; tmp = tmp->next) { - lbl = (label_x *)tmp->data; - if (lbl == NULL) - continue; - if (lbl->lang) { - if (strcmp(lbl->lang, locale) == 0) { - *label = (char *)lbl->text; - break; - } - } - } - for (tmp = lcns; tmp; tmp = tmp->next) { - lcn = (license_x *)tmp->data; - if (lcn == NULL) - continue; - if (lcn->lang) { - if (strcmp(lcn->lang, locale) == 0) { - *license = (char *)lcn->text; - break; - } - } - } - - *icon = __find_icon(icns, locale); - - for (tmp = dcns; tmp; tmp = tmp->next) { - dcn = (description_x *)tmp->data; - if (dcn == NULL) - continue; - if (dcn->lang) { - if (strcmp(dcn->lang, locale) == 0) { - *description = (char *)dcn->text; - break; - } - } - } - for (tmp = aths; tmp; tmp = tmp->next) { - ath = (author_x *)tmp->data; - if (ath == NULL) - continue; - if (ath->lang) { - if (strcmp(ath->lang, locale) == 0) { - *author = (char *)ath->text; - break; - } - } - } -} - -static int __insert_app_localized_info(sqlite3 *db, application_x *app) -{ - static const char query[] = - "INSERT INTO package_app_localized_info (app_id, app_locale," - " app_label, app_icon) " - "VALUES (?, ?, ?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - GList *tmp; - GList *locales; - const char *locale; - char *label; - char *icon; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - locales = __create_locale_list(app->label, NULL, app->icon, NULL, NULL); - for (tmp = locales; tmp; tmp = tmp->next) { - locale = (const char *)tmp->data; - label = NULL; - icon = NULL; - __extract_data(locale, app->label, NULL, app->icon, NULL, NULL, - &label, NULL, &icon, NULL, NULL); - if (!label && !icon) - continue; - - idx = 1; - __BIND_TEXT(db, stmt, idx++, app->appid); - __BIND_TEXT(db, stmt, idx++, locale); - __BIND_TEXT(db, stmt, idx++, label); - __BIND_TEXT(db, stmt, idx++, icon); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - g_list_free(locales); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_reset(stmt); - - if (strcasecmp(app->mainapp, "true") == 0) { - if (__insert_mainapp_localized_info(db, app, locale, - label, icon)) - _LOGE("insert mainapp localized info failed"); - } - } - - g_list_free(locales); - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_app_res_control(sqlite3 *db, application_x *app) -{ - static const char query[] = - "INSERT INTO package_app_res_control (app_id, res_type," - " min_res_version, max_res_version, auto_close) " - "VALUES (?, ?, ?, ?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - GList *tmp; - res_control_x *rc; - - if (app->res_control == NULL) - return 0; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - for (tmp = app->res_control; tmp; tmp = tmp->next) { - rc = (res_control_x *)tmp->data; - if (rc == NULL) - continue; - idx = 1; - __BIND_TEXT(db, stmt, idx++, app->appid); - __BIND_TEXT(db, stmt, idx++, rc->res_type); - __BIND_TEXT(db, stmt, idx++, rc->min_res_version); - __BIND_TEXT(db, stmt, idx++, rc->max_res_version); - __BIND_TEXT(db, stmt, idx++, rc->auto_close); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_reset(stmt); - } - - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_package_privilege_info(sqlite3 *db, manifest_x *mfx) -{ - static const char query[] = - "INSERT INTO package_privilege_info (package, privilege, type) " - "VALUES (?, ?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - GList *tmp; - privilege_x *priv; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - for (tmp = mfx->privileges; tmp; tmp = tmp->next) { - priv = (privilege_x *)tmp->data; - if (priv == NULL) - continue; - - idx = 1; - __BIND_TEXT(db, stmt, idx++, mfx->package); - __BIND_TEXT(db, stmt, idx++, priv->value); - __BIND_TEXT(db, stmt, idx++, priv->type); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - sqlite3_reset(stmt); - } - - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_app_data_control_privilege_info(sqlite3 *db, - datacontrol_x *datacontrol) -{ - static const char query[] = - "INSERT INTO package_app_data_control_privilege (providerid," - " privilege, type) VALUES (?, ?, ?)"; - - int ret; - sqlite3_stmt *stmt; - int idx; - GList *privileges; - char *priv; - - if (datacontrol == NULL) - return 0; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - for (privileges = datacontrol->privileges; privileges; - privileges = privileges->next) { - priv = (char *)privileges->data; - if (priv == NULL) - continue; - - idx = 1; - __BIND_TEXT(db, stmt, idx++, datacontrol->providerid); - __BIND_TEXT(db, stmt, idx++, priv); - __BIND_TEXT(db, stmt, idx++, datacontrol->type); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_reset(stmt); - } - - sqlite3_finalize(stmt); - return 0; -} - -static int __insert_datacontrol_info(sqlite3 *db, application_x *app) -{ - static const char query[] = - "INSERT INTO package_app_data_control (app_id, providerid," - " access, type, trusted) VALUES (?, ?, ?, ?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - GList *tmp; - datacontrol_x *dc; - - if (app->datacontrol == NULL) - return 0; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - for (tmp = app->datacontrol; tmp; tmp = tmp->next) { - dc = (datacontrol_x *)tmp->data; - if (dc == NULL) - continue; - idx = 1; - __BIND_TEXT(db, stmt, idx++, app->appid); - __BIND_TEXT(db, stmt, idx++, dc->providerid); - __BIND_TEXT(db, stmt, idx++, dc->access); - __BIND_TEXT(db, stmt, idx++, dc->type); - __BIND_TEXT(db, stmt, idx++, dc->trusted); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - if (dc->privileges && - __insert_app_data_control_privilege_info( - db, dc)) { - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_reset(stmt); - } - - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_category_info(sqlite3 *db, application_x *app) -{ - static const char query[] = - "INSERT INTO package_app_app_category (app_id, category) " - "VALUES (?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - GList *tmp; - const char *category; - - if (app->category == NULL) - return 0; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - for (tmp = app->category; tmp; tmp = tmp->next) { - category = (const char *)tmp->data; - if (category == NULL) - continue; - idx = 1; - __BIND_TEXT(db, stmt, idx++, app->appid); - __BIND_TEXT(db, stmt, idx++, category); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_reset(stmt); - } - - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_metadata_info(sqlite3 *db, application_x *app) -{ - static const char query[] = - "INSERT INTO package_app_app_metadata (app_id," - " md_key, md_value) VALUES (?, ?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - GList *tmp; - metadata_x *md; - - if (app->metadata == NULL) - return 0; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - for (tmp = app->metadata; tmp; tmp = tmp->next) { - md = (metadata_x *)tmp->data; - if (md == NULL) - continue; - idx = 1; - __BIND_TEXT(db, stmt, idx++, app->appid); - __BIND_TEXT(db, stmt, idx++, md->key); - __BIND_TEXT(db, stmt, idx++, md->value); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_reset(stmt); - } - - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_appcontrol_privilege_info(sqlite3 *db, const char *appid, - appcontrol_x *ac) -{ - static const char query[] = - "INSERT INTO package_app_app_control_privilege (app_id," - " app_control, privilege) VALUES (?, ?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - char app_control[BUFSIZE]; - GList *tmp; - char *privilege; - - if (ac == NULL) - return 0; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - for (tmp = ac->privileges; tmp; tmp = tmp->next) { - privilege = (char *)tmp->data; - if (privilege == NULL || !strlen(privilege)) - continue; - - idx = 1; - snprintf(app_control, sizeof(app_control), "%s|%s|%s", - ac->operation ? (strlen(ac->operation) > 0 ? - ac->operation : "NULL") : "NULL", - ac->uri ? (strlen(ac->uri) > 0 ? - ac->uri : "NULL") : "NULL", - ac->mime ? (strlen(ac->mime) > 0 ? - ac->mime : "NULL") : "NULL"); - __BIND_TEXT(db, stmt, idx++, appid); - __BIND_TEXT(db, stmt, idx++, app_control); - __BIND_TEXT(db, stmt, idx++, privilege); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_reset(stmt); - } - - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_appcontrol_info(sqlite3 *db, application_x *app) -{ - static const char query[] = - "INSERT INTO package_app_app_control (app_id, app_control," - " visibility, app_control_id) " - "VALUES (?, ?, ?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - char app_control[BUFSIZE]; - GList *tmp; - appcontrol_x *ac; - - if (app->appcontrol == NULL) - return 0; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - for (tmp = app->appcontrol; tmp; tmp = tmp->next) { - ac = (appcontrol_x *)tmp->data; - if (ac == NULL) - continue; - idx = 1; - snprintf(app_control, sizeof(app_control), "%s|%s|%s", - ac->operation ? (strlen(ac->operation) > 0 ? - ac->operation : "NULL") : "NULL", - ac->uri ? (strlen(ac->uri) > 0 ? - ac->uri : "NULL") : "NULL", - ac->mime ? (strlen(ac->mime) > 0 ? - ac->mime : "NULL") : "NULL"); - __BIND_TEXT(db, stmt, idx++, app->appid); - __BIND_TEXT(db, stmt, idx++, app_control); - __BIND_TEXT(db, stmt, idx++, ac->visibility); - __BIND_TEXT(db, stmt, idx++, ac->id); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - if (__insert_appcontrol_privilege_info(db, app->appid, ac)) { - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_reset(stmt); - } - - sqlite3_finalize(stmt); - - return 0; -} - -static const char *__get_bool(char *value, bool is_true) -{ - if (value != NULL) { - if (!strcmp(value, "")) - return (is_true) ? "true" : "false"; - return value; - } - - return (is_true) ? "true" : "false"; -} - -#define EFFECTIVE_APPID_KEY "http://tizen.org/metadata/effective-appid" -static const char *__find_effective_appid(GList *metadata_list) -{ - GList *tmp; - metadata_x *md; - - for (tmp = metadata_list; tmp; tmp = tmp->next) { - md = (metadata_x *)tmp->data; - if (md == NULL || md->key == NULL) - continue; - - if (strcmp(md->key, EFFECTIVE_APPID_KEY) == 0) { - if (md->value) - return md->value; - } - } - - return NULL; -} - -static int __convert_background_category(GList *category_list) -{ - int ret = 0; - GList *tmp; - char *category_data; - - if (category_list == NULL) - return 0; - - for (tmp = category_list; tmp; tmp = tmp->next) { - category_data = (char *)tmp->data; - if (category_data == NULL) - continue; - if (!strcmp(category_data, APP_BG_CATEGORY_MEDIA_STR)) - ret |= APP_BG_CATEGORY_MEDIA_VAL; - else if (!strcmp(category_data, APP_BG_CATEGORY_DOWNLOAD_STR)) - ret |= APP_BG_CATEGORY_DOWNLOAD_VAL; - else if (!strcmp(category_data, APP_BG_CATEGORY_BGNETWORK_STR)) - ret |= APP_BG_CATEGORY_BGNETWORK_VAL; - else if (!strcmp(category_data, APP_BG_CATEGORY_LOCATION_STR)) - ret |= APP_BG_CATEGORY_LOCATION_VAL; - else if (!strcmp(category_data, APP_BG_CATEGORY_SENSOR_STR)) - ret |= APP_BG_CATEGORY_SENSOR_VAL; - else if (!strcmp(category_data, APP_BG_CATEGORY_IOTCOMM_STR)) - ret |= APP_BG_CATEGORY_IOTCOMM_VAL; - else if (!strcmp(category_data, APP_BG_CATEGORY_SYSTEM)) - ret |= APP_BG_CATEGORY_SYSTEM_VAL; - else - _LOGE("Unidentified category [%s]", category_data); - } - - return ret; -} - -static int __insert_package_res_info_allowed_package(sqlite3 *db, - const char *pkgid, GList *rap_list) -{ - static const char query[] = - "INSERT INTO package_res_allowed_package (package," - " allowed_package, required_privilege) VALUES (?, ?, ?)"; - int ret; - int idx; - sqlite3_stmt *stmt; - GList *tmp; - GList *priv_list; - res_allowed_package_x *rap; - - if (rap_list == NULL) - return 0; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - for (tmp = rap_list; tmp; tmp = tmp->next) { - rap = (res_allowed_package_x *)tmp->data; - if (rap == NULL) - continue; - - if (!rap->required_privileges) { - idx = 1; - __BIND_TEXT(db, stmt, idx++, pkgid); - __BIND_TEXT(db, stmt, idx++, rap->allowed_package); - __BIND_TEXT(db, stmt, idx++, NULL); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_reset(stmt); - continue; - } - - for (priv_list = rap->required_privileges; priv_list; - priv_list = priv_list->next) { - idx = 1; - __BIND_TEXT(db, stmt, idx++, pkgid); - __BIND_TEXT(db, stmt, idx++, rap->allowed_package); - __BIND_TEXT(db, stmt, idx++, (char *)priv_list->data); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_reset(stmt); - } - } - - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_package_res_info(sqlite3 *db, manifest_x *mfx) -{ - static const char query[] = - "INSERT INTO package_res_info (package, res_type," - " res_version) VALUES (?, ?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - - if (mfx->res_type == NULL || mfx->res_version == NULL) - return 0; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - idx = 1; - __BIND_TEXT(db, stmt, idx++, mfx->package); - __BIND_TEXT(db, stmt, idx++, mfx->res_type); - __BIND_TEXT(db, stmt, idx++, mfx->res_version); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - if (__insert_package_res_info_allowed_package(db, mfx->package, - mfx->res_allowed_packages) < 0) { - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_application_info(sqlite3 *db, manifest_x *mfx) -{ - static const char query[] = - "INSERT INTO package_app_info (app_id, app_component," - " app_exec, app_nodisplay, app_type, app_onboot, app_multiple," - " app_autorestart, app_taskmanage, 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_installed_storage, app_process_pool," - " app_launch_mode, app_ui_gadget, app_support_mode," - " app_support_disable, component_type, package, app_tep_name," - " app_zip_mount_file, app_background_category," - " app_package_type, app_root_path, app_api_version," - " app_effective_appid, app_splash_screen_display," - " app_package_system, app_removable," - " app_package_installed_time, app_support_ambient," - " app_external_path, app_setup_appid, light_user_switch_mode) " - "VALUES (?, ?, " - " ?, LOWER(?), ?, LOWER(?), LOWER(?)," - " LOWER(?), LOWER(?), ?," - " ?, LOWER(?), ?," - " ?, LOWER(?), ?," - " ?, LOWER(?)," - " ?, LOWER(?), LOWER(?)," - " ?, ?, LOWER(?)," - " COALESCE(?, 'single'), LOWER(?), ?," - " LOWER(?), ?, ?, ?," - " ?, ?," - " ?, ?, ?," - " ?, LOWER(?)," - " LOWER(?), LOWER(?)," - " ?, LOWER(?)," - " ?, ?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - GList *tmp; - application_x *app; - int bg_category; - const char *effective_appid; - GList *ss_list; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - for (tmp = mfx->application; tmp; tmp = tmp->next) { - app = (application_x *)tmp->data; - if (app == NULL) - continue; - - bg_category = __convert_background_category( - app->background_category); - effective_appid = __find_effective_appid(app->metadata); - - idx = 1; - __BIND_TEXT(db, stmt, idx++, app->appid); - __BIND_TEXT(db, stmt, idx++, app->component_type); - __BIND_TEXT(db, stmt, idx++, app->exec); - __BIND_TEXT(db, stmt, idx++, __get_bool(app->nodisplay, false)); - __BIND_TEXT(db, stmt, idx++, app->type); - __BIND_TEXT(db, stmt, idx++, __get_bool(app->onboot, false)); - __BIND_TEXT(db, stmt, idx++, __get_bool(app->multiple, false)); - __BIND_TEXT(db, stmt, idx++, - __get_bool(app->autorestart, false)); - __BIND_TEXT(db, stmt, idx++, - __get_bool(app->taskmanage, false)); - __BIND_TEXT(db, stmt, idx++, app->hwacceleration); - __BIND_TEXT(db, stmt, idx++, app->screenreader); - __BIND_TEXT(db, stmt, idx++, __get_bool(app->mainapp, false)); - __BIND_TEXT(db, stmt, idx++, app->recentimage); - __BIND_TEXT(db, stmt, idx++, app->launchcondition); - __BIND_TEXT(db, stmt, idx++, - __get_bool(app->indicatordisplay, true)); - __BIND_TEXT(db, stmt, idx++, app->portraitimg); - __BIND_TEXT(db, stmt, idx++, app->landscapeimg); - __BIND_TEXT(db, stmt, idx++, - __get_bool(app->guestmode_visibility, true)); - __BIND_TEXT(db, stmt, idx++, app->permission_type); - __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->preload, false)); - __BIND_TEXT(db, stmt, idx++, __get_bool(app->submode, false)); - __BIND_TEXT(db, stmt, idx++, app->submode_mainid); - __BIND_TEXT(db, stmt, idx++, mfx->installed_storage); - __BIND_TEXT(db, stmt, idx++, - __get_bool(app->process_pool, false)); - __BIND_TEXT(db, stmt, idx++, app->launch_mode); - __BIND_TEXT(db, stmt, idx++, __get_bool(app->ui_gadget, false)); - __BIND_TEXT(db, stmt, idx++, - app->support_mode ? app->support_mode : "0"); - __BIND_TEXT(db, stmt, idx++, - __get_bool(mfx->support_disable, false)); - __BIND_TEXT(db, stmt, idx++, app->component_type); - __BIND_TEXT(db, stmt, idx++, mfx->package); - __BIND_TEXT(db, stmt, idx++, mfx->tep_name); - __BIND_TEXT(db, stmt, idx++, mfx->zip_mount_file); - __BIND_INT(db, stmt, idx++, bg_category); - __BIND_TEXT(db, stmt, idx++, mfx->type ? mfx->type : "tpk"); - __BIND_TEXT(db, stmt, idx++, mfx->root_path); - __BIND_TEXT(db, stmt, idx++, app->api_version); - __BIND_TEXT(db, stmt, idx++, effective_appid); - __BIND_TEXT(db, stmt, idx++, - __get_bool(app->splash_screen_display, true)); - __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->system, false)); - __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->removable, false)); - __BIND_TEXT(db, stmt, idx++, mfx->installed_time); - __BIND_TEXT(db, stmt, idx++, - __get_bool(app->support_ambient, false)); - __BIND_TEXT(db, stmt, idx++, mfx->external_path); - __BIND_TEXT(db, stmt, idx++, app->setup_appid); - __BIND_TEXT(db, stmt, idx++, mfx->light_user_switch_mode); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_reset(stmt); - - if (__insert_appcontrol_info(db, app)) { - sqlite3_finalize(stmt); - return -1; - } - if (__insert_category_info(db, app)) { - sqlite3_finalize(stmt); - return -1; - } - if (__insert_metadata_info(db, app)) { - sqlite3_finalize(stmt); - return -1; - } - if (__insert_datacontrol_info(db, app)) { - sqlite3_finalize(stmt); - return -1; - } - ss_list = __find_splashscreens(app->splashscreens); - if (__insert_splashscreen_info(db, app, ss_list)) { - g_list_free(ss_list); - sqlite3_finalize(stmt); - return -1; - } - g_list_free(ss_list); - if (__insert_app_localized_info(db, app)) { - sqlite3_finalize(stmt); - return -1; - } - if (__insert_app_res_control(db, app)) { - sqlite3_finalize(stmt); - return -1; - } - } - - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_package_update_info(sqlite3 *db, manifest_x *mfx) -{ - static const char query[] = - "INSERT INTO package_update_info (package, update_version) " - "VALUES (?, ?)"; - int ret; - int idx; - sqlite3_stmt *stmt; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - idx = 1; - __BIND_TEXT(db, stmt, idx++, mfx->package); - __BIND_TEXT(db, stmt, idx, mfx->version); - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_package_localized_info(sqlite3 *db, manifest_x *mfx) -{ - static const char query[] = - "INSERT INTO package_localized_info (package, package_locale," - " package_label, package_icon, package_description," - " package_license, package_author) " - "VALUES (?, ?, ?, ?, ?, ?, ?)"; - int ret; - sqlite3_stmt *stmt; - int idx; - GList *tmp; - GList *locales; - const char *locale; - char *label; - char *icon; - char *description; - char *license; - char *author; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - locales = __create_locale_list(mfx->label, mfx->license, mfx->icon, - mfx->description, mfx->author); - for (tmp = locales; tmp; tmp = tmp->next) { - locale = (const char *)tmp->data; - label = NULL; - icon = NULL; - description = NULL; - license = NULL; - author = NULL; - __extract_data(locale, mfx->label, mfx->license, mfx->icon, - mfx->description, mfx->author, - &label, &license, &icon, &description, &author); - if (!label && !license && !icon && !description && !author) - continue; - - idx = 1; - __BIND_TEXT(db, stmt, idx++, mfx->package); - __BIND_TEXT(db, stmt, idx++, locale); - __BIND_TEXT(db, stmt, idx++, label); - __BIND_TEXT(db, stmt, idx++, icon); - __BIND_TEXT(db, stmt, idx++, description); - __BIND_TEXT(db, stmt, idx++, license); - __BIND_TEXT(db, stmt, idx++, author); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - g_list_free(locales); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_reset(stmt); - } - - g_list_free(locales); - sqlite3_finalize(stmt); - - return 0; -} - -static int __insert_package_info(sqlite3 *db, manifest_x *mfx) -{ - static const char query[] = - "INSERT INTO package_info (package, package_type," - " package_version, package_api_version, package_tep_name," - " package_zip_mount_file, install_location, package_size," - " package_removable, package_preload, package_readonly," - " package_update, package_appsetting, package_nodisplay," - " package_system, author_name, author_email, author_href," - " installed_time, installed_storage, storeclient_id," - " mainapp_id, package_url, root_path, external_path," - " csc_path, package_support_mode, package_support_disable," - " light_user_switch_mode)" - "VALUES (?, ?," - " ?, ?, ?," - " ?, ?, ?," - " LOWER(?), LOWER(?), LOWER(?)," - " LOWER(?), LOWER(?), LOWER(?)," - " LOWER(?), ?, ?, ?," - " ?, ?, ?," - " ?, ?, ?, ?," - " ?, ?, LOWER(?), ?)"; - int ret; - sqlite3_stmt *stmt; - int idx = 1; - const char *author_name = NULL; - const char *author_email = NULL; - const char *author_href = NULL; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - if (mfx->author && mfx->author->data) { - author_name = ((author_x *)mfx->author->data)->text; - author_email = ((author_x *)mfx->author->data)->email; - author_href = ((author_x *)mfx->author->data)->href; - } - - __BIND_TEXT(db, stmt, idx++, mfx->package); - __BIND_TEXT(db, stmt, idx++, mfx->type); - __BIND_TEXT(db, stmt, idx++, mfx->version); - __BIND_TEXT(db, stmt, idx++, mfx->api_version); - __BIND_TEXT(db, stmt, idx++, mfx->tep_name); - __BIND_TEXT(db, stmt, idx++, mfx->zip_mount_file); - __BIND_TEXT(db, stmt, idx++, mfx->installlocation); - __BIND_TEXT(db, stmt, idx++, mfx->package_size); - __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->removable, true)); - __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->preload, false)); - __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->readonly, false)); - __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->update, false)); - __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->appsetting, false)); - __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->nodisplay_setting, false)); - __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->system, false)); - __BIND_TEXT(db, stmt, idx++, author_name); - __BIND_TEXT(db, stmt, idx++, author_email); - __BIND_TEXT(db, stmt, idx++, author_href); - __BIND_TEXT(db, stmt, idx++, mfx->installed_time); - __BIND_TEXT(db, stmt, idx++, mfx->installed_storage); - __BIND_TEXT(db, stmt, idx++, mfx->storeclient_id); - __BIND_TEXT(db, stmt, idx++, mfx->mainapp_id); - __BIND_TEXT(db, stmt, idx++, mfx->package_url); - __BIND_TEXT(db, stmt, idx++, mfx->root_path); - __BIND_TEXT(db, stmt, idx++, mfx->external_path); - __BIND_TEXT(db, stmt, idx++, mfx->csc_path); - __BIND_TEXT(db, stmt, idx++, - mfx->support_mode ? mfx->support_mode : "0"); - __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->support_disable, false)); - __BIND_TEXT(db, stmt, idx++, mfx->light_user_switch_mode); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_finalize(stmt); - - if (__insert_package_update_info(db, mfx)) - return -1; - if (__insert_package_localized_info(db, mfx)) - return -1; - if (__insert_application_info(db, mfx)) - return -1; - if (__insert_package_privilege_info(db, mfx)) - return -1; - if (__insert_package_appdefined_privilege_info(db, mfx)) - return -1; - if (__insert_package_dependency_info(db, mfx)) - return -1; - if (__insert_package_res_info(db, mfx)) - return -1; - - return 0; -} - -static int __delete_package_info(sqlite3 *db, const char *pkgid) -{ - static const char query[] = - "DELETE FROM package_info WHERE package=?"; - int ret; - sqlite3_stmt *stmt; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _LOGE("prepare failed: %s", sqlite3_errmsg(db)); - return -1; - } - - __BIND_TEXT(db, stmt, 1, pkgid); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - _LOGE("step failed: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_finalize(stmt); - - return 0; -} - -API int pkgmgr_parser_delete_pkg_info(sqlite3 *db, - const char *package, uid_t uid) -{ - if (db == NULL || package == NULL) { - _LOGE("invalid parameter"); - return PM_PARSER_R_EINVAL; - } - - __BEGIN_TRANSACTION(db); - __DO_TRANSACTION(db, __delete_package_info(db, package)); - __END_TRANSACTION(db); - - return PM_PARSER_R_OK; -} - -API int pkgmgr_parser_update_pkg_info(sqlite3 *db, manifest_x *mfx, uid_t uid) -{ - if (db == NULL || mfx == NULL) { - _LOGE("invalid parameter"); - return PM_PARSER_R_EINVAL; - } - - __BEGIN_TRANSACTION(db); - __DO_TRANSACTION(db, __delete_package_info(db, mfx->package)); - __DO_TRANSACTION(db, __insert_package_info(db, mfx)); - __END_TRANSACTION(db); - - return PM_PARSER_R_OK; -} - -API int pkgmgr_parser_insert_pkg_info(sqlite3 *db, manifest_x *mfx, uid_t uid) -{ - if (db == NULL || mfx == NULL) { - _LOGE("invalid parameter"); - return PM_PARSER_R_EINVAL; - } - - __BEGIN_TRANSACTION(db); - __DO_TRANSACTION(db, __insert_package_info(db, mfx)); - __END_TRANSACTION(db); - - return PM_PARSER_R_OK; -} diff --git a/src/server/pkginfo_internal.cc b/src/server/pkginfo_internal.cc new file mode 100644 index 0000000..4399f88 --- /dev/null +++ b/src/server/pkginfo_internal.cc @@ -0,0 +1,2160 @@ +/* +* Copyright (c) 2023 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "pkgmgr_parser.h" +#include "pkgmgrinfo_basic.h" +#include "pkgmgrinfo_internal.h" +#include "pkgmgrinfo_private.h" +#include "pkgmgrinfo_debug.h" +#include "pkgmgr-info.h" + +namespace { + +constexpr const char LDPI[] = "ldpi"; +constexpr const char MDPI[] = "mdpi"; +constexpr const char HDPI[] = "hdpi"; +constexpr const char XHDPI[] = "xhdpi"; +constexpr const char XXHDPI[] = "xxhdpi"; + +constexpr const int LDPI_MIN = 0; +constexpr const int LDPI_MAX = 240; +constexpr const int MDPI_MIN = 241; +constexpr const int MDPI_MAX = 300; +constexpr const int HDPI_MIN = 301; +constexpr const int HDPI_MAX = 380; +constexpr const int XHDPI_MIN = 381; +constexpr const int XHDPI_MAX = 480; +constexpr const int XXHDPI_MIN = 481; +constexpr const int XXHDPI_MAX = 600; + +constexpr const char join_localized_info[] = + " LEFT OUTER JOIN package_localized_info" + " ON pi.package=package_localized_info.package" + " AND package_localized_info.package_locale=?"; +constexpr const char join_privilege_info[] = + " LEFT OUTER JOIN package_privilege_info" + " ON pi.package=package_privilege_info.package"; +constexpr const char join_res_info[] = + " LEFT OUTER JOIN package_res_info" + " ON pi.package=package_res_info.package"; + +char* GetCString(int idx, const tizen_base::Database::Result::Record& rec) { + std::optional str = rec.GetString(idx); + if (!str) + return nullptr; + + return strdup(str->c_str()); +} + +int _pkginfo_add_description_info_into_list(const char *locale, + char *record, GList **description) { + description_x *info; + + info = reinterpret_cast(calloc(1, sizeof(description_x))); + if (info == NULL) { + LOGE("out of memory"); + return PMINFO_R_ERROR; + } + info->lang = strdup(locale); + info->text = record; + *description = g_list_prepend(*description, info); + + return PMINFO_R_OK; +} + +int GetPluginExecutionInfo(const tizen_base::Database& db, + const char* pkgid, GList** plugins) { + auto q = tizen_base::Database::Sql( + "SELECT appid, plugin_type, plugin_name FROM package_plugin_info " + "WHERE pkgid=?") + .Bind(pkgid); + + auto r = db.Exec(q); + if (!r) { + LOGE("db.Exec failed : %s", static_cast(r)); + return PMINFO_R_ERROR; + } + + for (const auto& rec : r) { + plugin_x* plugin = reinterpret_cast( + calloc(1, sizeof(plugin_x))); + if (!plugin) { + LOGE("out of memory"); + return PMINFO_R_ERROR; + } + + plugin->pkgid = strdup(pkgid); + plugin->appid = GetCString(0, rec); + plugin->plugin_type = GetCString(1, rec); + plugin->plugin_name = GetCString(2, rec); + *plugins = g_list_prepend(*plugins, (gpointer)plugin); + } + + return PMINFO_R_OK; +} + +int GetPrivilege(const tizen_base::Database& db, const char* pkgid, + GList** privileges) { + auto q = tizen_base::Database::Sql( + "SELECT DISTINCT privilege, type FROM package_privilege_info " + "WHERE package=?") + .Bind(pkgid); + auto r = db.Exec(q); + if (!r) { + LOGE("db.Exec failed : %s", static_cast(r)); + return PMINFO_R_ERROR; + } + + for (const auto& rec : r) { + privilege_x* privilege = reinterpret_cast( + calloc(1, sizeof(privilege_x))); + if (!privilege) { + LOGE("failed to alloc memory"); + return PMINFO_R_ERROR; + } + + privilege->value = GetCString(0, rec); + privilege->type = GetCString(1, rec); + *privileges = g_list_prepend(*privileges, (gpointer)privilege); + } + + return PMINFO_R_OK; +} + +int GetAppdefinedPrivilege(const tizen_base::Database& db, + const char* pkgid, GList** privileges) { + auto q = tizen_base::Database::Sql( + "SELECT DISTINCT privilege, license, type FROM " + "package_appdefined_privilege_info WHERE package=?") + .Bind(pkgid); + auto r = db.Exec(q); + if (!r) { + LOGE("db.Exec failed : %s", static_cast(r)); + return PMINFO_R_ERROR; + } + + for (const auto& rec : r) { + appdefined_privilege_x* privilege = reinterpret_cast< + appdefined_privilege_x*>(calloc(1, sizeof(appdefined_privilege_x))); + if (!privilege) { + LOGE("failed to alloc memory"); + return PMINFO_R_ERROR; + } + + privilege->value = GetCString(0, rec); + privilege->license = GetCString(1, rec); + privilege->type = GetCString(2, rec); + *privileges = g_list_prepend(*privileges, (gpointer)privilege); + } + + return PMINFO_R_OK; +} + +int GetDependency(const tizen_base::Database& db, const char* pkgid, + GList** dependencies) { + auto q = tizen_base::Database::Sql( + "SELECT DISTINCT depends_on, type, required_version " + "FROM package_dependency_info WHERE package=?") + .Bind(pkgid); + auto r = db.Exec(q); + if (!r) { + LOGE("db.Exec failed : %s", static_cast(r)); + return PMINFO_R_ERROR; + } + + for (const auto& rec : r) { + dependency_x* dependency = reinterpret_cast< + dependency_x*>(calloc(1, sizeof(dependency_x))); + if (!dependency) { + LOGE("failed to alloc memory"); + return PMINFO_R_ERROR; + } + + dependency->depends_on = GetCString(0, rec); + dependency->type = GetCString(1, rec); + dependency->required_version = GetCString(2, rec); + *dependencies = g_list_prepend(*dependencies, (gpointer)dependency); + } + + return PMINFO_R_OK; +} + +int GetResAllowedPackages(const tizen_base::Database& db, const char* pkgid, + GList** allowed_packages) { + auto q = tizen_base::Database::Sql( + "SELECT DISTINCT allowed_package, required_privilege " + "FROM package_res_allowed_package WHERE package=?") + .Bind(pkgid); + auto r = db.Exec(q); + if (!r) { + LOGE("db.Exec failed : %s", static_cast(r)); + return PMINFO_R_ERROR; + } + + for (const auto& rec : r) { + res_allowed_package_x* allowed_package_x = nullptr; + char* package = nullptr; + char* privilege = nullptr; + + package = GetCString(0, rec); + if (!package) + continue; + + for (GList* l = *allowed_packages; l; l = l->next) { + allowed_package_x = (res_allowed_package_x *)l->data; + if (!strcmp(package, (char *)l->data)) + break; + allowed_package_x = nullptr; + } + + if (allowed_package_x) { + free(package); + } else { + allowed_package_x = reinterpret_cast(calloc(1, + sizeof(res_allowed_package_x))); + if (allowed_package_x == nullptr) { + LOGE("failed to alloc memory"); + free(package); + return PMINFO_R_ERROR; + } + allowed_package_x->allowed_package = package; + *allowed_packages = g_list_prepend(*allowed_packages, + (gpointer)allowed_package_x); + } + + privilege = GetCString(1, rec); + if (!privilege) + continue; + + allowed_package_x->required_privileges = g_list_prepend( + allowed_package_x->required_privileges, + privilege); + } + + return PMINFO_R_OK; +} + +int GetResInfo(const tizen_base::Database& db, const char* pkgid, + char** res_type, char** res_version, + GList** res_allowed_packages) { + auto q = tizen_base::Database::Sql( + "SELECT DISTINCT res_type, res_version " + "FROM package_res_info WHERE package=?") + .Bind(pkgid); + auto r = db.Exec(q); + if (!r) { + LOGE("db.Exec() failed : %s", static_cast(r)); + return PMINFO_R_ERROR; + } + + auto rec = r.GetFirstRecord(); + if (!rec) + return PMINFO_R_OK; + + if (GetResAllowedPackages(db, pkgid, res_allowed_packages) != PMINFO_R_OK) + return PMINFO_R_ERROR; + + *res_type = GetCString(0, *rec); + *res_version = GetCString(1, *rec); + + return PMINFO_R_OK; +} + +int _get_filtered_query(pkgmgrinfo_filter_x *filter, + const std::string& locale, uid_t uid, + std::string& query, std::vector& bind_params) { + if (!filter) + return PMINFO_R_OK; + + int joined = 0; + if (filter->cache_flag) { + joined = E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO | + E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO | + E_PMINFO_PKGINFO_JOIN_RES_INFO; + } + + std::string buf = " WHERE 1=1 "; + GList *tmp_params = nullptr; + for (GSList* list = filter->list; list; list = list->next) { + char* condition = nullptr; + joined |= __get_filter_condition(list->data, uid, &condition, + &tmp_params); + if (condition == nullptr) + continue; + + buf += " AND "; + buf += condition; + free(condition); + } + + std::string buf2; + if (joined & E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO) { + buf2 += join_localized_info; + bind_params.push_back(locale); + } + + if (joined & E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO) + buf2 += join_privilege_info; + if (joined & E_PMINFO_PKGINFO_JOIN_RES_INFO) + buf2 += join_res_info; + + for (GList* l = tmp_params; l != nullptr; l = l->next) + bind_params.push_back(reinterpret_cast(l->data)); + + query = buf2 + buf; + g_list_free_full(tmp_params, free); + + return PMINFO_R_OK; +} + +bool CheckPackageStorageStatus(pkgmgrinfo_filter_x* tmp_filter) { + GSList* tmp_list = nullptr; + pkgmgrinfo_node_x* tmp_node = nullptr; + int property = -1; + + if (tmp_filter->cache_flag) + return false; + + property = _pminfo_pkginfo_convert_to_prop_bool( + PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE); + for (tmp_list = tmp_filter->list; tmp_list != nullptr; + tmp_list = g_slist_next(tmp_list)) { + tmp_node = reinterpret_cast(tmp_list->data); + if (property == tmp_node->prop) { + if (strcmp(tmp_node->value, "true") == 0) + return true; + else + return false; + } + } + return true; +} + +int DoGetPkgInfo(const tizen_base::Database& db, uid_t uid, + const std::string& locale, pkgmgrinfo_filter_x* filter, int flag, + std::map>& packages) { + static const char query_raw[] = + "SELECT DISTINCT pi.package, pi.installed_storage, pi.external_path"; + static const char query_basic[] = + ", 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.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, pi.package_support_mode, pi.package_disable, " + "pi.light_user_switch_mode"; + static const char query_author[] = + ", pi.author_name, pi.author_email, pi.author_href"; + static const char query_label[] = + ", COALESCE(" + "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale=?), " + "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))"; + static const char query_icon[] = + ", COALESCE(" + "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale=?), " + "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))"; + static const char query_description[] = + ", COALESCE(" + "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale=?), " + "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))"; + static const char query_res_type[] = + ", (SELECT res_type FROM package_res_info WHERE pi.package=package)"; + static const char query_res_version[] = + ", (SELECT res_version FROM package_res_info WHERE pi.package=package)"; + static const char query_from_clause[] = " FROM package_info as pi"; + int ret = PMINFO_R_ERROR; + char* tmp_record = nullptr; + std::vector bind_params; + bool is_check_storage = true; + const uid_t global_user_uid = GLOBAL_USER; + + if (!static_cast(db) || locale.empty() || filter == nullptr) { + LOGE("Invalid parameter"); + return PMINFO_R_EINVAL; + } + + is_check_storage = CheckPackageStorageStatus(filter); + std::string query = query_raw; + if (flag & PMINFO_APPINFO_GET_BASICINFO) + query += query_basic; + if (flag & PMINFO_PKGINFO_GET_AUTHOR) + query += query_author; + if (flag & PMINFO_PKGINFO_GET_LABEL) { + query += query_label; + bind_params.push_back(locale); + } + + if (flag & PMINFO_PKGINFO_GET_ICON) { + query += query_icon; + bind_params.push_back(locale); + } + + if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) { + query += query_description; + bind_params.push_back(locale); + } + + if (flag & PMINFO_PKGINFO_GET_RES_INFO) { + query += query_res_type; + query += query_res_version; + } + + query += query_from_clause; + std::string constraints; + ret = _get_filtered_query(filter, locale, uid, + constraints, bind_params); + if (ret != PMINFO_R_OK) { + LOGE("Failed to get WHERE clause"); + return PMINFO_R_EINVAL; + } + + if (!constraints.empty()) + query += constraints; + + auto q = tizen_base::Database::Sql(query); + for (auto& i : bind_params) + q.Bind(i); + + auto r = db.Exec(q); + if (!r) { + LOGE("db.Exec failed : %s", static_cast(r)); + return PMINFO_R_ERROR; + } + + for (const auto& rec : r) { + package_x* info = reinterpret_cast(calloc(1, sizeof(package_x))); + if (info == nullptr) { + LOGE("out of memory"); + return PMINFO_R_ERROR; + } + + std::shared_ptr pkg(info, pkgmgrinfo_basic_free_package); + info->locale = strdup(locale.c_str()); + if (info->locale == nullptr) { + LOGE("Out of memory"); + return PMINFO_R_ERROR; + } + + int idx = 0; + // Temp impl + info->package = GetCString(idx++, rec); + info->installed_storage = GetCString(idx++, rec); + info->external_path = GetCString(idx++, rec); + if (flag & PMINFO_APPINFO_GET_BASICINFO) { + info->version = GetCString(idx++, rec); + info->installlocation = GetCString(idx++, rec); + info->removable = GetCString(idx++, rec); + info->preload = GetCString(idx++, rec); + info->readonly = GetCString(idx++, rec); + info->update = GetCString(idx++, rec); + info->appsetting = GetCString(idx++, rec); + info->system = GetCString(idx++, rec); + info->type = GetCString(idx++, rec); + info->package_size = GetCString(idx++, rec); + info->installed_time = GetCString(idx++, rec); + info->storeclient_id = GetCString(idx++, rec); + info->mainapp_id = GetCString(idx++, rec); + info->package_url = GetCString(idx++, rec); + info->root_path = GetCString(idx++, rec); + info->csc_path = GetCString(idx++, rec); + info->nodisplay_setting = GetCString(idx++, rec); + info->api_version = GetCString(idx++, rec); + info->support_disable = GetCString(idx++, rec); + info->tep_name = GetCString(idx++, rec); + info->zip_mount_file = GetCString(idx++, rec); + info->support_mode = GetCString(idx++, rec); + info->is_disabled = GetCString(idx++, rec); + info->light_user_switch_mode = GetCString(idx++, rec); + } + + info->for_all_users = + strdup((uid != global_user_uid) ? "false" : "true"); + + if (GetPluginExecutionInfo(db, info->package, &info->plugin)) + return PMINFO_R_ERROR; + + if (flag & PMINFO_PKGINFO_GET_AUTHOR) { + author_x* author = reinterpret_cast(calloc(1, sizeof(author_x))); + if (author == nullptr) { + return PMINFO_R_ERROR; + } + author->text = GetCString(idx++, rec); + author->email = GetCString(idx++, rec); + author->href = GetCString(idx++, rec); + info->author = g_list_prepend(info->author, author); + } + + if (flag & PMINFO_PKGINFO_GET_LABEL) { + tmp_record = GetCString(idx++, rec); + if (_add_label_info_into_list(locale.c_str(), + tmp_record, &info->label)) { + return PMINFO_R_ERROR; + } + } + + if (flag & PMINFO_PKGINFO_GET_ICON) { + tmp_record = GetCString(idx++, rec); + if (_add_icon_info_into_list(locale.c_str(), + tmp_record, &info->icon)) { + return PMINFO_R_ERROR; + } + } + + if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) { + tmp_record = GetCString(idx++, rec); + if (_pkginfo_add_description_info_into_list(locale.c_str(), + tmp_record, &info->description)) { + return PMINFO_R_ERROR; + } + } + + if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) { + if (GetPrivilege(db, info->package, &info->privileges)) + return PMINFO_R_ERROR; + } + + if (flag & PMINFO_PKGINFO_GET_APPDEFINED_PRIVILEGE) { + if (GetAppdefinedPrivilege(db, info->package, + &info->appdefined_privileges)) { + return PMINFO_R_ERROR; + } + } + + if (flag & PMINFO_PKGINFO_GET_DEPENDENCY) { + if (GetDependency(db, info->package, &info->dependencies)) + return PMINFO_R_ERROR; + } + + if (flag & PMINFO_PKGINFO_GET_RES_INFO) { + if (GetResInfo(db, info->package, &info->res_type, + &info->res_version, &info->res_allowed_packages) < 0) { + return PMINFO_R_ERROR; + } + } + + if (is_check_storage && __pkginfo_check_installed_storage(info) != + PMINFO_R_OK) + continue; + + packages[info->package] = std::move(pkg); + } + + return PMINFO_R_OK; +} + +int DoGetDependsOn(const tizen_base::Database& db, const std::string& pkgid, + std::queue& queue, std::set& dup_checker, + std::vector& dep_list) { + if (dup_checker.find(pkgid) != dup_checker.end()) + return PMINFO_R_OK; + dup_checker.insert(pkgid); + + auto q = tizen_base::Database::Sql( + "SELECT package, depends_on, type, required_version " + "FROM package_dependency_info WHERE depends_on=?") + .Bind(pkgid); + auto r = db.Exec(q); + + if (!r) { + LOGE("db.Exec() failed : %s", static_cast(r)); + return PMINFO_R_ERROR; + } + + for (const auto& rec : r) { + auto* req = reinterpret_cast(calloc(1, sizeof(dependency_x))); + if (req == nullptr) { + LOGE("out of memory"); + return PMINFO_R_ERROR; + } + + req->pkgid = GetCString(0, rec); + req->depends_on = GetCString(1, rec); + req->type = GetCString(2, rec); + req->required_version = GetCString(3, rec); + + dep_list.push_back(req); + queue.push(req->pkgid); + } + + return PMINFO_R_OK; +} + +void __free_depends_on(dependency_x* dep) { + free(dep->pkgid); + free(dep->depends_on); + free(dep->type); + free(dep->required_version); + free(dep); +} + +int DoExecuteQuery(const tizen_base::Database& db, const std::string& query, + const std::vector>& param) { + auto q = tizen_base::Database::Sql(query); + for (auto& p : param) { + if (p) + q.Bind(*p); + else + q.Bind(std::nullopt); + } + + auto r = db.Exec(q); + if (!r) { + LOGE("db.Exec() failed : %s", static_cast(r)); + return PMINFO_R_ERROR; + } + + return PMINFO_R_OK; +} + +int __check_dpi(const char *dpi_char, int dpi_int) { + if (dpi_char == NULL) + return -1; + + if (strcasecmp(dpi_char, LDPI) == 0) { + if (dpi_int >= LDPI_MIN && dpi_int <= LDPI_MAX) + return 0; + else + return -1; + } else if (strcasecmp(dpi_char, MDPI) == 0) { + if (dpi_int >= MDPI_MIN && dpi_int <= MDPI_MAX) + return 0; + else + return -1; + } else if (strcasecmp(dpi_char, HDPI) == 0) { + if (dpi_int >= HDPI_MIN && dpi_int <= HDPI_MAX) + return 0; + else + return -1; + } else if (strcasecmp(dpi_char, XHDPI) == 0) { + if (dpi_int >= XHDPI_MIN && dpi_int <= XHDPI_MAX) + return 0; + else + return -1; + } else if (strcasecmp(dpi_char, XXHDPI) == 0) { + if (dpi_int >= XXHDPI_MIN && dpi_int <= XXHDPI_MAX) + return 0; + else + return -1; + } else + return -1; +} + +void __find_appcontrol_splashscreen_with_dpi(gpointer data, + gpointer user_data) { + splashscreen_x *ss = (splashscreen_x *)data; + GList **list = (GList **)user_data; + int dpi = -1; + int ret; + + if (ss->operation == NULL || ss->dpi == NULL) + return; + + ret = system_info_get_platform_int( + "http://tizen.org/feature/screen.dpi", &dpi); + if (ret != SYSTEM_INFO_ERROR_NONE) + return; + + if (__check_dpi(ss->dpi, dpi) != 0) + return; + + *list = g_list_prepend(*list, ss); +} + +void __find_appcontrol_splashscreen(gpointer data, gpointer user_data) { + splashscreen_x *ss = (splashscreen_x *)data; + GList **list = (GList **)user_data; + splashscreen_x *ss_tmp; + GList *tmp; + + if (ss->operation == NULL || ss->dpi) + return; + + for (tmp = *list; tmp; tmp = tmp->next) { + ss_tmp = (splashscreen_x *)tmp->data; + if (ss_tmp->operation + && strcmp(ss_tmp->operation, ss->operation) == 0 + && strcmp(ss_tmp->orientation, ss->orientation) == 0) + return; + } + + *list = g_list_prepend(*list, ss); +} + +gint __compare_splashscreen_with_orientation_dpi(gconstpointer a, + gconstpointer b) { + splashscreen_x *ss = (splashscreen_x *)a; + const char *orientation = (const char *)b; + int dpi = -1; + int ret; + + if (ss->operation || ss->dpi == NULL) + return -1; + + ret = system_info_get_platform_int( + "http://tizen.org/feature/screen.dpi", &dpi); + if (ret != SYSTEM_INFO_ERROR_NONE) + return -1; + + if (strcasecmp(ss->orientation, orientation) == 0 && + __check_dpi(ss->dpi, dpi) == 0) + return 0; + + return -1; +} + +gint __compare_splashscreen_with_orientation(gconstpointer a, + gconstpointer b) { + splashscreen_x *ss = (splashscreen_x *)a; + const char *orientation = (const char *)b; + + if (ss->operation || ss->dpi) + return -1; + + if (strcasecmp(ss->orientation, orientation) == 0) + return 0; + + return -1; +} + +splashscreen_x *__find_default_splashscreen(GList *splashscreens, + const char *orientation) { + GList *tmp; + + tmp = g_list_find_custom(splashscreens, orientation, + (GCompareFunc) + __compare_splashscreen_with_orientation_dpi); + if (tmp) + return (splashscreen_x *)tmp->data; + + tmp = g_list_find_custom(splashscreens, orientation, + (GCompareFunc)__compare_splashscreen_with_orientation); + if (tmp) + return (splashscreen_x *)tmp->data; + + return NULL; +} + +GList *__find_splashscreens(GList *splashscreens) { + GList *list = NULL; + splashscreen_x *ss; + + if (splashscreens == NULL) + return NULL; + + g_list_foreach(splashscreens, + __find_appcontrol_splashscreen_with_dpi, &list); + g_list_foreach(splashscreens, + __find_appcontrol_splashscreen, &list); + + ss = __find_default_splashscreen(splashscreens, "portrait"); + if (ss) + list = g_list_prepend(list, ss); + ss = __find_default_splashscreen(splashscreens, "landscape"); + if (ss) + list = g_list_prepend(list, ss); + + return list; +} + +int InsertSplashscreenInfo(const tizen_base::Database& db, + application_x *app, GList *ss_list) { + if (app->splashscreens == nullptr) + return 0; + + if (ss_list == nullptr) + return 0; + + auto q = tizen_base::Database::Sql( + "INSERT INTO package_app_splash_screen (app_id, src, type," + " orientation, indicatordisplay, operation, color_depth) " + "VALUES (?, ?, ?, ?, ?, ?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + for (GList* tmp = ss_list; tmp; tmp = tmp->next) { + splashscreen_x* ss = reinterpret_cast(tmp->data); + if (ss == nullptr) + continue; + q.Reset() + .Bind(app->appid) + .Bind(ss->src) + .Bind(ss->type) + .Bind(ss->orientation) + .Bind(ss->indicatordisplay) + .Bind(ss->operation) + .Bind(ss->color_depth); + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed"); + return -1; + } + } + + return 0; +} + +void __trimfunc(GList *trim_list) { + char *trim_data; + char *prev = NULL; + GList *list = g_list_first(trim_list); + + while (list) { + trim_data = (char *)list->data; + if (trim_data) { + if (prev) { + if (strcmp(trim_data, prev) == 0) { + trim_list = g_list_remove(trim_list, + trim_data); + list = g_list_first(trim_list); + prev = NULL; + continue; + } else + prev = trim_data; + } else { + prev = trim_data; + } + } + list = g_list_next(list); + } +} + +int InsertPackageAppdefinedPrivilegeInfo(const tizen_base::Database& db, + manifest_x* mfx) { + auto q = tizen_base::Database::Sql( + "INSERT INTO package_appdefined_privilege_info " + "(package, privilege, license, type) " + "VALUES (?, ?, ?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + for (GList* tmp = mfx->appdefined_privileges; tmp; tmp = tmp->next) { + appdefined_privilege_x* priv = + reinterpret_cast(tmp->data); + if (priv == nullptr) + continue; + + q.Reset() + .Bind(mfx->package) + .Bind(priv->value) + .Bind(priv->license) + .Bind(priv->type); + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed"); + return -1; + } + } + + return 0; +} + +int InsertPackageDependencyInfo(const tizen_base::Database& db, + manifest_x *mfx) { + auto q = tizen_base::Database::Sql( + "INSERT INTO package_dependency_info" + " (package, depends_on, type, required_version) " + "VALUES (?, ?, ?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + for (GList* tmp = mfx->dependencies; tmp; tmp = tmp->next) { + dependency_x* dep = reinterpret_cast(tmp->data); + if (dep == nullptr) + continue; + + q.Reset() + .Bind(mfx->package) + .Bind(dep->depends_on) + .Bind(dep->type) + .Bind(dep->required_version); + + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed"); + return -1; + } + } + + return 0; +} + +int InsertMainappLocalizedInfo(const tizen_base::Database& db, + application_x* app, const char* locale, const char* label, + const char* icon) { + auto q = tizen_base::Database::Sql( + "INSERT OR REPLACE INTO package_localized_info (" + " package, package_locale, package_label, package_icon," + " package_description, package_license, package_author) " + "VALUES (?, ?," + " COALESCE((SELECT package_label FROM package_localized_info" + " WHERE package=? AND package_locale=?), ?)," + " COALESCE((SELECT package_icon FROM package_localized_info" + " WHERE package=? AND package_icon=?), ?)," + " (SELECT package_description FROM package_localized_info" + " WHERE package=? AND package_locale=?)," + " (SELECT package_description FROM package_localized_info" + " WHERE package=? AND package_locale=?)," + " (SELECT package_description FROM package_localized_info" + " WHERE package=? AND package_locale=?))") + .Bind(app->package) + .Bind(locale) + .Bind(app->package) + .Bind(locale) + .Bind(label) + .Bind(app->package) + .Bind(locale) + .Bind(icon) + .Bind(app->package) + .Bind(locale) + .Bind(app->package) + .Bind(locale) + .Bind(app->package) + .Bind(locale); + auto r = db.Exec(q); + if (!r) { + _LOGE("db.Exec() failed: %s", static_cast(r)); + return -1; + } + + return 0; +} + +gint __comparefunc(gconstpointer a, gconstpointer b, gpointer userdata) { + if (a == NULL || b == NULL) + return 0; + if (strcmp((char *)a, (char *)b) == 0) + return 0; + if (strcmp((char *)a, (char *)b) < 0) + return -1; + if (strcmp((char *)a, (char *)b) > 0) + return 1; + return 0; +} + +GList *__create_locale_list(GList *lbls, GList *lcns, GList *icns, + GList *dcns, GList *aths) { + GList *locale = NULL; + GList *tmp; + label_x *lbl; + license_x *lcn; + icon_x *icn; + description_x *dcn; + author_x *ath; + + for (tmp = lbls; tmp; tmp = tmp->next) { + lbl = (label_x *)tmp->data; + if (lbl == NULL) + continue; + if (lbl->lang) + locale = g_list_insert_sorted_with_data( + locale, (gpointer)lbl->lang, + __comparefunc, NULL); + } + for (tmp = lcns; tmp; tmp = tmp->next) { + lcn = (license_x *)tmp->data; + if (lcn == NULL) + continue; + if (lcn->lang) + locale = g_list_insert_sorted_with_data( + locale, (gpointer)lcn->lang, + __comparefunc, NULL); + } + for (tmp = icns; tmp; tmp = tmp->next) { + icn = (icon_x *)tmp->data; + if (icn == NULL) + continue; + if (icn->lang) + locale = g_list_insert_sorted_with_data( + locale, (gpointer)icn->lang, + __comparefunc, NULL); + } + for (tmp = dcns; tmp; tmp = tmp->next) { + dcn = (description_x *)tmp->data; + if (dcn == NULL) + continue; + if (dcn->lang) + locale = g_list_insert_sorted_with_data( + locale, (gpointer)dcn->lang, + __comparefunc, NULL); + } + for (tmp = aths; tmp; tmp = tmp->next) { + ath = (author_x *)tmp->data; + if (ath == NULL) + continue; + if (ath->lang) + locale = g_list_insert_sorted_with_data( + locale, (gpointer)ath->lang, + __comparefunc, NULL); + } + __trimfunc(locale); + return locale; +} + +gint __check_icon_resolution(std::string_view orig_icon_path, + char **new_icon_path) { + const char* dpi_path[2]; + std::string modified_iconpath; + if (orig_icon_path.empty()) + return -1; + + int dpi = -1; + int ret = system_info_get_platform_int( + "http://tizen.org/feature/screen.dpi", &dpi); + if (ret != SYSTEM_INFO_ERROR_NONE) + return -1; + + if (dpi >= LDPI_MIN && dpi <= LDPI_MAX) { + dpi_path[0] = "LDPI"; + dpi_path[1] = "ldpi"; + } else if (dpi >= MDPI_MIN && dpi <= MDPI_MAX) { + dpi_path[0] = "MDPI"; + dpi_path[1] = "mdpi"; + } else if (dpi >= HDPI_MIN && dpi <= HDPI_MAX) { + dpi_path[0] = "HDPI"; + dpi_path[1] = "hdpi"; + } else if (dpi >= XHDPI_MIN && dpi <= XHDPI_MAX) { + dpi_path[0] = "XHDPI"; + dpi_path[1] = "xhdpi"; + } else if (dpi >= XXHDPI_MIN && dpi <= XXHDPI_MAX) { + dpi_path[0] = "XXHDPI"; + dpi_path[1] = "xxhdpi"; + } else { + _LOGE("Unidentified dpi[%d]", dpi); + return -1; + } + + auto pos = orig_icon_path.rfind('/'); + if (pos == std::string::npos) + return -1; + std::string_view icon_filename = orig_icon_path.substr(pos); + + for (int i = 0; i < 2; i++) { + modified_iconpath = std::string(orig_icon_path) + + "/" + dpi_path[i] + std::string(icon_filename); + if (access(modified_iconpath.c_str(), F_OK) != -1) { + *new_icon_path = strdup(modified_iconpath.c_str()); + return 0; + } + } + + return -1; +} + +gint __compare_icon(gconstpointer a, gconstpointer b) { + icon_x *icon = (icon_x *)a; + char *icon_path; + + if (icon->lang != NULL && strcasecmp(icon->lang, DEFAULT_LOCALE) != 0) + return -1; + + if (icon->dpi != NULL) + return -1; + + if (__check_icon_resolution(icon->text, &icon_path) == 0) { + free(icon->text); + icon->text = icon_path; + } + + return 0; +} + +gint __compare_icon_with_lang(gconstpointer a, gconstpointer b) { + icon_x *icon = (icon_x *)a; + char *lang = (char *)b; + char *icon_path; + + if (icon->dpi != NULL) + return -1; + + if (strcasecmp(icon->lang, lang) == 0) { + if (strcasecmp(icon->lang, DEFAULT_LOCALE) == 0) { + /* icon for no locale. check existance of + * folder-hierachied default icons + */ + if (__check_icon_resolution(icon->text, + &icon_path) == 0) { + free(icon->text); + icon->text = icon_path; + } + } + return 0; + } + + return -1; +} + +gint __compare_icon_with_dpi(gconstpointer a, gconstpointer b) { + icon_x *icon = (icon_x *)a; + int dpi = GPOINTER_TO_INT(b); + + if (icon->lang != NULL && strcasecmp(icon->lang, DEFAULT_LOCALE) != 0) + return -1; + + if (icon->dpi == NULL) + return -1; + + if (__check_dpi(icon->dpi, dpi) == 0) + return 0; + + return -1; +} + +gint __compare_icon_with_lang_dpi(gconstpointer a, gconstpointer b) { + int ret; + icon_x *icon = (icon_x *)a; + char *lang = (char *)b; + int dpi = -1; + + ret = system_info_get_platform_int( + "http://tizen.org/feature/screen.dpi", &dpi); + if (ret != SYSTEM_INFO_ERROR_NONE) + return -1; + + if (strcasecmp(icon->lang, lang) == 0 && + __check_dpi(icon->dpi, dpi) == 0) + return 0; + + return -1; +} + +char *__find_icon(GList *icons, const char *lang) { + GList *tmp; + icon_x *icon; + int dpi = 0; + int ret; + + /* first, find icon whose locale and dpi with given lang and + * system's dpi has matched + */ + tmp = g_list_find_custom(icons, lang, + (GCompareFunc)__compare_icon_with_lang_dpi); + if (tmp != NULL) { + icon = (icon_x *)tmp->data; + return (char *)icon->text; + } + + /* if first has failed, find icon whose locale has matched */ + tmp = g_list_find_custom(icons, lang, + (GCompareFunc)__compare_icon_with_lang); + if (tmp != NULL) { + icon = (icon_x *)tmp->data; + return (char *)icon->text; + } + + /* if second has failed, find icon whose dpi has matched with + * system's dpi + */ + ret = system_info_get_platform_int( + "http://tizen.org/feature/screen.dpi", &dpi); + if (ret == SYSTEM_INFO_ERROR_NONE) { + tmp = g_list_find_custom(icons, GINT_TO_POINTER(dpi), + (GCompareFunc)__compare_icon_with_dpi); + if (tmp != NULL) { + icon = (icon_x *)tmp->data; + return (char *)icon->text; + } + } + + /* last, find default icon marked as "No Locale" */ + tmp = g_list_find_custom(icons, NULL, (GCompareFunc)__compare_icon); + if (tmp != NULL) { + icon = (icon_x *)tmp->data; + return (char *)icon->text; + } + + return NULL; +} + +void __extract_data(const char *locale, GList *lbls, GList *lcns, + GList *icns, GList *dcns, GList *aths, char **label, + char **license, char **icon, char **description, char **author) { + GList *tmp; + label_x *lbl; + license_x *lcn; + description_x *dcn; + author_x *ath; + + for (tmp = lbls; tmp; tmp = tmp->next) { + lbl = (label_x *)tmp->data; + if (lbl == NULL) + continue; + if (lbl->lang) { + if (strcmp(lbl->lang, locale) == 0) { + *label = (char *)lbl->text; + break; + } + } + } + for (tmp = lcns; tmp; tmp = tmp->next) { + lcn = (license_x *)tmp->data; + if (lcn == NULL) + continue; + if (lcn->lang) { + if (strcmp(lcn->lang, locale) == 0) { + *license = (char *)lcn->text; + break; + } + } + } + + *icon = __find_icon(icns, locale); + + for (tmp = dcns; tmp; tmp = tmp->next) { + dcn = (description_x *)tmp->data; + if (dcn == NULL) + continue; + if (dcn->lang) { + if (strcmp(dcn->lang, locale) == 0) { + *description = (char *)dcn->text; + break; + } + } + } + for (tmp = aths; tmp; tmp = tmp->next) { + ath = (author_x *)tmp->data; + if (ath == NULL) + continue; + if (ath->lang) { + if (strcmp(ath->lang, locale) == 0) { + *author = (char *)ath->text; + break; + } + } + } +} + +int InsertAppLocalizedInfo(const tizen_base::Database& db, + application_x* app) { + auto q = tizen_base::Database::Sql( + "INSERT INTO package_app_localized_info (app_id, app_locale," + " app_label, app_icon) " + "VALUES (?, ?, ?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + std::unique_ptr locales( + __create_locale_list(app->label, nullptr, app->icon, nullptr, nullptr), + g_list_free); + for (GList* tmp = locales.get(); tmp; tmp = tmp->next) { + const char* locale = reinterpret_cast(tmp->data); + char* label = nullptr; + char* icon = nullptr; + __extract_data(locale, app->label, nullptr, app->icon, nullptr, nullptr, + &label, nullptr, &icon, nullptr, nullptr); + if (!label && !icon) + continue; + + q.Reset() + .Bind(app->appid) + .Bind(locale) + .Bind(label) + .Bind(icon); + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed"); + return -1; + } + + if (strcasecmp(app->mainapp, "true") == 0) { + if (InsertMainappLocalizedInfo(db, app, locale, label, icon)) + _LOGE("insert mainapp localized info failed"); + } + } + + return 0; +} + +int InsertAppResControl(const tizen_base::Database& db, + application_x *app) { + if (app->res_control == nullptr) + return 0; + + auto q = tizen_base::Database::Sql( + "INSERT INTO package_app_res_control (app_id, res_type," + " min_res_version, max_res_version, auto_close) " + "VALUES (?, ?, ?, ?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + for (GList* tmp = app->res_control; tmp; tmp = tmp->next) { + res_control_x* rc = reinterpret_cast(tmp->data); + if (rc == nullptr) + continue; + + q.Reset() + .Bind(app->appid) + .Bind(rc->res_type) + .Bind(rc->min_res_version) + .Bind(rc->max_res_version) + .Bind(rc->auto_close); + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed"); + return -1; + } + } + + return 0; +} + +int InsertPackagePrivilegeInfo(const tizen_base::Database& db, manifest_x* mfx) { + auto q = tizen_base::Database::Sql( + "INSERT INTO package_privilege_info (package, privilege, type) " + "VALUES (?, ?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + for (GList* tmp = mfx->privileges; tmp; tmp = tmp->next) { + privilege_x* priv = reinterpret_cast(tmp->data); + if (priv == nullptr) + continue; + + q.Reset() + .Bind(mfx->package) + .Bind(priv->value) + .Bind(priv->type); + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed"); + return -1; + } + } + + return 0; +} + +int InsertAppDataControlPrivilegeInfo(const tizen_base::Database& db, + datacontrol_x* datacontrol) { + if (datacontrol == nullptr) + return 0; + + auto q = tizen_base::Database::Sql( + "INSERT INTO package_app_data_control_privilege (providerid," + " privilege, type) VALUES (?, ?, ?)"); + + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + for (GList* privileges = datacontrol->privileges; privileges; + privileges = privileges->next) { + char* priv = reinterpret_cast(privileges->data); + if (priv == nullptr) + continue; + + q.Reset() + .Bind(datacontrol->providerid) + .Bind(priv) + .Bind(datacontrol->type); + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed"); + return -1; + } + } + + return 0; +} + +int InsertDatacontrolInfo(const tizen_base::Database& db, application_x* app) { + if (app->datacontrol == nullptr) + return 0; + + auto q = tizen_base::Database::Sql( + "INSERT INTO package_app_data_control (app_id, providerid," + " access, type, trusted) VALUES (?, ?, ?, ?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + for (GList* tmp = app->datacontrol; tmp; tmp = tmp->next) { + datacontrol_x* dc = reinterpret_cast(tmp->data); + if (dc == nullptr) + continue; + q.Reset() + .Bind(app->appid) + .Bind(dc->providerid) + .Bind(dc->access) + .Bind(dc->type) + .Bind(dc->trusted); + + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed: %s", static_cast(r)); + return -1; + } + + if (dc->privileges && InsertAppDataControlPrivilegeInfo(db, dc)) + return -1; + } + + return 0; +} + +int InsertCategoryInfo(const tizen_base::Database& db, application_x* app) { + if (app->category == nullptr) + return 0; + + auto q = tizen_base::Database::Sql( + "INSERT INTO package_app_app_category (app_id, category) " + "VALUES (?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + for (GList* tmp = app->category; tmp; tmp = tmp->next) { + const char* category = reinterpret_cast(tmp->data); + if (category == nullptr) + continue; + q.Reset() + .Bind(app->appid) + .Bind(category); + + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed"); + return -1; + } + } + + return 0; +} + +int InsertMetadataInfo(const tizen_base::Database& db, application_x* app) { + if (app->metadata == nullptr) + return 0; + + auto q = tizen_base::Database::Sql( + "INSERT INTO package_app_app_metadata (app_id," + " md_key, md_value) VALUES (?, ?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + for (GList* tmp = app->metadata; tmp; tmp = tmp->next) { + metadata_x* md = reinterpret_cast(tmp->data); + if (md == nullptr) + continue; + q.Reset() + .Bind(app->appid) + .Bind(md->key) + .Bind(md->value); + + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed: %s", static_cast(r)); + return -1; + } + } + + return 0; +} + +int InsertAppcontrolPrivilegeInfo(const tizen_base::Database& db, + const char *appid, appcontrol_x* ac) { + if (ac == nullptr) + return 0; + + auto q = tizen_base::Database::Sql( + "INSERT INTO package_app_app_control_privilege (app_id," + " app_control, privilege) VALUES (?, ?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + char app_control[BUFSIZE]; + for (GList* tmp = ac->privileges; tmp; tmp = tmp->next) { + char* privilege = reinterpret_cast(tmp->data); + if (privilege == nullptr || !strlen(privilege)) + continue; + + snprintf(app_control, sizeof(app_control), "%s|%s|%s", + ac->operation ? (strlen(ac->operation) > 0 ? + ac->operation : "NULL") : "NULL", + ac->uri ? (strlen(ac->uri) > 0 ? + ac->uri : "NULL") : "NULL", + ac->mime ? (strlen(ac->mime) > 0 ? + ac->mime : "NULL") : "NULL"); + q.Reset() + .Bind(appid) + .Bind(app_control) + .Bind(privilege); + if (!db.Exec(q,r)) { + _LOGE("db.Exec() failed: %s", static_cast(r)); + return -1; + } + } + + return 0; +} + +int InsertAppcontrolInfo(const tizen_base::Database& db, application_x* app) { + if (app->appcontrol == nullptr) + return 0; + + auto q = tizen_base::Database::Sql( + "INSERT INTO package_app_app_control (app_id, app_control," + " visibility, app_control_id) " + "VALUES (?, ?, ?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + for (GList* tmp = app->appcontrol; tmp; tmp = tmp->next) { + appcontrol_x* ac = reinterpret_cast(tmp->data); + if (ac == nullptr) + continue; + std::string op = ac->operation ? (strlen(ac->operation) > 0 ? + ac->operation : "NULL") : "NULL"; + std::string uri = ac->uri ? (strlen(ac->uri) > 0 ? + ac->uri : "NULL") : "NULL"; + std::string mime = ac->mime ? (strlen(ac->mime) > 0 ? + ac->mime : "NULL") : "NULL"; + std::string app_control = std::move(op) + "|" + std::move(uri) + + "|" + std::move(mime); + q.Reset() + .Bind(app->appid) + .Bind(std::move(app_control)) + .Bind(ac->visibility) + .Bind(ac->id); + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed"); + return -1; + } + + if (InsertAppcontrolPrivilegeInfo(db, app->appid, ac)) + return -1; + } + + return 0; +} + +const char *__get_bool(char *value, bool is_true) { + if (value != NULL) { + if (!strcmp(value, "")) + return (is_true) ? "true" : "false"; + return value; + } + + return (is_true) ? "true" : "false"; +} + +const char *__find_effective_appid(GList *metadata_list) { + constexpr const char EFFECTIVE_APPID_KEY[] = + "http://tizen.org/metadata/effective-appid"; + + GList *tmp; + metadata_x *md; + + for (tmp = metadata_list; tmp; tmp = tmp->next) { + md = (metadata_x *)tmp->data; + if (md == NULL || md->key == NULL) + continue; + + if (strcmp(md->key, EFFECTIVE_APPID_KEY) == 0) { + if (md->value) + return md->value; + } + } + + return NULL; +} + +int __convert_background_category(GList *category_list) { + int ret = 0; + GList *tmp; + char *category_data; + + if (category_list == NULL) + return 0; + + for (tmp = category_list; tmp; tmp = tmp->next) { + category_data = (char *)tmp->data; + if (category_data == NULL) + continue; + if (!strcmp(category_data, APP_BG_CATEGORY_MEDIA_STR)) + ret |= APP_BG_CATEGORY_MEDIA_VAL; + else if (!strcmp(category_data, APP_BG_CATEGORY_DOWNLOAD_STR)) + ret |= APP_BG_CATEGORY_DOWNLOAD_VAL; + else if (!strcmp(category_data, APP_BG_CATEGORY_BGNETWORK_STR)) + ret |= APP_BG_CATEGORY_BGNETWORK_VAL; + else if (!strcmp(category_data, APP_BG_CATEGORY_LOCATION_STR)) + ret |= APP_BG_CATEGORY_LOCATION_VAL; + else if (!strcmp(category_data, APP_BG_CATEGORY_SENSOR_STR)) + ret |= APP_BG_CATEGORY_SENSOR_VAL; + else if (!strcmp(category_data, APP_BG_CATEGORY_IOTCOMM_STR)) + ret |= APP_BG_CATEGORY_IOTCOMM_VAL; + else if (!strcmp(category_data, APP_BG_CATEGORY_SYSTEM)) + ret |= APP_BG_CATEGORY_SYSTEM_VAL; + else + _LOGE("Unidentified category [%s]", category_data); + } + + return ret; +} + +int InsertPackageResInfoAllowedPackage(const tizen_base::Database& db, + const char* pkgid, GList* rap_list) { + if (rap_list == nullptr) + return 0; + + auto q = tizen_base::Database::Sql( + "INSERT INTO package_res_allowed_package (package," + " allowed_package, required_privilege) VALUES (?, ?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + for (GList* tmp = rap_list; tmp; tmp = tmp->next) { + res_allowed_package_x* rap = + reinterpret_cast(tmp->data); + if (rap == nullptr) + continue; + + if (!rap->required_privileges) { + q.Reset() + .Bind(pkgid) + .Bind(rap->allowed_package) + .Bind(nullptr); + + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed"); + return -1; + } + + continue; + } + + for (GList* priv_list = rap->required_privileges; priv_list; + priv_list = priv_list->next) { + q.Reset() + .Bind(pkgid) + .Bind(rap->allowed_package) + .Bind(reinterpret_cast(priv_list->data)); + + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed"); + return -1; + } + } + } + + return 0; +} + +int InsertPackageResInfo(const tizen_base::Database& db, manifest_x* mfx) { + if (mfx->res_type == nullptr || mfx->res_version == nullptr) + return 0; + + auto q = tizen_base::Database::Sql( + "INSERT INTO package_res_info (package, res_type," + " res_version) VALUES (?, ?, ?)") + .Bind(mfx->package) + .Bind(mfx->res_type) + .Bind(mfx->res_version); + + auto r = db.Exec(q); + if (!r) { + _LOGE("db.Exec() failed: %s", static_cast(r)); + return -1; + } + + if (InsertPackageResInfoAllowedPackage(db, mfx->package, + mfx->res_allowed_packages) < 0) { + return -1; + } + + return 0; +} + +int InsertApplicationInfo(const tizen_base::Database& db, manifest_x *mfx) { + auto q = tizen_base::Database::Sql( + "INSERT INTO package_app_info (app_id, app_component," + " app_exec, app_nodisplay, app_type, app_onboot, app_multiple," + " app_autorestart, app_taskmanage, 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_installed_storage, app_process_pool," + " app_launch_mode, app_ui_gadget, app_support_mode," + " app_support_disable, component_type, package, app_tep_name," + " app_zip_mount_file, app_background_category," + " app_package_type, app_root_path, app_api_version," + " app_effective_appid, app_splash_screen_display," + " app_package_system, app_removable," + " app_package_installed_time, app_support_ambient," + " app_external_path, app_setup_appid, light_user_switch_mode) " + "VALUES (?, ?, " + " ?, LOWER(?), ?, LOWER(?), LOWER(?)," + " LOWER(?), LOWER(?), ?," + " ?, LOWER(?), ?," + " ?, LOWER(?), ?," + " ?, LOWER(?)," + " ?, LOWER(?), LOWER(?)," + " ?, ?, LOWER(?)," + " COALESCE(?, 'single'), LOWER(?), ?," + " LOWER(?), ?, ?, ?," + " ?, ?," + " ?, ?, ?," + " ?, LOWER(?)," + " LOWER(?), LOWER(?)," + " ?, LOWER(?)," + " ?, ?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + for (GList* tmp = mfx->application; tmp; tmp = tmp->next) { + application_x* app = reinterpret_cast(tmp->data); + if (app == nullptr) + continue; + + int bg_category = __convert_background_category( + app->background_category); + const char* effective_appid = __find_effective_appid(app->metadata); + + q.Reset() + .Bind(app->appid) + .Bind(app->component_type) + .Bind(app->exec) + .Bind(__get_bool(app->nodisplay, false)) + .Bind(app->type) + .Bind(__get_bool(app->onboot, false)) + .Bind(__get_bool(app->multiple, false)) + .Bind(__get_bool(app->autorestart, false)) + .Bind(__get_bool(app->taskmanage, false)) + .Bind(app->hwacceleration) + .Bind(app->screenreader) + .Bind(__get_bool(app->mainapp, false)) + .Bind(app->recentimage) + .Bind(app->launchcondition) + .Bind(__get_bool(app->indicatordisplay, true)) + .Bind(app->portraitimg) + .Bind(app->landscapeimg) + .Bind(__get_bool(app->guestmode_visibility, true)) + .Bind(app->permission_type) + .Bind(__get_bool(mfx->preload, false)) + .Bind(__get_bool(app->submode, false)) + .Bind(app->submode_mainid) + .Bind(mfx->installed_storage) + .Bind(__get_bool(app->process_pool, false)) + .Bind(app->launch_mode) + .Bind(__get_bool(app->ui_gadget, false)) + .Bind(app->support_mode ? app->support_mode : "0") + .Bind(__get_bool(mfx->support_disable, false)) + .Bind(app->component_type) + .Bind(mfx->package) + .Bind(mfx->tep_name) + .Bind(mfx->zip_mount_file) + .Bind(bg_category) + .Bind(mfx->type ? mfx->type : "tpk") + .Bind(mfx->root_path) + .Bind(app->api_version) + .Bind(effective_appid) + .Bind(__get_bool(app->splash_screen_display, true)) + .Bind(__get_bool(mfx->system, false)) + .Bind(__get_bool(mfx->removable, false)) + .Bind(mfx->installed_time) + .Bind(__get_bool(app->support_ambient, false)) + .Bind(mfx->external_path) + .Bind(app->setup_appid) + .Bind(mfx->light_user_switch_mode); + + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed"); + return -1; + } + + if (InsertAppcontrolInfo(db, app)) + return -1; + if (InsertCategoryInfo(db, app)) + return -1; + if (InsertMetadataInfo(db, app)) + return -1; + if (InsertDatacontrolInfo(db, app)) + return -1; + GList* ss_list = __find_splashscreens(app->splashscreens); + if (InsertSplashscreenInfo(db, app, ss_list)) { + g_list_free(ss_list); + return -1; + } + g_list_free(ss_list); + if (InsertAppLocalizedInfo(db, app)) + return -1; + if (InsertAppResControl(db, app)) + return -1; + } + + return 0; +} + +int InsertPackageUpdateInfo(const tizen_base::Database& db, manifest_x *mfx) { + auto q = tizen_base::Database::Sql( + "INSERT INTO package_update_info (package, update_version) " + "VALUES (?, ?)") + .Bind(mfx->package) + .Bind(mfx->version); + + auto r = db.Exec(q); + if (!r) { + _LOGE("db.Exec() failed : %s", static_cast(r)); + return -1; + } + + return 0; +} + +int InsertPackageLocalizedInfo(const tizen_base::Database& db, + manifest_x *mfx) { + auto q = tizen_base::Database::Sql( + "INSERT INTO package_localized_info (package, package_locale," + " package_label, package_icon, package_description," + " package_license, package_author) " + "VALUES (?, ?, ?, ?, ?, ?, ?)"); + auto r = db.Prepare(q); + if (!r) { + _LOGE("db.Prepare() failed: %s", static_cast(r)); + return -1; + } + + GList* locales = __create_locale_list(mfx->label, mfx->license, mfx->icon, + mfx->description, mfx->author); + for (GList* tmp = locales; tmp; tmp = tmp->next) { + const char* locale = (const char *)tmp->data; + char* label = nullptr; + char* icon = nullptr; + char* description = nullptr; + char* license = nullptr; + char* author = nullptr; + __extract_data(locale, mfx->label, mfx->license, mfx->icon, + mfx->description, mfx->author, + &label, &license, &icon, &description, &author); + if (!label && !license && !icon && !description && !author) + continue; + + q.Reset() + .Bind(mfx->package) + .Bind(locale) + .Bind(label) + .Bind(icon) + .Bind(description) + .Bind(license) + .Bind(author); + + if (!db.Exec(q, r)) { + _LOGE("db.Exec() failed : %s", static_cast(r)); + g_list_free(locales); + return -1; + } + } + + g_list_free(locales); + + return 0; +} + +int DoInsertPackageInfo(const tizen_base::Database& db, manifest_x* mfx) { + const char* author_name = nullptr; + const char* author_email = nullptr; + const char* author_href = nullptr; + + if (mfx->author && mfx->author->data) { + author_name = ((author_x *)mfx->author->data)->text; + author_email = ((author_x *)mfx->author->data)->email; + author_href = ((author_x *)mfx->author->data)->href; + } + + auto q = tizen_base::Database::Sql( + "INSERT INTO package_info (package, package_type," + " package_version, package_api_version, package_tep_name," + " package_zip_mount_file, install_location, package_size," + " package_removable, package_preload, package_readonly," + " package_update, package_appsetting, package_nodisplay," + " package_system, author_name, author_email, author_href," + " installed_time, installed_storage, storeclient_id," + " mainapp_id, package_url, root_path, external_path," + " csc_path, package_support_mode, package_support_disable," + " light_user_switch_mode)" + "VALUES (?, ?," + " ?, ?, ?," + " ?, ?, ?," + " LOWER(?), LOWER(?), LOWER(?)," + " LOWER(?), LOWER(?), LOWER(?)," + " LOWER(?), ?, ?, ?," + " ?, ?, ?," + " ?, ?, ?, ?," + " ?, ?, LOWER(?), ?)") + .Bind(mfx->package) + .Bind(mfx->type) + .Bind(mfx->version) + .Bind(mfx->api_version) + .Bind(mfx->tep_name) + .Bind(mfx->zip_mount_file) + .Bind(mfx->installlocation) + .Bind(mfx->package_size) + .Bind(__get_bool(mfx->removable, true)) + .Bind(__get_bool(mfx->preload, false)) + .Bind(__get_bool(mfx->readonly, false)) + .Bind(__get_bool(mfx->update, false)) + .Bind(__get_bool(mfx->appsetting, false)) + .Bind(__get_bool(mfx->nodisplay_setting, false)) + .Bind(__get_bool(mfx->system, false)) + .Bind(author_name) + .Bind(author_email) + .Bind(author_href) + .Bind(mfx->installed_time) + .Bind(mfx->installed_storage) + .Bind(mfx->storeclient_id) + .Bind(mfx->mainapp_id) + .Bind(mfx->package_url) + .Bind(mfx->root_path) + .Bind(mfx->external_path) + .Bind(mfx->csc_path) + .Bind(mfx->support_mode ? mfx->support_mode : "0") + .Bind(__get_bool(mfx->support_disable, false)) + .Bind(mfx->light_user_switch_mode); + + auto r = db.Exec(q); + if (!r) { + _LOGE("db.Exec() failed: %s", static_cast(r)); + return -1; + } + + if (InsertPackageUpdateInfo(db, mfx)) + return -1; + if (InsertPackageLocalizedInfo(db, mfx)) + return -1; + if (InsertApplicationInfo(db, mfx)) + return -1; + if (InsertPackagePrivilegeInfo(db, mfx)) + return -1; + if (InsertPackageAppdefinedPrivilegeInfo(db, mfx)) + return -1; + if (InsertPackageDependencyInfo(db, mfx)) + return -1; + if (InsertPackageResInfo(db, mfx)) + return -1; + + return 0; +} + +int DoDeletePackageInfo(const tizen_base::Database& db, const char* pkgid) { + auto q = tizen_base::Database::Sql( + "DELETE FROM package_info WHERE package=?") + .Bind(pkgid); + auto r = db.Exec(q); + if (!r) { + _LOGE("db.Exec() failed: %s", static_cast(r)); + return -1; + } + + return 0; +} + +} // namesapce + + +namespace pkgmgr_server::internal { + +int DeletePkgInfo(const tizen_base::Database& db, const char* package, + uid_t uid) { + if (!static_cast(db) || package == nullptr) { + _LOGE("invalid parameter"); + return PM_PARSER_R_EINVAL; + } + + auto guard = db.CreateTransactionGuard(); + if (DoDeletePackageInfo(db, package) != 0) + return -1; + guard.Commit(); + + return PM_PARSER_R_OK; +} + +int UpdatePkgInfo(const tizen_base::Database& db, manifest_x* mfx, uid_t uid) { + if (!static_cast(db) || mfx == nullptr || mfx->package == nullptr) { + _LOGE("invalid parameter"); + return PM_PARSER_R_EINVAL; + } + + auto guard = db.CreateTransactionGuard(); + if (DoDeletePackageInfo(db, mfx->package) != 0) + return -1; + if (DoInsertPackageInfo(db, mfx) != 0) + return -1; + guard.Commit(); + + return PM_PARSER_R_OK; +} + +int InsertPkgInfo(const tizen_base::Database& db, manifest_x* mfx, uid_t uid) { + if (!static_cast(db) || mfx == nullptr) { + _LOGE("invalid parameter"); + return PM_PARSER_R_EINVAL; + } + + auto guard = db.CreateTransactionGuard(); + if (DoInsertPackageInfo(db, mfx) != 0) + return -1; + guard.Commit(); + + return PM_PARSER_R_OK; +} + +bool CheckPackageStorageStatus(pkgmgrinfo_filter_x* tmp_filter) { + return ::CheckPackageStorageStatus(tmp_filter); +} + +int ExecuteWriteQueries(const tizen_base::Database& db, + const std::vector& queries, + const std::vector>>& args_list) { + if (!static_cast(db) || queries.empty()) { + _LOGE("Invalid parameter"); + return PMINFO_R_EINVAL; + } + + auto guard = db.CreateTransactionGuard(); + + int idx = 0; + for (const auto& i : queries) { + if (DoExecuteQuery(db, i, args_list[idx++]) != 0) + return -1; + } + guard.Commit(); + + return PMINFO_R_OK; +} + +int GetQueryResult(const tizen_base::Database& db, + const std::string& query, + const std::vector>& param, + std::vector>>& result) { + if (!static_cast(db) || query.empty()) { + LOGE("Invalid parameter"); + return PMINFO_R_EINVAL; + } + + auto q = tizen_base::Database::Sql(query); + for (auto& p : param) { + if (p) + q.Bind(*p); + else + q.Bind(std::nullopt); + } + + auto r = db.Exec(q); + if (!r) + return PMINFO_R_ERROR; + + int col_cnt = r.GetColumnCount(); + for (const auto& row : r) { + std::vector> rec; + for (int i = 0; i < col_cnt; i++) + rec.push_back(row.GetString(i)); + + result.push_back(std::move(rec)); + } + + return PMINFO_R_OK; +} + +int GetPkgInfo(const tizen_base::Database& db, + pkgmgrinfo_pkginfo_filter_h filter, uid_t uid, + const std::string& locale, + std::map>& pkginfo_list) { + if (!static_cast(db) || filter == nullptr) { + LOGE("Invalid argument"); + return PMINFO_R_EINVAL; + } + + int ret = DoGetPkgInfo(db, uid, locale, (pkgmgrinfo_filter_x*)filter, + PMINFO_PKGINFO_GET_ALL, pkginfo_list); + return ret; +} + +int GetDependsOn(const tizen_base::Database& db, const std::string& pkgid, + std::vector& dep_list) { + if (!static_cast(db) || pkgid.empty()) { + LOGE("Invalid parameter"); + return PMINFO_R_EINVAL; + } + + std::queue queue; + std::set dup_checker; + + queue.push(pkgid); + while (!queue.empty()) { + auto item = queue.front(); + queue.pop(); + int ret = DoGetDependsOn(db, item, queue, dup_checker, dep_list); + if (ret != PMINFO_R_OK) { + LOGE("failed to get pkgs depends on %s", pkgid.c_str()); + for (auto i : dep_list) + __free_depends_on(i); + return PMINFO_R_ERROR; + } + } + + return PMINFO_R_OK; +} + +} // namespace pkgmgr_server::internal diff --git a/src/server/pkgmgrinfo_internal.h b/src/server/pkgmgrinfo_internal.h index cef3d7c..5e5d315 100644 --- a/src/server/pkgmgrinfo_internal.h +++ b/src/server/pkgmgrinfo_internal.h @@ -1,18 +1,18 @@ /* - * 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. - */ +* 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_H__ #define __PKGMGRINFO_INTERNAL_H__ @@ -21,98 +21,48 @@ #include #include #include - #include +#include + +#include #include "pkgmgr_parser.h" #include "pkgmgrinfo_private.h" #include "pkgmgrinfo_type.h" #include "pkgmgr-info.h" -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - int len; - GList *argument; -} query_args; - -#define __BEGIN_TRANSACTION(db) \ -do { \ - if (sqlite3_exec(db, "BEGIN DEFERRED", NULL, NULL, NULL) != \ - SQLITE_OK) { \ - _LOGE("begin transaction failed: %s", sqlite3_errmsg(db)); \ - return -1; \ - } \ -} while (0) \ - -#define __DO_TRANSACTION(db, func) \ -do { \ - if (func) { \ - _LOGE("transaction failed: %s, rollback", sqlite3_errmsg(db)); \ - if (sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL) != \ - SQLITE_OK) \ - _LOGE("roll back transaction failed: %s", \ - sqlite3_errmsg(db)); \ - return -1; \ - } \ -} while (0) \ - -#define __END_TRANSACTION(db) \ -do { \ - if (sqlite3_exec(db, "COMMIT", NULL, NULL, NULL) != \ - SQLITE_OK) { \ - _LOGE("commit failed: %s, rollback", sqlite3_errmsg(db)); \ - if (sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL) != \ - SQLITE_OK) \ - _LOGE("roll back transaction failed: %s", \ - sqlite3_errmsg(db)); \ - return -1; \ - } \ -} while (0) \ -#define __BIND_TEXT(db, stmt, i, text) \ -do { \ - if (sqlite3_bind_text(stmt, i, text, -1, SQLITE_STATIC) != SQLITE_OK) {\ - _LOGE("bind error(index %d): %s", i, sqlite3_errmsg(db)); \ - sqlite3_finalize(stmt); \ - return -1; \ - } \ -} while (0) -#define __BIND_INT(db, stmt, i, int) \ -do { \ - if (sqlite3_bind_int(stmt, i, int) != SQLITE_OK) { \ - _LOGE("bind error(index %d): %s", i, sqlite3_errmsg(db)); \ - sqlite3_finalize(stmt); \ - return -1; \ - } \ -} while (0) +namespace pkgmgr_server::internal { + +void SetEnableUnitTest(bool enable); +int CertInfoGet(const tizen_base::Database& db, + std::string_view pkgid, uid_t uid, pkgmgrinfo_certinfo_h certinfo); +int CertInfoSet(const tizen_base::Database& db, + std::string_view pkgid, pkgmgrinfo_instcertinfo_h handle, uid_t uid); +int InitializeDb(const tizen_base::Database& db, uid_t uid); +int InsertPkgInfo(const tizen_base::Database& db, manifest_x* mfx, uid_t uid); +int UpdatePkgInfo(const tizen_base::Database& db, manifest_x* mfx, uid_t uid); +int DeletePkgInfo(const tizen_base::Database& db, const char* package, uid_t uid); +bool CheckPackageStorageStatus(pkgmgrinfo_filter_x* tmp_filter); +int ExecuteWriteQueries(const tizen_base::Database& db, + const std::vector& queries, + const std::vector>>& args_list); +int GetQueryResult(const tizen_base::Database& db, + const std::string& query, + const std::vector>& param, + std::vector>>& result); +bool CheckAppStorageStatus(pkgmgrinfo_filter_x* tmp_filter); +int GetAppInfo(const tizen_base::Database& db, + pkgmgrinfo_appinfo_filter_h filter, uid_t db_uid, uid_t uid, + const std::string& locale, + std::vector>& appinfo_list); +int GetPkgInfo(const tizen_base::Database& db, + pkgmgrinfo_pkginfo_filter_h filter, uid_t uid, + const std::string& locale, + std::map>& pkginfo_list); +int GetDependsOn(const tizen_base::Database& db, const std::string& pkgid, + std::vector& dep_list); + +} // namespace pkgmgr_server::internal -int pkginfo_internal_filter_get_list(sqlite3 *db, pkgmgrinfo_pkginfo_filter_h filter, 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); -int execute_write_queries(sqlite3 *db, GList *queries, GList *params_list); -int pkginfo_internal_filter_get_depends_on(sqlite3 *db, const char *pkgid, GList **list); - -bool __check_package_storage_status(pkgmgrinfo_filter_x *tmp_filter); -void _save_column_int(sqlite3_stmt *stmt, int idx, int *i); -void _save_column_str(sqlite3_stmt *stmt, int idx, char **str); - -int pkgmgr_parser_insert_pkg_info(sqlite3 *db, manifest_x *mfx, uid_t uid); -int pkgmgr_parser_update_pkg_info(sqlite3 *db, manifest_x *mfx, uid_t uid); -int pkgmgr_parser_delete_pkg_info(sqlite3 *db, const char *package, uid_t uid); - -int pkgmgr_parser_internal_initialize_db(sqlite3 *db, uid_t uid); - -/** @} */ -#ifdef __cplusplus -} -#endif #endif /* __PKGMGRINFO_INTERNAL_H__ */ -/** - * @} - * @} - */ - diff --git a/src/server/pkgmgrinfo_internal.hh b/src/server/pkgmgrinfo_internal.hh deleted file mode 100644 index a51502f..0000000 --- a/src/server/pkgmgrinfo_internal.hh +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 -#include -#include - -#include -#include - -#include "pkgmgr_parser.h" -#include "pkgmgrinfo_type.h" -#include "pkgmgr-info.h" - -namespace pkgmgr_server { -namespace internal { - -extern API bool check_app_storage_status(pkgmgrinfo_filter_x* tmp_filter); - -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>& appinfo_list); - -} // namespace internal -} // namespace pkgmgr_server - -#endif // __PKGMGRINFO_INTERNAL_HH__ diff --git a/src/server/sqlite_util_internal.c b/src/server/sqlite_util_internal.c deleted file mode 100644 index 84c9f4a..0000000 --- a/src/server/sqlite_util_internal.c +++ /dev/null @@ -1,35 +0,0 @@ -// copyright - -#define _GNU_SOURCE - -#include - -#include "pkgmgrinfo_internal.h" - -void _save_column_int(sqlite3_stmt *stmt, int idx, int *i) -{ - *i = sqlite3_column_int(stmt, idx); -} - -inline void _save_column_str(sqlite3_stmt *stmt, int idx, char **str) -{ - const char *val; - - val = (const char *)sqlite3_column_text(stmt, idx); - if (val) - *str = strdup(val); -} - -void _save_column_bool(sqlite3_stmt *stmt, int idx, bool *bool_value) -{ - const char *val; - - val = (const char *)sqlite3_column_text(stmt, idx); - if (!val) - return; - - if (strcasecmp(val, "true") == 0) - *bool_value = true; - else if (strcasecmp(val, "false") == 0) - *bool_value = false; -} diff --git a/test/unit_tests/CMakeLists.txt b/test/unit_tests/CMakeLists.txt index ed51645..1c238d1 100644 --- a/test/unit_tests/CMakeLists.txt +++ b/test/unit_tests/CMakeLists.txt @@ -17,7 +17,7 @@ ADD_EXECUTABLE(${TARGET_PKGMGR_INFO_UNIT_TEST} ADD_DEFINITIONS("-DSYSCONFDIR=\"${SYSCONFDIR}\"") include(FindPkgConfig) -pkg_check_modules(unit_test_pkgs REQUIRED dlog glib-2.0 gio-2.0 sqlite3 gmock parcel) +pkg_check_modules(unit_test_pkgs REQUIRED dlog glib-2.0 gio-2.0 sqlite3 gmock parcel tizen-database) FOREACH(flag ${unit_test_pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/test/unit_tests/main.cc b/test/unit_tests/main.cc index 0029d65..b79bef7 100644 --- a/test/unit_tests/main.cc +++ b/test/unit_tests/main.cc @@ -5,6 +5,21 @@ #include #include +#ifdef LOG_INTERNAL +#include + +extern "C" int __dlog_print(log_id_t log_id, int prio, const char *tag, const char *fmt, ...) { + printf("%s:", tag); + va_list ap; + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + printf("\n"); + + return 0; +} +#endif + int main(int argc, char** argv) { int ret = -1; try { diff --git a/test/unit_tests/mock/file_mock.c b/test/unit_tests/mock/file_mock.c deleted file mode 100644 index defc7d5..0000000 --- a/test/unit_tests/mock/file_mock.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. - * - * 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 "file_mock.h" - -#include -#include - -extern FILE *__real_fopen(const char *filename, const char *modes); -extern FILE *__real_fopen64(const char *filename, const char *modes); -extern char *__real_fgets(char *s, int n, FILE * stream); -extern int __real_fclose(FILE *stream); - -static bool flag_ = false; - -void fopen_mock_setup(bool flag) { - flag_ = flag; -} - -FILE* __wrap_fopen(const char *filename, const char *modes) { - if (!flag_) - return __real_fopen(filename, modes); - - return (FILE *)1; -} - -FILE* __wrap_fopen64(const char *filename, const char *modes) { - if (!flag_) - return __real_fopen64(filename, modes); - - return (FILE *)1; -} - -char * __wrap_fgets(char *s, int n, FILE *stream) { - if (!flag_) - return __real_fgets(s, n, stream); - - char buf[1024] = "30005"; - snprintf(s, n, "%s", buf); - - return s; -} - -int __wrap_fclose(FILE *stream) { - if (!flag_) - return __real_fclose(stream); - - return 0; -} diff --git a/test/unit_tests/mock/file_mock.h b/test/unit_tests/mock/file_mock.h deleted file mode 100644 index b5b9958..0000000 --- a/test/unit_tests/mock/file_mock.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. - * - * 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 TEST_UNIT_TESTS_MOCK_FILE_MOCK_H_ -#define TEST_UNIT_TESTS_MOCK_FILE_MOCK_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void fopen_mock_setup(bool flag); - -#ifdef __cplusplus -} -#endif - -#endif /* TEST_UNIT_TESTS_MOCK_FILE_MOCK_H_ */ diff --git a/test/unit_tests/test_cert_db_handlers.cc b/test/unit_tests/test_cert_db_handlers.cc index aa6da59..8fc35ed 100644 --- a/test/unit_tests/test_cert_db_handlers.cc +++ b/test/unit_tests/test_cert_db_handlers.cc @@ -15,20 +15,19 @@ */ #include - #include #include +#include #include "cert_set_db_handler.hh" #include "cert_get_db_handler.hh" #include "create_db_handler.hh" #include "db_type.hh" -#include "mock/file_mock.h" #include "parcel_utils.hh" - #include "pkgmgr-info.h" #include "pkgmgrinfo_basic.h" +#include "server/pkgmgrinfo_internal.h" #define TEST_CERT_DB "test.pkgmgr_cert.db" @@ -40,7 +39,8 @@ class CreateCertDBHandlerMock : public psd::CreateDBHandler { : psd::CreateDBHandler(uid, pid) {} MOCK_METHOD0(Connect, bool()); - MOCK_METHOD0(GetConnection, std::vector>()); + MOCK_METHOD0(GetConnection, const std::vector>&()); }; class CertSetDBHandlerMock : public psd::CertSetDBHandler { @@ -48,7 +48,8 @@ class CertSetDBHandlerMock : public psd::CertSetDBHandler { CertSetDBHandlerMock(uid_t uid, int pid) : psd::CertSetDBHandler(uid, pid) {} MOCK_METHOD0(Connect, bool()); - MOCK_METHOD0(GetConnection, std::vector>()); + MOCK_METHOD0(GetConnection, const std::vector>&()); }; class CertGetDBHandlerMock : public psd::CertGetDBHandler { @@ -56,55 +57,46 @@ class CertGetDBHandlerMock : public psd::CertGetDBHandler { CertGetDBHandlerMock(uid_t uid, int pid) : psd::CertGetDBHandler(uid, pid) {} MOCK_METHOD0(Connect, bool()); - MOCK_METHOD0(GetConnection, std::vector>()); + MOCK_METHOD0(GetConnection, const std::vector>&()); }; class CertDBHandlerTest : public ::testing::Test { public: virtual void SetUp() { - sqlite3 *db; - - int ret = sqlite3_open_v2(TEST_CERT_DB, &db, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); - if (ret != SQLITE_OK) - sqlite3_close_v2(db); - - ASSERT_EQ(ret, SQLITE_OK); - - SetDBHandles( - std::vector> { std::make_pair(db, 0) }); + tizen_base::Database db(TEST_CERT_DB, SQLITE_OPEN_READWRITE | + SQLITE_OPEN_CREATE); + db_handles_.emplace_back(std::move(db), 0); CreateCertDBHandlerMock create_db_handler(0, 0); EXPECT_CALL(create_db_handler, Connect()) .Times(2).WillRepeatedly(testing::Return(true)); EXPECT_CALL(create_db_handler, GetConnection()) - .Times(2).WillRepeatedly(testing::Return(GetDBHandles())); + .Times(2).WillRepeatedly(testing::ReturnRef(db_handles_)); - fopen_mock_setup(true); + MakeVersionFile(); + pkgmgr_server::internal::SetEnableUnitTest(true); ASSERT_EQ(create_db_handler.Execute(), 0); - fopen_mock_setup(false); + pkgmgr_server::internal::SetEnableUnitTest(false); } virtual void TearDown() { - for (auto& handle : db_handles_) - sqlite3_close_v2(handle.first); - + db_handles_.clear(); ASSERT_EQ(remove(TEST_CERT_DB), 0); std::string journal_path(TEST_CERT_DB); journal_path += "-journal"; ASSERT_EQ(remove(journal_path.c_str()), 0); } - const std::vector>& GetDBHandles() { - return db_handles_; - } - private: - void SetDBHandles(std::vector> db_handles) { - db_handles_ = std::move(db_handles); + void MakeVersionFile() { + std::remove("./pkg_db_version.txt"); + std::ofstream ofs("./pkg_db_version.txt"); + ofs << "30005"; } - std::vector> db_handles_; + protected: + std::vector> db_handles_; }; TEST_F(CertDBHandlerTest, CertDBHandlerTest) { @@ -116,13 +108,13 @@ TEST_F(CertDBHandlerTest, CertDBHandlerTest) { EXPECT_CALL(cert_set_db_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(cert_set_db_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); ASSERT_EQ(cert_set_db_handler.Execute(), 0); CertGetDBHandlerMock cert_get_db_handler(0, 0); EXPECT_CALL(cert_get_db_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(cert_get_db_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); cert_get_db_handler.SetPkgID("test_pkgid"); ASSERT_EQ(cert_get_db_handler.Execute(), PMINFO_R_OK); diff --git a/test/unit_tests/test_parcel.cc b/test/unit_tests/test_parcel.cc index 8dd603f..a8d8f4c 100644 --- a/test/unit_tests/test_parcel.cc +++ b/test/unit_tests/test_parcel.cc @@ -107,8 +107,8 @@ TEST_F(ParcelTest, AppInfoParcelable) { tizen_base::Parcel parcel; std::vector> origin_applications; - origin_applications.emplace_back(GetTestApplication("test_appid1")); - origin_applications.emplace_back(GetTestApplication("test_appid2")); + origin_applications.emplace_back(GetTestApplication("test_appid1"), std::free); + origin_applications.emplace_back(GetTestApplication("test_appid2"), std::free); pp::AppInfoParcelable origin_parcelable(0, std::move(origin_applications)); pp::AppInfoParcelable new_parcelable; parcel.WriteParcelable(origin_parcelable); @@ -122,8 +122,8 @@ TEST_F(ParcelTest, PkgInfoParcelable) { tizen_base::Parcel parcel; std::vector> origin_packages; - origin_packages.emplace_back(GetTestPackage("test_pkgid1")); - origin_packages.emplace_back(GetTestPackage("test_pkgid2")); + origin_packages.emplace_back(GetTestPackage("test_pkgid1"), std::free); + origin_packages.emplace_back(GetTestPackage("test_pkgid2"), std::free); pp::PkgInfoParcelable origin_parcelable(0, std::move(origin_packages)); pp::PkgInfoParcelable new_parcelable; parcel.WriteParcelable(origin_parcelable); diff --git a/test/unit_tests/test_parser_db_handlers.cc b/test/unit_tests/test_parser_db_handlers.cc index f1fb3ef..30545bd 100644 --- a/test/unit_tests/test_parser_db_handlers.cc +++ b/test/unit_tests/test_parser_db_handlers.cc @@ -15,10 +15,10 @@ */ #include - #include #include +#include #include "appinfo_db_handler.hh" #include "create_db_handler.hh" @@ -27,14 +27,12 @@ #include "parcel_utils.hh" #include "pkg_get_db_handler.hh" #include "pkg_set_db_handler.hh" - -#include "mock/file_mock.h" #include "mock/test_fixture.h" #include "mock/system_info_mock.h" - #include "pkgmgr-info.h" #include "pkgmgr_query_index.h" #include "pkgmgrinfo_basic.h" +#include "server/pkgmgrinfo_internal.h" #define TEST_PARSER_DB "test.pkgmgr_parser.db" @@ -47,7 +45,8 @@ class CreateParserDBHandlerMock : public psd::CreateDBHandler { : psd::CreateDBHandler(uid, pid) {} MOCK_METHOD0(Connect, bool()); - MOCK_METHOD0(GetConnection, std::vector>()); + MOCK_METHOD0(GetConnection, const std::vector>&()); }; class PkgSetDBHandlerMock : public psd::PkgSetDBHandler { @@ -55,7 +54,8 @@ class PkgSetDBHandlerMock : public psd::PkgSetDBHandler { PkgSetDBHandlerMock(uid_t uid, int pid) : psd::PkgSetDBHandler(uid, pid) {} MOCK_METHOD0(Connect, bool()); - MOCK_METHOD0(GetConnection, std::vector>()); + MOCK_METHOD0(GetConnection, const std::vector>&()); }; class PkgGetDBHandlerMock : public psd::PkgGetDBHandler { @@ -63,7 +63,8 @@ class PkgGetDBHandlerMock : public psd::PkgGetDBHandler { PkgGetDBHandlerMock(uid_t uid, int pid) : psd::PkgGetDBHandler(uid, pid) {} MOCK_METHOD0(Connect, bool()); - MOCK_METHOD0(GetConnection, std::vector>()); + MOCK_METHOD0(GetConnection, const std::vector>&()); }; class AppInfoDBHandlerMock : public psd::AppInfoDBHandler { @@ -71,7 +72,8 @@ class AppInfoDBHandlerMock : public psd::AppInfoDBHandler { AppInfoDBHandlerMock(uid_t uid, int pid) : psd::AppInfoDBHandler(uid, pid) {} MOCK_METHOD0(Connect, bool()); - MOCK_METHOD0(GetConnection, std::vector>()); + MOCK_METHOD0(GetConnection, const std::vector>&()); }; class DepInfoGetDBHandlerMock : public psd::DepInfoGetDBHandler { @@ -80,7 +82,8 @@ class DepInfoGetDBHandlerMock : public psd::DepInfoGetDBHandler { psd::DepInfoGetDBHandler(uid, pid) {} MOCK_METHOD0(Connect, bool()); - MOCK_METHOD0(GetConnection, std::vector>()); + MOCK_METHOD0(GetConnection, const std::vector>&()); }; class Mocks : public ::testing::NiceMock {}; @@ -91,52 +94,42 @@ class ParserDBHandlerTest : public TestFixture { virtual ~ParserDBHandlerTest() {} virtual void SetUp() { - sqlite3* db; - - int ret = sqlite3_open_v2(TEST_PARSER_DB, &db, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); - if (ret != SQLITE_OK) - sqlite3_close_v2(db); - - ASSERT_EQ(ret, SQLITE_OK); - - SetDBHandles( - std::vector> { std::make_pair(db, 0) }); + tizen_base::Database db(TEST_PARSER_DB, SQLITE_OPEN_READWRITE | + SQLITE_OPEN_CREATE); + db_handles_.emplace_back(std::move(db), 0); CreateParserDBHandlerMock create_db_handler(0, 0); EXPECT_CALL(create_db_handler, Connect()) .Times(2).WillRepeatedly(testing::Return(true)); EXPECT_CALL(create_db_handler, GetConnection()) - .Times(2).WillRepeatedly(testing::Return(GetDBHandles())); + .Times(2).WillRepeatedly(testing::ReturnRef(db_handles_)); EXPECT_CALL(GetMock(), system_info_get_platform_int(testing::_, testing::_)) .WillRepeatedly(testing::DoAll( testing::SetArgPointee<1>(120), testing::Return(0))); - fopen_mock_setup(true); + MakeVersionFile(); + pkgmgr_server::internal::SetEnableUnitTest(true); ASSERT_EQ(create_db_handler.Execute(), 0); - fopen_mock_setup(false); + pkgmgr_server::internal::SetEnableUnitTest(false); } virtual void TearDown() { - for (auto& handle : db_handles_) - sqlite3_close_v2(handle.first); - + db_handles_.clear(); ASSERT_EQ(remove(TEST_PARSER_DB), 0); std::string journal_path(TEST_PARSER_DB); journal_path += "-journal"; ASSERT_EQ(remove(journal_path.c_str()), 0); } - const std::vector>& GetDBHandles() { - return db_handles_; - } - private: - void SetDBHandles(std::vector>&& db_handles) { - db_handles_ = db_handles; + void MakeVersionFile() { + std::remove("./pkg_db_version.txt"); + std::ofstream ofs("./pkg_db_version.txt"); + ofs << "30005"; } - std::vector> db_handles_; + protected: + std::vector> db_handles_; }; TEST_F(ParserDBHandlerTest, PkgSetDBHandlerTest_Install) { @@ -148,7 +141,7 @@ TEST_F(ParserDBHandlerTest, PkgSetDBHandlerTest_Install) { EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(pkg_set_db_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); ASSERT_EQ(pkg_set_db_handler.Execute(), 0); } @@ -161,7 +154,7 @@ TEST_F(ParserDBHandlerTest, PkgSetDBHandlerTest_Update) { EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(pkg_set_db_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); ASSERT_EQ(pkg_set_db_handler.Execute(), 0); } @@ -176,7 +169,7 @@ TEST_F(ParserDBHandlerTest, PkgSetDBHandlerTest_Delete) { EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(pkg_set_db_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); ASSERT_EQ(pkg_set_db_handler.Execute(), 0); pkgmgrinfo_pkginfo_filter_h filter; @@ -197,7 +190,7 @@ TEST_F(ParserDBHandlerTest, PkgSetDBHandlerTest_Delete) { EXPECT_CALL(pkg_get_db_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(pkg_get_db_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); ASSERT_EQ(pkg_get_db_handler.Execute(), PMINFO_R_ENOENT); } @@ -211,7 +204,7 @@ TEST_F(ParserDBHandlerTest, PkgGetDBHandlerTest) { EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(pkg_set_db_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); ASSERT_EQ(pkg_set_db_handler.Execute(), 0); pkgmgrinfo_pkginfo_filter_h filter; @@ -232,7 +225,7 @@ TEST_F(ParserDBHandlerTest, PkgGetDBHandlerTest) { EXPECT_CALL(pkg_get_db_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(pkg_get_db_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); ASSERT_EQ(pkg_get_db_handler.Execute(), 0); auto lpkginfo_list = pkg_get_db_handler.GetPkgHandle(); @@ -240,7 +233,7 @@ TEST_F(ParserDBHandlerTest, PkgGetDBHandlerTest) { auto test_pkginfo = GetTestPackage(pkgid); std::vector> rpkginfo_list; - rpkginfo_list.emplace_back(test_pkginfo); + rpkginfo_list.emplace_back(test_pkginfo, pkgmgrinfo_basic_free_package); ASSERT_EQ(IsEqualPackagesInfo(lpkginfo_list, rpkginfo_list), true); } @@ -254,7 +247,7 @@ TEST_F(ParserDBHandlerTest, AppInfoDBHandlerTest) { EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(pkg_set_db_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); ASSERT_EQ(pkg_set_db_handler.Execute(), 0); pkgmgrinfo_appinfo_filter_h filter; @@ -275,7 +268,7 @@ TEST_F(ParserDBHandlerTest, AppInfoDBHandlerTest) { EXPECT_CALL(appinfo_db_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(appinfo_db_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); appinfo_db_handler.SetLocale("test_lang"); ASSERT_EQ(appinfo_db_handler.Execute(), 0); @@ -284,7 +277,7 @@ TEST_F(ParserDBHandlerTest, AppInfoDBHandlerTest) { auto test_appinfo = GetTestApplication(appid); std::vector> rappinfo_list; - rappinfo_list.emplace_back(test_appinfo); + rappinfo_list.emplace_back(test_appinfo, std::free); ASSERT_EQ(IsEqualApplicationsInfo(lappinfo_list, rappinfo_list), true); } @@ -298,7 +291,7 @@ TEST_F(ParserDBHandlerTest, DepInfoDBHandlerTest) { EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(pkg_set_db_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); ASSERT_EQ(pkg_set_db_handler.Execute(), 0); DepInfoGetDBHandlerMock depinfo_get_db_handler(0, 0); @@ -306,7 +299,7 @@ TEST_F(ParserDBHandlerTest, DepInfoDBHandlerTest) { EXPECT_CALL(depinfo_get_db_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(depinfo_get_db_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); ASSERT_EQ(depinfo_get_db_handler.Execute(), 0); auto depinfo_from_db = depinfo_get_db_handler.GetDependencyList(); diff --git a/test/unit_tests/test_query_db_handlers.cc b/test/unit_tests/test_query_db_handlers.cc index 432bdb3..e081fab 100644 --- a/test/unit_tests/test_query_db_handlers.cc +++ b/test/unit_tests/test_query_db_handlers.cc @@ -15,24 +15,22 @@ */ #include - #include #include +#include #include "create_db_handler.hh" #include "db_type.hh" #include "parcel_utils.hh" #include "pkg_set_db_handler.hh" #include "query_handler.hh" - -#include "mock/file_mock.h" #include "mock/test_fixture.h" #include "mock/system_info_mock.h" - #include "pkgmgr-info.h" #include "pkgmgr_query_index.h" #include "pkgmgrinfo_basic.h" +#include "server/pkgmgrinfo_internal.h" #define TEST_PARSER_DB "test.pkgmgr_parser.db" @@ -45,7 +43,8 @@ class CreateParserDBHandlerMock : public psd::CreateDBHandler { : psd::CreateDBHandler(uid, pid) {} MOCK_METHOD0(Connect, bool()); - MOCK_METHOD0(GetConnection, std::vector>()); + MOCK_METHOD0(GetConnection, const std::vector>&()); }; class PkgSetDBHandlerMock : public psd::PkgSetDBHandler { @@ -53,7 +52,8 @@ class PkgSetDBHandlerMock : public psd::PkgSetDBHandler { PkgSetDBHandlerMock(uid_t uid, int pid) : psd::PkgSetDBHandler(uid, pid) {} MOCK_METHOD0(Connect, bool()); - MOCK_METHOD0(GetConnection, std::vector>()); + MOCK_METHOD0(GetConnection, const std::vector>&()); }; class QueryHandlerMock : public psd::QueryHandler { @@ -62,7 +62,8 @@ class QueryHandlerMock : public psd::QueryHandler { psd::QueryHandler(uid, pid) {} MOCK_METHOD0(Connect, bool()); - MOCK_METHOD0(GetConnection, std::vector>()); + MOCK_METHOD0(GetConnection, const std::vector>&()); }; class Mocks : public ::testing::NiceMock {}; @@ -73,52 +74,42 @@ class ParserDBHandlerTest : public TestFixture { virtual ~ParserDBHandlerTest() {} virtual void SetUp() { - sqlite3* db; - - int ret = sqlite3_open_v2(TEST_PARSER_DB, &db, - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); - if (ret != SQLITE_OK) - sqlite3_close_v2(db); - - ASSERT_EQ(ret, SQLITE_OK); - - SetDBHandles( - std::vector> { std::make_pair(db, 0) }); + tizen_base::Database db(TEST_PARSER_DB, SQLITE_OPEN_READWRITE | + SQLITE_OPEN_CREATE); + db_handles_.emplace_back(std::move(db), 0); CreateParserDBHandlerMock create_db_handler(0, 0); EXPECT_CALL(create_db_handler, Connect()) .Times(2).WillRepeatedly(testing::Return(true)); EXPECT_CALL(create_db_handler, GetConnection()) - .Times(2).WillRepeatedly(testing::Return(GetDBHandles())); + .Times(2).WillRepeatedly(testing::ReturnRef(db_handles_)); EXPECT_CALL(GetMock(), system_info_get_platform_int(testing::_, testing::_)) .WillRepeatedly(testing::DoAll( testing::SetArgPointee<1>(120), testing::Return(0))); - fopen_mock_setup(true); + MakeVersionFile(); + pkgmgr_server::internal::SetEnableUnitTest(true); ASSERT_EQ(create_db_handler.Execute(), 0); - fopen_mock_setup(false); + pkgmgr_server::internal::SetEnableUnitTest(false); } virtual void TearDown() { - for (auto& handle : db_handles_) - sqlite3_close_v2(handle.first); - + db_handles_.clear(); ASSERT_EQ(remove(TEST_PARSER_DB), 0); std::string journal_path(TEST_PARSER_DB); journal_path += "-journal"; ASSERT_EQ(remove(journal_path.c_str()), 0); } - const std::vector>& GetDBHandles() { - return db_handles_; - } - private: - void SetDBHandles(std::vector>&& db_handles) { - db_handles_ = db_handles; + void MakeVersionFile() { + std::remove("./pkg_db_version.txt"); + std::ofstream ofs("./pkg_db_version.txt"); + ofs << "30005"; } - std::vector> db_handles_; + protected: + std::vector> db_handles_; }; TEST_F(ParserDBHandlerTest, QueryDBHandler_PluginInfoTest) { @@ -141,7 +132,7 @@ TEST_F(ParserDBHandlerTest, QueryDBHandler_PluginInfoTest) { EXPECT_CALL(set_query_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(set_query_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); ASSERT_EQ(set_query_handler.Execute(), 0); QueryHandlerMock get_query_handler(0, 0); @@ -158,7 +149,7 @@ TEST_F(ParserDBHandlerTest, QueryDBHandler_PluginInfoTest) { EXPECT_CALL(get_query_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(get_query_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); ASSERT_EQ(get_query_handler.Execute(), 0); auto result = get_query_handler.GetResult(); ASSERT_EQ(result.size(), 1); @@ -175,7 +166,7 @@ TEST_F(ParserDBHandlerTest, QueryDBHandler_GetLocaledLabelTest) { EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true)); EXPECT_CALL(pkg_set_db_handler, GetConnection()) - .WillOnce(testing::Return(GetDBHandles())); + .WillOnce(testing::ReturnRef(db_handles_)); ASSERT_EQ(pkg_set_db_handler.Execute(), 0); std::vector