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