2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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.
17 #include "manager/pkginfo_manager.h"
19 #include <sys/types.h>
30 #include "pkgmgr_parser.h"
31 #include "pkgmgrinfo_private.h"
33 #include "client/pkginfo_client.hh"
34 #include "common/database/abstract_db_handler.hh"
35 #include "common/database/pkg_set_db_handler.hh"
36 #include "common/parcel/appinfo_parcelable.hh"
37 #include "common/parcel/certinfo_parcelable.hh"
38 #include "common/parcel/command_parcelable.hh"
39 #include "common/parcel/depinfo_parcelable.hh"
40 #include "common/parcel/filter_parcelable.hh"
41 #include "common/parcel/pkginfo_parcelable.hh"
42 #include "common/parcel/query_parcelable.hh"
43 #include "common/parcel/result_parcelable.hh"
50 #define LOG_TAG "PKGMGR_INFO"
55 #define EXPORT_API __attribute__((visibility("default")))
57 namespace pcp = pkgmgr_common::parcel;
58 namespace pcd = pkgmgr_common::database;
60 extern "C" EXPORT_API int _pkginfo_get_packages(uid_t uid,
61 pkgmgrinfo_filter_x* filter, int flag, GHashTable* packages) {
62 std::shared_ptr<pcp::AbstractParcelable> parcelable(
63 new pcp::FilterParcelable(uid,
64 static_cast<pkgmgrinfo_filter_x*>(filter), flag, false));
66 pkgmgr_client::PkgInfoClient client(parcelable, uid,
67 pkgmgr_common::ReqType::GET_PKG_INFO);
68 if (!client.SendRequest())
69 return PMINFO_R_ERROR;
71 auto ptr = client.GetResultParcel();
73 LOG(ERROR) << "Fail to get return parcelable";
74 return PMINFO_R_ERROR;
77 if (ptr->GetRequestResult() != PMINFO_R_OK) {
78 LOG(ERROR) << "Request fail";
79 return ptr->GetRequestResult();
82 if (ptr->GetType() != pcp::ParcelableType::PkgInfo) {
83 LOG(ERROR) << "Invalid parcelable type";
84 return PMINFO_R_ERROR;
87 std::shared_ptr<pcp::PkgInfoParcelable> return_parcel(
88 std::static_pointer_cast<pcp::PkgInfoParcelable>(
91 auto result_list = return_parcel->ExtractPkgInfo();
92 // TODO: check noentry error has returned if size of result_list is 0
93 for (auto &pkginfo : result_list)
94 g_hash_table_insert(packages, (gpointer)pkginfo->package,
100 extern "C" EXPORT_API int _pkginfo_get_depends_on(uid_t uid,
101 const char* pkgid, GList** dependencies) {
102 std::shared_ptr<pcp::AbstractParcelable> parcelable(
103 new pcp::DepInfoParcelable(std::string(pkgid)));
105 pkgmgr_client::PkgInfoClient client(parcelable, uid,
106 pkgmgr_common::ReqType::GET_PKG_DEP_INFO);
107 if (!client.SendRequest())
108 return PMINFO_R_ERROR;
110 auto ptr = client.GetResultParcel();
111 if (ptr == nullptr) {
112 LOG(ERROR) << "Fail to get return parcelable";
113 return PMINFO_R_ERROR;
116 if (ptr->GetRequestResult() != PMINFO_R_OK) {
117 LOG(ERROR) << "Request fail";
118 return ptr->GetRequestResult();
121 if (ptr->GetType() != pcp::ParcelableType::DepInfo) {
122 LOG(ERROR) << "Invalid parcelable type";
123 return PMINFO_R_ERROR;
126 std::shared_ptr<pcp::DepInfoParcelable> return_parcel(
127 std::static_pointer_cast<pcp::DepInfoParcelable>(ptr));
129 auto dependency_list = return_parcel->ExtractDependencyInfo();
130 for (auto &dependency : dependency_list)
131 *dependencies = g_list_prepend(*dependencies, dependency);
135 // TODO: Need to add target db uid to identify which database to be searched
136 extern "C" EXPORT_API int _appinfo_get_applications(uid_t db_uid, uid_t uid,
137 pkgmgrinfo_filter_x* filter, int flag, GHashTable* packages) {
138 std::shared_ptr<pcp::AbstractParcelable> parcelable(
139 new pcp::FilterParcelable(uid,
140 static_cast<pkgmgrinfo_filter_x*>(filter), flag, false));
142 pkgmgr_client::PkgInfoClient client(
143 parcelable, uid, pkgmgr_common::ReqType::GET_APP_INFO);
144 if (!client.SendRequest())
145 return PMINFO_R_ERROR;
147 auto ptr = client.GetResultParcel();
148 if (ptr == nullptr) {
149 LOG(ERROR) << "Fail to get return parcelable";
150 return PMINFO_R_ERROR;
153 int ret = ptr->GetRequestResult();
154 if (ret != PMINFO_R_OK) {
155 if (ret == PMINFO_R_ENOENT)
156 LOG(DEBUG) << "No such application";
158 LOG(ERROR) << "Request fail";
162 if (ptr->GetType() != pcp::ParcelableType::AppInfo) {
163 LOG(ERROR) << "Invalid parcelable type";
164 return PMINFO_R_ERROR;
167 std::shared_ptr<pcp::AppInfoParcelable> return_parcel(
168 std::static_pointer_cast<pcp::AppInfoParcelable>(ptr));
170 std::vector<application_x*> result_list = return_parcel->ExtractAppInfo();
171 for (application_x* app : result_list)
172 g_hash_table_insert(packages, (gpointer)app->appid,
178 extern "C" EXPORT_API char* _appinfo_get_localed_label(
179 const char* appid, const char* locale, uid_t uid) {
180 char* query = nullptr;
181 query = sqlite3_mprintf(
182 "SELECT COALESCE((SELECT app_label FROM package_app_localized_info "
183 "WHERE app_id=%Q AND app_locale=%Q),"
184 "(SELECT app_label FROM package_app_localized_info WHERE "
185 "app_id=%Q AND app_locale='No Locale'))",
186 appid, locale, appid);
187 if (query == nullptr) {
188 LOG(ERROR) << "Out of memory";
192 std::shared_ptr<pcp::AbstractParcelable> parcelable(
193 new pcp::QueryParcelable(uid, std::string(query),
194 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
195 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
198 pkgmgr_client::PkgInfoClient client(parcelable, uid,
199 pkgmgr_common::ReqType::QUERY);
200 if (!client.SendRequest())
202 auto ptr = client.GetResultParcel();
203 if (ptr == nullptr) {
204 LOG(ERROR) << "Fail to get return parcelable";
208 if (ptr->GetRequestResult() != PMINFO_R_OK) {
209 LOG(ERROR) << "Request fail";
213 if (ptr->GetType() != pcp::ParcelableType::Result) {
214 LOG(ERROR) << "Invalid parcelable type";
218 std::shared_ptr<pcp::ResultParcelable> return_parcel(
219 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
221 // result_list is vector of string vector
222 char* label = nullptr;
223 auto result_list = return_parcel->GetResult();
224 for (auto result : result_list) {
225 // result is string vector
226 // it only has one string or not.
227 if (result.front().empty() || result.front().length() == 0)
229 label = strdup(result.front().c_str());
230 if (label == nullptr) {
231 LOG(ERROR) << "Out of memory";
240 extern "C" EXPORT_API int _appinfo_get_datacontrol_info(
241 const char* providerid, const char* type, uid_t uid,
242 char** appid, char** access) {
243 char* query = nullptr;
244 query = sqlite3_mprintf("SELECT app_id, access FROM "
245 "package_app_data_control WHERE "
246 "providerid=%Q AND type=%Q",
248 if (query == nullptr) {
249 LOG(ERROR) << "Out of memory";
250 return PMINFO_R_ERROR;
253 std::shared_ptr<pcp::AbstractParcelable> parcelable(
254 new pcp::QueryParcelable(uid, std::string(query),
255 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
256 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
259 pkgmgr_client::PkgInfoClient client(parcelable, uid,
260 pkgmgr_common::ReqType::QUERY);
261 if (!client.SendRequest())
262 return PMINFO_R_ERROR;
264 auto ptr = client.GetResultParcel();
265 if (ptr == nullptr) {
266 LOG(ERROR) << "Fail to get return parcelable";
267 return PMINFO_R_ERROR;
270 if (ptr->GetRequestResult() != PMINFO_R_OK) {
271 LOG(ERROR) << "Request fail";
272 return ptr->GetRequestResult();
275 if (ptr->GetType() != pcp::ParcelableType::Result) {
276 LOG(ERROR) << "Invalid parcelable type";
277 return PMINFO_R_ERROR;
280 std::shared_ptr<pcp::ResultParcelable> return_parcel(
281 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
283 // result_list is vector of string vector
284 auto result_list = return_parcel->GetResult();
285 if (result_list.size() == 0)
286 return PMINFO_R_ENOENT;
287 for (auto result : result_list) {
288 if (result.size() != 2)
289 return PMINFO_R_ERROR;
290 if (result.front().empty() || result.front().size() == 0 ||
291 result.back().empty() || result.back().size() == 0)
292 return PMINFO_R_ERROR;
293 *appid = strdup(result.front().c_str());
294 *access = strdup(result.back().c_str());
295 if (*appid == nullptr || *access == nullptr) {
296 LOG(ERROR) << "Out of memory";
297 return PMINFO_R_ERROR;
304 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
305 const char* providerid, uid_t uid, char** appid) {
306 char* query = nullptr;
308 query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
309 "WHERE providerid=%Q",
311 if (query == nullptr) {
312 LOGE("Out of memory");
313 return PMINFO_R_ERROR;
315 std::shared_ptr<pcp::AbstractParcelable> parcelable(
316 new pcp::QueryParcelable(uid, std::string(query),
317 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
318 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
321 pkgmgr_client::PkgInfoClient client(parcelable, uid,
322 pkgmgr_common::ReqType::QUERY);
323 if (!client.SendRequest())
324 return PMINFO_R_ERROR;
326 auto ptr = client.GetResultParcel();
327 if (ptr == nullptr) {
328 LOG(ERROR) << "Fail to get return parcelable";
329 return PMINFO_R_ERROR;
332 if (ptr->GetRequestResult() != PMINFO_R_OK) {
333 LOG(ERROR) << "Request fail";
334 return ptr->GetRequestResult();
337 if (ptr->GetType() != pcp::ParcelableType::Result) {
338 LOG(ERROR) << "Invalid parcelable type";
339 return PMINFO_R_ERROR;
342 std::shared_ptr<pcp::ResultParcelable> return_parcel(
343 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
345 // result_list is vector of string vector
346 auto result_list = return_parcel->GetResult();
347 if (result_list.size() == 0)
348 return PMINFO_R_ENOENT;
349 for (auto result : result_list) {
350 if (result.size() != 1)
351 return PMINFO_R_ERROR;
352 if (result.front().empty() || result.front().size() == 0)
353 return PMINFO_R_ERROR;
354 *appid = strdup(result.front().c_str());
355 if (*appid == nullptr) {
356 LOG(ERROR) << "Out of memory";
357 return PMINFO_R_ERROR;
364 extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
365 const char* providerid, const char* type, uid_t uid,
366 char** appid, char** trusted) {
367 char* query = nullptr;
368 query = sqlite3_mprintf(
369 "SELECT app_id, trusted FROM package_app_data_control "
370 "WHERE providerid=%Q AND type=%Q",
372 if (query == nullptr) {
373 LOGE("Out of memory");
374 return PMINFO_R_ERROR;
377 std::shared_ptr<pcp::AbstractParcelable> parcelable(
378 new pcp::QueryParcelable(uid, std::string(query),
379 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
380 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
383 pkgmgr_client::PkgInfoClient client(parcelable, uid,
384 pkgmgr_common::ReqType::QUERY);
385 if (!client.SendRequest())
386 return PMINFO_R_ERROR;
388 auto ptr = client.GetResultParcel();
389 if (ptr == nullptr) {
390 LOG(ERROR) << "Fail to get return parcelable";
391 return PMINFO_R_ERROR;
394 if (ptr->GetRequestResult() != PMINFO_R_OK) {
395 LOG(ERROR) << "Request fail";
396 return ptr->GetRequestResult();
399 if (ptr->GetType() != pcp::ParcelableType::Result) {
400 LOG(ERROR) << "Invalid parcelable type";
401 return PMINFO_R_ERROR;
404 std::shared_ptr<pcp::ResultParcelable> return_parcel(
405 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
407 // result_list is vector of string vector
408 auto result_list = return_parcel->GetResult();
409 if (result_list.size() == 0)
410 return PMINFO_R_ENOENT;
411 for (auto result : result_list) {
412 if (result.size() != 2)
413 return PMINFO_R_ERROR;
414 if (result.front().empty() || result.front().size() == 0 ||
415 result.back().empty() || result.back().size() == 0)
416 return PMINFO_R_ERROR;
417 *appid = strdup(result.front().c_str());
418 *trusted = strdup(result.back().c_str());
419 if (*appid == nullptr || *trusted == nullptr) {
420 LOG(ERROR) << "Out of memory";
421 return PMINFO_R_ERROR;
428 extern "C" EXPORT_API int _appinfo_get_datacontrol_privileges(
429 const char* providerid, const char* type, uid_t uid, GList** privileges) {
430 char* query = nullptr;
431 query = sqlite3_mprintf(
432 "SELECT privilege FROM package_app_data_control_privilege "
433 "WHERE providerid=%Q AND type=%Q",
435 if (query == nullptr) {
436 LOGE("Out of memory");
437 return PMINFO_R_ERROR;
440 std::shared_ptr<pcp::AbstractParcelable> parcelable(
441 new pcp::QueryParcelable(uid, std::string(query),
442 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
443 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
446 pkgmgr_client::PkgInfoClient client(parcelable, uid,
447 pkgmgr_common::ReqType::QUERY);
448 if (!client.SendRequest())
449 return PMINFO_R_ERROR;
451 auto ptr = client.GetResultParcel();
452 if (ptr == nullptr) {
453 LOG(ERROR) << "Fail to get return parcelable";
454 return PMINFO_R_ERROR;
457 if (ptr->GetRequestResult() != PMINFO_R_OK) {
458 LOG(ERROR) << "Request fail";
459 return ptr->GetRequestResult();
462 if (ptr->GetType() != pcp::ParcelableType::Result) {
463 LOG(ERROR) << "Invalid parcelable type";
464 return PMINFO_R_ERROR;
467 std::shared_ptr<pcp::ResultParcelable> return_parcel(
468 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
470 // result_list is vector of string vector
471 auto result_list = return_parcel->GetResult();
472 if (result_list.size() == 0)
473 return PMINFO_R_ENOENT;
475 for (auto result : result_list) {
476 if (result.size() != 1)
477 return PMINFO_R_ERROR;
478 if (result.front().empty() || result.front().size() == 0)
479 return PMINFO_R_ERROR;
480 char* privilege = strdup(result.front().c_str());
481 if (privilege == nullptr) {
482 LOG(ERROR) << "Out of memory";
483 return PMINFO_R_ERROR;
485 *privileges = g_list_append(*privileges, privilege);
491 extern "C" EXPORT_API int _appinfo_get_appcontrol_privileges(
492 const char* appid, const char* operation, uid_t uid, GList** privileges) {
493 char* query = nullptr;
494 query = sqlite3_mprintf(
495 "SELECT app_control, privilege FROM package_app_app_control_privilege "
496 "WHERE app_id=%Q", appid);
497 if (query == nullptr) {
498 LOG(ERROR) << "Out of memory";
499 return PMINFO_R_ERROR;
502 std::shared_ptr<pcp::AbstractParcelable> parcelable(
503 new pcp::QueryParcelable(uid, std::string(query),
504 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
505 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
508 pkgmgr_client::PkgInfoClient client(parcelable, uid,
509 pkgmgr_common::ReqType::QUERY);
510 if (!client.SendRequest())
511 return PMINFO_R_ERROR;
513 auto ptr = client.GetResultParcel();
514 if (ptr == nullptr) {
515 LOG(ERROR) << "Fail to get return parcelable";
516 return PMINFO_R_ERROR;
519 if (ptr->GetRequestResult() != PMINFO_R_OK) {
520 LOG(ERROR) << "Request fail";
521 return ptr->GetRequestResult();
524 if (ptr->GetType() != pcp::ParcelableType::Result) {
525 LOG(ERROR) << "Invalid parcelable type";
526 return PMINFO_R_ERROR;
529 std::shared_ptr<pcp::ResultParcelable> return_parcel(
530 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
532 // result_list is vector of string vector
533 auto result_list = return_parcel->GetResult();
534 if (result_list.size() == 0)
535 return PMINFO_R_ENOENT;
537 for (auto result : result_list) {
538 if (result.size() != 2)
539 return PMINFO_R_ERROR;
540 if (result.front().empty() || result.front().size() == 0 ||
541 result.back().empty() || result.back().size() == 0)
542 return PMINFO_R_ERROR;
543 std::string app_control = result.front();
544 std::stringstream ss(app_control);
546 while (std::getline(ss, token, '|')) {
547 if (token.compare(std::string(operation))) {
548 char* privilege = strdup(result.back().c_str());
549 if (privilege == nullptr) {
550 LOG(ERROR) << "Out of memory";
551 return PMINFO_R_ERROR;
553 *privileges = g_list_append(*privileges, privilege);
560 extern "C" EXPORT_API int _plugininfo_get_appids(
561 const char* pkgid, const char* plugin_type,
562 const char* plugin_name, GList** list) {
563 if (!pkgid || !plugin_type || !plugin_name || !list) {
564 LOG(ERROR) << "Invalid parameter";
565 return PMINFO_R_EINVAL;
568 char* query = nullptr;
569 query = sqlite3_mprintf(
571 "package_plugin_info WHERE pkgid=%Q AND "
572 "plugin_type=%Q AND plugin_name=%Q",
573 pkgid, plugin_type, plugin_name);
574 if (query == nullptr) {
575 LOG(ERROR) << "Out of memory";
576 return PMINFO_R_ERROR;
579 std::shared_ptr<pcp::AbstractParcelable> parcelable(
580 new pcp::QueryParcelable(_getuid(), std::string(query),
581 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
582 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
585 pkgmgr_client::PkgInfoClient client(parcelable, _getuid(),
586 pkgmgr_common::ReqType::QUERY);
587 if (!client.SendRequest())
588 return PMINFO_R_ERROR;
590 auto ptr = client.GetResultParcel();
591 if (ptr == nullptr) {
592 LOG(ERROR) << "Fail to get return parcelable";
593 return PMINFO_R_ERROR;
596 if (ptr->GetRequestResult() != PMINFO_R_OK) {
597 LOG(ERROR) << "Request fail";
598 return ptr->GetRequestResult();
601 if (ptr->GetType() != pcp::ParcelableType::Result) {
602 LOG(ERROR) << "Invalid parcelable type";
603 return PMINFO_R_ERROR;
606 std::shared_ptr<pcp::ResultParcelable> return_parcel(
607 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
609 if (return_parcel->GetCol() != 1) {
610 LOG(ERROR) << "Invalid result";
611 return PMINFO_R_ERROR;
613 // result_list is vector of string vector
614 auto &result_list = return_parcel->GetResult();
615 if (result_list.size() == 0)
616 return PMINFO_R_ENOENT;
618 for (auto result : result_list) {
619 if (result.size() != 1) {
620 LOG(ERROR) << "Invalid result";
621 g_list_free_full(*list, free);
622 return PMINFO_R_ERROR;
624 *list = g_list_append(*list, strdup(result[0].c_str()));
630 static int __convert_update_type(const char* type,
631 pkgmgrinfo_updateinfo_update_type* convert_type) {
632 if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_NONE,
633 strlen(PMINFO_UPDATEINFO_TYPE_NONE)) == 0)
634 *convert_type = PMINFO_UPDATEINFO_NONE;
635 else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_FORCE,
636 strlen(PMINFO_UPDATEINFO_TYPE_FORCE)) == 0)
637 *convert_type = PMINFO_UPDATEINFO_FORCE;
638 else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_OPTIONAL,
639 strlen(PMINFO_UPDATEINFO_TYPE_OPTIONAL)) == 0)
640 *convert_type = PMINFO_UPDATEINFO_OPTIONAL;
646 static void __free_update_info(gpointer data) {
647 updateinfo_x* update_info = reinterpret_cast<updateinfo_x*>(data);
648 if (update_info == nullptr)
651 if (update_info->pkgid)
652 free(reinterpret_cast<void*>(update_info->pkgid));
653 if (update_info->version)
654 free(reinterpret_cast<void*>(update_info->version));
655 free(reinterpret_cast<void*>(update_info));
658 extern "C" EXPORT_API int _get_pkg_updateinfo(const char* pkgid,
659 GSList** update_info_list, uid_t uid) {
660 char* query = nullptr;
663 if (pkgid == nullptr)
664 query = sqlite3_mprintf(
665 "SELECT package, update_version, update_type "
666 "FROM package_update_info");
668 query = sqlite3_mprintf(
669 "SELECT package, update_version, update_type "
670 "FROM package_update_info WHERE package=%Q",
672 if (query == nullptr) {
673 LOG(ERROR) << "Out of memory";
674 return PMINFO_R_ERROR;
677 std::shared_ptr<pcp::AbstractParcelable> parcelable(
678 new pcp::QueryParcelable(uid, std::string(query),
679 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
680 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
683 pkgmgr_client::PkgInfoClient client(parcelable, uid,
684 pkgmgr_common::ReqType::QUERY);
685 if (!client.SendRequest())
686 return PMINFO_R_ERROR;
688 auto ptr = client.GetResultParcel();
689 if (ptr == nullptr) {
690 LOG(ERROR) << "Fail to get return parcelable";
691 return PMINFO_R_ERROR;
694 if (ptr->GetRequestResult() != PMINFO_R_OK) {
695 LOG(ERROR) << "Request fail";
696 return ptr->GetRequestResult();
699 if (ptr->GetType() != pcp::ParcelableType::Result) {
700 LOG(ERROR) << "Invalid parcelable type";
701 return PMINFO_R_ERROR;
704 std::shared_ptr<pcp::ResultParcelable> return_parcel(
705 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
707 if (return_parcel->GetCol() != 3) {
708 LOG(ERROR) << "Invalid result";
709 return PMINFO_R_ERROR;
712 auto result_list = return_parcel->GetResult();
713 if (result_list.size() == 0)
714 return PMINFO_R_ENOENT;
716 for (auto result : result_list) {
717 if (result.size() != 3) {
718 LOG(ERROR) << "Invalid result";
719 g_slist_free_full(*update_info_list, __free_update_info);
720 return PMINFO_R_ERROR;
722 updateinfo_x* update_info = reinterpret_cast<updateinfo_x*>(
723 calloc(1, sizeof(updateinfo_x)));
724 if (update_info == nullptr) {
725 LOG(ERROR) << "Out of memory";
726 return PMINFO_R_ERROR;
728 update_info->pkgid = strdup(result[0].c_str());
729 update_info->version = strdup(result[1].c_str());
730 pkgmgrinfo_updateinfo_update_type convert_type;
731 ret = __convert_update_type(result[2].c_str(), &convert_type);
733 __free_update_info(update_info);
734 g_slist_free_full(*update_info_list, __free_update_info);
735 return PMINFO_R_ERROR;
737 update_info->type = static_cast<int>(convert_type);
738 *update_info_list = g_slist_prepend(*update_info_list,
745 extern "C" EXPORT_API int _pkginfo_set_usr_installed_storage(const char* pkgid,
746 INSTALL_LOCATION location, const char* external_pkg_path, uid_t uid) {
747 char* query = nullptr;
748 const char* location_str;
749 std::vector<std::string> queries;
751 if (location == INSTALL_INTERNAL)
752 location_str = "installed_internal";
753 else if (location == INSTALL_EXTERNAL)
754 location_str = "installed_external";
756 location_str = "installed_extended";
757 /* pkgcakge_info table */
758 query = sqlite3_mprintf(
759 "UPDATE package_info SET installed_storage=%Q, external_path=%Q "
761 location_str, external_pkg_path, pkgid);
762 queries.emplace_back(query);
765 /* package_app_info table */
766 query = sqlite3_mprintf(
767 "UPDATE package_app_info SET app_installed_storage=%Q, "
768 "app_external_path=%Q WGERE package=%Q",
769 location_str, external_pkg_path, pkgid);
770 queries.emplace_back(query);
773 std::shared_ptr<pcp::AbstractParcelable> parcelable(
774 new pcp::QueryParcelable(uid, queries,
775 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
776 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
778 pkgmgr_client::PkgInfoClient client(parcelable, uid,
779 pkgmgr_common::ReqType::QUERY);
780 if (!client.SendRequest())
781 return PMINFO_R_ERROR;
783 auto ptr = client.GetResultParcel();
784 if (ptr == nullptr) {
785 LOG(ERROR) << "Fail to get return parcelable";
786 return PMINFO_R_ERROR;
789 if (ptr->GetRequestResult() != PMINFO_R_OK) {
790 LOG(ERROR) << "Request fail";
791 return ptr->GetRequestResult();
794 if (ptr->GetType() != pcp::ParcelableType::Result) {
795 LOG(ERROR) << "Invalid parcelable type";
796 return PMINFO_R_ERROR;
802 extern "C" EXPORT_API int _certinfo_compare_pkg_certinfo(const char* l_pkgid,
803 const char* r_pkgid, pkgmgrinfo_cert_compare_result_type_e* result) {
804 char* query = sqlite3_mprintf("SELECT package, "
805 "COALESCE(author_signer_cert, -1) FROM package_cert_info WHERE "
806 "package IN (%Q, %Q)",
808 if (query == nullptr) {
809 LOG(ERROR) << "Out of memory";
810 return PMINFO_R_ERROR;
812 std::vector<std::string> queries;
813 queries.emplace_back(query);
816 std::shared_ptr<pcp::AbstractParcelable> parcelable(
817 new pcp::QueryParcelable(0, queries,
818 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_CERTDB,
819 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
820 pkgmgr_client::PkgInfoClient client(parcelable, 0,
821 pkgmgr_common::ReqType::QUERY);
822 if (!client.SendRequest())
823 return PMINFO_R_ERROR;
825 auto ptr = client.GetResultParcel();
826 if (ptr == nullptr) {
827 LOG(ERROR) << "Fail to get return parcelable";
828 return PMINFO_R_ERROR;
831 if (ptr->GetRequestResult() != PMINFO_R_OK) {
832 LOG(ERROR) << "Request fail";
833 return ptr->GetRequestResult();
836 if (ptr->GetType() != pcp::ParcelableType::Result) {
837 LOG(ERROR) << "Invalid parcelable type";
838 return PMINFO_R_ERROR;
841 std::shared_ptr<pcp::ResultParcelable> return_parcel(
842 std::static_pointer_cast<pcp::ResultParcelable>(
845 auto certinfo_list = return_parcel->GetResult();
846 if (certinfo_list.size() != 2)
847 return PMINFO_R_ERROR;
849 std::map<std::string, std::string> result_map;
850 for (auto &certinfo : certinfo_list)
851 result_map.insert(make_pair(certinfo.front(), certinfo.back()));
853 if (result_map.find(std::string(l_pkgid))->second == "-1" &&
854 result_map.find(std::string(r_pkgid))->second == "-1")
855 *result = PMINFO_CERT_COMPARE_BOTH_NO_CERT;
856 else if (result_map.find(std::string(l_pkgid))->second == "-1")
857 *result = PMINFO_CERT_COMPARE_LHS_NO_CERT;
858 else if (result_map.find(std::string(r_pkgid))->second == "-1")
859 *result = PMINFO_CERT_COMPARE_RHS_NO_CERT;
860 else if (result_map.find(std::string(l_pkgid))->second ==
861 result_map.find(std::string(r_pkgid))->second)
862 *result = PMINFO_CERT_COMPARE_MATCH;
864 *result = PMINFO_CERT_COMPARE_MISMATCH;
869 extern "C" EXPORT_API int _certinfo_compare_app_certinfo(uid_t uid,
870 const char* l_appid, const char* r_appid,
871 pkgmgrinfo_cert_compare_result_type_e* result) {
872 char* query = sqlite3_mprintf("SELECT app_id, package FROM "
873 "package_app_info WHERE app_id IN (%Q, %Q)",
875 if (query == nullptr) {
876 LOG(ERROR) << "Out of memory";
877 return PMINFO_R_ERROR;
879 std::vector<std::string> queries;
880 queries.emplace_back(query);
883 std::shared_ptr<pcp::AbstractParcelable> parcelable(
884 new pcp::QueryParcelable(uid, queries,
885 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
886 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
887 pkgmgr_client::PkgInfoClient client(parcelable, uid,
888 pkgmgr_common::ReqType::QUERY);
889 if (!client.SendRequest())
890 return PMINFO_R_ERROR;
892 auto ptr = client.GetResultParcel();
893 if (ptr == nullptr) {
894 LOG(ERROR) << "Fail to get return parcelable";
895 return PMINFO_R_ERROR;
898 if (ptr->GetRequestResult() != PMINFO_R_OK) {
899 LOG(ERROR) << "Request fail";
900 return ptr->GetRequestResult();
903 if (ptr->GetType() != pcp::ParcelableType::Result) {
904 LOG(ERROR) << "Invalid parcelable type";
905 return PMINFO_R_ERROR;
908 std::shared_ptr<pcp::ResultParcelable> return_parcel(
909 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
911 auto pkgid_list = return_parcel->GetResult();
912 std::map<std::string, std::string> result_map;
913 for (auto &pkgid : pkgid_list)
914 result_map.insert(make_pair(pkgid.front(), pkgid.back()));
916 if (result_map.find(std::string(l_appid)) == result_map.end()) {
917 LOG(ERROR) << "Cannot find pkgid of app " << l_appid
918 << " for uid " << uid;
919 return PMINFO_R_ENOENT;
920 } else if (result_map.find(std::string(r_appid)) == result_map.end()) {
921 LOG(ERROR) << "Cannot find pkgid of app " << r_appid
922 << " for uid " << uid;
923 return PMINFO_R_ENOENT;
926 const char* l_pkgid = result_map.find(std::string(l_appid))->second.c_str();
927 const char* r_pkgid = result_map.find(std::string(r_appid))->second.c_str();
929 return _certinfo_compare_pkg_certinfo(l_pkgid, r_pkgid, result);
932 extern "C" EXPORT_API int _parser_execute_write_query(
933 const char* query, uid_t uid) {
934 std::shared_ptr<pcp::AbstractParcelable> parcelable(
935 new pcp::QueryParcelable(uid, query,
936 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
937 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
939 pkgmgr_client::PkgInfoClient client(parcelable, uid,
940 pkgmgr_common::ReqType::QUERY);
941 if (!client.SendRequest())
944 auto ptr = client.GetResultParcel();
945 if (ptr == nullptr) {
946 LOG(ERROR) << "Fail to get return parcelable";
950 if (ptr->GetRequestResult() != PMINFO_R_OK) {
951 LOG(ERROR) << "Request fail";
955 if (ptr->GetType() != pcp::ParcelableType::Result) {
956 LOG(ERROR) << "Invalid parcelable type";
963 extern "C" EXPORT_API int _parser_execute_write_queries(
964 const char** queries, int len, uid_t uid) {
965 std::vector<std::string> query_vt;
966 for (int i = 0; i < len; ++i)
967 query_vt.emplace_back(queries[i]);
969 std::shared_ptr<pcp::AbstractParcelable> parcelable(
970 new pcp::QueryParcelable(uid, query_vt,
971 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
972 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
974 pkgmgr_client::PkgInfoClient client(parcelable, uid,
975 pkgmgr_common::ReqType::QUERY);
976 if (!client.SendRequest())
979 auto ptr = client.GetResultParcel();
980 if (ptr == nullptr) {
981 LOG(ERROR) << "Fail to get return parcelable";
985 if (ptr->GetRequestResult() != PMINFO_R_OK) {
986 LOG(ERROR) << "Request fail";
990 if (ptr->GetType() != pcp::ParcelableType::Result) {
991 LOG(ERROR) << "Invalid parcelable type";
998 extern "C" EXPORT_API int _parser_insert_manifest_info(
999 manifest_x* mfx, uid_t uid) {
1001 std::make_shared<pcp::PkgInfoParcelable>(uid,
1002 std::vector<package_x*>{mfx}, WriteType::Insert, false);
1004 pkgmgr_client::PkgInfoClient client(parcelable, uid,
1005 pkgmgr_common::ReqType::SET_PKG_INFO);
1006 if (!client.SendRequest())
1009 auto ptr = client.GetResultParcel();
1010 if (ptr == nullptr) {
1011 LOG(ERROR) << "Fail to get return parcelable";
1015 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1016 LOG(ERROR) << "Request fail";
1020 if (ptr->GetType() != pcp::ParcelableType::Result) {
1021 LOG(ERROR) << "Invalid parcelable type";
1028 extern "C" EXPORT_API int _parser_update_manifest_info(
1029 manifest_x* mfx, uid_t uid) {
1031 std::make_shared<pcp::PkgInfoParcelable>(uid,
1032 std::vector<package_x*>{mfx}, WriteType::Update, false);
1034 pkgmgr_client::PkgInfoClient client(parcelable, uid,
1035 pkgmgr_common::ReqType::SET_PKG_INFO);
1036 if (!client.SendRequest())
1039 auto ptr = client.GetResultParcel();
1040 if (ptr == nullptr) {
1041 LOG(ERROR) << "Fail to get return parcelable";
1045 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1046 LOG(ERROR) << "Request fail";
1050 if (ptr->GetType() != pcp::ParcelableType::Result) {
1051 LOG(ERROR) << "Invalid parcelable type";
1058 extern "C" EXPORT_API int _parser_delete_manifest_info(
1059 manifest_x* mfx, uid_t uid) {
1061 std::make_shared<pcp::PkgInfoParcelable>(uid,
1062 std::vector<package_x*>{mfx}, WriteType::Delete, false);
1064 pkgmgr_client::PkgInfoClient client(parcelable, uid,
1065 pkgmgr_common::ReqType::SET_PKG_INFO);
1066 if (!client.SendRequest())
1069 auto ptr = client.GetResultParcel();
1070 if (ptr == nullptr) {
1071 LOG(ERROR) << "Fail to get return parcelable";
1075 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1076 LOG(ERROR) << "Request fail";
1080 if (ptr->GetType() != pcp::ParcelableType::Result) {
1081 LOG(ERROR) << "Invalid parcelable type";
1088 extern "C" EXPORT_API int _pkginfo_insert_certinfo(const char* pkgid,
1089 pkgmgr_certinfo_x* cert, uid_t uid) {
1090 std::shared_ptr<pcp::AbstractParcelable> parcelable(
1091 new pcp::CertInfoParcelable(uid, cert, false));
1092 pkgmgr_client::PkgInfoClient client(parcelable, uid,
1093 pkgmgr_common::ReqType::SET_CERT_INFO);
1095 if (!client.SendRequest())
1096 return PMINFO_R_ERROR;
1098 auto ptr = client.GetResultParcel();
1099 if (ptr == nullptr) {
1100 LOG(ERROR) << "Fail to get return parcelable";
1101 return PMINFO_R_ERROR;
1104 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1105 LOG(ERROR) << "Request fail";
1106 return ptr->GetRequestResult();
1109 if (ptr->GetType() != pcp::ParcelableType::Result) {
1110 LOG(ERROR) << "Invalid parcelable type";
1111 return PMINFO_R_ERROR;
1117 extern "C" EXPORT_API int _pkginfo_get_certinfo(const char* pkgid,
1118 pkgmgr_certinfo_x* cert, uid_t uid) {
1119 std::shared_ptr<pcp::AbstractParcelable> parcelable(
1120 new pcp::CertInfoParcelable(uid,
1121 std::string(pkgid)));
1123 pkgmgr_client::PkgInfoClient client(parcelable, uid,
1124 pkgmgr_common::ReqType::GET_CERT_INFO);
1125 if (!client.SendRequest())
1126 return PMINFO_R_ERROR;
1128 auto ptr = client.GetResultParcel();
1129 if (ptr == nullptr) {
1130 LOG(ERROR) << "Fail to get return parcelable";
1131 return PMINFO_R_ERROR;
1134 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1135 LOG(ERROR) << "Request fail";
1136 return ptr->GetRequestResult();
1139 if (ptr->GetType() != pcp::ParcelableType::CertInfo) {
1140 LOG(ERROR) << "Invalid parcelable type";
1141 return PMINFO_R_ERROR;
1144 std::shared_ptr<pcp::CertInfoParcelable> return_parcel(
1145 std::static_pointer_cast<pcp::CertInfoParcelable>(ptr));
1147 pkgmgr_certinfo_x* certinfo = return_parcel->ExtractCertInfo();
1148 if (certinfo == nullptr)
1149 return PMINFO_R_ERROR;
1151 cert->for_all_users = certinfo->for_all_users;
1152 cert->pkgid = certinfo->pkgid;
1153 certinfo->pkgid = nullptr;
1154 cert->cert_value = certinfo->cert_value;
1155 certinfo->cert_value = nullptr;
1156 for (int i = 0; i < MAX_CERT_TYPE; i++) {
1157 cert->cert_info[i] = certinfo->cert_info[i];
1158 certinfo->cert_info[i] = nullptr;
1160 for (int i = 0; i < MAX_CERT_TYPE; i++)
1161 cert->cert_id[i] = certinfo->cert_id[i];
1168 extern "C" EXPORT_API int _pkginfo_delete_certinfo(const char* pkgid) {
1169 char* query = sqlite3_mprintf("UPDATE package_cert_info SET "
1170 "package_count = package_count - 1 WHERE package=%Q", pkgid);
1171 if (query == nullptr) {
1172 LOG(ERROR) << "Out of memory";
1173 return PMINFO_R_ERROR;
1176 std::vector<std::string> queries;
1177 queries.emplace_back(query);
1178 sqlite3_free(query);
1180 std::shared_ptr<pcp::AbstractParcelable> parcelable(
1181 new pcp::QueryParcelable(0, queries,
1182 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_CERTDB,
1183 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
1185 pkgmgr_client::PkgInfoClient client(parcelable, 0,
1186 pkgmgr_common::ReqType::QUERY);
1187 if (!client.SendRequest())
1188 return PMINFO_R_ERROR;
1190 auto ptr = client.GetResultParcel();
1191 if (ptr == nullptr) {
1192 LOG(ERROR) << "Fail to get return parcelable";
1193 return PMINFO_R_ERROR;
1196 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1197 LOG(ERROR) << "Request fail";
1198 return PMINFO_R_ERROR;
1201 if (ptr->GetType() != pcp::ParcelableType::Result) {
1202 LOG(ERROR) << "Invalid parcelable type";
1203 return PMINFO_R_ERROR;
1209 extern "C" EXPORT_API int _parser_clear_cache_memory_db(uid_t uid) {
1210 std::shared_ptr<pcp::AbstractParcelable> parcelable(
1211 new pcp::CommandParcelable(uid, CommandType::RemoveCache));
1213 pkgmgr_client::PkgInfoClient client(parcelable, uid,
1214 pkgmgr_common::ReqType::COMMAND);
1216 if (!client.SendRequest())
1217 return PMINFO_R_ERROR;
1219 auto ptr = client.GetResultParcel();
1220 if (ptr == nullptr) {
1221 LOG(ERROR) << "Fail to get return parcelable";
1222 return PMINFO_R_ERROR;
1225 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1226 LOG(ERROR) << "Request fail";
1227 return PMINFO_R_ERROR;
1230 if (ptr->GetType() != pcp::ParcelableType::Result) {
1231 LOG(ERROR) << "Invalid parcelable type";
1232 return PMINFO_R_ERROR;