Add busy handler when initializing pkg db
[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 <linux/limits.h>
26 #include <unistd.h>
27 #include <pwd.h>
28
29 #include <glib.h>
30 #include <gio/gio.h>
31 #include <sqlite3.h>
32
33 #include <tzplatform_config.h>
34 #include <system_info.h>
35
36 #include "pkgmgr-info.h"
37 #include "pkgmgrinfo_basic.h"
38 #include "pkgmgr_parser.h"
39 #include "pkgmgr_parser_db_queries.h"
40 #include "pkgmgr_parser_debug.h"
41 #include "pkgmgr_parser_internal.h"
42
43 #ifndef OWNER_ROOT
44 #define OWNER_ROOT 0
45 #endif
46 #ifndef GLOBAL_USER
47 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
48 #endif
49 #ifndef APPFW_USER
50 #define APPFW_USER "app_fw"
51 #endif
52
53 #define BUFSIZE 4096
54
55 #define LDPI "ldpi"
56 #define MDPI "mdpi"
57 #define HDPI "hdpi"
58 #define XHDPI "xhdpi"
59 #define XXHDPI "xxhdpi"
60
61 #define LDPI_MIN 0
62 #define LDPI_MAX 240
63 #define MDPI_MIN 241
64 #define MDPI_MAX 300
65 #define HDPI_MIN 301
66 #define HDPI_MAX 380
67 #define XHDPI_MIN 381
68 #define XHDPI_MAX 480
69 #define XXHDPI_MIN 481
70 #define XXHDPI_MAX 600
71
72 /* app background category value */
73 #define APP_BG_CATEGORY_USER_DISABLE_FALSE_VAL 0x00000
74 #define APP_BG_CATEGORY_USER_DISABLE_TRUE_VAL  0x00001
75 #define APP_BG_CATEGORY_MEDIA_VAL              0x00002
76 #define APP_BG_CATEGORY_DOWNLOAD_VAL           0x00004
77 #define APP_BG_CATEGORY_BGNETWORK_VAL          0x00008
78 #define APP_BG_CATEGORY_LOCATION_VAL           0x00010
79 #define APP_BG_CATEGORY_SENSOR_VAL             0x00020
80 #define APP_BG_CATEGORY_IOTCOMM_VAL            0x00040
81 #define APP_BG_CATEGORY_SYSTEM_VAL             0x00080
82
83 #define APP_BG_CATEGORY_USER_DISABLE_FALSE_STR "enable"
84 #define APP_BG_CATEGORY_USER_DISABLE_TRUE_STR  "disable"
85 #define APP_BG_CATEGORY_MEDIA_STR              "media"
86 #define APP_BG_CATEGORY_DOWNLOAD_STR           "download"
87 #define APP_BG_CATEGORY_BGNETWORK_STR          "background-network"
88 #define APP_BG_CATEGORY_LOCATION_STR           "location"
89 #define APP_BG_CATEGORY_SENSOR_STR             "sensor"
90 #define APP_BG_CATEGORY_IOTCOMM_STR            "iot-communication"
91 #define APP_BG_CATEGORY_SYSTEM                 "system"
92
93 #define REGULAR_USER 5000
94 static inline uid_t __getuid(void)
95 {
96         uid_t uid = getuid();
97
98         if (uid < REGULAR_USER)
99                 return tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
100         else
101                 return uid;
102 }
103
104 static const char *__get_bool(char *value, bool is_true)
105 {
106         if (value != NULL) {
107                 if (!strcmp(value, ""))
108                         return (is_true) ? "true" : "false";
109                 return value;
110         }
111
112         return (is_true) ? "true" : "false";
113 }
114
115 #define __BEGIN_TRANSACTION(db)                                                \
116 do {                                                                           \
117         if (sqlite3_exec(db, "BEGIN DEFERRED", NULL, NULL, NULL) !=           \
118                         SQLITE_OK) {                                           \
119                 _LOGE("begin transaction failed: %s", sqlite3_errmsg(db));     \
120                 sqlite3_close_v2(db);                                          \
121                 return PM_PARSER_R_ERROR;                                      \
122         }                                                                      \
123 } while (0)                                                                    \
124
125 #define __DO_TRANSACTION(db, func)                                             \
126 do {                                                                           \
127         if (func) {                                                            \
128                 _LOGE("transaction failed: %s, rollback", sqlite3_errmsg(db)); \
129                 if (sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL) !=          \
130                                 SQLITE_OK)                                     \
131                         _LOGE("roll back transaction failed: %s",              \
132                                         sqlite3_errmsg(db));                   \
133                 sqlite3_close_v2(db);                                          \
134                 return PM_PARSER_R_ERROR;                                      \
135         }                                                                      \
136 } while (0)                                                                    \
137
138 #define __END_TRANSACTION(db)                                                  \
139 do {                                                                           \
140         if (sqlite3_exec(db, "COMMIT", NULL, NULL, NULL) !=                    \
141                         SQLITE_OK) {                                           \
142                 _LOGE("commit failed: %s, rollback", sqlite3_errmsg(db));      \
143                 if (sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL) !=          \
144                                 SQLITE_OK)                                     \
145                         _LOGE("roll back transaction failed: %s",              \
146                                         sqlite3_errmsg(db));                   \
147                 sqlite3_close_v2(db);                                          \
148                 return PM_PARSER_R_ERROR;                                      \
149         }                                                                      \
150 } while (0)                                                                    \
151
152 #define __BIND_TEXT(db, stmt, i, text)                                         \
153 do {                                                                           \
154         if (sqlite3_bind_text(stmt, i, text, -1, SQLITE_STATIC) != SQLITE_OK) {\
155                 _LOGE("bind error(index %d): %s", i, sqlite3_errmsg(db));      \
156                 sqlite3_finalize(stmt);                                        \
157                 return -1;                                                     \
158         }                                                                      \
159 } while (0)
160
161 #define __BIND_INT(db, stmt, i, int)                                           \
162 do {                                                                           \
163         if (sqlite3_bind_int(stmt, i, int) != SQLITE_OK) {                     \
164                 _LOGE("bind error(index %d): %s", i, sqlite3_errmsg(db));      \
165                 sqlite3_finalize(stmt);                                        \
166                 return -1;                                                     \
167         }                                                                      \
168 } while (0)
169
170 static const char *__get_parser_db_path(uid_t uid)
171 {
172         char buf[PATH_MAX];
173         const char *path;
174
175         if (uid == GLOBAL_USER || uid == OWNER_ROOT) {
176                 path = tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_parser.db");
177         } else {
178                 snprintf(buf, sizeof(buf), "user/%d/.pkgmgr_parser.db", uid);
179                 path = tzplatform_mkpath(TZ_SYS_DB, buf);
180         }
181
182         return path;
183 }
184
185 static const char *__get_cert_db_path(void)
186 {
187         return tzplatform_mkpath(TZ_SYS_DB, ".pkgmgr_cert.db");
188 }
189
190 #define DB_VERSION_PATH SYSCONFDIR "/package-manager/pkg_db_version.txt"
191 static int __set_db_version(sqlite3 *db)
192 {
193         int ret;
194         FILE *fp = NULL;
195         char version[PKG_STRING_LEN_MAX] = { 0 };
196         char *query = NULL;
197
198         fp = fopen(DB_VERSION_PATH, "r");
199         retvm_if(fp == NULL, -1, "Failed to open db version file");
200         if (fgets(version, sizeof(version), fp) == NULL) {
201                 _LOGE("Failed to get version information");
202                 fclose(fp);
203                 return -1;
204         }
205         fclose(fp);
206
207         query = sqlite3_mprintf("PRAGMA user_version=%Q", version);
208         if (!query) {
209                 _LOGE("Out of memory");
210                 return -1;
211         }
212
213         ret = sqlite3_exec(db, query, NULL, NULL, NULL);
214         if (ret != SQLITE_OK) {
215                 _LOGE("exec failed: %s", sqlite3_errmsg(db));
216                 sqlite3_free(query);
217                 return -1;
218         }
219         sqlite3_free(query);
220
221         return 0;
222 }
223
224 /* TODO: Do not labeling directly */
225 #define DB_LABEL "User::Home"
226 #define SET_SMACK_LABEL(x)                                                     \
227 do {                                                                           \
228         if (smack_setlabel((x), DB_LABEL, SMACK_LABEL_ACCESS))                 \
229                 _LOGE("failed chsmack -a %s %s", DB_LABEL, x);                 \
230         else                                                                   \
231                 _LOGD("chsmack -a %s %s", DB_LABEL, x);                        \
232 } while (0)
233
234 static int __set_db_permission(const char *path, uid_t uid)
235 {
236         int fd;
237         const char *files[2];
238         char journal_file[BUFSIZE];
239         struct stat sb;
240         mode_t mode;
241         struct passwd pwd;
242         struct passwd *result;
243         char buf[BUFSIZE];
244         int ret;
245         int i;
246
247         if (getuid() != OWNER_ROOT)
248                 return 0;
249
250         if (uid == OWNER_ROOT || uid == GLOBAL_USER) {
251                 ret = getpwnam_r(APPFW_USER, &pwd, buf, sizeof(buf), &result);
252                 if (result == NULL) {
253                         if (ret == 0)
254                                 _LOGE("no such user: %d", uid);
255                         else
256                                 _LOGE("getpwuid_r failed: %d", errno);
257                         return -1;
258                 }
259                 uid = pwd.pw_uid;
260         }
261
262         snprintf(journal_file, sizeof(journal_file), "%s-journal", path);
263         files[0] = path;
264         files[1] = journal_file;
265
266         ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
267         if (result == NULL) {
268                 if (ret == 0)
269                         _LOGE("no such user: %d", uid);
270                 else
271                         _LOGE("getpwuid_r failed: %d", errno);
272                 return -1;
273         }
274
275         for (i = 0; i < 2; i++) {
276                 fd = open(files[i], O_RDONLY);
277                 if (fd == -1) {
278                         _LOGE("open %s failed: %d", files[i], errno);
279                         return -1;
280                 }
281                 ret = fstat(fd, &sb);
282                 if (ret == -1) {
283                         _LOGE("stat %s failed: %d", files[i], errno);
284                         close(fd);
285                         return -1;
286                 }
287                 if (S_ISLNK(sb.st_mode)) {
288                         _LOGE("%s is symlink!", files[i]);
289                         close(fd);
290                         return -1;
291                 }
292                 ret = fchown(fd, uid, pwd.pw_gid);
293                 if (ret == -1) {
294                         _LOGE("fchown %s failed: %d", files[i], errno);
295                         close(fd);
296                         return -1;
297                 }
298
299                 mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
300                 if (!strcmp(path, __get_cert_db_path()))
301                         mode |= S_IWOTH;
302                 ret = fchmod(fd, mode);
303                 if (ret == -1) {
304                         _LOGD("fchmod %s failed: %d", files[i], errno);
305                         close(fd);
306                         return -1;
307                 }
308                 close(fd);
309                 SET_SMACK_LABEL(files[i]);
310         }
311
312         return 0;
313 }
314
315 static const char *parser_init_queries[] = {
316         QUERY_CREATE_TABLE_PACKAGE_INFO,
317         QUERY_CREATE_TABLE_PACKAGE_LOCALIZED_INFO,
318         QUERY_CREATE_TABLE_PACKAGE_PRIVILEGE_INFO,
319         QUERY_CREATE_TABLE_PACKAGE_APPDEFINED_PRIVILEGE_INFO,
320         QUERY_CREATE_TABLE_PACKAGE_UPDATE_INFO,
321         QUERY_CREATE_TABLE_PACKAGE_APP_INFO,
322         QUERY_CREATE_TABLE_PACKAGE_APP_LOCALIZED_INFO,
323         QUERY_CREATE_TABLE_PACKAGE_APP_APP_CONTROL,
324         QUERY_CREATE_TABLE_PACKAGE_APP_APP_CONTROL_PRIVILEGE,
325         QUERY_CREATE_TABLE_PACKAGE_APP_APP_CATEGORY,
326         QUERY_CREATE_TABLE_PACKAGE_APP_APP_METADATA,
327         QUERY_CREATE_TABLE_PACKAGE_APP_DATA_CONTROL,
328         QUERY_CREATE_TABLE_PACKAGE_APP_DATA_CONTROL_PRIVILEGE,
329         QUERY_CREATE_TABLE_PACKAGE_APP_INFO_FOR_UID,
330         QUERY_CREATE_TRIGGER_UPDATE_PACKAGE_APP_INFO_FOR_UID,
331         QUERY_CREATE_TABLE_PACKAGE_APP_SPLASH_SCREEN,
332         NULL,
333 };
334
335 static const char *cert_init_queries[] = {
336         QUERY_CREATE_TABLE_PACKAGE_CERT_INFO,
337         QUERY_CREATE_TABLE_PACKAGE_CERT_INDEX_INFO,
338         QUERY_CREATE_TRIGGER_UPDATE_CERT_INFO,
339         QUERY_CREATE_TRIGGER_UPDATE_CERT_INFO2,
340         QUERY_CREATE_TRIGGER_DELETE_CERT_INFO,
341         QUERY_CREATE_TRIGGER_UPDATE_CERT_INDEX_INFO,
342         NULL
343 };
344
345 static int __initialize_db(sqlite3 *db, const char *dbpath, uid_t uid)
346 {
347         int ret;
348         const char **queries;
349         int i;
350
351         if (__set_db_version(db))
352                 return -1;
353
354         if (strstr(dbpath, ".pkgmgr_parser.db")) {
355                 queries = parser_init_queries;
356         } else if (strstr(dbpath, ".pkgmgr_cert.db")) {
357                 queries = cert_init_queries;
358         } else {
359                 _LOGE("unexpected dbpath: %s", dbpath);
360                 return -1;
361         }
362
363         for (i = 0; queries[i] != NULL; i++) {
364                 ret = sqlite3_exec(db, queries[i], NULL, NULL, NULL);
365                 if (ret != SQLITE_OK) {
366                         _LOGE("exec failed: %s", sqlite3_errmsg(db));
367                         return -1;
368                 }
369         }
370
371         if (__set_db_permission(dbpath, uid))
372                 _LOGE("failed to set db permission");
373
374         return 0;
375 }
376
377 #define RESOURCED_BUS_NAME "org.tizen.resourced"
378 #define RESOURCED_PROC_PATH "/Org/Tizen/ResourceD/Process"
379 #define RESOURCED_PROC_INTERFACE "org.tizen.resourced.process"
380 #define RESOURCED_PROC_METHOD "ProcExclude"
381 static void __send_wakeup_signal_to_resourced(pid_t pid)
382 {
383         GError *error = NULL;
384         GDBusConnection *conn;
385         GDBusProxy *proxy;
386         GVariant *reply;
387
388         conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
389         if (conn == NULL) {
390                 _LOGE("Failed to connect to dbus: %s", error->message);
391                 g_error_free(error);
392                 return;
393         }
394
395         proxy = g_dbus_proxy_new_sync(conn,
396                         G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
397                         NULL, RESOURCED_BUS_NAME,
398                         RESOURCED_PROC_PATH, RESOURCED_PROC_INTERFACE,
399                         NULL, &error);
400         if (proxy == NULL) {
401                 _LOGE("failed to get proxy object: %s", error->message);
402                 g_error_free(error);
403                 g_object_unref(conn);
404                 return;
405         }
406
407         reply = g_dbus_proxy_call_sync(proxy, RESOURCED_PROC_METHOD,
408                         g_variant_new("(si)", "wakeup", pid),
409                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
410         if (reply == NULL)
411                 _LOGE("failed to get reply from resourced");
412         if (error) {
413                 _LOGE("failed to send request: %s", error->message);
414                 g_error_free(error);
415         }
416
417         g_object_unref(proxy);
418         g_object_unref(conn);
419 }
420
421 static void __check_db_lock(const char *dbpath)
422 {
423         FILE *fp;
424         FILE *fp_cmdline;
425         struct stat sb;
426         int pid;
427         unsigned int maj;
428         unsigned int min;
429         ino_t ino;
430         char cmdline[BUFSIZE];
431         char name[BUFSIZE];
432         size_t len;
433
434         if (stat(dbpath, &sb) == -1) {
435                 _LOGE("get db file(%s) status failed: %d", dbpath, errno);
436                 return;
437         }
438
439         fp = fopen("/proc/locks", "r");
440         if (fp == NULL) {
441                 _LOGE("Failed to open lock info: %d", errno);
442                 return;
443         }
444
445         while (fscanf(fp, "%*s %*s %*s %*s %d %x:%x:%lu %*s %*s",
446                                 &pid, &maj, &min, &ino) != EOF) {
447                 if (maj != major(sb.st_dev) || min != minor(sb.st_dev) ||
448                                 ino != sb.st_ino || pid == getpid())
449                         continue;
450
451                 snprintf(cmdline, sizeof(cmdline), "/proc/%d/cmdline", pid);
452                 fp_cmdline = fopen(cmdline, "r");
453                 name[0] = '\0';
454                 if (fp_cmdline != NULL) {
455                         len = fread(name, sizeof(char), sizeof(name) - 1,
456                                         fp_cmdline);
457                         if (len > 0) {
458                                 if (name[len - 1] == '\n')
459                                         name[len - 1] = '\0';
460                                 else
461                                         name[len] = '\0';
462                         }
463                         fclose(fp_cmdline);
464                 }
465
466                 _LOGE("%s (%d) has lock on pkgmgr db(%s)!", name, pid, dbpath);
467                 __send_wakeup_signal_to_resourced(pid);
468         }
469
470         fclose(fp);
471 }
472
473 #define BUSY_WAITING_USEC (1000000 / 10 / 2) /* 0.05 sec */
474 #define BUSY_WAITING_MAX 40 /* wait for max 2 sec */
475 static int __db_busy_handler(void *data, int count)
476 {
477         if (count < (BUSY_WAITING_MAX / 2)) {
478                 usleep(BUSY_WAITING_USEC);
479                 return 1;
480         } else if (count == (BUSY_WAITING_MAX / 2)) {
481                 __check_db_lock((const char *)data);
482                 usleep(BUSY_WAITING_USEC);
483                 return 1;
484         } else if (count < BUSY_WAITING_MAX) {
485                 usleep(BUSY_WAITING_USEC);
486                 return 1;
487         } else {
488                 /* sqlite3_prepare_v2 will return SQLITE_BUSY */
489                 return 0;
490         }
491 }
492
493 API int pkgmgr_parser_initialize_parser_db(uid_t uid)
494 {
495         int ret;
496         const char *dbpath;
497         sqlite3 *db;
498
499         dbpath = __get_parser_db_path(uid);
500         if (access(dbpath, F_OK) != -1) {
501                 _LOGE("Manifest db for user %d is already exists", uid);
502                 return PM_PARSER_R_ERROR;
503         }
504
505         ret = sqlite3_open_v2(dbpath, &db,
506                         SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
507         if (ret != SQLITE_OK) {
508                 _LOGE("open db failed: %d", ret);
509                 return PM_PARSER_R_ERROR;
510         }
511
512         ret = sqlite3_busy_handler(db, __db_busy_handler, NULL);
513         if (ret != SQLITE_OK) {
514                 _LOGE("failed to register busy handler: %s",
515                                 sqlite3_errmsg(db));
516                 sqlite3_close_v2(db);
517                 return ret;
518         }
519
520         if (__initialize_db(db, dbpath, uid)) {
521                 sqlite3_close_v2(db);
522                 return PM_PARSER_R_ERROR;
523         }
524         sqlite3_close_v2(db);
525
526         return PM_PARSER_R_OK;
527 }
528
529 API int pkgmgr_parser_initialize_cert_db(void)
530 {
531         int ret;
532         const char *dbpath;
533         sqlite3 *db;
534
535         dbpath = __get_cert_db_path();
536         if (access(dbpath, F_OK) != -1) {
537                 _LOGE("Cert db is already exists");
538                 return PM_PARSER_R_ERROR;
539         }
540
541         ret = sqlite3_open_v2(dbpath, &db,
542                         SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
543         if (ret != SQLITE_OK) {
544                 _LOGE("open db failed: %d", ret);
545                 return PM_PARSER_R_ERROR;
546         }
547
548         ret = sqlite3_busy_handler(db, __db_busy_handler, NULL);
549         if (ret != SQLITE_OK) {
550                 _LOGE("failed to register busy handler: %s",
551                                 sqlite3_errmsg(db));
552                 sqlite3_close_v2(db);
553                 return ret;
554         }
555
556         if (__initialize_db(db, dbpath, GLOBAL_USER)) {
557                 sqlite3_close_v2(db);
558                 return PM_PARSER_R_ERROR;
559         }
560         sqlite3_close_v2(db);
561
562         return PM_PARSER_R_OK;
563 }
564
565 API int pkgmgr_parser_create_and_initialize_db(uid_t uid)
566 {
567         int ret;
568         struct passwd pwd;
569         struct passwd *result;
570         char buf[BUFSIZE];
571
572         ret = getpwnam_r(APPFW_USER, &pwd, buf, sizeof(buf), &result);
573         if (result == NULL) {
574                 if (ret == 0)
575                         _LOGE("no such user: %s", APPFW_USER);
576                 else
577                         _LOGE("getpwnam_r failed: %d", errno);
578                 return PM_PARSER_R_ERROR;
579         }
580
581         if (getuid() != OWNER_ROOT && getuid() != pwd.pw_uid) {
582                 _LOGE("Only root or app_fw user is allowed");
583                 return PM_PARSER_R_EINVAL;
584         }
585
586         if (pkgmgr_parser_initialize_parser_db(uid))
587                 return PM_PARSER_R_ERROR;
588
589         if (uid == OWNER_ROOT || uid == GLOBAL_USER)
590                 if (pkgmgr_parser_initialize_cert_db())
591                         return PM_PARSER_R_ERROR;
592
593         return PM_PARSER_R_OK;
594 }
595
596 static int __open_db(uid_t uid, const char *path, sqlite3 **db, int flags)
597 {
598         int ret;
599
600         /* FIXME: always open with OPEN_CREATE flag for keeping previous
601          * implementation
602          */
603         if (flags & SQLITE_OPEN_READWRITE)
604                 flags = flags | SQLITE_OPEN_CREATE;
605
606         ret = sqlite3_open_v2(path, db, flags, NULL);
607         if (ret != SQLITE_OK)
608                 return ret;
609
610         ret = sqlite3_busy_handler(*db, __db_busy_handler, (void *)path);
611         if (ret != SQLITE_OK) {
612                 _LOGE("failed to register busy handler: %s",
613                                 sqlite3_errmsg(*db));
614                 sqlite3_close_v2(*db);
615                 return ret;
616         }
617
618         if (flags & SQLITE_OPEN_CREATE) {
619                 ret = __initialize_db(*db, path, uid);
620                 if (ret) {
621                         _LOGE("failed to initialize db: %s", path);
622                         sqlite3_close_v2(*db);
623                         return -1;
624                 }
625         }
626
627         ret = sqlite3_exec(*db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL);
628         if (ret != SQLITE_OK) {
629                 _LOGE("failed to enable foreign key support: %s",
630                                 sqlite3_errmsg(*db));
631                 sqlite3_close_v2(*db);
632                 return ret;
633         }
634
635         return ret;
636 }
637
638
639 static int __convert_background_category(GList *category_list)
640 {
641         int ret = 0;
642         GList *tmp;
643         char *category_data;
644
645         if (category_list == NULL)
646                 return 0;
647
648         for (tmp = category_list; tmp; tmp = tmp->next) {
649                 category_data = (char *)tmp->data;
650                 if (category_data == NULL)
651                         continue;
652                 if (!strcmp(category_data, APP_BG_CATEGORY_MEDIA_STR))
653                         ret |= APP_BG_CATEGORY_MEDIA_VAL;
654                 else if (!strcmp(category_data, APP_BG_CATEGORY_DOWNLOAD_STR))
655                         ret |= APP_BG_CATEGORY_DOWNLOAD_VAL;
656                 else if (!strcmp(category_data, APP_BG_CATEGORY_BGNETWORK_STR))
657                         ret |= APP_BG_CATEGORY_BGNETWORK_VAL;
658                 else if (!strcmp(category_data, APP_BG_CATEGORY_LOCATION_STR))
659                         ret |= APP_BG_CATEGORY_LOCATION_VAL;
660                 else if (!strcmp(category_data, APP_BG_CATEGORY_SENSOR_STR))
661                         ret |= APP_BG_CATEGORY_SENSOR_VAL;
662                 else if (!strcmp(category_data, APP_BG_CATEGORY_IOTCOMM_STR))
663                         ret |= APP_BG_CATEGORY_IOTCOMM_VAL;
664                 else if (!strcmp(category_data, APP_BG_CATEGORY_SYSTEM))
665                         ret |= APP_BG_CATEGORY_SYSTEM_VAL;
666                 else
667                         _LOGE("Unidentified category [%s]", category_data);
668         }
669
670         return ret;
671 }
672
673 #define EFFECTIVE_APPID_KEY "http://tizen.org/metadata/effective-appid"
674 static const char *__find_effective_appid(GList *metadata_list)
675 {
676         GList *tmp;
677         metadata_x *md;
678
679         for (tmp = metadata_list; tmp; tmp = tmp->next) {
680                 md = (metadata_x *)tmp->data;
681                 if (md == NULL || md->key == NULL)
682                         continue;
683
684                 if (strcmp(md->key, EFFECTIVE_APPID_KEY) == 0) {
685                         if (md->value)
686                                 return md->value;
687                 }
688         }
689
690         return NULL;
691 }
692
693 static int __insert_appcontrol_privilege_info(sqlite3 *db, const char *appid,
694                 appcontrol_x *ac)
695 {
696         static const char query[] =
697                 "INSERT INTO package_app_app_control_privilege (app_id,"
698                 "  app_control, privilege) VALUES (?, ?, ?)";
699         int ret;
700         sqlite3_stmt *stmt;
701         int idx;
702         char app_control[BUFSIZE];
703         GList *tmp;
704         char *privilege;
705
706         if (ac == NULL)
707                 return 0;
708
709         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
710         if (ret != SQLITE_OK) {
711                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
712                 return -1;
713         }
714
715         for (tmp = ac->privileges; tmp; tmp = tmp->next) {
716                 privilege = (char *)tmp->data;
717                 if (privilege == NULL || !strlen(privilege))
718                         continue;
719
720                 idx = 1;
721                 snprintf(app_control, sizeof(app_control), "%s|%s|%s",
722                                 ac->operation ? (strlen(ac->operation) > 0 ?
723                                         ac->operation : "NULL") : "NULL",
724                                 ac->uri ? (strlen(ac->uri) > 0 ?
725                                         ac->uri : "NULL") : "NULL",
726                                 ac->mime ? (strlen(ac->mime) > 0 ?
727                                         ac->mime : "NULL") : "NULL");
728                 __BIND_TEXT(db, stmt, idx++, appid);
729                 __BIND_TEXT(db, stmt, idx++, app_control);
730                 __BIND_TEXT(db, stmt, idx++, privilege);
731
732                 ret = sqlite3_step(stmt);
733                 if (ret != SQLITE_DONE) {
734                         _LOGE("step failed: %s", sqlite3_errmsg(db));
735                         sqlite3_finalize(stmt);
736                         return -1;
737                 }
738
739                 sqlite3_reset(stmt);
740         }
741
742         sqlite3_finalize(stmt);
743
744         return 0;
745 }
746
747 static int __insert_appcontrol_info(sqlite3 *db, application_x *app)
748 {
749         static const char query[] =
750                 "INSERT INTO package_app_app_control (app_id, app_control,"
751                 "  visibility) "
752                 "VALUES (?, ?, ?)";
753         int ret;
754         sqlite3_stmt *stmt;
755         int idx;
756         char app_control[BUFSIZE];
757         GList *tmp;
758         appcontrol_x *ac;
759
760         if (app->appcontrol == NULL)
761                 return 0;
762
763         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
764         if (ret != SQLITE_OK) {
765                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
766                 return -1;
767         }
768
769         for (tmp = app->appcontrol; tmp; tmp = tmp->next) {
770                 ac = (appcontrol_x *)tmp->data;
771                 if (ac == NULL)
772                         continue;
773                 idx = 1;
774                 snprintf(app_control, sizeof(app_control), "%s|%s|%s",
775                                 ac->operation ? (strlen(ac->operation) > 0 ?
776                                         ac->operation : "NULL") : "NULL",
777                                 ac->uri ? (strlen(ac->uri) > 0 ?
778                                         ac->uri : "NULL") : "NULL",
779                                 ac->mime ? (strlen(ac->mime) > 0 ?
780                                         ac->mime : "NULL") : "NULL");
781                 __BIND_TEXT(db, stmt, idx++, app->appid);
782                 __BIND_TEXT(db, stmt, idx++, app_control);
783                 __BIND_TEXT(db, stmt, idx++, ac->visibility);
784
785                 ret = sqlite3_step(stmt);
786                 if (ret != SQLITE_DONE) {
787                         _LOGE("step failed: %s", sqlite3_errmsg(db));
788                         sqlite3_finalize(stmt);
789                         return -1;
790                 }
791
792                 if (__insert_appcontrol_privilege_info(db, app->appid, ac)) {
793                         sqlite3_finalize(stmt);
794                         return -1;
795                 }
796
797                 sqlite3_reset(stmt);
798         }
799
800         sqlite3_finalize(stmt);
801
802         return 0;
803 }
804
805 static int __insert_category_info(sqlite3 *db, application_x *app)
806 {
807         static const char query[] =
808                 "INSERT INTO package_app_app_category (app_id, category) "
809                 "VALUES (?, ?)";
810         int ret;
811         sqlite3_stmt *stmt;
812         int idx;
813         GList *tmp;
814         const char *category;
815
816         if (app->category == NULL)
817                 return 0;
818
819         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
820         if (ret != SQLITE_OK) {
821                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
822                 return -1;
823         }
824
825         for (tmp = app->category; tmp; tmp = tmp->next) {
826                 category = (const char *)tmp->data;
827                 if (category == NULL)
828                         continue;
829                 idx = 1;
830                 __BIND_TEXT(db, stmt, idx++, app->appid);
831                 __BIND_TEXT(db, stmt, idx++, category);
832
833                 ret = sqlite3_step(stmt);
834                 if (ret != SQLITE_DONE) {
835                         _LOGE("step failed: %s", sqlite3_errmsg(db));
836                         sqlite3_finalize(stmt);
837                         return -1;
838                 }
839
840                 sqlite3_reset(stmt);
841         }
842
843         sqlite3_finalize(stmt);
844
845         return 0;
846 }
847
848 static int __insert_metadata_info(sqlite3 *db, application_x *app)
849 {
850         static const char query[] =
851                 "INSERT INTO package_app_app_metadata (app_id,"
852                 "  md_key, md_value) VALUES (?, ?, ?)";
853         int ret;
854         sqlite3_stmt *stmt;
855         int idx;
856         GList *tmp;
857         metadata_x *md;
858
859         if (app->metadata == NULL)
860                 return 0;
861
862         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
863         if (ret != SQLITE_OK) {
864                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
865                 return -1;
866         }
867
868         for (tmp = app->metadata; tmp; tmp = tmp->next) {
869                 md = (metadata_x *)tmp->data;
870                 if (md == NULL)
871                         continue;
872                 idx = 1;
873                 __BIND_TEXT(db, stmt, idx++, app->appid);
874                 __BIND_TEXT(db, stmt, idx++, md->key);
875                 __BIND_TEXT(db, stmt, idx++, md->value);
876
877                 ret = sqlite3_step(stmt);
878                 if (ret != SQLITE_DONE) {
879                         _LOGE("step failed: %s", sqlite3_errmsg(db));
880                         sqlite3_finalize(stmt);
881                         return -1;
882                 }
883
884                 sqlite3_reset(stmt);
885         }
886
887         sqlite3_finalize(stmt);
888
889         return 0;
890 }
891
892 static int __insert_app_data_control_privilege_info(sqlite3 *db,
893                 datacontrol_x *datacontrol)
894 {
895         static const char query[] =
896                 "INSERT INTO package_app_data_control_privilege (providerid,"
897                 "  privilege, type) VALUES (?, ?, ?)";
898
899         int ret;
900         sqlite3_stmt *stmt;
901         int idx;
902         GList *privileges;
903         char *priv;
904
905         if (datacontrol == NULL)
906                 return 0;
907
908         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
909         if (ret != SQLITE_OK) {
910                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
911                 return -1;
912         }
913
914         for (privileges = datacontrol->privileges; privileges;
915                         privileges = privileges->next) {
916                 priv = (char *)privileges->data;
917                 if (priv == NULL)
918                         continue;
919
920                 idx = 1;
921                 __BIND_TEXT(db, stmt, idx++, datacontrol->providerid);
922                 __BIND_TEXT(db, stmt, idx++, priv);
923                 __BIND_TEXT(db, stmt, idx++, datacontrol->type);
924
925                 ret = sqlite3_step(stmt);
926                 if (ret != SQLITE_DONE) {
927                         _LOGE("step failed: %s", sqlite3_errmsg(db));
928                         sqlite3_finalize(stmt);
929                         return -1;
930                 }
931
932                 sqlite3_reset(stmt);
933         }
934
935         sqlite3_finalize(stmt);
936         return 0;
937 }
938
939 static int __insert_datacontrol_info(sqlite3 *db, application_x *app)
940 {
941         static const char query[] =
942                 "INSERT INTO package_app_data_control (app_id, providerid,"
943                 "  access, type, trusted) VALUES (?, ?, ?, ?, ?)";
944         int ret;
945         sqlite3_stmt *stmt;
946         int idx;
947         GList *tmp;
948         datacontrol_x *dc;
949
950         if (app->datacontrol == NULL)
951                 return 0;
952
953         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
954         if (ret != SQLITE_OK) {
955                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
956                 return -1;
957         }
958
959         for (tmp = app->datacontrol; tmp; tmp = tmp->next) {
960                 dc = (datacontrol_x *)tmp->data;
961                 if (dc == NULL)
962                         continue;
963                 idx = 1;
964                 __BIND_TEXT(db, stmt, idx++, app->appid);
965                 __BIND_TEXT(db, stmt, idx++, dc->providerid);
966                 __BIND_TEXT(db, stmt, idx++, dc->access);
967                 __BIND_TEXT(db, stmt, idx++, dc->type);
968                 __BIND_TEXT(db, stmt, idx++, dc->trusted);
969
970                 ret = sqlite3_step(stmt);
971                 if (ret != SQLITE_DONE) {
972                         _LOGE("step failed: %s", sqlite3_errmsg(db));
973                         sqlite3_finalize(stmt);
974                         return -1;
975                 }
976
977                 if (dc->privileges &&
978                                 __insert_app_data_control_privilege_info(db, dc)) {
979                         sqlite3_finalize(stmt);
980                         return -1;
981                 }
982
983                 sqlite3_reset(stmt);
984         }
985
986         sqlite3_finalize(stmt);
987
988         return 0;
989 }
990
991 /* TODO: move to installer */
992 static int __check_dpi(const char *dpi_char, int dpi_int)
993 {
994         if (dpi_char == NULL)
995                 return -1;
996
997         if (strcasecmp(dpi_char, LDPI) == 0) {
998                 if (dpi_int >= LDPI_MIN && dpi_int <= LDPI_MAX)
999                         return 0;
1000                 else
1001                         return -1;
1002         } else if (strcasecmp(dpi_char, MDPI) == 0) {
1003                 if (dpi_int >= MDPI_MIN && dpi_int <= MDPI_MAX)
1004                         return 0;
1005                 else
1006                         return -1;
1007         } else if (strcasecmp(dpi_char, HDPI) == 0) {
1008                 if (dpi_int >= HDPI_MIN && dpi_int <= HDPI_MAX)
1009                         return 0;
1010                 else
1011                         return -1;
1012         } else if (strcasecmp(dpi_char, XHDPI) == 0) {
1013                 if (dpi_int >= XHDPI_MIN && dpi_int <= XHDPI_MAX)
1014                         return 0;
1015                 else
1016                         return -1;
1017         } else if (strcasecmp(dpi_char, XXHDPI) == 0) {
1018                 if (dpi_int >= XXHDPI_MIN && dpi_int <= XXHDPI_MAX)
1019                         return 0;
1020                 else
1021                         return -1;
1022         } else
1023                 return -1;
1024 }
1025
1026 static gint __compare_splashscreen_with_orientation_dpi(gconstpointer a,
1027                 gconstpointer b)
1028 {
1029         splashscreen_x *ss = (splashscreen_x *)a;
1030         const char *orientation = (const char *)b;
1031         int dpi = -1;
1032         int ret;
1033
1034         if (ss->operation || ss->dpi == NULL)
1035                 return -1;
1036
1037         ret = system_info_get_platform_int(
1038                         "http://tizen.org/feature/screen.dpi", &dpi);
1039         if (ret != SYSTEM_INFO_ERROR_NONE)
1040                 return -1;
1041
1042         if (strcasecmp(ss->orientation, orientation) == 0 &&
1043                         __check_dpi(ss->dpi, dpi) == 0)
1044                 return 0;
1045
1046         return -1;
1047 }
1048
1049 static gint __compare_splashscreen_with_orientation(gconstpointer a,
1050                 gconstpointer b)
1051 {
1052         splashscreen_x *ss = (splashscreen_x *)a;
1053         const char *orientation = (const char *)b;
1054
1055         if (ss->operation || ss->dpi)
1056                 return -1;
1057
1058         if (strcasecmp(ss->orientation, orientation) == 0)
1059                 return 0;
1060
1061         return -1;
1062 }
1063
1064 static splashscreen_x *__find_default_splashscreen(GList *splashscreens,
1065                 const char *orientation)
1066 {
1067         GList *tmp;
1068
1069         tmp = g_list_find_custom(splashscreens, orientation,
1070                         (GCompareFunc)
1071                         __compare_splashscreen_with_orientation_dpi);
1072         if (tmp)
1073                 return (splashscreen_x *)tmp->data;
1074
1075         tmp = g_list_find_custom(splashscreens, orientation,
1076                         (GCompareFunc)__compare_splashscreen_with_orientation);
1077         if (tmp)
1078                 return (splashscreen_x *)tmp->data;
1079
1080         return NULL;
1081 }
1082
1083 static void __find_appcontrol_splashscreen_with_dpi(gpointer data,
1084                 gpointer user_data)
1085 {
1086         splashscreen_x *ss = (splashscreen_x *)data;
1087         GList **list = (GList **)user_data;
1088         int dpi = -1;
1089         int ret;
1090
1091         if (ss->operation == NULL || ss->dpi == NULL)
1092                 return;
1093
1094         ret = system_info_get_platform_int(
1095                         "http://tizen.org/feature/screen.dpi", &dpi);
1096         if (ret != SYSTEM_INFO_ERROR_NONE)
1097                 return;
1098
1099         if (__check_dpi(ss->dpi, dpi) != 0)
1100                 return;
1101
1102         *list = g_list_append(*list, ss);
1103 }
1104
1105 static void __find_appcontrol_splashscreen(gpointer data, gpointer user_data)
1106 {
1107         splashscreen_x *ss = (splashscreen_x *)data;
1108         GList **list = (GList **)user_data;
1109         splashscreen_x *ss_tmp;
1110         GList *tmp;
1111
1112         if (ss->operation == NULL || ss->dpi)
1113                 return;
1114
1115         for (tmp = *list; tmp; tmp = tmp->next) {
1116                 ss_tmp = (splashscreen_x *)tmp->data;
1117                 if (ss_tmp->operation
1118                         && strcmp(ss_tmp->operation, ss->operation) == 0
1119                         && strcmp(ss_tmp->orientation, ss->orientation) == 0)
1120                         return;
1121         }
1122
1123         *list = g_list_append(*list, ss);
1124 }
1125
1126 static GList *__find_splashscreens(GList *splashscreens)
1127 {
1128         GList *list = NULL;
1129         splashscreen_x *ss;
1130
1131         if (splashscreens == NULL)
1132                 return NULL;
1133
1134         g_list_foreach(splashscreens,
1135                         __find_appcontrol_splashscreen_with_dpi, &list);
1136         g_list_foreach(splashscreens,
1137                         __find_appcontrol_splashscreen, &list);
1138
1139         ss = __find_default_splashscreen(splashscreens, "portrait");
1140         if (ss)
1141                 list = g_list_append(list, ss);
1142         ss = __find_default_splashscreen(splashscreens, "landscape");
1143         if (ss)
1144                 list = g_list_append(list, ss);
1145
1146         return list;
1147 }
1148
1149 static int __insert_splashscreen_info(sqlite3 *db, application_x *app,
1150                 GList *ss_list)
1151 {
1152         static const char query[] =
1153                 "INSERT INTO package_app_splash_screen (app_id, src, type,"
1154                 "  orientation, indicatordisplay, operation, color_depth) "
1155                 "VALUES (?, ?, ?, ?, ?, ?, ?)";
1156         int ret;
1157         sqlite3_stmt *stmt;
1158         int idx;
1159         GList *tmp;
1160         splashscreen_x *ss;
1161
1162         if (app->splashscreens == NULL)
1163                 return 0;
1164
1165         if (ss_list == NULL)
1166                 return 0;
1167
1168         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1169         if (ret != SQLITE_OK) {
1170                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
1171                 return -1;
1172         }
1173
1174         for (tmp = ss_list; tmp; tmp = tmp->next) {
1175                 ss = (splashscreen_x *)tmp->data;
1176                 if (ss == NULL)
1177                         continue;
1178                 idx = 1;
1179                 __BIND_TEXT(db, stmt, idx++, app->appid);
1180                 __BIND_TEXT(db, stmt, idx++, ss->src);
1181                 __BIND_TEXT(db, stmt, idx++, ss->type);
1182                 __BIND_TEXT(db, stmt, idx++, ss->orientation);
1183                 __BIND_TEXT(db, stmt, idx++, ss->indicatordisplay);
1184                 __BIND_TEXT(db, stmt, idx++, ss->operation);
1185                 __BIND_TEXT(db, stmt, idx++, ss->color_depth);
1186
1187                 ret = sqlite3_step(stmt);
1188                 if (ret != SQLITE_DONE) {
1189                         _LOGE("step failed: %s", sqlite3_errmsg(db));
1190                         sqlite3_finalize(stmt);
1191                         return -1;
1192                 }
1193
1194                 sqlite3_reset(stmt);
1195         }
1196
1197         sqlite3_finalize(stmt);
1198
1199         return 0;
1200 }
1201
1202 static void __trimfunc(GList *trim_list)
1203 {
1204         char *trim_data;
1205         char *prev = NULL;
1206         GList *list = g_list_first(trim_list);
1207
1208         while (list) {
1209                 trim_data = (char *)list->data;
1210                 if (trim_data) {
1211                         if (prev) {
1212                                 if (strcmp(trim_data, prev) == 0) {
1213                                         trim_list = g_list_remove(trim_list,
1214                                                         trim_data);
1215                                         list = g_list_first(trim_list);
1216                                         prev = NULL;
1217                                         continue;
1218                                 } else
1219                                         prev = trim_data;
1220                         } else {
1221                                 prev = trim_data;
1222                         }
1223                 }
1224                 list = g_list_next(list);
1225         }
1226 }
1227
1228 static gint __comparefunc(gconstpointer a, gconstpointer b, gpointer userdata)
1229 {
1230         if (a == NULL || b == NULL)
1231                 return 0;
1232         if (strcmp((char *)a, (char *)b) == 0)
1233                 return 0;
1234         if (strcmp((char *)a, (char *)b) < 0)
1235                 return -1;
1236         if (strcmp((char *)a, (char *)b) > 0)
1237                 return 1;
1238         return 0;
1239 }
1240
1241 /* TODO: refactor inserting localized info */
1242 static GList *__create_locale_list(GList *lbls, GList *lcns, GList *icns,
1243                 GList *dcns, GList *aths)
1244 {
1245         GList *locale = NULL;
1246         GList *tmp;
1247         label_x *lbl;
1248         license_x *lcn;
1249         icon_x *icn;
1250         description_x *dcn;
1251         author_x *ath;
1252
1253         for (tmp = lbls; tmp; tmp = tmp->next) {
1254                 lbl = (label_x *)tmp->data;
1255                 if (lbl == NULL)
1256                         continue;
1257                 if (lbl->lang)
1258                         locale = g_list_insert_sorted_with_data(
1259                                         locale, (gpointer)lbl->lang,
1260                                         __comparefunc, NULL);
1261         }
1262         for (tmp = lcns; tmp; tmp = tmp->next) {
1263                 lcn = (license_x *)tmp->data;
1264                 if (lcn == NULL)
1265                         continue;
1266                 if (lcn->lang)
1267                         locale = g_list_insert_sorted_with_data(
1268                                         locale, (gpointer)lcn->lang,
1269                                         __comparefunc, NULL);
1270         }
1271         for (tmp = icns; tmp; tmp = tmp->next) {
1272                 icn = (icon_x *)tmp->data;
1273                 if (icn == NULL)
1274                         continue;
1275                 if (icn->lang)
1276                         locale = g_list_insert_sorted_with_data(
1277                                         locale, (gpointer)icn->lang,
1278                                         __comparefunc, NULL);
1279         }
1280         for (tmp = dcns; tmp; tmp = tmp->next) {
1281                 dcn = (description_x *)tmp->data;
1282                 if (dcn == NULL)
1283                         continue;
1284                 if (dcn->lang)
1285                         locale = g_list_insert_sorted_with_data(
1286                                         locale, (gpointer)dcn->lang,
1287                                         __comparefunc, NULL);
1288         }
1289         for (tmp = aths; tmp; tmp = tmp->next) {
1290                 ath = (author_x *)tmp->data;
1291                 if (ath == NULL)
1292                         continue;
1293                 if (ath->lang)
1294                         locale = g_list_insert_sorted_with_data(
1295                                         locale, (gpointer)ath->lang,
1296                                         __comparefunc, NULL);
1297         }
1298         __trimfunc(locale);
1299         return locale;
1300 }
1301
1302 static gint __check_icon_resolution(const char *orig_icon_path,
1303                 char **new_icon_path)
1304 {
1305         int ret;
1306         char *dpi_path[2];
1307         char *icon_filename;
1308         char modified_iconpath[BUFSIZE];
1309         char icon_path[BUFSIZE];
1310         int i;
1311         int dpi = -1;
1312
1313         if (orig_icon_path == NULL)
1314                 return -1;
1315
1316         ret = system_info_get_platform_int(
1317                         "http://tizen.org/feature/screen.dpi", &dpi);
1318         if (ret != SYSTEM_INFO_ERROR_NONE)
1319                 return -1;
1320
1321         if (dpi >= LDPI_MIN && dpi <= LDPI_MAX) {
1322                 dpi_path[0] = "LDPI";
1323                 dpi_path[1] = "ldpi";
1324         } else if (dpi >= MDPI_MIN && dpi <= MDPI_MAX) {
1325                 dpi_path[0] = "MDPI";
1326                 dpi_path[1] = "mdpi";
1327         } else if (dpi >= HDPI_MIN && dpi <= HDPI_MAX) {
1328                 dpi_path[0] = "HDPI";
1329                 dpi_path[1] = "hdpi";
1330         } else if (dpi >= XHDPI_MIN && dpi <= XHDPI_MAX) {
1331                 dpi_path[0] = "XHDPI";
1332                 dpi_path[1] = "xhdpi";
1333         } else if (dpi >= XXHDPI_MIN && dpi <= XXHDPI_MAX) {
1334                 dpi_path[0] = "XXHDPI";
1335                 dpi_path[1] = "xxhdpi";
1336         } else {
1337                 _LOGE("Unidentified dpi[%d]", dpi);
1338                 return -1;
1339         }
1340
1341         icon_filename = strrchr(orig_icon_path, '/');
1342         if (icon_filename == NULL)
1343                 return -1;
1344
1345         snprintf(icon_path,
1346                         strlen(orig_icon_path) - (strlen(icon_filename) - 1),
1347                         "%s", orig_icon_path);
1348         for (i = 0; i < 2; i++) {
1349                 snprintf(modified_iconpath, BUFSIZE - 1, "%s/%s%s",
1350                                 icon_path, dpi_path[i], icon_filename);
1351                 if (access(modified_iconpath, F_OK) != -1) {
1352                         /* if exists, return modified icon path */
1353                         *new_icon_path = strdup(modified_iconpath);
1354                         return 0;
1355                 }
1356         }
1357
1358         return -1;
1359 }
1360
1361 static gint __compare_icon(gconstpointer a, gconstpointer b)
1362 {
1363         icon_x *icon = (icon_x *)a;
1364         char *icon_path;
1365
1366         if (icon->lang != NULL && strcasecmp(icon->lang, DEFAULT_LOCALE) != 0)
1367                 return -1;
1368
1369         if (icon->dpi != NULL)
1370                 return -1;
1371
1372         if (__check_icon_resolution(icon->text, &icon_path) == 0) {
1373                 free(icon->text);
1374                 icon->text = icon_path;
1375         }
1376
1377         return 0;
1378 }
1379
1380 static gint __compare_icon_with_dpi(gconstpointer a, gconstpointer b)
1381 {
1382         icon_x *icon = (icon_x *)a;
1383         int dpi = GPOINTER_TO_INT(b);
1384
1385         if (icon->lang != NULL && strcasecmp(icon->lang, DEFAULT_LOCALE) != 0)
1386                 return -1;
1387
1388         if (icon->dpi == NULL)
1389                 return -1;
1390
1391         if (__check_dpi(icon->dpi, dpi) == 0)
1392                 return 0;
1393
1394         return -1;
1395 }
1396
1397 static gint __compare_icon_with_lang(gconstpointer a, gconstpointer b)
1398 {
1399         icon_x *icon = (icon_x *)a;
1400         char *lang = (char *)b;
1401         char *icon_path;
1402
1403         if (icon->dpi != NULL)
1404                 return -1;
1405
1406         if (strcasecmp(icon->lang, lang) == 0) {
1407                 if (strcasecmp(icon->lang, DEFAULT_LOCALE) == 0) {
1408                         /* icon for no locale. check existance of
1409                          * folder-hierachied default icons
1410                          */
1411                         if (__check_icon_resolution(icon->text,
1412                                                 &icon_path) == 0) {
1413                                 free(icon->text);
1414                                 icon->text = icon_path;
1415                         }
1416                 }
1417                 return 0;
1418         }
1419
1420         return -1;
1421 }
1422
1423 static gint __compare_icon_with_lang_dpi(gconstpointer a, gconstpointer b)
1424 {
1425         int ret;
1426         icon_x *icon = (icon_x *)a;
1427         char *lang = (char *)b;
1428         int dpi = -1;
1429
1430         ret = system_info_get_platform_int(
1431                         "http://tizen.org/feature/screen.dpi", &dpi);
1432         if (ret != SYSTEM_INFO_ERROR_NONE)
1433                 return -1;
1434
1435         if (strcasecmp(icon->lang, lang) == 0 &&
1436                         __check_dpi(icon->dpi, dpi) == 0)
1437                 return 0;
1438
1439         return -1;
1440 }
1441
1442 static char *__find_icon(GList *icons, const char *lang)
1443 {
1444         GList *tmp;
1445         icon_x *icon;
1446         int dpi = 0;
1447         int ret;
1448
1449         /* first, find icon whose locale and dpi with given lang and
1450          * system's dpi has matched
1451          */
1452         tmp = g_list_find_custom(icons, lang,
1453                         (GCompareFunc)__compare_icon_with_lang_dpi);
1454         if (tmp != NULL) {
1455                 icon = (icon_x *)tmp->data;
1456                 return (char *)icon->text;
1457         }
1458
1459         /* if first has failed, find icon whose locale has matched */
1460         tmp = g_list_find_custom(icons, lang,
1461                         (GCompareFunc)__compare_icon_with_lang);
1462         if (tmp != NULL) {
1463                 icon = (icon_x *)tmp->data;
1464                 return (char *)icon->text;
1465         }
1466
1467         /* if second has failed, find icon whose dpi has matched with
1468          * system's dpi
1469          */
1470         ret = system_info_get_platform_int(
1471                         "http://tizen.org/feature/screen.dpi", &dpi);
1472         if (ret == SYSTEM_INFO_ERROR_NONE) {
1473                 tmp = g_list_find_custom(icons, GINT_TO_POINTER(dpi),
1474                                 (GCompareFunc)__compare_icon_with_dpi);
1475                 if (tmp != NULL) {
1476                         icon = (icon_x *)tmp->data;
1477                         return (char *)icon->text;
1478                 }
1479         }
1480
1481         /* last, find default icon marked as "No Locale" */
1482         tmp = g_list_find_custom(icons, NULL, (GCompareFunc)__compare_icon);
1483         if (tmp != NULL) {
1484                 icon = (icon_x *)tmp->data;
1485                 return (char *)icon->text;
1486         }
1487
1488         return NULL;
1489 }
1490
1491 static void __extract_data(const char *locale, GList *lbls, GList *lcns,
1492                 GList *icns, GList *dcns, GList *aths, char **label,
1493                 char **license, char **icon, char **description, char **author)
1494 {
1495         GList *tmp;
1496         label_x *lbl;
1497         license_x *lcn;
1498         description_x *dcn;
1499         author_x *ath;
1500
1501         for (tmp = lbls; tmp; tmp = tmp->next) {
1502                 lbl = (label_x *)tmp->data;
1503                 if (lbl == NULL)
1504                         continue;
1505                 if (lbl->lang) {
1506                         if (strcmp(lbl->lang, locale) == 0) {
1507                                 *label = (char *)lbl->text;
1508                                 break;
1509                         }
1510                 }
1511         }
1512         for (tmp = lcns; tmp; tmp = tmp->next) {
1513                 lcn = (license_x *)tmp->data;
1514                 if (lcn == NULL)
1515                         continue;
1516                 if (lcn->lang) {
1517                         if (strcmp(lcn->lang, locale) == 0) {
1518                                 *license = (char *)lcn->text;
1519                                 break;
1520                         }
1521                 }
1522         }
1523
1524         *icon = __find_icon(icns, locale);
1525
1526         for (tmp = dcns; tmp; tmp = tmp->next) {
1527                 dcn = (description_x *)tmp->data;
1528                 if (dcn == NULL)
1529                         continue;
1530                 if (dcn->lang) {
1531                         if (strcmp(dcn->lang, locale) == 0) {
1532                                 *description = (char *)dcn->text;
1533                                 break;
1534                         }
1535                 }
1536         }
1537         for (tmp = aths; tmp; tmp = tmp->next) {
1538                 ath = (author_x *)tmp->data;
1539                 if (ath == NULL)
1540                         continue;
1541                 if (ath->lang) {
1542                         if (strcmp(ath->lang, locale) == 0) {
1543                                 *author = (char *)ath->text;
1544                                 break;
1545                         }
1546                 }
1547         }
1548 }
1549
1550 static int __insert_mainapp_localized_info(sqlite3 *db, application_x *app,
1551                 const char *locale, const char *label, const char *icon)
1552 {
1553         static const char query[] =
1554                 "INSERT OR REPLACE INTO package_localized_info ("
1555                 "  package, package_locale, package_label, package_icon,"
1556                 "  package_description, package_license, package_author) "
1557                 "VALUES (?, ?,"
1558                 "  COALESCE((SELECT package_label FROM package_localized_info"
1559                 "            WHERE package=? AND package_locale=?), ?),"
1560                 "  COALESCE((SELECT package_icon FROM package_localized_info"
1561                 "            WHERE package=? AND package_icon=?), ?),"
1562                 "  (SELECT package_description FROM package_localized_info"
1563                 "   WHERE package=? AND package_locale=?),"
1564                 "  (SELECT package_description FROM package_localized_info"
1565                 "   WHERE package=? AND package_locale=?),"
1566                 "  (SELECT package_description FROM package_localized_info"
1567                 "   WHERE package=? AND package_locale=?))";
1568         int ret;
1569         sqlite3_stmt *stmt;
1570         int idx = 1;
1571
1572         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1573         if (ret != SQLITE_OK) {
1574                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
1575                 return -1;
1576         }
1577
1578         __BIND_TEXT(db, stmt, idx++, app->package);
1579         __BIND_TEXT(db, stmt, idx++, locale);
1580         __BIND_TEXT(db, stmt, idx++, app->package);
1581         __BIND_TEXT(db, stmt, idx++, locale);
1582         __BIND_TEXT(db, stmt, idx++, label);
1583         __BIND_TEXT(db, stmt, idx++, app->package);
1584         __BIND_TEXT(db, stmt, idx++, locale);
1585         __BIND_TEXT(db, stmt, idx++, icon);
1586         __BIND_TEXT(db, stmt, idx++, app->package);
1587         __BIND_TEXT(db, stmt, idx++, locale);
1588         __BIND_TEXT(db, stmt, idx++, app->package);
1589         __BIND_TEXT(db, stmt, idx++, locale);
1590         __BIND_TEXT(db, stmt, idx++, app->package);
1591         __BIND_TEXT(db, stmt, idx++, locale);
1592
1593         ret = sqlite3_step(stmt);
1594         if (ret != SQLITE_DONE) {
1595                 _LOGE("step failed: %s", sqlite3_errmsg(db));
1596                 sqlite3_finalize(stmt);
1597                 return -1;
1598         }
1599
1600         sqlite3_finalize(stmt);
1601
1602         return 0;
1603 }
1604
1605 static int __insert_app_localized_info(sqlite3 *db, application_x *app)
1606 {
1607         static const char query[] =
1608                 "INSERT INTO package_app_localized_info (app_id, app_locale,"
1609                 "  app_label, app_icon) "
1610                 "VALUES (?, ?, ?, ?)";
1611         int ret;
1612         sqlite3_stmt *stmt;
1613         int idx;
1614         GList *tmp;
1615         GList *locales;
1616         const char *locale;
1617         char *label;
1618         char *icon;
1619
1620         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1621         if (ret != SQLITE_OK) {
1622                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
1623                 return -1;
1624         }
1625
1626         locales = __create_locale_list(app->label, NULL, app->icon, NULL, NULL);
1627         for (tmp = locales; tmp; tmp = tmp->next) {
1628                 locale = (const char *)tmp->data;
1629                 label = NULL;
1630                 icon = NULL;
1631                 __extract_data(locale, app->label, NULL, app->icon, NULL, NULL,
1632                                 &label, NULL, &icon, NULL, NULL);
1633                 if (!label && !icon)
1634                         continue;
1635
1636                 idx = 1;
1637                 __BIND_TEXT(db, stmt, idx++, app->appid);
1638                 __BIND_TEXT(db, stmt, idx++, locale);
1639                 __BIND_TEXT(db, stmt, idx++, label);
1640                 __BIND_TEXT(db, stmt, idx++, icon);
1641
1642                 ret = sqlite3_step(stmt);
1643                 if (ret != SQLITE_DONE) {
1644                         _LOGE("step failed: %s", sqlite3_errmsg(db));
1645                         g_list_free(locales);
1646                         sqlite3_finalize(stmt);
1647                         return -1;
1648                 }
1649
1650                 sqlite3_reset(stmt);
1651
1652                 if (strcasecmp(app->mainapp, "true") == 0) {
1653                         if (__insert_mainapp_localized_info(db, app, locale,
1654                                                 label, icon))
1655                                 _LOGE("insert mainapp localized info failed");
1656                 }
1657         }
1658
1659         g_list_free(locales);
1660         sqlite3_finalize(stmt);
1661
1662         return 0;
1663 }
1664
1665 static int __insert_package_privilege_info(sqlite3 *db, manifest_x *mfx)
1666 {
1667         static const char query[] =
1668                 "INSERT INTO package_privilege_info (package, privilege, type) "
1669                 "VALUES (?, ?, ?)";
1670         int ret;
1671         sqlite3_stmt *stmt;
1672         int idx;
1673         GList *tmp;
1674         privilege_x *priv;
1675
1676         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1677         if (ret != SQLITE_OK) {
1678                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
1679                 return -1;
1680         }
1681
1682         for (tmp = mfx->privileges; tmp; tmp = tmp->next) {
1683                 priv = (privilege_x *)tmp->data;
1684                 if (priv == NULL)
1685                         continue;
1686
1687                 idx = 1;
1688                 __BIND_TEXT(db, stmt, idx++, mfx->package);
1689                 __BIND_TEXT(db, stmt, idx++, priv->value);
1690                 __BIND_TEXT(db, stmt, idx++, priv->type);
1691
1692                 ret = sqlite3_step(stmt);
1693                 if (ret != SQLITE_DONE) {
1694                         _LOGE("step failed: %s", sqlite3_errmsg(db));
1695                         sqlite3_finalize(stmt);
1696                         return -1;
1697                 }
1698                 sqlite3_reset(stmt);
1699         }
1700
1701         sqlite3_finalize(stmt);
1702
1703         return 0;
1704 }
1705
1706 static int __insert_package_appdefined_privilege_info(sqlite3 *db,
1707                 manifest_x *mfx)
1708 {
1709         static const char query[] =
1710                 "INSERT INTO package_appdefined_privilege_info "
1711                 "(package, privilege, license, type) "
1712                 "VALUES (?, ?, ?, ?)";
1713         int ret;
1714         sqlite3_stmt *stmt;
1715         int idx;
1716         GList *tmp;
1717         appdefined_privilege_x *priv;
1718
1719         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1720         if (ret != SQLITE_OK) {
1721                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
1722                 return -1;
1723         }
1724
1725         for (tmp = mfx->appdefined_privileges; tmp; tmp = tmp->next) {
1726                 priv = (appdefined_privilege_x *)tmp->data;
1727                 if (priv == NULL)
1728                         continue;
1729
1730                 idx = 1;
1731                 __BIND_TEXT(db, stmt, idx++, mfx->package);
1732                 __BIND_TEXT(db, stmt, idx++, priv->value);
1733                 __BIND_TEXT(db, stmt, idx++, priv->license);
1734                 __BIND_TEXT(db, stmt, idx++, priv->type);
1735
1736                 ret = sqlite3_step(stmt);
1737                 if (ret != SQLITE_DONE) {
1738                         _LOGE("step failed: %s", sqlite3_errmsg(db));
1739                         sqlite3_finalize(stmt);
1740                         return -1;
1741                 }
1742                 sqlite3_reset(stmt);
1743         }
1744
1745         sqlite3_finalize(stmt);
1746
1747         return 0;
1748 }
1749
1750 /* _PRODUCT_LAUNCHING_ENHANCED_
1751  *  app->indicatordisplay, app->portraitimg, app->landscapeimg,
1752  *  app->guestmode_appstatus
1753  */
1754 static int __insert_application_info(sqlite3 *db, manifest_x *mfx)
1755 {
1756         static const char query[] =
1757                 "INSERT INTO package_app_info (app_id, app_component,"
1758                 "  app_exec, app_nodisplay, app_type, app_onboot, app_multiple,"
1759                 "  app_autorestart, app_taskmanage, app_hwacceleration,"
1760                 "  app_screenreader, app_mainapp, app_recentimage,"
1761                 "  app_launchcondition, app_indicatordisplay, app_portraitimg,"
1762                 "  app_landscapeimg, app_guestmodevisibility,"
1763                 "  app_permissiontype, app_preload, app_submode,"
1764                 "  app_submode_mainid, app_installed_storage, app_process_pool,"
1765                 "  app_launch_mode, app_ui_gadget, app_support_mode,"
1766                 "  app_support_disable, component_type, package, app_tep_name,"
1767                 "  app_zip_mount_file, app_background_category,"
1768                 "  app_package_type, app_root_path, app_api_version,"
1769                 "  app_effective_appid, app_splash_screen_display,"
1770                 "  app_package_system, app_removable,"
1771                 "  app_package_installed_time, app_support_ambient,"
1772                 "  app_external_path, app_setup_appid) "
1773                 "VALUES (?, ?, "
1774                 "  ?, LOWER(?), ?, LOWER(?), LOWER(?),"
1775                 "  LOWER(?), LOWER(?), ?,"
1776                 "  ?, LOWER(?), ?,"
1777                 "  ?, LOWER(?), ?,"
1778                 "  ?, LOWER(?),"
1779                 "  ?, LOWER(?), LOWER(?),"
1780                 "  ?, ?, LOWER(?),"
1781                 "  COALESCE(?, 'single'), LOWER(?), ?,"
1782                 "  LOWER(?), ?, ?, ?,"
1783                 "  ?, ?,"
1784                 "  ?, ?, ?,"
1785                 "  ?, LOWER(?),"
1786                 "  LOWER(?), LOWER(?),"
1787                 "  ?, LOWER(?),"
1788                 "  ?, ?)";
1789         int ret;
1790         sqlite3_stmt *stmt;
1791         int idx;
1792         GList *tmp;
1793         application_x *app;
1794         int bg_category;
1795         const char *effective_appid;
1796         GList *ss_list;
1797
1798         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1799         if (ret != SQLITE_OK) {
1800                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
1801                 return -1;
1802         }
1803
1804         for (tmp = mfx->application; tmp; tmp = tmp->next) {
1805                 app = (application_x *)tmp->data;
1806                 if (app == NULL)
1807                         continue;
1808
1809                 bg_category = __convert_background_category(
1810                                 app->background_category);
1811                 effective_appid = __find_effective_appid(app->metadata);
1812
1813                 idx = 1;
1814                 __BIND_TEXT(db, stmt, idx++, app->appid);
1815                 __BIND_TEXT(db, stmt, idx++, app->component_type);
1816                 __BIND_TEXT(db, stmt, idx++, app->exec);
1817                 __BIND_TEXT(db, stmt, idx++, __get_bool(app->nodisplay, false));
1818                 __BIND_TEXT(db, stmt, idx++, app->type);
1819                 __BIND_TEXT(db, stmt, idx++, __get_bool(app->onboot, false));
1820                 __BIND_TEXT(db, stmt, idx++, __get_bool(app->multiple, false));
1821                 __BIND_TEXT(db, stmt, idx++,
1822                                 __get_bool(app->autorestart, false));
1823                 __BIND_TEXT(db, stmt, idx++,
1824                                 __get_bool(app->taskmanage, false));
1825                 __BIND_TEXT(db, stmt, idx++, app->hwacceleration);
1826                 __BIND_TEXT(db, stmt, idx++, app->screenreader);
1827                 __BIND_TEXT(db, stmt, idx++, __get_bool(app->mainapp, false));
1828                 __BIND_TEXT(db, stmt, idx++, app->recentimage);
1829                 __BIND_TEXT(db, stmt, idx++, app->launchcondition);
1830                 __BIND_TEXT(db, stmt, idx++,
1831                                 __get_bool(app->indicatordisplay, true));
1832                 __BIND_TEXT(db, stmt, idx++, app->portraitimg);
1833                 __BIND_TEXT(db, stmt, idx++, app->landscapeimg);
1834                 __BIND_TEXT(db, stmt, idx++,
1835                                 __get_bool(app->guestmode_visibility, true));
1836                 __BIND_TEXT(db, stmt, idx++, app->permission_type);
1837                 __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->preload, false));
1838                 __BIND_TEXT(db, stmt, idx++, __get_bool(app->submode, false));
1839                 __BIND_TEXT(db, stmt, idx++, app->submode_mainid);
1840                 __BIND_TEXT(db, stmt, idx++, mfx->installed_storage);
1841                 __BIND_TEXT(db, stmt, idx++,
1842                                 __get_bool(app->process_pool, false));
1843                 __BIND_TEXT(db, stmt, idx++, app->launch_mode);
1844                 __BIND_TEXT(db, stmt, idx++, __get_bool(app->ui_gadget, false));
1845                 __BIND_TEXT(db, stmt, idx++, app->support_mode);
1846                 __BIND_TEXT(db, stmt, idx++,
1847                                 __get_bool(mfx->support_disable, false));
1848                 __BIND_TEXT(db, stmt, idx++, app->component_type);
1849                 __BIND_TEXT(db, stmt, idx++, mfx->package);
1850                 __BIND_TEXT(db, stmt, idx++, mfx->tep_name);
1851                 __BIND_TEXT(db, stmt, idx++, mfx->zip_mount_file);
1852                 __BIND_INT(db, stmt, idx++, bg_category);
1853                 __BIND_TEXT(db, stmt, idx++, mfx->type ? mfx->type : "tpk");
1854                 __BIND_TEXT(db, stmt, idx++, mfx->root_path);
1855                 __BIND_TEXT(db, stmt, idx++, mfx->api_version);
1856                 __BIND_TEXT(db, stmt, idx++, effective_appid);
1857                 __BIND_TEXT(db, stmt, idx++,
1858                                 __get_bool(app->splash_screen_display, true));
1859                 __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->system, false));
1860                 __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->removable, false));
1861                 __BIND_TEXT(db, stmt, idx++, mfx->installed_time);
1862                 __BIND_TEXT(db, stmt, idx++,
1863                                 __get_bool(app->support_ambient, false));
1864                 __BIND_TEXT(db, stmt, idx++, mfx->external_path);
1865                 __BIND_TEXT(db, stmt, idx++, app->setup_appid);
1866
1867                 ret = sqlite3_step(stmt);
1868                 if (ret != SQLITE_DONE) {
1869                         _LOGE("step failed: %s", sqlite3_errmsg(db));
1870                         sqlite3_finalize(stmt);
1871                         return -1;
1872                 }
1873
1874                 sqlite3_reset(stmt);
1875
1876                 if (__insert_appcontrol_info(db, app)) {
1877                         sqlite3_finalize(stmt);
1878                         return -1;
1879                 }
1880                 if (__insert_category_info(db, app)) {
1881                         sqlite3_finalize(stmt);
1882                         return -1;
1883                 }
1884                 if (__insert_metadata_info(db, app)) {
1885                         sqlite3_finalize(stmt);
1886                         return -1;
1887                 }
1888                 if (__insert_datacontrol_info(db, app)) {
1889                         sqlite3_finalize(stmt);
1890                         return -1;
1891                 }
1892                 ss_list = __find_splashscreens(app->splashscreens);
1893                 if (__insert_splashscreen_info(db, app, ss_list)) {
1894                         g_list_free(ss_list);
1895                         sqlite3_finalize(stmt);
1896                         return -1;
1897                 }
1898                 g_list_free(ss_list);
1899                 if (__insert_app_localized_info(db, app)) {
1900                         sqlite3_finalize(stmt);
1901                         return -1;
1902                 }
1903         }
1904
1905         sqlite3_finalize(stmt);
1906
1907         return 0;
1908 }
1909
1910 static int __insert_package_update_info(sqlite3 *db, manifest_x *mfx)
1911 {
1912         static const char query[] =
1913                 "INSERT INTO package_update_info (package, update_version) "
1914                 "VALUES (?, ?)";
1915         int ret;
1916         int idx;
1917         sqlite3_stmt *stmt;
1918
1919         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1920         if (ret != SQLITE_OK) {
1921                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
1922                 return -1;
1923         }
1924
1925         idx = 1;
1926         __BIND_TEXT(db, stmt, idx++, mfx->package);
1927         __BIND_TEXT(db, stmt, idx, mfx->version);
1928         ret = sqlite3_step(stmt);
1929         if (ret != SQLITE_DONE) {
1930                 _LOGE("step failed: %s", sqlite3_errmsg(db));
1931                 sqlite3_finalize(stmt);
1932                 return -1;
1933         }
1934         sqlite3_finalize(stmt);
1935
1936         return 0;
1937 }
1938
1939 static int __insert_package_localized_info(sqlite3 *db, manifest_x *mfx)
1940 {
1941         static const char query[] =
1942                 "INSERT INTO package_localized_info (package, package_locale,"
1943                 "  package_label, package_icon, package_description,"
1944                 "  package_license, package_author) "
1945                 "VALUES (?, ?, ?, ?, ?, ?, ?)";
1946         int ret;
1947         sqlite3_stmt *stmt;
1948         int idx;
1949         GList *tmp;
1950         GList *locales;
1951         const char *locale;
1952         char *label;
1953         char *icon;
1954         char *description;
1955         char *license;
1956         char *author;
1957
1958         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1959         if (ret != SQLITE_OK) {
1960                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
1961                 return -1;
1962         }
1963
1964         locales = __create_locale_list(mfx->label, mfx->license, mfx->icon,
1965                         mfx->description, mfx->author);
1966         for (tmp = locales; tmp; tmp = tmp->next) {
1967                 locale = (const char *)tmp->data;
1968                 label = NULL;
1969                 icon = NULL;
1970                 description = NULL;
1971                 license = NULL;
1972                 author = NULL;
1973                 __extract_data(locale, mfx->label, mfx->license, mfx->icon,
1974                                 mfx->description, mfx->author,
1975                                 &label, &license, &icon, &description, &author);
1976                 if (!label && !license && !icon && !description && !author)
1977                         continue;
1978
1979                 idx = 1;
1980                 __BIND_TEXT(db, stmt, idx++, mfx->package);
1981                 __BIND_TEXT(db, stmt, idx++, locale);
1982                 __BIND_TEXT(db, stmt, idx++, label);
1983                 __BIND_TEXT(db, stmt, idx++, icon);
1984                 __BIND_TEXT(db, stmt, idx++, description);
1985                 __BIND_TEXT(db, stmt, idx++, license);
1986                 __BIND_TEXT(db, stmt, idx++, author);
1987
1988                 ret = sqlite3_step(stmt);
1989                 if (ret != SQLITE_DONE) {
1990                         _LOGE("step failed: %s", sqlite3_errmsg(db));
1991                         g_list_free(locales);
1992                         sqlite3_finalize(stmt);
1993                         return -1;
1994                 }
1995
1996                 sqlite3_reset(stmt);
1997         }
1998
1999         g_list_free(locales);
2000         sqlite3_finalize(stmt);
2001
2002         return 0;
2003 }
2004
2005 static int __insert_package_info(sqlite3 *db, manifest_x *mfx)
2006 {
2007         static const char query[] =
2008                 "INSERT INTO package_info (package, package_type,"
2009                 "  package_version, package_api_version, package_tep_name,"
2010                 "  package_zip_mount_file, install_location, package_size,"
2011                 "  package_removable, package_preload, package_readonly,"
2012                 "  package_update, package_appsetting, package_nodisplay,"
2013                 "  package_system, author_name, author_email, author_href,"
2014                 "  installed_time, installed_storage, storeclient_id,"
2015                 "  mainapp_id, package_url, root_path, external_path,"
2016                 "  csc_path, package_support_mode, package_support_disable) "
2017                 "VALUES (?, ?,"
2018                 "  ?, ?, ?,"
2019                 "  ?, ?, ?,"
2020                 "  LOWER(?), LOWER(?), LOWER(?),"
2021                 "  LOWER(?), LOWER(?), LOWER(?),"
2022                 "  LOWER(?), ?, ?, ?,"
2023                 "  ?, ?, ?,"
2024                 "  ?, ?, ?, ?,"
2025                 "  ?, ?, LOWER(?))";
2026         int ret;
2027         sqlite3_stmt *stmt;
2028         int idx = 1;
2029         const char *author_name = NULL;
2030         const char *author_email = NULL;
2031         const char *author_href = NULL;
2032
2033         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2034         if (ret != SQLITE_OK) {
2035                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
2036                 return -1;
2037         }
2038
2039         if (mfx->author && mfx->author->data) {
2040                 author_name = ((author_x *)mfx->author->data)->text;
2041                 author_email = ((author_x *)mfx->author->data)->email;
2042                 author_href = ((author_x *)mfx->author->data)->href;
2043         }
2044
2045         __BIND_TEXT(db, stmt, idx++, mfx->package);
2046         __BIND_TEXT(db, stmt, idx++, mfx->type);
2047         __BIND_TEXT(db, stmt, idx++, mfx->version);
2048         __BIND_TEXT(db, stmt, idx++, mfx->api_version);
2049         __BIND_TEXT(db, stmt, idx++, mfx->tep_name);
2050         __BIND_TEXT(db, stmt, idx++, mfx->zip_mount_file);
2051         __BIND_TEXT(db, stmt, idx++, mfx->installlocation);
2052         __BIND_TEXT(db, stmt, idx++, mfx->package_size);
2053         __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->removable, true));
2054         __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->preload, false));
2055         __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->readonly, false));
2056         __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->update, false));
2057         __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->appsetting, false));
2058         __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->nodisplay_setting, false));
2059         __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->system, false));
2060         __BIND_TEXT(db, stmt, idx++, author_name);
2061         __BIND_TEXT(db, stmt, idx++, author_email);
2062         __BIND_TEXT(db, stmt, idx++, author_href);
2063         __BIND_TEXT(db, stmt, idx++, mfx->installed_time);
2064         __BIND_TEXT(db, stmt, idx++, mfx->installed_storage);
2065         __BIND_TEXT(db, stmt, idx++, mfx->storeclient_id);
2066         __BIND_TEXT(db, stmt, idx++, mfx->mainapp_id);
2067         __BIND_TEXT(db, stmt, idx++, mfx->package_url);
2068         __BIND_TEXT(db, stmt, idx++, mfx->root_path);
2069         __BIND_TEXT(db, stmt, idx++, mfx->external_path);
2070         __BIND_TEXT(db, stmt, idx++, mfx->csc_path);
2071         __BIND_TEXT(db, stmt, idx++, mfx->support_mode);
2072         __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->support_disable, false));
2073
2074         ret = sqlite3_step(stmt);
2075         if (ret != SQLITE_DONE) {
2076                 _LOGE("step failed: %s", sqlite3_errmsg(db));
2077                 sqlite3_finalize(stmt);
2078                 return -1;
2079         }
2080
2081         sqlite3_finalize(stmt);
2082
2083         if (__insert_package_update_info(db, mfx))
2084                 return -1;
2085         if (__insert_package_localized_info(db, mfx))
2086                 return -1;
2087         if (__insert_application_info(db, mfx))
2088                 return -1;
2089         if (__insert_package_privilege_info(db, mfx))
2090                 return -1;
2091         if (__insert_package_appdefined_privilege_info(db, mfx))
2092                 return -1;
2093
2094         return 0;
2095 }
2096
2097 API int pkgmgr_parser_insert_manifest_info_in_usr_db(manifest_x *mfx, uid_t uid)
2098 {
2099         int ret;
2100         const char *dbpath;
2101         sqlite3 *db;
2102
2103         if (mfx == NULL) {
2104                 _LOGE("invalid parameter");
2105                 return PM_PARSER_R_EINVAL;
2106         }
2107
2108         dbpath = __get_parser_db_path(uid);
2109
2110         ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
2111         if (ret != SQLITE_OK) {
2112                 _LOGE("open db failed: %d", ret);
2113                 return PM_PARSER_R_ERROR;
2114         }
2115
2116         __BEGIN_TRANSACTION(db);
2117         __DO_TRANSACTION(db, __insert_package_info(db, mfx));
2118         __END_TRANSACTION(db);
2119
2120         sqlite3_close_v2(db);
2121
2122         return PM_PARSER_R_OK;
2123 }
2124
2125 API int pkgmgr_parser_insert_manifest_info_in_db(manifest_x *mfx)
2126 {
2127         return pkgmgr_parser_insert_manifest_info_in_usr_db(mfx, __getuid());
2128 }
2129
2130 static int __delete_package_info(sqlite3 *db, const char *pkgid)
2131 {
2132         static const char query[] =
2133                 "DELETE FROM package_info WHERE package=?";
2134         int ret;
2135         sqlite3_stmt *stmt;
2136
2137         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2138         if (ret != SQLITE_OK) {
2139                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
2140                 return -1;
2141         }
2142
2143         __BIND_TEXT(db, stmt, 1, pkgid);
2144
2145         ret = sqlite3_step(stmt);
2146         if (ret != SQLITE_DONE) {
2147                 _LOGE("step failed: %s", sqlite3_errmsg(db));
2148                 sqlite3_finalize(stmt);
2149                 return -1;
2150         }
2151
2152         sqlite3_finalize(stmt);
2153
2154         return 0;
2155 }
2156
2157 API int pkgmgr_parser_delete_manifest_info_from_usr_db(manifest_x *mfx,
2158         uid_t uid)
2159 {
2160         int ret;
2161         const char *dbpath;
2162         sqlite3 *db;
2163
2164         if (mfx == NULL) {
2165                 _LOGE("invalid parameter");
2166                 return PM_PARSER_R_EINVAL;
2167         }
2168
2169         dbpath = __get_parser_db_path(uid);
2170
2171         ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
2172         if (ret != SQLITE_OK) {
2173                 _LOGE("open db failed: %d", ret);
2174                 return PM_PARSER_R_ERROR;
2175         }
2176
2177         __BEGIN_TRANSACTION(db);
2178         __DO_TRANSACTION(db, __delete_package_info(db, mfx->package));
2179         __END_TRANSACTION(db);
2180
2181         sqlite3_close_v2(db);
2182
2183         return PM_PARSER_R_OK;
2184 }
2185
2186 API int pkgmgr_parser_delete_manifest_info_from_db(manifest_x *mfx)
2187 {
2188         return pkgmgr_parser_delete_manifest_info_from_usr_db(mfx, __getuid());
2189 }
2190
2191 API int pkgmgr_parser_update_manifest_info_in_usr_db(manifest_x *mfx, uid_t uid)
2192 {
2193         int ret;
2194         const char *dbpath;
2195         sqlite3 *db;
2196
2197         if (mfx == NULL) {
2198                 _LOGE("invalid parameter");
2199                 return PM_PARSER_R_EINVAL;
2200         }
2201
2202         dbpath = __get_parser_db_path(uid);
2203
2204         ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
2205         if (ret != SQLITE_OK) {
2206                 _LOGE("open db failed: %d", ret);
2207                 return PM_PARSER_R_ERROR;
2208         }
2209
2210         __BEGIN_TRANSACTION(db);
2211         __DO_TRANSACTION(db, __delete_package_info(db, mfx->package));
2212         __DO_TRANSACTION(db, __insert_package_info(db, mfx));
2213         __END_TRANSACTION(db);
2214
2215         sqlite3_close_v2(db);
2216
2217         return PM_PARSER_R_OK;
2218 }
2219
2220 API int pkgmgr_parser_update_manifest_info_in_db(manifest_x *mfx)
2221 {
2222         return pkgmgr_parser_update_manifest_info_in_usr_db(mfx, __getuid());
2223 }
2224
2225 static int __set_global_app_disable_for_uid(sqlite3 *db, const char *appid,
2226                 uid_t uid, bool is_disable)
2227 {
2228         static const char query[] =
2229                 "INSERT OR REPLACE INTO package_app_info_for_uid ("
2230                 "  app_id, uid, is_disabled, is_splash_screen_enabled) "
2231                 "VALUES (?, ?, ?,"
2232                 "  (SELECT app_splash_screen_display FROM package_app_info"
2233                 "   WHERE app_id=?))";
2234         int ret;
2235         sqlite3_stmt *stmt;
2236         int idx = 1;
2237
2238         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2239         if (ret != SQLITE_OK) {
2240                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
2241                 return -1;
2242         }
2243
2244         __BIND_TEXT(db, stmt, idx++, appid);
2245         __BIND_INT(db, stmt, idx++, uid);
2246         __BIND_TEXT(db, stmt, idx++, is_disable ? "true" : "false");
2247         __BIND_TEXT(db, stmt, idx++, appid);
2248
2249         ret = sqlite3_step(stmt);
2250         if (ret != SQLITE_DONE) {
2251                 _LOGE("step failed: %s", sqlite3_errmsg(db));
2252                 sqlite3_finalize(stmt);
2253                 return -1;
2254         }
2255
2256         sqlite3_finalize(stmt);
2257
2258         return 0;
2259 }
2260
2261 API int pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(
2262                 const char *appid, uid_t uid, int is_disable)
2263 {
2264         int ret;
2265         const char *dbpath;
2266         sqlite3 *db;
2267
2268         if (appid == NULL) {
2269                 _LOGE("invalid parameter");
2270                 return PM_PARSER_R_EINVAL;
2271         }
2272
2273         dbpath = __get_parser_db_path(GLOBAL_USER);
2274
2275         ret = __open_db(GLOBAL_USER, dbpath, &db, SQLITE_OPEN_READWRITE);
2276         if (ret != SQLITE_OK) {
2277                 _LOGE("open db failed: %d", ret);
2278                 return PM_PARSER_R_ERROR;
2279         }
2280
2281         __BEGIN_TRANSACTION(db);
2282         __DO_TRANSACTION(db, __set_global_app_disable_for_uid(db, appid,
2283                                 uid, (bool)is_disable));
2284         __END_TRANSACTION(db);
2285
2286         sqlite3_close_v2(db);
2287
2288         return PM_PARSER_R_OK;
2289 }
2290
2291 static int __set_app_disable(sqlite3 *db, const char *appid, uid_t uid,
2292                 bool is_disable)
2293 {
2294         static const char query[] =
2295                 "UPDATE package_app_info SET app_disable=? "
2296                 "WHERE app_id=?";
2297         int ret;
2298         sqlite3_stmt *stmt;
2299         int idx = 1;
2300
2301         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2302         if (ret != SQLITE_OK) {
2303                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
2304                 return -1;
2305         }
2306
2307         __BIND_TEXT(db, stmt, idx++, is_disable ? "true" : "false");
2308         __BIND_TEXT(db, stmt, idx++, appid);
2309
2310         ret = sqlite3_step(stmt);
2311         if (ret != SQLITE_DONE) {
2312                 _LOGE("step failed: %s", sqlite3_errmsg(db));
2313                 sqlite3_finalize(stmt);
2314                 return -1;
2315         }
2316
2317         sqlite3_finalize(stmt);
2318
2319         return 0;
2320 }
2321
2322 API int pkgmgr_parser_update_app_disable_info_in_usr_db(const char *appid,
2323                 uid_t uid, int is_disable)
2324 {
2325         int ret;
2326         const char *dbpath;
2327         sqlite3 *db;
2328
2329         if (appid == NULL) {
2330                 _LOGE("invalid parameter");
2331                 return PM_PARSER_R_EINVAL;
2332         }
2333
2334         dbpath = __get_parser_db_path(uid);
2335
2336         ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
2337         if (ret != SQLITE_OK) {
2338                 _LOGE("open db failed: %d", ret);
2339                 return PM_PARSER_R_ERROR;
2340         }
2341
2342         __BEGIN_TRANSACTION(db);
2343         __DO_TRANSACTION(db, __set_app_disable(db, appid, uid,
2344                                 (bool)is_disable));
2345         __END_TRANSACTION(db);
2346
2347         sqlite3_close_v2(db);
2348
2349         return PM_PARSER_R_OK;
2350 }
2351
2352 API int pkgmgr_parser_update_app_disable_info_in_db(const char *appid,
2353                 int is_disable)
2354 {
2355         return pkgmgr_parser_update_app_disable_info_in_usr_db(appid,
2356                         __getuid(), is_disable);
2357 }
2358
2359 static int __set_pkg_disable(sqlite3 *db, const char *pkgid, uid_t uid,
2360                 bool is_disable)
2361 {
2362         static const char query[] =
2363                 "UPDATE package_info SET package_disable=? "
2364                 "WHERE package=?";
2365         int ret;
2366         sqlite3_stmt *stmt;
2367         int idx = 1;
2368
2369         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2370         if (ret != SQLITE_OK) {
2371                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
2372                 return -1;
2373         }
2374
2375         __BIND_TEXT(db, stmt, idx++, is_disable ? "true" : "false");
2376         __BIND_TEXT(db, stmt, idx++, pkgid);
2377
2378         ret = sqlite3_step(stmt);
2379         if (ret != SQLITE_DONE) {
2380                 _LOGE("step failed: %s", sqlite3_errmsg(db));
2381                 sqlite3_finalize(stmt);
2382                 return -1;
2383         }
2384
2385         sqlite3_finalize(stmt);
2386
2387         return 0;
2388 }
2389
2390 API int pkgmgr_parser_update_pkg_disable_info_in_usr_db(const char *pkgid,
2391                 uid_t uid, int is_disable)
2392 {
2393         int ret;
2394         const char *dbpath;
2395         sqlite3 *db;
2396
2397         if (pkgid == NULL) {
2398                 _LOGE("invalid parameter");
2399                 return PM_PARSER_R_EINVAL;
2400         }
2401
2402         dbpath = __get_parser_db_path(uid);
2403
2404         ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
2405         if (ret != SQLITE_OK) {
2406                 _LOGE("open db failed: %d", ret);
2407                 return PM_PARSER_R_ERROR;
2408         }
2409
2410         __BEGIN_TRANSACTION(db);
2411         __DO_TRANSACTION(db, __set_pkg_disable(db, pkgid, uid,
2412                                 (bool)is_disable));
2413         __END_TRANSACTION(db);
2414
2415         sqlite3_close_v2(db);
2416
2417         return PM_PARSER_R_OK;
2418 }
2419
2420 API int pkgmgr_parser_update_pkg_disable_info_in_db(const char *pkgid,
2421                 int is_disable)
2422 {
2423         return pkgmgr_parser_update_pkg_disable_info_in_usr_db(pkgid,
2424                         __getuid(), is_disable);
2425 }
2426
2427 static int __set_global_app_splash_screen_for_uid(sqlite3 *db,
2428                 const char *appid, uid_t uid, bool is_enabled)
2429 {
2430         static const char query[] =
2431                 "INSERT OR REPLACE INTO package_app_info_for_uid("
2432                 "  appid, uid, is_splash_screen_enabled) "
2433                 "VALUES (?, ?, ?)";
2434         int ret;
2435         sqlite3_stmt *stmt;
2436         int idx = 1;
2437
2438         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2439         if (ret != SQLITE_OK) {
2440                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
2441                 return -1;
2442         }
2443
2444         __BIND_TEXT(db, stmt, idx++, appid);
2445         __BIND_INT(db, stmt, idx++, uid);
2446         __BIND_TEXT(db, stmt, idx++, is_enabled ? "true" : "false");
2447
2448         ret = sqlite3_step(stmt);
2449         if (ret != SQLITE_DONE) {
2450                 _LOGE("step failed: %s", sqlite3_errmsg(db));
2451                 sqlite3_finalize(stmt);
2452                 return -1;
2453         }
2454
2455         sqlite3_finalize(stmt);
2456
2457         return 0;
2458 }
2459
2460 API int pkgmgr_parser_update_global_app_splash_screen_display_info_in_usr_db(
2461                 const char *appid, uid_t uid, int flag)
2462 {
2463         int ret;
2464         const char *dbpath;
2465         sqlite3 *db;
2466
2467         if (appid == NULL) {
2468                 _LOGE("invalid parameter");
2469                 return PM_PARSER_R_EINVAL;
2470         }
2471
2472         dbpath = __get_parser_db_path(GLOBAL_USER);
2473
2474         ret = __open_db(GLOBAL_USER, dbpath, &db, SQLITE_OPEN_READWRITE);
2475         if (ret != SQLITE_OK) {
2476                 _LOGE("open db failed: %d", ret);
2477                 return PM_PARSER_R_ERROR;
2478         }
2479
2480         __BEGIN_TRANSACTION(db);
2481         __DO_TRANSACTION(db, __set_global_app_splash_screen_for_uid(db,
2482                                 appid, uid, (bool)flag));
2483         __END_TRANSACTION(db);
2484
2485         sqlite3_close_v2(db);
2486
2487         return PM_PARSER_R_OK;
2488 }
2489
2490 static int __set_app_splash_screen(sqlite3 *db, const char *appid,
2491                 bool is_enabled)
2492 {
2493         static const char query[] =
2494                 "UPDATE package_app_info SET app_splash_screen_display=? "
2495                 "WHERE app_id=?";
2496         int ret;
2497         sqlite3_stmt *stmt;
2498         int idx = 1;
2499
2500         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2501         if (ret != SQLITE_OK) {
2502                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
2503                 return -1;
2504         }
2505
2506         __BIND_TEXT(db, stmt, idx++, is_enabled ? "true" : "false");
2507         __BIND_TEXT(db, stmt, idx++, appid);
2508
2509         ret = sqlite3_step(stmt);
2510         if (ret != SQLITE_DONE) {
2511                 _LOGE("step failed: %s", sqlite3_errmsg(db));
2512                 sqlite3_finalize(stmt);
2513                 return -1;
2514         }
2515
2516         sqlite3_finalize(stmt);
2517
2518         return 0;
2519 }
2520
2521 API int pkgmgr_parser_update_app_splash_screen_display_info_in_usr_db(
2522                 const char *appid, uid_t uid, int flag)
2523 {
2524         int ret;
2525         const char *dbpath;
2526         sqlite3 *db;
2527
2528         if (appid == NULL) {
2529                 _LOGE("invalid parameter");
2530                 return PM_PARSER_R_EINVAL;
2531         }
2532
2533         dbpath = __get_parser_db_path(uid);
2534
2535         ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
2536         if (ret != SQLITE_OK) {
2537                 _LOGE("open db failed: %d", ret);
2538                 return PM_PARSER_R_ERROR;
2539         }
2540
2541         __BEGIN_TRANSACTION(db);
2542         __DO_TRANSACTION(db, __set_app_splash_screen(db, appid, (bool)flag));
2543         __END_TRANSACTION(db);
2544
2545         sqlite3_close_v2(db);
2546
2547         return PM_PARSER_R_OK;
2548 }
2549
2550 API int pkgmgr_parser_update_app_splash_screen_display_info_in_db(
2551                 const char *appid, int flag)
2552 {
2553         return pkgmgr_parser_update_app_splash_screen_display_info_in_usr_db(
2554                         appid, __getuid(), flag);
2555 }
2556
2557 static int __set_app_label(sqlite3 *db, const char *appid, const char *label)
2558 {
2559         static const char query[] =
2560                 "UPDATE package_app_localized_info SET app_label=? "
2561                 "WHERE app_id=? AND app_label IS NOT NULL";
2562         int ret;
2563         sqlite3_stmt *stmt;
2564         int idx = 1;
2565
2566         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2567         if (ret != SQLITE_OK) {
2568                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
2569                 return -1;
2570         }
2571
2572         __BIND_TEXT(db, stmt, idx++, label);
2573         __BIND_TEXT(db, stmt, idx++, appid);
2574
2575         ret = sqlite3_step(stmt);
2576         if (ret != SQLITE_DONE) {
2577                 _LOGE("step failed: %s", sqlite3_errmsg(db));
2578                 sqlite3_finalize(stmt);
2579                 return -1;
2580         }
2581
2582         sqlite3_finalize(stmt);
2583
2584         return 0;
2585 }
2586
2587 API int pkgmgr_parser_update_app_label_info_in_usr_db(const char *appid,
2588                 uid_t uid, const char *label)
2589 {
2590         int ret;
2591         const char *dbpath;
2592         sqlite3 *db;
2593
2594         if (appid == NULL) {
2595                 _LOGE("invalid parameter");
2596                 return PM_PARSER_R_EINVAL;
2597         }
2598
2599         dbpath = __get_parser_db_path(uid);
2600
2601         ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
2602         if (ret != SQLITE_OK) {
2603                 _LOGE("open db failed: %d", ret);
2604                 return PM_PARSER_R_ERROR;
2605         }
2606
2607         __BEGIN_TRANSACTION(db);
2608         __DO_TRANSACTION(db, __set_app_label(db, appid, label));
2609         __END_TRANSACTION(db);
2610
2611         sqlite3_close_v2(db);
2612
2613         return PM_PARSER_R_OK;
2614 }
2615
2616 API int pkgmgr_parser_update_app_label_info_in_db(const char *appid,
2617                 const char *label)
2618 {
2619         return pkgmgr_parser_update_app_label_info_in_usr_db(appid, __getuid(),
2620                         label);
2621 }
2622
2623 static int __set_app_icon(sqlite3 *db, const char *appid, const char *icon_path)
2624 {
2625         static const char query[] =
2626                 "UPDATE package_app_localized_info SET app_icon=? "
2627                 "WHERE app_id=? AND app_icon IS NOT NULL";
2628         int ret;
2629         sqlite3_stmt *stmt;
2630         int idx = 1;
2631
2632         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2633         if (ret != SQLITE_OK) {
2634                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
2635                 return -1;
2636         }
2637
2638         __BIND_TEXT(db, stmt, idx++, icon_path);
2639         __BIND_TEXT(db, stmt, idx++, appid);
2640
2641         ret = sqlite3_step(stmt);
2642         if (ret != SQLITE_DONE) {
2643                 _LOGE("step failed: %s", sqlite3_errmsg(db));
2644                 sqlite3_finalize(stmt);
2645                 return -1;
2646         }
2647
2648         sqlite3_finalize(stmt);
2649
2650         return 0;
2651 }
2652
2653 API int pkgmgr_parser_update_app_icon_info_in_usr_db(const char *appid,
2654                 uid_t uid, const char *icon_path)
2655 {
2656         int ret;
2657         const char *dbpath;
2658         sqlite3 *db;
2659
2660         if (appid == NULL) {
2661                 _LOGE("invalid parameter");
2662                 return PM_PARSER_R_EINVAL;
2663         }
2664
2665         dbpath = __get_parser_db_path(uid);
2666
2667         ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
2668         if (ret != SQLITE_OK) {
2669                 _LOGE("open db failed: %d", ret);
2670                 return PM_PARSER_R_ERROR;
2671         }
2672
2673         __BEGIN_TRANSACTION(db);
2674         __DO_TRANSACTION(db, __set_app_icon(db, appid, icon_path));
2675         __END_TRANSACTION(db);
2676
2677         sqlite3_close_v2(db);
2678
2679         return PM_PARSER_R_OK;
2680 }
2681
2682 API int pkgmgr_parser_update_app_icon_info_in_db(const char *appid,
2683                 const char *icon_path)
2684 {
2685         return pkgmgr_parser_update_app_icon_info_in_usr_db(appid, __getuid(),
2686                         icon_path);
2687 }
2688
2689 static int __set_tep_path(sqlite3 *db, const char *pkgid, const char *tep_path)
2690 {
2691         static const char query[] =
2692                 "UPDATE package_info SET package_tep_name=? "
2693                 "WHERE package=?";
2694         int ret;
2695         sqlite3_stmt *stmt;
2696         int idx = 1;
2697
2698         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2699         if (ret != SQLITE_OK) {
2700                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
2701                 return -1;
2702         }
2703
2704         __BIND_TEXT(db, stmt, idx++, tep_path);
2705         __BIND_TEXT(db, stmt, idx++, pkgid);
2706
2707         ret = sqlite3_step(stmt);
2708         if (ret != SQLITE_DONE) {
2709                 _LOGE("step failed: %s", sqlite3_errmsg(db));
2710                 sqlite3_finalize(stmt);
2711                 return -1;
2712         }
2713
2714         sqlite3_finalize(stmt);
2715
2716         return 0;
2717 }
2718
2719 API int pkgmgr_parser_update_tep_info_in_usr_db(const char *pkgid,
2720                 const char *tep_path, uid_t uid)
2721 {
2722         int ret;
2723         const char *dbpath;
2724         sqlite3 *db;
2725
2726         if (pkgid == NULL) {
2727                 _LOGE("invalid parameter");
2728                 return PM_PARSER_R_EINVAL;
2729         }
2730
2731         dbpath = __get_parser_db_path(uid);
2732
2733         ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
2734         if (ret != SQLITE_OK) {
2735                 _LOGE("open db failed: %d", ret);
2736                 return PM_PARSER_R_ERROR;
2737         }
2738
2739         __BEGIN_TRANSACTION(db);
2740         __DO_TRANSACTION(db, __set_tep_path(db, pkgid, tep_path));
2741         __END_TRANSACTION(db);
2742
2743         sqlite3_close_v2(db);
2744
2745         return PM_PARSER_R_OK;
2746 }
2747
2748 API int pkgmgr_parser_update_tep_info_in_db(const char *pkgid,
2749                 const char *tep_path)
2750 {
2751         return pkgmgr_parser_update_tep_info_in_usr_db(pkgid, tep_path,
2752                         __getuid());
2753 }
2754
2755 static int __convert_update_type(pkgmgrinfo_updateinfo_update_type type,
2756                 const char **update_type)
2757 {
2758         if (type == PMINFO_UPDATEINFO_NONE)
2759                 *update_type = PMINFO_UPDATEINFO_TYPE_NONE;
2760         else if (type == PMINFO_UPDATEINFO_FORCE)
2761                 *update_type = PMINFO_UPDATEINFO_TYPE_FORCE;
2762         else if (type == PMINFO_UPDATEINFO_OPTIONAL)
2763                 *update_type = PMINFO_UPDATEINFO_TYPE_OPTIONAL;
2764         else
2765                 return -1;
2766         return 0;
2767 }
2768
2769 static int __register_pkg_update_info(sqlite3 *db, updateinfo_x *info,
2770                 const char *update_type)
2771 {
2772         static const char query[] =
2773                 "UPDATE package_update_info "
2774                 "SET update_version=?, update_type=? "
2775                 "WHERE package=?";
2776         int ret;
2777         sqlite3_stmt *stmt;
2778         int idx = 1;
2779
2780         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2781         if (ret != SQLITE_OK) {
2782                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
2783                 return -1;
2784         }
2785
2786         __BIND_TEXT(db, stmt, idx++, info->version);
2787         __BIND_TEXT(db, stmt, idx++, update_type);
2788         __BIND_TEXT(db, stmt, idx++, info->pkgid);
2789
2790         ret = sqlite3_step(stmt);
2791         if (ret != SQLITE_DONE) {
2792                 _LOGE("step failed: %s", sqlite3_errmsg(db));
2793                 sqlite3_finalize(stmt);
2794                 return -1;
2795         }
2796
2797         sqlite3_finalize(stmt);
2798
2799         return 0;
2800 }
2801
2802 API int pkgmgr_parser_register_pkg_update_info_in_usr_db(
2803                 pkgmgrinfo_updateinfo_h handle, uid_t uid)
2804 {
2805         int ret;
2806         updateinfo_x *update_info;
2807         updateinfo_x *prev_update_info;
2808         pkgmgrinfo_updateinfo_h prev_update_handle;
2809         pkgmgrinfo_pkginfo_h pkginfo;
2810         pkgmgrinfo_version_compare_type compare_result;
2811         bool is_global_pkg;
2812         const char *update_type;
2813         const char *dbpath;
2814         sqlite3 *db;
2815
2816         if (handle == NULL) {
2817                 _LOGE("invalid parameter");
2818                 return PM_PARSER_R_EINVAL;
2819         }
2820
2821         update_info = (updateinfo_x *)handle;
2822         if (update_info->pkgid == NULL || update_info->version == NULL)
2823                 return PM_PARSER_R_EINVAL;
2824         if (__convert_update_type(update_info->type, &update_type) != 0)
2825                 return PM_PARSER_R_EINVAL;
2826
2827         ret = pkgmgrinfo_updateinfo_get_usr_updateinfo(update_info->pkgid,
2828                         &prev_update_handle, uid);
2829         if (ret != PMINFO_R_OK)
2830                 return PM_PARSER_R_ERROR;
2831
2832         prev_update_info = (updateinfo_x *)prev_update_handle;
2833         ret = pkgmgrinfo_compare_package_version(update_info->version,
2834                         prev_update_info->version, &compare_result);
2835         if (ret != PMINFO_R_OK) {
2836                 pkgmgrinfo_updateinfo_destroy(prev_update_handle);
2837                 return PM_PARSER_R_ERROR;
2838         }
2839
2840         if (compare_result == PMINFO_VERSION_SAME &&
2841                         prev_update_info->type == PMINFO_UPDATEINFO_NONE) {
2842                 _LOGI("Given update info version[%s] of pkgid[%s] "
2843                                 "will be ignored",
2844                                 update_info->version, update_info->pkgid);
2845                 pkgmgrinfo_updateinfo_destroy(prev_update_handle);
2846                 return PM_PARSER_R_OK;
2847         }
2848         pkgmgrinfo_updateinfo_destroy(prev_update_handle);
2849
2850         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(update_info->pkgid, uid,
2851                         &pkginfo);
2852         if (ret != PMINFO_R_OK)
2853                 return PM_PARSER_R_ERROR;
2854
2855         ret = pkgmgrinfo_pkginfo_is_global(pkginfo, &is_global_pkg);
2856         if (ret != PMINFO_R_OK) {
2857                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
2858                 return PM_PARSER_R_ERROR;
2859         }
2860         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
2861
2862         dbpath = __get_parser_db_path(is_global_pkg ? GLOBAL_USER : uid);
2863
2864         ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
2865         if (ret != SQLITE_OK) {
2866                 _LOGE("open db failed: %d", ret);
2867                 return PM_PARSER_R_ERROR;
2868         }
2869
2870         __BEGIN_TRANSACTION(db);
2871         __DO_TRANSACTION(db, __register_pkg_update_info(db, update_info,
2872                                 update_type));
2873         __END_TRANSACTION(db);
2874
2875         sqlite3_close_v2(db);
2876
2877         return PM_PARSER_R_OK;
2878 }
2879
2880 API int pkgmgr_parser_register_pkg_update_info_in_db(
2881                 pkgmgrinfo_updateinfo_h handle)
2882 {
2883         return pkgmgr_parser_register_pkg_update_info_in_usr_db(handle,
2884                         __getuid());
2885 }
2886
2887 static int __unregister_pkg_update_info(sqlite3 *db, const char *pkgid)
2888 {
2889         static const char query[] =
2890                 "UPDATE package_update_info SET update_type='none' "
2891                 "WHERE package=?";
2892         int ret;
2893         sqlite3_stmt *stmt;
2894         int idx = 1;
2895
2896         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2897         if (ret != SQLITE_OK) {
2898                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
2899                 return -1;
2900         }
2901
2902         __BIND_TEXT(db, stmt, idx++, pkgid);
2903
2904         ret = sqlite3_step(stmt);
2905         if (ret != SQLITE_DONE) {
2906                 _LOGE("step failed: %s", sqlite3_errmsg(db));
2907                 sqlite3_finalize(stmt);
2908                 return -1;
2909         }
2910
2911         sqlite3_finalize(stmt);
2912
2913         return 0;
2914 }
2915
2916 API int pkgmgr_parser_unregister_pkg_update_info_in_usr_db(const char *pkgid,
2917                 uid_t uid)
2918 {
2919         int ret;
2920         const char *dbpath;
2921         sqlite3 *db;
2922         pkgmgrinfo_pkginfo_h pkginfo;
2923         bool is_global_pkg;
2924
2925         if (pkgid == NULL) {
2926                 _LOGE("invalid parameter");
2927                 return PM_PARSER_R_EINVAL;
2928         }
2929
2930         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &pkginfo);
2931         if (ret != PMINFO_R_OK)
2932                 return PM_PARSER_R_EINVAL;
2933
2934         ret = pkgmgrinfo_pkginfo_is_global(pkginfo, &is_global_pkg);
2935         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
2936         if (ret != PMINFO_R_OK)
2937                 return PM_PARSER_R_ERROR;
2938
2939         dbpath = __get_parser_db_path(is_global_pkg ? GLOBAL_USER : uid);
2940
2941         ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
2942         if (ret != SQLITE_OK) {
2943                 _LOGE("open db failed: %d", ret);
2944                 return PM_PARSER_R_ERROR;
2945         }
2946
2947         __BEGIN_TRANSACTION(db);
2948         __DO_TRANSACTION(db, __unregister_pkg_update_info(db, pkgid));
2949         __END_TRANSACTION(db);
2950
2951         sqlite3_close_v2(db);
2952
2953         return PM_PARSER_R_OK;
2954 }
2955
2956 API int pkgmgr_parser_unregister_pkg_update_info_in_db(const char *pkgid)
2957 {
2958         return pkgmgr_parser_unregister_pkg_update_info_in_usr_db(pkgid,
2959                         __getuid());
2960 }
2961
2962 static int __unregister_all_pkg_update_info(sqlite3 *db)
2963 {
2964         static const char query[] =
2965                 "UPDATE package_update_info SET update_type='none'";
2966         int ret;
2967         sqlite3_stmt *stmt;
2968
2969         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2970         if (ret != SQLITE_OK) {
2971                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
2972                 return -1;
2973         }
2974
2975         ret = sqlite3_step(stmt);
2976         if (ret != SQLITE_DONE) {
2977                 _LOGE("step failed: %s", sqlite3_errmsg(db));
2978                 sqlite3_finalize(stmt);
2979                 return -1;
2980         }
2981
2982         sqlite3_finalize(stmt);
2983
2984         return 0;
2985 }
2986
2987 API int pkgmgr_parser_unregister_all_pkg_update_info_in_usr_db(uid_t uid)
2988 {
2989         int ret;
2990         const char *dbpath;
2991         sqlite3 *db;
2992
2993         dbpath = __get_parser_db_path(uid);
2994
2995         ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
2996         if (ret != SQLITE_OK) {
2997                 _LOGE("open db failed: %d", ret);
2998                 return PM_PARSER_R_ERROR;
2999         }
3000
3001         __BEGIN_TRANSACTION(db);
3002         __DO_TRANSACTION(db, __unregister_all_pkg_update_info(db));
3003         __END_TRANSACTION(db);
3004
3005         sqlite3_close_v2(db);
3006
3007         return PM_PARSER_R_OK;
3008 }
3009
3010 API int pkgmgr_parser_unregister_all_pkg_update_info_in_db(void)
3011 {
3012         return pkgmgr_parser_unregister_all_pkg_update_info_in_usr_db(
3013                         __getuid());
3014 }