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