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