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