Fix the GCC 4.7 build error
[platform/framework/web/livebox-service.git] / src / livebox-service.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.tizenopensource.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 <stdlib.h> /* malloc */
20 #include <string.h> /* strdup, strerror */
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <unistd.h>
24 #include <sqlite3.h>
25 #include <X11/X.h>
26 #include <X11/Xlib.h>
27 #include <ctype.h>
28
29 #include <com-core_packet.h>
30 #include <packet.h>
31 #include <dlog.h>
32 #include <db-util.h>
33 #include <package-manager.h>
34 #include <vconf.h>
35 #include <vconf-keys.h>
36
37 #include "dlist.h"
38 #include "util.h"
39 #include "debug.h"
40 #include "livebox-service.h"
41
42 #define EAPI __attribute__((visibility("default")))
43 #define DEFAULT_TIMEOUT 2.0
44 #define MAX_COLUMN 80
45
46 static struct supported_size_list {
47         int w;
48         int h;
49 } SIZE_LIST[NR_OF_SIZE_LIST] = {
50         { 172, 172 }, /*!< 1x1 */
51         { 348, 172 }, /*!< 2x1 */
52         { 348, 348 }, /*!< 2x2 */
53         { 700, 172 }, /*!< 4x1 */
54         { 700, 348 }, /*!< 4x2 */
55         { 700, 520 }, /*!< 4x3 */
56         { 700, 700 }, /*!< 4x4 */
57 };
58
59 static struct info {
60         sqlite3 *handle;
61         const char *dbfile;
62         const char *conf_file;
63         int init_count;
64         int res_resolved;
65 } s_info = {
66         .handle = NULL,
67         .dbfile = "/opt/dbspace/.livebox.db", 
68         .conf_file = "/usr/share/data-provider-master/resolution.ini",
69         .init_count = 0,
70         .res_resolved = 0,
71 };
72
73 static inline int update_info(int width_type, int height_type, int width, int height)
74 {
75         int idx;
76
77         if (width_type == 1 && height_type == 1) {
78                 DbgPrint("1x1 Updated to %dx%d\n", width, height);
79                 idx = 0;
80         } else if (width_type == 2 && height_type == 1) {
81                 DbgPrint("2x1 Updated to %dx%d\n", width, height);
82                 idx = 1;
83         } else if (width_type == 2 && height_type == 2) {
84                 DbgPrint("2x2 Updated to %dx%d\n", width, height);
85                 idx = 2;
86         } else if (width_type == 4 && height_type == 1) {
87                 DbgPrint("4x1 Updated to %dx%d\n", width, height);
88                 idx = 3;
89         } else if (width_type == 4 && height_type == 2) {
90                 DbgPrint("4x2 Updated to %dx%d\n", width, height);
91                 idx = 4;
92         } else if (width_type == 4 && height_type == 3) {
93                 DbgPrint("4x3 Updated to %dx%d\n", width, height);
94                 idx = 5;
95         } else if (width_type == 4 && height_type == 4) {
96                 DbgPrint("4x4 Updated to %dx%d\n", width, height);
97                 idx = 6;
98         } else {
99                 ErrPrint("Unknown size type: %dx%d (%dx%d)\n", width_type, height_type, width, height);
100                 return 0;
101         }
102
103         SIZE_LIST[idx].w = width;
104         SIZE_LIST[idx].h = height;
105         return 1;
106 }
107
108 static inline int update_from_file(void)
109 {
110         FILE *fp;
111         int updated;
112         int width_type;
113         int height_type;
114         int width;
115         int height;
116         char buffer[MAX_COLUMN];
117         int ch;
118         int idx;
119         enum status {
120                 START = 0x0,
121                 TYPE = 0x01,
122                 SIZE = 0x02,
123                 COMMENT = 0x03,
124                 ERROR = 0x04,
125                 EOL = 0x05,
126                 TYPE_END = 0x06,
127                 SIZE_START = 0x07,
128         } status;
129
130         fp = fopen(s_info.conf_file, "r");
131         if (!fp) {
132                 ErrPrint("Open failed: %s\n", strerror(errno));
133                 return -EIO;
134         }
135
136         updated = 0;
137         status = START;
138         idx = 0;
139         do {
140                 ch = fgetc(fp);
141
142                 if (idx == MAX_COLUMN) {
143                         ErrPrint("Buffer overflow. Too long line. LINE MUST BE SHOT THAN %d\n", MAX_COLUMN);
144                         status = ERROR;
145                 }
146
147                 switch (status) {
148                 case START:
149                         if (isspace(ch) || ch == EOF)
150                                 continue;
151
152                         if (ch == '#') {
153                                 status = COMMENT;
154                         } else {
155                                 status = TYPE;
156                                 idx = 0;
157                                 ungetc(ch, fp);
158                         }
159                         break;
160                 case TYPE:
161                         if (isblank(ch)) {
162                                 buffer[idx] = '\0';
163                                 status = TYPE_END;
164                                 if (sscanf(buffer, "%dx%d", &width_type, &height_type) != 2) {
165                                         ErrPrint("Invalid syntax: [%s]\n", buffer);
166                                         status = ERROR;
167                                 }
168                                 break;
169                         } else if (ch == '=') {
170                                 buffer[idx] = '\0';
171                                 status = SIZE_START;
172                                 if (sscanf(buffer, "%dx%d", &width_type, &height_type) != 2) {
173                                         ErrPrint("Invalid syntax: [%s]\n", buffer);
174                                         status = ERROR;
175                                 }
176                                 break;
177                         } else if (ch == EOF) {
178                                 ErrPrint("Invalid Syntax\n");
179                                 status = ERROR;
180                                 continue;
181                         }
182                         buffer[idx++] = ch;
183                         break;
184                 case TYPE_END:
185                         if (ch == '=')
186                                 status = SIZE_START;
187                         break;
188                 case SIZE_START:
189                         if (isspace(ch) || ch == EOF)
190                                 continue;
191
192                         status = SIZE;
193                         idx = 0;
194                         ungetc(ch, fp);
195                         break;
196                 case SIZE:
197                         if (isspace(ch) || ch == EOF) {
198                                 buffer[idx] = '\0';
199                                 status = EOL;
200
201                                 if (sscanf(buffer, "%dx%d", &width, &height) != 2) {
202                                         ErrPrint("Invalid syntax: [%s]\n", buffer);
203                                         status = ERROR;
204                                 } else if (ch == EOF) {
205                                         updated += update_info(width_type, height_type, width, height);
206                                 }
207                                 break;
208                         }
209                         buffer[idx++] = ch;
210                         break;
211                 case EOL:
212                         updated += update_info(width_type, height_type, width, height);
213                         status = START;
214                         ungetc(ch, fp);
215                         break;
216                 case ERROR:
217                         if (ch == '\n' || ch == '\r' || ch == '\f')
218                                 status = START;
219                         break;
220                 case COMMENT:
221                         if (ch == '\n' || ch == '\r' || ch == '\f')
222                                 status = START;
223                         break;
224                 default:
225                         ErrPrint("Unknown status. couldn't be reach to here\n");
226                         break;
227                 }
228         } while (!feof(fp));
229         fclose(fp);
230
231         return NR_OF_SIZE_LIST - updated;
232 }
233
234 static int update_resolution(void)
235 {
236         Display *disp;
237         Window root;
238         Window dummy;
239         int x, y;
240         unsigned int width;
241         unsigned int height;
242         unsigned int border;
243         unsigned int depth;
244         register int i;
245
246         if (s_info.res_resolved)
247                 return 0;
248
249         disp = XOpenDisplay(NULL);
250         if (!disp) {
251                 ErrPrint("Failed to open a display\n");
252                 return -EFAULT;
253         }
254
255         root = XDefaultRootWindow(disp);
256         if (!XGetGeometry(disp, root, &dummy, &x, &y, &width, &height, &border, &depth)) {
257                 XCloseDisplay(disp);
258                 return -EFAULT;
259         }
260
261         if (update_from_file() == 0)
262                 DbgPrint("Resolution info is all updated by file\n");
263
264         DbgPrint("Screen resolution: %dx%d\n", width, height);
265         for (i = 0; i < NR_OF_SIZE_LIST; i++) {
266                 SIZE_LIST[i].w = (unsigned int)((double)SIZE_LIST[i].w * (double)width / 720.0f);
267                 SIZE_LIST[i].h = (unsigned int)((double)SIZE_LIST[i].h * (double)height / 1280.0f);
268                 DbgPrint("(Ratio)Size is updated [%d] %dx%d\n", i, SIZE_LIST[i].w, SIZE_LIST[i].h);
269         }
270
271         XCloseDisplay(disp);
272         s_info.res_resolved = 1;
273         return 0;
274 }
275
276 static inline sqlite3 *open_db(void)
277 {
278         sqlite3 *handle;
279
280         if (!s_info.handle) {
281                 int ret;
282
283                 ret = db_util_open(s_info.dbfile, &handle, DB_UTIL_REGISTER_HOOK_METHOD);
284                 if (ret != SQLITE_OK) {
285                         ErrPrint("Failed to open a DB\n");
286                         return NULL;
287                 }
288         } else {
289                 handle = s_info.handle;
290         }
291
292         return handle;
293 }
294
295 static inline void close_db(sqlite3 *handle)
296 {
297         if (!s_info.handle)
298                 db_util_close(handle);
299 }
300
301 static inline int convert_size_from_type(enum livebox_size_type type, int *width, int *height)
302 {
303         int idx;
304
305         switch (type) {
306         case LB_SIZE_TYPE_1x1: /*!< 172x172 */
307                 idx = 0;
308                 break;
309         case LB_SIZE_TYPE_2x1: /*!< 348x172 */
310                 idx = 1;
311                 break;
312         case LB_SIZE_TYPE_2x2: /*!< 348x348 */
313                 idx = 2;
314                 break;
315         case LB_SIZE_TYPE_4x1: /*!< 700x172 */
316                 idx = 3;
317                 break;
318         case LB_SIZE_TYPE_4x2: /*!< 700x348 */
319                 idx = 4;
320                 break;
321         case LB_SIZE_TYPE_4x3: /*!< 700x520 */
322                 idx = 5;
323                 break;
324         case LB_SIZE_TYPE_4x4: /*!< 700x700 */
325                 idx = 6;
326                 break;
327         default:
328                 return -EINVAL;
329         }
330
331         if (update_resolution() < 0)
332                 ErrPrint("Failed to update resolution\n");
333
334         *width = SIZE_LIST[idx].w;
335         *height = SIZE_LIST[idx].h;
336         return 0;
337 }
338
339 EAPI int livebox_service_trigger_update(const char *pkgname, const char *cluster, const char *category)
340 {
341         struct packet *packet;
342         struct packet *result;
343         int ret;
344
345         if (!pkgname) {
346                 ErrPrint("Invalid argument\n");
347                 return -EINVAL;
348         }
349
350         if (access("/tmp/.live.paused", R_OK) == 0) {
351                 DbgPrint("Provider is paused\n");
352                 return -ECANCELED;
353         }
354
355         if (!cluster)
356                 cluster = "user,created";
357
358         if (!category)
359                 category = "default";
360
361         packet = packet_create("service_update", "sss", pkgname, cluster, category);
362         if (!packet) {
363                 ErrPrint("Failed to create a packet for service_update\n");
364                 return -EFAULT;
365         }
366
367         result = com_core_packet_oneshot_send(SERVICE_SOCKET, packet, DEFAULT_TIMEOUT);
368         packet_unref(packet);
369
370         if (result) {
371                 if (packet_get(result, "i", &ret) != 1) {
372                         ErrPrint("Failed to parse a result packet\n");
373                         ret = -EINVAL;
374                 }
375
376                 packet_unref(result);
377         } else {
378                 ErrPrint("Failed to get result packet\n");
379                 ret = -EFAULT;
380         }
381
382         return ret;
383 }
384
385 EAPI int livebox_service_get_pkglist(int (*cb)(const char *appid, const char *pkgname, int is_prime, void *data), void *data)
386 {
387         int ret;
388         sqlite3_stmt *stmt;
389         char *appid;
390         char *pkgid;
391         int is_prime;
392         sqlite3 *handle;
393
394         if (!cb)
395                 return -EINVAL;
396
397         handle = open_db();
398         if (!handle)
399                 return -EIO;
400
401         ret = sqlite3_prepare_v2(handle, "SELECT appid, pkgid, prime FROM pkgmap", -1, &stmt, NULL);
402         if (ret != SQLITE_OK) {
403                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
404                 ret = -EIO;
405                 goto out;
406         }
407
408         ret = 0;
409         while (sqlite3_step(stmt) == SQLITE_ROW) {
410                 appid = (char *)sqlite3_column_text(stmt, 0);
411                 if (!appid || !strlen(appid)) {
412                         ErrPrint("APPID is not valid\n");
413                         continue;
414                 }
415
416                 pkgid = (char *)sqlite3_column_text(stmt, 1);
417                 if (!pkgid || !strlen(pkgid)) {
418                         ErrPrint("pkgid is not valid\n");
419                         continue;
420                 }
421
422                 is_prime = sqlite3_column_int(stmt, 2);
423
424                 ret++;
425
426                 if (cb(appid, pkgid, is_prime, data) < 0) {
427                         DbgPrint("Callback stopped package crawling\n");
428                         break;
429                 }
430         }
431
432         sqlite3_reset(stmt);
433         sqlite3_finalize(stmt);
434
435 out:
436         close_db(handle);
437         return ret;
438 }
439
440 EAPI int livebox_service_get_supported_size_types(const char *pkgid, int *cnt, int *types)
441 {
442         sqlite3_stmt *stmt;
443         sqlite3 *handle;
444         int size;
445         int ret;
446
447         if (!types || !cnt || !pkgid)
448                 return -EINVAL;
449
450         handle = open_db();
451         if (!handle)
452                 return -EIO;
453
454         ret = sqlite3_prepare_v2(handle, "SELECT size_type FROM box_size WHERE pkgid = ? ORDER BY size_type ASC", -1, &stmt, NULL);
455         if (ret != SQLITE_OK) {
456                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
457                 ret = -EIO;
458                 goto out;
459         }
460
461         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
462         if (ret != SQLITE_OK) {
463                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
464                 sqlite3_reset(stmt);
465                 sqlite3_finalize(stmt);
466                 ret = -EIO;
467                 goto out;
468         }
469
470         if (*cnt > NR_OF_SIZE_LIST)
471                 *cnt = NR_OF_SIZE_LIST;
472
473         ret = 0;
474         while (sqlite3_step(stmt) == SQLITE_ROW && ret < *cnt) {
475                 size = sqlite3_column_int(stmt, 0);
476                 types[ret] = size;
477                 ret++;
478         }
479
480         *cnt = ret;
481         sqlite3_reset(stmt);
482         sqlite3_finalize(stmt);
483         ret = 0;
484 out:
485         close_db(handle);
486         return ret;
487 }
488
489 static inline char *cur_locale(void)
490 {
491         char *language;
492         language = vconf_get_str(VCONFKEY_LANGSET);
493         if (language) {
494                 char *ptr;
495
496                 ptr = language;
497                 while (*ptr) {
498                         if (*ptr == '.') {
499                                 *ptr = '\0';
500                                 break;
501                         }
502
503                         if (*ptr == '_')
504                                 *ptr = '-';
505
506                         ptr++;
507                 }
508         } else {
509                 language = strdup("en-us");
510                 if (!language)
511                         ErrPrint("Heap: %s\n", strerror(errno));
512         }
513
514         return language;
515 }
516
517 static inline char *get_default_name(const char *pkgid)
518 {
519         sqlite3_stmt *stmt;
520         sqlite3 *handle;
521         char *name = NULL;
522         int ret;
523
524         handle = open_db();
525         if (!handle)
526                 return NULL;
527
528         ret = sqlite3_prepare_v2(handle, "SELECT name FROM client WHERE pkgid = ?", -1, &stmt, NULL);
529         if (ret != SQLITE_OK) {
530                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
531                 close_db(handle);
532                 return NULL;
533         }
534
535         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
536         if (ret != SQLITE_OK) {
537                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
538                 goto out;
539         }
540
541         ret = sqlite3_step(stmt);
542         if (ret ==  SQLITE_ROW) {
543                 const char *tmp;
544
545                 tmp = (const char *)sqlite3_column_text(stmt, 0);
546                 if (tmp && strlen(tmp)) {
547                         name = strdup(tmp);
548                         if (!name)
549                                 ErrPrint("Heap: %s\n", strerror(errno));
550                 }
551         }
552
553 out:
554         sqlite3_reset(stmt);
555         sqlite3_finalize(stmt);
556         close_db(handle);
557         return name;
558 }
559
560 static inline char *get_default_icon(const char *pkgid)
561 {
562         sqlite3_stmt *stmt;
563         sqlite3 *handle;
564         char *icon = NULL;
565         int ret;
566
567         handle = open_db();
568         if (!handle)
569                 return NULL;
570
571         ret = sqlite3_prepare_v2(handle, "SELECT icon FROM client WHERE pkgid = ?", -1, &stmt, NULL);
572         if (ret != SQLITE_OK) {
573                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
574                 close_db(handle);
575                 return NULL;
576         }
577
578         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
579         if (ret != SQLITE_OK) {
580                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
581                 goto out;
582         }
583
584         ret = sqlite3_step(stmt);
585         if (ret == SQLITE_ROW) {
586                 const char *tmp;
587
588                 tmp = (const char *)sqlite3_column_text(stmt, 0);
589                 if (tmp && strlen(tmp)) {
590                         icon = strdup(tmp);
591                         if (!icon)
592                                 ErrPrint("Heap: %s\n", strerror(errno));
593                 }
594         }
595
596 out:
597         sqlite3_reset(stmt);
598         sqlite3_finalize(stmt);
599         close_db(handle);
600         return icon;
601 }
602
603 EAPI char *livebox_service_content(const char *pkgid)
604 {
605         sqlite3_stmt *stmt;
606         sqlite3 *handle;
607         char *content = NULL;
608         int ret;
609
610         handle = open_db();
611         if (!handle)
612                 return NULL;
613
614         ret = sqlite3_prepare_v2(handle, "SELECT content FROM client WHERE pkgid = ?", -1, &stmt, NULL);
615         if (ret != SQLITE_OK) {
616                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
617                 close_db(handle);
618                 return NULL;
619         }
620
621         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
622         if (ret != SQLITE_OK) {
623                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
624                 goto out;
625         }
626
627         ret = sqlite3_step(stmt);
628         if (ret == SQLITE_ROW) {
629                 const char *tmp;
630
631                 tmp = (const char *)sqlite3_column_text(stmt, 0);
632                 if (tmp && strlen(tmp)) {
633                         content = strdup(tmp);
634                         if (!content)
635                                 ErrPrint("Heap: %s\n", strerror(errno));
636                 }
637         }
638
639 out:
640         sqlite3_reset(stmt);
641         sqlite3_finalize(stmt);
642         close_db(handle);
643         return content;
644 }
645
646 EAPI char *livebox_service_setup_appid(const char *lbid)
647 {
648         sqlite3_stmt *stmt;
649         sqlite3 *handle;
650         int ret;
651         char *appid;
652
653         handle = open_db();
654         if (!handle)
655                 return NULL;
656
657         ret = sqlite3_prepare_v2(handle, "SELECT setup FROM client WHERE pkgid = ?", -1, &stmt, NULL);
658         if (ret != SQLITE_OK) {
659                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
660                 close_db(handle);
661                 return NULL;
662         }
663
664         appid = NULL;
665         ret = sqlite3_bind_text(stmt, 1, lbid, -1, NULL);
666         if (ret != SQLITE_OK) {
667                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
668                 goto out;
669         }
670
671         ret = sqlite3_step(stmt);
672         if (ret == SQLITE_ROW) {
673                 const char *tmp;
674
675                 tmp = (const char *)sqlite3_column_text(stmt, 0);
676                 if (!tmp || !strlen(tmp))
677                         goto out;
678
679                 appid = strdup(tmp);
680                 if (!appid)
681                         ErrPrint("Error: %s\n", strerror(errno));
682         }
683
684 out:
685         sqlite3_reset(stmt);
686         sqlite3_finalize(stmt);
687         close_db(handle);
688         return appid;
689 }
690
691 EAPI int livebox_service_nodisplay(const char *pkgid)
692 {
693         sqlite3_stmt *stmt;
694         sqlite3 *handle;
695         int ret;
696
697         handle = open_db();
698         if (!handle)
699                 return 0;
700
701         ret = sqlite3_prepare_v2(handle, "SELECT nodisplay FROM client WHERE pkgid = ?", -1, &stmt, NULL);
702         if (ret != SQLITE_OK) {
703                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
704                 close_db(handle);
705                 return 0;
706         }
707
708         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
709         if (ret != SQLITE_OK) {
710                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
711                 ret = 0;
712                 goto out;
713         }
714
715         ret = sqlite3_step(stmt);
716         if (ret == SQLITE_ROW) 
717                 ret = !!sqlite3_column_int(stmt, 0);
718         else
719                 ret = 0;
720
721 out:
722         sqlite3_reset(stmt);
723         sqlite3_finalize(stmt);
724         close_db(handle);
725         return ret;
726 }
727
728 EAPI int livebox_service_mouse_event(const char *pkgid)
729 {
730         sqlite3_stmt *stmt;
731         sqlite3 *handle;
732         int ret;
733
734         handle = open_db();
735         if (!handle)
736                 return 0;
737
738         ret = sqlite3_prepare_v2(handle, "SELECT mouse_event FROM client WHERE pkgid = ?", -1, &stmt, NULL);
739         if (ret != SQLITE_OK) {
740                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
741                 close_db(handle);
742                 return 0;
743         }
744
745         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
746         if (ret != SQLITE_OK) {
747                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
748                 ret = 0;
749                 goto out;
750         }
751
752         ret = sqlite3_step(stmt);
753         if (ret == SQLITE_ROW)
754                 ret = !!sqlite3_column_int(stmt, 0);
755         else
756                 ret = 0;
757
758 out:
759         sqlite3_reset(stmt);
760         sqlite3_finalize(stmt);
761         close_db(handle);
762         return ret;
763 }
764
765 EAPI char *livebox_service_preview(const char *pkgid, int size_type)
766 {
767         sqlite3_stmt *stmt;
768         sqlite3 *handle;
769         int ret;
770         char *preview = NULL;
771
772         handle = open_db();
773         if (!handle)
774                 return NULL;
775
776         ret = sqlite3_prepare_v2(handle, "SELECT preview FROM box_size WHERE pkgid = ? AND size_type = ?", -1, &stmt, NULL);
777         if (ret != SQLITE_OK) {
778                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
779                 close_db(handle);
780                 return NULL;
781         }
782
783         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
784         if (ret != SQLITE_OK) {
785                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
786                 goto out;
787         }
788
789         ret = sqlite3_bind_int(stmt, 2, size_type);
790         if (ret != SQLITE_OK) {
791                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
792                 goto out;
793         }
794
795         ret = sqlite3_step(stmt);
796         if (ret == SQLITE_ROW) {
797                 const char *tmp;
798                 tmp = (const char *)sqlite3_column_text(stmt, 0);
799                 if (tmp && strlen(tmp)) {
800                         preview = strdup(tmp);
801                         if (!preview)
802                                 ErrPrint("Heap: %s\n", strerror(errno));
803                 }
804         }
805
806 out:
807         sqlite3_reset(stmt);
808         sqlite3_finalize(stmt);
809         close_db(handle);
810         return preview;
811 }
812
813 EAPI char *livebox_service_i18n_icon(const char *pkgid, const char *lang)
814 {
815         sqlite3_stmt *stmt;
816         sqlite3 *handle;
817         char *language;
818         char *icon = NULL;
819         int ret;
820
821         if (lang) {
822                 language = strdup(lang);
823                 if (!language) {
824                         ErrPrint("Heap: %s\n", strerror(errno));
825                         return NULL;
826                 }
827         } else {
828                 language = cur_locale();
829                 if (!language)
830                         return NULL;
831         }
832
833         handle = open_db();
834         if (!handle) {
835                 free(language);
836                 return NULL;
837         }
838
839         ret = sqlite3_prepare_v2(handle, "SELECT icon FROM i18n WHERE pkgid = ? AND lang = ?", -1, &stmt, NULL);
840         if (ret != SQLITE_OK) {
841                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
842                 close_db(handle);
843                 free(language);
844                 return NULL;
845         }
846
847         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
848         if (ret != SQLITE_OK) {
849                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
850                 goto out;
851         }
852
853         ret = sqlite3_bind_text(stmt, 2, language, -1, NULL);
854         if (ret != SQLITE_OK) {
855                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
856                 goto out;
857         }
858
859         ret = sqlite3_step(stmt);
860         if (ret == SQLITE_ROW) {
861                 const char *tmp;
862                 tmp = (const char *)sqlite3_column_text(stmt, 0);
863                 if (!tmp || !strlen(tmp)) {
864                         icon = get_default_icon(pkgid);
865                 } else {
866                         icon = strdup(tmp);
867                         if (!icon)
868                                 ErrPrint("Heap: %s\n", strerror(errno));
869                 }
870         } else {
871                 icon = get_default_icon(pkgid);
872         }
873
874 out:
875         sqlite3_reset(stmt);
876         sqlite3_finalize(stmt);
877         close_db(handle);
878         free(language);
879         return icon;
880 }
881
882 EAPI char *livebox_service_i18n_name(const char *pkgid, const char *lang)
883 {
884         sqlite3_stmt *stmt;
885         sqlite3 *handle;
886         char *language;
887         char *name = NULL;
888         int ret;
889
890         if (lang) {
891                 language = strdup(lang);
892                 if (!language) {
893                         ErrPrint("Error: %s\n", strerror(errno));
894                         return NULL;
895                 }
896         } else {
897                 language = cur_locale();
898                 if (!language)
899                         return NULL;
900         }
901
902         handle = open_db();
903         if (!handle) {
904                 free(language);
905                 return NULL;
906         }
907
908         ret = sqlite3_prepare_v2(handle, "SELECT name FROM i18n WHERE pkgid = ? AND lang = ?", -1, &stmt, NULL);
909         if (ret != SQLITE_OK) {
910                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
911                 close_db(handle);
912                 free(language);
913                 return NULL;
914         }
915
916         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
917         if (ret != SQLITE_OK) {
918                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
919                 goto out;
920         }
921
922         ret = sqlite3_bind_text(stmt, 2, language, -1, NULL);
923         if (ret != SQLITE_OK) {
924                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
925                 goto out;
926         }
927
928         ret = sqlite3_step(stmt);
929         if (ret == SQLITE_ROW) {
930                 const char *tmp;
931                 tmp = (const char *)sqlite3_column_text(stmt, 0);
932                 if (!tmp || !strlen(tmp)) {
933                         name = get_default_name(pkgid);
934                 } else {
935                         name = strdup(tmp);
936                         if (!name)
937                                 ErrPrint("Heap: %s\n", strerror(errno));
938                 }
939         } else {
940                 name = get_default_name(pkgid);
941         }
942
943 out:
944         sqlite3_reset(stmt);
945         sqlite3_finalize(stmt);
946         close_db(handle);
947         free(language);
948         return name;
949 }
950
951 EAPI int livebox_service_get_supported_sizes(const char *pkgid, int *cnt, int *w, int *h)
952 {
953         sqlite3_stmt *stmt;
954         sqlite3 *handle;
955         int size;
956         int ret;
957
958         if (!w || !h || !cnt || !pkgid)
959                 return -EINVAL;
960
961         handle = open_db();
962         if (!handle)
963                 return -EIO;
964
965         ret = sqlite3_prepare_v2(handle, "SELECT size_type FROM box_size WHERE pkgid = ? ORDER BY size_type ASC", -1, &stmt, NULL);
966         if (ret != SQLITE_OK) {
967                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
968                 ret = -EIO;
969                 goto out;
970         }
971
972         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
973         if (ret != SQLITE_OK) {
974                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
975                 sqlite3_reset(stmt);
976                 sqlite3_finalize(stmt);
977                 ret = -EIO;
978                 goto out;
979         }
980
981         if (*cnt > NR_OF_SIZE_LIST)
982                 *cnt = NR_OF_SIZE_LIST;
983
984         ret = 0;
985         while (sqlite3_step(stmt) == SQLITE_ROW && ret < *cnt) {
986                 size = sqlite3_column_int(stmt, 0);
987                 ret += (convert_size_from_type(size, w + ret, h + ret) == 0);
988         }
989
990         *cnt = ret;
991         sqlite3_reset(stmt);
992         sqlite3_finalize(stmt);
993         ret = 0;
994 out:
995         close_db(handle);
996         return ret;
997 }
998
999 EAPI char *livebox_service_libexec(const char *pkgid)
1000 {
1001         sqlite3_stmt *stmt;
1002         sqlite3 *handle;
1003         int ret;
1004         char *libexec;
1005         char *appid;
1006         char *path;
1007
1008         if (!pkgid)
1009                 return NULL;
1010
1011         libexec = NULL;
1012         handle = open_db();
1013         if (!handle)
1014                 return NULL;
1015
1016         ret = sqlite3_prepare_v2(handle, "SELECT pkgmap.appid, provider.libexec FROM pkgmap, provider WHERE pkgmap.pkgid = ? AND provider.pkgid = ?", -1, &stmt, NULL);
1017         if (ret != SQLITE_OK) {
1018                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1019                 goto out;
1020         }
1021
1022         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1023         if (ret != SQLITE_OK) {
1024                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1025                 sqlite3_finalize(stmt);
1026                 goto out;
1027         }
1028
1029         ret = sqlite3_bind_text(stmt, 2, pkgid, -1, NULL);
1030         if (ret != SQLITE_OK) {
1031                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1032                 sqlite3_finalize(stmt);
1033                 goto out;
1034         }
1035
1036         if (sqlite3_step(stmt) != SQLITE_ROW) {
1037                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1038                 sqlite3_reset(stmt);
1039                 sqlite3_finalize(stmt);
1040
1041                 libexec = util_conf_get_libexec(pkgid);
1042                 DbgPrint("Fallback to conf checker: %s\n", libexec);
1043                 goto out;
1044         }
1045
1046         appid = (char *)sqlite3_column_text(stmt, 0);
1047         if (!appid || !strlen(appid)) {
1048                 ErrPrint("Invalid appid: %s\n", sqlite3_errmsg(handle));
1049                 sqlite3_reset(stmt);
1050                 sqlite3_finalize(stmt);
1051                 goto out;
1052         }
1053
1054         path = (char *)sqlite3_column_text(stmt, 1);
1055         if (!path || !strlen(path)) {
1056                 ErrPrint("Invalid libexec: %s\n", sqlite3_errmsg(handle));
1057                 sqlite3_reset(stmt);
1058                 sqlite3_finalize(stmt);
1059                 goto out;
1060         }
1061
1062         libexec = strdup(path);
1063         if (!libexec) {
1064                 ErrPrint("Heap: %s\n", strerror(errno));
1065                 sqlite3_reset(stmt);
1066                 sqlite3_finalize(stmt);
1067                 goto out;
1068         }
1069
1070         DbgPrint("libexec: %s\n", libexec);
1071
1072         sqlite3_reset(stmt);
1073         sqlite3_finalize(stmt);
1074 out:
1075         close_db(handle);
1076         return libexec;
1077 }
1078
1079 static inline char *get_lb_pkgname_by_appid(const char *appid)
1080 {
1081         sqlite3_stmt *stmt;
1082         char *pkgid;
1083         char *tmp;
1084         sqlite3 *handle;
1085         int ret;
1086
1087         if (!appid)
1088                 return NULL;
1089
1090         pkgid = NULL;
1091         handle = open_db();
1092         if (!handle)
1093                 return NULL;
1094
1095         ret = sqlite3_prepare_v2(handle, "SELECT pkgid FROM pkgmap WHERE (appid = ? AND prime = 1) OR pkgid = ?", -1, &stmt, NULL);
1096         if (ret != SQLITE_OK) {
1097                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1098                 close_db(handle);
1099                 return NULL;
1100         }
1101
1102         ret = sqlite3_bind_text(stmt, 1, appid, -1, NULL);
1103         if (ret != SQLITE_OK) {
1104                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1105                 goto out;
1106         }
1107
1108         ret = sqlite3_bind_text(stmt, 2, appid, -1, NULL);
1109         if (ret != SQLITE_OK) {
1110                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1111                 goto out;
1112         }
1113
1114         if (sqlite3_step(stmt) != SQLITE_ROW) {
1115                 ErrPrint("Error: %s (has no record? - %s)\n", sqlite3_errmsg(handle), appid);
1116                 goto out;
1117         }
1118
1119         tmp = (char *)sqlite3_column_text(stmt, 0);
1120         if (tmp && strlen(tmp)) {
1121                 pkgid = strdup(tmp);
1122                 if (!pkgid)
1123                         ErrPrint("Heap: %s\n", strerror(errno));
1124         }
1125
1126 out:
1127         sqlite3_reset(stmt);
1128         sqlite3_finalize(stmt);
1129         close_db(handle);
1130         return pkgid;
1131 }
1132
1133 EAPI char *livebox_service_pkgname(const char *appid)
1134 {
1135         char *lb_pkgname;
1136         pkgmgr_appinfo_h handle;
1137         int ret;
1138         char *new_appid;
1139
1140         if (!appid)
1141                 return NULL;
1142
1143         lb_pkgname = get_lb_pkgname_by_appid(appid);
1144         if (lb_pkgname)
1145                 return lb_pkgname;
1146
1147         /*!
1148          * \note
1149          * Try to get the package id using given appid
1150          */
1151         ret = pkgmgr_appinfo_get_appinfo(appid, &handle);
1152         if (ret != PKGMGR_R_OK) {
1153                 ErrPrint("Failed to get appinfo\n");
1154                 return NULL;
1155         }
1156
1157         ret = pkgmgr_appinfo_get_pkgname(handle, &new_appid);
1158         if (ret != PKGMGR_R_OK) {
1159                 pkgmgr_appinfo_destroy_appinfo(handle);
1160                 ErrPrint("Failed to get pkgname for (%s)\n", appid);
1161                 return NULL;
1162         }
1163
1164         lb_pkgname = get_lb_pkgname_by_appid(new_appid);
1165         pkgmgr_appinfo_destroy_appinfo(handle);
1166
1167         if (!lb_pkgname && util_validate_livebox_package(appid) == 0)
1168                 return strdup(appid);
1169
1170         return lb_pkgname;
1171 }
1172
1173 EAPI char *livebox_service_provider_name(const char *lbid)
1174 {
1175         char *ret;
1176
1177         if (!lbid)
1178                 return NULL;
1179
1180         ret = strdup(lbid);
1181         if (!ret) {
1182                 ErrPrint("Error: %s\n", strerror(errno));
1183                 return NULL;
1184         }
1185
1186         return ret;
1187 }
1188
1189 EAPI char *livebox_service_appid(const char *pkgname)
1190 {
1191         sqlite3_stmt *stmt;
1192         char *appid;
1193         char *tmp;
1194         sqlite3 *handle;
1195         int is_prime __attribute__((__unused__));
1196         int ret;
1197
1198         if (!pkgname)
1199                 return NULL;
1200
1201         appid = NULL;
1202         handle = open_db();
1203         if (!handle)
1204                 return NULL;
1205
1206         ret = sqlite3_prepare_v2(handle, "SELECT appid, prime FROM pkgmap WHERE pkgid = ? OR appid = ?", -1, &stmt, NULL);
1207         if (ret != SQLITE_OK) {
1208                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1209                 goto out;
1210         }
1211
1212         ret = sqlite3_bind_text(stmt, 1, pkgname, -1, NULL);
1213         if (ret != SQLITE_OK) {
1214                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1215                 sqlite3_reset(stmt);
1216                 sqlite3_finalize(stmt);
1217                 goto out;
1218         }
1219
1220         ret = sqlite3_bind_text(stmt, 2, pkgname, -1, NULL);
1221         if (ret != SQLITE_OK) {
1222                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1223                 sqlite3_reset(stmt);
1224                 sqlite3_finalize(stmt);
1225                 goto out;
1226         }
1227
1228         ret = sqlite3_step(stmt);
1229         if (ret != SQLITE_ROW) {
1230                 pkgmgr_appinfo_h pkg_handle;
1231                 char *new_appid;
1232
1233                 ErrPrint("Has no record?: %s\n", sqlite3_errmsg(handle));
1234                 sqlite3_reset(stmt);
1235                 sqlite3_finalize(stmt);
1236
1237                 ret = pkgmgr_appinfo_get_appinfo(pkgname, &pkg_handle);
1238                 if (ret != PKGMGR_R_OK) {
1239                         ErrPrint("Failed to get appinfo: %s\n", pkgname);
1240                         goto out;
1241                 }
1242
1243                 ret = pkgmgr_appinfo_get_pkgname(pkg_handle, &new_appid);
1244                 if (ret != PKGMGR_R_OK) {
1245                         ErrPrint("Failed to get pkgname for (%s)\n", appid);
1246                         pkgmgr_appinfo_destroy_appinfo(pkg_handle);
1247                         goto out;
1248                 }
1249
1250                 appid = strdup(new_appid);
1251                 if (!appid)
1252                         ErrPrint("Heap: %s\n", strerror(errno));
1253
1254                 pkgmgr_appinfo_destroy_appinfo(pkg_handle);
1255                 goto out;
1256         }
1257
1258         tmp = (char *)sqlite3_column_text(stmt, 0);
1259         if (!tmp || !strlen(tmp)) {
1260                 ErrPrint("APPID is NIL\n");
1261                 sqlite3_reset(stmt);
1262                 sqlite3_finalize(stmt);
1263                 goto out;
1264         }
1265
1266         appid = strdup(tmp);
1267         if (!appid) {
1268                 ErrPrint("Heap: %s\n", strerror(errno));
1269                 sqlite3_reset(stmt);
1270                 sqlite3_finalize(stmt);
1271                 goto out;
1272         }
1273
1274         is_prime = sqlite3_column_int(stmt, 1);
1275
1276         sqlite3_reset(stmt);
1277         sqlite3_finalize(stmt);
1278 out:
1279         close_db(handle);
1280         return appid;
1281 }
1282
1283 EAPI char *livebox_service_lb_script_path(const char *pkgid)
1284 {
1285         sqlite3_stmt *stmt;
1286         sqlite3 *handle;
1287         int ret;
1288         char *path;
1289         char *appid;
1290         char *lb_src;
1291
1292         if (!pkgid)
1293                 return NULL;
1294
1295         path = NULL;
1296         handle = open_db();
1297         if (!handle)
1298                 return NULL;
1299
1300         ret = sqlite3_prepare_v2(handle, "SELECT pkgmap.appid, provider.box_src FROM provider, pkgmap WHERE pkgmap.pkgid = ? AND provider.pkgid = ?", -1, &stmt, NULL);
1301         if (ret != SQLITE_OK) {
1302                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1303                 goto out;
1304         }
1305
1306         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1307         if (ret != SQLITE_OK) {
1308                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1309                 sqlite3_finalize(stmt);
1310                 goto out;
1311         }
1312
1313         ret = sqlite3_bind_text(stmt, 2, pkgid, -1, NULL);
1314         if (ret != SQLITE_OK) {
1315                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1316                 sqlite3_finalize(stmt);
1317                 goto out;
1318         }
1319
1320         ret = sqlite3_step(stmt);
1321         if (ret != SQLITE_ROW) {
1322                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1323                 sqlite3_reset(stmt);
1324                 sqlite3_finalize(stmt);
1325                 goto out;
1326         }
1327
1328         appid = (char *)sqlite3_column_text(stmt, 0);
1329         if (!appid || !strlen(appid)) {
1330                 ErrPrint("Invalid appid : %s\n", sqlite3_errmsg(handle));
1331                 sqlite3_reset(stmt);
1332                 sqlite3_finalize(stmt);
1333                 goto out;
1334         }
1335
1336         lb_src = (char *)sqlite3_column_text(stmt, 1);
1337         if (!lb_src || !strlen(lb_src)) {
1338                 ErrPrint("No records for lb src : %s\n", sqlite3_errmsg(handle));
1339                 sqlite3_reset(stmt);
1340                 sqlite3_finalize(stmt);
1341                 goto out;
1342         }
1343
1344         path = strdup(lb_src);
1345         if (!path) {
1346                 ErrPrint("Heap: %s\n", strerror(errno));
1347                 sqlite3_reset(stmt);
1348                 sqlite3_finalize(stmt);
1349                 goto out;
1350         }
1351
1352         DbgPrint("LB Src: %s\n", path);
1353
1354         sqlite3_reset(stmt);
1355         sqlite3_finalize(stmt);
1356 out:
1357         close_db(handle);
1358         return path;
1359 }
1360
1361 EAPI char *livebox_service_lb_script_group(const char *pkgid)
1362 {
1363         sqlite3_stmt *stmt;
1364         sqlite3 *handle;
1365         int ret;
1366         char *group;
1367         char *tmp;
1368
1369         if (!pkgid)
1370                 return NULL;
1371
1372         group = NULL;
1373         handle = open_db();
1374         if (!handle)
1375                 return NULL;
1376
1377         ret = sqlite3_prepare_v2(handle, "SELECT box_group FROM provider WHERE pkgid = ?", -1, &stmt, NULL);
1378         if (ret != SQLITE_OK) {
1379                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1380                 goto out;
1381         }
1382
1383         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1384         if (ret != SQLITE_OK) {
1385                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1386                 sqlite3_finalize(stmt);
1387                 goto out;
1388         }
1389
1390         ret = sqlite3_step(stmt);
1391         if (ret != SQLITE_ROW) {
1392                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1393                 sqlite3_reset(stmt);
1394                 sqlite3_finalize(stmt);
1395                 goto out;
1396         }
1397
1398         tmp = (char *)sqlite3_column_text(stmt, 0);
1399         if (tmp && strlen(tmp)) {
1400                 group = strdup(tmp);
1401                 if (!group)
1402                         ErrPrint("Heap: %s\n", strerror(errno));
1403         }
1404
1405         sqlite3_reset(stmt);
1406         sqlite3_finalize(stmt);
1407 out:
1408         close_db(handle);
1409         return group;
1410 }
1411
1412 EAPI char *livebox_service_pd_script_path(const char *pkgid)
1413 {
1414         sqlite3_stmt *stmt;
1415         sqlite3 *handle;
1416         int ret;
1417         char *path;
1418         char *pd_src;
1419         const char *appid;
1420
1421         if (!pkgid)
1422                 return NULL;
1423
1424         path = NULL;
1425         handle = open_db();
1426         if (!handle)
1427                 return NULL;
1428
1429         ret = sqlite3_prepare_v2(handle, "SELECT pkgmap.appid, provider.pd_src FROM provider, pkgmap WHERE provider.pkgid = ? AND pkgmap.pkgid = ?", -1, &stmt, NULL);
1430         if (ret != SQLITE_OK) {
1431                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1432                 goto out;
1433         }
1434
1435         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1436         if (ret != SQLITE_OK) {
1437                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1438                 sqlite3_finalize(stmt);
1439                 goto out;
1440         }
1441
1442         ret = sqlite3_bind_text(stmt, 2, pkgid, -1, NULL);
1443         if (ret != SQLITE_OK) {
1444                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1445                 sqlite3_finalize(stmt);
1446                 goto out;
1447         }
1448
1449         ret = sqlite3_step(stmt);
1450         if (ret != SQLITE_ROW) {
1451                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1452                 sqlite3_reset(stmt);
1453                 sqlite3_finalize(stmt);
1454                 goto out;
1455         }
1456
1457         appid = (char *)sqlite3_column_text(stmt, 0);
1458         if (!appid || !strlen(appid)) {
1459                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1460                 sqlite3_reset(stmt);
1461                 sqlite3_finalize(stmt);
1462                 goto out;
1463         }
1464
1465         pd_src = (char *)sqlite3_column_text(stmt, 1);
1466         if (!pd_src || !strlen(pd_src)) {
1467                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1468                 sqlite3_reset(stmt);
1469                 sqlite3_finalize(stmt);
1470                 goto out;
1471         }
1472
1473         path = strdup(pd_src);
1474         if (!path) {
1475                 ErrPrint("Heap: %s\n", strerror(errno));
1476                 sqlite3_reset(stmt);
1477                 sqlite3_finalize(stmt);
1478                 goto out;
1479         }
1480
1481         DbgPrint("PD Src: %s\n", path);
1482         sqlite3_reset(stmt);
1483         sqlite3_finalize(stmt);
1484 out:
1485         close_db(handle);
1486         return path;
1487 }
1488
1489 EAPI char *livebox_service_pd_script_group(const char *pkgid)
1490 {
1491         sqlite3_stmt *stmt;
1492         sqlite3 *handle;
1493         int ret;
1494         char *group;
1495         char *tmp;
1496
1497         if (!pkgid)
1498                 return NULL;
1499
1500         group = NULL;
1501         handle = open_db();
1502         if (!handle)
1503                 return NULL;
1504
1505         ret = sqlite3_prepare_v2(handle, "SELECT pd_group FROM provider WHERE pkgid = ?", -1, &stmt, NULL);
1506         if (ret != SQLITE_OK) {
1507                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1508                 goto out;
1509         }
1510
1511         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1512         if (ret != SQLITE_OK) {
1513                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1514                 sqlite3_finalize(stmt);
1515                 goto out;
1516         }
1517
1518         ret = sqlite3_step(stmt);
1519         if (ret != SQLITE_ROW) {
1520                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1521                 sqlite3_reset(stmt);
1522                 sqlite3_finalize(stmt);
1523                 goto out;
1524         }
1525
1526         tmp = (char *)sqlite3_column_text(stmt, 0);
1527         if (tmp && strlen(tmp)) {
1528                 group = strdup(tmp);
1529                 if (!group)
1530                         ErrPrint("Heap: %s\n", strerror(errno));
1531         }
1532         sqlite3_reset(stmt);
1533         sqlite3_finalize(stmt);
1534 out:
1535         close_db(handle);
1536         return group;
1537 }
1538
1539 EAPI int livebox_service_enumerate_cluster_list(int (*cb)(const char *cluster, void *data), void *data)
1540 {
1541         sqlite3_stmt *stmt;
1542         sqlite3 *handle;
1543         const char *cluster;
1544         int cnt;
1545         int ret;
1546
1547         if (!cb)
1548                 return -EINVAL;
1549
1550         handle = open_db();
1551         if (!handle)
1552                 return -EIO;
1553
1554         cnt = 0;
1555         ret = sqlite3_prepare_v2(handle, "SELECT DISTINCT cluster FROM groupinfo", -1, &stmt, NULL);
1556         if (ret != SQLITE_OK) {
1557                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1558                 cnt = -EIO;
1559                 goto out;
1560         }
1561
1562         while (sqlite3_step(stmt) == SQLITE_ROW) {
1563                 cluster = (const char *)sqlite3_column_text(stmt, 0);
1564                 if (!cluster || !strlen(cluster))
1565                         continue;
1566
1567                 if (cb(cluster, data) < 0)
1568                         break;
1569
1570                 cnt++;
1571         }
1572
1573         sqlite3_reset(stmt);
1574         sqlite3_finalize(stmt);
1575 out:
1576         close_db(handle);
1577         return cnt;
1578 }
1579
1580 EAPI int livebox_service_enumerate_category_list(const char *cluster, int (*cb)(const char *cluster, const char *category, void *data), void *data)
1581 {
1582         sqlite3_stmt *stmt;
1583         sqlite3 *handle;
1584         const char *category;
1585         int cnt;
1586         int ret;
1587
1588         if (!cluster || !cb)
1589                 return -EINVAL;
1590
1591         handle = open_db();
1592         if (!handle)
1593                 return -EIO;
1594
1595         ret = sqlite3_prepare_v2(handle, "SELECT DISTINCT category FROM groupinfo WHERE cluster = ?", -1, &stmt, NULL);
1596         if (ret != SQLITE_OK) {
1597                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1598                 cnt = -EIO;
1599                 goto out;
1600         }
1601
1602         cnt = 0;
1603         while (sqlite3_step(stmt) == SQLITE_ROW) {
1604                 category = (const char *)sqlite3_column_text(stmt, 0);
1605                 if (!category || !strlen(category))
1606                         continue;
1607
1608                 if (cb(cluster, category, data) < 0)
1609                         break;
1610
1611                 cnt++;
1612         }
1613
1614         sqlite3_reset(stmt);
1615         sqlite3_finalize(stmt);
1616 out:
1617         close_db(handle);
1618         return cnt;
1619 }
1620
1621 EAPI int livebox_service_init(void)
1622 {
1623         if (s_info.handle) {
1624                 DbgPrint("Already initialized\n");
1625                 s_info.init_count++;
1626                 return 0;
1627         }
1628
1629         s_info.handle = open_db();
1630         if (s_info.handle) {
1631                 s_info.init_count++;
1632                 return 0;
1633         }
1634
1635         return -EIO;
1636 }
1637
1638 EAPI int livebox_service_fini(void)
1639 {
1640         if (!s_info.handle || s_info.init_count <= 0) {
1641                 ErrPrint("Service is not initialized\n");
1642                 return -EIO;
1643         }
1644
1645         s_info.init_count--;
1646         if (s_info.init_count > 0) {
1647                 DbgPrint("Init count %d\n", s_info.init_count);
1648                 return 0;
1649         }
1650
1651         db_util_close(s_info.handle);
1652         s_info.handle = NULL;
1653         return 0;
1654 }
1655
1656 EAPI int livebox_service_get_size(int type, int *width, int *height)
1657 {
1658         int _width;
1659         int _height;
1660
1661         if (!width)
1662                 width = &_width;
1663
1664         if (!height)
1665                 height = &_height;
1666
1667         return convert_size_from_type(type, width, height);
1668 }
1669
1670 EAPI int livebox_service_size_type(int width, int height)
1671 {
1672         int idx;
1673
1674         if (update_resolution() < 0)
1675                 ErrPrint("Failed to update the size list\n");
1676
1677         for (idx = 0; idx < NR_OF_SIZE_LIST; idx++) {
1678                 if (SIZE_LIST[idx].w == width && SIZE_LIST[idx].h == height)
1679                         break;
1680         }
1681
1682         switch (idx) {
1683         case 0:
1684                 return LB_SIZE_TYPE_1x1;
1685         case 1:
1686                 return LB_SIZE_TYPE_2x1;
1687         case 2:
1688                 return LB_SIZE_TYPE_2x2;
1689         case 3:
1690                 return LB_SIZE_TYPE_4x1;
1691         case 4:
1692                 return LB_SIZE_TYPE_4x2;
1693         case 5:
1694                 return LB_SIZE_TYPE_4x3;
1695         case 6:
1696                 return LB_SIZE_TYPE_4x4;
1697         default:
1698                 break;
1699         }
1700
1701         return LB_SIZE_TYPE_UNKNOWN;
1702 }
1703
1704 /* End of a file */