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