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