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 if (ptr->GetRequestResult() == PMINFO_R_ERROR)
79 LOG(ERROR) << "Request fail";
80 return ptr->GetRequestResult();
83 if (ptr->GetType() != pcp::ParcelableType::PkgInfo) {
84 LOG(ERROR) << "Invalid parcelable type";
85 return PMINFO_R_ERROR;
88 std::shared_ptr<pcp::PkgInfoParcelable> return_parcel(
89 std::static_pointer_cast<pcp::PkgInfoParcelable>(
92 auto result_list = return_parcel->ExtractPkgInfo();
93 if (result_list.size() == 0) {
94 LOG(DEBUG) << "No packages meets given condition for user " << uid;
95 return PMINFO_R_ENOENT;
97 for (auto &pkginfo : result_list)
98 g_hash_table_insert(packages, (gpointer)pkginfo->package,
104 extern "C" EXPORT_API int _pkginfo_get_depends_on(uid_t uid,
105 const char* pkgid, GList** dependencies) {
106 std::shared_ptr<pcp::AbstractParcelable> parcelable(
107 new pcp::DepInfoParcelable(std::string(pkgid)));
109 pkgmgr_client::PkgInfoClient client(parcelable, uid,
110 pkgmgr_common::ReqType::GET_PKG_DEP_INFO);
111 if (!client.SendRequest())
112 return PMINFO_R_ERROR;
114 auto ptr = client.GetResultParcel();
115 if (ptr == nullptr) {
116 LOG(ERROR) << "Fail to get return parcelable";
117 return PMINFO_R_ERROR;
120 if (ptr->GetRequestResult() != PMINFO_R_OK) {
121 LOG(ERROR) << "Request fail";
122 return ptr->GetRequestResult();
125 if (ptr->GetType() != pcp::ParcelableType::DepInfo) {
126 LOG(ERROR) << "Invalid parcelable type";
127 return PMINFO_R_ERROR;
130 std::shared_ptr<pcp::DepInfoParcelable> return_parcel(
131 std::static_pointer_cast<pcp::DepInfoParcelable>(ptr));
133 auto dependency_list = return_parcel->ExtractDependencyInfo();
134 for (auto &dependency : dependency_list)
135 *dependencies = g_list_prepend(*dependencies, dependency);
139 extern "C" EXPORT_API int _appinfo_get_applications(uid_t uid,
140 pkgmgrinfo_filter_x* filter, int flag, GHashTable* packages) {
141 std::shared_ptr<pcp::AbstractParcelable> parcelable(
142 new pcp::FilterParcelable(uid,
143 static_cast<pkgmgrinfo_filter_x*>(filter), flag, false));
145 pkgmgr_client::PkgInfoClient client(
146 parcelable, uid, pkgmgr_common::ReqType::GET_APP_INFO);
147 if (!client.SendRequest())
148 return PMINFO_R_ERROR;
150 auto ptr = client.GetResultParcel();
151 if (ptr == nullptr) {
152 LOG(ERROR) << "Fail to get return parcelable";
153 return PMINFO_R_ERROR;
156 int ret = ptr->GetRequestResult();
157 if (ret != PMINFO_R_OK) {
158 if (ret == PMINFO_R_ENOENT)
159 LOG(DEBUG) << "No such application";
161 LOG(ERROR) << "Request fail";
165 if (ptr->GetType() != pcp::ParcelableType::AppInfo) {
166 LOG(ERROR) << "Invalid parcelable type";
167 return PMINFO_R_ERROR;
170 std::shared_ptr<pcp::AppInfoParcelable> return_parcel(
171 std::static_pointer_cast<pcp::AppInfoParcelable>(ptr));
173 std::vector<application_x*> result_list = return_parcel->ExtractAppInfo();
174 for (application_x* app : result_list)
175 g_hash_table_insert(packages, (gpointer)app->appid,
181 extern "C" EXPORT_API char* _appinfo_get_localed_label(
182 const char* appid, const char* locale, uid_t uid) {
183 char* query = nullptr;
184 query = sqlite3_mprintf(
185 "SELECT COALESCE((SELECT app_label FROM package_app_localized_info "
186 "WHERE app_id=%Q AND app_locale=%Q),"
187 "(SELECT app_label FROM package_app_localized_info WHERE "
188 "app_id=%Q AND app_locale='No Locale'))",
189 appid, locale, appid);
190 if (query == nullptr) {
191 LOG(ERROR) << "Out of memory";
195 std::shared_ptr<pcp::AbstractParcelable> parcelable(
196 new pcp::QueryParcelable(uid, std::string(query),
197 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
198 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
201 pkgmgr_client::PkgInfoClient client(parcelable, uid,
202 pkgmgr_common::ReqType::QUERY);
203 if (!client.SendRequest())
205 auto ptr = client.GetResultParcel();
206 if (ptr == nullptr) {
207 LOG(ERROR) << "Fail to get return parcelable";
211 if (ptr->GetRequestResult() != PMINFO_R_OK) {
212 LOG(ERROR) << "Request fail";
216 if (ptr->GetType() != pcp::ParcelableType::Result) {
217 LOG(ERROR) << "Invalid parcelable type";
221 std::shared_ptr<pcp::ResultParcelable> return_parcel(
222 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
224 // result_list is vector of string vector
225 char* label = nullptr;
226 auto result_list = return_parcel->GetResult();
227 for (auto result : result_list) {
228 // result is string vector
229 // it only has one string or not.
230 if (result.front().empty() || result.front().length() == 0)
232 label = strdup(result.front().c_str());
233 if (label == nullptr) {
234 LOG(ERROR) << "Out of memory";
243 extern "C" EXPORT_API int _appinfo_get_datacontrol_info(
244 const char* providerid, const char* type, uid_t uid,
245 char** appid, char** access) {
246 char* query = nullptr;
247 query = sqlite3_mprintf("SELECT app_id, access FROM "
248 "package_app_data_control WHERE "
249 "providerid=%Q AND type=%Q",
251 if (query == nullptr) {
252 LOG(ERROR) << "Out of memory";
253 return PMINFO_R_ERROR;
256 std::shared_ptr<pcp::AbstractParcelable> parcelable(
257 new pcp::QueryParcelable(uid, std::string(query),
258 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
259 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
262 pkgmgr_client::PkgInfoClient client(parcelable, uid,
263 pkgmgr_common::ReqType::QUERY);
264 if (!client.SendRequest())
265 return PMINFO_R_ERROR;
267 auto ptr = client.GetResultParcel();
268 if (ptr == nullptr) {
269 LOG(ERROR) << "Fail to get return parcelable";
270 return PMINFO_R_ERROR;
273 if (ptr->GetRequestResult() != PMINFO_R_OK) {
274 LOG(ERROR) << "Request fail";
275 return ptr->GetRequestResult();
278 if (ptr->GetType() != pcp::ParcelableType::Result) {
279 LOG(ERROR) << "Invalid parcelable type";
280 return PMINFO_R_ERROR;
283 std::shared_ptr<pcp::ResultParcelable> return_parcel(
284 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
286 auto result_list = return_parcel->GetResult();
287 if (result_list.size() == 0)
288 return PMINFO_R_ENOENT;
289 for (auto result : result_list) {
290 if (result.size() != 2)
291 return PMINFO_R_ERROR;
292 if (result.front().empty() || result.front().size() == 0 ||
293 result.back().empty() || result.back().size() == 0)
294 return PMINFO_R_ERROR;
295 *appid = strdup(result.front().c_str());
296 *access = strdup(result.back().c_str());
297 if (*appid == nullptr || *access == nullptr) {
298 LOG(ERROR) << "Out of memory";
299 return PMINFO_R_ERROR;
306 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
307 const char* providerid, uid_t uid, char** appid) {
308 char* query = nullptr;
310 query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
311 "WHERE providerid=%Q",
313 if (query == nullptr) {
314 LOGE("Out of memory");
315 return PMINFO_R_ERROR;
317 std::shared_ptr<pcp::AbstractParcelable> parcelable(
318 new pcp::QueryParcelable(uid, std::string(query),
319 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
320 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
323 pkgmgr_client::PkgInfoClient client(parcelable, uid,
324 pkgmgr_common::ReqType::QUERY);
325 if (!client.SendRequest())
326 return PMINFO_R_ERROR;
328 auto ptr = client.GetResultParcel();
329 if (ptr == nullptr) {
330 LOG(ERROR) << "Fail to get return parcelable";
331 return PMINFO_R_ERROR;
334 if (ptr->GetRequestResult() != PMINFO_R_OK) {
335 LOG(ERROR) << "Request fail";
336 return ptr->GetRequestResult();
339 if (ptr->GetType() != pcp::ParcelableType::Result) {
340 LOG(ERROR) << "Invalid parcelable type";
341 return PMINFO_R_ERROR;
344 std::shared_ptr<pcp::ResultParcelable> return_parcel(
345 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
347 // result_list is vector of string vector
348 auto result_list = return_parcel->GetResult();
349 if (result_list.size() == 0)
350 return PMINFO_R_ENOENT;
351 for (auto result : result_list) {
352 if (result.size() != 1)
353 return PMINFO_R_ERROR;
354 if (result.front().empty() || result.front().size() == 0)
355 return PMINFO_R_ERROR;
356 *appid = strdup(result.front().c_str());
357 if (*appid == nullptr) {
358 LOG(ERROR) << "Out of memory";
359 return PMINFO_R_ERROR;
366 extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
367 const char* providerid, const char* type, uid_t uid,
368 char** appid, char** trusted) {
369 char* query = nullptr;
370 query = sqlite3_mprintf(
371 "SELECT app_id, trusted FROM package_app_data_control "
372 "WHERE providerid=%Q AND type=%Q",
374 if (query == nullptr) {
375 LOGE("Out of memory");
376 return PMINFO_R_ERROR;
379 std::shared_ptr<pcp::AbstractParcelable> parcelable(
380 new pcp::QueryParcelable(uid, std::string(query),
381 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
382 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
385 pkgmgr_client::PkgInfoClient client(parcelable, uid,
386 pkgmgr_common::ReqType::QUERY);
387 if (!client.SendRequest())
388 return PMINFO_R_ERROR;
390 auto ptr = client.GetResultParcel();
391 if (ptr == nullptr) {
392 LOG(ERROR) << "Fail to get return parcelable";
393 return PMINFO_R_ERROR;
396 if (ptr->GetRequestResult() != PMINFO_R_OK) {
397 LOG(ERROR) << "Request fail";
398 return ptr->GetRequestResult();
401 if (ptr->GetType() != pcp::ParcelableType::Result) {
402 LOG(ERROR) << "Invalid parcelable type";
403 return PMINFO_R_ERROR;
406 std::shared_ptr<pcp::ResultParcelable> return_parcel(
407 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
409 // result_list is vector of string vector
410 auto result_list = return_parcel->GetResult();
411 if (result_list.size() == 0)
412 return PMINFO_R_ENOENT;
413 for (auto result : result_list) {
414 if (result.size() != 2)
415 return PMINFO_R_ERROR;
416 if (result.front().empty() || result.front().size() == 0 ||
417 result.back().empty() || result.back().size() == 0)
418 return PMINFO_R_ERROR;
419 *appid = strdup(result.front().c_str());
420 *trusted = strdup(result.back().c_str());
421 if (*appid == nullptr || *trusted == nullptr) {
422 LOG(ERROR) << "Out of memory";
423 return PMINFO_R_ERROR;
430 extern "C" EXPORT_API int _appinfo_get_datacontrol_privileges(
431 const char* providerid, const char* type, uid_t uid, GList** privileges) {
432 char* query = nullptr;
433 query = sqlite3_mprintf(
434 "SELECT privilege FROM package_app_data_control_privilege "
435 "WHERE providerid=%Q AND type=%Q",
437 if (query == nullptr) {
438 LOGE("Out of memory");
439 return PMINFO_R_ERROR;
442 std::shared_ptr<pcp::AbstractParcelable> parcelable(
443 new pcp::QueryParcelable(uid, std::string(query),
444 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
445 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
448 pkgmgr_client::PkgInfoClient client(parcelable, uid,
449 pkgmgr_common::ReqType::QUERY);
450 if (!client.SendRequest())
451 return PMINFO_R_ERROR;
453 auto ptr = client.GetResultParcel();
454 if (ptr == nullptr) {
455 LOG(ERROR) << "Fail to get return parcelable";
456 return PMINFO_R_ERROR;
459 if (ptr->GetRequestResult() != PMINFO_R_OK) {
460 LOG(ERROR) << "Request fail";
461 return ptr->GetRequestResult();
464 if (ptr->GetType() != pcp::ParcelableType::Result) {
465 LOG(ERROR) << "Invalid parcelable type";
466 return PMINFO_R_ERROR;
469 std::shared_ptr<pcp::ResultParcelable> return_parcel(
470 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
472 // result_list is vector of string vector
473 auto result_list = return_parcel->GetResult();
474 if (result_list.size() == 0)
475 return PMINFO_R_ENOENT;
477 for (auto result : result_list) {
478 if (result.size() != 1)
479 return PMINFO_R_ERROR;
480 if (result.front().empty() || result.front().size() == 0)
481 return PMINFO_R_ERROR;
482 char* privilege = strdup(result.front().c_str());
483 if (privilege == nullptr) {
484 LOG(ERROR) << "Out of memory";
485 return PMINFO_R_ERROR;
487 *privileges = g_list_append(*privileges, privilege);
493 extern "C" EXPORT_API int _appinfo_get_appcontrol_privileges(
494 const char* appid, const char* operation, uid_t uid, GList** privileges) {
495 char* query = nullptr;
496 query = sqlite3_mprintf(
497 "SELECT app_control, privilege FROM package_app_app_control_privilege "
498 "WHERE app_id=%Q", appid);
499 if (query == nullptr) {
500 LOG(ERROR) << "Out of memory";
501 return PMINFO_R_ERROR;
504 std::shared_ptr<pcp::AbstractParcelable> parcelable(
505 new pcp::QueryParcelable(uid, std::string(query),
506 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
507 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
510 pkgmgr_client::PkgInfoClient client(parcelable, uid,
511 pkgmgr_common::ReqType::QUERY);
512 if (!client.SendRequest())
513 return PMINFO_R_ERROR;
515 auto ptr = client.GetResultParcel();
516 if (ptr == nullptr) {
517 LOG(ERROR) << "Fail to get return parcelable";
518 return PMINFO_R_ERROR;
521 if (ptr->GetRequestResult() != PMINFO_R_OK) {
522 LOG(ERROR) << "Request fail";
523 return ptr->GetRequestResult();
526 if (ptr->GetType() != pcp::ParcelableType::Result) {
527 LOG(ERROR) << "Invalid parcelable type";
528 return PMINFO_R_ERROR;
531 std::shared_ptr<pcp::ResultParcelable> return_parcel(
532 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
534 // result_list is vector of string vector
535 auto result_list = return_parcel->GetResult();
536 if (result_list.size() == 0)
537 return PMINFO_R_ENOENT;
539 for (auto result : result_list) {
540 if (result.size() != 2)
541 return PMINFO_R_ERROR;
542 if (result.front().empty() || result.front().size() == 0 ||
543 result.back().empty() || result.back().size() == 0)
544 return PMINFO_R_ERROR;
545 std::string app_control = result.front();
546 std::stringstream ss(app_control);
548 while (std::getline(ss, token, '|')) {
549 if (token.compare(std::string(operation))) {
550 char* privilege = strdup(result.back().c_str());
551 if (privilege == nullptr) {
552 LOG(ERROR) << "Out of memory";
553 return PMINFO_R_ERROR;
555 *privileges = g_list_append(*privileges, privilege);
562 extern "C" EXPORT_API int _plugininfo_get_appids(
563 const char* pkgid, const char* plugin_type,
564 const char* plugin_name, GList** list) {
565 if (!pkgid || !plugin_type || !plugin_name || !list) {
566 LOG(ERROR) << "Invalid parameter";
567 return PMINFO_R_EINVAL;
570 char* query = nullptr;
571 query = sqlite3_mprintf(
573 "package_plugin_info WHERE pkgid=%Q AND "
574 "plugin_type=%Q AND plugin_name=%Q",
575 pkgid, plugin_type, plugin_name);
576 if (query == nullptr) {
577 LOG(ERROR) << "Out of memory";
578 return PMINFO_R_ERROR;
581 std::shared_ptr<pcp::AbstractParcelable> parcelable(
582 new pcp::QueryParcelable(_getuid(), std::string(query),
583 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
584 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
587 pkgmgr_client::PkgInfoClient client(parcelable, _getuid(),
588 pkgmgr_common::ReqType::QUERY);
589 if (!client.SendRequest())
590 return PMINFO_R_ERROR;
592 auto ptr = client.GetResultParcel();
593 if (ptr == nullptr) {
594 LOG(ERROR) << "Fail to get return parcelable";
595 return PMINFO_R_ERROR;
598 if (ptr->GetRequestResult() != PMINFO_R_OK) {
599 LOG(ERROR) << "Request fail";
600 return ptr->GetRequestResult();
603 if (ptr->GetType() != pcp::ParcelableType::Result) {
604 LOG(ERROR) << "Invalid parcelable type";
605 return PMINFO_R_ERROR;
608 std::shared_ptr<pcp::ResultParcelable> return_parcel(
609 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
611 if (return_parcel->GetCol() != 1) {
612 LOG(ERROR) << "Invalid result";
613 return PMINFO_R_ERROR;
615 // result_list is vector of string vector
616 auto &result_list = return_parcel->GetResult();
617 if (result_list.size() == 0)
618 return PMINFO_R_ENOENT;
620 for (auto result : result_list) {
621 if (result.size() != 1) {
622 LOG(ERROR) << "Invalid result";
623 g_list_free_full(*list, free);
624 return PMINFO_R_ERROR;
626 *list = g_list_append(*list, strdup(result[0].c_str()));
632 static int __convert_update_type(const char* type,
633 pkgmgrinfo_updateinfo_update_type* convert_type) {
634 if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_NONE,
635 strlen(PMINFO_UPDATEINFO_TYPE_NONE)) == 0)
636 *convert_type = PMINFO_UPDATEINFO_NONE;
637 else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_FORCE,
638 strlen(PMINFO_UPDATEINFO_TYPE_FORCE)) == 0)
639 *convert_type = PMINFO_UPDATEINFO_FORCE;
640 else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_OPTIONAL,
641 strlen(PMINFO_UPDATEINFO_TYPE_OPTIONAL)) == 0)
642 *convert_type = PMINFO_UPDATEINFO_OPTIONAL;
648 static void __free_update_info(gpointer data) {
649 updateinfo_x* update_info = reinterpret_cast<updateinfo_x*>(data);
650 if (update_info == nullptr)
653 if (update_info->pkgid)
654 free(reinterpret_cast<void*>(update_info->pkgid));
655 if (update_info->version)
656 free(reinterpret_cast<void*>(update_info->version));
657 free(reinterpret_cast<void*>(update_info));
660 extern "C" EXPORT_API int _get_pkg_updateinfo(const char* pkgid,
661 GSList** update_info_list, uid_t uid) {
662 char* query = nullptr;
665 if (pkgid == nullptr)
666 query = sqlite3_mprintf(
667 "SELECT package, update_version, update_type "
668 "FROM package_update_info");
670 query = sqlite3_mprintf(
671 "SELECT package, update_version, update_type "
672 "FROM package_update_info WHERE package=%Q",
674 if (query == nullptr) {
675 LOG(ERROR) << "Out of memory";
676 return PMINFO_R_ERROR;
679 std::shared_ptr<pcp::AbstractParcelable> parcelable(
680 new pcp::QueryParcelable(uid, std::string(query),
681 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
682 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
685 pkgmgr_client::PkgInfoClient client(parcelable, uid,
686 pkgmgr_common::ReqType::QUERY);
687 if (!client.SendRequest())
688 return PMINFO_R_ERROR;
690 auto ptr = client.GetResultParcel();
691 if (ptr == nullptr) {
692 LOG(ERROR) << "Fail to get return parcelable";
693 return PMINFO_R_ERROR;
696 if (ptr->GetRequestResult() != PMINFO_R_OK) {
697 LOG(ERROR) << "Request fail";
698 return ptr->GetRequestResult();
701 if (ptr->GetType() != pcp::ParcelableType::Result) {
702 LOG(ERROR) << "Invalid parcelable type";
703 return PMINFO_R_ERROR;
706 std::shared_ptr<pcp::ResultParcelable> return_parcel(
707 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
709 if (return_parcel->GetCol() != 3) {
710 LOG(ERROR) << "Invalid result";
711 return PMINFO_R_ERROR;
714 auto result_list = return_parcel->GetResult();
715 if (result_list.size() == 0)
716 return PMINFO_R_ENOENT;
718 for (auto result : result_list) {
719 if (result.size() != 3) {
720 LOG(ERROR) << "Invalid result";
721 g_slist_free_full(*update_info_list, __free_update_info);
722 return PMINFO_R_ERROR;
724 updateinfo_x* update_info = reinterpret_cast<updateinfo_x*>(
725 calloc(1, sizeof(updateinfo_x)));
726 if (update_info == nullptr) {
727 LOG(ERROR) << "Out of memory";
728 return PMINFO_R_ERROR;
730 update_info->pkgid = strdup(result[0].c_str());
731 update_info->version = strdup(result[1].c_str());
732 pkgmgrinfo_updateinfo_update_type convert_type;
733 ret = __convert_update_type(result[2].c_str(), &convert_type);
735 __free_update_info(update_info);
736 g_slist_free_full(*update_info_list, __free_update_info);
737 return PMINFO_R_ERROR;
739 update_info->type = static_cast<int>(convert_type);
740 *update_info_list = g_slist_prepend(*update_info_list,
747 extern "C" EXPORT_API int _pkginfo_set_usr_installed_storage(const char* pkgid,
748 INSTALL_LOCATION location, const char* external_pkg_path, uid_t uid) {
749 char* query = nullptr;
750 const char* location_str;
751 std::vector<std::string> queries;
753 if (location == INSTALL_INTERNAL)
754 location_str = "installed_internal";
755 else if (location == INSTALL_EXTERNAL)
756 location_str = "installed_external";
758 location_str = "installed_extended";
759 /* pkgcakge_info table */
760 query = sqlite3_mprintf(
761 "UPDATE package_info SET installed_storage=%Q, external_path=%Q "
763 location_str, external_pkg_path, pkgid);
764 queries.emplace_back(query);
767 /* package_app_info table */
768 query = sqlite3_mprintf(
769 "UPDATE package_app_info SET app_installed_storage=%Q, "
770 "app_external_path=%Q WHERE package=%Q",
771 location_str, external_pkg_path, pkgid);
772 queries.emplace_back(query);
775 std::shared_ptr<pcp::AbstractParcelable> parcelable(
776 new pcp::QueryParcelable(uid, queries,
777 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
778 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
780 pkgmgr_client::PkgInfoClient client(parcelable, uid,
781 pkgmgr_common::ReqType::QUERY);
782 if (!client.SendRequest())
783 return PMINFO_R_ERROR;
785 auto ptr = client.GetResultParcel();
786 if (ptr == nullptr) {
787 LOG(ERROR) << "Fail to get return parcelable";
788 return PMINFO_R_ERROR;
791 if (ptr->GetRequestResult() != PMINFO_R_OK) {
792 LOG(ERROR) << "Request fail";
793 return ptr->GetRequestResult();
796 if (ptr->GetType() != pcp::ParcelableType::Result) {
797 LOG(ERROR) << "Invalid parcelable type";
798 return PMINFO_R_ERROR;
804 extern "C" EXPORT_API int _certinfo_compare_pkg_certinfo(const char* l_pkgid,
805 const char* r_pkgid, pkgmgrinfo_cert_compare_result_type_e* result) {
806 char* query = sqlite3_mprintf("SELECT package, "
807 "COALESCE(author_signer_cert, -1) FROM package_cert_info WHERE "
808 "package IN (%Q, %Q)",
810 if (query == nullptr) {
811 LOG(ERROR) << "Out of memory";
812 return PMINFO_R_ERROR;
814 std::vector<std::string> queries;
815 queries.emplace_back(query);
818 std::shared_ptr<pcp::AbstractParcelable> parcelable(
819 new pcp::QueryParcelable(0, queries,
820 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_CERTDB,
821 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
822 pkgmgr_client::PkgInfoClient client(parcelable, 0,
823 pkgmgr_common::ReqType::QUERY);
824 if (!client.SendRequest())
825 return PMINFO_R_ERROR;
827 auto ptr = client.GetResultParcel();
828 if (ptr == nullptr) {
829 LOG(ERROR) << "Fail to get return parcelable";
830 return PMINFO_R_ERROR;
833 if (ptr->GetRequestResult() != PMINFO_R_OK) {
834 LOG(ERROR) << "Request fail";
835 return ptr->GetRequestResult();
838 if (ptr->GetType() != pcp::ParcelableType::Result) {
839 LOG(ERROR) << "Invalid parcelable type";
840 return PMINFO_R_ERROR;
843 std::shared_ptr<pcp::ResultParcelable> return_parcel(
844 std::static_pointer_cast<pcp::ResultParcelable>(
847 auto certinfo_list = return_parcel->GetResult();
849 std::map<std::string, std::string> result_map;
850 result_map.insert(make_pair(std::string(l_pkgid), "-1"));
851 result_map.insert(make_pair(std::string(r_pkgid), "-1"));
853 for (auto &certinfo : certinfo_list)
854 result_map[certinfo.front()] = certinfo.back();
856 if (result_map.find(std::string(l_pkgid))->second == "-1" &&
857 result_map.find(std::string(r_pkgid))->second == "-1")
858 *result = PMINFO_CERT_COMPARE_BOTH_NO_CERT;
859 else if (result_map.find(std::string(l_pkgid))->second == "-1")
860 *result = PMINFO_CERT_COMPARE_LHS_NO_CERT;
861 else if (result_map.find(std::string(r_pkgid))->second == "-1")
862 *result = PMINFO_CERT_COMPARE_RHS_NO_CERT;
863 else if (result_map.find(std::string(l_pkgid))->second ==
864 result_map.find(std::string(r_pkgid))->second)
865 *result = PMINFO_CERT_COMPARE_MATCH;
867 *result = PMINFO_CERT_COMPARE_MISMATCH;
872 extern "C" EXPORT_API int _certinfo_compare_app_certinfo(uid_t uid,
873 const char* l_appid, const char* r_appid,
874 pkgmgrinfo_cert_compare_result_type_e* result) {
875 char* query = sqlite3_mprintf("SELECT app_id, package FROM "
876 "package_app_info WHERE app_id IN (%Q, %Q)",
878 if (query == nullptr) {
879 LOG(ERROR) << "Out of memory";
880 return PMINFO_R_ERROR;
882 std::vector<std::string> queries;
883 queries.emplace_back(query);
886 std::shared_ptr<pcp::AbstractParcelable> parcelable(
887 new pcp::QueryParcelable(uid, queries,
888 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
889 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
890 pkgmgr_client::PkgInfoClient client(parcelable, uid,
891 pkgmgr_common::ReqType::QUERY);
892 if (!client.SendRequest())
893 return PMINFO_R_ERROR;
895 auto ptr = client.GetResultParcel();
896 if (ptr == nullptr) {
897 LOG(ERROR) << "Fail to get return parcelable";
898 return PMINFO_R_ERROR;
901 if (ptr->GetRequestResult() != PMINFO_R_OK) {
902 LOG(ERROR) << "Request fail";
903 return ptr->GetRequestResult();
906 if (ptr->GetType() != pcp::ParcelableType::Result) {
907 LOG(ERROR) << "Invalid parcelable type";
908 return PMINFO_R_ERROR;
911 std::shared_ptr<pcp::ResultParcelable> return_parcel(
912 std::static_pointer_cast<pcp::ResultParcelable>(ptr));
914 auto pkgid_list = return_parcel->GetResult();
915 std::map<std::string, std::string> result_map;
916 for (auto &pkgid : pkgid_list)
917 result_map.insert(make_pair(pkgid.front(), pkgid.back()));
919 if (result_map.find(std::string(l_appid)) == result_map.end()) {
920 LOG(ERROR) << "Cannot find pkgid of app " << l_appid
921 << " for uid " << uid;
922 return PMINFO_R_ENOENT;
923 } else if (result_map.find(std::string(r_appid)) == result_map.end()) {
924 LOG(ERROR) << "Cannot find pkgid of app " << r_appid
925 << " for uid " << uid;
926 return PMINFO_R_ENOENT;
929 const char* l_pkgid = result_map.find(std::string(l_appid))->second.c_str();
930 const char* r_pkgid = result_map.find(std::string(r_appid))->second.c_str();
932 return _certinfo_compare_pkg_certinfo(l_pkgid, r_pkgid, result);
935 extern "C" EXPORT_API int _parser_execute_write_query(
936 const char* query, uid_t uid) {
937 std::shared_ptr<pcp::AbstractParcelable> parcelable(
938 new pcp::QueryParcelable(uid, query,
939 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
940 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
942 pkgmgr_client::PkgInfoClient client(parcelable, uid,
943 pkgmgr_common::ReqType::QUERY);
944 if (!client.SendRequest())
947 auto ptr = client.GetResultParcel();
948 if (ptr == nullptr) {
949 LOG(ERROR) << "Fail to get return parcelable";
953 if (ptr->GetRequestResult() != PMINFO_R_OK) {
954 LOG(ERROR) << "Request fail";
958 if (ptr->GetType() != pcp::ParcelableType::Result) {
959 LOG(ERROR) << "Invalid parcelable type";
966 extern "C" EXPORT_API int _parser_execute_write_queries(
967 const char** queries, int len, uid_t uid) {
968 std::vector<std::string> query_vt;
969 for (int i = 0; i < len; ++i)
970 query_vt.emplace_back(queries[i]);
972 std::shared_ptr<pcp::AbstractParcelable> parcelable(
973 new pcp::QueryParcelable(uid, query_vt,
974 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
975 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
977 pkgmgr_client::PkgInfoClient client(parcelable, uid,
978 pkgmgr_common::ReqType::QUERY);
979 if (!client.SendRequest())
982 auto ptr = client.GetResultParcel();
983 if (ptr == nullptr) {
984 LOG(ERROR) << "Fail to get return parcelable";
988 if (ptr->GetRequestResult() != PMINFO_R_OK) {
989 LOG(ERROR) << "Request fail";
993 if (ptr->GetType() != pcp::ParcelableType::Result) {
994 LOG(ERROR) << "Invalid parcelable type";
1001 extern "C" EXPORT_API int _parser_insert_manifest_info(
1002 manifest_x* mfx, uid_t uid) {
1004 std::make_shared<pcp::PkgInfoParcelable>(uid,
1005 std::vector<package_x*>{mfx}, WriteType::Insert, false);
1007 pkgmgr_client::PkgInfoClient client(parcelable, uid,
1008 pkgmgr_common::ReqType::SET_PKG_INFO);
1009 if (!client.SendRequest())
1012 auto ptr = client.GetResultParcel();
1013 if (ptr == nullptr) {
1014 LOG(ERROR) << "Fail to get return parcelable";
1018 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1019 LOG(ERROR) << "Request fail";
1023 if (ptr->GetType() != pcp::ParcelableType::Result) {
1024 LOG(ERROR) << "Invalid parcelable type";
1031 extern "C" EXPORT_API int _parser_update_manifest_info(
1032 manifest_x* mfx, uid_t uid) {
1034 std::make_shared<pcp::PkgInfoParcelable>(uid,
1035 std::vector<package_x*>{mfx}, WriteType::Update, false);
1037 pkgmgr_client::PkgInfoClient client(parcelable, uid,
1038 pkgmgr_common::ReqType::SET_PKG_INFO);
1039 if (!client.SendRequest())
1042 auto ptr = client.GetResultParcel();
1043 if (ptr == nullptr) {
1044 LOG(ERROR) << "Fail to get return parcelable";
1048 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1049 LOG(ERROR) << "Request fail";
1053 if (ptr->GetType() != pcp::ParcelableType::Result) {
1054 LOG(ERROR) << "Invalid parcelable type";
1061 extern "C" EXPORT_API int _parser_delete_manifest_info(
1062 manifest_x* mfx, uid_t uid) {
1064 std::make_shared<pcp::PkgInfoParcelable>(uid,
1065 std::vector<package_x*>{mfx}, WriteType::Delete, false);
1067 pkgmgr_client::PkgInfoClient client(parcelable, uid,
1068 pkgmgr_common::ReqType::SET_PKG_INFO);
1069 if (!client.SendRequest())
1072 auto ptr = client.GetResultParcel();
1073 if (ptr == nullptr) {
1074 LOG(ERROR) << "Fail to get return parcelable";
1078 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1079 LOG(ERROR) << "Request fail";
1083 if (ptr->GetType() != pcp::ParcelableType::Result) {
1084 LOG(ERROR) << "Invalid parcelable type";
1091 extern "C" EXPORT_API int _pkginfo_insert_certinfo(const char* pkgid,
1092 pkgmgr_certinfo_x* cert, uid_t uid) {
1093 std::shared_ptr<pcp::AbstractParcelable> parcelable(
1094 new pcp::CertInfoParcelable(uid, cert, false));
1095 pkgmgr_client::PkgInfoClient client(parcelable, uid,
1096 pkgmgr_common::ReqType::SET_CERT_INFO);
1098 if (!client.SendRequest())
1099 return PMINFO_R_ERROR;
1101 auto ptr = client.GetResultParcel();
1102 if (ptr == nullptr) {
1103 LOG(ERROR) << "Fail to get return parcelable";
1104 return PMINFO_R_ERROR;
1107 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1108 LOG(ERROR) << "Request fail";
1109 return ptr->GetRequestResult();
1112 if (ptr->GetType() != pcp::ParcelableType::Result) {
1113 LOG(ERROR) << "Invalid parcelable type";
1114 return PMINFO_R_ERROR;
1120 extern "C" EXPORT_API int _pkginfo_get_certinfo(const char* pkgid,
1121 pkgmgr_certinfo_x* cert, uid_t uid) {
1122 std::shared_ptr<pcp::AbstractParcelable> parcelable(
1123 new pcp::CertInfoParcelable(uid,
1124 std::string(pkgid)));
1126 pkgmgr_client::PkgInfoClient client(parcelable, uid,
1127 pkgmgr_common::ReqType::GET_CERT_INFO);
1128 if (!client.SendRequest())
1129 return PMINFO_R_ERROR;
1131 auto ptr = client.GetResultParcel();
1132 if (ptr == nullptr) {
1133 LOG(ERROR) << "Fail to get return parcelable";
1134 return PMINFO_R_ERROR;
1137 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1138 LOG(ERROR) << "Request fail";
1139 return ptr->GetRequestResult();
1142 if (ptr->GetType() != pcp::ParcelableType::CertInfo) {
1143 LOG(ERROR) << "Invalid parcelable type";
1144 return PMINFO_R_ERROR;
1147 std::shared_ptr<pcp::CertInfoParcelable> return_parcel(
1148 std::static_pointer_cast<pcp::CertInfoParcelable>(ptr));
1150 pkgmgr_certinfo_x* certinfo = return_parcel->ExtractCertInfo();
1151 if (certinfo == nullptr)
1152 return PMINFO_R_ERROR;
1154 cert->for_all_users = certinfo->for_all_users;
1155 cert->pkgid = certinfo->pkgid;
1156 certinfo->pkgid = nullptr;
1157 cert->cert_value = certinfo->cert_value;
1158 certinfo->cert_value = nullptr;
1159 for (int i = 0; i < MAX_CERT_TYPE; i++) {
1160 cert->cert_info[i] = certinfo->cert_info[i];
1161 certinfo->cert_info[i] = nullptr;
1163 for (int i = 0; i < MAX_CERT_TYPE; i++)
1164 cert->cert_id[i] = certinfo->cert_id[i];
1171 extern "C" EXPORT_API int _pkginfo_delete_certinfo(const char* pkgid) {
1172 char* query = sqlite3_mprintf("UPDATE package_cert_info SET "
1173 "package_count = package_count - 1 WHERE package=%Q", pkgid);
1174 if (query == nullptr) {
1175 LOG(ERROR) << "Out of memory";
1176 return PMINFO_R_ERROR;
1179 std::vector<std::string> queries;
1180 queries.emplace_back(query);
1181 sqlite3_free(query);
1183 std::shared_ptr<pcp::AbstractParcelable> parcelable(
1184 new pcp::QueryParcelable(0, queries,
1185 pcd::AbstractDBHandler::DBType::DB_TYPE_FILE_CERTDB,
1186 pcd::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
1188 pkgmgr_client::PkgInfoClient client(parcelable, 0,
1189 pkgmgr_common::ReqType::QUERY);
1190 if (!client.SendRequest())
1191 return PMINFO_R_ERROR;
1193 auto ptr = client.GetResultParcel();
1194 if (ptr == nullptr) {
1195 LOG(ERROR) << "Fail to get return parcelable";
1196 return PMINFO_R_ERROR;
1199 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1200 LOG(ERROR) << "Request fail";
1201 return PMINFO_R_ERROR;
1204 if (ptr->GetType() != pcp::ParcelableType::Result) {
1205 LOG(ERROR) << "Invalid parcelable type";
1206 return PMINFO_R_ERROR;
1212 extern "C" EXPORT_API int _parser_clear_cache_memory_db(uid_t uid) {
1213 std::shared_ptr<pcp::AbstractParcelable> parcelable(
1214 new pcp::CommandParcelable(uid, CommandType::RemoveCache));
1216 pkgmgr_client::PkgInfoClient client(parcelable, uid,
1217 pkgmgr_common::ReqType::COMMAND);
1219 if (!client.SendRequest())
1220 return PMINFO_R_ERROR;
1222 auto ptr = client.GetResultParcel();
1223 if (ptr == nullptr) {
1224 LOG(ERROR) << "Fail to get return parcelable";
1225 return PMINFO_R_ERROR;
1228 if (ptr->GetRequestResult() != PMINFO_R_OK) {
1229 LOG(ERROR) << "Request fail";
1230 return PMINFO_R_ERROR;
1233 if (ptr->GetType() != pcp::ParcelableType::Result) {
1234 LOG(ERROR) << "Invalid parcelable type";
1235 return PMINFO_R_ERROR;