Implement pkgmgrinfo_pkginfo_set_installed_storage
[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/parcel/appinfo_parcelable.hh"
31 #include "common/parcel/filter_parcelable.hh"
32 #include "common/parcel/pkginfo_parcelable.hh"
33 #include "common/parcel/query_parcelable.hh"
34 #include "common/parcel/result_parcelable.hh"
35
36 #include "client/pkginfo_client.hh"
37
38 #include <parcel.hh>
39
40 #ifdef LOG_TAG
41 #undef LOG_TAG
42 #endif
43 #define LOG_TAG "PKGMGR_INFO"
44
45 #ifdef EXPORT_API
46 #undef EXPORT_API
47 #endif
48 #define EXPORT_API __attribute__((visibility("default")))
49
50 extern "C" EXPORT_API int _pkginfo_get_packages(uid_t uid,
51             pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
52         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
53                         new pkgmgr_common::parcel::FilterParcelable(uid,
54                                         static_cast<pkgmgrinfo_filter_x*>(filter), flag));
55
56         pkgmgr_client::PkgInfoClient client(parcelable, uid,
57                         pkgmgr_common::ReqType::GET_PKG_INFO);
58         if (!client.SendRequest())
59       return PMINFO_R_ERROR;
60
61         std::shared_ptr<pkgmgr_common::parcel::PkgInfoParcelable> return_parcel(
62                         std::static_pointer_cast<pkgmgr_common::parcel::PkgInfoParcelable>(
63                                         client.GetResultParcel()));
64
65         tizen_base::Parcel parcel;
66         parcel.ReadParcelable(return_parcel.get());
67
68         auto result_list = return_parcel->GetPkgInfo();
69         // TODO: check noentry error has returned if size of result_list is 0
70         for (auto& pkginfo : result_list)
71                 g_hash_table_insert(packages, (gpointer)pkginfo->package,
72                                 (gpointer)pkginfo);
73
74         return PMINFO_R_OK;
75 }
76
77 // TODO: Need to add target db uid to identify which database to be searched
78 extern "C" EXPORT_API int _appinfo_get_applications(uid_t db_uid, uid_t uid,
79                 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
80         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
81                         new pkgmgr_common::parcel::FilterParcelable(uid,
82                                         static_cast<pkgmgrinfo_filter_x*>(filter), flag));
83
84         pkgmgr_client::PkgInfoClient client(parcelable, uid, pkgmgr_common::ReqType::GET_APP_INFO);
85         if (!client.SendRequest())
86       return PMINFO_R_ERROR;
87
88         std::shared_ptr<pkgmgr_common::parcel::AppInfoParcelable> return_parcel(
89                         std::static_pointer_cast<pkgmgr_common::parcel::AppInfoParcelable>(
90                                         client.GetResultParcel()));
91
92         tizen_base::Parcel parcel;
93         parcel.ReadParcelable(return_parcel.get());
94         auto result_list = return_parcel->GetAppInfo();
95         for (auto& appinfo : result_list)
96                 g_hash_table_insert(packages, (gpointer)appinfo->appid,
97                                 (gpointer)appinfo);
98
99         return PMINFO_R_OK;
100 }
101
102 extern "C" EXPORT_API char *_appinfo_get_localed_label(
103                 const char *appid, const char *locale, uid_t uid) {
104         char *query = nullptr;
105     query = sqlite3_mprintf(
106                         "SELECT COALESCE((SELECT app_label FROM package_app_localized_info "
107                         "WHERE app_id=%Q AND app_locale=%Q),"
108                         "(SELECT app_label FROM package_app_localized_info WHERE "
109                         "app_id=%Q AND app_locale='No Locale'))", appid, locale, appid);
110         if (query == nullptr) {
111                 LOG(ERROR) << "Out of memory";
112                 return nullptr;
113         }
114
115         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
116                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
117           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
118           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
119
120         pkgmgr_client::PkgInfoClient client(parcelable, uid,
121                         pkgmgr_common::ReqType::QUERY);
122         if (!client.SendRequest()) {
123                 sqlite3_free(query);
124                 return nullptr;
125         }
126
127         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
128                                 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
129                                                 client.GetResultParcel()));
130         tizen_base::Parcel parcel;
131         parcel.ReadParcelable(return_parcel.get());
132         sqlite3_free(query);
133         // result_list is vector of string vector
134         char *label = nullptr;
135         auto result_list = return_parcel->GetResult();
136         for (auto result : result_list) {
137                 // result is string vector
138                 // it only has one string or not.
139                 if (result.front().empty() || result.front().length() == 0)
140                         return nullptr;
141                 label = strdup(result.front().c_str());
142                 if (label == nullptr) {
143                         LOG(ERROR) << "Out of memory";
144                         return nullptr;
145                 }
146                 return label;
147         }
148
149         return label;
150 }
151
152 extern "C" EXPORT_API int _appinfo_get_datacontrol_info(
153                 const char *providerid, const char *type, uid_t uid,
154                 char **appid, char **access) {
155         char *query = nullptr;
156         query = sqlite3_mprintf("SELECT app_id, access FROM "
157                         "package_app_data_control WHERE "
158                         "providerid=%Q AND type=%Q", providerid, type);
159         if (query == nullptr) {
160                 LOG(ERROR) << "Out of memory";
161                 return PMINFO_R_ERROR;
162         }
163
164         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
165                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
166           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
167           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
168
169         pkgmgr_client::PkgInfoClient client(parcelable, uid,
170                         pkgmgr_common::ReqType::QUERY);
171         if (!client.SendRequest()) {
172                 sqlite3_free(query);
173                 return PMINFO_R_ERROR;
174         }
175
176         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
177                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
178                                         client.GetResultParcel()));
179         tizen_base::Parcel parcel;
180         parcel.ReadParcelable(return_parcel.get());
181         sqlite3_free(query);
182         // result_list is vector of string vector
183         auto result_list = return_parcel->GetResult();
184         if (result_list.size() == 0)
185                 return PMINFO_R_ENOENT;
186         for (auto result : result_list) {
187                 if (result.size() != 2)
188                         return PMINFO_R_ERROR;
189                 if (result.front().empty() || result.front().size() == 0 ||
190                                 result.back().empty() || result.back().size() == 0)
191                         return PMINFO_R_ERROR;
192                 *appid = strdup(result.front().c_str());
193                 *access = strdup(result.back().c_str());
194                 if (*appid == nullptr || *access == nullptr) {
195                         LOG(ERROR) << "Out of memory";
196                         return PMINFO_R_ERROR;
197                 }
198         }
199
200         return PMINFO_R_OK;
201 }
202
203 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
204                 const char *providerid, uid_t uid, char **appid) {
205         char *query = nullptr;
206
207         query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
208                 "WHERE providerid=%Q", providerid);
209         if (query == NULL) {
210                 LOGE("Out of memory");
211                 return PMINFO_R_ERROR;
212         }
213         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
214                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
215           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
216           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
217
218         pkgmgr_client::PkgInfoClient client(parcelable, uid,
219                         pkgmgr_common::ReqType::QUERY);
220         if (!client.SendRequest()) {
221                 sqlite3_free(query);
222                 return PMINFO_R_ERROR;
223         }
224         // TODO: deliver rawdata to reqhandler directly if server is not working
225
226         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
227                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
228                                         client.GetResultParcel()));
229         tizen_base::Parcel parcel;
230         parcel.ReadParcelable(return_parcel.get());
231         sqlite3_free(query);
232
233         // result_list is vector of string vector
234         auto result_list = return_parcel->GetResult();
235         if (result_list.size() == 0)
236                 return PMINFO_R_ENOENT;
237         for (auto result : result_list) {
238                 if (result.size() != 1)
239                         return PMINFO_R_ERROR;
240                 if (result.front().empty() || result.front().size() == 0)
241                         return PMINFO_R_ERROR;
242                 *appid = strdup(result.front().c_str());
243                 if (*appid == nullptr) {
244                         LOG(ERROR) << "Out of memory";
245                         return PMINFO_R_ERROR;
246                 }
247         }
248
249         return PMINFO_R_OK;
250 }
251
252 extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
253                 const char *providerid, const char *type, uid_t uid,
254                 char **appid, char **trusted) {
255         char *query = nullptr;
256         query = sqlite3_mprintf(
257                         "SELECT app_id, trusted FROM package_app_data_control "
258                         "WHERE providerid=%Q AND type=%Q", providerid, type);
259         if (query == NULL) {
260                 LOGE("Out of memory");
261                 return PMINFO_R_ERROR;
262         }
263
264         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
265                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
266           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
267           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
268
269         pkgmgr_client::PkgInfoClient client(parcelable, uid,
270                         pkgmgr_common::ReqType::QUERY);
271         if (!client.SendRequest()) {
272                 sqlite3_free(query);
273                 return PMINFO_R_ERROR;
274         }
275         // TODO: deliver rawdata to reqhandler directly if server is not working
276
277         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
278                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
279                                         client.GetResultParcel()));
280         tizen_base::Parcel parcel;
281         parcel.ReadParcelable(return_parcel.get());
282         sqlite3_free(query);
283         // result_list is vector of string vector
284         auto result_list = return_parcel->GetResult();
285         if (result_list.size() == 0)
286                 return PMINFO_R_ENOENT;
287         for (auto result : result_list) {
288                 if (result.size() != 2)
289                         return PMINFO_R_ERROR;
290                 if (result.front().empty() || result.front().size() == 0 ||
291                                 result.back().empty() || result.back().size() == 0)
292                         return PMINFO_R_ERROR;
293                 *appid = strdup(result.front().c_str());
294                 *trusted = strdup(result.back().c_str());
295                 if (*appid == nullptr || *trusted == nullptr) {
296                         LOG(ERROR) << "Out of memory";
297                         return PMINFO_R_ERROR;
298                 }
299         }
300
301         return PMINFO_R_OK;
302 }
303
304 extern "C" EXPORT_API int _appinfo_get_datacontrol_privileges(
305                 const char *providerid, const char *type, uid_t uid,
306                 GList **privileges) {
307         char *query = nullptr;
308         query = sqlite3_mprintf(
309                         "SELECT privilege FROM package_app_data_control_privilege "
310                         "WHERE providerid=%Q AND type=%Q", providerid, type);
311         if (query == NULL) {
312                 LOGE("Out of memory");
313                 return PMINFO_R_ERROR;
314         }
315
316         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
317                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
318           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
319           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
320
321         pkgmgr_client::PkgInfoClient client(parcelable, uid,
322                         pkgmgr_common::ReqType::QUERY);
323         if (!client.SendRequest()) {
324                 sqlite3_free(query);
325                 return PMINFO_R_ERROR;
326         }
327         // TODO: deliver rawdata to reqhandler directly if server is not working
328
329         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
330                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
331                                         client.GetResultParcel()));
332         tizen_base::Parcel parcel;
333         parcel.ReadParcelable(return_parcel.get());
334         sqlite3_free(query);
335         // result_list is vector of string vector
336         auto result_list = return_parcel->GetResult();
337         if (result_list.size() == 0)
338                 return PMINFO_R_ENOENT;
339
340         for (auto result : result_list) {
341                 if (result.size() != 1)
342                         return PMINFO_R_ERROR;
343                 if (result.front().empty() || result.front().size() == 0)
344                         return PMINFO_R_ERROR;
345                 char *privilege = strdup(result.front().c_str());
346                 if (privilege == nullptr) {
347                         LOG(ERROR) << "Out of memory";
348                         return PMINFO_R_ERROR;
349                 }
350                 *privileges = g_list_append(*privileges, privilege);
351         }
352
353         return PMINFO_R_OK;
354 }
355
356 extern "C" EXPORT_API int _appinfo_get_appcontrol_privileges(
357                 const char *appid, const char *operation, uid_t uid, GList **privileges) {
358         char *query = nullptr;
359         query = sqlite3_mprintf(
360                 "SELECT app_control, privilege FROM package_app_app_control_privilege "
361                 "WHERE app_id=%Q", appid);
362         if (query == NULL) {
363                 LOG(ERROR) << "Out of memory";
364                 return PMINFO_R_ERROR;
365         }
366
367         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
368                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
369           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
370           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
371
372         pkgmgr_client::PkgInfoClient client(parcelable, uid,
373                         pkgmgr_common::ReqType::QUERY);
374         if (!client.SendRequest()) {
375                 sqlite3_free(query);
376                 return PMINFO_R_ERROR;
377         }
378         // TODO: deliver rawdata to reqhandler directly if server is not working
379
380         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
381                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
382                                         client.GetResultParcel()));
383         tizen_base::Parcel parcel;
384         parcel.ReadParcelable(return_parcel.get());
385         sqlite3_free(query);
386         // result_list is vector of string vector
387         auto result_list = return_parcel->GetResult();
388         if (result_list.size() == 0)
389                 return PMINFO_R_ENOENT;
390
391         for (auto result : result_list) {
392                 if (result.size() != 2)
393                         return PMINFO_R_ERROR;
394                 if (result.front().empty() || result.front().size() == 0 ||
395                                 result.back().empty() || result.back().size() == 0)
396                         return PMINFO_R_ERROR;
397                 std::string app_control = result.front();
398                 std::stringstream ss(app_control);
399                 std::string token;
400                 while (std::getline(ss, token, '|')) {
401                         if (token.compare(std::string(operation))) {
402                                 char *privilege = strdup(result.back().c_str());
403                                 if (privilege == nullptr) {
404                                         LOG(ERROR) << "Out of memory";
405                                         return PMINFO_R_ERROR;
406                                 }
407                                 *privileges = g_list_append(*privileges, privilege);
408                         }
409                 }
410         }
411         return PMINFO_R_OK;
412 }
413
414 extern "C" EXPORT_API int _plugininfo_get_appids(
415                 const char *pkgid, const char *plugin_type,
416                 const char *plugin_name, GList **list) {
417         if (!pkgid || !plugin_type || !plugin_name || !list) {
418                 LOG(ERROR) << "Invalid parameter";
419                 return PMINFO_R_EINVAL;
420         }
421
422         char *query = nullptr;
423         query = sqlite3_mprintf(
424                         "SELECT appid FROM "
425                         "package_plugin_info WHERE pkgid=%Q AND "
426                         "plugin_type=%Q AND plugin_name=%Q",
427       pkgid, plugin_type, plugin_name);
428         if (query == NULL) {
429                 LOG(ERROR) << "Out of memory";
430                 return PMINFO_R_ERROR;
431         }
432
433         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
434                         new pkgmgr_common::parcel::QueryParcelable(_getuid(), std::string(query),
435           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
436           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
437         sqlite3_free(query);
438
439         pkgmgr_client::PkgInfoClient client(parcelable, _getuid(),
440                         pkgmgr_common::ReqType::QUERY);
441         if (!client.SendRequest()) {
442                 return PMINFO_R_ERROR;
443         }
444
445         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
446                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
447                                         client.GetResultParcel()));
448   if (return_parcel->GetCol() != 1) {
449     LOG(ERROR) << "Invalid result";
450     return PMINFO_R_ERROR;
451   }
452         // result_list is vector of string vector
453         auto result_list = return_parcel->GetResult();
454         if (result_list.size() == 0)
455                 return PMINFO_R_ENOENT;
456
457         for (auto result : result_list) {
458     if (result.size() != 1) {
459       LOG(ERROR) << "Invalid result";
460       g_list_free_full(*list, free);
461       return PMINFO_R_ERROR;
462     }
463     *list = g_list_append(*list, strdup(result[0].c_str()));
464   }
465
466   return PMINFO_R_OK;
467 }
468
469 static int __convert_update_type(const char *type, pkgmgrinfo_updateinfo_update_type *convert_type)
470 {
471         if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_NONE,
472                         strlen(PMINFO_UPDATEINFO_TYPE_NONE)) == 0)
473                 *convert_type = PMINFO_UPDATEINFO_NONE;
474         else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_FORCE,
475                         strlen(PMINFO_UPDATEINFO_TYPE_FORCE)) == 0)
476                 *convert_type = PMINFO_UPDATEINFO_FORCE;
477         else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_OPTIONAL,
478                         strlen(PMINFO_UPDATEINFO_TYPE_OPTIONAL)) == 0)
479                 *convert_type = PMINFO_UPDATEINFO_OPTIONAL;
480         else
481                 return -1;
482         return 0;
483 }
484
485 static void __free_update_info(gpointer data)
486 {
487         updateinfo_x *update_info = (updateinfo_x *)data;
488         if (update_info == NULL)
489                 return;
490
491         if (update_info->pkgid)
492                 free((void *)update_info->pkgid);
493         if (update_info->version)
494                 free((void *)update_info->version);
495         free((void *)update_info);
496
497 }
498
499 extern "C" EXPORT_API int _get_pkg_updateinfo(const char *pkgid,
500                 GSList **update_info_list, uid_t uid)
501 {
502         char *query = nullptr;
503         int ret;
504
505         if (pkgid == NULL)
506                 query = sqlite3_mprintf(
507                                                 "SELECT package, update_version, update_type "
508                                                 "FROM package_update_info");
509         else
510                 query = sqlite3_mprintf(
511                                                 "SELECT package, update_version, update_type "
512                                                 "FROM package_update_info WHERE package=%Q",
513                                                 pkgid);
514         if (query == NULL) {
515                 LOG(ERROR) << "Out of memory";
516                 return PMINFO_R_ERROR;
517         }
518
519         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
520                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
521           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
522           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
523         sqlite3_free(query);
524
525         pkgmgr_client::PkgInfoClient client(parcelable, uid,
526                         pkgmgr_common::ReqType::QUERY);
527         if (!client.SendRequest()) {
528                 return PMINFO_R_ERROR;
529         }
530
531         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
532                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
533                                         client.GetResultParcel()));
534   if (return_parcel->GetCol() != 3) {
535     LOG(ERROR) << "Invalid result";
536     return PMINFO_R_ERROR;
537   }
538
539         auto result_list = return_parcel->GetResult();
540         if (result_list.size() == 0)
541                 return PMINFO_R_ENOENT;
542
543         for (auto result : result_list) {
544     if (result.size() != 3) {
545       LOG(ERROR) << "Invalid result";
546       g_slist_free_full(*update_info_list, __free_update_info);
547       return PMINFO_R_ERROR;
548     }
549     updateinfo_x *update_info = reinterpret_cast<updateinfo_x *>(calloc(1, sizeof(updateinfo_x)));
550                 if (update_info == NULL) {
551                         LOG(ERROR) << "Out of memory";
552                         return PMINFO_R_ERROR;
553                 }
554     update_info->pkgid = strdup(result[0].c_str());
555     update_info->version = strdup(result[1].c_str());
556           pkgmgrinfo_updateinfo_update_type convert_type;
557                 ret = __convert_update_type(result[2].c_str(), &convert_type);
558                 if (ret != 0) {
559                         __free_update_info(update_info);
560       g_slist_free_full(*update_info_list, __free_update_info);
561                         return PMINFO_R_ERROR;
562                 }
563                 update_info->type = static_cast<int>(convert_type);
564                 *update_info_list = g_slist_prepend(*update_info_list,
565                                 update_info);
566   }
567
568         return PMINFO_R_OK;
569 }
570
571 extern "C" EXPORT_API int _pkginfo_set_usr_installed_storage(const char *pkgid,
572                 INSTALL_LOCATION location, const char *external_pkg_path,
573                 uid_t uid)
574 {
575         char *query = NULL;
576         const char *location_str;
577         std::vector<std::string> queries;
578
579         if (location == INSTALL_INTERNAL)
580                 location_str = "installed_internal";
581         else if (location == INSTALL_EXTERNAL)
582                 location_str = "installed_external";
583         else
584                 location_str = "installed_extended";
585         /* pkgcakge_info table */
586         query = sqlite3_mprintf(
587                         "update package_info set installed_storage=%Q, external_path=%Q where package=%Q",
588                         location_str, external_pkg_path, pkgid);
589         queries.emplace_back(query);
590         sqlite3_free(query);
591
592         /* package_app_info table */
593         query = sqlite3_mprintf(
594                         "update package_app_info set app_installed_storage=%Q, app_external_path=%Q where package=%Q",
595                         location_str, external_pkg_path, pkgid);
596         queries.emplace_back(query);
597         sqlite3_free(query);
598
599         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
600                         new pkgmgr_common::parcel::QueryParcelable(uid, queries,
601                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
602                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
603
604         pkgmgr_client::PkgInfoClient client(parcelable, uid,
605                         pkgmgr_common::ReqType::QUERY);
606         if (!client.SendRequest()) {
607                 return PMINFO_R_ERROR;
608         }
609
610         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
611                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
612                                         client.GetResultParcel()));
613
614         auto result_list = return_parcel->GetResult();
615         if (result_list.size() != 1) {
616                 LOG(ERROR) << "Invalid result";
617                 return PMINFO_R_ERROR;
618         }
619
620         if (result_list[0].size() != 1) {
621                 LOG(ERROR) << "Invalid result";
622                 return PMINFO_R_ERROR;
623         }
624
625         LOG(ERROR) << "result : " << result_list[0][0];
626         if (result_list[0][0] != "SUCCESS")
627                 return PMINFO_R_ERROR;
628
629         return PMINFO_R_OK;
630 }