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