Implement compare cert API using server-client architecture
[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 <map>
22 #include <string>
23
24 #include "sqlite3.h"
25 #include "glib.h"
26
27 #include "pkgmgrinfo_private.h"
28
29 #include "logging.hh"
30 #include "common/database/abstract_db_handler.hh"
31 #include "common/database/pkg_set_db_handler.hh"
32 #include "common/parcel/appinfo_parcelable.hh"
33 #include "common/parcel/certinfo_parcelable.hh"
34 #include "common/parcel/depinfo_parcelable.hh"
35 #include "common/parcel/filter_parcelable.hh"
36 #include "common/parcel/pkginfo_parcelable.hh"
37 #include "common/parcel/query_parcelable.hh"
38 #include "common/parcel/result_parcelable.hh"
39
40 #include "client/pkginfo_client.hh"
41
42 #include <parcel.hh>
43
44 #ifdef LOG_TAG
45 #undef LOG_TAG
46 #endif
47 #define LOG_TAG "PKGMGR_INFO"
48
49 #ifdef EXPORT_API
50 #undef EXPORT_API
51 #endif
52 #define EXPORT_API __attribute__((visibility("default")))
53
54 extern "C" EXPORT_API int _pkginfo_get_packages(uid_t uid,
55             pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
56         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
57                         new pkgmgr_common::parcel::FilterParcelable(uid,
58                                         static_cast<pkgmgrinfo_filter_x*>(filter), flag));
59
60         pkgmgr_client::PkgInfoClient client(parcelable, uid,
61                         pkgmgr_common::ReqType::GET_PKG_INFO);
62         if (!client.SendRequest())
63       return PMINFO_R_ERROR;
64
65         std::shared_ptr<pkgmgr_common::parcel::PkgInfoParcelable> return_parcel(
66                         std::static_pointer_cast<pkgmgr_common::parcel::PkgInfoParcelable>(
67                                         client.GetResultParcel()));
68
69         tizen_base::Parcel parcel;
70         parcel.ReadParcelable(return_parcel.get());
71
72         auto result_list = return_parcel->GetPkgInfo();
73         // TODO: check noentry error has returned if size of result_list is 0
74         for (auto& pkginfo : result_list)
75                 g_hash_table_insert(packages, (gpointer)pkginfo->package,
76                                 (gpointer)pkginfo);
77
78         return PMINFO_R_OK;
79 }
80
81 extern "C" EXPORT_API int _pkginfo_get_depends_on(uid_t uid,
82                 const char *pkgid, GList **dependencies) {
83         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
84                         new pkgmgr_common::parcel::DepInfoParcelable(std::string(pkgid)));
85
86         pkgmgr_client::PkgInfoClient client(parcelable, uid,
87                         pkgmgr_common::ReqType::GET_PKG_DEP_INFO);
88         if (!client.SendRequest())
89       return PMINFO_R_ERROR;
90
91         std::shared_ptr<pkgmgr_common::parcel::DepInfoParcelable> return_parcel(
92                         std::static_pointer_cast<pkgmgr_common::parcel::DepInfoParcelable>(
93                                         client.GetResultParcel()));
94
95         tizen_base::Parcel parcel;
96         parcel.ReadParcelable(return_parcel.get());
97
98         auto dependency_list = return_parcel->GetDependencyInfo();
99         for (auto& dependency : dependency_list)
100                 *dependencies = g_list_prepend(*dependencies, dependency);
101         return PMINFO_R_OK;
102 }
103
104 // TODO: Need to add target db uid to identify which database to be searched
105 extern "C" EXPORT_API int _appinfo_get_applications(uid_t db_uid, uid_t uid,
106                 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
107         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
108                         new pkgmgr_common::parcel::FilterParcelable(uid,
109                                         static_cast<pkgmgrinfo_filter_x*>(filter), flag));
110
111         pkgmgr_client::PkgInfoClient client(parcelable, uid, pkgmgr_common::ReqType::GET_APP_INFO);
112         if (!client.SendRequest())
113       return PMINFO_R_ERROR;
114
115         std::shared_ptr<pkgmgr_common::parcel::AppInfoParcelable> return_parcel(
116                         std::static_pointer_cast<pkgmgr_common::parcel::AppInfoParcelable>(
117                                         client.GetResultParcel()));
118
119         tizen_base::Parcel parcel;
120         parcel.ReadParcelable(return_parcel.get());
121         auto result_list = return_parcel->GetAppInfo();
122         for (auto& appinfo : result_list)
123                 g_hash_table_insert(packages, (gpointer)appinfo->appid,
124                                 (gpointer)appinfo);
125
126         return PMINFO_R_OK;
127 }
128
129 extern "C" EXPORT_API char *_appinfo_get_localed_label(
130                 const char *appid, const char *locale, uid_t uid) {
131         char *query = nullptr;
132     query = sqlite3_mprintf(
133                         "SELECT COALESCE((SELECT app_label FROM package_app_localized_info "
134                         "WHERE app_id=%Q AND app_locale=%Q),"
135                         "(SELECT app_label FROM package_app_localized_info WHERE "
136                         "app_id=%Q AND app_locale='No Locale'))", appid, locale, appid);
137         if (query == nullptr) {
138                 LOG(ERROR) << "Out of memory";
139                 return nullptr;
140         }
141
142         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
143                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
144           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
145           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
146
147         pkgmgr_client::PkgInfoClient client(parcelable, uid,
148                         pkgmgr_common::ReqType::QUERY);
149         if (!client.SendRequest()) {
150                 sqlite3_free(query);
151                 return nullptr;
152         }
153
154         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
155                                 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
156                                                 client.GetResultParcel()));
157         tizen_base::Parcel parcel;
158         parcel.ReadParcelable(return_parcel.get());
159         sqlite3_free(query);
160         // result_list is vector of string vector
161         char *label = nullptr;
162         auto result_list = return_parcel->GetResult();
163         for (auto result : result_list) {
164                 // result is string vector
165                 // it only has one string or not.
166                 if (result.front().empty() || result.front().length() == 0)
167                         return nullptr;
168                 label = strdup(result.front().c_str());
169                 if (label == nullptr) {
170                         LOG(ERROR) << "Out of memory";
171                         return nullptr;
172                 }
173                 return label;
174         }
175
176         return label;
177 }
178
179 extern "C" EXPORT_API int _appinfo_get_datacontrol_info(
180                 const char *providerid, const char *type, uid_t uid,
181                 char **appid, char **access) {
182         char *query = nullptr;
183         query = sqlite3_mprintf("SELECT app_id, access FROM "
184                         "package_app_data_control WHERE "
185                         "providerid=%Q AND type=%Q", providerid, type);
186         if (query == nullptr) {
187                 LOG(ERROR) << "Out of memory";
188                 return PMINFO_R_ERROR;
189         }
190
191         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
192                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
193           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
194           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
195
196         pkgmgr_client::PkgInfoClient client(parcelable, uid,
197                         pkgmgr_common::ReqType::QUERY);
198         if (!client.SendRequest()) {
199                 sqlite3_free(query);
200                 return PMINFO_R_ERROR;
201         }
202
203         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
204                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
205                                         client.GetResultParcel()));
206         tizen_base::Parcel parcel;
207         parcel.ReadParcelable(return_parcel.get());
208         sqlite3_free(query);
209         // result_list is vector of string vector
210         auto result_list = return_parcel->GetResult();
211         if (result_list.size() == 0)
212                 return PMINFO_R_ENOENT;
213         for (auto result : result_list) {
214                 if (result.size() != 2)
215                         return PMINFO_R_ERROR;
216                 if (result.front().empty() || result.front().size() == 0 ||
217                                 result.back().empty() || result.back().size() == 0)
218                         return PMINFO_R_ERROR;
219                 *appid = strdup(result.front().c_str());
220                 *access = strdup(result.back().c_str());
221                 if (*appid == nullptr || *access == nullptr) {
222                         LOG(ERROR) << "Out of memory";
223                         return PMINFO_R_ERROR;
224                 }
225         }
226
227         return PMINFO_R_OK;
228 }
229
230 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
231                 const char *providerid, uid_t uid, char **appid) {
232         char *query = nullptr;
233
234         query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
235                 "WHERE providerid=%Q", providerid);
236         if (query == nullptr) {
237                 LOGE("Out of memory");
238                 return PMINFO_R_ERROR;
239         }
240         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
241                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
242           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
243           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
244
245         pkgmgr_client::PkgInfoClient client(parcelable, uid,
246                         pkgmgr_common::ReqType::QUERY);
247         if (!client.SendRequest()) {
248                 sqlite3_free(query);
249                 return PMINFO_R_ERROR;
250         }
251         // TODO: deliver rawdata to reqhandler directly if server is not working
252
253         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
254                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
255                                         client.GetResultParcel()));
256         tizen_base::Parcel parcel;
257         parcel.ReadParcelable(return_parcel.get());
258         sqlite3_free(query);
259
260         // result_list is vector of string vector
261         auto result_list = return_parcel->GetResult();
262         if (result_list.size() == 0)
263                 return PMINFO_R_ENOENT;
264         for (auto result : result_list) {
265                 if (result.size() != 1)
266                         return PMINFO_R_ERROR;
267                 if (result.front().empty() || result.front().size() == 0)
268                         return PMINFO_R_ERROR;
269                 *appid = strdup(result.front().c_str());
270                 if (*appid == nullptr) {
271                         LOG(ERROR) << "Out of memory";
272                         return PMINFO_R_ERROR;
273                 }
274         }
275
276         return PMINFO_R_OK;
277 }
278
279 extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
280                 const char *providerid, const char *type, uid_t uid,
281                 char **appid, char **trusted) {
282         char *query = nullptr;
283         query = sqlite3_mprintf(
284                         "SELECT app_id, trusted FROM package_app_data_control "
285                         "WHERE providerid=%Q AND type=%Q", providerid, type);
286         if (query == nullptr) {
287                 LOGE("Out of memory");
288                 return PMINFO_R_ERROR;
289         }
290
291         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
292                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
293           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
294           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
295
296         pkgmgr_client::PkgInfoClient client(parcelable, uid,
297                         pkgmgr_common::ReqType::QUERY);
298         if (!client.SendRequest()) {
299                 sqlite3_free(query);
300                 return PMINFO_R_ERROR;
301         }
302         // TODO: deliver rawdata to reqhandler directly if server is not working
303
304         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
305                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
306                                         client.GetResultParcel()));
307         tizen_base::Parcel parcel;
308         parcel.ReadParcelable(return_parcel.get());
309         sqlite3_free(query);
310         // result_list is vector of string vector
311         auto result_list = return_parcel->GetResult();
312         if (result_list.size() == 0)
313                 return PMINFO_R_ENOENT;
314         for (auto result : result_list) {
315                 if (result.size() != 2)
316                         return PMINFO_R_ERROR;
317                 if (result.front().empty() || result.front().size() == 0 ||
318                                 result.back().empty() || result.back().size() == 0)
319                         return PMINFO_R_ERROR;
320                 *appid = strdup(result.front().c_str());
321                 *trusted = strdup(result.back().c_str());
322                 if (*appid == nullptr || *trusted == nullptr) {
323                         LOG(ERROR) << "Out of memory";
324                         return PMINFO_R_ERROR;
325                 }
326         }
327
328         return PMINFO_R_OK;
329 }
330
331 extern "C" EXPORT_API int _appinfo_get_datacontrol_privileges(
332                 const char *providerid, const char *type, uid_t uid,
333                 GList **privileges) {
334         char *query = nullptr;
335         query = sqlite3_mprintf(
336                         "SELECT privilege FROM package_app_data_control_privilege "
337                         "WHERE providerid=%Q AND type=%Q", providerid, type);
338         if (query == nullptr) {
339                 LOGE("Out of memory");
340                 return PMINFO_R_ERROR;
341         }
342
343         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
344                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
345           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
346           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
347
348         pkgmgr_client::PkgInfoClient client(parcelable, uid,
349                         pkgmgr_common::ReqType::QUERY);
350         if (!client.SendRequest()) {
351                 sqlite3_free(query);
352                 return PMINFO_R_ERROR;
353         }
354         // TODO: deliver rawdata to reqhandler directly if server is not working
355
356         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
357                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
358                                         client.GetResultParcel()));
359         tizen_base::Parcel parcel;
360         parcel.ReadParcelable(return_parcel.get());
361         sqlite3_free(query);
362         // result_list is vector of string vector
363         auto result_list = return_parcel->GetResult();
364         if (result_list.size() == 0)
365                 return PMINFO_R_ENOENT;
366
367         for (auto result : result_list) {
368                 if (result.size() != 1)
369                         return PMINFO_R_ERROR;
370                 if (result.front().empty() || result.front().size() == 0)
371                         return PMINFO_R_ERROR;
372                 char *privilege = strdup(result.front().c_str());
373                 if (privilege == nullptr) {
374                         LOG(ERROR) << "Out of memory";
375                         return PMINFO_R_ERROR;
376                 }
377                 *privileges = g_list_append(*privileges, privilege);
378         }
379
380         return PMINFO_R_OK;
381 }
382
383 extern "C" EXPORT_API int _appinfo_get_appcontrol_privileges(
384                 const char *appid, const char *operation, uid_t uid, GList **privileges) {
385         char *query = nullptr;
386         query = sqlite3_mprintf(
387                 "SELECT app_control, privilege FROM package_app_app_control_privilege "
388                 "WHERE app_id=%Q", appid);
389         if (query == nullptr) {
390                 LOG(ERROR) << "Out of memory";
391                 return PMINFO_R_ERROR;
392         }
393
394         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
395                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
396           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
397           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
398
399         pkgmgr_client::PkgInfoClient client(parcelable, uid,
400                         pkgmgr_common::ReqType::QUERY);
401         if (!client.SendRequest()) {
402                 sqlite3_free(query);
403                 return PMINFO_R_ERROR;
404         }
405         // TODO: deliver rawdata to reqhandler directly if server is not working
406
407         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
408                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
409                                         client.GetResultParcel()));
410         tizen_base::Parcel parcel;
411         parcel.ReadParcelable(return_parcel.get());
412         sqlite3_free(query);
413         // result_list is vector of string vector
414         auto result_list = return_parcel->GetResult();
415         if (result_list.size() == 0)
416                 return PMINFO_R_ENOENT;
417
418         for (auto result : result_list) {
419                 if (result.size() != 2)
420                         return PMINFO_R_ERROR;
421                 if (result.front().empty() || result.front().size() == 0 ||
422                                 result.back().empty() || result.back().size() == 0)
423                         return PMINFO_R_ERROR;
424                 std::string app_control = result.front();
425                 std::stringstream ss(app_control);
426                 std::string token;
427                 while (std::getline(ss, token, '|')) {
428                         if (token.compare(std::string(operation))) {
429                                 char *privilege = strdup(result.back().c_str());
430                                 if (privilege == nullptr) {
431                                         LOG(ERROR) << "Out of memory";
432                                         return PMINFO_R_ERROR;
433                                 }
434                                 *privileges = g_list_append(*privileges, privilege);
435                         }
436                 }
437         }
438         return PMINFO_R_OK;
439 }
440
441 extern "C" EXPORT_API int _plugininfo_get_appids(
442                 const char *pkgid, const char *plugin_type,
443                 const char *plugin_name, GList **list) {
444         if (!pkgid || !plugin_type || !plugin_name || !list) {
445                 LOG(ERROR) << "Invalid parameter";
446                 return PMINFO_R_EINVAL;
447         }
448
449         char *query = nullptr;
450         query = sqlite3_mprintf(
451                         "SELECT appid FROM "
452                         "package_plugin_info WHERE pkgid=%Q AND "
453                         "plugin_type=%Q AND plugin_name=%Q",
454       pkgid, plugin_type, plugin_name);
455         if (query == nullptr) {
456                 LOG(ERROR) << "Out of memory";
457                 return PMINFO_R_ERROR;
458         }
459
460         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
461                         new pkgmgr_common::parcel::QueryParcelable(_getuid(), std::string(query),
462           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
463           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
464         sqlite3_free(query);
465
466         pkgmgr_client::PkgInfoClient client(parcelable, _getuid(),
467                         pkgmgr_common::ReqType::QUERY);
468         if (!client.SendRequest()) {
469                 return PMINFO_R_ERROR;
470         }
471
472         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
473                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
474                                         client.GetResultParcel()));
475   if (return_parcel->GetCol() != 1) {
476     LOG(ERROR) << "Invalid result";
477     return PMINFO_R_ERROR;
478   }
479         // result_list is vector of string vector
480         auto& result_list = return_parcel->GetResult();
481         if (result_list.size() == 0)
482                 return PMINFO_R_ENOENT;
483
484         for (auto result : result_list) {
485     if (result.size() != 1) {
486       LOG(ERROR) << "Invalid result";
487       g_list_free_full(*list, free);
488       return PMINFO_R_ERROR;
489     }
490     *list = g_list_append(*list, strdup(result[0].c_str()));
491   }
492
493   return PMINFO_R_OK;
494 }
495
496 static int __convert_update_type(const char *type, pkgmgrinfo_updateinfo_update_type *convert_type)
497 {
498         if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_NONE,
499                         strlen(PMINFO_UPDATEINFO_TYPE_NONE)) == 0)
500                 *convert_type = PMINFO_UPDATEINFO_NONE;
501         else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_FORCE,
502                         strlen(PMINFO_UPDATEINFO_TYPE_FORCE)) == 0)
503                 *convert_type = PMINFO_UPDATEINFO_FORCE;
504         else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_OPTIONAL,
505                         strlen(PMINFO_UPDATEINFO_TYPE_OPTIONAL)) == 0)
506                 *convert_type = PMINFO_UPDATEINFO_OPTIONAL;
507         else
508                 return -1;
509         return 0;
510 }
511
512 static void __free_update_info(gpointer data)
513 {
514         updateinfo_x *update_info = (updateinfo_x *)data;
515         if (update_info == nullptr)
516                 return;
517
518         if (update_info->pkgid)
519                 free((void *)update_info->pkgid);
520         if (update_info->version)
521                 free((void *)update_info->version);
522         free((void *)update_info);
523
524 }
525
526 extern "C" EXPORT_API int _get_pkg_updateinfo(const char *pkgid,
527                 GSList **update_info_list, uid_t uid)
528 {
529         char *query = nullptr;
530         int ret;
531
532         if (pkgid == nullptr)
533                 query = sqlite3_mprintf(
534                                                 "SELECT package, update_version, update_type "
535                                                 "FROM package_update_info");
536         else
537                 query = sqlite3_mprintf(
538                                                 "SELECT package, update_version, update_type "
539                                                 "FROM package_update_info WHERE package=%Q",
540                                                 pkgid);
541         if (query == nullptr) {
542                 LOG(ERROR) << "Out of memory";
543                 return PMINFO_R_ERROR;
544         }
545
546         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
547                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
548           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
549           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
550         sqlite3_free(query);
551
552         pkgmgr_client::PkgInfoClient client(parcelable, uid,
553                         pkgmgr_common::ReqType::QUERY);
554         if (!client.SendRequest()) {
555                 return PMINFO_R_ERROR;
556         }
557
558         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
559                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
560                                         client.GetResultParcel()));
561   if (return_parcel->GetCol() != 3) {
562     LOG(ERROR) << "Invalid result";
563     return PMINFO_R_ERROR;
564   }
565
566         auto result_list = return_parcel->GetResult();
567         if (result_list.size() == 0)
568                 return PMINFO_R_ENOENT;
569
570         for (auto result : result_list) {
571     if (result.size() != 3) {
572       LOG(ERROR) << "Invalid result";
573       g_slist_free_full(*update_info_list, __free_update_info);
574       return PMINFO_R_ERROR;
575     }
576     updateinfo_x *update_info = reinterpret_cast<updateinfo_x *>(calloc(1, sizeof(updateinfo_x)));
577                 if (update_info == nullptr) {
578                         LOG(ERROR) << "Out of memory";
579                         return PMINFO_R_ERROR;
580                 }
581     update_info->pkgid = strdup(result[0].c_str());
582     update_info->version = strdup(result[1].c_str());
583           pkgmgrinfo_updateinfo_update_type convert_type;
584                 ret = __convert_update_type(result[2].c_str(), &convert_type);
585                 if (ret != 0) {
586                         __free_update_info(update_info);
587       g_slist_free_full(*update_info_list, __free_update_info);
588                         return PMINFO_R_ERROR;
589                 }
590                 update_info->type = static_cast<int>(convert_type);
591                 *update_info_list = g_slist_prepend(*update_info_list,
592                                 update_info);
593   }
594
595         return PMINFO_R_OK;
596 }
597
598 extern "C" EXPORT_API int _pkginfo_set_usr_installed_storage(const char *pkgid,
599                 INSTALL_LOCATION location, const char *external_pkg_path,
600                 uid_t uid)
601 {
602         char *query = nullptr;
603         const char *location_str;
604         std::vector<std::string> queries;
605
606         if (location == INSTALL_INTERNAL)
607                 location_str = "installed_internal";
608         else if (location == INSTALL_EXTERNAL)
609                 location_str = "installed_external";
610         else
611                 location_str = "installed_extended";
612         /* pkgcakge_info table */
613         query = sqlite3_mprintf(
614                         "update package_info set installed_storage=%Q, external_path=%Q where package=%Q",
615                         location_str, external_pkg_path, pkgid);
616         queries.emplace_back(query);
617         sqlite3_free(query);
618
619         /* package_app_info table */
620         query = sqlite3_mprintf(
621                         "update package_app_info set app_installed_storage=%Q, app_external_path=%Q where package=%Q",
622                         location_str, external_pkg_path, pkgid);
623         queries.emplace_back(query);
624         sqlite3_free(query);
625
626         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
627                         new pkgmgr_common::parcel::QueryParcelable(uid, queries,
628                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
629                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
630
631         pkgmgr_client::PkgInfoClient client(parcelable, uid,
632                         pkgmgr_common::ReqType::QUERY);
633         if (!client.SendRequest()) {
634                 return PMINFO_R_ERROR;
635         }
636
637         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
638                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
639                                         client.GetResultParcel()));
640
641         auto result_list = return_parcel->GetResult();
642         if (result_list.size() != 1) {
643                 LOG(ERROR) << "Invalid result";
644                 return PMINFO_R_ERROR;
645         }
646
647         if (result_list[0].size() != 1) {
648                 LOG(ERROR) << "Invalid result";
649                 return PMINFO_R_ERROR;
650         }
651
652         LOG(ERROR) << "result : " << result_list[0][0];
653         if (result_list[0][0] != "SUCCESS")
654                 return PMINFO_R_ERROR;
655
656         return PMINFO_R_OK;
657 }
658
659 extern "C" EXPORT_API int _certinfo_compare_certinfo(const char *l_pkgid,
660                 const char *r_pkgid, pkgmgrinfo_cert_compare_result_type_e *result) {
661         char *query = sqlite3_mprintf("SELECT package, "
662                         "COALESCE(author_signer_cert, -1) FROM package_cert_info WHERE "
663                         "package IN (%Q, %Q)");
664         if (query == nullptr) {
665                 LOG(ERROR) << "Out of memory";
666                 return PMINFO_R_ERROR;
667         }
668         std::vector<std::string> queries;
669         queries.emplace_back(query);
670         sqlite3_free(query);
671
672         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
673                 new pkgmgr_common::parcel::QueryParcelable(0, queries,
674                                 pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_CERTDB,
675                                 pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
676         pkgmgr_client::PkgInfoClient client(parcelable, 0,
677                         pkgmgr_common::ReqType::QUERY);
678         if (!client.SendRequest()) {
679                 return PMINFO_R_ERROR;
680         }
681
682         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
683                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
684                                         client.GetResultParcel()));
685
686         auto certinfo_list = return_parcel->GetResult();
687         if (certinfo_list.size() != 2)
688                 return PMINFO_R_ERROR;
689
690         std::map<std::string, std::string> result_map;
691         for (auto& certinfo : certinfo_list)
692                 result_map.insert(make_pair(certinfo.front(), certinfo.back()));
693
694         if (result_map.find(std::string(l_pkgid))->second == "-1" &&
695                         result_map.find(std::string(r_pkgid))->second == "-1")
696                 *result = PMINFO_CERT_COMPARE_BOTH_NO_CERT;
697         else if (result_map.find(std::string(l_pkgid))->second == "-1")
698                 *result = PMINFO_CERT_COMPARE_LHS_NO_CERT;
699         else if (result_map.find(std::string(r_pkgid))->second == "-1")
700                 *result = PMINFO_CERT_COMPARE_RHS_NO_CERT;
701         else if (result_map.find(std::string(l_pkgid))->second ==
702                         result_map.find(std::string(r_pkgid))->second)
703                 *result = PMINFO_CERT_COMPARE_MATCH;
704         else
705                 *result = PMINFO_CERT_COMPARE_MISMATCH;
706
707 /*
708         auto cert_list = return_parcel->GetResult();
709         for (auto& cert : cert_list) {
710
711         }
712 */
713         return PMINFO_R_OK;
714 }
715
716 extern "C" EXPORT_API int _parser_execute_write_query(const char *query, uid_t uid)
717 {
718         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
719                         new pkgmgr_common::parcel::QueryParcelable(uid, query,
720                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
721                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
722
723         pkgmgr_client::PkgInfoClient client(parcelable, uid,
724                         pkgmgr_common::ReqType::QUERY);
725         if (!client.SendRequest()) {
726                 return -1;
727         }
728
729         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
730                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
731                                         client.GetResultParcel()));
732
733         auto result_list = return_parcel->GetResult();
734         if (result_list.size() != 1) {
735                 LOG(ERROR) << "Invalid result";
736                 return -1;
737         }
738
739         if (result_list[0].size() != 1) {
740                 LOG(ERROR) << "Invalid result";
741                 return -1;
742         }
743
744         LOG(ERROR) << "result : " << result_list[0][0];
745         if (result_list[0][0] != "SUCCESS")
746                 return -1;
747
748         return 0;
749 }
750
751 extern "C" EXPORT_API int _parser_execute_write_queries(const char **queries, int len, uid_t uid)
752 {
753         std::vector<std::string> query_vt;
754         for (int i = 0; i < len; ++i)
755                 query_vt.emplace_back(queries[i]);
756
757         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
758                         new pkgmgr_common::parcel::QueryParcelable(uid, query_vt,
759                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
760                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
761
762         pkgmgr_client::PkgInfoClient client(parcelable, uid,
763                         pkgmgr_common::ReqType::QUERY);
764         if (!client.SendRequest()) {
765                 return -1;
766         }
767
768         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
769                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
770                                         client.GetResultParcel()));
771
772         auto result_list = return_parcel->GetResult();
773         if (result_list.size() != 1) {
774                 LOG(ERROR) << "Invalid result";
775                 return -1;
776         }
777
778         if (result_list[0].size() != 1) {
779                 LOG(ERROR) << "Invalid result";
780                 return -1;
781         }
782
783         LOG(ERROR) << "result : " << result_list[0][0];
784         if (result_list[0][0] != "SUCCESS")
785                 return -1;
786
787         return 0;
788 }
789
790 extern "C" EXPORT_API int _parser_insert_manifest_info(manifest_x *mfx, uid_t uid)
791 {
792         std::vector<package_x *> vt { mfx };
793
794         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
795                         new pkgmgr_common::parcel::PkgInfoParcelable(uid, std::move(vt), WriteType::Insert));
796
797         pkgmgr_client::PkgInfoClient client(parcelable, uid,
798                         pkgmgr_common::ReqType::SET_PKG_INFO);
799         if (!client.SendRequest()) {
800                 return -1;
801         }
802
803         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
804                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
805                                         client.GetResultParcel()));
806
807         auto result_list = return_parcel->GetResult();
808         if (result_list.size() != 1) {
809                 LOG(ERROR) << "Invalid result";
810                 return -1;
811         }
812
813         if (result_list[0].size() != 1) {
814                 LOG(ERROR) << "Invalid result";
815                 return -1;
816         }
817
818         LOG(ERROR) << "result : " << result_list[0][0];
819         if (result_list[0][0] != "SUCCESS")
820                 return -1;
821
822         return 0;
823 }
824
825 extern "C" EXPORT_API int _parser_update_manifest_info(manifest_x *mfx, uid_t uid)
826 {
827         std::vector<package_x *> vt { mfx };
828
829         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
830                         new pkgmgr_common::parcel::PkgInfoParcelable(uid, std::move(vt), WriteType::Update));
831
832         pkgmgr_client::PkgInfoClient client(parcelable, uid,
833                         pkgmgr_common::ReqType::SET_PKG_INFO);
834         if (!client.SendRequest()) {
835                 return -1;
836         }
837
838         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
839                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
840                                         client.GetResultParcel()));
841
842         auto result_list = return_parcel->GetResult();
843         if (result_list.size() != 1) {
844                 LOG(ERROR) << "Invalid result";
845                 return -1;
846         }
847
848         if (result_list[0].size() != 1) {
849                 LOG(ERROR) << "Invalid result";
850                 return -1;
851         }
852
853         LOG(ERROR) << "result : " << result_list[0][0];
854         if (result_list[0][0] != "SUCCESS")
855                 return -1;
856
857         return 0;
858 }
859
860 extern "C" EXPORT_API int _parser_delete_manifest_info(manifest_x *mfx, uid_t uid)
861 {
862         std::vector<package_x *> vt { mfx };
863
864         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
865                         new pkgmgr_common::parcel::PkgInfoParcelable(uid, std::move(vt), WriteType::Delete));
866
867         pkgmgr_client::PkgInfoClient client(parcelable, uid,
868                         pkgmgr_common::ReqType::SET_PKG_INFO);
869         if (!client.SendRequest()) {
870                 return -1;
871         }
872
873         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
874                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
875                                         client.GetResultParcel()));
876
877         auto result_list = return_parcel->GetResult();
878         if (result_list.size() != 1) {
879                 LOG(ERROR) << "Invalid result";
880                 return -1;
881         }
882
883         if (result_list[0].size() != 1) {
884                 LOG(ERROR) << "Invalid result";
885                 return -1;
886         }
887
888         LOG(ERROR) << "result : " << result_list[0][0];
889         if (result_list[0][0] != "SUCCESS")
890                 return -1;
891
892         return 0;
893 }
894
895 extern "C" EXPORT_API int _pkginfo_insert_certinfo(const char* pkgid,
896                 pkgmgr_certinfo_x* cert, uid_t uid)
897 {
898         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
899                         new pkgmgr_common::parcel::CertInfoParcelable(uid, cert));
900
901         pkgmgr_client::PkgInfoClient client(parcelable, uid,
902                         pkgmgr_common::ReqType::SET_CERT_INFO);
903         if (!client.SendRequest())
904         return PMINFO_R_ERROR;
905
906         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
907                 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
908                                 client.GetResultParcel()));
909
910         auto result_list = return_parcel->GetResult();
911         if (result_list.size() != 1) {
912                 LOG(ERROR) << "Invalid result";
913                 return PMINFO_R_ERROR;
914         }
915
916         if (result_list[0].size() != 1) {
917                 LOG(ERROR) << "Invalid result";
918                 return PMINFO_R_ERROR;
919         }
920
921         LOG(ERROR) << "result : " << result_list[0][0];
922         if (result_list[0][0] != "SUCCESS")
923                 return PMINFO_R_ERROR;
924
925         return PMINFO_R_OK;
926 }
927
928 extern "C" EXPORT_API int _pkginfo_get_certinfo(const char *pkgid,
929                 pkgmgr_certinfo_x** cert, uid_t uid)
930 {
931         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
932                         new pkgmgr_common::parcel::CertInfoParcelable(uid,
933                                         std::string(pkgid)));
934
935         pkgmgr_client::PkgInfoClient client(parcelable, uid,
936                         pkgmgr_common::ReqType::GET_CERT_INFO);
937         if (!client.SendRequest())
938         return PMINFO_R_ERROR;
939
940         std::shared_ptr<pkgmgr_common::parcel::CertInfoParcelable> return_parcel(
941                 std::static_pointer_cast<pkgmgr_common::parcel::CertInfoParcelable>(
942                                 client.GetResultParcel()));
943
944         tizen_base::Parcel parcel;
945         parcel.ReadParcelable(return_parcel.get());
946         auto certinfo = return_parcel->GetCertInfo();
947         if (certinfo == nullptr)
948                 return PMINFO_R_ERROR;
949
950         *cert = (pkgmgr_certinfo_x*)certinfo;
951         return PMINFO_R_OK;
952 }
953
954 extern "C" EXPORT_API int _pkginfo_delete_certinfo(const char *pkgid)
955 {
956         char* query = sqlite3_mprintf("UPDATE package_cert_info SET "
957                         "package_count = package_count - 1 WHERE package=%Q", pkgid);
958         if (query == nullptr) {
959                 LOG(ERROR) << "Out of memory";
960                 return PMINFO_R_ERROR;
961         }
962
963         std::vector<std::string> queries;
964         queries.emplace_back(query);
965         sqlite3_free(query);
966
967         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
968                         new pkgmgr_common::parcel::QueryParcelable(0, queries,
969                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_CERTDB,
970                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
971
972         pkgmgr_client::PkgInfoClient client(parcelable, 0,
973                         pkgmgr_common::ReqType::QUERY);
974         if (!client.SendRequest()) {
975                 return PMINFO_R_ERROR;
976         }
977
978         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
979                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
980                                         client.GetResultParcel()));
981
982         auto result_list = return_parcel->GetResult();
983         if (result_list.size() != 1) {
984                 LOG(ERROR) << "Invalid result";
985                 return PMINFO_R_ERROR;
986         }
987
988         if (result_list[0].size() != 1) {
989                 LOG(ERROR) << "Invalid result";
990                 return PMINFO_R_ERROR;
991         }
992
993         LOG(ERROR) << "result : " << result_list[0][0];
994         if (result_list[0][0] != "SUCCESS")
995                 return PMINFO_R_ERROR;
996
997         return PMINFO_R_OK;
998 }