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