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