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