2 * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include <sys/smack.h>
24 #include <linux/limits.h>
29 #include <system_info.h>
34 #include <string_view>
36 #include "pkgmgr_parser.h"
37 #include "pkgmgrinfo_basic.h"
38 #include "pkgmgrinfo_internal.h"
39 #include "pkgmgrinfo_private.h"
40 #include "pkgmgrinfo_debug.h"
41 #include "pkgmgr-info.h"
45 constexpr const char LDPI[] = "ldpi";
46 constexpr const char MDPI[] = "mdpi";
47 constexpr const char HDPI[] = "hdpi";
48 constexpr const char XHDPI[] = "xhdpi";
49 constexpr const char XXHDPI[] = "xxhdpi";
51 constexpr const int LDPI_MIN = 0;
52 constexpr const int LDPI_MAX = 240;
53 constexpr const int MDPI_MIN = 241;
54 constexpr const int MDPI_MAX = 300;
55 constexpr const int HDPI_MIN = 301;
56 constexpr const int HDPI_MAX = 380;
57 constexpr const int XHDPI_MIN = 381;
58 constexpr const int XHDPI_MAX = 480;
59 constexpr const int XXHDPI_MIN = 481;
60 constexpr const int XXHDPI_MAX = 600;
62 constexpr const char join_localized_info[] =
63 " LEFT OUTER JOIN package_localized_info"
64 " ON pi.package=package_localized_info.package"
65 " AND package_localized_info.package_locale=?";
66 constexpr const char join_privilege_info[] =
67 " LEFT OUTER JOIN package_privilege_info"
68 " ON pi.package=package_privilege_info.package";
69 constexpr const char join_res_info[] =
70 " LEFT OUTER JOIN package_res_info"
71 " ON pi.package=package_res_info.package";
72 constexpr const char join_metadata[] =
73 " LEFT OUTER JOIN package_metadata"
74 " ON pi.package=package_metadata.package";
76 char* GetCString(int idx, const tizen_base::Database::Result::Record& rec) {
77 std::optional<std::string> str = rec.GetString(idx);
81 return strdup(str->c_str());
84 int _pkginfo_add_description_info_into_list(const char *locale,
85 char *record, GList **description) {
88 info = reinterpret_cast<description_x*>(calloc(1, sizeof(description_x)));
90 LOGE("out of memory");
91 return PMINFO_R_ERROR;
93 info->lang = strdup(locale);
95 *description = g_list_prepend(*description, info);
100 int GetPluginExecutionInfo(const tizen_base::Database& db,
101 const char* pkgid, GList** plugins) {
102 auto q = std::move(tizen_base::Database::Sql(
103 "SELECT appid, plugin_type, plugin_name FROM package_plugin_info "
109 LOGE("db.Exec failed : %s", static_cast<const char*>(r));
110 return PMINFO_R_ERROR;
113 for (const auto& rec : r) {
114 plugin_x* plugin = reinterpret_cast<plugin_x*>(
115 calloc(1, sizeof(plugin_x)));
117 LOGE("out of memory");
118 return PMINFO_R_ERROR;
121 plugin->pkgid = strdup(pkgid);
122 plugin->appid = GetCString(0, rec);
123 plugin->plugin_type = GetCString(1, rec);
124 plugin->plugin_name = GetCString(2, rec);
125 *plugins = g_list_prepend(*plugins, (gpointer)plugin);
131 int GetPrivilege(const tizen_base::Database& db, const char* pkgid,
132 GList** privileges) {
133 auto q = std::move(tizen_base::Database::Sql(
134 "SELECT DISTINCT privilege, type FROM package_privilege_info "
139 LOGE("db.Exec failed : %s", static_cast<const char*>(r));
140 return PMINFO_R_ERROR;
143 for (const auto& rec : r) {
144 privilege_x* privilege = reinterpret_cast<privilege_x*>(
145 calloc(1, sizeof(privilege_x)));
147 LOGE("failed to alloc memory");
148 return PMINFO_R_ERROR;
151 privilege->value = GetCString(0, rec);
152 privilege->type = GetCString(1, rec);
153 *privileges = g_list_prepend(*privileges, (gpointer)privilege);
159 int GetAppdefinedPrivilege(const tizen_base::Database& db,
160 const char* pkgid, GList** privileges) {
161 auto q = std::move(tizen_base::Database::Sql(
162 "SELECT DISTINCT privilege, license, type FROM "
163 "package_appdefined_privilege_info WHERE package=?")
167 LOGE("db.Exec failed : %s", static_cast<const char*>(r));
168 return PMINFO_R_ERROR;
171 for (const auto& rec : r) {
172 appdefined_privilege_x* privilege = reinterpret_cast<
173 appdefined_privilege_x*>(calloc(1, sizeof(appdefined_privilege_x)));
175 LOGE("failed to alloc memory");
176 return PMINFO_R_ERROR;
179 privilege->value = GetCString(0, rec);
180 privilege->license = GetCString(1, rec);
181 privilege->type = GetCString(2, rec);
182 *privileges = g_list_prepend(*privileges, (gpointer)privilege);
188 int GetDependency(const tizen_base::Database& db, const char* pkgid,
189 GList** dependencies) {
190 auto q = std::move(tizen_base::Database::Sql(
191 "SELECT DISTINCT depends_on, type, required_version "
192 "FROM package_dependency_info WHERE package=?")
196 LOGE("db.Exec failed : %s", static_cast<const char*>(r));
197 return PMINFO_R_ERROR;
200 for (const auto& rec : r) {
201 dependency_x* dependency = reinterpret_cast<
202 dependency_x*>(calloc(1, sizeof(dependency_x)));
204 LOGE("failed to alloc memory");
205 return PMINFO_R_ERROR;
208 dependency->depends_on = GetCString(0, rec);
209 dependency->type = GetCString(1, rec);
210 dependency->required_version = GetCString(2, rec);
211 *dependencies = g_list_prepend(*dependencies, (gpointer)dependency);
217 int GetResAllowedPackages(const tizen_base::Database& db, const char* pkgid,
218 GList** allowed_packages) {
219 auto q = std::move(tizen_base::Database::Sql(
220 "SELECT DISTINCT allowed_package, required_privilege "
221 "FROM package_res_allowed_package WHERE package=?")
225 LOGE("db.Exec failed : %s", static_cast<const char*>(r));
226 return PMINFO_R_ERROR;
229 for (const auto& rec : r) {
230 res_allowed_package_x* allowed_package_x = nullptr;
231 char* package = nullptr;
232 char* privilege = nullptr;
234 package = GetCString(0, rec);
238 for (GList* l = *allowed_packages; l; l = l->next) {
239 allowed_package_x = (res_allowed_package_x *)l->data;
240 if (!strcmp(package, allowed_package_x->allowed_package))
242 allowed_package_x = nullptr;
245 if (allowed_package_x) {
248 allowed_package_x = reinterpret_cast<res_allowed_package_x*>(calloc(1,
249 sizeof(res_allowed_package_x)));
250 if (allowed_package_x == nullptr) {
251 LOGE("failed to alloc memory");
253 return PMINFO_R_ERROR;
255 allowed_package_x->allowed_package = package;
256 *allowed_packages = g_list_prepend(*allowed_packages,
257 (gpointer)allowed_package_x);
260 privilege = GetCString(1, rec);
264 allowed_package_x->required_privileges = g_list_prepend(
265 allowed_package_x->required_privileges,
272 int GetResInfo(const tizen_base::Database& db, const char* pkgid,
273 char** res_type, char** res_version, char** lib,
274 GList** res_allowed_packages) {
275 auto q = std::move(tizen_base::Database::Sql(
276 "SELECT DISTINCT res_type, res_version, lib "
277 "FROM package_res_info WHERE package=?")
281 LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
282 return PMINFO_R_ERROR;
285 auto rec = r.GetFirstRecord();
289 if (GetResAllowedPackages(db, pkgid, res_allowed_packages) != PMINFO_R_OK)
290 return PMINFO_R_ERROR;
292 *res_type = GetCString(0, *rec);
293 *res_version = GetCString(1, *rec);
294 *lib = GetCString(2, *rec);
299 int GetPackageMetadata(const tizen_base::Database& db,
300 const char* pkgid, GList** metadata) {
301 auto q = std::move(tizen_base::Database::Sql(
302 "SELECT md_key, md_value "
303 "FROM package_metadata WHERE package=?")
308 _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
309 return PMINFO_R_ERROR;
312 for (const auto& rec : r) {
313 metadata_x* info = static_cast<metadata_x*>(
314 calloc(1, sizeof(metadata_x)));
315 if (info == nullptr) {
316 LOGE("out of memory");
317 return PMINFO_R_ERROR;
321 info->key = GetCString(idx++, rec);
322 info->value = GetCString(idx++, rec);
323 *metadata = g_list_prepend(*metadata, info);
329 int _get_filtered_query(pkgmgrinfo_filter_x *filter,
330 const std::string& locale, uid_t uid,
331 std::string& query, std::vector<std::string>& bind_params) {
336 if (filter->cache_flag) {
337 joined = E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO |
338 E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO |
339 E_PMINFO_PKGINFO_JOIN_RES_INFO |
340 E_PMINFO_PKGINFO_JOIN_METADATA;
343 std::string buf = " WHERE 1=1 ";
344 GList *tmp_params = nullptr;
345 for (GSList* list = filter->list; list; list = list->next) {
346 char* condition = nullptr;
347 joined |= __get_filter_condition(list->data, uid, &condition,
349 if (condition == nullptr)
357 if (filter->list_pkg_metadata)
359 for (GSList* list = filter->list_pkg_metadata; list; list = list->next) {
360 char* condition = nullptr;
361 joined |= __get_pkg_metadata_filter_condition(list->data,
362 &condition, &tmp_params);
363 if (condition == nullptr)
369 if (filter->list_pkg_metadata)
373 if (joined & E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO) {
374 buf2 += join_localized_info;
375 bind_params.push_back(locale);
378 if (joined & E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO)
379 buf2 += join_privilege_info;
380 if (joined & E_PMINFO_PKGINFO_JOIN_RES_INFO)
381 buf2 += join_res_info;
382 if (joined & E_PMINFO_PKGINFO_JOIN_METADATA)
383 buf2 += join_metadata;
385 for (GList* l = tmp_params; l != nullptr; l = l->next)
386 bind_params.push_back(reinterpret_cast<const char*>(l->data));
389 g_list_free_full(tmp_params, free);
394 bool CheckPackageStorageStatus(pkgmgrinfo_filter_x* tmp_filter) {
395 GSList* tmp_list = nullptr;
396 pkgmgrinfo_node_x* tmp_node = nullptr;
399 if (tmp_filter->cache_flag)
402 property = _pminfo_pkginfo_convert_to_prop_bool(
403 PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE);
404 for (tmp_list = tmp_filter->list; tmp_list != nullptr;
405 tmp_list = g_slist_next(tmp_list)) {
406 tmp_node = reinterpret_cast<pkgmgrinfo_node_x*>(tmp_list->data);
407 if (property == tmp_node->prop) {
408 if (strcmp(tmp_node->value, "true") == 0)
417 bool CheckPackageDisableFilter(const pkgmgrinfo_filter_x* filter,
418 const package_x* pkg_info) {
419 GSList* tmp_list = nullptr;
420 pkgmgrinfo_node_x* tmp_node = nullptr;
423 property = _pminfo_pkginfo_convert_to_prop_bool(
424 PMINFO_PKGINFO_PROP_PACKAGE_DISABLE);
425 for (tmp_list = filter->list; tmp_list != nullptr;
426 tmp_list = g_slist_next(tmp_list)) {
427 tmp_node = reinterpret_cast<pkgmgrinfo_node_x*>(tmp_list->data);
428 if (property != tmp_node->prop)
431 if (strcasecmp(tmp_node->value, pkg_info->is_disabled) == 0)
434 if (strcasecmp(pkg_info->is_disabled, "true") == 0)
435 LOGW("The package [%s] is disabled", pkg_info->package);
442 int DoGetPkgInfo(const tizen_base::Database& db, uid_t uid,
443 const std::string& locale, pkgmgrinfo_filter_x* filter, int flag,
444 std::map<std::string, std::shared_ptr<package_x>>& packages) {
445 static const char query_raw[] =
446 "SELECT DISTINCT pi.package, pi.installed_storage, pi.external_path, "
447 "pi.package_disable";
448 static const char query_basic[] =
449 ", pi.package_version, pi.install_location, "
450 "pi.package_removable, pi.package_preload, pi.package_readonly, "
451 "pi.package_update, pi.package_appsetting, pi.package_system, "
452 "pi.package_type, pi.package_size, pi.installed_time, "
453 "pi.storeclient_id, pi.mainapp_id, pi.package_url, pi.root_path, "
454 "pi.csc_path, pi.package_nodisplay, pi.package_api_version, "
455 "pi.package_support_disable, pi.package_tep_name, "
456 "pi.package_zip_mount_file, pi.package_support_mode, "
457 "pi.light_user_switch_mode";
458 static const char query_author[] =
459 ", pi.author_name, pi.author_email, pi.author_href";
460 static const char query_label[] =
462 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
463 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
464 static const char query_icon[] =
466 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
467 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
468 static const char query_description[] =
470 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
471 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
472 static const char query_res_type[] =
473 ", (SELECT res_type FROM package_res_info WHERE pi.package=package)";
474 static const char query_res_version[] =
475 ", (SELECT res_version FROM package_res_info WHERE pi.package=package)";
476 static const char query_res_lib[] =
477 ", (SELECT lib FROM package_res_info WHERE pi.package=package)";
478 static const char query_from_clause[] = " FROM package_info as pi";
479 int ret = PMINFO_R_ERROR;
480 char* tmp_record = nullptr;
481 std::vector<std::string> bind_params;
482 bool is_check_storage = true;
483 const uid_t global_user_uid = GLOBAL_USER;
485 if (!static_cast<bool>(db) || locale.empty() || filter == nullptr) {
486 LOGE("Invalid parameter");
487 return PMINFO_R_EINVAL;
490 is_check_storage = CheckPackageStorageStatus(filter);
491 std::string query = query_raw;
492 if (flag & PMINFO_APPINFO_GET_BASICINFO)
493 query += query_basic;
494 if (flag & PMINFO_PKGINFO_GET_AUTHOR)
495 query += query_author;
496 if (flag & PMINFO_PKGINFO_GET_LABEL) {
497 query += query_label;
498 bind_params.push_back(locale);
501 if (flag & PMINFO_PKGINFO_GET_ICON) {
503 bind_params.push_back(locale);
506 if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
507 query += query_description;
508 bind_params.push_back(locale);
511 if (flag & PMINFO_PKGINFO_GET_RES_INFO) {
512 query += query_res_type;
513 query += query_res_version;
514 query += query_res_lib;
517 query += query_from_clause;
518 std::string constraints;
519 ret = _get_filtered_query(filter, locale, uid,
520 constraints, bind_params);
521 if (ret != PMINFO_R_OK) {
522 LOGE("Failed to get WHERE clause");
523 return PMINFO_R_EINVAL;
526 if (!constraints.empty())
527 query += constraints;
529 auto q = tizen_base::Database::Sql(query);
530 for (auto& i : bind_params)
535 LOGE("db.Exec failed : %s", static_cast<const char*>(r));
536 return PMINFO_R_ERROR;
539 for (const auto& rec : r) {
540 package_x* info = reinterpret_cast<package_x*>(calloc(1, sizeof(package_x)));
541 if (info == nullptr) {
542 LOGE("out of memory");
543 return PMINFO_R_ERROR;
546 std::shared_ptr<package_x> pkg(info, pkgmgrinfo_basic_free_package);
547 info->locale = strdup(locale.c_str());
548 if (info->locale == nullptr) {
549 LOGE("Out of memory");
550 return PMINFO_R_ERROR;
555 info->package = GetCString(idx++, rec);
556 info->installed_storage = GetCString(idx++, rec);
557 info->external_path = GetCString(idx++, rec);
558 info->is_disabled = GetCString(idx++, rec);
559 if (flag & PMINFO_APPINFO_GET_BASICINFO) {
560 info->version = GetCString(idx++, rec);
561 info->installlocation = GetCString(idx++, rec);
562 info->removable = GetCString(idx++, rec);
563 info->preload = GetCString(idx++, rec);
564 info->readonly = GetCString(idx++, rec);
565 info->update = GetCString(idx++, rec);
566 info->appsetting = GetCString(idx++, rec);
567 info->system = GetCString(idx++, rec);
568 info->type = GetCString(idx++, rec);
569 info->package_size = GetCString(idx++, rec);
570 info->installed_time = GetCString(idx++, rec);
571 info->storeclient_id = GetCString(idx++, rec);
572 info->mainapp_id = GetCString(idx++, rec);
573 info->package_url = GetCString(idx++, rec);
574 info->root_path = GetCString(idx++, rec);
575 info->csc_path = GetCString(idx++, rec);
576 info->nodisplay_setting = GetCString(idx++, rec);
577 info->api_version = GetCString(idx++, rec);
578 info->support_disable = GetCString(idx++, rec);
579 info->tep_name = GetCString(idx++, rec);
580 info->zip_mount_file = GetCString(idx++, rec);
581 info->support_mode = GetCString(idx++, rec);
582 info->light_user_switch_mode = GetCString(idx++, rec);
585 info->for_all_users =
586 strdup((uid != global_user_uid) ? "false" : "true");
588 if (GetPluginExecutionInfo(db, info->package, &info->plugin))
589 return PMINFO_R_ERROR;
591 if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
592 author_x* author = reinterpret_cast<author_x*>(calloc(1, sizeof(author_x)));
593 if (author == nullptr) {
594 return PMINFO_R_ERROR;
596 author->text = GetCString(idx++, rec);
597 author->email = GetCString(idx++, rec);
598 author->href = GetCString(idx++, rec);
599 info->author = g_list_prepend(info->author, author);
602 if (flag & PMINFO_PKGINFO_GET_LABEL) {
603 tmp_record = GetCString(idx++, rec);
604 if (_add_label_info_into_list(locale.c_str(),
605 tmp_record, &info->label)) {
606 return PMINFO_R_ERROR;
610 if (flag & PMINFO_PKGINFO_GET_ICON) {
611 tmp_record = GetCString(idx++, rec);
612 if (_add_icon_info_into_list(locale.c_str(),
613 tmp_record, &info->icon)) {
614 return PMINFO_R_ERROR;
618 if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
619 tmp_record = GetCString(idx++, rec);
620 if (_pkginfo_add_description_info_into_list(locale.c_str(),
621 tmp_record, &info->description)) {
622 return PMINFO_R_ERROR;
626 if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) {
627 if (GetPrivilege(db, info->package, &info->privileges))
628 return PMINFO_R_ERROR;
631 if (flag & PMINFO_PKGINFO_GET_APPDEFINED_PRIVILEGE) {
632 if (GetAppdefinedPrivilege(db, info->package,
633 &info->appdefined_privileges)) {
634 return PMINFO_R_ERROR;
638 if (flag & PMINFO_PKGINFO_GET_DEPENDENCY) {
639 if (GetDependency(db, info->package, &info->dependencies))
640 return PMINFO_R_ERROR;
643 if (flag & PMINFO_PKGINFO_GET_RES_INFO) {
644 if (GetResInfo(db, info->package, &info->res_type,
645 &info->res_version, &info->lib, &info->res_allowed_packages) < 0) {
646 return PMINFO_R_ERROR;
650 if (flag & PMINFO_PKGINFO_GET_METADATA) {
651 if (GetPackageMetadata(db, info->package, &info->metadata) < 0)
652 return PMINFO_R_ERROR;
655 if (is_check_storage && __pkginfo_check_installed_storage(info) !=
659 if (!CheckPackageDisableFilter(filter, info))
662 if (!(flag & PMINFO_APPINFO_GET_BASICINFO) && info->is_disabled) {
663 free(info->is_disabled);
664 info->is_disabled = nullptr;
667 packages[info->package] = std::move(pkg);
673 int DoGetDependsOn(const tizen_base::Database& db, const std::string& pkgid,
674 std::queue<std::string>& queue, std::set<std::string>& dup_checker,
675 std::vector<dependency_x*>& dep_list) {
676 if (dup_checker.find(pkgid) != dup_checker.end())
678 dup_checker.insert(pkgid);
680 auto q = std::move(tizen_base::Database::Sql(
681 "SELECT package, depends_on, type, required_version "
682 "FROM package_dependency_info WHERE depends_on=?")
687 LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
688 return PMINFO_R_ERROR;
691 for (const auto& rec : r) {
692 auto* req = reinterpret_cast<dependency_x*>(calloc(1, sizeof(dependency_x)));
693 if (req == nullptr) {
694 LOGE("out of memory");
695 return PMINFO_R_ERROR;
698 req->pkgid = GetCString(0, rec);
699 req->depends_on = GetCString(1, rec);
700 req->type = GetCString(2, rec);
701 req->required_version = GetCString(3, rec);
703 dep_list.push_back(req);
704 queue.push(req->pkgid);
710 void __free_depends_on(dependency_x* dep) {
712 free(dep->depends_on);
714 free(dep->required_version);
718 int DoExecuteQuery(const tizen_base::Database& db, const std::string& query,
719 const std::vector<std::optional<std::string>>& param) {
720 auto q = tizen_base::Database::Sql(query);
721 for (auto& p : param) {
725 q.Bind(std::nullopt);
730 LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
731 return PMINFO_R_ERROR;
737 int __check_dpi(const char *dpi_char, int dpi_int) {
738 if (dpi_char == NULL)
741 if (strcasecmp(dpi_char, LDPI) == 0) {
742 if (dpi_int >= LDPI_MIN && dpi_int <= LDPI_MAX)
746 } else if (strcasecmp(dpi_char, MDPI) == 0) {
747 if (dpi_int >= MDPI_MIN && dpi_int <= MDPI_MAX)
751 } else if (strcasecmp(dpi_char, HDPI) == 0) {
752 if (dpi_int >= HDPI_MIN && dpi_int <= HDPI_MAX)
756 } else if (strcasecmp(dpi_char, XHDPI) == 0) {
757 if (dpi_int >= XHDPI_MIN && dpi_int <= XHDPI_MAX)
761 } else if (strcasecmp(dpi_char, XXHDPI) == 0) {
762 if (dpi_int >= XXHDPI_MIN && dpi_int <= XXHDPI_MAX)
770 void __find_appcontrol_splashscreen_with_dpi(gpointer data,
771 gpointer user_data) {
772 splashscreen_x *ss = (splashscreen_x *)data;
773 GList **list = (GList **)user_data;
777 if (ss->operation == NULL || ss->dpi == NULL)
780 ret = system_info_get_platform_int(
781 "http://tizen.org/feature/screen.dpi", &dpi);
782 if (ret != SYSTEM_INFO_ERROR_NONE)
785 if (__check_dpi(ss->dpi, dpi) != 0)
788 *list = g_list_prepend(*list, ss);
791 void __find_appcontrol_splashscreen(gpointer data, gpointer user_data) {
792 splashscreen_x *ss = (splashscreen_x *)data;
793 GList **list = (GList **)user_data;
794 splashscreen_x *ss_tmp;
797 if (ss->operation == NULL || ss->dpi)
800 for (tmp = *list; tmp; tmp = tmp->next) {
801 ss_tmp = (splashscreen_x *)tmp->data;
802 if (ss_tmp->operation
803 && strcmp(ss_tmp->operation, ss->operation) == 0
804 && strcmp(ss_tmp->orientation, ss->orientation) == 0)
808 *list = g_list_prepend(*list, ss);
811 gint __compare_splashscreen_with_orientation_dpi(gconstpointer a,
813 splashscreen_x *ss = (splashscreen_x *)a;
814 const char *orientation = (const char *)b;
818 if (ss->operation || ss->dpi == NULL)
821 ret = system_info_get_platform_int(
822 "http://tizen.org/feature/screen.dpi", &dpi);
823 if (ret != SYSTEM_INFO_ERROR_NONE)
826 if (strcasecmp(ss->orientation, orientation) == 0 &&
827 __check_dpi(ss->dpi, dpi) == 0)
833 gint __compare_splashscreen_with_orientation(gconstpointer a,
835 splashscreen_x *ss = (splashscreen_x *)a;
836 const char *orientation = (const char *)b;
838 if (ss->operation || ss->dpi)
841 if (strcasecmp(ss->orientation, orientation) == 0)
847 splashscreen_x *__find_default_splashscreen(GList *splashscreens,
848 const char *orientation) {
851 tmp = g_list_find_custom(splashscreens, orientation,
853 __compare_splashscreen_with_orientation_dpi);
855 return (splashscreen_x *)tmp->data;
857 tmp = g_list_find_custom(splashscreens, orientation,
858 (GCompareFunc)__compare_splashscreen_with_orientation);
860 return (splashscreen_x *)tmp->data;
865 GList *__find_splashscreens(GList *splashscreens) {
869 if (splashscreens == NULL)
872 g_list_foreach(splashscreens,
873 __find_appcontrol_splashscreen_with_dpi, &list);
874 g_list_foreach(splashscreens,
875 __find_appcontrol_splashscreen, &list);
877 ss = __find_default_splashscreen(splashscreens, "portrait");
879 list = g_list_prepend(list, ss);
880 ss = __find_default_splashscreen(splashscreens, "landscape");
882 list = g_list_prepend(list, ss);
887 int InsertSplashscreenInfo(const tizen_base::Database& db,
888 application_x *app, GList *ss_list) {
889 if (app->splashscreens == nullptr)
892 if (ss_list == nullptr)
895 auto q = tizen_base::Database::Sql(
896 "INSERT INTO package_app_splash_screen (app_id, src, type,"
897 " orientation, indicatordisplay, operation, color_depth) "
898 "VALUES (?, ?, ?, ?, ?, ?, ?)");
899 auto r = db.Prepare(q);
901 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
905 for (GList* tmp = ss_list; tmp; tmp = tmp->next) {
906 splashscreen_x* ss = reinterpret_cast<splashscreen_x*>(tmp->data);
913 .Bind(ss->orientation)
914 .Bind(ss->indicatordisplay)
916 .Bind(ss->color_depth);
917 if (!db.Exec(q, r)) {
918 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
926 void __trimfunc(GList *trim_list) {
929 GList *list = g_list_first(trim_list);
932 trim_data = (char *)list->data;
935 if (strcmp(trim_data, prev) == 0) {
936 trim_list = g_list_remove(trim_list,
938 list = g_list_first(trim_list);
947 list = g_list_next(list);
951 int InsertPackageAppdefinedPrivilegeInfo(const tizen_base::Database& db,
953 auto q = tizen_base::Database::Sql(
954 "INSERT INTO package_appdefined_privilege_info "
955 "(package, privilege, license, type) "
956 "VALUES (?, ?, ?, ?)");
957 auto r = db.Prepare(q);
959 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
963 for (GList* tmp = mfx->appdefined_privileges; tmp; tmp = tmp->next) {
964 appdefined_privilege_x* priv =
965 reinterpret_cast<appdefined_privilege_x*>(tmp->data);
974 if (!db.Exec(q, r)) {
975 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
983 int InsertPackageDependencyInfo(const tizen_base::Database& db,
985 auto q = tizen_base::Database::Sql(
986 "INSERT INTO package_dependency_info"
987 " (package, depends_on, type, required_version) "
988 "VALUES (?, ?, ?, ?)");
989 auto r = db.Prepare(q);
991 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
995 for (GList* tmp = mfx->dependencies; tmp; tmp = tmp->next) {
996 dependency_x* dep = reinterpret_cast<dependency_x*>(tmp->data);
1002 .Bind(dep->depends_on)
1004 .Bind(dep->required_version);
1006 if (!db.Exec(q, r)) {
1007 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
1015 int InsertMainappLocalizedInfo(const tizen_base::Database& db,
1016 application_x* app, const char* locale, const char* label,
1018 auto q = std::move(tizen_base::Database::Sql(
1019 "INSERT OR REPLACE INTO package_localized_info ("
1020 " package, package_locale, package_label, package_icon,"
1021 " package_description, package_license, package_author) "
1023 " COALESCE((SELECT package_label FROM package_localized_info"
1024 " WHERE package=? AND package_locale=?), ?),"
1025 " COALESCE((SELECT package_icon FROM package_localized_info"
1026 " WHERE package=? AND package_icon=?), ?),"
1027 " (SELECT package_description FROM package_localized_info"
1028 " WHERE package=? AND package_locale=?),"
1029 " (SELECT package_description FROM package_localized_info"
1030 " WHERE package=? AND package_locale=?),"
1031 " (SELECT package_description FROM package_localized_info"
1032 " WHERE package=? AND package_locale=?))")
1047 auto r = db.Exec(q);
1049 _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
1056 gint __comparefunc(gconstpointer a, gconstpointer b, gpointer userdata) {
1057 if (a == NULL || b == NULL)
1059 if (strcmp((char *)a, (char *)b) == 0)
1061 if (strcmp((char *)a, (char *)b) < 0)
1063 if (strcmp((char *)a, (char *)b) > 0)
1068 GList *__create_locale_list(GList *lbls, GList *lcns, GList *icns,
1069 GList *dcns, GList *aths) {
1070 GList *locale = NULL;
1078 for (tmp = lbls; tmp; tmp = tmp->next) {
1079 lbl = (label_x *)tmp->data;
1083 locale = g_list_insert_sorted_with_data(
1084 locale, (gpointer)lbl->lang,
1085 __comparefunc, NULL);
1087 for (tmp = lcns; tmp; tmp = tmp->next) {
1088 lcn = (license_x *)tmp->data;
1092 locale = g_list_insert_sorted_with_data(
1093 locale, (gpointer)lcn->lang,
1094 __comparefunc, NULL);
1096 for (tmp = icns; tmp; tmp = tmp->next) {
1097 icn = (icon_x *)tmp->data;
1101 locale = g_list_insert_sorted_with_data(
1102 locale, (gpointer)icn->lang,
1103 __comparefunc, NULL);
1105 for (tmp = dcns; tmp; tmp = tmp->next) {
1106 dcn = (description_x *)tmp->data;
1110 locale = g_list_insert_sorted_with_data(
1111 locale, (gpointer)dcn->lang,
1112 __comparefunc, NULL);
1114 for (tmp = aths; tmp; tmp = tmp->next) {
1115 ath = (author_x *)tmp->data;
1119 locale = g_list_insert_sorted_with_data(
1120 locale, (gpointer)ath->lang,
1121 __comparefunc, NULL);
1127 gint __check_icon_resolution(std::string_view orig_icon_path,
1128 char **new_icon_path) {
1129 const char* dpi_path[2];
1130 std::string modified_iconpath;
1131 if (orig_icon_path.empty())
1135 int ret = system_info_get_platform_int(
1136 "http://tizen.org/feature/screen.dpi", &dpi);
1137 if (ret != SYSTEM_INFO_ERROR_NONE)
1140 if (dpi >= LDPI_MIN && dpi <= LDPI_MAX) {
1141 dpi_path[0] = "LDPI";
1142 dpi_path[1] = "ldpi";
1143 } else if (dpi >= MDPI_MIN && dpi <= MDPI_MAX) {
1144 dpi_path[0] = "MDPI";
1145 dpi_path[1] = "mdpi";
1146 } else if (dpi >= HDPI_MIN && dpi <= HDPI_MAX) {
1147 dpi_path[0] = "HDPI";
1148 dpi_path[1] = "hdpi";
1149 } else if (dpi >= XHDPI_MIN && dpi <= XHDPI_MAX) {
1150 dpi_path[0] = "XHDPI";
1151 dpi_path[1] = "xhdpi";
1152 } else if (dpi >= XXHDPI_MIN && dpi <= XXHDPI_MAX) {
1153 dpi_path[0] = "XXHDPI";
1154 dpi_path[1] = "xxhdpi";
1156 _LOGE("Unidentified dpi[%d]", dpi);
1160 auto pos = orig_icon_path.rfind('/');
1161 if (pos == std::string::npos)
1163 std::string_view icon_filename = orig_icon_path.substr(pos);
1165 for (int i = 0; i < 2; i++) {
1166 modified_iconpath = std::string(orig_icon_path) +
1167 "/" + dpi_path[i] + std::string(icon_filename);
1168 if (access(modified_iconpath.c_str(), F_OK) != -1) {
1169 *new_icon_path = strdup(modified_iconpath.c_str());
1177 gint __compare_icon(gconstpointer a, gconstpointer b) {
1178 icon_x *icon = (icon_x *)a;
1181 if (icon->lang != NULL && strcasecmp(icon->lang, DEFAULT_LOCALE) != 0)
1184 if (icon->dpi != NULL)
1187 if (__check_icon_resolution(icon->text, &icon_path) == 0) {
1189 icon->text = icon_path;
1195 gint __compare_icon_with_lang(gconstpointer a, gconstpointer b) {
1196 icon_x *icon = (icon_x *)a;
1197 char *lang = (char *)b;
1200 if (icon->dpi != NULL)
1203 if (strcasecmp(icon->lang, lang) == 0) {
1204 if (strcasecmp(icon->lang, DEFAULT_LOCALE) == 0) {
1205 /* icon for no locale. check existance of
1206 * folder-hierachied default icons
1208 if (__check_icon_resolution(icon->text,
1211 icon->text = icon_path;
1220 gint __compare_icon_with_dpi(gconstpointer a, gconstpointer b) {
1221 icon_x *icon = (icon_x *)a;
1222 int dpi = GPOINTER_TO_INT(b);
1224 if (icon->lang != NULL && strcasecmp(icon->lang, DEFAULT_LOCALE) != 0)
1227 if (icon->dpi == NULL)
1230 if (__check_dpi(icon->dpi, dpi) == 0)
1236 gint __compare_icon_with_lang_dpi(gconstpointer a, gconstpointer b) {
1238 icon_x *icon = (icon_x *)a;
1239 char *lang = (char *)b;
1242 ret = system_info_get_platform_int(
1243 "http://tizen.org/feature/screen.dpi", &dpi);
1244 if (ret != SYSTEM_INFO_ERROR_NONE)
1247 if (strcasecmp(icon->lang, lang) == 0 &&
1248 __check_dpi(icon->dpi, dpi) == 0)
1254 char *__find_icon(GList *icons, const char *lang) {
1260 /* first, find icon whose locale and dpi with given lang and
1261 * system's dpi has matched
1263 tmp = g_list_find_custom(icons, lang,
1264 (GCompareFunc)__compare_icon_with_lang_dpi);
1266 icon = (icon_x *)tmp->data;
1267 return (char *)icon->text;
1270 /* if first has failed, find icon whose locale has matched */
1271 tmp = g_list_find_custom(icons, lang,
1272 (GCompareFunc)__compare_icon_with_lang);
1274 icon = (icon_x *)tmp->data;
1275 return (char *)icon->text;
1278 /* if second has failed, find icon whose dpi has matched with
1281 ret = system_info_get_platform_int(
1282 "http://tizen.org/feature/screen.dpi", &dpi);
1283 if (ret == SYSTEM_INFO_ERROR_NONE) {
1284 tmp = g_list_find_custom(icons, GINT_TO_POINTER(dpi),
1285 (GCompareFunc)__compare_icon_with_dpi);
1287 icon = (icon_x *)tmp->data;
1288 return (char *)icon->text;
1292 /* last, find default icon marked as "No Locale" */
1293 tmp = g_list_find_custom(icons, NULL, (GCompareFunc)__compare_icon);
1295 icon = (icon_x *)tmp->data;
1296 return (char *)icon->text;
1302 void __extract_data(const char *locale, GList *lbls, GList *lcns,
1303 GList *icns, GList *dcns, GList *aths, char **label,
1304 char **license, char **icon, char **description, char **author) {
1311 for (tmp = lbls; tmp; tmp = tmp->next) {
1312 lbl = (label_x *)tmp->data;
1316 if (strcmp(lbl->lang, locale) == 0) {
1317 *label = (char *)lbl->text;
1322 for (tmp = lcns; tmp; tmp = tmp->next) {
1323 lcn = (license_x *)tmp->data;
1327 if (strcmp(lcn->lang, locale) == 0) {
1328 *license = (char *)lcn->text;
1334 *icon = __find_icon(icns, locale);
1336 for (tmp = dcns; tmp; tmp = tmp->next) {
1337 dcn = (description_x *)tmp->data;
1341 if (strcmp(dcn->lang, locale) == 0) {
1342 *description = (char *)dcn->text;
1347 for (tmp = aths; tmp; tmp = tmp->next) {
1348 ath = (author_x *)tmp->data;
1352 if (strcmp(ath->lang, locale) == 0) {
1353 *author = (char *)ath->text;
1360 int InsertAppLocalizedInfo(const tizen_base::Database& db,
1361 application_x* app) {
1362 auto q = tizen_base::Database::Sql(
1363 "INSERT INTO package_app_localized_info (app_id, app_locale,"
1364 " app_label, app_icon) "
1365 "VALUES (?, ?, ?, ?)");
1366 auto r = db.Prepare(q);
1368 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
1372 std::unique_ptr<GList, decltype(g_list_free)*> locales(
1373 __create_locale_list(app->label, nullptr, app->icon, nullptr, nullptr),
1375 for (GList* tmp = locales.get(); tmp; tmp = tmp->next) {
1376 const char* locale = reinterpret_cast<char*>(tmp->data);
1377 char* label = nullptr;
1378 char* icon = nullptr;
1379 __extract_data(locale, app->label, nullptr, app->icon, nullptr, nullptr,
1380 &label, nullptr, &icon, nullptr, nullptr);
1381 if (!label && !icon)
1389 if (!db.Exec(q, r)) {
1390 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
1394 if (strcasecmp(app->mainapp, "true") == 0) {
1395 if (InsertMainappLocalizedInfo(db, app, locale, label, icon))
1396 _LOGE("insert mainapp localized info failed");
1403 int InsertAppResControl(const tizen_base::Database& db,
1404 application_x *app) {
1405 if (app->res_control == nullptr)
1408 auto q = tizen_base::Database::Sql(
1409 "INSERT INTO package_app_res_control (app_id, res_type,"
1410 " min_res_version, max_res_version, auto_close) "
1411 "VALUES (?, ?, ?, ?, ?)");
1412 auto r = db.Prepare(q);
1414 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
1418 for (GList* tmp = app->res_control; tmp; tmp = tmp->next) {
1419 res_control_x* rc = reinterpret_cast<res_control_x*>(tmp->data);
1426 .Bind(rc->min_res_version)
1427 .Bind(rc->max_res_version)
1428 .Bind(rc->auto_close);
1429 if (!db.Exec(q, r)) {
1430 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
1438 int InsertPackagePrivilegeInfo(const tizen_base::Database& db, manifest_x* mfx) {
1439 auto q = tizen_base::Database::Sql(
1440 "INSERT INTO package_privilege_info (package, privilege, type) "
1441 "VALUES (?, ?, ?)");
1442 auto r = db.Prepare(q);
1444 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
1448 for (GList* tmp = mfx->privileges; tmp; tmp = tmp->next) {
1449 privilege_x* priv = reinterpret_cast<privilege_x*>(tmp->data);
1450 if (priv == nullptr)
1457 if (!db.Exec(q, r)) {
1458 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
1466 int InsertAppDataControlPrivilegeInfo(const tizen_base::Database& db,
1467 datacontrol_x* datacontrol) {
1468 if (datacontrol == nullptr)
1471 auto q = tizen_base::Database::Sql(
1472 "INSERT INTO package_app_data_control_privilege (providerid,"
1473 " privilege, type) VALUES (?, ?, ?)");
1475 auto r = db.Prepare(q);
1477 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
1481 for (GList* privileges = datacontrol->privileges; privileges;
1482 privileges = privileges->next) {
1483 char* priv = reinterpret_cast<char*>(privileges->data);
1484 if (priv == nullptr)
1488 .Bind(datacontrol->providerid)
1490 .Bind(datacontrol->type);
1491 if (!db.Exec(q, r)) {
1492 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
1500 int InsertDatacontrolInfo(const tizen_base::Database& db, application_x* app) {
1501 if (app->datacontrol == nullptr)
1504 auto q = tizen_base::Database::Sql(
1505 "INSERT INTO package_app_data_control (app_id, providerid,"
1506 " access, type, trusted) VALUES (?, ?, ?, ?, ?)");
1507 auto r = db.Prepare(q);
1509 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
1513 for (GList* tmp = app->datacontrol; tmp; tmp = tmp->next) {
1514 datacontrol_x* dc = reinterpret_cast<datacontrol_x*>(tmp->data);
1519 .Bind(dc->providerid)
1524 if (!db.Exec(q, r)) {
1525 _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
1529 if (dc->privileges && InsertAppDataControlPrivilegeInfo(db, dc))
1536 int InsertCategoryInfo(const tizen_base::Database& db, application_x* app) {
1537 if (app->category == nullptr)
1540 auto q = tizen_base::Database::Sql(
1541 "INSERT INTO package_app_app_category (app_id, category) "
1543 auto r = db.Prepare(q);
1545 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
1549 for (GList* tmp = app->category; tmp; tmp = tmp->next) {
1550 const char* category = reinterpret_cast<const char*>(tmp->data);
1551 if (category == nullptr)
1557 if (!db.Exec(q, r)) {
1558 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
1566 int InsertMetadataInfo(const tizen_base::Database& db, application_x* app) {
1567 if (app->metadata == nullptr)
1570 auto q = tizen_base::Database::Sql(
1571 "INSERT INTO package_app_app_metadata (app_id,"
1572 " md_key, md_value) VALUES (?, ?, ?)");
1573 auto r = db.Prepare(q);
1575 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
1579 for (GList* tmp = app->metadata; tmp; tmp = tmp->next) {
1580 metadata_x* md = reinterpret_cast<metadata_x*>(tmp->data);
1588 if (!db.Exec(q, r)) {
1589 _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
1597 int InsertAppcontrolPrivilegeInfo(const tizen_base::Database& db,
1598 const char *appid, appcontrol_x* ac) {
1602 auto q = tizen_base::Database::Sql(
1603 "INSERT INTO package_app_app_control_privilege (app_id,"
1604 " app_control, privilege) VALUES (?, ?, ?)");
1605 auto r = db.Prepare(q);
1607 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
1611 char app_control[BUFSIZE];
1612 for (GList* tmp = ac->privileges; tmp; tmp = tmp->next) {
1613 char* privilege = reinterpret_cast<char*>(tmp->data);
1614 if (privilege == nullptr || !strlen(privilege))
1617 snprintf(app_control, sizeof(app_control), "%s|%s|%s",
1618 ac->operation ? (strlen(ac->operation) > 0 ?
1619 ac->operation : "NULL") : "NULL",
1620 ac->uri ? (strlen(ac->uri) > 0 ?
1621 ac->uri : "NULL") : "NULL",
1622 ac->mime ? (strlen(ac->mime) > 0 ?
1623 ac->mime : "NULL") : "NULL");
1628 if (!db.Exec(q,r)) {
1629 _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
1637 int InsertAppcontrolInfo(const tizen_base::Database& db, application_x* app) {
1638 if (app->appcontrol == nullptr)
1641 auto q = tizen_base::Database::Sql(
1642 "INSERT INTO package_app_app_control (app_id, app_control,"
1643 " visibility, app_control_id) "
1644 "VALUES (?, ?, ?, ?)");
1645 auto r = db.Prepare(q);
1647 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
1651 for (GList* tmp = app->appcontrol; tmp; tmp = tmp->next) {
1652 appcontrol_x* ac = reinterpret_cast<appcontrol_x*>(tmp->data);
1655 std::string op = ac->operation ? (strlen(ac->operation) > 0 ?
1656 ac->operation : "NULL") : "NULL";
1657 std::string uri = ac->uri ? (strlen(ac->uri) > 0 ?
1658 ac->uri : "NULL") : "NULL";
1659 std::string mime = ac->mime ? (strlen(ac->mime) > 0 ?
1660 ac->mime : "NULL") : "NULL";
1661 std::string app_control = std::move(op) + "|" + std::move(uri)
1662 + "|" + std::move(mime);
1665 .Bind(std::move(app_control))
1666 .Bind(ac->visibility)
1668 if (!db.Exec(q, r)) {
1669 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
1673 if (InsertAppcontrolPrivilegeInfo(db, app->appid, ac))
1680 const char *__get_bool(char *value, bool is_true) {
1681 if (value != NULL) {
1682 if (!strcmp(value, ""))
1683 return (is_true) ? "true" : "false";
1687 return (is_true) ? "true" : "false";
1690 const char *__find_effective_appid(GList *metadata_list) {
1691 constexpr const char EFFECTIVE_APPID_KEY[] =
1692 "http://tizen.org/metadata/effective-appid";
1697 for (tmp = metadata_list; tmp; tmp = tmp->next) {
1698 md = (metadata_x *)tmp->data;
1699 if (md == NULL || md->key == NULL)
1702 if (strcmp(md->key, EFFECTIVE_APPID_KEY) == 0) {
1711 int __convert_background_category(GList *category_list) {
1714 char *category_data;
1716 if (category_list == NULL)
1719 for (tmp = category_list; tmp; tmp = tmp->next) {
1720 category_data = (char *)tmp->data;
1721 if (category_data == NULL)
1723 if (!strcmp(category_data, APP_BG_CATEGORY_MEDIA_STR))
1724 ret |= APP_BG_CATEGORY_MEDIA_VAL;
1725 else if (!strcmp(category_data, APP_BG_CATEGORY_DOWNLOAD_STR))
1726 ret |= APP_BG_CATEGORY_DOWNLOAD_VAL;
1727 else if (!strcmp(category_data, APP_BG_CATEGORY_BGNETWORK_STR))
1728 ret |= APP_BG_CATEGORY_BGNETWORK_VAL;
1729 else if (!strcmp(category_data, APP_BG_CATEGORY_LOCATION_STR))
1730 ret |= APP_BG_CATEGORY_LOCATION_VAL;
1731 else if (!strcmp(category_data, APP_BG_CATEGORY_SENSOR_STR))
1732 ret |= APP_BG_CATEGORY_SENSOR_VAL;
1733 else if (!strcmp(category_data, APP_BG_CATEGORY_IOTCOMM_STR))
1734 ret |= APP_BG_CATEGORY_IOTCOMM_VAL;
1735 else if (!strcmp(category_data, APP_BG_CATEGORY_SYSTEM))
1736 ret |= APP_BG_CATEGORY_SYSTEM_VAL;
1738 _LOGE("Unidentified category [%s]", category_data);
1744 int InsertPackageResInfoAllowedPackage(const tizen_base::Database& db,
1745 const char* pkgid, GList* rap_list) {
1746 if (rap_list == nullptr)
1749 auto q = tizen_base::Database::Sql(
1750 "INSERT INTO package_res_allowed_package (package,"
1751 " allowed_package, required_privilege) VALUES (?, ?, ?)");
1752 auto r = db.Prepare(q);
1754 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
1758 for (GList* tmp = rap_list; tmp; tmp = tmp->next) {
1759 res_allowed_package_x* rap =
1760 reinterpret_cast<res_allowed_package_x*>(tmp->data);
1764 if (!rap->required_privileges) {
1767 .Bind(rap->allowed_package)
1770 if (!db.Exec(q, r)) {
1771 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
1778 for (GList* priv_list = rap->required_privileges; priv_list;
1779 priv_list = priv_list->next) {
1782 .Bind(rap->allowed_package)
1783 .Bind(reinterpret_cast<char*>(priv_list->data));
1785 if (!db.Exec(q, r)) {
1786 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
1795 int InsertPackageResInfo(const tizen_base::Database& db, manifest_x* mfx) {
1796 if (mfx->res_type == nullptr || mfx->res_version == nullptr)
1799 if (mfx->lib == nullptr)
1800 mfx->lib = strdup("false");
1802 auto q = std::move(tizen_base::Database::Sql(
1803 "INSERT INTO package_res_info (package, res_type,"
1804 " res_version, lib) VALUES (?, ?, ?, ?)")
1806 .Bind(mfx->res_type)
1807 .Bind(mfx->res_version)
1810 auto r = db.Exec(q);
1812 _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
1816 if (InsertPackageResInfoAllowedPackage(db, mfx->package,
1817 mfx->res_allowed_packages) < 0) {
1824 int InsertPackageMetadataInfo(const tizen_base::Database& db, manifest_x* mfx) {
1825 if (mfx->metadata == nullptr)
1828 auto q = tizen_base::Database::Sql(
1829 "INSERT INTO package_metadata (package,"
1830 " md_key, md_value) VALUES (?, ?, ?)");
1831 auto r = db.Prepare(q);
1833 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
1837 for (GList* tmp = mfx->metadata; tmp; tmp = tmp->next) {
1838 metadata_x* md = reinterpret_cast<metadata_x*>(tmp->data);
1846 if (!db.Exec(q, r)) {
1847 _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
1855 int InsertApplicationInfo(const tizen_base::Database& db, manifest_x *mfx) {
1856 auto q = tizen_base::Database::Sql(
1857 "INSERT INTO package_app_info (app_id, app_component,"
1858 " app_exec, app_nodisplay, app_type, app_onboot, app_multiple,"
1859 " app_autorestart, app_taskmanage, app_hwacceleration,"
1860 " app_screenreader, app_mainapp, app_recentimage,"
1861 " app_launchcondition, app_indicatordisplay, app_portraitimg,"
1862 " app_landscapeimg, app_guestmodevisibility,"
1863 " app_permissiontype, app_preload, app_submode,"
1864 " app_submode_mainid, app_installed_storage, app_process_pool,"
1865 " app_launch_mode, app_ui_gadget, app_support_mode,"
1866 " app_support_disable, component_type, package, app_tep_name,"
1867 " app_zip_mount_file, app_background_category,"
1868 " app_package_type, app_root_path, app_api_version,"
1869 " app_effective_appid, app_splash_screen_display,"
1870 " app_package_system, app_removable,"
1871 " app_package_installed_time, app_support_ambient,"
1872 " app_external_path, app_setup_appid, light_user_switch_mode) "
1874 " ?, LOWER(?), ?, LOWER(?), LOWER(?),"
1875 " LOWER(?), LOWER(?), ?,"
1879 " ?, LOWER(?), LOWER(?),"
1881 " COALESCE(?, 'single'), LOWER(?), ?,"
1882 " LOWER(?), ?, ?, ?,"
1886 " LOWER(?), LOWER(?),"
1889 auto r = db.Prepare(q);
1891 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
1895 for (GList* tmp = mfx->application; tmp; tmp = tmp->next) {
1896 application_x* app = reinterpret_cast<application_x*>(tmp->data);
1900 int bg_category = __convert_background_category(
1901 app->background_category);
1902 const char* effective_appid = __find_effective_appid(app->metadata);
1906 .Bind(app->component_type)
1908 .Bind(__get_bool(app->nodisplay, false))
1910 .Bind(__get_bool(app->onboot, false))
1911 .Bind(__get_bool(app->multiple, false))
1912 .Bind(__get_bool(app->autorestart, false))
1913 .Bind(__get_bool(app->taskmanage, false))
1914 .Bind(app->hwacceleration)
1915 .Bind(app->screenreader)
1916 .Bind(__get_bool(app->mainapp, false))
1917 .Bind(app->recentimage)
1918 .Bind(app->launchcondition)
1919 .Bind(__get_bool(app->indicatordisplay, true))
1920 .Bind(app->portraitimg)
1921 .Bind(app->landscapeimg)
1922 .Bind(__get_bool(app->guestmode_visibility, true))
1923 .Bind(app->permission_type)
1924 .Bind(__get_bool(mfx->preload, false))
1925 .Bind(__get_bool(app->submode, false))
1926 .Bind(app->submode_mainid)
1927 .Bind(mfx->installed_storage)
1928 .Bind(__get_bool(app->process_pool, false))
1929 .Bind(app->launch_mode)
1930 .Bind(__get_bool(app->ui_gadget, false))
1931 .Bind(app->support_mode ? app->support_mode : "0")
1932 .Bind(__get_bool(mfx->support_disable, false))
1933 .Bind(app->component_type)
1935 .Bind(mfx->tep_name)
1936 .Bind(mfx->zip_mount_file)
1938 .Bind(mfx->type ? mfx->type : "tpk")
1939 .Bind(mfx->root_path)
1940 .Bind(app->api_version)
1941 .Bind(effective_appid)
1942 .Bind(__get_bool(app->splash_screen_display, true))
1943 .Bind(__get_bool(mfx->system, false))
1944 .Bind(__get_bool(mfx->removable, false))
1945 .Bind(mfx->installed_time)
1946 .Bind(__get_bool(app->support_ambient, false))
1947 .Bind(mfx->external_path)
1948 .Bind(app->setup_appid)
1949 .Bind(mfx->light_user_switch_mode);
1951 if (!db.Exec(q, r)) {
1952 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
1956 if (InsertAppcontrolInfo(db, app))
1958 if (InsertCategoryInfo(db, app))
1960 if (InsertMetadataInfo(db, app))
1962 if (InsertDatacontrolInfo(db, app))
1964 GList* ss_list = __find_splashscreens(app->splashscreens);
1965 if (InsertSplashscreenInfo(db, app, ss_list)) {
1966 g_list_free(ss_list);
1969 g_list_free(ss_list);
1970 if (InsertAppLocalizedInfo(db, app))
1972 if (InsertAppResControl(db, app))
1979 int InsertPackageUpdateInfo(const tizen_base::Database& db, manifest_x *mfx) {
1980 auto q = std::move(tizen_base::Database::Sql(
1981 "INSERT INTO package_update_info (package, update_version) "
1984 .Bind(mfx->version));
1986 auto r = db.Exec(q);
1988 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
1995 int InsertPackageLocalizedInfo(const tizen_base::Database& db,
1997 auto q = tizen_base::Database::Sql(
1998 "INSERT INTO package_localized_info (package, package_locale,"
1999 " package_label, package_icon, package_description,"
2000 " package_license, package_author) "
2001 "VALUES (?, ?, ?, ?, ?, ?, ?)");
2002 auto r = db.Prepare(q);
2004 _LOGE("db.Prepare() failed: %s", static_cast<const char*>(r));
2008 GList* locales = __create_locale_list(mfx->label, mfx->license, mfx->icon,
2009 mfx->description, mfx->author);
2010 for (GList* tmp = locales; tmp; tmp = tmp->next) {
2011 const char* locale = (const char *)tmp->data;
2012 char* label = nullptr;
2013 char* icon = nullptr;
2014 char* description = nullptr;
2015 char* license = nullptr;
2016 char* author = nullptr;
2017 __extract_data(locale, mfx->label, mfx->license, mfx->icon,
2018 mfx->description, mfx->author,
2019 &label, &license, &icon, &description, &author);
2020 if (!label && !license && !icon && !description && !author)
2032 if (!db.Exec(q, r)) {
2033 _LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
2034 g_list_free(locales);
2039 g_list_free(locales);
2044 int DoInsertPackageInfo(const tizen_base::Database& db, manifest_x* mfx) {
2045 const char* author_name = nullptr;
2046 const char* author_email = nullptr;
2047 const char* author_href = nullptr;
2049 if (mfx->author && mfx->author->data) {
2050 author_name = ((author_x *)mfx->author->data)->text;
2051 author_email = ((author_x *)mfx->author->data)->email;
2052 author_href = ((author_x *)mfx->author->data)->href;
2055 auto q = std::move(tizen_base::Database::Sql(
2056 "INSERT INTO package_info (package, package_type,"
2057 " package_version, package_api_version, package_tep_name,"
2058 " package_zip_mount_file, install_location, package_size,"
2059 " package_removable, package_preload, package_readonly,"
2060 " package_update, package_appsetting, package_nodisplay,"
2061 " package_system, author_name, author_email, author_href,"
2062 " installed_time, installed_storage, storeclient_id,"
2063 " mainapp_id, package_url, root_path, external_path,"
2064 " csc_path, package_support_mode, package_support_disable,"
2065 " light_user_switch_mode)"
2069 " LOWER(?), LOWER(?), LOWER(?),"
2070 " LOWER(?), LOWER(?), LOWER(?),"
2071 " LOWER(?), ?, ?, ?,"
2074 " ?, ?, LOWER(?), ?)")
2078 .Bind(mfx->api_version)
2079 .Bind(mfx->tep_name)
2080 .Bind(mfx->zip_mount_file)
2081 .Bind(mfx->installlocation)
2082 .Bind(mfx->package_size)
2083 .Bind(__get_bool(mfx->removable, true))
2084 .Bind(__get_bool(mfx->preload, false))
2085 .Bind(__get_bool(mfx->readonly, false))
2086 .Bind(__get_bool(mfx->update, false))
2087 .Bind(__get_bool(mfx->appsetting, false))
2088 .Bind(__get_bool(mfx->nodisplay_setting, false))
2089 .Bind(__get_bool(mfx->system, false))
2093 .Bind(mfx->installed_time)
2094 .Bind(mfx->installed_storage)
2095 .Bind(mfx->storeclient_id)
2096 .Bind(mfx->mainapp_id)
2097 .Bind(mfx->package_url)
2098 .Bind(mfx->root_path)
2099 .Bind(mfx->external_path)
2100 .Bind(mfx->csc_path)
2101 .Bind(mfx->support_mode ? mfx->support_mode : "0")
2102 .Bind(__get_bool(mfx->support_disable, false))
2103 .Bind(mfx->light_user_switch_mode));
2105 auto r = db.Exec(q);
2107 _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
2111 if (InsertPackageUpdateInfo(db, mfx))
2113 if (InsertPackageLocalizedInfo(db, mfx))
2115 if (InsertApplicationInfo(db, mfx))
2117 if (InsertPackagePrivilegeInfo(db, mfx))
2119 if (InsertPackageAppdefinedPrivilegeInfo(db, mfx))
2121 if (InsertPackageDependencyInfo(db, mfx))
2123 if (InsertPackageResInfo(db, mfx))
2125 if (InsertPackageMetadataInfo(db, mfx))
2131 int DoDeletePackageInfo(const tizen_base::Database& db, const char* pkgid) {
2132 auto q = std::move(tizen_base::Database::Sql(
2133 "DELETE FROM package_info WHERE package=?")
2135 auto r = db.Exec(q);
2137 _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
2147 namespace pkgmgr_server::internal {
2149 int DeletePkgInfo(const tizen_base::Database& db, const char* package,
2151 if (!static_cast<bool>(db) || package == nullptr) {
2152 _LOGE("invalid parameter");
2153 return PM_PARSER_R_EINVAL;
2156 auto guard = db.CreateTransactionGuard();
2157 if (DoDeletePackageInfo(db, package) != 0)
2161 return PM_PARSER_R_OK;
2164 int UpdatePkgInfo(const tizen_base::Database& db, manifest_x* mfx, uid_t uid) {
2165 if (!static_cast<bool>(db) || mfx == nullptr || mfx->package == nullptr) {
2166 _LOGE("invalid parameter");
2167 return PM_PARSER_R_EINVAL;
2170 auto guard = db.CreateTransactionGuard();
2171 if (DoDeletePackageInfo(db, mfx->package) != 0)
2173 if (DoInsertPackageInfo(db, mfx) != 0)
2177 return PM_PARSER_R_OK;
2180 int InsertPkgInfo(const tizen_base::Database& db, manifest_x* mfx, uid_t uid) {
2181 if (!static_cast<bool>(db) || mfx == nullptr) {
2182 _LOGE("invalid parameter");
2183 return PM_PARSER_R_EINVAL;
2186 auto guard = db.CreateTransactionGuard();
2187 if (DoInsertPackageInfo(db, mfx) != 0)
2191 return PM_PARSER_R_OK;
2194 bool CheckPackageStorageStatus(pkgmgrinfo_filter_x* tmp_filter) {
2195 return ::CheckPackageStorageStatus(tmp_filter);
2198 int ExecuteWriteQueries(const tizen_base::Database& db,
2199 const std::vector<std::string>& queries,
2200 const std::vector<std::vector<std::optional<std::string>>>& args_list) {
2201 if (!static_cast<bool>(db) || queries.empty()) {
2202 _LOGE("Invalid parameter");
2203 return PMINFO_R_EINVAL;
2206 auto guard = db.CreateTransactionGuard();
2209 for (const auto& i : queries) {
2210 if (DoExecuteQuery(db, i, args_list[idx++]) != 0)
2218 int GetQueryResult(const tizen_base::Database& db,
2219 const std::string& query,
2220 const std::vector<std::optional<std::string>>& param,
2221 std::vector<std::vector<std::optional<std::string>>>& result) {
2222 if (!static_cast<bool>(db) || query.empty()) {
2223 LOGE("Invalid parameter");
2224 return PMINFO_R_EINVAL;
2227 auto q = tizen_base::Database::Sql(query);
2228 for (auto& p : param) {
2232 q.Bind(std::nullopt);
2235 auto r = db.Exec(q);
2237 LOGE("db.Exec() failed : %s", static_cast<const char*>(r));
2238 return PMINFO_R_ERROR;
2241 int col_cnt = r.GetColumnCount();
2242 for (const auto& row : r) {
2243 std::vector<std::optional<std::string>> rec;
2244 for (int i = 0; i < col_cnt; i++)
2245 rec.push_back(row.GetString(i));
2247 result.push_back(std::move(rec));
2253 int GetPkgInfo(const tizen_base::Database& db,
2254 pkgmgrinfo_pkginfo_filter_h filter, uid_t uid,
2255 const std::string& locale,
2256 std::map<std::string, std::shared_ptr<package_x>>& pkginfo_list) {
2257 if (!static_cast<bool>(db) || filter == nullptr) {
2258 LOGE("Invalid argument");
2259 return PMINFO_R_EINVAL;
2262 int ret = DoGetPkgInfo(db, uid, locale, (pkgmgrinfo_filter_x*)filter,
2263 PMINFO_PKGINFO_GET_ALL, pkginfo_list);
2267 int GetDependsOn(const tizen_base::Database& db, const std::string& pkgid,
2268 std::vector<dependency_x*>& dep_list) {
2269 if (!static_cast<bool>(db) || pkgid.empty()) {
2270 LOGE("Invalid parameter");
2271 return PMINFO_R_EINVAL;
2274 std::queue<std::string> queue;
2275 std::set<std::string> dup_checker;
2278 while (!queue.empty()) {
2279 const auto& item = queue.front();
2280 int ret = DoGetDependsOn(db, item, queue, dup_checker, dep_list);
2282 if (ret != PMINFO_R_OK) {
2283 LOGE("failed to get pkgs depends on %s", pkgid.c_str());
2284 for (auto i : dep_list)
2285 __free_depends_on(i);
2286 return PMINFO_R_ERROR;
2293 } // namespace pkgmgr_server::internal