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