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