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