Fix coding style
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_db.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <ctype.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <grp.h>
10 #include <dirent.h>
11 #include <libgen.h>
12
13 #include <sqlite3.h>
14
15 #include <tzplatform_config.h>
16 #include <db-util.h>
17
18 #include "pkgmgr-info.h"
19 #include "pkgmgrinfo_debug.h"
20 #include "pkgmgrinfo_private.h"
21 #include "pkgmgr_parser.h"
22 #include "pkgmgr_parser_internal.h"
23
24 #define QUERY_CREATE_TABLE_PACKAGE_CERT_INDEX_INFO \
25         "CREATE TABLE IF NOT EXISTS package_cert_index_info( " \
26         " cert_info TEXT UNIQUE, " \
27         " cert_id INTEGER PRIMARY KEY, " \
28         " cert_ref_count INTEGER NOT NULL)"
29
30 #define QUERY_CREATE_TABLE_PACKAGE_CERT_INFO \
31         "CREATE TABLE IF NOT EXISTS package_cert_info( " \
32         " package TEXT PRIMARY KEY, " \
33         " package_count INTEGER, " \
34         " author_root_cert INTEGER, " \
35         " author_im_cert INTEGER, " \
36         " author_signer_cert INTEGER, " \
37         " dist_root_cert INTEGER, " \
38         " dist_im_cert INTEGER, " \
39         " dist_signer_cert INTEGER, " \
40         " dist2_root_cert INTEGER, " \
41         " dist2_im_cert INTEGER, " \
42         " dist2_signer_cert INTEGER)"
43
44 #define QUERY_CREATE_TRIGGER_UPDATE_CERT_INFO \
45         "CREATE TRIGGER IF NOT EXISTS update_cert_info " \
46         "AFTER UPDATE ON package_cert_info " \
47         "WHEN (NEW.package_count = 0) " \
48         "BEGIN" \
49         " DELETE FROM package_cert_info WHERE package=OLD.package;" \
50         "END;"
51
52 #define QUERY_CREATE_TRIGGER_UPDATE_CERT_INFO2 \
53         "CREATE TRIGGER IF NOT EXISTS update_cert_info2 " \
54         "AFTER UPDATE ON package_cert_info " \
55         "WHEN (NEW.package_count = OLD.package_count + 1) " \
56         "BEGIN" \
57         " UPDATE package_cert_index_info SET" \
58         "  cert_ref_count = cert_ref_count - 1" \
59         " WHERE cert_id = OLD.author_root_cert" \
60         "  OR cert_id = OLD.author_im_cert" \
61         "  OR cert_id = OLD.author_signer_cert" \
62         "  OR cert_id = OLD.dist_root_cert" \
63         "  OR cert_id = OLD.dist_im_cert" \
64         "  OR cert_id = OLD.dist_signer_cert" \
65         "  OR cert_id = OLD.dist2_root_cert" \
66         "  OR cert_id = OLD.dist2_im_cert" \
67         "  OR cert_id = OLD.dist2_signer_cert;" \
68         "END;"
69
70 #define QUERY_CREATE_TRIGGER_DELETE_CERT_INFO \
71         "CREATE TRIGGER IF NOT EXISTS delete_cert_info " \
72         "AFTER DELETE ON package_cert_info " \
73         "BEGIN" \
74         " UPDATE package_cert_index_info SET" \
75         "  cert_ref_count = cert_ref_count - 1" \
76         " WHERE cert_id = OLD.author_root_cert" \
77         "  OR cert_id = OLD.author_im_cert" \
78         "  OR cert_id = OLD.author_signer_cert" \
79         "  OR cert_id = OLD.dist_root_cert" \
80         "  OR cert_id = OLD.dist_im_cert" \
81         "  OR cert_id = OLD.dist_signer_cert" \
82         "  OR cert_id = OLD.dist2_root_cert" \
83         "  OR cert_id = OLD.dist2_im_cert" \
84         "  OR cert_id = OLD.dist2_signer_cert;" \
85         "END;"
86
87 #define QUERY_CREATE_TRIGGER_UPDATE_CERT_INDEX_INFO \
88         "CREATE TRIGGER IF NOT EXISTS update_cert_index_info " \
89         "AFTER UPDATE ON package_cert_index_info " \
90         "WHEN ((SELECT cert_ref_count FROM package_cert_index_info " \
91         "       WHERE cert_id = OLD.cert_id) = 0) "\
92         "BEGIN" \
93         " DELETE FROM package_cert_index_info WHERE cert_id = OLD.cert_id;" \
94         "END;"
95
96 __thread db_handle manifest_db;
97 __thread db_handle cert_db;
98
99 typedef int (*sqlite_query_callback)(void *data, int ncols, char **coltxt, char **colname);
100
101 static int _mkdir_for_user(const char* dir, uid_t uid, gid_t gid)
102 {
103         int ret;
104         char *fullpath;
105         char *subpath;
106         char buf[1024];
107         int fd;
108         struct stat sb;
109
110         fullpath = strdup(dir);
111         if (fullpath == NULL)
112                 return -1;
113         subpath = dirname(fullpath);
114         if (strlen(subpath) > 1 && strcmp(subpath, fullpath) != 0) {
115                 ret = _mkdir_for_user(fullpath, uid, gid);
116                 if (ret == -1) {
117                         free(fullpath);
118                         return ret;
119                 }
120         }
121
122         ret = mkdir(dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
123         if (ret && errno != EEXIST) {
124                 free(fullpath);
125                 return ret;
126         } else if (ret && errno == EEXIST) {
127                 free(fullpath);
128                 return 0;
129         }
130
131         if (getuid() == ROOT_UID) {
132                 fd = open(dir, O_RDONLY);
133                 if (fd == -1) {
134                         _LOGE("FAIL : open %s : %s", dir,
135                                         strerror_r(errno, buf, sizeof(buf)));
136                         return -1;
137                 }
138                 ret = fstat(fd, &sb);
139                 if (ret == -1) {
140                         _LOGE("FAIL : fstat %s : %s", dir,
141                                         strerror_r(errno, buf, sizeof(buf)));
142                         close(fd);
143                         return -1;
144                 }
145                 if (S_ISLNK(sb.st_mode)) {
146                         _LOGE("FAIL : %s is symlink!", dir);
147                         close(fd);
148                         return -1;
149                 }
150                 ret = fchown(fd, uid, gid);
151                 if (ret == -1) {
152                         _LOGE("FAIL : fchown %s %d.%d, because %s", dir, uid,
153                                         gid, strerror_r(errno, buf, sizeof(buf)));
154                         close(fd);
155                         return -1;
156                 }
157                 close(fd);
158         }
159
160         free(fullpath);
161
162         return 0;
163 }
164
165 static const char *_get_db_path(uid_t uid)
166 {
167         const char *db_path = NULL;
168         if (uid != GLOBAL_USER && uid != ROOT_UID) {
169                 tzplatform_set_user(uid);
170                 db_path = tzplatform_getenv(TZ_USER_DB);
171                 tzplatform_reset_user();
172         } else {
173                 db_path = tzplatform_getenv(TZ_SYS_DB);
174         }
175         return db_path;
176 }
177
178 static int __attach_and_create_view(sqlite3 *handle, const char *db, const char *tables[], uid_t uid)
179 {
180         int i;
181         char *err;
182         char query[MAX_QUERY_LEN];
183
184         if (uid != GLOBAL_USER && uid != ROOT_UID) {
185                 snprintf(query, sizeof(query), "ATTACH DATABASE '%s' AS Global", db);
186                 if (SQLITE_OK != sqlite3_exec(handle, query, NULL, NULL, &err)) {
187                         _LOGD("Don't execute query = %s error message = %s\n", query, err);
188                         sqlite3_free(err);
189                         return SQLITE_ERROR;
190                 }
191         }
192
193         for (i = 0; tables[i]; i++) {
194                 if (uid != GLOBAL_USER && uid != ROOT_UID)
195                         snprintf(query, sizeof(query), "CREATE TEMP VIEW '%s' AS SELECT * \
196                                         FROM (SELECT *,0 AS for_all_users FROM main.'%s' UNION \
197                                         SELECT *,1 AS for_all_users FROM Global.'%s')",
198                                         tables[i], tables[i], tables[i]);
199                 else
200                         snprintf(query, sizeof(query), "CREATE TEMP VIEW '%s' AS SELECT * \
201                                         FROM (SELECT *,1 AS for_all_users FROM main.'%s')",
202                                         tables[i], tables[i]);
203                 if (SQLITE_OK != sqlite3_exec(handle, query, NULL, NULL, &err)) {
204                         _LOGD("Don't execute query = %s error message = %s\n", query, err);
205                         sqlite3_free(err);
206                 }
207         }
208
209         return SQLITE_OK;
210 }
211
212 static int __exec_db_query(sqlite3 *db, char *query, sqlite_query_callback callback, void *data)
213 {
214         char *error_message = NULL;
215         int ret = sqlite3_exec(db, query, callback, data, &error_message);
216         if (SQLITE_OK != ret) {
217                 _LOGE("Don't execute query = %s error message = %s   ret = %d\n", query,
218                        error_message, ret);
219                 sqlite3_free(error_message);
220                 return -1;
221         }
222         sqlite3_free(error_message);
223         return 0;
224 }
225
226 int _check_create_cert_db(sqlite3 *certdb)
227 {
228         int ret = 0;
229         ret = __exec_db_query(certdb, QUERY_CREATE_TABLE_PACKAGE_CERT_INDEX_INFO, NULL, NULL);
230         if (ret < 0)
231                 return ret;
232         ret = __exec_db_query(certdb, QUERY_CREATE_TABLE_PACKAGE_CERT_INFO, NULL, NULL);
233         if (ret < 0)
234                 return ret;
235         ret = __exec_db_query(certdb, QUERY_CREATE_TRIGGER_UPDATE_CERT_INFO, NULL, NULL);
236         if (ret < 0)
237                 return ret;
238         ret = __exec_db_query(certdb, QUERY_CREATE_TRIGGER_UPDATE_CERT_INFO2, NULL, NULL);
239         if (ret < 0)
240                 return ret;
241         ret = __exec_db_query(certdb, QUERY_CREATE_TRIGGER_DELETE_CERT_INFO, NULL, NULL);
242         if (ret < 0)
243                 return ret;
244         ret = __exec_db_query(certdb, QUERY_CREATE_TRIGGER_UPDATE_CERT_INDEX_INFO, NULL, NULL);
245         return ret;
246 }
247 static gid_t _get_gid(const char *name)
248 {
249         char buf[BUFSIZE];
250         struct group entry;
251         struct group *ge;
252         int ret;
253
254         ret = getgrnam_r(name, &entry, buf, sizeof(buf), &ge);
255         if (ret || ge == NULL) {
256                 _LOGE("fail to get gid of %s", name);
257                 return -1;
258         }
259
260         return entry.gr_gid;
261 }
262
263 API const char *getIconPath(uid_t uid, bool readonly)
264 {
265         const char *path = NULL;
266         uid_t uid_caller = getuid();
267         gid_t gid = ROOT_UID;
268
269         if (uid != GLOBAL_USER && uid != ROOT_UID) {
270                 tzplatform_set_user(uid);
271                 path = tzplatform_mkpath(TZ_USER_ICONS, "/");
272                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
273                 tzplatform_reset_user();
274         } else {
275                 if (readonly)
276                         path = tzplatform_mkpath(TZ_SYS_RO_ICONS, "/");
277                 else
278                         path = tzplatform_mkpath(TZ_SYS_RW_ICONS, "/");
279         }
280
281         /* just allow certain users to create the icon directory if needed. */
282         if (uid_caller == ROOT_UID || uid_caller == uid)
283                 _mkdir_for_user(path, uid, gid);
284
285         return path;
286 }
287
288 API const char *getUserPkgParserDBPath(void)
289 {
290         return getUserPkgParserDBPathUID(_getuid());
291 }
292
293 API const char *getUserPkgParserDBPathUID(uid_t uid)
294 {
295         const char *pkgmgr_parser_db = NULL;
296         uid_t uid_caller = getuid();
297         gid_t gid = ROOT_UID;
298
299         if (uid != GLOBAL_USER && uid != ROOT_UID) {
300                 tzplatform_set_user(uid);
301                 pkgmgr_parser_db = tzplatform_mkpath(TZ_USER_DB, ".pkgmgr_parser.db");
302                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
303                 tzplatform_reset_user();
304         } else {
305                 pkgmgr_parser_db = tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_parser.db");
306         }
307
308         /* just allow certain users to create the dbspace directory if needed. */
309         if (uid_caller == ROOT_UID || uid_caller == uid) {
310                 const char *db_path = _get_db_path(uid);
311                 _mkdir_for_user(db_path, uid, gid);
312         }
313
314         return pkgmgr_parser_db;
315 }
316
317 API const char *getUserPkgCertDBPath(void)
318 {
319          return getUserPkgCertDBPathUID(_getuid());
320 }
321
322 API const char *getUserPkgCertDBPathUID(uid_t uid)
323 {
324         const char *pkgmgr_cert_db = NULL;
325         uid_t uid_caller = getuid();
326         gid_t gid = ROOT_UID;
327
328         if (uid != GLOBAL_USER && uid != ROOT_UID) {
329                 tzplatform_set_user(uid);
330                 pkgmgr_cert_db = tzplatform_mkpath(TZ_USER_DB, ".pkgmgr_cert.db");
331                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
332                 tzplatform_reset_user();
333         } else {
334                 pkgmgr_cert_db = tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_cert.db");
335         }
336
337         /* just allow certain users to create the dbspace directory if needed. */
338         if (uid_caller == ROOT_UID || uid_caller == uid) {
339                 const char *db_path = _get_db_path(uid);
340                 _mkdir_for_user(db_path, uid, gid);
341         }
342
343         return pkgmgr_cert_db;
344 }
345
346 API const char *getUserManifestPath(uid_t uid, bool readonly)
347 {
348         const char *path = NULL;
349         uid_t uid_caller = getuid();
350         gid_t gid = ROOT_UID;
351
352         if (uid != GLOBAL_USER && uid != ROOT_UID) {
353                 tzplatform_set_user(uid);
354                 path = tzplatform_mkpath(TZ_USER_PACKAGES, "/");
355                 gid = _get_gid(tzplatform_getenv(TZ_SYS_USER_GROUP));
356                 tzplatform_reset_user();
357         } else {
358                 if (readonly)
359                         path = tzplatform_mkpath(TZ_SYS_RO_PACKAGES, "/");
360                 else
361                         path = tzplatform_mkpath(TZ_SYS_RW_PACKAGES, "/");
362         }
363
364         /* just allow certain users to create the icon directory if needed. */
365         if (uid_caller == ROOT_UID || uid_caller == uid)
366                 _mkdir_for_user(path, uid, gid);
367
368         return path;
369 }
370
371 int __close_manifest_db(void)
372 {
373         if (manifest_db.ref) {
374                 if (--manifest_db.ref == 0)
375                         sqlite3_close(GET_DB(manifest_db));
376                 return 0;
377         }
378         return -1;
379 }
380
381 static const char *parserdb_tables[] = {
382         "package_app_app_category",
383         "package_app_info",
384         "package_app_app_control",
385         "package_app_localized_info",
386         "package_app_app_metadata",
387         "package_app_share_allowed",
388         "package_app_app_permission",
389         "package_app_share_request",
390         "package_info",
391         "package_app_data_control",
392         "package_localized_info",
393         "package_app_icon_section_info",
394         "package_privilege_info",
395         "package_app_image_info",
396         NULL
397 };
398
399 int __open_manifest_db(uid_t uid, bool readonly)
400 {
401         int ret;
402         const char *user_pkg_parser;
403         int flags;
404
405         if (manifest_db.ref) {
406                 manifest_db.ref++;
407                 return 0;
408         }
409
410         user_pkg_parser = getUserPkgParserDBPathUID(uid);
411         if (access(user_pkg_parser, F_OK) != 0) {
412                 _LOGE("Manifest DB does not exists !!");
413                 return -1;
414         }
415
416         flags = readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE;
417         ret = db_util_open_with_options(user_pkg_parser, &GET_DB(manifest_db),
418                         flags, NULL);
419         retvm_if(ret != SQLITE_OK, -1, "connect db [%s] failed!\n",
420                         user_pkg_parser);
421         manifest_db.ref++;
422         if (readonly) {
423                 ret = __attach_and_create_view(GET_DB(manifest_db), MANIFEST_DB,
424                                 parserdb_tables, uid);
425                 retvm_if(ret != SQLITE_OK, -1, "attach db [%s] failed!\n",
426                                 user_pkg_parser);
427         }
428         return 0;
429 }
430
431 int __close_cert_db(void)
432 {
433         if (cert_db.ref) {
434                 if (--cert_db.ref == 0)
435                         sqlite3_close_v2(GET_DB(cert_db));
436                         return 0;
437         }
438         _LOGE("Certificate DB is already closed !!\n");
439         return -1;
440 }
441
442 static const char *certdb_tables[] = {
443         "package_cert_index_info",
444         "package_cert_info",
445         NULL
446 };
447
448 int __open_cert_db(uid_t uid, bool readonly)
449 {
450         int ret;
451         const char *user_cert_parser;
452         int flags;
453
454         if (cert_db.ref) {
455                 cert_db.ref++;
456                 return 0;
457         }
458
459         user_cert_parser = getUserPkgCertDBPathUID(uid);
460         if (access(user_cert_parser, F_OK) != 0) {
461                 _LOGE("Cert DB does not exists !!");
462                 return -1;
463         }
464
465         flags = readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE;
466         ret = db_util_open_with_options(user_cert_parser, &GET_DB(cert_db),
467                         flags, NULL);
468         retvm_if(ret != SQLITE_OK, -1, "connect db [%s] failed!",
469                         user_cert_parser);
470         cert_db.ref++;
471         if (readonly) {
472                 ret = __attach_and_create_view(GET_DB(cert_db), CERT_DB,
473                                 certdb_tables, uid);
474                 retvm_if(ret != SQLITE_OK, -1, "attach db [%s] failed!",
475                                 user_cert_parser);
476         }
477         return 0;
478 }
479
480 void _save_column_int(sqlite3_stmt *stmt, int idx, int *i)
481 {
482         *i = sqlite3_column_int(stmt, idx);
483 }
484
485 void _save_column_str(sqlite3_stmt *stmt, int idx, char **str)
486 {
487         const char *val;
488
489         val = (const char *)sqlite3_column_text(stmt, idx);
490         if (val)
491                 *str = strdup(val);
492 }
493
494 API int pkgmgrinfo_pkginfo_set_state_enabled(const char *pkgid, bool enabled)
495 {
496         /* Should be implemented later */
497         return 0;
498 }
499
500 API int pkgmgrinfo_appinfo_set_usr_state_enabled(const char *appid, bool enabled, uid_t uid)
501 {
502         int ret;
503         char query[MAX_QUERY_LEN] = {'\0'};
504         char *error_message;
505
506         retvm_if(appid == NULL, PMINFO_R_EINVAL, "appid is NULL\n");
507
508         /* Open db.*/
509         ret = __open_manifest_db(uid, false);
510         if (ret != SQLITE_OK) {
511                 _LOGE("connect db [%s] failed!\n", getUserPkgParserDBPathUID(uid));
512                 return PMINFO_R_ERROR;
513         }
514
515         /*Begin transaction*/
516         ret = sqlite3_exec(GET_DB(manifest_db), "BEGIN EXCLUSIVE", NULL, NULL, NULL);
517         if (ret != SQLITE_OK) {
518                 _LOGE("Failed to begin transaction\n");
519                 __close_manifest_db();
520                 return PMINFO_R_ERROR;
521         }
522         _LOGD("Transaction Begin\n");
523
524         memset(query, '\0', MAX_QUERY_LEN);
525         snprintf(query, MAX_QUERY_LEN,
526                 "update package_app_info set app_enabled='%s' where app_id='%s'",
527                 enabled ? "true" : "false", appid);
528
529         if (SQLITE_OK !=
530             sqlite3_exec(GET_DB(manifest_db), query, NULL, NULL, &error_message)) {
531                 _LOGE("Don't execute query = %s error message = %s\n", query,
532                        error_message);
533                 sqlite3_free(error_message);
534                 return PMINFO_R_ERROR;
535         }
536         sqlite3_free(error_message);
537
538         /*Commit transaction*/
539         ret = sqlite3_exec(GET_DB(manifest_db), "COMMIT", NULL, NULL, NULL);
540         if (ret != SQLITE_OK) {
541                 _LOGE("Failed to commit transaction. Rollback now\n");
542                 sqlite3_exec(GET_DB(manifest_db), "ROLLBACK", NULL, NULL, NULL);
543                 __close_manifest_db();
544                 return PMINFO_R_ERROR;
545         }
546         _LOGD("Transaction Commit and End\n");
547         __close_manifest_db();
548         return PMINFO_R_OK;
549 }
550
551 API int pkgmgrinfo_appinfo_set_state_enabled(const char *appid, bool enabled)
552 {
553         return pkgmgrinfo_appinfo_set_usr_state_enabled(appid, enabled, _getuid());
554 }
555
556 API int pkgmgrinfo_appinfo_set_usr_default_label(const char *appid, const char *label, uid_t uid)
557 {
558         int ret;
559         char query[MAX_QUERY_LEN] = {'\0'};
560         char *error_message;
561
562         retvm_if(appid == NULL, PMINFO_R_EINVAL, "appid is NULL\n");
563
564         ret = __open_manifest_db(uid, false);
565         if (ret == -1) {
566                 _LOGE("Fail to open manifest DB\n");
567                 return PMINFO_R_ERROR;
568         }
569
570         /*Begin transaction*/
571         ret = sqlite3_exec(GET_DB(manifest_db), "BEGIN EXCLUSIVE", NULL, NULL, NULL);
572         if (ret != SQLITE_OK) {
573                 _LOGE("Failed to begin transaction\n");
574                 __close_manifest_db();
575                 return PMINFO_R_ERROR;
576         }
577         _LOGD("Transaction Begin\n");
578
579         memset(query, '\0', MAX_QUERY_LEN);
580         snprintf(query, MAX_QUERY_LEN,
581                 "update package_app_localized_info set app_label='%s' where app_id='%s' and app_locale='No Locale'", label, appid);
582
583         if (SQLITE_OK !=
584             sqlite3_exec(GET_DB(manifest_db), query, NULL, NULL, &error_message)) {
585                 _LOGE("Don't execute query = %s error message = %s\n", query,
586                        error_message);
587                 sqlite3_free(error_message);
588                 return PMINFO_R_ERROR;
589         }
590
591         /*Commit transaction*/
592         ret = sqlite3_exec(GET_DB(manifest_db), "COMMIT", NULL, NULL, NULL);
593         if (ret != SQLITE_OK) {
594                 _LOGE("Failed to commit transaction. Rollback now\n");
595                 sqlite3_exec(GET_DB(manifest_db), "ROLLBACK", NULL, NULL, NULL);
596                 __close_manifest_db();
597                 return PMINFO_R_ERROR;
598         }
599         _LOGD("Transaction Commit and End\n");
600         __close_manifest_db();
601         return PMINFO_R_OK;
602 }
603
604 API int pkgmgrinfo_appinfo_set_default_label(const char *appid, const char *label)
605 {
606         return pkgmgrinfo_appinfo_set_usr_default_label(appid, label, _getuid());
607 }
608
609 API int pkgmgrinfo_appinfo_set_usr_guestmode_visibility(pkgmgrinfo_appinfo_h handle, uid_t uid, bool status)
610 {
611         const char *val;
612         int ret;
613         char query[MAX_QUERY_LEN] = {'\0'};
614         char *errmsg;
615         sqlite3 *pkgmgr_parser_db;
616
617         retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL\n");
618
619         pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
620         val = info->app_info->guestmode_visibility;
621         if (val) {
622                 ret = db_util_open_with_options(getUserPkgParserDBPathUID(uid), &pkgmgr_parser_db,
623                                 SQLITE_OPEN_READWRITE, NULL);
624                 if (ret != SQLITE_OK) {
625                         _LOGE("DB Open Failed\n");
626                         return PMINFO_R_ERROR;
627                 }
628
629                 /*TODO: Write to DB here*/
630                 if (status == true)
631                         snprintf(query, MAX_QUERY_LEN, "update package_app_info set app_guestmodevisibility = 'true' where app_id = '%s'", (char *)info->app_info->appid);
632                 else
633                         snprintf(query, MAX_QUERY_LEN, "update package_app_info set app_guestmodevisibility = 'false' where app_id = '%s'", (char *)info->app_info->appid);
634
635                 ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, &errmsg);
636                 sqlite3_close(pkgmgr_parser_db);
637                 if (ret != SQLITE_OK) {
638                         _LOGE("DB update [%s] failed, error message = %s\n", query, errmsg);
639                         free(errmsg);
640                         return PMINFO_R_ERROR;
641                 }
642         }
643         return PMINFO_R_OK;
644 }
645
646 API int pkgmgrinfo_appinfo_set_guestmode_visibility(pkgmgrinfo_appinfo_h handle, bool status)
647 {
648         return pkgmgrinfo_appinfo_set_usr_guestmode_visibility(handle, _getuid(), status);
649 }
650
651 API int pkgmgrinfo_pkginfo_set_usr_installed_storage(const char *pkgid, INSTALL_LOCATION location, uid_t uid)
652 {
653         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "pkgid is NULL\n");
654         int ret = -1;
655         sqlite3 *pkgmgr_parser_db = NULL;
656         char *query = NULL;
657
658         ret = db_util_open_with_options(getUserPkgParserDBPathUID(uid), &pkgmgr_parser_db,
659                         SQLITE_OPEN_READWRITE, NULL);
660         retvm_if(ret != SQLITE_OK, PMINFO_R_ERROR, "connect db failed!");
661
662         /*Begin transaction*/
663         /* Setting Manifest DB */
664         ret = sqlite3_exec(pkgmgr_parser_db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
665         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Failed to begin transaction\n");
666         _LOGD("Transaction Begin\n");
667
668         /* pkgcakge_info table */
669         query = sqlite3_mprintf(
670                         "update package_info set installed_storage=%Q where package=%Q",
671                         location ? "installed_external" : "installed_internal", pkgid);
672
673         ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, NULL);
674         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
675         sqlite3_free(query);
676
677         /* package_app_info table */
678         query = sqlite3_mprintf(
679                         "update package_app_info set app_installed_storage=%Q where package=%Q",
680                         location ? "installed_external" : "installed_internal", pkgid);
681
682         ret = sqlite3_exec(pkgmgr_parser_db, query, NULL, NULL, NULL);
683         tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
684
685         /*Commit transaction*/
686         ret = sqlite3_exec(pkgmgr_parser_db, "COMMIT", NULL, NULL, NULL);
687         if (ret != SQLITE_OK) {
688                 _LOGE("Failed to commit transaction. Rollback now\n");
689                 ret = sqlite3_exec(pkgmgr_parser_db, "ROLLBACK", NULL, NULL, NULL);
690                 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
691         }
692         _LOGD("Transaction Commit and End\n");
693
694         ret = PMINFO_R_OK;
695 catch:
696         sqlite3_close(pkgmgr_parser_db);
697         sqlite3_free(query);
698         return ret;
699 }
700
701 API int pkgmgrinfo_pkginfo_set_installed_storage(const char *pkgid, INSTALL_LOCATION location)
702 {
703         return pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid, location, _getuid());
704 }