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