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