Initialize the project.
[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 char *livebox_service_preview(const char *pkgid, int size_type)
729 {
730         sqlite3_stmt *stmt;
731         sqlite3 *handle;
732         int ret;
733         char *preview = NULL;
734
735         handle = open_db();
736         if (!handle)
737                 return NULL;
738
739         ret = sqlite3_prepare_v2(handle, "SELECT preview FROM box_size WHERE pkgid = ? AND size_type = ?", -1, &stmt, NULL);
740         if (ret != SQLITE_OK) {
741                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
742                 close_db(handle);
743                 return NULL;
744         }
745
746         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
747         if (ret != SQLITE_OK) {
748                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
749                 goto out;
750         }
751
752         ret = sqlite3_bind_int(stmt, 2, size_type);
753         if (ret != SQLITE_OK) {
754                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
755                 goto out;
756         }
757
758         ret = sqlite3_step(stmt);
759         if (ret == SQLITE_ROW) {
760                 const char *tmp;
761                 tmp = (const char *)sqlite3_column_text(stmt, 0);
762                 if (tmp && strlen(tmp)) {
763                         preview = strdup(tmp);
764                         if (!preview)
765                                 ErrPrint("Heap: %s\n", strerror(errno));
766                 }
767         }
768
769 out:
770         sqlite3_reset(stmt);
771         sqlite3_finalize(stmt);
772         close_db(handle);
773         return preview;
774 }
775
776 EAPI char *livebox_service_i18n_icon(const char *pkgid, const char *lang)
777 {
778         sqlite3_stmt *stmt;
779         sqlite3 *handle;
780         char *language;
781         char *icon = NULL;
782         int ret;
783
784         if (lang) {
785                 language = strdup(lang);
786                 if (!language) {
787                         ErrPrint("Heap: %s\n", strerror(errno));
788                         return NULL;
789                 }
790         } else {
791                 language = cur_locale();
792                 if (!language)
793                         return NULL;
794         }
795
796         handle = open_db();
797         if (!handle) {
798                 free(language);
799                 return NULL;
800         }
801
802         ret = sqlite3_prepare_v2(handle, "SELECT icon FROM i18n WHERE pkgid = ? AND lang = ?", -1, &stmt, NULL);
803         if (ret != SQLITE_OK) {
804                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
805                 close_db(handle);
806                 free(language);
807                 return NULL;
808         }
809
810         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
811         if (ret != SQLITE_OK) {
812                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
813                 goto out;
814         }
815
816         ret = sqlite3_bind_text(stmt, 2, language, -1, NULL);
817         if (ret != SQLITE_OK) {
818                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
819                 goto out;
820         }
821
822         ret = sqlite3_step(stmt);
823         if (ret == SQLITE_ROW) {
824                 const char *tmp;
825                 tmp = (const char *)sqlite3_column_text(stmt, 0);
826                 if (!tmp || !strlen(tmp)) {
827                         icon = get_default_icon(pkgid);
828                 } else {
829                         icon = strdup(tmp);
830                         if (!icon)
831                                 ErrPrint("Heap: %s\n", strerror(errno));
832                 }
833         } else {
834                 icon = get_default_icon(pkgid);
835         }
836
837 out:
838         sqlite3_reset(stmt);
839         sqlite3_finalize(stmt);
840         close_db(handle);
841         free(language);
842         return icon;
843 }
844
845 EAPI char *livebox_service_i18n_name(const char *pkgid, const char *lang)
846 {
847         sqlite3_stmt *stmt;
848         sqlite3 *handle;
849         char *language;
850         char *name = NULL;
851         int ret;
852
853         if (lang) {
854                 language = strdup(lang);
855                 if (!language) {
856                         ErrPrint("Error: %s\n", strerror(errno));
857                         return NULL;
858                 }
859         } else {
860                 language = cur_locale();
861                 if (!language)
862                         return NULL;
863         }
864
865         handle = open_db();
866         if (!handle) {
867                 free(language);
868                 return NULL;
869         }
870
871         ret = sqlite3_prepare_v2(handle, "SELECT name FROM i18n WHERE pkgid = ? AND lang = ?", -1, &stmt, NULL);
872         if (ret != SQLITE_OK) {
873                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
874                 close_db(handle);
875                 free(language);
876                 return NULL;
877         }
878
879         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
880         if (ret != SQLITE_OK) {
881                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
882                 goto out;
883         }
884
885         ret = sqlite3_bind_text(stmt, 2, language, -1, NULL);
886         if (ret != SQLITE_OK) {
887                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
888                 goto out;
889         }
890
891         ret = sqlite3_step(stmt);
892         if (ret == SQLITE_ROW) {
893                 const char *tmp;
894                 tmp = (const char *)sqlite3_column_text(stmt, 0);
895                 if (!tmp || !strlen(tmp)) {
896                         name = get_default_name(pkgid);
897                 } else {
898                         name = strdup(tmp);
899                         if (!name)
900                                 ErrPrint("Heap: %s\n", strerror(errno));
901                 }
902         } else {
903                 name = get_default_name(pkgid);
904         }
905
906 out:
907         sqlite3_reset(stmt);
908         sqlite3_finalize(stmt);
909         close_db(handle);
910         free(language);
911         return name;
912 }
913
914 EAPI int livebox_service_get_supported_sizes(const char *pkgid, int *cnt, int *w, int *h)
915 {
916         sqlite3_stmt *stmt;
917         sqlite3 *handle;
918         int size;
919         int ret;
920
921         if (!w || !h || !cnt || !pkgid)
922                 return -EINVAL;
923
924         handle = open_db();
925         if (!handle)
926                 return -EIO;
927
928         ret = sqlite3_prepare_v2(handle, "SELECT size_type FROM box_size WHERE pkgid = ? ORDER BY size_type ASC", -1, &stmt, NULL);
929         if (ret != SQLITE_OK) {
930                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
931                 ret = -EIO;
932                 goto out;
933         }
934
935         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
936         if (ret != SQLITE_OK) {
937                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
938                 sqlite3_reset(stmt);
939                 sqlite3_finalize(stmt);
940                 ret = -EIO;
941                 goto out;
942         }
943
944         if (*cnt > NR_OF_SIZE_LIST)
945                 *cnt = NR_OF_SIZE_LIST;
946
947         ret = 0;
948         while (sqlite3_step(stmt) == SQLITE_ROW && ret < *cnt) {
949                 size = sqlite3_column_int(stmt, 0);
950                 ret += (convert_size_from_type(size, w + ret, h + ret) == 0);
951         }
952
953         *cnt = ret;
954         sqlite3_reset(stmt);
955         sqlite3_finalize(stmt);
956         ret = 0;
957 out:
958         close_db(handle);
959         return ret;
960 }
961
962 EAPI char *livebox_service_libexec(const char *pkgid)
963 {
964         sqlite3_stmt *stmt;
965         sqlite3 *handle;
966         int ret;
967         char *libexec;
968         char *appid;
969         char *path;
970
971         if (!pkgid)
972                 return NULL;
973
974         libexec = NULL;
975         handle = open_db();
976         if (!handle)
977                 return NULL;
978
979         ret = sqlite3_prepare_v2(handle, "SELECT pkgmap.appid, provider.libexec FROM pkgmap, provider WHERE pkgmap.pkgid = ? AND provider.pkgid = ?", -1, &stmt, NULL);
980         if (ret != SQLITE_OK) {
981                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
982                 goto out;
983         }
984
985         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
986         if (ret != SQLITE_OK) {
987                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
988                 sqlite3_finalize(stmt);
989                 goto out;
990         }
991
992         ret = sqlite3_bind_text(stmt, 2, pkgid, -1, NULL);
993         if (ret != SQLITE_OK) {
994                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
995                 sqlite3_finalize(stmt);
996                 goto out;
997         }
998
999         if (sqlite3_step(stmt) != SQLITE_ROW) {
1000                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1001                 sqlite3_reset(stmt);
1002                 sqlite3_finalize(stmt);
1003
1004                 libexec = util_conf_get_libexec(pkgid);
1005                 DbgPrint("Fallback to conf checker: %s\n", libexec);
1006                 goto out;
1007         }
1008
1009         appid = (char *)sqlite3_column_text(stmt, 0);
1010         if (!appid || !strlen(appid)) {
1011                 ErrPrint("Invalid appid: %s\n", sqlite3_errmsg(handle));
1012                 sqlite3_reset(stmt);
1013                 sqlite3_finalize(stmt);
1014                 goto out;
1015         }
1016
1017         path = (char *)sqlite3_column_text(stmt, 1);
1018         if (!path || !strlen(path)) {
1019                 ErrPrint("Invalid libexec: %s\n", sqlite3_errmsg(handle));
1020                 sqlite3_reset(stmt);
1021                 sqlite3_finalize(stmt);
1022                 goto out;
1023         }
1024
1025         libexec = strdup(path);
1026         if (!libexec) {
1027                 ErrPrint("Heap: %s\n", strerror(errno));
1028                 sqlite3_reset(stmt);
1029                 sqlite3_finalize(stmt);
1030                 goto out;
1031         }
1032
1033         DbgPrint("libexec: %s\n", libexec);
1034
1035         sqlite3_reset(stmt);
1036         sqlite3_finalize(stmt);
1037 out:
1038         close_db(handle);
1039         return libexec;
1040 }
1041
1042 static inline char *get_lb_pkgname_by_appid(const char *appid)
1043 {
1044         sqlite3_stmt *stmt;
1045         char *pkgid;
1046         char *tmp;
1047         sqlite3 *handle;
1048         int ret;
1049
1050         if (!appid)
1051                 return NULL;
1052
1053         pkgid = NULL;
1054         handle = open_db();
1055         if (!handle)
1056                 return NULL;
1057
1058         ret = sqlite3_prepare_v2(handle, "SELECT pkgid FROM pkgmap WHERE (appid = ? AND prime = 1) OR pkgid = ?", -1, &stmt, NULL);
1059         if (ret != SQLITE_OK) {
1060                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1061                 close_db(handle);
1062                 return NULL;
1063         }
1064
1065         ret = sqlite3_bind_text(stmt, 1, appid, -1, NULL);
1066         if (ret != SQLITE_OK) {
1067                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1068                 goto out;
1069         }
1070
1071         ret = sqlite3_bind_text(stmt, 2, appid, -1, NULL);
1072         if (ret != SQLITE_OK) {
1073                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1074                 goto out;
1075         }
1076
1077         if (sqlite3_step(stmt) != SQLITE_ROW) {
1078                 ErrPrint("Error: %s (has no record? - %s)\n", sqlite3_errmsg(handle), appid);
1079                 goto out;
1080         }
1081
1082         tmp = (char *)sqlite3_column_text(stmt, 0);
1083         if (tmp && strlen(tmp)) {
1084                 pkgid = strdup(tmp);
1085                 if (!pkgid)
1086                         ErrPrint("Heap: %s\n", strerror(errno));
1087         }
1088
1089 out:
1090         sqlite3_reset(stmt);
1091         sqlite3_finalize(stmt);
1092         close_db(handle);
1093         return pkgid;
1094 }
1095
1096 EAPI char *livebox_service_pkgname(const char *appid)
1097 {
1098         char *lb_pkgname;
1099         pkgmgr_appinfo_h handle;
1100         int ret;
1101         char *new_appid;
1102
1103         if (!appid)
1104                 return NULL;
1105
1106         lb_pkgname = get_lb_pkgname_by_appid(appid);
1107         if (lb_pkgname)
1108                 return lb_pkgname;
1109
1110         /*!
1111          * \note
1112          * Try to get the package id using given appid
1113          */
1114         ret = pkgmgr_appinfo_get_appinfo(appid, &handle);
1115         if (ret != PKGMGR_R_OK) {
1116                 ErrPrint("Failed to get appinfo\n");
1117                 return NULL;
1118         }
1119
1120         ret = pkgmgr_appinfo_get_pkgname(handle, &new_appid);
1121         if (ret != PKGMGR_R_OK) {
1122                 pkgmgr_appinfo_destroy_appinfo(handle);
1123                 ErrPrint("Failed to get pkgname for (%s)\n", appid);
1124                 return NULL;
1125         }
1126
1127         lb_pkgname = get_lb_pkgname_by_appid(new_appid);
1128         pkgmgr_appinfo_destroy_appinfo(handle);
1129
1130         if (!lb_pkgname && util_validate_livebox_package(appid) == 0)
1131                 return strdup(appid);
1132
1133         return lb_pkgname;
1134 }
1135
1136 EAPI char *livebox_service_provider_name(const char *lbid)
1137 {
1138         char *ret;
1139
1140         if (!lbid)
1141                 return NULL;
1142
1143         ret = strdup(lbid);
1144         if (!ret) {
1145                 ErrPrint("Error: %s\n", strerror(errno));
1146                 return NULL;
1147         }
1148
1149         return ret;
1150 }
1151
1152 EAPI char *livebox_service_appid(const char *pkgname)
1153 {
1154         sqlite3_stmt *stmt;
1155         char *appid;
1156         char *tmp;
1157         sqlite3 *handle;
1158         int is_prime;
1159         int ret;
1160
1161         if (!pkgname)
1162                 return NULL;
1163
1164         appid = NULL;
1165         handle = open_db();
1166         if (!handle)
1167                 return NULL;
1168
1169         ret = sqlite3_prepare_v2(handle, "SELECT appid, prime FROM pkgmap WHERE pkgid = ? OR appid = ?", -1, &stmt, NULL);
1170         if (ret != SQLITE_OK) {
1171                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1172                 goto out;
1173         }
1174
1175         ret = sqlite3_bind_text(stmt, 1, pkgname, -1, NULL);
1176         if (ret != SQLITE_OK) {
1177                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1178                 sqlite3_reset(stmt);
1179                 sqlite3_finalize(stmt);
1180                 goto out;
1181         }
1182
1183         ret = sqlite3_bind_text(stmt, 2, pkgname, -1, NULL);
1184         if (ret != SQLITE_OK) {
1185                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1186                 sqlite3_reset(stmt);
1187                 sqlite3_finalize(stmt);
1188                 goto out;
1189         }
1190
1191         ret = sqlite3_step(stmt);
1192         if (ret != SQLITE_ROW) {
1193                 pkgmgr_appinfo_h pkg_handle;
1194                 char *new_appid;
1195
1196                 ErrPrint("Has no record?: %s\n", sqlite3_errmsg(handle));
1197                 sqlite3_reset(stmt);
1198                 sqlite3_finalize(stmt);
1199
1200                 ret = pkgmgr_appinfo_get_appinfo(pkgname, &pkg_handle);
1201                 if (ret != PKGMGR_R_OK) {
1202                         ErrPrint("Failed to get appinfo: %s\n", pkgname);
1203                         goto out;
1204                 }
1205
1206                 ret = pkgmgr_appinfo_get_pkgname(pkg_handle, &new_appid);
1207                 if (ret != PKGMGR_R_OK) {
1208                         ErrPrint("Failed to get pkgname for (%s)\n", appid);
1209                         pkgmgr_appinfo_destroy_appinfo(pkg_handle);
1210                         goto out;
1211                 }
1212
1213                 appid = strdup(new_appid);
1214                 if (!appid)
1215                         ErrPrint("Heap: %s\n", strerror(errno));
1216
1217                 pkgmgr_appinfo_destroy_appinfo(pkg_handle);
1218                 goto out;
1219         }
1220
1221         tmp = (char *)sqlite3_column_text(stmt, 0);
1222         if (!tmp || !strlen(tmp)) {
1223                 ErrPrint("APPID is NIL\n");
1224                 sqlite3_reset(stmt);
1225                 sqlite3_finalize(stmt);
1226                 goto out;
1227         }
1228
1229         appid = strdup(tmp);
1230         if (!appid) {
1231                 ErrPrint("Heap: %s\n", strerror(errno));
1232                 sqlite3_reset(stmt);
1233                 sqlite3_finalize(stmt);
1234                 goto out;
1235         }
1236
1237         is_prime = sqlite3_column_int(stmt, 1);
1238
1239         sqlite3_reset(stmt);
1240         sqlite3_finalize(stmt);
1241 out:
1242         close_db(handle);
1243         return appid;
1244 }
1245
1246 EAPI char *livebox_service_lb_script_path(const char *pkgid)
1247 {
1248         sqlite3_stmt *stmt;
1249         sqlite3 *handle;
1250         int ret;
1251         char *path;
1252         char *appid;
1253         char *lb_src;
1254
1255         if (!pkgid)
1256                 return NULL;
1257
1258         path = NULL;
1259         handle = open_db();
1260         if (!handle)
1261                 return NULL;
1262
1263         ret = sqlite3_prepare_v2(handle, "SELECT pkgmap.appid, provider.box_src FROM provider, pkgmap WHERE pkgmap.pkgid = ? AND provider.pkgid = ?", -1, &stmt, NULL);
1264         if (ret != SQLITE_OK) {
1265                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1266                 goto out;
1267         }
1268
1269         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1270         if (ret != SQLITE_OK) {
1271                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1272                 sqlite3_finalize(stmt);
1273                 goto out;
1274         }
1275
1276         ret = sqlite3_bind_text(stmt, 2, pkgid, -1, NULL);
1277         if (ret != SQLITE_OK) {
1278                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1279                 sqlite3_finalize(stmt);
1280                 goto out;
1281         }
1282
1283         ret = sqlite3_step(stmt);
1284         if (ret != SQLITE_ROW) {
1285                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1286                 sqlite3_reset(stmt);
1287                 sqlite3_finalize(stmt);
1288                 goto out;
1289         }
1290
1291         appid = (char *)sqlite3_column_text(stmt, 0);
1292         if (!appid || !strlen(appid)) {
1293                 ErrPrint("Invalid appid : %s\n", sqlite3_errmsg(handle));
1294                 sqlite3_reset(stmt);
1295                 sqlite3_finalize(stmt);
1296                 goto out;
1297         }
1298
1299         lb_src = (char *)sqlite3_column_text(stmt, 1);
1300         if (!lb_src || !strlen(lb_src)) {
1301                 ErrPrint("No records for lb src : %s\n", sqlite3_errmsg(handle));
1302                 sqlite3_reset(stmt);
1303                 sqlite3_finalize(stmt);
1304                 goto out;
1305         }
1306
1307         path = strdup(lb_src);
1308         if (!path) {
1309                 ErrPrint("Heap: %s\n", strerror(errno));
1310                 sqlite3_reset(stmt);
1311                 sqlite3_finalize(stmt);
1312                 goto out;
1313         }
1314
1315         DbgPrint("LB Src: %s\n", path);
1316
1317         sqlite3_reset(stmt);
1318         sqlite3_finalize(stmt);
1319 out:
1320         close_db(handle);
1321         return path;
1322 }
1323
1324 EAPI char *livebox_service_lb_script_group(const char *pkgid)
1325 {
1326         sqlite3_stmt *stmt;
1327         sqlite3 *handle;
1328         int ret;
1329         char *group;
1330         char *tmp;
1331
1332         if (!pkgid)
1333                 return NULL;
1334
1335         group = NULL;
1336         handle = open_db();
1337         if (!handle)
1338                 return NULL;
1339
1340         ret = sqlite3_prepare_v2(handle, "SELECT box_group FROM provider WHERE pkgid = ?", -1, &stmt, NULL);
1341         if (ret != SQLITE_OK) {
1342                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1343                 goto out;
1344         }
1345
1346         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1347         if (ret != SQLITE_OK) {
1348                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1349                 sqlite3_finalize(stmt);
1350                 goto out;
1351         }
1352
1353         ret = sqlite3_step(stmt);
1354         if (ret != SQLITE_ROW) {
1355                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1356                 sqlite3_reset(stmt);
1357                 sqlite3_finalize(stmt);
1358                 goto out;
1359         }
1360
1361         tmp = (char *)sqlite3_column_text(stmt, 0);
1362         if (tmp && strlen(tmp)) {
1363                 group = strdup(tmp);
1364                 if (!group)
1365                         ErrPrint("Heap: %s\n", strerror(errno));
1366         }
1367
1368         sqlite3_reset(stmt);
1369         sqlite3_finalize(stmt);
1370 out:
1371         close_db(handle);
1372         return group;
1373 }
1374
1375 EAPI char *livebox_service_pd_script_path(const char *pkgid)
1376 {
1377         sqlite3_stmt *stmt;
1378         sqlite3 *handle;
1379         int ret;
1380         char *path;
1381         char *pd_src;
1382         const char *appid;
1383
1384         if (!pkgid)
1385                 return NULL;
1386
1387         path = NULL;
1388         handle = open_db();
1389         if (!handle)
1390                 return NULL;
1391
1392         ret = sqlite3_prepare_v2(handle, "SELECT pkgmap.appid, provider.pd_src FROM provider, pkgmap WHERE provider.pkgid = ? AND pkgmap.pkgid = ?", -1, &stmt, NULL);
1393         if (ret != SQLITE_OK) {
1394                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1395                 goto out;
1396         }
1397
1398         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1399         if (ret != SQLITE_OK) {
1400                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1401                 sqlite3_finalize(stmt);
1402                 goto out;
1403         }
1404
1405         ret = sqlite3_bind_text(stmt, 2, pkgid, -1, NULL);
1406         if (ret != SQLITE_OK) {
1407                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1408                 sqlite3_finalize(stmt);
1409                 goto out;
1410         }
1411
1412         ret = sqlite3_step(stmt);
1413         if (ret != SQLITE_ROW) {
1414                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1415                 sqlite3_reset(stmt);
1416                 sqlite3_finalize(stmt);
1417                 goto out;
1418         }
1419
1420         appid = (char *)sqlite3_column_text(stmt, 0);
1421         if (!appid || !strlen(appid)) {
1422                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1423                 sqlite3_reset(stmt);
1424                 sqlite3_finalize(stmt);
1425                 goto out;
1426         }
1427
1428         pd_src = (char *)sqlite3_column_text(stmt, 1);
1429         if (!pd_src || !strlen(pd_src)) {
1430                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1431                 sqlite3_reset(stmt);
1432                 sqlite3_finalize(stmt);
1433                 goto out;
1434         }
1435
1436         path = strdup(pd_src);
1437         if (!path) {
1438                 ErrPrint("Heap: %s\n", strerror(errno));
1439                 sqlite3_reset(stmt);
1440                 sqlite3_finalize(stmt);
1441                 goto out;
1442         }
1443
1444         DbgPrint("PD Src: %s\n", path);
1445         sqlite3_reset(stmt);
1446         sqlite3_finalize(stmt);
1447 out:
1448         close_db(handle);
1449         return path;
1450 }
1451
1452 EAPI char *livebox_service_pd_script_group(const char *pkgid)
1453 {
1454         sqlite3_stmt *stmt;
1455         sqlite3 *handle;
1456         int ret;
1457         char *group;
1458         char *tmp;
1459
1460         if (!pkgid)
1461                 return NULL;
1462
1463         group = NULL;
1464         handle = open_db();
1465         if (!handle)
1466                 return NULL;
1467
1468         ret = sqlite3_prepare_v2(handle, "SELECT pd_group FROM provider WHERE pkgid = ?", -1, &stmt, NULL);
1469         if (ret != SQLITE_OK) {
1470                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1471                 goto out;
1472         }
1473
1474         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1475         if (ret != SQLITE_OK) {
1476                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1477                 sqlite3_finalize(stmt);
1478                 goto out;
1479         }
1480
1481         ret = sqlite3_step(stmt);
1482         if (ret != SQLITE_ROW) {
1483                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1484                 sqlite3_reset(stmt);
1485                 sqlite3_finalize(stmt);
1486                 goto out;
1487         }
1488
1489         tmp = (char *)sqlite3_column_text(stmt, 0);
1490         if (tmp && strlen(tmp)) {
1491                 group = strdup(tmp);
1492                 if (!group)
1493                         ErrPrint("Heap: %s\n", strerror(errno));
1494         }
1495         sqlite3_reset(stmt);
1496         sqlite3_finalize(stmt);
1497 out:
1498         close_db(handle);
1499         return group;
1500 }
1501
1502 EAPI int livebox_service_enumerate_cluster_list(int (*cb)(const char *cluster, void *data), void *data)
1503 {
1504         sqlite3_stmt *stmt;
1505         sqlite3 *handle;
1506         const char *cluster;
1507         int cnt;
1508         int ret;
1509
1510         if (!cb)
1511                 return -EINVAL;
1512
1513         handle = open_db();
1514         if (!handle)
1515                 return -EIO;
1516
1517         cnt = 0;
1518         ret = sqlite3_prepare_v2(handle, "SELECT DISTINCT cluster FROM groupinfo", -1, &stmt, NULL);
1519         if (ret != SQLITE_OK) {
1520                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1521                 cnt = -EIO;
1522                 goto out;
1523         }
1524
1525         while (sqlite3_step(stmt) == SQLITE_ROW) {
1526                 cluster = (const char *)sqlite3_column_text(stmt, 0);
1527                 if (!cluster || !strlen(cluster))
1528                         continue;
1529
1530                 if (cb(cluster, data) < 0)
1531                         break;
1532
1533                 cnt++;
1534         }
1535
1536         sqlite3_reset(stmt);
1537         sqlite3_finalize(stmt);
1538 out:
1539         close_db(handle);
1540         return cnt;
1541 }
1542
1543 EAPI int livebox_service_enumerate_category_list(const char *cluster, int (*cb)(const char *cluster, const char *category, void *data), void *data)
1544 {
1545         sqlite3_stmt *stmt;
1546         sqlite3 *handle;
1547         const char *category;
1548         int cnt;
1549         int ret;
1550
1551         if (!cluster || !cb)
1552                 return -EINVAL;
1553
1554         handle = open_db();
1555         if (!handle)
1556                 return -EIO;
1557
1558         ret = sqlite3_prepare_v2(handle, "SELECT DISTINCT category FROM groupinfo WHERE cluster = ?", -1, &stmt, NULL);
1559         if (ret != SQLITE_OK) {
1560                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1561                 cnt = -EIO;
1562                 goto out;
1563         }
1564
1565         cnt = 0;
1566         while (sqlite3_step(stmt) == SQLITE_ROW) {
1567                 category = (const char *)sqlite3_column_text(stmt, 0);
1568                 if (!category || !strlen(category))
1569                         continue;
1570
1571                 if (cb(cluster, category, data) < 0)
1572                         break;
1573
1574                 cnt++;
1575         }
1576
1577         sqlite3_reset(stmt);
1578         sqlite3_finalize(stmt);
1579 out:
1580         close_db(handle);
1581         return cnt;
1582 }
1583
1584 EAPI int livebox_service_init(void)
1585 {
1586         if (s_info.handle) {
1587                 DbgPrint("Already initialized\n");
1588                 s_info.init_count++;
1589                 return 0;
1590         }
1591
1592         s_info.handle = open_db();
1593         if (s_info.handle) {
1594                 s_info.init_count++;
1595                 return 0;
1596         }
1597
1598         return -EIO;
1599 }
1600
1601 EAPI int livebox_service_fini(void)
1602 {
1603         if (!s_info.handle || s_info.init_count <= 0) {
1604                 ErrPrint("Service is not initialized\n");
1605                 return -EIO;
1606         }
1607
1608         s_info.init_count--;
1609         if (s_info.init_count > 0) {
1610                 DbgPrint("Init count %d\n", s_info.init_count);
1611                 return 0;
1612         }
1613
1614         db_util_close(s_info.handle);
1615         s_info.handle = NULL;
1616         return 0;
1617 }
1618
1619 EAPI int livebox_service_get_size(int type, int *width, int *height)
1620 {
1621         int _width;
1622         int _height;
1623
1624         if (!width)
1625                 width = &_width;
1626
1627         if (!height)
1628                 height = &_height;
1629
1630         return convert_size_from_type(type, width, height);
1631 }
1632
1633 EAPI int livebox_service_size_type(int width, int height)
1634 {
1635         int idx;
1636
1637         if (update_resolution() < 0)
1638                 ErrPrint("Failed to update the size list\n");
1639
1640         for (idx = 0; idx < NR_OF_SIZE_LIST; idx++) {
1641                 if (SIZE_LIST[idx].w == width && SIZE_LIST[idx].h == height)
1642                         break;
1643         }
1644
1645         switch (idx) {
1646         case 0:
1647                 return LB_SIZE_TYPE_1x1;
1648         case 1:
1649                 return LB_SIZE_TYPE_2x1;
1650         case 2:
1651                 return LB_SIZE_TYPE_2x2;
1652         case 3:
1653                 return LB_SIZE_TYPE_4x1;
1654         case 4:
1655                 return LB_SIZE_TYPE_4x2;
1656         case 5:
1657                 return LB_SIZE_TYPE_4x3;
1658         case 6:
1659                 return LB_SIZE_TYPE_4x4;
1660         default:
1661                 break;
1662         }
1663
1664         return LB_SIZE_TYPE_UNKNOWN;
1665 }
1666
1667 /* End of a file */