tizen 2.3 release
[apps/livebox/data-provider-master.git] / pkgmgr_dynamicbox / src / service_register.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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 #include <stdio.h>
18 #include <errno.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 #include <libgen.h>
23 #include <string.h>
24
25 #include <sqlite3.h>
26 #include <db-util.h>
27 #include <libxml/parser.h>
28 #include <libxml/tree.h>
29 #include <dlog.h>
30
31 #include <dynamicbox_service.h>
32
33 #include "dlist.h"
34
35 #if !defined(FLOG)
36 #define DbgPrint(format, arg...)        SECURE_LOGD("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
37 #define ErrPrint(format, arg...)        SECURE_LOGE("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
38 #define ErrPrintWithConsole(format, arg...)     do { fprintf(stderr, "[%s/%s:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); SECURE_LOGE("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); } while (0)
39 #endif
40
41 #define CUR_VER 5
42 #define DEFAULT_CATEGORY        "http://tizen.org/category/default"
43
44 /*!
45  * \note
46  * DB Table schema
47  *
48  * version
49  * +---------+
50  * | version |
51  * +---------+
52  * |   -     |
53  * +---------+
54  * CREATE TABLE version ( version INTEGER )
55  * 
56  *
57  * pkgmap
58  * +-------+-------+-------+-------+-------------------+
59  * | appid | pkgid | uiapp | prime | categ(from ver 2) |
60  * +-------+-------+-------+-------+-------------------+
61  * |   -   |   -   |   -   |   -   |         -         |
62  * +-------+-------+-------+-------+-------------------+
63  * CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, uiapp TEXT, prime INTEGER, category TEXT )
64  *
65  *
66  * provider
67  * +-------+---------+-----+---------+----------+---------+-----------+---------+--------+----------+---------+---------+--------+--------+-------+-----------------------+
68  * | pkgid | network | abi | secured | box_type | box_src | box_group | gbar_type | gbar_src | gbar_group | libexec | timeout | period | script | pinup | count(from ver 4) | direct_input | hw_acceleration |
69  * +-------+---------+-----+---------+----------+---------+-----------+---------+--------+----------+---------+---------+--------+--------+-------+-----------------------+-------|---------------|
70  * |   -   |    -    |  -  |    -    |     -    |    -    |     -     |    -    |    -   |     -    |     -   |    -    |    -   |    -   |   -   |           -           |   -   |       -       |
71  * +-------+---------+-----+---------+----------+---------+-----------+---------+--------+----------+---------+---------+--------+--------+-------+-----------------------+-------|---------------|
72  * CREATE TABLE provider ( pkgid TEXT PRIMARY KEY NOT NULL, network INTEGER, abi TEXT, secured INTEGER, box_type INTEGER, box_src TEXT, box_group TEXT, gbar_type TEXT, gbar_src TEXT, gbar_group TEXT, libexec TEXT, timeout INTEGER, period TEXT, script TEXT, pinup INTEGER, count INTEGER, direct_input INTEGER DEFAULT 0, hw_acceleration TEXT DEFAULT 'none', FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid))
73  *
74  * = box_type = { text | buffer | script | image }
75  * = gbar_type = { text | buffer | script }
76  * = network = { 1 | 0 }
77  * = secured = { 1 | 0 }
78  *
79  *
80  * client
81  * +-------+------+---------+-------------+-----------+---------+-----------+-------+
82  * | pkgid | Icon |  Name   | auto_launch | gbar_size | content | nodisplay | setup |
83  * +-------+------+---------+-------------+-----------+---------+-----------+-------+
84  * |   -   |   -  |    -    |      -      |    -      |    -    |     -     |   -   |
85  * +-------+------+---------+-------------+-----------+---------+-----------+-------+
86  * CREATE TABLE client ( pkgid TEXT PRIMARY KEY NOT NULL, icon TEXT, name TEXT, auto_launch TEXT, gbar_size TEXT, content TEXT, nodisplay INTEGER, setup TEXT, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
87  *
88  * = auto_launch = UI-APPID
89  * = gbar_size = WIDTHxHEIGHT
90  *
91  *
92  * i18n
93  * +-------+------+------+------+
94  * |   fk  | lang | name | icon |
95  * +-------+------+------+------+
96  * | pkgid |   -  |   -  |   -  |
97  * +-------+------+------+------+
98  * CREATE TABLE i18n ( pkgid TEXT NOT NULL, lang TEXT COLLATE NOCASE, name TEXT, icon TEXT, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
99  *
100  *
101  * box_size
102  * +-------+-----------+---------+--------------+------------+-------------------------+
103  * | pkgid | size_type | preview | touch_effect | need_frame | mouse_event(from ver 3) |
104  * +-------+-----------+---------+--------------+------------+-------------------------+
105  * |   -   |     -     |    -    |       -      |     -      |            -            |
106  * +-------+-----------+---------+--------------+------------+-------------------------+
107  * CREATE TABLE box_size ( pkgid TEXT NOT NULL, size_type INTEGER, preview TEXT, INTEGER, touch_effect INTEGER, need_frame INTEGER, mouse_event INTEGER, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
108  *
109  * = box_size_list = { WIDTHxHEIGHT; WIDTHxHEIGHT; ... }
110  *
111  * groupinfo
112  * +----+---------+----------+-------+
113  * | id | cluster | category | pkgid |
114  * +----+---------+----------+-------+
115  * |  - |    -    |    -     |   -   |
116  * +----+---------+----------+-------|
117  * CREATE TABLE groupinfo ( id INTEGER PRIMARY KEY AUTOINCREMENT, cluster TEXT NOT NULL, category TEXT NOT NULL, appid TEXT NOT NULL, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ))
118  *
119  * groupmap
120  * +-------+----+----------+-----------+
121  * | pkgid | id | ctx_item | option_id |
122  * +-------+----+----------+-----------+
123  * CREATE TABLE groupmap ( option_id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER, pkgid TEXT NOT NULL, ctx_item TEXT NOT NULL, FOREIGN KEY(id) REFERENCES groupinfo(id), FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
124  *
125  *
126  * option
127  * +-------+-----------+-----+-------+
128  * | pkgid | option_id | key | value |
129  * +-------+-----------+-----+-------+
130  * CREATE TABLE option ( pkgid TEXT NOT NULL, option_id INTEGER, key TEXT NOT NULL, value TEXT NOT NULL, FOREIGN KEY(option_id) REFERENCES groupmap(option_id), FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid)  )
131  */
132
133 #if !defined(LIBXML_TREE_ENABLED)
134         #error "LIBXML is not supporting the tree"
135 #endif
136
137 #if defined(LOG_TAG)
138 #undef LOG_TAG
139 #endif
140
141 #define LOG_TAG "PKGMGR_DYNAMICBOX"
142
143  int errno;
144
145  struct i18n {
146      xmlChar *lang;
147      xmlChar *name;
148      xmlChar *icon;
149  };
150
151 struct dynamicbox {
152     xmlChar *pkgid;
153     int secured;
154     int network;
155     xmlChar *auto_launch;
156     xmlChar *abi;
157     xmlChar *name; /* Default name */
158     xmlChar *icon; /* Default icon */
159     xmlChar *libexec; /* Path of the SO file */
160     xmlChar *timeout; /* INTEGER, timeout */
161     xmlChar *period; /* DOUBLE, update period */
162     xmlChar *script; /* Script engine */
163     xmlChar *content; /* Content information */
164     xmlChar *setup;
165     xmlChar *uiapp;     /* UI App Id */
166     xmlChar *category; /* Category of this box */
167
168     int pinup; /* Is this support the pinup feature? */
169     int primary; /* Is this primary dynamicbox? */
170     int nodisplay;
171     int count; /* Max count of instances */
172     int direct_input; /* Use the input node to get the event directly */
173
174     int default_mouse_event; /* Mouse event processing option for dynamicbox */
175     int default_touch_effect;
176     int default_need_frame;
177
178     enum dynamicbox_dbox_type dbox_type;
179     xmlChar *dbox_src;
180     xmlChar *dbox_group;
181     int size_list; /* 1x1, 2x1, 2x2, 4x1, 4x2, 4x3, 4x4 */
182
183     xmlChar *preview[DBOX_NR_OF_SIZE_LIST];
184     int touch_effect[DBOX_NR_OF_SIZE_LIST]; /* Touch effect of a dynamicbox */
185     int need_frame[DBOX_NR_OF_SIZE_LIST]; /* Box needs frame which should be cared by viewer */
186     int mouse_event[DBOX_NR_OF_SIZE_LIST];
187
188     enum dynamicbox_gbar_type gbar_type;
189     xmlChar *gbar_src;
190     xmlChar *gbar_group;
191     xmlChar *gbar_size; /* Default PD size */
192     xmlChar *hw_acceleration;
193
194     struct dlist *i18n_list;
195     struct dlist *group_list;
196 };
197
198 struct group {
199     xmlChar *cluster;
200     xmlChar *category;
201     xmlChar *ctx_item;
202     struct dlist *option_list;
203 };
204
205 struct option {
206     xmlChar *key;
207     xmlChar *value;
208 };
209
210 static struct {
211     const char *dbfile;
212     sqlite3 *handle;
213 } s_info = {
214     .dbfile = "/opt/dbspace/.dynamicbox.db",
215     .handle = NULL,
216 };
217
218 static inline int begin_transaction(void)
219 {
220     sqlite3_stmt *stmt;
221     int ret;
222
223     ret = sqlite3_prepare_v2(s_info.handle, "BEGIN TRANSACTION", -1, &stmt, NULL);
224
225     if (ret != SQLITE_OK) {
226         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
227         return EXIT_FAILURE;
228     }
229
230     if (sqlite3_step(stmt) != SQLITE_DONE) {
231         DbgPrint("Failed to do update (%s)\n",
232                 sqlite3_errmsg(s_info.handle));
233         sqlite3_finalize(stmt);
234         return EXIT_FAILURE;
235     }
236
237     sqlite3_finalize(stmt);
238     return EXIT_SUCCESS;
239 }
240
241 static inline int rollback_transaction(void)
242 {
243     int ret;
244     sqlite3_stmt *stmt;
245
246     ret = sqlite3_prepare_v2(s_info.handle, "ROLLBACK TRANSACTION", -1, &stmt, NULL);
247     if (ret != SQLITE_OK) {
248         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
249         return EXIT_FAILURE;
250     }
251
252     if (sqlite3_step(stmt) != SQLITE_DONE) {
253         DbgPrint("Failed to do update (%s)\n",
254                 sqlite3_errmsg(s_info.handle));
255         sqlite3_finalize(stmt);
256         return EXIT_FAILURE;
257     }
258
259     sqlite3_finalize(stmt);
260     return EXIT_SUCCESS;
261 }
262
263 static inline int commit_transaction(void)
264 {
265     sqlite3_stmt *stmt;
266     int ret;
267
268     ret = sqlite3_prepare_v2(s_info.handle, "COMMIT TRANSACTION", -1, &stmt, NULL);
269     if (ret != SQLITE_OK) {
270         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
271         return EXIT_FAILURE;
272     }
273
274     if (sqlite3_step(stmt) != SQLITE_DONE) {
275         DbgPrint("Failed to do update (%s)\n",
276                 sqlite3_errmsg(s_info.handle));
277         sqlite3_finalize(stmt);
278         return EXIT_FAILURE;
279     }
280
281     sqlite3_finalize(stmt);
282     return EXIT_SUCCESS;
283 }
284
285 static void db_create_version(void)
286 {
287     static const char *ddl = "CREATE TABLE version (version INTEGER)";
288     char *err;
289
290     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
291         ErrPrint("Failed to execute the DDL (%s)\n", err);
292         return;
293     }
294
295     if (sqlite3_changes(s_info.handle) == 0) {
296         ErrPrint("No changes to DB\n");
297     }
298 }
299
300 static int set_version(int version)
301 {
302     static const char *dml = "INSERT INTO version (version) VALUES (?)";
303     sqlite3_stmt *stmt;
304     int ret;
305
306     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
307     if (ret != SQLITE_OK) {
308         ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
309         return -EIO;
310     }
311
312     if (sqlite3_bind_int(stmt, 1, version) != SQLITE_OK) {
313         ErrPrint("Failed to bind a id(%s)\n", sqlite3_errmsg(s_info.handle));
314         ret = -EIO;
315         goto out;
316     }
317
318     ret = sqlite3_step(stmt);
319     if (ret != SQLITE_DONE) {
320         ErrPrint("Failed to execute the DML for version: %d\n", ret);
321         ret = -EIO;
322     } else {
323         ret = 0;
324     }
325
326 out:
327     sqlite3_reset(stmt);
328     sqlite3_clear_bindings(stmt);
329     sqlite3_finalize(stmt);
330     return ret;
331 }
332
333 static int update_version(int version)
334 {
335     static const char *dml = "UPDATE version SET version = ?";
336     sqlite3_stmt *stmt;
337     int ret;
338
339     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
340     if (ret != SQLITE_OK) {
341         ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
342         return -EIO;
343     }
344
345     if (sqlite3_bind_int(stmt, 1, version) != SQLITE_OK) {
346         ErrPrint("Failed to bind a version: %s\n", sqlite3_errmsg(s_info.handle));
347         ret = -EIO;
348         goto out;
349     }
350
351     ret = sqlite3_step(stmt);
352     if (ret != SQLITE_DONE) {
353         ErrPrint("Failed to execute DML: %d\n", ret);
354         ret = -EIO;
355     } else {
356         ret = 0;
357     }
358
359 out:
360     sqlite3_reset(stmt);
361     sqlite3_clear_bindings(stmt);
362     sqlite3_finalize(stmt);
363     return ret;
364 }
365
366 static int get_version(void)
367 {
368     static const char *dml = "SELECT version FROM version";
369     sqlite3_stmt *stmt;
370     int ret;
371
372     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
373     if (ret != SQLITE_OK) {
374         return -ENOSYS;
375     }
376
377     if (sqlite3_step(stmt) != SQLITE_ROW) {
378         ret = -ENOENT;
379     } else {
380         ret = sqlite3_column_int(stmt, 0);
381     }
382
383     sqlite3_reset(stmt);
384     sqlite3_clear_bindings(stmt);
385     sqlite3_finalize(stmt);
386     return ret;
387 }
388
389 /*!
390  * \note
391  * From version 1 to 2
392  */
393 static void upgrade_pkgmap_for_category(void)
394 {
395     char *err;
396     static const char *ddl;
397
398     ddl = "ALTER TABLE pkgmap ADD COLUMN category TEXT DEFAULT \"" DEFAULT_CATEGORY "\"";
399     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
400         ErrPrint("Failed to execute the DDL (%s)\n", err);
401         return;
402     }
403
404     if (sqlite3_changes(s_info.handle) == 0) {
405         ErrPrint("No changes to DB\n");
406     }
407
408     return;
409 }
410
411 /**
412  * From version 4 to 5
413  * "provider" table should have "direct_input" column.
414  * "direct_input" will be used for selecting input event path.
415  * if it is "true", the provider must has to get all events from device node directly.
416  * The file descriptor will be given by data-provider-master
417  */
418 static void upgrade_to_version_5(void)
419 {
420     char *err;
421     static const char *ddl;
422
423     /*
424      * Step 1
425      * Create a new column "direct_input" for provider table
426      */
427     ddl = "ALTER TABLE provider ADD COLUMN direct_input INTEGER DEFAULT 0";
428     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
429         ErrPrint("Failed to execute the DDL (%s)\n", err);
430         return;
431     }
432
433     if (sqlite3_changes(s_info.handle) == 0) {
434         ErrPrint("No changes to DB\n");
435     }
436
437     /*
438      * Step 2
439      * Create a new column "hw_acceleration" for provider table
440      */
441     ddl = "ALTER TABLE provider ADD COLUMN hw_acceleration TEXT DEFAULT 'none'";
442     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
443         ErrPrint("Failed to execute the DDL (%s)\n", err);
444         return;
445     }
446
447     if (sqlite3_changes(s_info.handle) == 0) {
448         ErrPrint("No changes to DB\n");
449     }
450 }
451
452 /*!
453  * \note
454  * From version 3 to 4
455  * "provider" table should have "count" column.
456  * "count" will be used for limiting creatable count of instances for each dynamicbox.
457  * Every dynamicbox developer should describe their max count of creatable instances.
458  */
459 static void upgrade_to_version_4(void)
460 {
461     char *err;
462     static const char *ddl;
463
464     /*
465      * Step 1
466      * Create a new column for count to provider table.
467      */
468     ddl = "ALTER TABLE provider ADD COLUMN count INTEGER DEFAULT 0";
469     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
470         ErrPrint("Failed to execute the DDL (%s)\n", err);
471         return;
472     }
473
474     if (sqlite3_changes(s_info.handle) == 0) {
475         ErrPrint("No changes to DB\n");
476     }
477 }
478
479 /*!
480  * \note
481  * From version 2 to 3
482  * mouse_event is deleted from client table
483  * mouse_event is added to box_size table
484  *
485  * Every size has their own configuration for mouse_event flag.
486  */
487 static void upgrade_to_version_3(void)
488 {
489     char *err;
490     static const char *ddl;
491     static const char *dml;
492     sqlite3_stmt *select_stmt;
493     int ret;
494
495     /*
496      * Step 1
497      * Create a new column for mouse_event to box_size table.
498      */
499     ddl = "ALTER TABLE box_size ADD COLUMN mouse_event INTEGER DEFAULT 0";
500     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
501         ErrPrint("Failed to execute the DDL (%s)\n", err);
502         return;
503     }
504
505     if (sqlite3_changes(s_info.handle) == 0) {
506         ErrPrint("No changes to DB\n");
507     }
508
509     /*
510      * Step 2
511      * Copy mouse_event values from the client to the box_size table.
512      */
513     dml = "SELECT pkgid, mouse_event FROM client";
514     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &select_stmt, NULL);
515     if (ret == SQLITE_OK) {
516         sqlite3_stmt *update_stmt;
517
518         dml = "UPDATE box_size SET mouse_event = ? WHERE pkgid = ?";
519         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &update_stmt, NULL);
520         if (ret == SQLITE_OK) {
521             int mouse_event;
522             const char *pkgid;
523
524             while (sqlite3_step(select_stmt) == SQLITE_ROW) {
525                 pkgid = (const char *)sqlite3_column_text(select_stmt, 0);
526                 if (!pkgid) {
527                     ErrPrint("Package Id is not valid\n");
528                     continue;
529                 }
530
531                 mouse_event = sqlite3_column_int(select_stmt, 1);
532
533                 ret = sqlite3_bind_int(update_stmt, 1, mouse_event);
534                 if (ret != SQLITE_OK) {
535                     ErrPrint("Failed to bind mouse_event [%s], [%d]\n", pkgid, mouse_event);
536                     sqlite3_reset(update_stmt);
537                     sqlite3_clear_bindings(update_stmt);
538                     continue;
539                 }
540
541                 ret = sqlite3_bind_text(update_stmt, 2, pkgid, -1, SQLITE_TRANSIENT);
542                 if (ret != SQLITE_OK) {
543                     ErrPrint("Failed to bind pkgid [%s], [%d]\n", pkgid, mouse_event);
544                     sqlite3_reset(update_stmt);
545                     sqlite3_clear_bindings(update_stmt);
546                     continue;
547                 }
548
549                 ret = sqlite3_step(update_stmt);
550                 if (ret != SQLITE_DONE) {
551                     ErrPrint("Failed to execute DML: %d\n", ret);
552                     sqlite3_reset(update_stmt);
553                     sqlite3_clear_bindings(update_stmt);
554                     continue;
555                 }
556
557                 sqlite3_reset(update_stmt);
558                 sqlite3_clear_bindings(update_stmt);
559             }
560
561             sqlite3_finalize(update_stmt);
562         } else {
563             ErrPrint("Failed to execute DML\n");
564         }
565
566         sqlite3_reset(select_stmt);
567         sqlite3_clear_bindings(select_stmt);
568         sqlite3_finalize(select_stmt);
569     } else {
570         ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
571     }
572
573     /*
574      * Step 3
575      * Drop a column from the client table
576      */
577     ddl = "ALTER TABLE client DROP COLUMN mouse_event";
578     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
579         ErrPrint("Failed to execute the DDL (%s)\n", err);
580         return;
581     }
582
583     if (sqlite3_changes(s_info.handle) == 0) {
584         ErrPrint("No changes to DB\n");
585     }
586
587     return;
588 }
589
590 static void do_upgrade_db_schema(void)
591 {
592     int version;
593
594     version = get_version();
595
596     switch (version) {
597         case -ENOSYS:
598             db_create_version();
599             /* Need to create version table */
600         case -ENOENT:
601             if (set_version(CUR_VER) < 0) {
602                 ErrPrint("Failed to set version\n");
603             }
604             /* Need to set version */
605         case 1:
606             upgrade_pkgmap_for_category();
607         case 2:
608             upgrade_to_version_3();
609         case 3:
610             upgrade_to_version_4();
611         case 4:
612             upgrade_to_version_5();
613         default:
614             /* Need to update version */
615             DbgPrint("Old version: %d\n", version);
616             if (update_version(CUR_VER) < 0) {
617                 ErrPrint("Failed to update version\n");
618             }
619         case CUR_VER:
620             break;
621     }
622 }
623
624 static inline int db_create_pkgmap(void)
625 {
626     char *err;
627     static const char *ddl;
628
629     ddl = "CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, uiapp TEXT, prime INTEGER, category TEXT )";
630     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
631         ErrPrint("Failed to execute the DDL (%s)\n", err);
632         return -EIO;
633     }
634
635     if (sqlite3_changes(s_info.handle) == 0) {
636         ErrPrint("No changes to DB\n");
637     }
638
639     return 0;
640 }
641
642 static inline int db_insert_pkgmap(const char *appid, const char *pkgid, const char *uiappid, int primary, const char *category)
643 {
644     int ret;
645     static const char *dml;
646     sqlite3_stmt *stmt;
647
648     dml = "INSERT INTO pkgmap ( appid, pkgid, uiapp, prime, category ) VALUES (? ,?, ?, ?, ?)";
649     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
650     if (ret != SQLITE_OK) {
651         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
652         return -EIO;
653     }
654
655     ret = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT);
656     if (ret != SQLITE_OK) {
657         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
658         ret = -EIO;
659         goto out;
660     }
661
662     ret = sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_TRANSIENT);
663     if (ret != SQLITE_OK) {
664         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
665         ret = -EIO;
666         goto out;
667     }
668
669     ret = sqlite3_bind_text(stmt, 3, uiappid, -1, SQLITE_TRANSIENT);
670     if (ret != SQLITE_OK) {
671         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
672         ret = -EIO;
673         goto out;
674     }
675
676     ret = sqlite3_bind_int(stmt, 4, primary);
677     if (ret != SQLITE_OK) {
678         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
679         ret = -EIO;
680         goto out;
681     }
682
683     ret = sqlite3_bind_text(stmt, 5, category, -1, SQLITE_TRANSIENT);
684     if (ret != SQLITE_OK) {
685         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
686         ret = -EIO;
687         goto out;
688     }
689
690     ret = 0;
691     if (sqlite3_step(stmt) != SQLITE_DONE) {
692         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
693         ret = -EIO;
694     }
695
696 out:
697     sqlite3_reset(stmt);
698     sqlite3_clear_bindings(stmt);
699     sqlite3_finalize(stmt);
700     return ret;
701 }
702
703 static inline int db_remove_pkgmap(const char *pkgid)
704 {
705     int ret;
706     static const char *dml;
707     sqlite3_stmt *stmt;
708
709     dml = "DELETE FROM pkgmap WHERE pkgid = ?";
710     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
711     if (ret != SQLITE_OK) {
712         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
713         return -EIO;
714     }
715
716     ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
717     if (ret != SQLITE_OK) {
718         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
719         ret = -EIO;
720         goto out;
721     }
722
723     ret = 0;
724     if (sqlite3_step(stmt) != SQLITE_DONE) {
725         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
726         ret = -EIO;
727     }
728
729 out:
730     sqlite3_reset(stmt);
731     sqlite3_clear_bindings(stmt);
732     sqlite3_finalize(stmt);
733     return ret;
734 }
735
736 static inline int db_create_provider(void)
737 {
738     char *err;
739     static const char *ddl;
740
741     ddl = "CREATE TABLE provider (" \
742            "pkgid TEXT PRIMARY KEY NOT NULL, network INTEGER, " \
743            "abi TEXT, secured INTEGER, box_type INTEGER, " \
744            "box_src TEXT, box_group TEXT, gbar_type INTEGER, " \
745            "gbar_src TEXT, gbar_group TEXT, libexec TEXT, timeout INTEGER, period TEXT, script TEXT, pinup INTEGER, "\
746            "count INTEGER, direct_input INTEGER DEFAULT 0, hw_acceleration TEXT DEFAULT 'none', "\
747            "FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
748
749     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
750         ErrPrint("Failed to execute the DDL (%s)\n", err);
751         return -EIO;
752     }
753
754     if (sqlite3_changes(s_info.handle) == 0) {
755         ErrPrint("No changes to DB\n");
756     }
757
758     return 0;
759 }
760
761 static inline int db_remove_provider(const char *pkgid)
762 {
763     static const char *dml;
764     int ret;
765     sqlite3_stmt *stmt;
766
767     dml = "DELETE FROM provider WHERE pkgid = ?";
768     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
769     if (ret != SQLITE_OK) {
770         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
771         return -EIO;
772     }
773
774     ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
775     if (ret != SQLITE_OK) {
776         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
777         ret = -EIO;
778         goto out;
779     }
780
781     ret = 0;
782     if (sqlite3_step(stmt) != SQLITE_DONE) {
783         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
784         ret = -EIO;
785     }
786
787 out:
788     sqlite3_reset(stmt);
789     sqlite3_clear_bindings(stmt);
790     sqlite3_finalize(stmt);
791     return ret;
792 }
793 static int db_insert_provider(struct dynamicbox *dynamicbox)
794 {
795     static const char *dml;
796     int ret;
797     sqlite3_stmt *stmt;
798     char *abi = (char *)dynamicbox->abi;
799     char *box_src = (char *)dynamicbox->dbox_src;
800     char *box_group = (char *)dynamicbox->dbox_group;
801     char *gbar_src = (char *)dynamicbox->gbar_src;
802     char *gbar_group = (char *)dynamicbox->gbar_group;
803     char *libexec = (char *)dynamicbox->libexec;
804     char *timeout = (char *)dynamicbox->timeout;
805     char *period = (char *)dynamicbox->period;
806     char *script = (char *)dynamicbox->script;
807     char *hw_acceleration = (char *)dynamicbox->hw_acceleration;
808
809     if (!abi) {
810         abi = "c";
811     }
812
813     if (!timeout) {
814         timeout = "10";
815     }
816
817     if (!period) {
818         period = "0.0";
819     }
820
821     if (!script) {
822         script = "edje";
823     }
824
825     if (!hw_acceleration) {
826         hw_acceleration = "none";
827     }
828
829     dml = "INSERT INTO provider ( pkgid, network, abi, secured, box_type, box_src, box_group, gbar_type, gbar_src, gbar_group, libexec, timeout, period, script, pinup, count, direct_input, hw_acceleration) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
830     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
831     if (ret != SQLITE_OK) {
832         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
833         return -EIO;
834     }
835
836     ret = sqlite3_bind_text(stmt, 1, (char *)dynamicbox->pkgid, -1, SQLITE_TRANSIENT);
837     if (ret != SQLITE_OK) {
838         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
839         ret = -EIO;
840         goto out;
841     }
842
843     ret = sqlite3_bind_int(stmt, 2, dynamicbox->network);
844     if (ret != SQLITE_OK) {
845         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
846         ret = -EIO;
847         goto out;
848     }
849
850     ret = sqlite3_bind_text(stmt, 3, abi, -1, SQLITE_TRANSIENT);
851     if (ret != SQLITE_OK) {
852         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
853         ret = -EIO;
854         goto out;
855     }
856     ret = sqlite3_bind_int(stmt, 4, dynamicbox->secured);
857     if (ret != SQLITE_OK) {
858         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
859         ret = -EIO;
860         goto out;
861     }
862
863     ret = sqlite3_bind_int(stmt, 5, dynamicbox->dbox_type);
864     if (ret != SQLITE_OK) {
865         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
866         ret = -EIO;
867         goto out;
868     }
869
870     ret = sqlite3_bind_text(stmt, 6, box_src, -1, SQLITE_TRANSIENT);
871     if (ret != SQLITE_OK) {
872         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
873         ret = -EIO;
874         goto out;
875     }
876
877     ret = sqlite3_bind_text(stmt, 7, box_group, -1, SQLITE_TRANSIENT);
878     if (ret != SQLITE_OK) {
879         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
880         ret = -EIO;
881         goto out;
882     }
883
884     ret = sqlite3_bind_int(stmt, 8, dynamicbox->gbar_type);
885     if (ret != SQLITE_OK) {
886         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
887         ret = -EIO;
888         goto out;
889     }
890
891     ret = sqlite3_bind_text(stmt, 9, gbar_src, -1, SQLITE_TRANSIENT);
892     if (ret != SQLITE_OK) {
893         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
894         ret = -EIO;
895         goto out;
896     }
897
898     ret = sqlite3_bind_text(stmt, 10, gbar_group, -1, SQLITE_TRANSIENT);
899     if (ret != SQLITE_OK) {
900         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
901         ret = -EIO;
902         goto out;
903     }
904
905     ret = sqlite3_bind_text(stmt, 11, libexec, -1, SQLITE_TRANSIENT);
906     if (ret != SQLITE_OK) {
907         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
908         ret = -EIO;
909         goto out;
910     }
911
912     ret = sqlite3_bind_int(stmt, 12, atoi(timeout));
913     if (ret != SQLITE_OK) {
914         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
915         ret = -EIO;
916         goto out;
917     }
918
919     ret = sqlite3_bind_text(stmt, 13, period, -1, SQLITE_TRANSIENT);
920     if (ret != SQLITE_OK) {
921         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
922         ret = -EIO;
923         goto out;
924     }
925
926     ret = sqlite3_bind_text(stmt, 14, script, -1, SQLITE_TRANSIENT);
927     if (ret != SQLITE_OK) {
928         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
929         ret = -EIO;
930         goto out;
931     }
932
933     ret = sqlite3_bind_int(stmt, 15, dynamicbox->pinup);
934     if (ret != SQLITE_OK) {
935         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
936         ret = -EIO;
937         goto out;
938     }
939
940     ret = sqlite3_bind_int(stmt, 16, dynamicbox->count);
941     if (ret != SQLITE_OK) {
942         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
943         ret = -EIO;
944         goto out;
945     }
946
947     ret = sqlite3_bind_int(stmt, 17, dynamicbox->direct_input);
948     if (ret != SQLITE_OK) {
949         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
950         ret = -EIO;
951         goto out;
952     }
953
954     ret = sqlite3_bind_text(stmt, 18, hw_acceleration, -1, SQLITE_TRANSIENT);
955     if (ret != SQLITE_OK) {
956         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
957         ret = -EIO;
958         goto out;
959     }
960
961     ret = 0;
962     if (sqlite3_step(stmt) != SQLITE_DONE) {
963         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
964         ret = -EIO;
965     }
966
967 out:
968     sqlite3_reset(stmt);
969     sqlite3_clear_bindings(stmt);
970     sqlite3_finalize(stmt);
971     return ret;
972 }
973
974 static inline int db_create_client(void)
975 {
976     char *err;
977     static const char *ddl;
978
979     ddl = "CREATE TABLE client (" \
980            "pkgid TEXT PRIMARY KEY NOT NULL, icon TEXT, name TEXT, " \
981            "auto_launch TEXT, gbar_size TEXT, content TEXT, nodisplay INTEGER, setup TEXT, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
982     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
983         ErrPrint("Failed to execute the DDL (%s)\n", err);
984         return -EIO;
985     }
986
987     if (sqlite3_changes(s_info.handle) == 0) {
988         ErrPrint("No changes to DB\n");
989     }
990
991     return 0;
992 }
993
994 static inline int db_insert_client(struct dynamicbox *dynamicbox)
995 {
996     static const char *dml;
997     int ret;
998     sqlite3_stmt *stmt;
999
1000     dml = "INSERT INTO client ( pkgid, icon, name, auto_launch, gbar_size, content, nodisplay, setup ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
1001     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1002     if (ret != SQLITE_OK) {
1003         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1004         return -EIO;
1005     }
1006
1007     ret = sqlite3_bind_text(stmt, 1, (char *)dynamicbox->pkgid, -1, SQLITE_TRANSIENT);
1008     if (ret != SQLITE_OK) {
1009         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1010         ret = -EIO;
1011         goto out;
1012     }
1013
1014     ret = sqlite3_bind_text(stmt, 2, (char *)dynamicbox->icon, -1, SQLITE_TRANSIENT);
1015     if (ret != SQLITE_OK) {
1016         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1017         ret = -EIO;
1018         goto out;
1019     }
1020
1021     ret = sqlite3_bind_text(stmt, 3, (char *)dynamicbox->name, -1, SQLITE_TRANSIENT);
1022     if (ret != SQLITE_OK) {
1023         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1024         ret = -EIO;
1025         goto out;
1026     }
1027
1028     ret = sqlite3_bind_text(stmt, 4, (char *)dynamicbox->auto_launch, -1, SQLITE_TRANSIENT);
1029     if (ret != SQLITE_OK) {
1030         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1031         ret = -EIO;
1032         goto out;
1033     }
1034
1035     ret = sqlite3_bind_text(stmt, 5, (char *)dynamicbox->gbar_size, -1, SQLITE_TRANSIENT);
1036     if (ret != SQLITE_OK) {
1037         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1038         ret = -EIO;
1039         goto out;
1040     }
1041
1042     ret = sqlite3_bind_text(stmt, 6, (char *)dynamicbox->content, -1, SQLITE_TRANSIENT);
1043     if (ret != SQLITE_OK) {
1044         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1045         ret = -EIO;
1046         goto out;
1047     }
1048
1049     ret = sqlite3_bind_int(stmt, 7, dynamicbox->nodisplay);
1050     if (ret != SQLITE_OK) {
1051         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1052         ret = -EIO;
1053         goto out;
1054     }
1055
1056     ret = sqlite3_bind_text(stmt, 8, (char *)dynamicbox->setup, -1, SQLITE_TRANSIENT);
1057     if (ret != SQLITE_OK) {
1058         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1059         ret = -EIO;
1060         goto out;
1061     }
1062
1063     ret = 0;
1064     if (sqlite3_step(stmt) != SQLITE_DONE) {
1065         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1066         ret = -EIO;
1067     }
1068
1069 out:
1070     sqlite3_reset(stmt);
1071     sqlite3_clear_bindings(stmt);
1072     sqlite3_finalize(stmt);
1073     return ret;
1074 }
1075
1076 static inline int db_remove_client(const char *pkgid)
1077 {
1078     static const char *dml;
1079     int ret;
1080     sqlite3_stmt *stmt;
1081
1082     dml = "DELETE FROM client WHERE pkgid = ?";
1083     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1084     if (ret != SQLITE_OK) {
1085         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1086         return -EIO;
1087     }
1088
1089     ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1090     if (ret != SQLITE_OK) {
1091         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1092         ret = -EIO;
1093         goto out;
1094     }
1095
1096     ret = 0;
1097     if (sqlite3_step(stmt) != SQLITE_DONE) {
1098         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1099         ret = -EIO;
1100     }
1101
1102 out:
1103     sqlite3_reset(stmt);
1104     sqlite3_clear_bindings(stmt);
1105     sqlite3_finalize(stmt);
1106     return ret;
1107 }
1108
1109 static inline int db_create_i18n(void)
1110 {
1111     char *err;
1112     static const char *ddl;
1113
1114     ddl = "CREATE TABLE i18n ( pkgid TEXT NOT NULL, lang TEXT COLLATE NOCASE, name TEXT, " \
1115            "icon TEXT, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
1116     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
1117         ErrPrint("Failed to execute the DDL (%s)\n", err);
1118         return -EIO;
1119     }
1120
1121     if (sqlite3_changes(s_info.handle) == 0) {
1122         ErrPrint("No changes to DB\n");
1123     }
1124
1125     return 0;
1126 }
1127
1128 static inline int db_insert_i18n(const char *pkgid, const char *lang, const char *name, const char *icon)
1129 {
1130     static const char *dml;
1131     int ret;
1132     sqlite3_stmt *stmt;
1133
1134     DbgPrint("%s - lang[%s] name[%s] icon[%s]\n", pkgid, lang, name, icon);
1135     dml = "INSERT INTO i18n ( pkgid, lang, name, icon ) VALUES (?, ?, ?, ?)";
1136     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1137     if (ret != SQLITE_OK) {
1138         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1139         return -EIO;
1140     }
1141
1142     ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1143     if (ret != SQLITE_OK) {
1144         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1145         ret = -EIO;
1146         goto out;
1147     }
1148
1149     ret = sqlite3_bind_text(stmt, 2, lang, -1, SQLITE_TRANSIENT);
1150     if (ret != SQLITE_OK) {
1151         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1152         ret = -EIO;
1153         goto out;
1154     }
1155
1156     ret = sqlite3_bind_text(stmt, 3, name, -1, SQLITE_TRANSIENT);
1157     if (ret != SQLITE_OK) {
1158         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1159         ret = -EIO;
1160         goto out;
1161     }
1162
1163     ret = sqlite3_bind_text(stmt, 4, icon, -1, SQLITE_TRANSIENT);
1164     if (ret != SQLITE_OK) {
1165         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1166         ret = -EIO;
1167         goto out;
1168     }
1169
1170     ret = 0;
1171     if (sqlite3_step(stmt) != SQLITE_DONE) {
1172         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1173         ret = -EIO;
1174     }
1175
1176 out:
1177     sqlite3_reset(stmt);
1178     sqlite3_clear_bindings(stmt);
1179     sqlite3_finalize(stmt);
1180     return ret;
1181 }
1182
1183 static inline int db_remove_i18n(const char *pkgid)
1184 {
1185     static const char *dml;
1186     int ret;
1187     sqlite3_stmt *stmt;
1188
1189     dml = "DELETE FROM i18n WHERE pkgid = ?";
1190     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1191     if (ret != SQLITE_OK) {
1192         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1193         return -EIO;
1194     }
1195
1196     ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1197     if (ret != SQLITE_OK) {
1198         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1199         ret = -EIO;
1200         goto out;
1201     }
1202
1203     ret = 0;
1204     if (sqlite3_step(stmt) != SQLITE_DONE) {
1205         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1206         ret = -EIO;
1207     }
1208
1209     if (sqlite3_changes(s_info.handle) == 0) {
1210         DbgPrint("No changes\n");
1211     }
1212
1213 out:
1214     sqlite3_reset(stmt);
1215     sqlite3_clear_bindings(stmt);
1216     sqlite3_finalize(stmt);
1217     return ret;
1218 }
1219
1220 static inline int db_create_group(void)
1221 {
1222     char *err;
1223     static const char *ddl;
1224
1225     ddl = "CREATE TABLE groupinfo ( id INTEGER PRIMARY KEY AUTOINCREMENT, cluster TEXT NOT NULL, category TEXT NOT NULL, pkgid TEXT NOT NULL, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
1226     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
1227         ErrPrint("Failed to execute the DDL (%s)\n", err);
1228         return -EIO;
1229     }
1230
1231     if (sqlite3_changes(s_info.handle) == 0) {
1232         ErrPrint("No changes to DB\n");
1233     }
1234
1235     return 0;
1236 }
1237
1238 static inline int db_insert_group(const char *pkgid, const char *cluster, const char *category)
1239 {
1240     static const char *dml;
1241     int ret;
1242     sqlite3_stmt *stmt;
1243
1244     dml = "INSERT INTO groupinfo ( cluster, category, pkgid ) VALUES (?, ?, ?)";
1245     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1246     if (ret != SQLITE_OK) {
1247         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1248         return -EIO;
1249     }
1250
1251     ret = sqlite3_bind_text(stmt, 1, cluster, -1, SQLITE_TRANSIENT);
1252     if (ret != SQLITE_OK) {
1253         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1254         ret = -EIO;
1255         goto out;
1256     }
1257
1258     ret = sqlite3_bind_text(stmt, 2, category, -1, SQLITE_TRANSIENT);
1259     if (ret != SQLITE_OK) {
1260         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1261         ret = -EIO;
1262         goto out;
1263     }
1264
1265     ret = sqlite3_bind_text(stmt, 3, pkgid, -1, SQLITE_TRANSIENT);
1266     if (ret != SQLITE_OK) {
1267         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1268         ret = -EIO;
1269         goto out;
1270     }
1271
1272     ret = 0;
1273     if (sqlite3_step(stmt) != SQLITE_DONE) {
1274         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1275         ret = -EIO;
1276     }
1277
1278 out:
1279     sqlite3_reset(stmt);
1280     sqlite3_clear_bindings(stmt);
1281     sqlite3_finalize(stmt);
1282     return ret;
1283 }
1284
1285 static int db_get_group_id(const char *cluster, const char *category)
1286 {
1287     static const char *dml = "SELECT id FROM groupinfo WHERE cluster = ? AND category = ?";
1288     sqlite3_stmt *stmt;
1289     int ret;
1290
1291     if (!cluster || !category) {
1292         ErrPrint("Invalid argument\n");
1293         return -EINVAL;
1294     }
1295
1296     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1297     if (ret != SQLITE_OK) {
1298         ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
1299         return -EIO;
1300     }
1301
1302     ret = -EIO;
1303     if (sqlite3_bind_text(stmt, 1, cluster, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
1304         ErrPrint("Failed to bind a cluster(%s) - %s\n", cluster, sqlite3_errmsg(s_info.handle));
1305         goto out;
1306     }
1307
1308     if (sqlite3_bind_text(stmt, 2, category, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
1309         ErrPrint("Failed to bind a category(%s) - %s\n", category, sqlite3_errmsg(s_info.handle));
1310         goto out;
1311     }
1312
1313     if (sqlite3_step(stmt) != SQLITE_ROW) {
1314         ErrPrint("Failed to execute the DML for %s - %s\n", cluster, category);
1315         goto out;
1316     }
1317
1318     ret = sqlite3_column_int(stmt, 0);
1319
1320 out:
1321     sqlite3_reset(stmt);
1322     sqlite3_clear_bindings(stmt);
1323     sqlite3_finalize(stmt);
1324     return ret;
1325 }
1326
1327 static inline int db_remove_group(const char *pkgid)
1328 {
1329     static const char *dml;
1330     int ret;
1331     sqlite3_stmt *stmt;
1332
1333     dml = "DELETE FROM groupinfo WHERE pkgid = ?";
1334     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1335     if (ret != SQLITE_OK) {
1336         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1337         return -EIO;
1338     }
1339
1340     ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1341     if (ret != SQLITE_OK) {
1342         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1343         ret = -EIO;
1344         goto out;
1345     }
1346
1347     ret = 0;
1348     if (sqlite3_step(stmt) != SQLITE_DONE) {
1349         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1350         ret = -EIO;
1351     }
1352
1353     if (sqlite3_changes(s_info.handle) == 0) {
1354         DbgPrint("No changes\n");
1355     }
1356
1357 out:
1358     sqlite3_reset(stmt);
1359     sqlite3_clear_bindings(stmt);
1360     sqlite3_finalize(stmt);
1361     return ret;
1362 }
1363
1364 static inline int db_create_groupmap(void)
1365 {
1366     char *err;
1367     static const char *ddl;
1368
1369     ddl = "CREATE TABLE groupmap (option_id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER, pkgid TEXT NOT NULL, ctx_item TEXT NOT NULL, FOREIGN KEY(id) REFERENCES groupinfo(id), FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
1370     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
1371         ErrPrint("Failed to execute the DDL (%s)\n", err);
1372         return -EIO;
1373     }
1374
1375     if (sqlite3_changes(s_info.handle) == 0) {
1376         ErrPrint("No changes to DB\n");
1377     }
1378
1379     return 0;
1380 }
1381
1382 static inline int db_get_option_id(int id, const char *pkgid, const char *ctx_item)
1383 {
1384     static const char *dml;
1385     int ret;
1386     sqlite3_stmt *stmt;
1387
1388     dml = "SELECT option_id FROM groupmap WHERE id = ? AND pkgid = ? AND ctx_item = ?";
1389     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1390     if (ret != SQLITE_OK) {
1391         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1392         return -EIO;
1393     }
1394
1395     ret = sqlite3_bind_int(stmt, 1, id);
1396     if (ret != SQLITE_OK) {
1397         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1398         ret = -EIO;
1399         goto out;
1400     }
1401
1402     ret = sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_TRANSIENT);
1403     if (ret != SQLITE_OK) {
1404         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1405         ret = -EIO;
1406         goto out;
1407     }
1408
1409     ret = sqlite3_bind_text(stmt, 3, ctx_item, -1, SQLITE_TRANSIENT);
1410     if (ret != SQLITE_OK) {
1411         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1412         ret = -EIO;
1413         goto out;
1414     }
1415
1416     ret = 0;
1417     if (sqlite3_step(stmt) != SQLITE_ROW) {
1418         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1419         ret = -EIO;
1420         goto out;
1421     }
1422
1423     ret = sqlite3_column_int(stmt, 0);
1424
1425 out:
1426     sqlite3_reset(stmt);
1427     sqlite3_clear_bindings(stmt);
1428     sqlite3_finalize(stmt);
1429     return ret;
1430 }
1431
1432 static inline int db_insert_groupmap(int id, const char *pkgid, const char *ctx_item)
1433 {
1434     static const char *dml;
1435     int ret;
1436     sqlite3_stmt *stmt;
1437
1438     DbgPrint("%d (%s) add to groupmap\n", id, pkgid);
1439
1440     dml = "INSERT INTO groupmap ( id, pkgid, ctx_item ) VALUES (?, ?, ?)";
1441     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1442     if (ret != SQLITE_OK) {
1443         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1444         return -EIO;
1445     }
1446
1447     ret = sqlite3_bind_int(stmt, 1, id);
1448     if (ret != SQLITE_OK) {
1449         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1450         ret = -EIO;
1451         goto out;
1452     }
1453
1454     ret = sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_TRANSIENT);
1455     if (ret != SQLITE_OK) {
1456         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1457         ret = -EIO;
1458         goto out;
1459     }
1460
1461     ret = sqlite3_bind_text(stmt, 3, ctx_item, -1, SQLITE_TRANSIENT);
1462     if (ret != SQLITE_OK) {
1463         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1464         ret = -EIO;
1465         goto out;
1466     }
1467
1468     ret = 0;
1469     if (sqlite3_step(stmt) != SQLITE_DONE) {
1470         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1471         ret = -EIO;
1472     }
1473
1474 out:
1475     sqlite3_reset(stmt);
1476     sqlite3_clear_bindings(stmt);
1477     sqlite3_finalize(stmt);
1478     return ret;
1479 }
1480
1481 static inline int db_remove_groupmap(const char *pkgid)
1482 {
1483     static const char *dml;
1484     int ret;
1485     sqlite3_stmt *stmt;
1486
1487     dml = "DELETE FROM groupmap WHERE pkgid = ?";
1488     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1489     if (ret != SQLITE_OK) {
1490         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1491         return -EIO;
1492     }
1493
1494     ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1495     if (ret != SQLITE_OK) {
1496         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1497         ret = -EIO;
1498         goto out;
1499     }
1500
1501     ret = 0;
1502     if (sqlite3_step(stmt) != SQLITE_DONE) {
1503         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1504         ret = -EIO;
1505     }
1506
1507     if (sqlite3_changes(s_info.handle) == 0) {
1508         DbgPrint("No changes\n");
1509     }
1510
1511 out:
1512     sqlite3_reset(stmt);
1513     sqlite3_clear_bindings(stmt);
1514     sqlite3_finalize(stmt);
1515     return ret;
1516 }
1517
1518 static inline int db_create_option(void)
1519 {
1520     char *err;
1521     static const char *ddl;
1522
1523     ddl = "CREATE TABLE option ( pkgid TEXT NOT NULL, option_id INTEGER, key TEXT NOT NULL, value TEXT NOT NULL, " \
1524            "FOREIGN KEY(option_id) REFERENCES groupmap(option_id), " \
1525            "FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
1526     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
1527         ErrPrint("Failed to execute the DDL (%s)\n", err);
1528         return -EIO;
1529     }
1530
1531     if (sqlite3_changes(s_info.handle) == 0) {
1532         ErrPrint("No changes to DB\n");
1533     }
1534
1535     return 0;
1536 }
1537
1538 static inline int db_insert_option(const char *pkgid, int option_id, const char *key, const char *value)
1539 {
1540     static const char *dml;
1541     int ret;
1542     sqlite3_stmt *stmt;
1543
1544     dml = "INSERT INTO option (pkgid, option_id, key, value) VALUES (?, ?, ?, ?)";
1545     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1546     if (ret != SQLITE_OK) {
1547         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1548         return -EIO;
1549     }
1550
1551     ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1552     if (ret != SQLITE_OK) {
1553         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1554         ret = -EIO;
1555         goto out;
1556     }
1557
1558     ret = sqlite3_bind_int(stmt, 2, option_id);
1559     if (ret != SQLITE_OK) {
1560         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1561         ret = -EIO;
1562         goto out;
1563     }
1564
1565     ret = sqlite3_bind_text(stmt, 3, key, -1, SQLITE_TRANSIENT);
1566     if (ret != SQLITE_OK) {
1567         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1568         ret = -EIO;
1569         goto out;
1570     }
1571
1572     ret = sqlite3_bind_text(stmt, 4, value, -1, SQLITE_TRANSIENT);
1573     if (ret != SQLITE_OK) {
1574         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1575         ret = -EIO;
1576         goto out;
1577     }
1578
1579     ret = 0;
1580     if (sqlite3_step(stmt) != SQLITE_DONE) {
1581         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1582         ret = -EIO;
1583     }
1584 out:
1585     sqlite3_reset(stmt);
1586     sqlite3_clear_bindings(stmt);
1587     sqlite3_finalize(stmt);
1588     return ret;
1589 }
1590
1591 static inline int db_remove_option(const char *pkgid)
1592 {
1593     static const char *dml;
1594     int ret;
1595     sqlite3_stmt *stmt;
1596
1597     dml = "DELETE FROM option WHERE pkgid = ?";
1598     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1599     if (ret != SQLITE_OK) {
1600         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1601         return -EIO;
1602     }
1603
1604     ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1605     if (ret != SQLITE_OK) {
1606         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1607         ret = -EIO;
1608         goto out;
1609     }
1610
1611     ret = 0;
1612     if (sqlite3_step(stmt) != SQLITE_DONE) {
1613         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1614         ret = -EIO;
1615     }
1616
1617     if (sqlite3_changes(s_info.handle) == 0) {
1618         DbgPrint("No changes\n");
1619     }
1620
1621 out:
1622     sqlite3_reset(stmt);
1623     sqlite3_clear_bindings(stmt);
1624     sqlite3_finalize(stmt);
1625     return ret;
1626 }
1627
1628 static inline int db_create_box_size(void)
1629 {
1630     char *err;
1631     static const char *ddl;
1632
1633     ddl = "CREATE TABLE box_size ( pkgid TEXT NOT NULL, size_type INTEGER, preview TEXT, touch_effect INTEGER, need_frame INTEGER, mouse_event INTEGER " \
1634            "FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
1635     if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
1636         ErrPrint("Failed to execute the DDL (%s)\n", err);
1637         return -EIO;
1638     }
1639
1640     if (sqlite3_changes(s_info.handle) == 0) {
1641         ErrPrint("No changes to DB\n");
1642     }
1643
1644     return 0;
1645 }
1646
1647 static int db_insert_box_size(const char *pkgid, int size_type, const char *preview, int touch_effect, int need_frame, int mouse_event)
1648 {
1649     static const char *dml;
1650     int ret;
1651     sqlite3_stmt *stmt;
1652
1653     DbgPrint("box size: %s - %d (%s) is added\n", pkgid, size_type, preview);
1654     dml = "INSERT INTO box_size ( pkgid, size_type, preview, touch_effect, need_frame, mouse_event ) VALUES (?, ?, ?, ?, ?, ?)";
1655     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1656     if (ret != SQLITE_OK) {
1657         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1658         return -EIO;
1659     }
1660
1661     ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1662     if (ret != SQLITE_OK) {
1663         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1664         ret = -EIO;
1665         goto out;
1666     }
1667
1668     ret = sqlite3_bind_int(stmt, 2, size_type);
1669     if (ret != SQLITE_OK) {
1670         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1671         ret = -EIO;
1672         goto out;
1673     }
1674
1675     ret = sqlite3_bind_text(stmt, 3, preview, -1, SQLITE_TRANSIENT);
1676     if (ret != SQLITE_OK) {
1677         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1678         ret = -EIO;
1679         goto out;
1680     }
1681
1682     ret = sqlite3_bind_int(stmt, 4, touch_effect);
1683     if (ret != SQLITE_OK) {
1684         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1685         ret = -EIO;
1686         goto out;
1687     }
1688
1689     ret = sqlite3_bind_int(stmt, 5, need_frame);
1690     if (ret != SQLITE_OK) {
1691         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1692         ret = -EIO;
1693         goto out;
1694     }
1695
1696     ret = sqlite3_bind_int(stmt, 6, mouse_event);
1697     if (ret != SQLITE_OK) {
1698         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1699         ret = -EIO;
1700         goto out;
1701     }
1702
1703     ret = 0;
1704     if (sqlite3_step(stmt) != SQLITE_DONE) {
1705         ErrPrintWithConsole("Error: %s\n", sqlite3_errmsg(s_info.handle));
1706         ret = -EIO;
1707     }
1708
1709 out:
1710     sqlite3_reset(stmt);
1711     sqlite3_clear_bindings(stmt);
1712     sqlite3_finalize(stmt);
1713     return ret;
1714 }
1715
1716 static inline int db_remove_box_size(const char *pkgid)
1717 {
1718     static const char *dml;
1719     int ret;
1720     sqlite3_stmt *stmt;
1721
1722     dml = "DELETE FROM box_size WHERE pkgid = ?";
1723     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1724     if (ret != SQLITE_OK) {
1725         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1726         return -EIO;
1727     }
1728
1729     ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1730     if (ret != SQLITE_OK) {
1731         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1732         ret = -EIO;
1733         goto out;
1734     }
1735
1736     ret = 0;
1737     if (sqlite3_step(stmt) != SQLITE_DONE) {
1738         DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1739         ret = -EIO;
1740     }
1741
1742     if (sqlite3_changes(s_info.handle) == 0) {
1743         DbgPrint("No changes\n");
1744     }
1745
1746 out:
1747     sqlite3_reset(stmt);
1748     sqlite3_clear_bindings(stmt);
1749     sqlite3_finalize(stmt);
1750     return ret;
1751 }
1752
1753 static inline void db_create_table(void)
1754 {
1755     int ret;
1756     begin_transaction();
1757
1758     ret = db_create_pkgmap();
1759     if (ret < 0) {
1760         rollback_transaction();
1761         return;
1762     }
1763
1764     ret = db_create_provider();
1765     if (ret < 0) {
1766         rollback_transaction();
1767         return;
1768     }
1769
1770     ret = db_create_client();
1771     if (ret < 0) {
1772         rollback_transaction();
1773         return;
1774     }
1775
1776     ret = db_create_i18n();
1777     if (ret < 0) {
1778         rollback_transaction();
1779         return;
1780     }
1781
1782     ret = db_create_box_size();
1783     if (ret < 0) {
1784         rollback_transaction();
1785         return;
1786     }
1787
1788     ret = db_create_group();
1789     if (ret < 0) {
1790         rollback_transaction();
1791         return;
1792     }
1793
1794     ret = db_create_option();
1795     if (ret < 0) {
1796         rollback_transaction();
1797         return;
1798     }
1799
1800     ret = db_create_groupmap();
1801     if (ret < 0) {
1802         rollback_transaction();
1803         return;
1804     }
1805
1806     commit_transaction();
1807 }
1808
1809 static int db_init(void)
1810 {
1811     int ret;
1812     struct stat stat;
1813
1814     ret = db_util_open(s_info.dbfile, &s_info.handle, DB_UTIL_REGISTER_HOOK_METHOD);
1815     if (ret != SQLITE_OK) {
1816         ErrPrint("Failed to open a DB\n");
1817         return -EIO;
1818     }
1819
1820     if (lstat(s_info.dbfile, &stat) < 0) {
1821         ErrPrint("%s\n", strerror(errno));
1822         db_util_close(s_info.handle);
1823         s_info.handle = NULL;
1824         return -EIO;
1825     }
1826
1827     if (!S_ISREG(stat.st_mode)) {
1828         ErrPrint("Invalid file\n");
1829         db_util_close(s_info.handle);
1830         s_info.handle = NULL;
1831         return -EINVAL;
1832     }
1833
1834     if (!stat.st_size) {
1835         db_create_table();
1836     }
1837
1838     return 0;
1839 }
1840
1841 static inline int db_fini(void)
1842 {
1843     if (!s_info.handle) {
1844         return 0;
1845     }
1846
1847     db_util_close(s_info.handle);
1848     s_info.handle = NULL;
1849
1850     return 0;
1851 }
1852
1853 static inline int validate_pkgid(const char *appid, const char *pkgid)
1854 {
1855     /* Just return 1 Always */
1856     return 1 || !strncmp(appid, pkgid, strlen(appid));
1857 }
1858
1859 static int dynamicbox_destroy(struct dynamicbox *dynamicbox)
1860 {
1861     struct dlist *l;
1862     struct dlist *n;
1863     struct i18n *i18n;
1864     struct group *group;
1865     struct option *option;
1866     struct dlist *il;
1867     struct dlist *in;
1868
1869     xmlFree(dynamicbox->auto_launch);
1870     xmlFree(dynamicbox->pkgid);
1871     xmlFree(dynamicbox->abi);
1872     xmlFree(dynamicbox->name);
1873     xmlFree(dynamicbox->icon);
1874     xmlFree(dynamicbox->dbox_src);
1875     xmlFree(dynamicbox->dbox_group);
1876     xmlFree(dynamicbox->gbar_src);
1877     xmlFree(dynamicbox->gbar_group);
1878     xmlFree(dynamicbox->gbar_size);
1879     xmlFree(dynamicbox->libexec);
1880     xmlFree(dynamicbox->script);
1881     xmlFree(dynamicbox->period);
1882     xmlFree(dynamicbox->content);
1883     xmlFree(dynamicbox->setup);
1884     xmlFree(dynamicbox->category);
1885     xmlFree(dynamicbox->preview[0]); /* 1x1 */
1886     xmlFree(dynamicbox->preview[1]); /* 2x1 */
1887     xmlFree(dynamicbox->preview[2]); /* 2x2 */
1888     xmlFree(dynamicbox->preview[3]); /* 4x1 */
1889     xmlFree(dynamicbox->preview[4]); /* 4x2 */
1890     xmlFree(dynamicbox->preview[5]); /* 4x3 */
1891     xmlFree(dynamicbox->preview[6]); /* 4x4 */
1892     xmlFree(dynamicbox->preview[7]); /* 4x5 */
1893     xmlFree(dynamicbox->preview[8]); /* 4x6 */
1894     xmlFree(dynamicbox->preview[9]); /* easy 1x1 */
1895     xmlFree(dynamicbox->preview[10]); /* easy 3x1 */
1896     xmlFree(dynamicbox->preview[11]); /* easy 3x3 */
1897     xmlFree(dynamicbox->preview[12]); /* full */
1898     xmlFree(dynamicbox->hw_acceleration);
1899
1900     dlist_foreach_safe(dynamicbox->i18n_list, l, n, i18n) {
1901         dynamicbox->i18n_list = dlist_remove(dynamicbox->i18n_list, l);
1902         xmlFree(i18n->name);
1903         xmlFree(i18n->icon);
1904         xmlFree(i18n->lang);
1905         free(i18n);
1906     }
1907
1908     dlist_foreach_safe(dynamicbox->group_list, l, n, group) {
1909         dynamicbox->group_list = dlist_remove(dynamicbox->group_list, l);
1910         DbgPrint("Release %s/%s\n", group->cluster, group->category);
1911
1912         if (group->ctx_item) {
1913             dlist_foreach_safe(group->option_list, il, in, option) {
1914                 group->option_list = dlist_remove(group->option_list, il);
1915                 DbgPrint("Release option %s(%s)\n", option->key, option->value);
1916                 xmlFree(option->key);
1917                 xmlFree(option->value);
1918                 free(option);
1919             }
1920             xmlFree(group->ctx_item);
1921         }
1922
1923         xmlFree(group->cluster);
1924         xmlFree(group->category);
1925         free(group);
1926     }
1927
1928     free(dynamicbox);
1929     return 0;
1930 }
1931
1932 static inline void update_i18n_name(struct dynamicbox *dynamicbox, xmlNodePtr node)
1933 {
1934     struct i18n *i18n;
1935     struct dlist *l;
1936     xmlChar *lang;
1937     xmlChar *name;
1938
1939     name = xmlNodeGetContent(node);
1940     if (!name) {
1941         ErrPrint("Invalid tag\n");
1942         return;
1943     }
1944
1945     lang = xmlNodeGetLang(node);
1946     if (!lang) {
1947         if (dynamicbox->name) {
1948             DbgPrint("Override default name: %s\n", dynamicbox->name);
1949             xmlFree(dynamicbox->name);
1950         }
1951
1952         dynamicbox->name = name;
1953         return;
1954     }
1955
1956     dlist_foreach(dynamicbox->i18n_list, l, i18n) {
1957         if (!xmlStrcasecmp(i18n->lang, lang)) {
1958             if (i18n->name) {
1959                 DbgPrint("Override name: %s\n", i18n->name);
1960                 xmlFree(i18n->name);
1961             }
1962
1963             i18n->name = name;
1964             return;
1965         }
1966     }
1967
1968     i18n = calloc(1, sizeof(*i18n));
1969     if (!i18n) {
1970         ErrPrint("Heap: %s\n", strerror(errno));
1971         xmlFree(name);
1972         xmlFree(lang);
1973         return;
1974     }
1975
1976     i18n->name = name;
1977     i18n->lang = lang;
1978     DbgPrint("Label[%s] - [%s] added\n", i18n->lang, i18n->name);
1979     dynamicbox->i18n_list = dlist_append(dynamicbox->i18n_list, i18n);
1980 }
1981
1982 static inline void update_i18n_icon(struct dynamicbox *dynamicbox, xmlNodePtr node)
1983 {
1984     struct i18n *i18n;
1985     struct dlist *l;
1986     xmlChar *lang;
1987     xmlChar *icon;
1988
1989     icon = xmlNodeGetContent(node);
1990     if (!icon) {
1991         ErrPrint("Invalid tag\n");
1992         return;
1993     }
1994
1995     lang = xmlNodeGetLang(node);
1996     if (!lang) {
1997         if (dynamicbox->icon) {
1998             DbgPrint("Override default icon: %s\n", dynamicbox->icon);
1999             xmlFree(dynamicbox->icon);
2000         }
2001
2002         dynamicbox->icon = icon;
2003         return;
2004     }
2005
2006     dlist_foreach(dynamicbox->i18n_list, l, i18n) {
2007         if (!xmlStrcasecmp(i18n->lang, lang)) {
2008             if (i18n->icon) {
2009                 DbgPrint("Override icon %s for %s\n", i18n->icon, i18n->name);
2010                 xmlFree(i18n->icon);
2011             }
2012
2013             i18n->icon = icon;
2014             return;
2015         }
2016     }
2017
2018     i18n = calloc(1, sizeof(*i18n));
2019     if (!i18n) {
2020         ErrPrint("Heap: %s\n", strerror(errno));
2021         xmlFree(icon);
2022         xmlFree(lang);
2023         return;
2024     }
2025
2026     i18n->icon = icon;
2027     i18n->lang = lang;
2028     DbgPrint("Icon[%s] - [%s] added\n", i18n->lang, i18n->icon);
2029     dynamicbox->i18n_list = dlist_append(dynamicbox->i18n_list, i18n);
2030 }
2031
2032 static inline void update_launch(struct dynamicbox *dynamicbox, xmlNodePtr node)
2033 {
2034     xmlChar *launch;
2035
2036     launch = xmlNodeGetContent(node);
2037     if (!launch) {
2038         DbgPrint("Has no launch\n");
2039         return;
2040     }
2041
2042     if (dynamicbox->auto_launch) {
2043         xmlFree(dynamicbox->auto_launch);
2044     }
2045
2046     dynamicbox->auto_launch = xmlStrdup(launch);
2047     if (!dynamicbox->auto_launch) {
2048         ErrPrint("Failed to duplicate string: %s\n", (char *)launch);
2049         return;
2050     }
2051 }
2052
2053 static inline void update_category(struct dynamicbox *dynamicbox, xmlNodePtr node)
2054 {
2055     xmlChar *category;
2056
2057     category = xmlGetProp(node, (const xmlChar *)"name");
2058     if (!category) {
2059         DbgPrint("Has no valid category\n");
2060         return;
2061     }
2062
2063     if (dynamicbox->category) {
2064         xmlFree(dynamicbox->category);
2065     }
2066
2067     dynamicbox->category = xmlStrdup(category);
2068     if (!dynamicbox->category) {
2069         ErrPrint("Failed to duplicate string: %s\n", (char *)category);
2070         return;
2071     }
2072 }
2073
2074 static inline void update_ui_appid(struct dynamicbox *dynamicbox, xmlNodePtr node)
2075 {
2076     xmlChar *uiapp;
2077     uiapp = xmlNodeGetContent(node);
2078     if (!uiapp) {
2079         DbgPrint("Has no valid ui-appid\n");
2080         return;
2081     }
2082
2083     if (dynamicbox->uiapp) {
2084         xmlFree(dynamicbox->uiapp);
2085     }
2086
2087     dynamicbox->uiapp = xmlStrdup(uiapp);
2088     if (!dynamicbox->uiapp) {
2089         ErrPrint("Failed to duplicate string: %s\n", (char *)uiapp);
2090         return;
2091     }
2092 }
2093
2094 static inline void update_setup(struct dynamicbox *dynamicbox, xmlNodePtr node)
2095 {
2096     xmlChar *setup;
2097     setup = xmlNodeGetContent(node);
2098     if (!setup) {
2099         DbgPrint("Has no setup\n");
2100         return;
2101     }
2102
2103     if (dynamicbox->setup) {
2104         xmlFree(dynamicbox->setup);
2105     }
2106
2107     dynamicbox->setup = xmlStrdup(setup);
2108     if (!dynamicbox->setup) {
2109         ErrPrint("Failed to duplicate string: %s\n", (char *)setup);
2110         return;
2111     }
2112 }
2113
2114 static inline void update_content(struct dynamicbox *dynamicbox, xmlNodePtr node)
2115 {
2116     xmlChar *content;
2117     content = xmlNodeGetContent(node);
2118     if (!content) {
2119         DbgPrint("Has no content\n");
2120         return;
2121     }
2122
2123     if (dynamicbox->content) {
2124         xmlFree(dynamicbox->content);
2125     }
2126
2127     dynamicbox->content = xmlStrdup(content);
2128     if (!dynamicbox->content) {
2129         ErrPrint("Failed to duplicate string: %s\n", (char *)content);
2130         return;
2131     }
2132 }
2133
2134 static void update_size_info(struct dynamicbox *dynamicbox, int idx, xmlNodePtr node)
2135 {
2136     if (xmlHasProp(node, (const xmlChar *)"preview")) {
2137         dynamicbox->preview[idx] = xmlGetProp(node, (const xmlChar *)"preview");
2138     }
2139
2140     if (xmlHasProp(node, (const xmlChar *)"need_frame")) {
2141         xmlChar *need_frame;
2142
2143         need_frame = xmlGetProp(node, (const xmlChar *)"need_frame");
2144         if (need_frame) {
2145             dynamicbox->need_frame[idx] = !xmlStrcasecmp(need_frame, (const xmlChar *)"true");
2146             xmlFree(need_frame);
2147         } else {
2148             dynamicbox->need_frame[idx] = dynamicbox->default_need_frame;
2149         }
2150     } else {
2151         dynamicbox->need_frame[idx] = dynamicbox->default_need_frame;
2152     }
2153
2154     if (xmlHasProp(node, (const xmlChar *)"touch_effect")) {
2155         xmlChar *touch_effect;
2156
2157         touch_effect = xmlGetProp(node, (const xmlChar *)"touch_effect");
2158         if (touch_effect) {
2159             dynamicbox->touch_effect[idx] = !xmlStrcasecmp(touch_effect, (const xmlChar *)"true");
2160             xmlFree(touch_effect);
2161         } else {
2162             dynamicbox->touch_effect[idx] = dynamicbox->default_touch_effect;
2163         }
2164     } else {
2165         dynamicbox->touch_effect[idx] = dynamicbox->default_touch_effect;
2166     }
2167
2168     if (xmlHasProp(node, (const xmlChar *)"mouse_event")) {
2169         xmlChar *mouse_event;
2170
2171         mouse_event = xmlGetProp(node, (const xmlChar *)"mouse_event");
2172         if (mouse_event) {
2173             dynamicbox->mouse_event[idx] = !xmlStrcasecmp(mouse_event, (const xmlChar *)"true");
2174             xmlFree(mouse_event);
2175         } else {
2176             dynamicbox->mouse_event[idx] = dynamicbox->default_mouse_event;
2177         }
2178     } else {
2179         dynamicbox->mouse_event[idx] = dynamicbox->default_mouse_event;
2180     }
2181 }
2182
2183 static void update_box(struct dynamicbox *dynamicbox, xmlNodePtr node)
2184 {
2185     if (!xmlHasProp(node, (const xmlChar *)"type")) {
2186         dynamicbox->dbox_type = DBOX_TYPE_FILE;
2187     } else {
2188         xmlChar *type;
2189
2190         type = xmlGetProp(node, (const xmlChar *)"type");
2191         if (!type) {
2192             ErrPrint("Type is NIL\n");
2193             dynamicbox->dbox_type = DBOX_TYPE_FILE;
2194         } else {
2195             if (!xmlStrcasecmp(type, (const xmlChar *)"text")) {
2196                 dynamicbox->dbox_type = DBOX_TYPE_TEXT;
2197             } else if (!xmlStrcasecmp(type, (const xmlChar *)"buffer")) {
2198                 dynamicbox->dbox_type = DBOX_TYPE_BUFFER;
2199             } else if (!xmlStrcasecmp(type, (const xmlChar *)"script")) {
2200                 dynamicbox->dbox_type = DBOX_TYPE_SCRIPT;
2201             } else if (!xmlStrcasecmp(type, (const xmlChar *)"elm")) {
2202                 dynamicbox->dbox_type = DBOX_TYPE_UIFW;
2203             } else { /* Default */
2204                 dynamicbox->dbox_type = DBOX_TYPE_FILE;
2205             }
2206
2207             xmlFree(type);
2208         }
2209     }
2210
2211     if (!xmlHasProp(node, (const xmlChar *)"mouse_event")) {
2212         dynamicbox->default_mouse_event = 0;
2213     } else {
2214         xmlChar *mouse_event;
2215
2216         mouse_event = xmlGetProp(node, (const xmlChar *)"mouse_event");
2217         if (!mouse_event) {
2218             ErrPrint("mouse_event is NIL\n");
2219             dynamicbox->default_mouse_event = 0;
2220         } else {
2221             dynamicbox->default_mouse_event = !xmlStrcasecmp(mouse_event, (const xmlChar *)"true");
2222             xmlFree(mouse_event);
2223         }
2224     }
2225
2226     if (!xmlHasProp(node, (const xmlChar *)"touch_effect")) {
2227         dynamicbox->default_touch_effect = 1;
2228     } else {
2229         xmlChar *touch_effect;
2230
2231         touch_effect = xmlGetProp(node, (const xmlChar *)"touch_effect");
2232         if (!touch_effect) {
2233             ErrPrint("default touch_effect is NIL\n");
2234             dynamicbox->default_touch_effect = 1;
2235         } else {
2236             dynamicbox->default_touch_effect = !xmlStrcasecmp(touch_effect, (const xmlChar *)"true");
2237             xmlFree(touch_effect);
2238         }
2239     }
2240
2241     if (!xmlHasProp(node, (const xmlChar *)"need_frame")) {
2242         dynamicbox->default_need_frame = 0;
2243     } else {
2244         xmlChar *need_frame;
2245
2246         need_frame = xmlGetProp(node, (const xmlChar *)"need_frame");
2247         if (!need_frame) {
2248             ErrPrint("default need_frame is NIL\n");
2249             dynamicbox->default_need_frame = 0;
2250         } else {
2251             dynamicbox->default_need_frame = !xmlStrcasecmp(need_frame, (const xmlChar *)"true");
2252             xmlFree(need_frame);
2253         }
2254     }
2255
2256     for (node = node->children; node; node = node->next) {
2257         if (!xmlStrcasecmp(node->name, (const xmlChar *)"size")) {
2258             xmlChar *size;
2259             int is_easy = 0;
2260
2261             size = xmlNodeGetContent(node);
2262             if (!size) {
2263                 ErrPrint("Invalid size tag\n");
2264                 continue;
2265             }
2266
2267             if (xmlHasProp(node, (const xmlChar *)"mode")) {
2268                 xmlChar *mode;
2269                 mode = xmlGetProp(node, (const xmlChar *)"mode");
2270                 if (mode) {
2271                     DbgPrint("Easy mode: %s\n", mode);
2272                     is_easy = !xmlStrcasecmp(mode, (const xmlChar *)"easy");
2273                     xmlFree(mode);
2274                 }
2275             }
2276
2277             if (!xmlStrcasecmp(size, (const xmlChar *)"1x1")) {
2278                 if (is_easy) {
2279                     dynamicbox->size_list |= DBOX_SIZE_TYPE_EASY_1x1;
2280                     update_size_info(dynamicbox, 9, node);
2281                 } else {
2282                     dynamicbox->size_list |= DBOX_SIZE_TYPE_1x1;
2283                     update_size_info(dynamicbox, 0, node);
2284                 }
2285             } else if (!xmlStrcasecmp(size, (const xmlChar *)"3x1")) {
2286                 if (is_easy) {
2287                     dynamicbox->size_list |= DBOX_SIZE_TYPE_EASY_3x1;
2288                     update_size_info(dynamicbox, 10, node);
2289                 } else {
2290                     ErrPrint("Invalid size tag (%s)\n", size);
2291                 }
2292             } else if (!xmlStrcasecmp(size, (const xmlChar *)"3x3")) {
2293                 if (is_easy) {
2294                     dynamicbox->size_list |= DBOX_SIZE_TYPE_EASY_3x3;
2295                     update_size_info(dynamicbox, 11, node);
2296                 } else {
2297                     ErrPrint("Invalid size tag (%s)\n", size);
2298                 }
2299             } else if (!xmlStrcasecmp(size, (const xmlChar *)"2x1")) {
2300                 dynamicbox->size_list |= DBOX_SIZE_TYPE_2x1;
2301                 update_size_info(dynamicbox, 1, node);
2302             } else if (!xmlStrcasecmp(size, (const xmlChar *)"2x2")) {
2303                 dynamicbox->size_list |= DBOX_SIZE_TYPE_2x2;
2304                 update_size_info(dynamicbox, 2, node);
2305             } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x1")) {
2306                 dynamicbox->size_list |= DBOX_SIZE_TYPE_4x1;
2307                 update_size_info(dynamicbox, 3, node);
2308             } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x2")) {
2309                 dynamicbox->size_list |= DBOX_SIZE_TYPE_4x2;
2310                 update_size_info(dynamicbox, 4, node);
2311             } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x3")) {
2312                 dynamicbox->size_list |= DBOX_SIZE_TYPE_4x3;
2313                 update_size_info(dynamicbox, 5, node);
2314             } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x4")) {
2315                 dynamicbox->size_list |= DBOX_SIZE_TYPE_4x4;
2316                 update_size_info(dynamicbox, 6, node);
2317             } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x5")) {
2318                 dynamicbox->size_list |= DBOX_SIZE_TYPE_4x5;
2319                 update_size_info(dynamicbox, 7, node);
2320             } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x6")) {
2321                 dynamicbox->size_list |= DBOX_SIZE_TYPE_4x6;
2322                 update_size_info(dynamicbox, 8, node);
2323             } else if (!xmlStrcasecmp(size, (const xmlChar *)"21x21")) {
2324                 dynamicbox->size_list |= DBOX_SIZE_TYPE_EASY_1x1;
2325                 update_size_info(dynamicbox, 9, node);
2326             } else if (!xmlStrcasecmp(size, (const xmlChar *)"23x21")) {
2327                 dynamicbox->size_list |= DBOX_SIZE_TYPE_EASY_3x1;
2328                 update_size_info(dynamicbox, 10, node);
2329             } else if (!xmlStrcasecmp(size, (const xmlChar *)"23x23")) {
2330                 dynamicbox->size_list |= DBOX_SIZE_TYPE_EASY_3x3;
2331                 update_size_info(dynamicbox, 11, node);
2332             } else if (!xmlStrcasecmp(size, (const xmlChar *)"0x0")) {
2333                 dynamicbox->size_list |= DBOX_SIZE_TYPE_0x0;
2334                 update_size_info(dynamicbox, 12, node);
2335             } else {
2336                 ErrPrint("Invalid size tag (%s)\n", size);
2337             }
2338
2339             xmlFree(size);
2340         } else if (!xmlStrcasecmp(node->name, (const xmlChar *)"script")) {
2341             xmlChar *src;
2342
2343             if (!xmlHasProp(node, (const xmlChar *)"src")) {
2344                 ErrPrint("Invalid script tag. has no src\n");
2345                 continue;
2346             }
2347
2348             src = xmlGetProp(node, (const xmlChar *)"src");
2349             if (!src) {
2350                 ErrPrint("Invalid script tag. src is NIL\n");
2351                 continue;
2352             }
2353
2354             if (dynamicbox->dbox_src) {
2355                 DbgPrint("Override lb src: %s\n", dynamicbox->dbox_src);
2356                 xmlFree(dynamicbox->dbox_src);
2357             }
2358
2359             dynamicbox->dbox_src = src;
2360
2361             if (xmlHasProp(node, (const xmlChar *)"group")) {
2362                 xmlChar *group;
2363                 group = xmlGetProp(node, (const xmlChar *)"group");
2364                 if (!group) {
2365                     ErrPrint("Group is NIL\n");
2366                 } else {
2367                     if (dynamicbox->dbox_group) {
2368                         DbgPrint("Override lb group: %s\n", dynamicbox->dbox_group);
2369                         xmlFree(dynamicbox->dbox_group);
2370                     }
2371
2372                     dynamicbox->dbox_group = group;
2373                 }
2374             }
2375         }
2376     }
2377 }
2378
2379 static inline void update_group(struct dynamicbox *dynamicbox, xmlNodePtr node)
2380 {
2381     xmlNodePtr cluster;
2382     xmlNodePtr category;
2383     xmlNodePtr option_item;
2384     xmlChar *cluster_name;
2385     xmlChar *category_name;
2386     xmlChar *ctx_item;
2387
2388     xmlChar *key;
2389     xmlChar *value;
2390
2391     struct group *group;
2392     struct option *option;
2393
2394     cluster = node;
2395     for (cluster = cluster->children; cluster; cluster = cluster->next) {
2396         if (xmlStrcasecmp(cluster->name, (const xmlChar *)"cluster")) {
2397             DbgPrint("Skip: %s\n", cluster->name);
2398             continue;
2399         }
2400
2401         if (!xmlHasProp(cluster, (const xmlChar *)"name")) {
2402             ErrPrint("Invalid cluster, has no name\n");
2403             continue;
2404         }
2405
2406         cluster_name = xmlGetProp(cluster, (const xmlChar *)"name");
2407         if (!cluster_name) {
2408             ErrPrint("Invalid cluster name. NIL\n");
2409             continue;
2410         }
2411
2412         for (category = cluster->children; category; category = category->next) {
2413             if (xmlStrcasecmp(category->name, (const xmlChar *)"category")) {
2414                 DbgPrint("Skip: %s\n", category->name);
2415                 continue;
2416             }
2417
2418             if (!xmlHasProp(category, (const xmlChar *)"name")) {
2419                 ErrPrint("Invalid category, has no name\n");
2420                 continue;
2421             }
2422
2423             category_name = xmlGetProp(category, (const xmlChar *)"name");
2424             if (!category_name) {
2425                 ErrPrint("Invalid category name. NIL\n");
2426                 continue;
2427             }
2428
2429             group = calloc(1, sizeof(*group));
2430             if (!group) {
2431                 ErrPrint("Heap: %s\n", strerror(errno));
2432                 xmlFree(category_name);
2433                 continue;
2434             }
2435
2436             group->cluster = xmlStrdup(cluster_name);
2437             if (!group->cluster) {
2438                 ErrPrint("Heap: %s\n", strerror(errno));
2439                 xmlFree(category_name);
2440                 free(group);
2441                 continue;
2442             }
2443
2444             group->category = category_name;
2445             dynamicbox->group_list = dlist_append(dynamicbox->group_list, group);
2446
2447             if (!xmlHasProp(category, (const xmlChar *)"context")) {
2448                 DbgPrint("%s, %s has no ctx info\n", group->cluster, group->category);
2449                 continue;
2450             }
2451
2452             ctx_item = xmlGetProp(category, (const xmlChar *)"context");
2453             if (!ctx_item) {
2454                 ErrPrint("Failed to get context ID (%s, %s)\n", group->cluster, group->category);
2455                 continue;
2456             }
2457
2458             group->ctx_item = ctx_item;
2459             DbgPrint("Build group item: %s - %s - %s\n", group->cluster, group->category, group->ctx_item);
2460
2461             for (option_item = category->children; option_item; option_item = option_item->next) {
2462                 if (xmlStrcasecmp(option_item->name, (const xmlChar *)"option")) {
2463                     DbgPrint("Skip: %s\n", option_item->name);
2464                     continue;
2465                 }
2466
2467                 if (!xmlHasProp(option_item, (const xmlChar *)"key")) {
2468                     ErrPrint("Invalid option, has no key\n");
2469                     continue;
2470                 }
2471
2472                 if (!xmlHasProp(option_item, (const xmlChar *)"value")) {
2473                     ErrPrint("Invalid option, has no value\n");
2474                     continue;
2475                 }
2476
2477                 key = xmlGetProp(option_item, (const xmlChar *)"key");
2478                 if (!key) {
2479                     ErrPrint("Invalid key. NIL\n");
2480                     continue;
2481                 }
2482
2483                 value = xmlGetProp(option_item, (const xmlChar *)"value");
2484                 if (!value) {
2485                     ErrPrint("Invalid valid. NIL\n");
2486                     xmlFree(key);
2487                     continue;
2488                 }
2489
2490                 option = calloc(1, sizeof(*option));
2491                 if (!option) {
2492                     ErrPrint("Heap: %s\n", strerror(errno));
2493                     xmlFree(key);
2494                     xmlFree(value);
2495                     continue;
2496                 }
2497
2498                 option->key = key;
2499                 option->value = value;
2500
2501                 group->option_list = dlist_append(group->option_list, option);
2502             }
2503         }
2504
2505         xmlFree(cluster_name);
2506     }
2507 }
2508
2509 static inline void update_pd(struct dynamicbox *dynamicbox, xmlNodePtr node)
2510 {
2511     if (!xmlHasProp(node, (const xmlChar *)"type")) {
2512         dynamicbox->gbar_type = GBAR_TYPE_SCRIPT;
2513     } else {
2514         xmlChar *type;
2515
2516         type = xmlGetProp(node, (const xmlChar *)"type");
2517         if (!type) {
2518             ErrPrint("type is NIL\n");
2519             return;
2520         }
2521
2522         if (!xmlStrcasecmp(type, (const xmlChar *)"text")) {
2523             dynamicbox->gbar_type = GBAR_TYPE_TEXT;
2524         } else if (!xmlStrcasecmp(type, (const xmlChar *)"buffer")) {
2525             dynamicbox->gbar_type = GBAR_TYPE_BUFFER;
2526         } else if (!xmlStrcasecmp(type, (const xmlChar *)"elm")) {
2527             dynamicbox->gbar_type = GBAR_TYPE_UIFW;
2528         } else {
2529             dynamicbox->gbar_type = GBAR_TYPE_SCRIPT;
2530         }
2531
2532         xmlFree(type);
2533     }
2534
2535     for (node = node->children; node; node = node->next) {
2536         if (!xmlStrcasecmp(node->name, (const xmlChar *)"size")) {
2537             xmlChar *size;
2538
2539             size = xmlNodeGetContent(node);
2540             if (!size) {
2541                 ErrPrint("Invalid size tag\n");
2542                 continue;
2543             }
2544
2545             if (dynamicbox->gbar_size) {
2546                 DbgPrint("Override pd size: %s\n", dynamicbox->gbar_size);
2547                 xmlFree(dynamicbox->gbar_size);
2548             }
2549             dynamicbox->gbar_size = size;
2550         } else if (!xmlStrcasecmp(node->name, (const xmlChar *)"script")) {
2551             xmlChar *src;
2552
2553             if (!xmlHasProp(node, (const xmlChar *)"src")) {
2554                 ErrPrint("Invalid script tag, has no src\n");
2555                 continue;
2556             }
2557
2558             src = xmlGetProp(node, (const xmlChar *)"src");
2559             if (!src) {
2560                 ErrPrint("src is NIL\n");
2561                 continue;
2562             }
2563
2564             if (dynamicbox->gbar_src) {
2565                 DbgPrint("Overide PD src: %s\n", dynamicbox->gbar_src);
2566                 xmlFree(dynamicbox->gbar_src);
2567             }
2568
2569             dynamicbox->gbar_src = src;
2570
2571             if (xmlHasProp(node, (const xmlChar *)"group")) {
2572                 xmlChar *group;
2573                 group = xmlGetProp(node, (const xmlChar *)"group");
2574                 if (!group) {
2575                     ErrPrint("Group is NIL\n");
2576                 } else {
2577                     if (dynamicbox->gbar_group) {
2578                         DbgPrint("Override PD group : %s\n", dynamicbox->gbar_group);
2579                         xmlFree(dynamicbox->gbar_group);
2580                     }
2581
2582                     dynamicbox->gbar_group = group;
2583                 }
2584             }
2585         }
2586     }
2587 }
2588
2589 static int db_insert_dynamicbox(struct dynamicbox *dynamicbox, const char *appid)
2590 {
2591     struct dlist *l;
2592     struct dlist *il;
2593     struct i18n *i18n;
2594     struct group *group;
2595     int ret;
2596     int id;
2597     struct option *option;
2598
2599     begin_transaction();
2600     ret = db_insert_pkgmap(appid, (char *)dynamicbox->pkgid, (char *)dynamicbox->uiapp, dynamicbox->primary, (char *)dynamicbox->category);
2601     if (ret < 0) {
2602         goto errout;
2603     }
2604
2605     ret = db_insert_provider(dynamicbox);
2606     if (ret < 0) {
2607         goto errout;
2608     }
2609
2610     ret = db_insert_client(dynamicbox);
2611     if (ret < 0) {
2612         goto errout;
2613     }
2614
2615     dlist_foreach(dynamicbox->i18n_list, l, i18n) {
2616         ret = db_insert_i18n((char *)dynamicbox->pkgid, (char *)i18n->lang, (char *)i18n->name, (char *)i18n->icon);
2617         if (ret < 0) {
2618             goto errout;
2619         }
2620     }
2621
2622     if (dynamicbox->size_list & DBOX_SIZE_TYPE_1x1) {
2623         ret = db_insert_box_size((char *)dynamicbox->pkgid, DBOX_SIZE_TYPE_1x1, (char *)dynamicbox->preview[0], dynamicbox->touch_effect[0], dynamicbox->need_frame[0], dynamicbox->mouse_event[0]);
2624         if (ret < 0) {
2625             goto errout;
2626         }
2627     }
2628
2629     if (dynamicbox->size_list & DBOX_SIZE_TYPE_2x1) {
2630         ret = db_insert_box_size((char *)dynamicbox->pkgid, DBOX_SIZE_TYPE_2x1, (char *)dynamicbox->preview[1], dynamicbox->touch_effect[1], dynamicbox->need_frame[1], dynamicbox->mouse_event[1]);
2631         if (ret < 0) {
2632             goto errout;
2633         }
2634     }
2635
2636     if (dynamicbox->size_list & DBOX_SIZE_TYPE_2x2) {
2637         ret = db_insert_box_size((char *)dynamicbox->pkgid, DBOX_SIZE_TYPE_2x2, (char *)dynamicbox->preview[2], dynamicbox->touch_effect[2], dynamicbox->need_frame[2], dynamicbox->mouse_event[2]);
2638         if (ret < 0) {
2639             goto errout;
2640         }
2641     }
2642
2643     if (dynamicbox->size_list & DBOX_SIZE_TYPE_4x1) {
2644         ret = db_insert_box_size((char *)dynamicbox->pkgid, DBOX_SIZE_TYPE_4x1, (char *)dynamicbox->preview[3], dynamicbox->touch_effect[3], dynamicbox->need_frame[3], dynamicbox->mouse_event[3]);
2645         if (ret < 0) {
2646             goto errout;
2647         }
2648     }
2649
2650     if (dynamicbox->size_list & DBOX_SIZE_TYPE_4x2) {
2651         ret = db_insert_box_size((char *)dynamicbox->pkgid, DBOX_SIZE_TYPE_4x2, (char *)dynamicbox->preview[4], dynamicbox->touch_effect[4], dynamicbox->need_frame[4], dynamicbox->mouse_event[4]);
2652         if (ret < 0) {
2653             goto errout;
2654         }
2655     }
2656
2657     if (dynamicbox->size_list & DBOX_SIZE_TYPE_4x3) {
2658         ret = db_insert_box_size((char *)dynamicbox->pkgid, DBOX_SIZE_TYPE_4x3, (char *)dynamicbox->preview[5], dynamicbox->touch_effect[5], dynamicbox->need_frame[5], dynamicbox->mouse_event[5]);
2659         if (ret < 0) {
2660             goto errout;
2661         }
2662     }
2663
2664     if (dynamicbox->size_list & DBOX_SIZE_TYPE_4x4) {
2665         ret = db_insert_box_size((char *)dynamicbox->pkgid, DBOX_SIZE_TYPE_4x4, (char *)dynamicbox->preview[6], dynamicbox->touch_effect[6], dynamicbox->need_frame[6], dynamicbox->mouse_event[6]);
2666         if (ret < 0) {
2667             goto errout;
2668         }
2669     }
2670
2671     if (dynamicbox->size_list & DBOX_SIZE_TYPE_4x5) {
2672         ret = db_insert_box_size((char *)dynamicbox->pkgid, DBOX_SIZE_TYPE_4x5, (char *)dynamicbox->preview[7], dynamicbox->touch_effect[7], dynamicbox->need_frame[7], dynamicbox->mouse_event[7]);
2673         if (ret < 0) {
2674             goto errout;
2675         }
2676     }
2677
2678     if (dynamicbox->size_list & DBOX_SIZE_TYPE_4x6) {
2679         ret = db_insert_box_size((char *)dynamicbox->pkgid, DBOX_SIZE_TYPE_4x6, (char *)dynamicbox->preview[8], dynamicbox->touch_effect[8], dynamicbox->need_frame[8], dynamicbox->mouse_event[8]);
2680         if (ret < 0) {
2681             goto errout;
2682         }
2683     }
2684
2685     if (dynamicbox->size_list & DBOX_SIZE_TYPE_EASY_1x1) {
2686         ret = db_insert_box_size((char *)dynamicbox->pkgid, DBOX_SIZE_TYPE_EASY_1x1, (char *)dynamicbox->preview[9], dynamicbox->touch_effect[9], dynamicbox->need_frame[9], dynamicbox->mouse_event[9]);
2687         if (ret < 0) {
2688             goto errout;
2689         }
2690     }
2691
2692     if (dynamicbox->size_list & DBOX_SIZE_TYPE_EASY_3x1) {
2693         ret = db_insert_box_size((char *)dynamicbox->pkgid, DBOX_SIZE_TYPE_EASY_3x1, (char *)dynamicbox->preview[10], dynamicbox->touch_effect[10], dynamicbox->need_frame[10], dynamicbox->mouse_event[10]);
2694         if (ret < 0) {
2695             goto errout;
2696         }
2697     }
2698
2699     if (dynamicbox->size_list & DBOX_SIZE_TYPE_EASY_3x3) {
2700         ret = db_insert_box_size((char *)dynamicbox->pkgid, DBOX_SIZE_TYPE_EASY_3x3, (char *)dynamicbox->preview[11], dynamicbox->touch_effect[11], dynamicbox->need_frame[11], dynamicbox->mouse_event[11]);
2701         if (ret < 0) {
2702             goto errout;
2703         }
2704     }
2705
2706     if (dynamicbox->size_list & DBOX_SIZE_TYPE_0x0) {
2707         ret = db_insert_box_size((char *)dynamicbox->pkgid, DBOX_SIZE_TYPE_0x0, (char *)dynamicbox->preview[12], dynamicbox->touch_effect[12], dynamicbox->need_frame[12], dynamicbox->mouse_event[12]);
2708         if (ret < 0) {
2709             goto errout;
2710         }
2711     }
2712
2713     dlist_foreach(dynamicbox->group_list, l, group) {
2714         /* group ID "id" */
2715         id = db_get_group_id((char *)group->cluster, (char *)group->category);
2716         if (id < 0) {
2717             int ret;
2718
2719             ret = db_insert_group((char *)dynamicbox->pkgid, (char *)group->cluster, (char *)group->category);
2720             if (ret < 0) {
2721                 ErrPrint("[%s]-[%s] is not exists\n", group->cluster, group->category);
2722                 continue;
2723             }
2724
2725             DbgPrint("New group name is built - %s/%s\n", group->cluster, group->category);
2726             id = db_get_group_id((char *)group->cluster, (char *)group->category);
2727             if (id < 0) {
2728                 ErrPrint("Failed to get group id for %s/%s\n", group->cluster, group->category);
2729                 continue;
2730             }
2731         }
2732
2733         if (!group->ctx_item) {
2734             DbgPrint("%s, %s - has no ctx info\n", group->cluster, group->category);
2735             continue;
2736         }
2737
2738         ret = db_insert_groupmap(id, (char *)dynamicbox->pkgid, (char *)group->ctx_item);
2739         if (ret < 0) {
2740             goto errout;
2741         }
2742
2743         /* REUSE "id" from here , option ID */
2744         id = db_get_option_id(id, (char *)dynamicbox->pkgid, (char *)group->ctx_item);
2745         if (id < 0) {
2746             goto errout;
2747         }
2748
2749         dlist_foreach(group->option_list, il, option) {
2750             ret = db_insert_option((char *)dynamicbox->pkgid, id, (char *)option->key, (char *)option->value);
2751             if (ret < 0) {
2752                 goto errout;
2753             }
2754         }
2755     }
2756
2757     commit_transaction();
2758     dynamicbox_destroy(dynamicbox);
2759     return 0;
2760
2761 errout:
2762     ErrPrint("ROLLBACK\n");
2763     rollback_transaction();
2764     dynamicbox_destroy(dynamicbox);
2765     return ret;
2766 }
2767
2768 static int do_install(xmlNodePtr node, const char *appid)
2769 {
2770     struct dynamicbox *dynamicbox;
2771     xmlChar *pkgid;
2772     xmlChar *tmp;
2773
2774     if (!xmlHasProp(node, (const xmlChar *)"appid")) {
2775         ErrPrint("Missing appid\n");
2776         return -EINVAL;
2777     }
2778
2779     pkgid = xmlGetProp(node, (const xmlChar *)"appid");
2780     if (!pkgid || !validate_pkgid(appid, (char *)pkgid)) {
2781         ErrPrint("Invalid appid\n");
2782         xmlFree(pkgid);
2783         return -EINVAL;
2784     }
2785
2786     DbgPrint("appid: %s\n", (char *)pkgid);
2787
2788     dynamicbox = calloc(1, sizeof(*dynamicbox));
2789     if (!dynamicbox) {
2790         ErrPrint("Heap: %s\n", strerror(errno));
2791         xmlFree(pkgid);
2792         return -ENOMEM;
2793     }
2794
2795     dynamicbox->pkgid = pkgid;
2796
2797     if (xmlHasProp(node, (const xmlChar *)"count")) {
2798         tmp = xmlGetProp(node, (const xmlChar *)"count");
2799         if (sscanf((const char *)tmp, "%d", &dynamicbox->count) != 1) {
2800             ErrPrint("Invalid syntax: %s\n", (const char *)tmp);
2801         }
2802         xmlFree(tmp);
2803     }
2804
2805     if (xmlHasProp(node, (const xmlChar *)"primary")) {
2806         tmp = xmlGetProp(node, (const xmlChar *)"primary");
2807         dynamicbox->primary = !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2808         xmlFree(tmp);
2809     }
2810
2811     if (xmlHasProp(node, (const xmlChar *)"script")) {
2812         dynamicbox->script = xmlGetProp(node, (const xmlChar *)"script");
2813         if (!dynamicbox->script) {
2814             ErrPrint("script is NIL\n");
2815         }
2816     }
2817
2818     if (xmlHasProp(node, (const xmlChar *)"nodisplay")) {
2819         tmp = xmlGetProp(node, (const xmlChar *)"nodisplay");
2820         dynamicbox->nodisplay = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2821         xmlFree(tmp);
2822     }
2823
2824     if (xmlHasProp(node, (const xmlChar *)"pinup")) {
2825         tmp = xmlGetProp(node, (const xmlChar *)"pinup");
2826         dynamicbox->pinup = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2827         xmlFree(tmp);
2828     }
2829
2830     if (xmlHasProp(node, (const xmlChar *)"period")) {
2831         dynamicbox->period = xmlGetProp(node, (const xmlChar *)"period");
2832         if (!dynamicbox->period) {
2833             ErrPrint("Period is NIL\n");
2834         }
2835     }
2836
2837     if (xmlHasProp(node, (const xmlChar *)"timeout")) {
2838         dynamicbox->timeout = xmlGetProp(node, (const xmlChar *)"timeout");
2839         if (!dynamicbox->timeout) {
2840             ErrPrint("Timeout is NIL\n");
2841         }
2842     }
2843
2844     if (xmlHasProp(node, (const xmlChar *)"secured")) {
2845         tmp = xmlGetProp(node, (const xmlChar *)"secured");
2846         dynamicbox->secured = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2847         xmlFree(tmp);
2848     }
2849
2850     if (xmlHasProp(node, (const xmlChar *)"network")) {
2851         tmp = xmlGetProp(node, (const xmlChar *)"network");
2852         dynamicbox->network = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2853         xmlFree(tmp);
2854     }
2855
2856     if (xmlHasProp(node, (const xmlChar *)"direct_input")) {
2857         tmp = xmlGetProp(node, (const xmlChar *)"direct_input");
2858         dynamicbox->direct_input = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2859         xmlFree(tmp);
2860     }
2861
2862     if (xmlHasProp(node, (const xmlChar *)"hw-acceleration")) {
2863         dynamicbox->hw_acceleration = xmlGetProp(node, (const xmlChar *)"hw-acceleration");
2864         if (!dynamicbox->hw_acceleration) {
2865             ErrPrint("hw-acceleration is NIL\n");
2866         }
2867     }
2868
2869     if (xmlHasProp(node, (const xmlChar *)"abi")) {
2870         dynamicbox->abi = xmlGetProp(node, (const xmlChar *)"abi");
2871         if (!dynamicbox->abi) {
2872             ErrPrint("ABI is NIL\n");
2873             dynamicbox_destroy(dynamicbox);
2874             return -EFAULT;
2875         }
2876     } else {
2877         dynamicbox->abi = xmlStrdup((const xmlChar *)"c");
2878         if (!dynamicbox->abi) {
2879             ErrPrint("Heap: %s\n", strerror(errno));
2880             dynamicbox_destroy(dynamicbox);
2881             return -ENOMEM;
2882         }
2883     }
2884
2885     if (xmlHasProp(node, (const xmlChar *)"libexec")) {
2886         dynamicbox->libexec = xmlGetProp(node, (const xmlChar *)"libexec");
2887         if (!dynamicbox->libexec) {
2888             ErrPrint("libexec is NIL\n");
2889             dynamicbox_destroy(dynamicbox);
2890             return -EFAULT;
2891         }
2892     } else if (!xmlStrcasecmp(dynamicbox->abi, (const xmlChar *)"c") || !xmlStrcasecmp(dynamicbox->abi, (const xmlChar *)"cpp")) {
2893         char *filename;
2894         int len;
2895
2896         len = strlen((char *)dynamicbox->pkgid) + strlen("/libexec/liblive-.so") + 1;
2897
2898         filename = malloc(len);
2899         if (!filename) {
2900             dynamicbox_destroy(dynamicbox);
2901             return -ENOMEM;
2902         }
2903
2904         snprintf(filename, len, "/libexec/liblive-%s.so", dynamicbox->pkgid);
2905         dynamicbox->libexec = xmlStrdup((xmlChar *)filename);
2906         DbgPrint("Use the default libexec: %s\n", filename);
2907         free(filename);
2908
2909         if (!dynamicbox->libexec) {
2910             dynamicbox_destroy(dynamicbox);
2911             return -ENOMEM;
2912         }
2913     }
2914
2915     for (node = node->children; node; node = node->next) {
2916         if (!xmlStrcmp(node->name, (const xmlChar *)"text")) {
2917             continue;
2918         }
2919
2920         DbgPrint("Nodename: %s\n", node->name);
2921         if (!xmlStrcasecmp(node->name, (const xmlChar *)"label")) {
2922             update_i18n_name(dynamicbox, node);
2923             continue;
2924         }
2925
2926         if (!xmlStrcasecmp(node->name, (const xmlChar *)"icon")) {
2927             update_i18n_icon(dynamicbox, node);
2928             continue;
2929         }
2930
2931         if (!xmlStrcasecmp(node->name, (const xmlChar *)"box")) {
2932             update_box(dynamicbox, node);
2933             continue;
2934         }
2935
2936         if (!xmlStrcasecmp(node->name, (const xmlChar *)"glancebar")) {
2937             update_pd(dynamicbox, node);
2938             continue;
2939         }
2940
2941         if (!xmlStrcasecmp(node->name, (const xmlChar *)"group")) {
2942             update_group(dynamicbox, node);
2943             continue;
2944         }
2945
2946         if (!xmlStrcasecmp(node->name, (const xmlChar *)"content")) {
2947             update_content(dynamicbox, node);
2948             continue;
2949         }
2950
2951         if (!xmlStrcasecmp(node->name, (const xmlChar *)"setup")) {
2952             update_setup(dynamicbox, node);
2953             continue;
2954         }
2955
2956         if (!xmlStrcasecmp(node->name, (const xmlChar *)"launch")) {
2957             update_launch(dynamicbox, node);
2958             continue;
2959         }
2960
2961         if (!xmlStrcasecmp(node->name, (const xmlChar *)"ui-appid")) {
2962             update_ui_appid(dynamicbox, node);
2963             continue;
2964         }
2965
2966         if (!xmlStrcasecmp(node->name, (const xmlChar *)"category")) {
2967             update_category(dynamicbox, node);
2968             continue;
2969         }
2970     }
2971
2972     return db_insert_dynamicbox(dynamicbox, appid);
2973 }
2974
2975 static inline int do_uninstall(xmlNodePtr node, const char *appid)
2976 {
2977     xmlChar *pkgid;
2978     int ret;
2979
2980     if (!xmlHasProp(node, (const xmlChar *)"appid")) {
2981         ErrPrint("Missing appid\n");
2982         return -EINVAL;
2983     }
2984
2985     pkgid = xmlGetProp(node, (const xmlChar *)"appid");
2986     if (!validate_pkgid(appid, (char *)pkgid)) {
2987         ErrPrint("Invalid package\n");
2988         xmlFree(pkgid);
2989         return -EINVAL;
2990     }
2991
2992     begin_transaction();
2993     ret = db_remove_box_size((char *)pkgid);
2994     if (ret < 0) {
2995         goto errout;
2996     }
2997
2998     ret = db_remove_i18n((char *)pkgid);
2999     if (ret < 0) {
3000         goto errout;
3001     }
3002
3003     ret = db_remove_client((char *)pkgid);
3004     if (ret < 0) {
3005         goto errout;
3006     }
3007
3008     ret = db_remove_provider((char *)pkgid);
3009     if (ret < 0) {
3010         goto errout;
3011     }
3012
3013     ret = db_remove_option((char *)pkgid);
3014     DbgPrint("Remove option: %d\n", ret);
3015
3016     ret = db_remove_groupmap((char *)pkgid);
3017     DbgPrint("Remove groupmap: %d\n", ret);
3018
3019     ret = db_remove_group((char *)pkgid);
3020     if (ret < 0) {
3021         goto errout;
3022     }
3023
3024     ret = db_remove_pkgmap((char *)pkgid);
3025     if (ret < 0) {
3026         goto errout;
3027     }
3028
3029     commit_transaction();
3030     xmlFree(pkgid);
3031
3032     return 0;
3033
3034 errout:
3035     rollback_transaction();
3036     xmlFree(pkgid);
3037     return ret;
3038 }
3039
3040 static int pkglist_get_via_callback(const char *appid, void (*cb)(const char *appid, const char *pkgid, int prime, void *data), void *data)
3041 {
3042     const char *dml = "SELECT pkgid, prime FROM pkgmap WHERE appid = ?";
3043     int ret;
3044     sqlite3_stmt *stmt;
3045     const char *pkgid;
3046     int prime;
3047     int cnt = 0;
3048
3049     if (!cb || !appid || !strlen(appid)) {
3050         return -EINVAL;
3051     }
3052
3053     if (!s_info.handle) {
3054         if (db_init() < 0) {
3055             ErrPrint("Failed to init DB\n");
3056             return -EIO;
3057         }
3058     }
3059
3060     ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
3061     if (ret != SQLITE_OK) {
3062         ErrPrint("Failed to prepare the intial DML(%s)\n", sqlite3_errmsg(s_info.handle));
3063         return -EIO;
3064     }
3065
3066     ret = -EIO;
3067     if (sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
3068         ErrPrint("Failed to bind a cluster - %s\n", sqlite3_errmsg(s_info.handle));
3069         goto out;
3070     }
3071
3072     while (sqlite3_step(stmt) == SQLITE_ROW) {
3073         pkgid = (const char *)sqlite3_column_text(stmt, 0);
3074         if (!pkgid || !strlen(pkgid)) {
3075             continue;
3076         }
3077
3078         prime = sqlite3_column_int(stmt, 1);
3079         cb(appid, pkgid, prime, data);
3080         cnt++;
3081     }
3082
3083 out:
3084     sqlite3_reset(stmt);
3085     sqlite3_clear_bindings(stmt);
3086     sqlite3_finalize(stmt);
3087     return cnt;
3088 }
3089
3090 static void clear_all_pkg(const char *appid, const char *pkgid, int prime, void *data)
3091 {
3092     int ret;
3093
3094     ErrPrintWithConsole("Remove old package info: appid(%s), pkgid(%s)\n", appid, pkgid);
3095
3096     ret = db_remove_box_size((char *)pkgid);
3097     if (ret < 0) {
3098         ErrPrint("Remove box size: %d\n", ret);
3099     }
3100
3101     ret = db_remove_i18n((char *)pkgid);
3102     if (ret < 0) {
3103         ErrPrint("Remove i18n: %d\n", ret);
3104     }
3105
3106     ret = db_remove_client((char *)pkgid);
3107     if (ret < 0) {
3108         ErrPrint("Remove client: %d\n", ret);
3109     }
3110
3111     ret = db_remove_provider((char *)pkgid);
3112     if (ret < 0) {
3113         ErrPrint("Remove provider: %d\n", ret);
3114     }
3115
3116     ret = db_remove_option((char *)pkgid);
3117     if (ret < 0) {
3118         ErrPrint("Remove option: %d\n", ret);
3119     }
3120
3121     ret = db_remove_groupmap((char *)pkgid);
3122     if (ret < 0) {
3123         ErrPrint("Remove groupmap: %d\n", ret);
3124     }
3125
3126     ret = db_remove_group((char *)pkgid);
3127     if (ret < 0) {
3128         ErrPrint("Remove group: %d\n", ret);
3129     }
3130
3131     ret = db_remove_pkgmap((char *)pkgid);
3132     if (ret < 0) {
3133         ErrPrint("Remove pkgmap: %d\n", ret);
3134     }
3135 }
3136
3137 int PKGMGR_PARSER_PLUGIN_PRE_INSTALL(const char *appid)
3138 {
3139     int cnt;
3140
3141     ErrPrintWithConsole("%s\n", appid);
3142
3143     if (!s_info.handle) {
3144         if (db_init() < 0) {
3145             ErrPrintWithConsole("Failed to init DB\n");
3146             return -EIO;
3147         }
3148     }
3149
3150     do_upgrade_db_schema();
3151
3152     begin_transaction();
3153     cnt = pkglist_get_via_callback(appid, clear_all_pkg, NULL);
3154     commit_transaction();
3155
3156     if (cnt > 0) {
3157         DbgPrint("Package[%s] is not deleted: %d\n", appid, cnt);
3158     }
3159     return 0;
3160 }
3161
3162 int PKGMGR_PARSER_PLUGIN_POST_INSTALL(const char *appid)
3163 {
3164     ErrPrintWithConsole("[%s]\n", appid);
3165     db_fini();
3166     return 0;
3167 }
3168
3169 int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr docPtr, const char *appid)
3170 {
3171     xmlNodePtr node;
3172     int ret;
3173
3174     ErrPrintWithConsole("[%s]\n", appid);
3175
3176     if (!s_info.handle) {
3177         ErrPrintWithConsole("Failed to init DB\n");
3178         return -EIO;
3179     }
3180
3181     node = xmlDocGetRootElement(docPtr);
3182     if (!node) {
3183         ErrPrintWithConsole("Invalid document\n");
3184         return -EINVAL;
3185     }
3186
3187     for (node = node->children; node; node = node->next) {
3188         DbgPrint("node->name: %s\n", node->name);
3189         if (!xmlStrcasecmp(node->name, (const xmlChar *)"dynamicbox")) {
3190             ret = do_install(node, appid);
3191             if (ret < 0) {
3192                 DbgPrint("Returns: %d\n", ret);
3193             }
3194         }
3195     }
3196
3197     return 0;
3198 }
3199
3200 int PKGMGR_PARSER_PLUGIN_PRE_UPGRADE(const char *appid)
3201 {
3202     int cnt;
3203
3204     ErrPrintWithConsole("[%s]\n", appid);
3205
3206     if (!s_info.handle) {
3207         if (db_init() < 0) {
3208             ErrPrint("Failed to init DB\n");
3209             return -EIO;
3210         }
3211     }
3212
3213     do_upgrade_db_schema();
3214
3215     begin_transaction();
3216     cnt = pkglist_get_via_callback(appid, clear_all_pkg, NULL);
3217     commit_transaction();
3218
3219     if (cnt > 0) {
3220         DbgPrint("Package %s is deleted: %d\n", appid, cnt);
3221     }
3222     return 0;
3223 }
3224
3225 int PKGMGR_PARSER_PLUGIN_POST_UPGRADE(const char *appid)
3226 {
3227     ErrPrintWithConsole("[%s]\n", appid);
3228     db_fini();
3229     return 0;
3230 }
3231
3232 int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr docPtr, const char *appid)
3233 {
3234     xmlNodePtr node;
3235     int ret;
3236
3237     ErrPrintWithConsole("[%s]\n", appid);
3238
3239     if (!s_info.handle) {
3240         ErrPrint("Failed to init DB\n");
3241         return -EIO;
3242     }
3243
3244     node = xmlDocGetRootElement(docPtr);
3245     if (!node) {
3246         ErrPrint("Invalid document\n");
3247         return -EINVAL;
3248     }
3249
3250     for (node = node->children; node; node = node->next) {
3251         if (!xmlStrcasecmp(node->name, (const xmlChar *)"dynamicbox")) {
3252             ret = do_install(node, appid);
3253             if (ret < 0) {
3254                 DbgPrint("Returns: %d\n", ret);
3255             }
3256         }
3257     }
3258
3259     return 0;
3260 }
3261
3262 int PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL(const char *appid)
3263 {
3264     ErrPrintWithConsole("[%s]\n", appid);
3265
3266     if (!s_info.handle) {
3267         if (db_init() < 0) {
3268             ErrPrint("Failed to init DB\n");
3269             return -EIO;
3270         }
3271     }
3272
3273     do_upgrade_db_schema();
3274     return 0;
3275 }
3276
3277 int PKGMGR_PARSER_PLUGIN_POST_UNINSTALL(const char *appid)
3278 {
3279     int cnt;
3280
3281     ErrPrintWithConsole("[%s]\n", appid);
3282
3283     if (!s_info.handle) {
3284         return -EIO;
3285     }
3286
3287     begin_transaction();
3288     cnt = pkglist_get_via_callback(appid, clear_all_pkg, NULL);
3289     commit_transaction();
3290
3291     if (cnt > 0) {
3292         DbgPrint("Package %s is deleted: %d\n", appid, cnt);
3293     }
3294     db_fini();
3295     return 0;
3296 }
3297
3298 int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr docPtr, const char *appid)
3299 {
3300     ErrPrintWithConsole("[%s]\n", appid);
3301     if (!s_info.handle) {
3302         return -EIO;
3303     }
3304     /* Doesn't need to do anything from here, we already dealt it with this */
3305     return 0;
3306 }
3307
3308 /* End of a file */