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