Merge branch 'master' into fix_log
[platform/core/appfw/pkgmgr-info.git] / src / manager / pkginfo_manager.cc
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "manager/pkginfo_manager.h"
18
19 #include <sys/types.h>
20
21 #include <map>
22 #include <string>
23
24 #include "sqlite3.h"
25 #include "glib.h"
26
27 #include "pkgmgr_parser.h"
28 #include "pkgmgrinfo_private.h"
29
30 #include "logging.hh"
31 #include "common/database/abstract_db_handler.hh"
32 #include "common/database/pkg_set_db_handler.hh"
33 #include "common/parcel/appinfo_parcelable.hh"
34 #include "common/parcel/certinfo_parcelable.hh"
35 #include "common/parcel/depinfo_parcelable.hh"
36 #include "common/parcel/filter_parcelable.hh"
37 #include "common/parcel/pkginfo_parcelable.hh"
38 #include "common/parcel/query_parcelable.hh"
39 #include "common/parcel/result_parcelable.hh"
40
41 #include "client/pkginfo_client.hh"
42
43 #include <parcel.hh>
44
45 #ifdef LOG_TAG
46 #undef LOG_TAG
47 #endif
48 #define LOG_TAG "PKGMGR_INFO"
49
50 #ifdef EXPORT_API
51 #undef EXPORT_API
52 #endif
53 #define EXPORT_API __attribute__((visibility("default")))
54
55 extern "C" EXPORT_API int _pkginfo_get_packages(uid_t uid,
56             pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
57         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
58                         new pkgmgr_common::parcel::FilterParcelable(uid,
59                                         static_cast<pkgmgrinfo_filter_x*>(filter), flag));
60
61         pkgmgr_client::PkgInfoClient client(parcelable, uid,
62                         pkgmgr_common::ReqType::GET_PKG_INFO);
63         if (!client.SendRequest())
64       return PMINFO_R_ERROR;
65
66         auto ptr = client.GetResultParcel();
67         if (ptr == nullptr) {
68                 LOG(ERROR) << "Fail to get return parcelable";
69                 return PMINFO_R_ERROR;
70         }
71
72         if (ptr->GetRequestResult() != PMINFO_R_OK) {
73                 LOG(ERROR) << "Request fail";
74                 return ptr->GetRequestResult();
75         }
76
77         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::PkgInfo) {
78                 LOG(ERROR) << "Invalid parcelable type";
79                 return PMINFO_R_ERROR;
80         }
81
82         std::shared_ptr<pkgmgr_common::parcel::PkgInfoParcelable> return_parcel(
83                         std::static_pointer_cast<pkgmgr_common::parcel::PkgInfoParcelable>(
84                                         ptr));
85
86         auto result_list = return_parcel->GetPkgInfo();
87         // TODO: check noentry error has returned if size of result_list is 0
88         for (auto& pkginfo : result_list)
89                 g_hash_table_insert(packages, (gpointer)pkginfo->package,
90                                 (gpointer)pkginfo);
91
92         return PMINFO_R_OK;
93 }
94
95 extern "C" EXPORT_API int _pkginfo_get_depends_on(uid_t uid,
96                 const char *pkgid, GList **dependencies) {
97         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
98                         new pkgmgr_common::parcel::DepInfoParcelable(std::string(pkgid)));
99
100         pkgmgr_client::PkgInfoClient client(parcelable, uid,
101                         pkgmgr_common::ReqType::GET_PKG_DEP_INFO);
102         if (!client.SendRequest())
103       return PMINFO_R_ERROR;
104
105         auto ptr = client.GetResultParcel();
106         if (ptr == nullptr) {
107                 LOG(ERROR) << "Fail to get return parcelable";
108                 return PMINFO_R_ERROR;
109         }
110
111         if (ptr->GetRequestResult() != PMINFO_R_OK) {
112                 LOG(ERROR) << "Request fail";
113                 return ptr->GetRequestResult();
114         }
115
116         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::DepInfo) {
117                 LOG(ERROR) << "Invalid parcelable type";
118                 return PMINFO_R_ERROR;
119         }
120
121         std::shared_ptr<pkgmgr_common::parcel::DepInfoParcelable> return_parcel(
122                         std::static_pointer_cast<pkgmgr_common::parcel::DepInfoParcelable>(
123                                         ptr));
124
125         auto dependency_list = return_parcel->GetDependencyInfo();
126         for (auto& dependency : dependency_list)
127                 *dependencies = g_list_prepend(*dependencies, dependency);
128         return PMINFO_R_OK;
129 }
130
131 // TODO: Need to add target db uid to identify which database to be searched
132 extern "C" EXPORT_API int _appinfo_get_applications(uid_t db_uid, uid_t uid,
133                 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
134         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
135                         new pkgmgr_common::parcel::FilterParcelable(uid,
136                                         static_cast<pkgmgrinfo_filter_x*>(filter), flag));
137
138         pkgmgr_client::PkgInfoClient client(parcelable, uid, pkgmgr_common::ReqType::GET_APP_INFO);
139         if (!client.SendRequest())
140       return PMINFO_R_ERROR;
141
142         auto ptr = client.GetResultParcel();
143         if (ptr == nullptr) {
144                 LOG(ERROR) << "Fail to get return parcelable";
145                 return PMINFO_R_ERROR;
146         }
147
148         int ret = return_parcel->GetRequestResult();
149         if (ret != PMINFO_R_OK) {
150                 if (ret == PMINFO_R_ENOENT) {
151                         LOG(DEBUG) << "No such application";
152                 } else {
153                         LOG(ERROR) << "Request fail";
154                 }
155                 return ret;
156         }
157
158         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::AppInfo) {
159                 LOG(ERROR) << "Invalid parcelable type";
160                 return PMINFO_R_ERROR;
161         }
162
163         std::shared_ptr<pkgmgr_common::parcel::AppInfoParcelable> return_parcel(
164                         std::static_pointer_cast<pkgmgr_common::parcel::AppInfoParcelable>(
165                                         ptr));
166
167         auto result_list = return_parcel->GetAppInfo();
168         for (auto& appinfo : result_list)
169                 g_hash_table_insert(packages, (gpointer)appinfo->appid,
170                                 (gpointer)appinfo);
171
172         return PMINFO_R_OK;
173 }
174
175 extern "C" EXPORT_API char *_appinfo_get_localed_label(
176                 const char *appid, const char *locale, uid_t uid) {
177         char *query = nullptr;
178     query = sqlite3_mprintf(
179                         "SELECT COALESCE((SELECT app_label FROM package_app_localized_info "
180                         "WHERE app_id=%Q AND app_locale=%Q),"
181                         "(SELECT app_label FROM package_app_localized_info WHERE "
182                         "app_id=%Q AND app_locale='No Locale'))", appid, locale, appid);
183         if (query == nullptr) {
184                 LOG(ERROR) << "Out of memory";
185                 return nullptr;
186         }
187
188         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
189                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
190           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
191           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
192         sqlite3_free(query);
193
194         pkgmgr_client::PkgInfoClient client(parcelable, uid,
195                         pkgmgr_common::ReqType::QUERY);
196         if (!client.SendRequest()) {
197                 return nullptr;
198         }
199
200         auto ptr = client.GetResultParcel();
201         if (ptr == nullptr) {
202                 LOG(ERROR) << "Fail to get return parcelable";
203                 return nullptr;
204         }
205
206         if (ptr->GetRequestResult() != PMINFO_R_OK) {
207                 LOG(ERROR) << "Request fail";
208                 return nullptr;
209         }
210
211         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
212                 LOG(ERROR) << "Invalid parcelable type";
213                 return nullptr;
214         }
215
216         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
217                                 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
218                                                 ptr));
219
220         // result_list is vector of string vector
221         char *label = nullptr;
222         auto result_list = return_parcel->GetResult();
223         for (auto result : result_list) {
224                 // result is string vector
225                 // it only has one string or not.
226                 if (result.front().empty() || result.front().length() == 0)
227                         return nullptr;
228                 label = strdup(result.front().c_str());
229                 if (label == nullptr) {
230                         LOG(ERROR) << "Out of memory";
231                         return nullptr;
232                 }
233                 return label;
234         }
235
236         return label;
237 }
238
239 extern "C" EXPORT_API int _appinfo_get_datacontrol_info(
240                 const char *providerid, const char *type, uid_t uid,
241                 char **appid, char **access) {
242         char *query = nullptr;
243         query = sqlite3_mprintf("SELECT app_id, access FROM "
244                         "package_app_data_control WHERE "
245                         "providerid=%Q AND type=%Q", providerid, type);
246         if (query == nullptr) {
247                 LOG(ERROR) << "Out of memory";
248                 return PMINFO_R_ERROR;
249         }
250
251         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
252                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
253           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
254           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
255         sqlite3_free(query);
256
257         pkgmgr_client::PkgInfoClient client(parcelable, uid,
258                         pkgmgr_common::ReqType::QUERY);
259         if (!client.SendRequest()) {
260                 return PMINFO_R_ERROR;
261         }
262
263         auto ptr = client.GetResultParcel();
264         if (ptr == nullptr) {
265                 LOG(ERROR) << "Fail to get return parcelable";
266                 return PMINFO_R_ERROR;
267         }
268
269         if (ptr->GetRequestResult() != PMINFO_R_OK) {
270                 LOG(ERROR) << "Request fail";
271                 return ptr->GetRequestResult();
272         }
273
274         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
275                 LOG(ERROR) << "Invalid parcelable type";
276                 return PMINFO_R_ERROR;
277         }
278
279         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
280                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
281                                         ptr));
282
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;
298                 }
299         }
300
301         return PMINFO_R_OK;
302 }
303
304 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
305                 const char *providerid, uid_t uid, char **appid) {
306         char *query = nullptr;
307
308         query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
309                 "WHERE providerid=%Q", providerid);
310         if (query == nullptr) {
311                 LOGE("Out of memory");
312                 return PMINFO_R_ERROR;
313         }
314         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
315                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
316           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
317           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
318         sqlite3_free(query);
319
320         pkgmgr_client::PkgInfoClient client(parcelable, uid,
321                         pkgmgr_common::ReqType::QUERY);
322         if (!client.SendRequest()) {
323                 return PMINFO_R_ERROR;
324         }
325
326         auto ptr = client.GetResultParcel();
327         if (ptr == nullptr) {
328                 LOG(ERROR) << "Fail to get return parcelable";
329                 return PMINFO_R_ERROR;
330         }
331
332         if (ptr->GetRequestResult() != PMINFO_R_OK) {
333                 LOG(ERROR) << "Request fail";
334                 return ptr->GetRequestResult();
335         }
336
337         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
338                 LOG(ERROR) << "Invalid parcelable type";
339                 return PMINFO_R_ERROR;
340         }
341
342         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
343                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
344                                         ptr));
345
346         // result_list is vector of string vector
347         auto result_list = return_parcel->GetResult();
348         if (result_list.size() == 0)
349                 return PMINFO_R_ENOENT;
350         for (auto result : result_list) {
351                 if (result.size() != 1)
352                         return PMINFO_R_ERROR;
353                 if (result.front().empty() || result.front().size() == 0)
354                         return PMINFO_R_ERROR;
355                 *appid = strdup(result.front().c_str());
356                 if (*appid == nullptr) {
357                         LOG(ERROR) << "Out of memory";
358                         return PMINFO_R_ERROR;
359                 }
360         }
361
362         return PMINFO_R_OK;
363 }
364
365 extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
366                 const char *providerid, const char *type, uid_t uid,
367                 char **appid, char **trusted) {
368         char *query = nullptr;
369         query = sqlite3_mprintf(
370                         "SELECT app_id, trusted FROM package_app_data_control "
371                         "WHERE providerid=%Q AND type=%Q", providerid, type);
372         if (query == nullptr) {
373                 LOGE("Out of memory");
374                 return PMINFO_R_ERROR;
375         }
376
377         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
378                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
379           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
380           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
381         sqlite3_free(query);
382
383         pkgmgr_client::PkgInfoClient client(parcelable, uid,
384                         pkgmgr_common::ReqType::QUERY);
385         if (!client.SendRequest()) {
386                 return PMINFO_R_ERROR;
387         }
388
389         auto ptr = client.GetResultParcel();
390         if (ptr == nullptr) {
391                 LOG(ERROR) << "Fail to get return parcelable";
392                 return PMINFO_R_ERROR;
393         }
394
395         if (ptr->GetRequestResult() != PMINFO_R_OK) {
396                 LOG(ERROR) << "Request fail";
397                 return ptr->GetRequestResult();
398         }
399
400         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
401                 LOG(ERROR) << "Invalid parcelable type";
402                 return PMINFO_R_ERROR;
403         }
404
405         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
406                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
407                                         ptr));
408
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;
424                 }
425         }
426
427         return PMINFO_R_OK;
428 }
429
430 extern "C" EXPORT_API int _appinfo_get_datacontrol_privileges(
431                 const char *providerid, const char *type, uid_t uid,
432                 GList **privileges) {
433         char *query = nullptr;
434         query = sqlite3_mprintf(
435                         "SELECT privilege FROM package_app_data_control_privilege "
436                         "WHERE providerid=%Q AND type=%Q", providerid, type);
437         if (query == nullptr) {
438                 LOGE("Out of memory");
439                 return PMINFO_R_ERROR;
440         }
441
442         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
443                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
444           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
445           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
446         sqlite3_free(query);
447
448         pkgmgr_client::PkgInfoClient client(parcelable, uid,
449                         pkgmgr_common::ReqType::QUERY);
450         if (!client.SendRequest()) {
451                 return PMINFO_R_ERROR;
452         }
453
454         auto ptr = client.GetResultParcel();
455         if (ptr == nullptr) {
456                 LOG(ERROR) << "Fail to get return parcelable";
457                 return PMINFO_R_ERROR;
458         }
459
460         if (ptr->GetRequestResult() != PMINFO_R_OK) {
461                 LOG(ERROR) << "Request fail";
462                 return ptr->GetRequestResult();
463         }
464
465         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
466                 LOG(ERROR) << "Invalid parcelable type";
467                 return PMINFO_R_ERROR;
468         }
469
470         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
471                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
472                                         ptr));
473
474         // result_list is vector of string vector
475         auto result_list = return_parcel->GetResult();
476         if (result_list.size() == 0)
477                 return PMINFO_R_ENOENT;
478
479         for (auto result : result_list) {
480                 if (result.size() != 1)
481                         return PMINFO_R_ERROR;
482                 if (result.front().empty() || result.front().size() == 0)
483                         return PMINFO_R_ERROR;
484                 char *privilege = strdup(result.front().c_str());
485                 if (privilege == nullptr) {
486                         LOG(ERROR) << "Out of memory";
487                         return PMINFO_R_ERROR;
488                 }
489                 *privileges = g_list_append(*privileges, privilege);
490         }
491
492         return PMINFO_R_OK;
493 }
494
495 extern "C" EXPORT_API int _appinfo_get_appcontrol_privileges(
496                 const char *appid, const char *operation, uid_t uid, GList **privileges) {
497         char *query = nullptr;
498         query = sqlite3_mprintf(
499                 "SELECT app_control, privilege FROM package_app_app_control_privilege "
500                 "WHERE app_id=%Q", appid);
501         if (query == nullptr) {
502                 LOG(ERROR) << "Out of memory";
503                 return PMINFO_R_ERROR;
504         }
505
506         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
507                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
508           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
509           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
510         sqlite3_free(query);
511
512         pkgmgr_client::PkgInfoClient client(parcelable, uid,
513                         pkgmgr_common::ReqType::QUERY);
514         if (!client.SendRequest()) {
515                 return PMINFO_R_ERROR;
516         }
517
518         auto ptr = client.GetResultParcel();
519         if (ptr == nullptr) {
520                 LOG(ERROR) << "Fail to get return parcelable";
521                 return PMINFO_R_ERROR;
522         }
523
524         if (ptr->GetRequestResult() != PMINFO_R_OK) {
525                 LOG(ERROR) << "Request fail";
526                 return ptr->GetRequestResult();
527         }
528
529         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
530                 LOG(ERROR) << "Invalid parcelable type";
531                 return PMINFO_R_ERROR;
532         }
533
534         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
535                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
536                                         ptr));
537
538         // result_list is vector of string vector
539         auto result_list = return_parcel->GetResult();
540         if (result_list.size() == 0)
541                 return PMINFO_R_ENOENT;
542
543         for (auto result : result_list) {
544                 if (result.size() != 2)
545                         return PMINFO_R_ERROR;
546                 if (result.front().empty() || result.front().size() == 0 ||
547                                 result.back().empty() || result.back().size() == 0)
548                         return PMINFO_R_ERROR;
549                 std::string app_control = result.front();
550                 std::stringstream ss(app_control);
551                 std::string token;
552                 while (std::getline(ss, token, '|')) {
553                         if (token.compare(std::string(operation))) {
554                                 char *privilege = strdup(result.back().c_str());
555                                 if (privilege == nullptr) {
556                                         LOG(ERROR) << "Out of memory";
557                                         return PMINFO_R_ERROR;
558                                 }
559                                 *privileges = g_list_append(*privileges, privilege);
560                         }
561                 }
562         }
563         return PMINFO_R_OK;
564 }
565
566 extern "C" EXPORT_API int _plugininfo_get_appids(
567                 const char *pkgid, const char *plugin_type,
568                 const char *plugin_name, GList **list) {
569         if (!pkgid || !plugin_type || !plugin_name || !list) {
570                 LOG(ERROR) << "Invalid parameter";
571                 return PMINFO_R_EINVAL;
572         }
573
574         char *query = nullptr;
575         query = sqlite3_mprintf(
576                         "SELECT appid FROM "
577                         "package_plugin_info WHERE pkgid=%Q AND "
578                         "plugin_type=%Q AND plugin_name=%Q",
579       pkgid, plugin_type, plugin_name);
580         if (query == nullptr) {
581                 LOG(ERROR) << "Out of memory";
582                 return PMINFO_R_ERROR;
583         }
584
585         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
586                         new pkgmgr_common::parcel::QueryParcelable(_getuid(), std::string(query),
587           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
588           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
589         sqlite3_free(query);
590
591         pkgmgr_client::PkgInfoClient client(parcelable, _getuid(),
592                         pkgmgr_common::ReqType::QUERY);
593         if (!client.SendRequest()) {
594                 return PMINFO_R_ERROR;
595         }
596
597         auto ptr = client.GetResultParcel();
598         if (ptr == nullptr) {
599                 LOG(ERROR) << "Fail to get return parcelable";
600                 return PMINFO_R_ERROR;
601         }
602
603         if (ptr->GetRequestResult() != PMINFO_R_OK) {
604                 LOG(ERROR) << "Request fail";
605                 return ptr->GetRequestResult();
606         }
607
608         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
609                 LOG(ERROR) << "Invalid parcelable type";
610                 return PMINFO_R_ERROR;
611         }
612
613         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
614                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
615                                         ptr));
616
617   if (return_parcel->GetCol() != 1) {
618     LOG(ERROR) << "Invalid result";
619     return PMINFO_R_ERROR;
620   }
621         // result_list is vector of string vector
622         auto& result_list = return_parcel->GetResult();
623         if (result_list.size() == 0)
624                 return PMINFO_R_ENOENT;
625
626         for (auto result : result_list) {
627     if (result.size() != 1) {
628       LOG(ERROR) << "Invalid result";
629       g_list_free_full(*list, free);
630       return PMINFO_R_ERROR;
631     }
632     *list = g_list_append(*list, strdup(result[0].c_str()));
633   }
634
635   return PMINFO_R_OK;
636 }
637
638 static int __convert_update_type(const char *type, pkgmgrinfo_updateinfo_update_type *convert_type)
639 {
640         if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_NONE,
641                         strlen(PMINFO_UPDATEINFO_TYPE_NONE)) == 0)
642                 *convert_type = PMINFO_UPDATEINFO_NONE;
643         else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_FORCE,
644                         strlen(PMINFO_UPDATEINFO_TYPE_FORCE)) == 0)
645                 *convert_type = PMINFO_UPDATEINFO_FORCE;
646         else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_OPTIONAL,
647                         strlen(PMINFO_UPDATEINFO_TYPE_OPTIONAL)) == 0)
648                 *convert_type = PMINFO_UPDATEINFO_OPTIONAL;
649         else
650                 return -1;
651         return 0;
652 }
653
654 static void __free_update_info(gpointer data)
655 {
656         updateinfo_x *update_info = (updateinfo_x *)data;
657         if (update_info == nullptr)
658                 return;
659
660         if (update_info->pkgid)
661                 free((void *)update_info->pkgid);
662         if (update_info->version)
663                 free((void *)update_info->version);
664         free((void *)update_info);
665
666 }
667
668 extern "C" EXPORT_API int _get_pkg_updateinfo(const char *pkgid,
669                 GSList **update_info_list, uid_t uid)
670 {
671         char *query = nullptr;
672         int ret;
673
674         if (pkgid == nullptr)
675                 query = sqlite3_mprintf(
676                                                 "SELECT package, update_version, update_type "
677                                                 "FROM package_update_info");
678         else
679                 query = sqlite3_mprintf(
680                                                 "SELECT package, update_version, update_type "
681                                                 "FROM package_update_info WHERE package=%Q",
682                                                 pkgid);
683         if (query == nullptr) {
684                 LOG(ERROR) << "Out of memory";
685                 return PMINFO_R_ERROR;
686         }
687
688         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
689                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
690           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
691           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
692         sqlite3_free(query);
693
694         pkgmgr_client::PkgInfoClient client(parcelable, uid,
695                         pkgmgr_common::ReqType::QUERY);
696         if (!client.SendRequest()) {
697                 return PMINFO_R_ERROR;
698         }
699
700         auto ptr = client.GetResultParcel();
701         if (ptr == nullptr) {
702                 LOG(ERROR) << "Fail to get return parcelable";
703                 return PMINFO_R_ERROR;
704         }
705
706         if (ptr->GetRequestResult() != PMINFO_R_OK) {
707                 LOG(ERROR) << "Request fail";
708                 return ptr->GetRequestResult();
709         }
710
711         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
712                 LOG(ERROR) << "Invalid parcelable type";
713                 return PMINFO_R_ERROR;
714         }
715
716         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
717                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
718                                         ptr));
719
720   if (return_parcel->GetCol() != 3) {
721     LOG(ERROR) << "Invalid result";
722     return PMINFO_R_ERROR;
723   }
724
725         auto result_list = return_parcel->GetResult();
726         if (result_list.size() == 0)
727                 return PMINFO_R_ENOENT;
728
729         for (auto result : result_list) {
730     if (result.size() != 3) {
731       LOG(ERROR) << "Invalid result";
732       g_slist_free_full(*update_info_list, __free_update_info);
733       return PMINFO_R_ERROR;
734     }
735     updateinfo_x *update_info = reinterpret_cast<updateinfo_x *>(calloc(1, sizeof(updateinfo_x)));
736                 if (update_info == nullptr) {
737                         LOG(ERROR) << "Out of memory";
738                         return PMINFO_R_ERROR;
739                 }
740     update_info->pkgid = strdup(result[0].c_str());
741     update_info->version = strdup(result[1].c_str());
742           pkgmgrinfo_updateinfo_update_type convert_type;
743                 ret = __convert_update_type(result[2].c_str(), &convert_type);
744                 if (ret != 0) {
745                         __free_update_info(update_info);
746       g_slist_free_full(*update_info_list, __free_update_info);
747                         return PMINFO_R_ERROR;
748                 }
749                 update_info->type = static_cast<int>(convert_type);
750                 *update_info_list = g_slist_prepend(*update_info_list,
751                                 update_info);
752   }
753
754         return PMINFO_R_OK;
755 }
756
757 extern "C" EXPORT_API int _pkginfo_set_usr_installed_storage(const char *pkgid,
758                 INSTALL_LOCATION location, const char *external_pkg_path,
759                 uid_t uid)
760 {
761         char *query = nullptr;
762         const char *location_str;
763         std::vector<std::string> queries;
764
765         if (location == INSTALL_INTERNAL)
766                 location_str = "installed_internal";
767         else if (location == INSTALL_EXTERNAL)
768                 location_str = "installed_external";
769         else
770                 location_str = "installed_extended";
771         /* pkgcakge_info table */
772         query = sqlite3_mprintf(
773                         "update package_info set installed_storage=%Q, external_path=%Q where package=%Q",
774                         location_str, external_pkg_path, pkgid);
775         queries.emplace_back(query);
776         sqlite3_free(query);
777
778         /* package_app_info table */
779         query = sqlite3_mprintf(
780                         "update package_app_info set app_installed_storage=%Q, app_external_path=%Q where package=%Q",
781                         location_str, external_pkg_path, pkgid);
782         queries.emplace_back(query);
783         sqlite3_free(query);
784
785         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
786                         new pkgmgr_common::parcel::QueryParcelable(uid, queries,
787                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
788                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
789
790         pkgmgr_client::PkgInfoClient client(parcelable, uid,
791                         pkgmgr_common::ReqType::QUERY);
792         if (!client.SendRequest()) {
793                 return PMINFO_R_ERROR;
794         }
795
796         auto ptr = client.GetResultParcel();
797         if (ptr == nullptr) {
798                 LOG(ERROR) << "Fail to get return parcelable";
799                 return PMINFO_R_ERROR;
800         }
801
802         if (ptr->GetRequestResult() != PMINFO_R_OK) {
803                 LOG(ERROR) << "Request fail";
804                 return ptr->GetRequestResult();
805         }
806
807         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
808                 LOG(ERROR) << "Invalid parcelable type";
809                 return PMINFO_R_ERROR;
810         }
811
812         return PMINFO_R_OK;
813 }
814
815 extern "C" EXPORT_API int _certinfo_compare_pkg_certinfo(const char *l_pkgid,
816                 const char *r_pkgid, pkgmgrinfo_cert_compare_result_type_e *result) {
817         char *query = sqlite3_mprintf("SELECT package, "
818                         "COALESCE(author_signer_cert, -1) FROM package_cert_info WHERE "
819                         "package IN (%Q, %Q)", l_pkgid, r_pkgid);
820         if (query == nullptr) {
821                 LOG(ERROR) << "Out of memory";
822                 return PMINFO_R_ERROR;
823         }
824         std::vector<std::string> queries;
825         queries.emplace_back(query);
826         sqlite3_free(query);
827
828         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
829                 new pkgmgr_common::parcel::QueryParcelable(0, queries,
830                                 pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_CERTDB,
831                                 pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
832         pkgmgr_client::PkgInfoClient client(parcelable, 0,
833                         pkgmgr_common::ReqType::QUERY);
834         if (!client.SendRequest()) {
835                 return PMINFO_R_ERROR;
836         }
837
838         auto ptr = client.GetResultParcel();
839         if (ptr == nullptr) {
840                 LOG(ERROR) << "Fail to get return parcelable";
841                 return PMINFO_R_ERROR;
842         }
843
844         if (ptr->GetRequestResult() != PMINFO_R_OK) {
845                 LOG(ERROR) << "Request fail";
846                 return ptr->GetRequestResult();
847         }
848
849         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
850                 LOG(ERROR) << "Invalid parcelable type";
851                 return PMINFO_R_ERROR;
852         }
853
854         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
855                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
856                                         ptr));
857
858         auto certinfo_list = return_parcel->GetResult();
859         if (certinfo_list.size() != 2)
860                 return PMINFO_R_ERROR;
861
862         std::map<std::string, std::string> result_map;
863         for (auto& certinfo : certinfo_list)
864                 result_map.insert(make_pair(certinfo.front(), certinfo.back()));
865
866         if (result_map.find(std::string(l_pkgid))->second == "-1" &&
867                         result_map.find(std::string(r_pkgid))->second == "-1")
868                 *result = PMINFO_CERT_COMPARE_BOTH_NO_CERT;
869         else if (result_map.find(std::string(l_pkgid))->second == "-1")
870                 *result = PMINFO_CERT_COMPARE_LHS_NO_CERT;
871         else if (result_map.find(std::string(r_pkgid))->second == "-1")
872                 *result = PMINFO_CERT_COMPARE_RHS_NO_CERT;
873         else if (result_map.find(std::string(l_pkgid))->second ==
874                         result_map.find(std::string(r_pkgid))->second)
875                 *result = PMINFO_CERT_COMPARE_MATCH;
876         else
877                 *result = PMINFO_CERT_COMPARE_MISMATCH;
878
879         return PMINFO_R_OK;
880 }
881
882 extern "C" EXPORT_API int _certinfo_compare_app_certinfo(uid_t uid,
883                 const char *l_appid, const char *r_appid,
884                 pkgmgrinfo_cert_compare_result_type_e *result) {
885         char* query = sqlite3_mprintf("SELECT app_id, package FROM "
886                         "package_app_info WHERE app_id IN (%Q, %Q)", l_appid, r_appid);
887         if (query == nullptr) {
888                 LOG(ERROR) << "Out of memory";
889                 return PMINFO_R_ERROR;
890         }
891         std::vector<std::string> queries;
892         queries.emplace_back(query);
893         sqlite3_free(query);
894
895         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
896                 new pkgmgr_common::parcel::QueryParcelable(uid, queries,
897                                 pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
898                                 pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
899         pkgmgr_client::PkgInfoClient client(parcelable, uid,
900                         pkgmgr_common::ReqType::QUERY);
901         if (!client.SendRequest()) {
902                 return PMINFO_R_ERROR;
903         }
904
905         auto ptr = client.GetResultParcel();
906         if (ptr == nullptr) {
907                 LOG(ERROR) << "Fail to get return parcelable";
908                 return PMINFO_R_ERROR;
909         }
910
911         if (ptr->GetRequestResult() != PMINFO_R_OK) {
912                 LOG(ERROR) << "Request fail";
913                 return ptr->GetRequestResult();
914         }
915
916         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
917                 LOG(ERROR) << "Invalid parcelable type";
918                 return PMINFO_R_ERROR;
919         }
920
921         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
922                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
923                                         ptr));
924
925         auto pkgid_list = return_parcel->GetResult();
926         std::map<std::string, std::string> result_map;
927         for (auto& pkgid : pkgid_list)
928                 result_map.insert(make_pair(pkgid.front(), pkgid.back()));
929
930         if (result_map.find(std::string(l_appid)) == result_map.end()) {
931                 LOG(ERROR) << "Cannot find pkgid of app " << l_appid
932                                 << " for uid " << uid;
933                 return PMINFO_R_ENOENT;
934         } else if (result_map.find(std::string(r_appid)) == result_map.end()) {
935                 LOG(ERROR) << "Cannot find pkgid of app " << r_appid
936                                 << " for uid " << uid;
937                 return PMINFO_R_ENOENT;
938         }
939
940         const char* l_pkgid = result_map.find(
941                         std::string(l_appid))->second.c_str();
942         const char* r_pkgid = result_map.find(
943                         std::string(r_appid))->second.c_str();
944
945         return _certinfo_compare_pkg_certinfo(l_pkgid, r_pkgid, result);
946 }
947
948 extern "C" EXPORT_API int _parser_execute_write_query(const char *query, uid_t uid)
949 {
950         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
951                         new pkgmgr_common::parcel::QueryParcelable(uid, query,
952                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
953                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
954
955         pkgmgr_client::PkgInfoClient client(parcelable, uid,
956                         pkgmgr_common::ReqType::QUERY);
957         if (!client.SendRequest()) {
958                 return -1;
959         }
960
961         auto ptr = client.GetResultParcel();
962         if (ptr == nullptr) {
963                 LOG(ERROR) << "Fail to get return parcelable";
964                 return -1;
965         }
966
967         if (ptr->GetRequestResult() != PMINFO_R_OK) {
968                 LOG(ERROR) << "Request fail";
969                 return -1;
970         }
971
972         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
973                 LOG(ERROR) << "Invalid parcelable type";
974                 return -1;
975         }
976
977         return 0;
978 }
979
980 extern "C" EXPORT_API int _parser_execute_write_queries(const char **queries, int len, uid_t uid)
981 {
982         std::vector<std::string> query_vt;
983         for (int i = 0; i < len; ++i)
984                 query_vt.emplace_back(queries[i]);
985
986         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
987                         new pkgmgr_common::parcel::QueryParcelable(uid, query_vt,
988                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
989                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
990
991         pkgmgr_client::PkgInfoClient client(parcelable, uid,
992                         pkgmgr_common::ReqType::QUERY);
993         if (!client.SendRequest()) {
994                 return -1;
995         }
996
997         auto ptr = client.GetResultParcel();
998         if (ptr == nullptr) {
999                 LOG(ERROR) << "Fail to get return parcelable";
1000                 return -1;
1001         }
1002
1003         if (ptr->GetRequestResult() != PMINFO_R_OK) {
1004                 LOG(ERROR) << "Request fail";
1005                 return -1;
1006         }
1007
1008         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
1009                 LOG(ERROR) << "Invalid parcelable type";
1010                 return -1;
1011         }
1012
1013         return 0;
1014 }
1015
1016 extern "C" EXPORT_API int _parser_insert_manifest_info(manifest_x *mfx, uid_t uid)
1017 {
1018         std::vector<package_x *> vt { mfx };
1019
1020         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
1021                         new pkgmgr_common::parcel::PkgInfoParcelable(uid, std::move(vt), WriteType::Insert));
1022
1023         pkgmgr_client::PkgInfoClient client(parcelable, uid,
1024                         pkgmgr_common::ReqType::SET_PKG_INFO);
1025         if (!client.SendRequest()) {
1026                 return -1;
1027         }
1028
1029         auto ptr = client.GetResultParcel();
1030         if (ptr == nullptr) {
1031                 LOG(ERROR) << "Fail to get return parcelable";
1032                 return -1;
1033         }
1034
1035         if (ptr->GetRequestResult() != PMINFO_R_OK) {
1036                 LOG(ERROR) << "Request fail";
1037                 return -1;
1038         }
1039
1040         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
1041                 LOG(ERROR) << "Invalid parcelable type";
1042                 return -1;
1043         }
1044
1045         return 0;
1046 }
1047
1048 extern "C" EXPORT_API int _parser_update_manifest_info(manifest_x *mfx, uid_t uid)
1049 {
1050         std::vector<package_x *> vt { mfx };
1051
1052         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
1053                         new pkgmgr_common::parcel::PkgInfoParcelable(uid, std::move(vt), WriteType::Update));
1054
1055         pkgmgr_client::PkgInfoClient client(parcelable, uid,
1056                         pkgmgr_common::ReqType::SET_PKG_INFO);
1057         if (!client.SendRequest()) {
1058                 return -1;
1059         }
1060
1061         auto ptr = client.GetResultParcel();
1062         if (ptr == nullptr) {
1063                 LOG(ERROR) << "Fail to get return parcelable";
1064                 return -1;
1065         }
1066
1067         if (ptr->GetRequestResult() != PMINFO_R_OK) {
1068                 LOG(ERROR) << "Request fail";
1069                 return -1;
1070         }
1071
1072         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
1073                 LOG(ERROR) << "Invalid parcelable type";
1074                 return -1;
1075         }
1076
1077         return 0;
1078 }
1079
1080 extern "C" EXPORT_API int _parser_delete_manifest_info(manifest_x *mfx, uid_t uid)
1081 {
1082         std::vector<package_x *> vt { mfx };
1083
1084         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
1085                         new pkgmgr_common::parcel::PkgInfoParcelable(uid, std::move(vt), WriteType::Delete));
1086
1087         pkgmgr_client::PkgInfoClient client(parcelable, uid,
1088                         pkgmgr_common::ReqType::SET_PKG_INFO);
1089         if (!client.SendRequest()) {
1090                 return -1;
1091         }
1092
1093         auto ptr = client.GetResultParcel();
1094         if (ptr == nullptr) {
1095                 LOG(ERROR) << "Fail to get return parcelable";
1096                 return -1;
1097         }
1098
1099         if (ptr->GetRequestResult() != PMINFO_R_OK) {
1100                 LOG(ERROR) << "Request fail";
1101                 return -1;
1102         }
1103
1104         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
1105                 LOG(ERROR) << "Invalid parcelable type";
1106                 return -1;
1107         }
1108
1109         return 0;
1110 }
1111
1112 extern "C" EXPORT_API int _pkginfo_insert_certinfo(const char* pkgid,
1113                 pkgmgr_certinfo_x* cert, uid_t uid)
1114 {
1115         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
1116                         new pkgmgr_common::parcel::CertInfoParcelable(uid, cert));
1117
1118         pkgmgr_client::PkgInfoClient client(parcelable, uid,
1119                         pkgmgr_common::ReqType::SET_CERT_INFO);
1120         if (!client.SendRequest())
1121         return PMINFO_R_ERROR;
1122
1123         auto ptr = client.GetResultParcel();
1124         if (ptr == nullptr) {
1125                 LOG(ERROR) << "Fail to get return parcelable";
1126                 return PMINFO_R_ERROR;
1127         }
1128
1129         if (ptr->GetRequestResult() != PMINFO_R_OK) {
1130                 LOG(ERROR) << "Request fail";
1131                 return ptr->GetRequestResult();
1132         }
1133
1134         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
1135                 LOG(ERROR) << "Invalid parcelable type";
1136                 return PMINFO_R_ERROR;
1137         }
1138
1139         return PMINFO_R_OK;
1140 }
1141
1142 extern "C" EXPORT_API int _pkginfo_get_certinfo(const char *pkgid,
1143                 pkgmgr_certinfo_x** cert, uid_t uid)
1144 {
1145         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
1146                         new pkgmgr_common::parcel::CertInfoParcelable(uid,
1147                                         std::string(pkgid)));
1148
1149         pkgmgr_client::PkgInfoClient client(parcelable, uid,
1150                         pkgmgr_common::ReqType::GET_CERT_INFO);
1151         if (!client.SendRequest())
1152         return PMINFO_R_ERROR;
1153
1154         auto ptr = client.GetResultParcel();
1155         if (ptr == nullptr) {
1156                 LOG(ERROR) << "Fail to get return parcelable";
1157                 return PMINFO_R_ERROR;
1158         }
1159
1160         if (ptr->GetRequestResult() != PMINFO_R_OK) {
1161                 LOG(ERROR) << "Request fail";
1162                 return ptr->GetRequestResult();
1163         }
1164
1165         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::CertInfo) {
1166                 LOG(ERROR) << "Invalid parcelable type";
1167                 return PMINFO_R_ERROR;
1168         }
1169
1170         std::shared_ptr<pkgmgr_common::parcel::CertInfoParcelable> return_parcel(
1171                 std::static_pointer_cast<pkgmgr_common::parcel::CertInfoParcelable>(
1172                                 ptr));
1173
1174         auto certinfo = return_parcel->GetCertInfo();
1175         if (certinfo == nullptr)
1176                 return PMINFO_R_ERROR;
1177
1178         *cert = (pkgmgr_certinfo_x*)certinfo;
1179         return PMINFO_R_OK;
1180 }
1181
1182 extern "C" EXPORT_API int _pkginfo_delete_certinfo(const char *pkgid)
1183 {
1184         char* query = sqlite3_mprintf("UPDATE package_cert_info SET "
1185                         "package_count = package_count - 1 WHERE package=%Q", pkgid);
1186         if (query == nullptr) {
1187                 LOG(ERROR) << "Out of memory";
1188                 return PMINFO_R_ERROR;
1189         }
1190
1191         std::vector<std::string> queries;
1192         queries.emplace_back(query);
1193         sqlite3_free(query);
1194
1195         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
1196                         new pkgmgr_common::parcel::QueryParcelable(0, queries,
1197                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_CERTDB,
1198                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
1199
1200         pkgmgr_client::PkgInfoClient client(parcelable, 0,
1201                         pkgmgr_common::ReqType::QUERY);
1202         if (!client.SendRequest()) {
1203                 return PMINFO_R_ERROR;
1204         }
1205
1206         auto ptr = client.GetResultParcel();
1207         if (ptr == nullptr) {
1208                 LOG(ERROR) << "Fail to get return parcelable";
1209                 return PMINFO_R_ERROR;
1210         }
1211
1212         if (ptr->GetRequestResult() != PMINFO_R_OK) {
1213                 LOG(ERROR) << "Request fail";
1214                 return PMINFO_R_ERROR;
1215         }
1216
1217         if (ptr->GetType() != pkgmgr_common::parcel::ParcelableType::Result) {
1218                 LOG(ERROR) << "Invalid parcelable type";
1219                 return PMINFO_R_ERROR;
1220         }
1221
1222         return PMINFO_R_OK;
1223 }