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