4686b5c73802393479300adca214aae72ba98808
[platform/core/appfw/pkgmgr-info.git] / parser / src / pkgmgr_parser_db.c
1 /*
2  * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd. All rights reserved.
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
18 #include <fcntl.h>
19 #include <stdio.h>
20 #include <stdbool.h>
21 #include <string.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <sys/smack.h>
25 #include <sys/sysmacros.h>
26 #include <linux/limits.h>
27 #include <unistd.h>
28 #include <pwd.h>
29
30 #include <glib.h>
31 #include <gio/gio.h>
32 #include <sqlite3.h>
33
34 #include <tzplatform_config.h>
35 #include <system_info.h>
36
37 #include "pkgmgr-info.h"
38 #include "pkgmgrinfo_basic.h"
39 #include "pkgmgr_parser.h"
40 #include "pkgmgr_parser_db_queries.h"
41 #include "pkgmgr_parser_debug.h"
42 #include "pkgmgr_parser_internal.h"
43 #include "manager/pkginfo_manager.h"
44
45 #ifndef OWNER_ROOT
46 #define OWNER_ROOT 0
47 #endif
48 #ifndef GLOBAL_USER
49 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
50 #endif
51 #ifndef APPFW_USER
52 #define APPFW_USER "app_fw"
53 #endif
54
55 #define BUFSIZE 4096
56
57 #define LDPI "ldpi"
58 #define MDPI "mdpi"
59 #define HDPI "hdpi"
60 #define XHDPI "xhdpi"
61 #define XXHDPI "xxhdpi"
62
63 #define LDPI_MIN 0
64 #define LDPI_MAX 240
65 #define MDPI_MIN 241
66 #define MDPI_MAX 300
67 #define HDPI_MIN 301
68 #define HDPI_MAX 380
69 #define XHDPI_MIN 381
70 #define XHDPI_MAX 480
71 #define XXHDPI_MIN 481
72 #define XXHDPI_MAX 600
73
74 /* app background category value */
75 #define APP_BG_CATEGORY_USER_DISABLE_FALSE_VAL 0x00000
76 #define APP_BG_CATEGORY_USER_DISABLE_TRUE_VAL  0x00001
77 #define APP_BG_CATEGORY_MEDIA_VAL              0x00002
78 #define APP_BG_CATEGORY_DOWNLOAD_VAL           0x00004
79 #define APP_BG_CATEGORY_BGNETWORK_VAL          0x00008
80 #define APP_BG_CATEGORY_LOCATION_VAL           0x00010
81 #define APP_BG_CATEGORY_SENSOR_VAL             0x00020
82 #define APP_BG_CATEGORY_IOTCOMM_VAL            0x00040
83 #define APP_BG_CATEGORY_SYSTEM_VAL             0x00080
84
85 #define APP_BG_CATEGORY_USER_DISABLE_FALSE_STR "enable"
86 #define APP_BG_CATEGORY_USER_DISABLE_TRUE_STR  "disable"
87 #define APP_BG_CATEGORY_MEDIA_STR              "media"
88 #define APP_BG_CATEGORY_DOWNLOAD_STR           "download"
89 #define APP_BG_CATEGORY_BGNETWORK_STR          "background-network"
90 #define APP_BG_CATEGORY_LOCATION_STR           "location"
91 #define APP_BG_CATEGORY_SENSOR_STR             "sensor"
92 #define APP_BG_CATEGORY_IOTCOMM_STR            "iot-communication"
93 #define APP_BG_CATEGORY_SYSTEM                 "system"
94
95 #define REGULAR_USER 5000
96 static inline uid_t __getuid(void)
97 {
98         uid_t uid = getuid();
99
100         if (uid < REGULAR_USER)
101                 return tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
102         else
103                 return uid;
104 }
105
106 #define __BEGIN_TRANSACTION(db)                                                \
107 do {                                                                           \
108         if (sqlite3_exec(db, "BEGIN DEFERRED", NULL, NULL, NULL) !=           \
109                         SQLITE_OK) {                                           \
110                 _LOGE("begin transaction failed: %s", sqlite3_errmsg(db));     \
111                 return PM_PARSER_R_ERROR;                                      \
112         }                                                                      \
113 } while (0)                                                                    \
114
115 #define __DO_TRANSACTION(db, func)                                             \
116 do {                                                                           \
117         if (func) {                                                            \
118                 _LOGE("transaction failed: %s, rollback", sqlite3_errmsg(db)); \
119                 if (sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL) !=          \
120                                 SQLITE_OK)                                     \
121                         _LOGE("roll back transaction failed: %s",              \
122                                         sqlite3_errmsg(db));                   \
123                 return PM_PARSER_R_ERROR;                                      \
124         }                                                                      \
125 } while (0)                                                                    \
126
127 #define __END_TRANSACTION(db)                                                  \
128 do {                                                                           \
129         if (sqlite3_exec(db, "COMMIT", NULL, NULL, NULL) !=                    \
130                         SQLITE_OK) {                                           \
131                 _LOGE("commit failed: %s, rollback", sqlite3_errmsg(db));      \
132                 if (sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL) !=          \
133                                 SQLITE_OK)                                     \
134                         _LOGE("roll back transaction failed: %s",              \
135                                         sqlite3_errmsg(db));                   \
136                 return PM_PARSER_R_ERROR;                                      \
137         }                                                                      \
138 } while (0)                                                                    \
139
140 static const char *__get_parser_db_path(uid_t uid)
141 {
142         char buf[PATH_MAX];
143         const char *path;
144
145         if (uid == GLOBAL_USER || uid == OWNER_ROOT) {
146                 path = tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_parser.db");
147         } else {
148                 snprintf(buf, sizeof(buf), "user/%d/.pkgmgr_parser.db", uid);
149                 path = tzplatform_mkpath(TZ_SYS_DB, buf);
150         }
151
152         return path;
153 }
154
155 static const char *__get_cert_db_path(void)
156 {
157         return tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_cert.db");
158 }
159
160 #define DB_VERSION_PATH SYSCONFDIR "/package-manager/pkg_db_version.txt"
161 static int __set_db_version(sqlite3 *db)
162 {
163         int ret;
164         FILE *fp = NULL;
165         char version[PKG_STRING_LEN_MAX] = { 0 };
166         char *query = NULL;
167
168         fp = fopen(DB_VERSION_PATH, "r");
169         retvm_if(fp == NULL, -1, "Failed to open db version file");
170         if (fgets(version, sizeof(version), fp) == NULL) {
171                 _LOGE("Failed to get version information");
172                 fclose(fp);
173                 return -1;
174         }
175         fclose(fp);
176
177         query = sqlite3_mprintf("PRAGMA user_version=%Q", version);
178         if (!query) {
179                 _LOGE("Out of memory");
180                 return -1;
181         }
182
183         ret = sqlite3_exec(db, query, NULL, NULL, NULL);
184         if (ret != SQLITE_OK) {
185                 _LOGE("exec failed: %s", sqlite3_errmsg(db));
186                 sqlite3_free(query);
187                 return -1;
188         }
189         sqlite3_free(query);
190
191         return 0;
192 }
193
194 /* TODO: Do not labeling directly */
195 #define DB_LABEL "User::Home"
196 #define SET_SMACK_LABEL(x)                                                     \
197 do {                                                                           \
198         if (smack_setlabel((x), DB_LABEL, SMACK_LABEL_ACCESS))                 \
199                 _LOGE("failed chsmack -a %s %s", DB_LABEL, x);                 \
200         else                                                                   \
201                 _LOGD("chsmack -a %s %s", DB_LABEL, x);                        \
202 } while (0)
203
204 static int __set_db_permission(const char *path, uid_t uid)
205 {
206         int fd;
207         const char *files[2];
208         char journal_file[BUFSIZE];
209         struct stat sb;
210         mode_t mode;
211         struct passwd pwd;
212         struct passwd *result;
213         char buf[BUFSIZE];
214         int ret;
215         int i;
216
217         if (getuid() != OWNER_ROOT)
218                 return 0;
219
220         if (uid == OWNER_ROOT || uid == GLOBAL_USER) {
221                 ret = getpwnam_r(APPFW_USER, &pwd, buf, sizeof(buf), &result);
222                 if (result == NULL) {
223                         if (ret == 0)
224                                 _LOGE("no such user: %d", uid);
225                         else
226                                 _LOGE("getpwuid_r failed: %d", errno);
227                         return -1;
228                 }
229                 uid = pwd.pw_uid;
230         }
231
232         snprintf(journal_file, sizeof(journal_file), "%s-journal", path);
233         files[0] = path;
234         files[1] = journal_file;
235
236         ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
237         if (result == NULL) {
238                 if (ret == 0)
239                         _LOGE("no such user: %d", uid);
240                 else
241                         _LOGE("getpwuid_r failed: %d", errno);
242                 return -1;
243         }
244
245         for (i = 0; i < 2; i++) {
246                 fd = open(files[i], O_RDONLY);
247                 if (fd == -1) {
248                         _LOGE("open %s failed: %d", files[i], errno);
249                         return -1;
250                 }
251                 ret = fstat(fd, &sb);
252                 if (ret == -1) {
253                         _LOGE("stat %s failed: %d", files[i], errno);
254                         close(fd);
255                         return -1;
256                 }
257                 if (S_ISLNK(sb.st_mode)) {
258                         _LOGE("%s is symlink!", files[i]);
259                         close(fd);
260                         return -1;
261                 }
262                 ret = fchown(fd, uid, pwd.pw_gid);
263                 if (ret == -1) {
264                         _LOGE("fchown %s failed: %d", files[i], errno);
265                         close(fd);
266                         return -1;
267                 }
268
269                 mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
270                 if (!strcmp(path, __get_cert_db_path()))
271                         mode |= S_IWOTH;
272                 ret = fchmod(fd, mode);
273                 if (ret == -1) {
274                         _LOGD("fchmod %s failed: %d", files[i], errno);
275                         close(fd);
276                         return -1;
277                 }
278                 close(fd);
279                 SET_SMACK_LABEL(files[i]);
280         }
281
282         return 0;
283 }
284
285 static int __create_tables(sqlite3 *db, const char **queries)
286 {
287         int ret;
288         int i;
289         for (i = 0; queries[i] != NULL; i++) {
290                 ret = sqlite3_exec(db, queries[i], NULL, NULL, NULL);
291                 if (ret != SQLITE_OK) {
292                         _LOGE("exec failed: %s", sqlite3_errmsg(db));
293                         return -1;
294                 }
295         }
296         return 0;
297 }
298
299 static int __initialize_db(sqlite3 *db, const char *dbpath, uid_t uid)
300 {
301         const char **queries;
302
303         if (__set_db_version(db))
304                 return -1;
305
306         if (strstr(dbpath, ".pkgmgr_parser.db")) {
307                 queries = PARSER_INIT_QUERIES;
308         } else if (strstr(dbpath, ".pkgmgr_cert.db")) {
309                 queries = CERT_INIT_QUERIES;
310         } else {
311                 _LOGE("unexpected dbpath: %s", dbpath);
312                 return -1;
313         }
314
315         __BEGIN_TRANSACTION(db);
316         __DO_TRANSACTION(db, __create_tables(db, queries));
317         __END_TRANSACTION(db);
318
319         if (__set_db_permission(dbpath, uid))
320                 _LOGE("failed to set db permission");
321
322         return 0;
323 }
324
325 #define RESOURCED_BUS_NAME "org.tizen.resourced"
326 #define RESOURCED_PROC_PATH "/Org/Tizen/ResourceD/Process"
327 #define RESOURCED_PROC_INTERFACE "org.tizen.resourced.process"
328 #define RESOURCED_PROC_METHOD "ProcExclude"
329 // This should be removed when the client server structure is complete
330 static void __send_wakeup_signal_to_resourced(pid_t pid)
331 {
332         GError *error = NULL;
333         GDBusConnection *conn;
334         GDBusProxy *proxy;
335         GVariant *reply;
336
337         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
338         if (conn == NULL) {
339                 _LOGE("Failed to connect to dbus: %s", error->message);
340                 g_error_free(error);
341                 return;
342         }
343
344         proxy = g_dbus_proxy_new_sync(conn,
345                         G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
346                         NULL, RESOURCED_BUS_NAME,
347                         RESOURCED_PROC_PATH, RESOURCED_PROC_INTERFACE,
348                         NULL, &error);
349         if (proxy == NULL) {
350                 _LOGE("failed to get proxy object: %s", error->message);
351                 g_error_free(error);
352                 g_object_unref(conn);
353                 return;
354         }
355
356         reply = g_dbus_proxy_call_sync(proxy, RESOURCED_PROC_METHOD,
357                         g_variant_new("(si)", "wakeup", pid),
358                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
359         if (reply == NULL)
360                 _LOGE("failed to get reply from resourced");
361         if (error) {
362                 _LOGE("failed to send request: %s", error->message);
363                 g_error_free(error);
364         }
365
366         g_object_unref(proxy);
367         g_object_unref(conn);
368 }
369
370 // This should be removed when the client server structure is complete
371 static void __check_db_lock(const char *dbpath)
372 {
373         FILE *fp;
374         FILE *fp_cmdline;
375         struct stat sb;
376         char type[BUFSIZE];
377         int pid;
378         unsigned int maj;
379         unsigned int min;
380         unsigned long long ino;
381         char cmdline[BUFSIZE];
382         char name[BUFSIZE];
383         size_t len;
384
385         if (stat(dbpath, &sb) == -1) {
386                 _LOGE("get db file(%s) status failed: %d", dbpath, errno);
387                 return;
388         }
389
390         fp = fopen("/proc/locks", "r");
391         if (fp == NULL) {
392                 _LOGE("Failed to open lock info: %d", errno);
393                 return;
394         }
395
396         while (fscanf(fp, "%*s %*s %*s %5s %d %x:%x:%llu %*s %*s",
397                                 type, &pid, &maj, &min, &ino) != EOF) {
398                 if (maj != major(sb.st_dev) || min != minor(sb.st_dev) ||
399                                 ino != sb.st_ino || pid == getpid() ||
400                                 strcasecmp(type, "WRITE"))
401                         continue;
402
403                 snprintf(cmdline, sizeof(cmdline), "/proc/%d/cmdline", pid);
404                 fp_cmdline = fopen(cmdline, "r");
405                 name[0] = '\0';
406                 if (fp_cmdline != NULL) {
407                         len = fread(name, sizeof(char), sizeof(name) - 1,
408                                         fp_cmdline);
409                         if (len > 0) {
410                                 if (name[len - 1] == '\n')
411                                         name[len - 1] = '\0';
412                                 else
413                                         name[len] = '\0';
414                         }
415                         fclose(fp_cmdline);
416                 }
417
418                 _LOGE("%s (%d) has lock on pkgmgr db(%s)!", name, pid, dbpath);
419                 __send_wakeup_signal_to_resourced(pid);
420         }
421
422         fclose(fp);
423 }
424
425 #define BUSY_WAITING_USEC (1000000 / 10 / 2) /* 0.05 sec */
426 #define BUSY_WAITING_MAX 100 /* wait for max 5 sec */
427
428 // This should be removed when the client server structure is complete
429 static int __db_busy_handler(void *data, int count)
430 {
431         if (count < (BUSY_WAITING_MAX / 2)) {
432                 usleep(BUSY_WAITING_USEC);
433                 return 1;
434         } else if (count == (BUSY_WAITING_MAX / 2)) {
435                 __check_db_lock((const char *)data);
436                 usleep(BUSY_WAITING_USEC);
437                 return 1;
438         } else if (count < BUSY_WAITING_MAX) {
439                 usleep(BUSY_WAITING_USEC);
440                 return 1;
441         } else {
442                 /* sqlite3_prepare_v2 will return SQLITE_BUSY */
443                 return 0;
444         }
445 }
446
447 API int pkgmgr_parser_initialize_parser_db(uid_t uid)
448 {
449         int ret;
450         const char *dbpath;
451         sqlite3 *db;
452
453         dbpath = __get_parser_db_path(uid);
454         if (access(dbpath, F_OK) != -1) {
455                 _LOGE("Manifest db for user %d is already exists", uid);
456                 return PM_PARSER_R_ERROR;
457         }
458
459         ret = sqlite3_open_v2(dbpath, &db,
460                         SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
461         if (ret != SQLITE_OK) {
462                 _LOGE("open db failed: %d", ret);
463                 sqlite3_close_v2(db);
464                 return PM_PARSER_R_ERROR;
465         }
466
467         ret = sqlite3_busy_handler(db, __db_busy_handler, NULL);
468         if (ret != SQLITE_OK) {
469                 _LOGE("failed to register busy handler: %s",
470                                 sqlite3_errmsg(db));
471                 sqlite3_close_v2(db);
472                 return ret;
473         }
474
475         if (__initialize_db(db, dbpath, uid)) {
476                 sqlite3_close_v2(db);
477                 return PM_PARSER_R_ERROR;
478         }
479         sqlite3_close_v2(db);
480
481         return PM_PARSER_R_OK;
482 }
483
484 API int pkgmgr_parser_initialize_cert_db(void)
485 {
486         int ret;
487         const char *dbpath;
488         sqlite3 *db;
489
490         dbpath = __get_cert_db_path();
491         if (access(dbpath, F_OK) != -1) {
492                 _LOGE("Cert db is already exists");
493                 return PM_PARSER_R_ERROR;
494         }
495
496         ret = sqlite3_open_v2(dbpath, &db,
497                         SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
498         if (ret != SQLITE_OK) {
499                 _LOGE("open db failed: %d", ret);
500                 sqlite3_close_v2(db);
501                 return PM_PARSER_R_ERROR;
502         }
503
504         ret = sqlite3_busy_handler(db, __db_busy_handler, NULL);
505         if (ret != SQLITE_OK) {
506                 _LOGE("failed to register busy handler: %s",
507                                 sqlite3_errmsg(db));
508                 sqlite3_close_v2(db);
509                 return ret;
510         }
511
512         if (__initialize_db(db, dbpath, GLOBAL_USER)) {
513                 sqlite3_close_v2(db);
514                 return PM_PARSER_R_ERROR;
515         }
516         sqlite3_close_v2(db);
517
518         return PM_PARSER_R_OK;
519 }
520
521 API int pkgmgr_parser_create_and_initialize_db(uid_t uid)
522 {
523         int ret;
524         struct passwd pwd;
525         struct passwd *result;
526         char buf[BUFSIZE];
527
528         ret = getpwnam_r(APPFW_USER, &pwd, buf, sizeof(buf), &result);
529         if (result == NULL) {
530                 if (ret == 0)
531                         _LOGE("no such user: %s", APPFW_USER);
532                 else
533                         _LOGE("getpwnam_r failed: %d", errno);
534                 return PM_PARSER_R_ERROR;
535         }
536
537         if (getuid() != OWNER_ROOT && getuid() != pwd.pw_uid) {
538                 _LOGE("Only root or app_fw user is allowed");
539                 return PM_PARSER_R_EINVAL;
540         }
541
542         if (pkgmgr_parser_initialize_parser_db(uid))
543                 return PM_PARSER_R_ERROR;
544
545         if (uid == OWNER_ROOT || uid == GLOBAL_USER)
546                 if (pkgmgr_parser_initialize_cert_db())
547                         return PM_PARSER_R_ERROR;
548
549         return PM_PARSER_R_OK;
550 }
551
552 /* TODO: move to installer */
553
554 /* TODO: refactor inserting localized info */
555
556 static int __insert_package_plugin_execution_info(
557                 manifest_x *mfx, uid_t uid)
558 {
559         GList *tmp;
560         plugin_x *plugin;
561         char **queries = NULL;
562         int idx = 0;
563         int i = 0;
564
565         if (!mfx->plugin)
566                 return PM_PARSER_R_OK;
567
568         queries = calloc(g_list_length(mfx->plugin), sizeof (char *));
569         if (queries == NULL) {
570                 _LOGE("Out of memory");
571                 return PM_PARSER_R_ERROR;
572         }
573
574         for (tmp = mfx->plugin; tmp; tmp = tmp->next) {
575                 plugin = (plugin_x *)tmp->data;
576                 if (plugin == NULL)
577                         continue;
578
579                 queries[idx] = sqlite3_mprintf("INSERT INTO package_plugin_info "
580                                 "(pkgid, appid, plugin_type, plugin_name) "
581                                 "VALUES (%Q, %Q, %Q, %Q)",
582                                 plugin->pkgid, plugin->appid,
583                                 plugin->plugin_type, plugin->plugin_name);
584                 if (queries[idx] == NULL) {
585                         _LOGE("Out of memory");
586                         for (i = 0; i < idx; ++i)
587                                 sqlite3_free(queries[i]);
588                         free(queries);
589                         return PM_PARSER_R_ERROR;
590                 }
591
592                 idx++;
593         }
594
595         if (_parser_execute_write_queries((const char **)queries, idx, uid) < 0) {
596                 _LOGE("Fail to write to db");
597                 for (i = 0; i < idx; ++i)
598                         sqlite3_free(queries[i]);
599                 free(queries);
600                 return PM_PARSER_R_ERROR;
601         }
602
603         for (i = 0; i < idx; ++i)
604                 sqlite3_free(queries[i]);
605         free(queries);
606
607         return PM_PARSER_R_OK;
608 }
609
610 static int __delete_package_plugin_execution_info(const char *pkgid, uid_t uid)
611 {
612         char *query = NULL;
613
614         query = sqlite3_mprintf(
615                         "DELETE FROM package_plugin_info WHERE pkgid=%Q", pkgid);
616         if (query == NULL) {
617                 _LOGE("Out of memory");
618                 return PM_PARSER_R_ERROR;
619         }
620
621         if (_parser_execute_write_query(query, uid) < 0) {
622                 _LOGE("Fail to write to db");
623                 sqlite3_free(query);
624                 return PM_PARSER_R_ERROR;
625         }
626         sqlite3_free(query);
627
628         return PM_PARSER_R_OK;
629 }
630
631 API int pkgmgr_parser_insert_manifest_info_in_usr_db(manifest_x *mfx, uid_t uid)
632 {
633         if (_parser_insert_manifest_info(mfx, uid) < 0) {
634                 _LOGE("Fail to insert manifest uid[%d]", uid);
635                 return PM_PARSER_R_ERROR;
636         }
637
638         return PM_PARSER_R_OK;
639 }
640
641 API int pkgmgr_parser_insert_manifest_info_in_db(manifest_x *mfx)
642 {
643         return pkgmgr_parser_insert_manifest_info_in_usr_db(mfx, __getuid());
644 }
645
646 API int pkgmgr_parser_delete_manifest_info_from_usr_db(manifest_x *mfx,
647         uid_t uid)
648 {
649         if (_parser_delete_manifest_info(mfx, uid) < 0) {
650                 _LOGE("Fail to update manifest uid[%d]", uid);
651                 return PM_PARSER_R_ERROR;
652         }
653
654         return PM_PARSER_R_OK;
655 }
656
657 API int pkgmgr_parser_delete_manifest_info_from_db(manifest_x *mfx)
658 {
659         return pkgmgr_parser_delete_manifest_info_from_usr_db(mfx, __getuid());
660 }
661
662 API int pkgmgr_parser_update_manifest_info_in_usr_db(manifest_x *mfx, uid_t uid)
663 {
664         if (_parser_update_manifest_info(mfx, uid) < 0) {
665                 _LOGE("Fail to update manifest uid[%d]", uid);
666                 return PM_PARSER_R_ERROR;
667         }
668
669         return PM_PARSER_R_OK;
670 }
671
672 API int pkgmgr_parser_update_manifest_info_in_db(manifest_x *mfx)
673 {
674         return pkgmgr_parser_update_manifest_info_in_usr_db(mfx, __getuid());
675 }
676
677 API int pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(
678                 const char *appid, uid_t uid, int is_disable)
679 {
680         // TODO: construct query at here and send it to server
681         char *query = NULL;
682
683         query = sqlite3_mprintf("INSERT OR REPLACE INTO package_app_info_for_uid ("
684                         "  app_id, uid, is_disabled, is_splash_screen_enabled) "
685                         "VALUES (%Q, %u, %Q,"
686                         "  (SELECT app_splash_screen_display FROM package_app_info"
687                         "   WHERE app_id=%Q))", appid, uid,
688                         (is_disable ? "true" : "false"), appid);
689         if (query == NULL) {
690                 _LOGE("Out of memory");
691                 return PM_PARSER_R_ERROR;
692         }
693
694         if (_parser_execute_write_query(query, uid) < 0) {
695                 _LOGE("Fail to write to db");
696                 sqlite3_free(query);
697                 return PM_PARSER_R_ERROR;
698         }
699         sqlite3_free(query);
700
701         return PM_PARSER_R_OK;
702 }
703
704 API int pkgmgr_parser_update_app_disable_info_in_usr_db(const char *appid,
705                 uid_t uid, int is_disable)
706 {
707         char *query = NULL;
708
709         query = sqlite3_mprintf("UPDATE package_app_info SET app_disable=%Q "
710                 "WHERE app_id=%Q", (is_disable ? "true" : "false"), appid);
711         if (query == NULL) {
712                 _LOGE("Out of memory");
713                 return PM_PARSER_R_ERROR;
714         }
715
716         if (_parser_execute_write_query(query, uid) < 0) {
717                 _LOGE("Fail to write to db");
718                 sqlite3_free(query);
719                 return PM_PARSER_R_ERROR;
720         }
721         sqlite3_free(query);
722
723         return PM_PARSER_R_OK;
724 }
725
726 API int pkgmgr_parser_update_app_disable_info_in_db(const char *appid,
727                 int is_disable)
728 {
729         return pkgmgr_parser_update_app_disable_info_in_usr_db(appid,
730                         __getuid(), is_disable);
731 }
732
733 API int pkgmgr_parser_update_pkg_disable_info_in_usr_db(const char *pkgid,
734                 uid_t uid, int is_disable)
735 {
736         char *query = NULL;
737
738         query = sqlite3_mprintf("UPDATE package_info SET package_disable=%Q "
739                         "WHERE package=%Q", (is_disable ? "true" : "false"), pkgid);
740         if (query == NULL) {
741                 _LOGE("Out of memory");
742                 return PM_PARSER_R_ERROR;
743         }
744
745         if (_parser_execute_write_query(query, uid) < 0) {
746                 _LOGE("Fail to write to db");
747                 sqlite3_free(query);
748                 return PM_PARSER_R_ERROR;
749         }
750         sqlite3_free(query);
751
752         return PM_PARSER_R_OK;
753 }
754
755 API int pkgmgr_parser_update_pkg_disable_info_in_db(const char *pkgid,
756                 int is_disable)
757 {
758         return pkgmgr_parser_update_pkg_disable_info_in_usr_db(pkgid,
759                         __getuid(), is_disable);
760 }
761
762 API int pkgmgr_parser_update_global_app_splash_screen_display_info_in_usr_db(
763                 const char *appid, uid_t uid, int flag)
764 {
765         char *query = NULL;
766
767         query = sqlite3_mprintf("INSERT OR REPLACE INTO package_app_info_for_uid("
768                 "  app_id, uid, is_splash_screen_enabled) "
769                 "VALUES (%Q, %u, %Q)", appid, uid, (flag == 1 ? "true" : "false"));
770         if (query == NULL) {
771                 _LOGE("Out of memory");
772                 return PM_PARSER_R_ERROR;
773         }
774
775         if (_parser_execute_write_query(query, uid) < 0) {
776                 _LOGE("Fail to write to db");
777                 sqlite3_free(query);
778                 return PM_PARSER_R_ERROR;
779         }
780         sqlite3_free(query);
781
782         return PM_PARSER_R_OK;
783 }
784
785 API int pkgmgr_parser_update_app_splash_screen_display_info_in_usr_db(
786                 const char *appid, uid_t uid, int flag)
787 {
788         char *query = NULL;
789
790         query = sqlite3_mprintf("UPDATE package_app_info SET app_splash_screen_display=%Q "
791                 "WHERE app_id=%Q", (flag == 1 ? "true" : "false"), appid);
792         if (query == NULL) {
793                 _LOGE("Out of memory");
794                 return PM_PARSER_R_ERROR;
795         }
796
797         if (_parser_execute_write_query(query, uid) < 0) {
798                 _LOGE("Fail to write to db");
799                 sqlite3_free(query);
800                 return PM_PARSER_R_ERROR;
801         }
802         sqlite3_free(query);
803
804         return PM_PARSER_R_OK;
805 }
806
807 API int pkgmgr_parser_update_app_splash_screen_display_info_in_db(
808                 const char *appid, int flag)
809 {
810         return pkgmgr_parser_update_app_splash_screen_display_info_in_usr_db(
811                         appid, __getuid(), flag);
812 }
813
814 API int pkgmgr_parser_update_app_label_info_in_usr_db(const char *appid,
815                 uid_t uid, const char *label)
816 {
817         char *query = NULL;
818
819         query = sqlite3_mprintf("UPDATE package_app_localized_info SET app_label=%Q "
820                 "WHERE app_id=%Q AND app_label IS NOT NULL", label, appid);
821         if (query == NULL) {
822                 _LOGE("Out of memory");
823                 return PM_PARSER_R_ERROR;
824         }
825
826         if (_parser_execute_write_query(query, uid) < 0) {
827                 _LOGE("Fail to write to db");
828                 sqlite3_free(query);
829                 return PM_PARSER_R_ERROR;
830         }
831         sqlite3_free(query);
832
833         return PM_PARSER_R_OK;
834 }
835
836 API int pkgmgr_parser_update_app_label_info_in_db(const char *appid,
837                 const char *label)
838 {
839         return pkgmgr_parser_update_app_label_info_in_usr_db(appid, __getuid(),
840                         label);
841 }
842
843 API int pkgmgr_parser_update_app_icon_info_in_usr_db(const char *appid,
844                 uid_t uid, const char *icon_path)
845 {
846         char *query = NULL;
847
848         query = sqlite3_mprintf("UPDATE package_app_localized_info SET app_icon=%Q "
849                 "WHERE app_id=%Q AND app_icon IS NOT NULL", icon_path, appid);
850         if (query == NULL) {
851                 _LOGE("Out of memory");
852                 return PM_PARSER_R_ERROR;
853         }
854
855         if (_parser_execute_write_query(query, uid) < 0) {
856                 _LOGE("Fail to write to db");
857                 sqlite3_free(query);
858                 return PM_PARSER_R_ERROR;
859         }
860         sqlite3_free(query);
861
862         return PM_PARSER_R_OK;
863 }
864
865 API int pkgmgr_parser_update_app_icon_info_in_db(const char *appid,
866                 const char *icon_path)
867 {
868         return pkgmgr_parser_update_app_icon_info_in_usr_db(appid, __getuid(),
869                         icon_path);
870 }
871
872 API int pkgmgr_parser_update_tep_info_in_usr_db(const char *pkgid,
873                 const char *tep_path, uid_t uid)
874 {
875         char *query = NULL;
876
877         query = sqlite3_mprintf("UPDATE package_info SET package_tep_name=%Q "
878                 "WHERE package=%Q", tep_path, pkgid);
879         if (query == NULL) {
880                 _LOGE("Out of memory");
881                 return PM_PARSER_R_ERROR;
882         }
883
884         if (_parser_execute_write_query(query, uid) < 0) {
885                 _LOGE("Fail to write to db");
886                 sqlite3_free(query);
887                 return PM_PARSER_R_ERROR;
888         }
889         sqlite3_free(query);
890
891         return PM_PARSER_R_OK;
892 }
893
894 API int pkgmgr_parser_update_tep_info_in_db(const char *pkgid,
895                 const char *tep_path)
896 {
897         return pkgmgr_parser_update_tep_info_in_usr_db(pkgid, tep_path,
898                         __getuid());
899 }
900
901 static int __convert_update_type(pkgmgrinfo_updateinfo_update_type type,
902                 const char **update_type)
903 {
904         if (type == PMINFO_UPDATEINFO_NONE)
905                 *update_type = PMINFO_UPDATEINFO_TYPE_NONE;
906         else if (type == PMINFO_UPDATEINFO_FORCE)
907                 *update_type = PMINFO_UPDATEINFO_TYPE_FORCE;
908         else if (type == PMINFO_UPDATEINFO_OPTIONAL)
909                 *update_type = PMINFO_UPDATEINFO_TYPE_OPTIONAL;
910         else
911                 return -1;
912         return 0;
913 }
914
915 static int __register_pkg_update_info(updateinfo_x *info,
916                 const char *update_type, uid_t uid)
917 {
918         char *query = NULL;
919
920         query = sqlite3_mprintf("UPDATE package_update_info "
921                 "SET update_version=%Q, update_type=%Q "
922                 "WHERE package=%Q", info->version, update_type, info->pkgid);
923         if (query == NULL) {
924                 _LOGE("Out of memory");
925                 return PM_PARSER_R_ERROR;
926         }
927
928         if (_parser_execute_write_query(query, uid) < 0) {
929                 _LOGE("Fail to write to db");
930                 sqlite3_free(query);
931                 return PM_PARSER_R_ERROR;
932         }
933         sqlite3_free(query);
934
935         return PM_PARSER_R_OK;
936 }
937
938 API int pkgmgr_parser_register_pkg_update_info_in_usr_db(
939                 pkgmgrinfo_updateinfo_h handle, uid_t uid)
940 {
941         int ret;
942         updateinfo_x *update_info;
943         updateinfo_x *prev_update_info;
944         pkgmgrinfo_updateinfo_h prev_update_handle;
945         pkgmgrinfo_pkginfo_h pkginfo;
946         pkgmgrinfo_version_compare_type compare_result;
947         bool is_global_pkg;
948         const char *update_type;
949
950         if (handle == NULL) {
951                 _LOGE("invalid parameter");
952                 return PM_PARSER_R_EINVAL;
953         }
954
955         update_info = (updateinfo_x *)handle;
956         if (update_info->pkgid == NULL || update_info->version == NULL)
957                 return PM_PARSER_R_EINVAL;
958         if (__convert_update_type(update_info->type, &update_type) != 0)
959                 return PM_PARSER_R_EINVAL;
960
961         ret = pkgmgrinfo_updateinfo_get_usr_updateinfo(update_info->pkgid,
962                         &prev_update_handle, uid);
963         if (ret != PMINFO_R_OK)
964                 return PM_PARSER_R_ERROR;
965
966         prev_update_info = (updateinfo_x *)prev_update_handle;
967         ret = pkgmgrinfo_compare_package_version(update_info->version,
968                         prev_update_info->version, &compare_result);
969         if (ret != PMINFO_R_OK) {
970                 pkgmgrinfo_updateinfo_destroy(prev_update_handle);
971                 return PM_PARSER_R_ERROR;
972         }
973
974         if (compare_result == PMINFO_VERSION_SAME &&
975                         prev_update_info->type == PMINFO_UPDATEINFO_NONE) {
976                 _LOGI("Given update info version[%s] of pkgid[%s] "
977                                 "will be ignored",
978                                 update_info->version, update_info->pkgid);
979                 pkgmgrinfo_updateinfo_destroy(prev_update_handle);
980                 return PM_PARSER_R_OK;
981         }
982         pkgmgrinfo_updateinfo_destroy(prev_update_handle);
983
984         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(update_info->pkgid, uid,
985                         &pkginfo);
986         if (ret != PMINFO_R_OK)
987                 return PM_PARSER_R_ERROR;
988
989         ret = pkgmgrinfo_pkginfo_is_global(pkginfo, &is_global_pkg);
990         if (ret != PMINFO_R_OK) {
991                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
992                 return PM_PARSER_R_ERROR;
993         }
994         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
995
996         return __register_pkg_update_info(update_info, update_type, uid);
997 }
998
999 API int pkgmgr_parser_register_pkg_update_info_in_db(
1000                 pkgmgrinfo_updateinfo_h handle)
1001 {
1002         return pkgmgr_parser_register_pkg_update_info_in_usr_db(handle,
1003                         __getuid());
1004 }
1005
1006 static int __unregister_pkg_update_info(const char *pkgid, uid_t uid)
1007 {
1008         char *query = NULL;
1009
1010         query = sqlite3_mprintf("UPDATE package_update_info "
1011                 "SET update_type='none' WHERE package=%Q", pkgid);
1012         if (query == NULL) {
1013                 _LOGE("Out of memory");
1014                 return PM_PARSER_R_ERROR;
1015         }
1016
1017         if (_parser_execute_write_query(query, uid) < 0) {
1018                 _LOGE("Fail to write to db");
1019                 sqlite3_free(query);
1020                 return PM_PARSER_R_ERROR;
1021         }
1022         sqlite3_free(query);
1023
1024         return PM_PARSER_R_OK;
1025 }
1026
1027 API int pkgmgr_parser_unregister_pkg_update_info_in_usr_db(const char *pkgid,
1028                 uid_t uid)
1029 {
1030         int ret;
1031         pkgmgrinfo_pkginfo_h pkginfo;
1032         bool is_global_pkg;
1033         uid_t target_uid;
1034
1035         if (pkgid == NULL) {
1036                 _LOGE("invalid parameter");
1037                 return PM_PARSER_R_EINVAL;
1038         }
1039
1040         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &pkginfo);
1041         if (ret != PMINFO_R_OK)
1042                 return PM_PARSER_R_EINVAL;
1043
1044         ret = pkgmgrinfo_pkginfo_is_global(pkginfo, &is_global_pkg);
1045         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
1046         if (ret != PMINFO_R_OK)
1047                 return PM_PARSER_R_ERROR;
1048
1049         target_uid = is_global_pkg ? GLOBAL_USER : uid;
1050
1051         // TODO: what we do with is_global_pkg?
1052         return __unregister_pkg_update_info(pkgid, target_uid);
1053 }
1054
1055 API int pkgmgr_parser_unregister_pkg_update_info_in_db(const char *pkgid)
1056 {
1057         return pkgmgr_parser_unregister_pkg_update_info_in_usr_db(pkgid,
1058                         __getuid());
1059 }
1060
1061 API int pkgmgr_parser_unregister_all_pkg_update_info_in_usr_db(uid_t uid)
1062 {
1063         char *query = NULL;
1064
1065         query = sqlite3_mprintf("UPDATE package_update_info "
1066                         "SET update_type='none'");
1067         if (query == NULL) {
1068                 _LOGE("Out of memory");
1069                 return PM_PARSER_R_ERROR;
1070         }
1071
1072         if (_parser_execute_write_query(query, uid) < 0) {
1073                 _LOGE("Fail to write to db");
1074                 sqlite3_free(query);
1075                 return PM_PARSER_R_ERROR;
1076         }
1077         sqlite3_free(query);
1078
1079         return PM_PARSER_R_OK;
1080 }
1081
1082 API int pkgmgr_parser_unregister_all_pkg_update_info_in_db(void)
1083 {
1084         return pkgmgr_parser_unregister_all_pkg_update_info_in_usr_db(
1085                         __getuid());
1086 }
1087
1088 API int pkgmgr_parser_register_pkg_plugin_info_in_usr_db(
1089                 manifest_x *mfx, uid_t uid)
1090 {
1091         return __insert_package_plugin_execution_info(mfx, uid);
1092 }
1093
1094 API int pkgmgr_parser_register_pkg_plugin_info_in_db(manifest_x *mfx)
1095 {
1096         return pkgmgr_parser_register_pkg_plugin_info_in_usr_db(mfx, __getuid());
1097 }
1098
1099 API int pkgmgr_parser_update_pkg_plugin_info_in_usr_db(
1100                 manifest_x *mfx, uid_t uid)
1101 {
1102         // TODO: construct query and send to server
1103         int ret;
1104
1105         ret = __delete_package_plugin_execution_info(mfx->package, uid);
1106         if (ret != PM_PARSER_R_OK)
1107                 return ret;
1108         ret = __insert_package_plugin_execution_info(mfx, uid);
1109         if (ret != PM_PARSER_R_OK)
1110                 return ret;
1111
1112         return PM_PARSER_R_OK;
1113 }
1114
1115 API int pkgmgr_parser_update_pkg_plugin_info_in_db(manifest_x *mfx)
1116 {
1117         return pkgmgr_parser_update_pkg_plugin_info_in_usr_db(mfx, __getuid());
1118 }
1119
1120 API int pkgmgr_parser_unregister_pkg_plugin_info_in_usr_db(
1121                 const char *pkgid, uid_t uid)
1122 {
1123         return __delete_package_plugin_execution_info(pkgid, uid);
1124 }
1125
1126 API int pkgmgr_parser_unregister_pkg_plugin_info_in_db(const char *pkgid)
1127 {
1128         return pkgmgr_parser_unregister_pkg_plugin_info_in_usr_db(pkgid, __getuid());
1129 }
1130
1131 API int pkgmgr_parser_clear_cache_memory_db()
1132 {
1133         return pkgmgr_parser_clear_cache_usr_memory_db(__getuid());
1134 }
1135
1136 API int pkgmgr_parser_clear_cache_usr_memory_db(uid_t uid)
1137 {
1138         return _parser_clear_cache_memory_db(uid);
1139 }