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