Update error code and mapping UI-app and DBox
[platform/framework/web/livebox-service.git] / src / livebox-service.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <errno.h>
19 #include <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 <pkgmgr-info.h>
35 #include <vconf.h>
36 #include <vconf-keys.h>
37 #include <ail.h>
38
39 #include "dlist.h"
40 #include "util.h"
41 #include "debug.h"
42 #include "livebox-service.h"
43 #include "livebox-errno.h"
44
45 #define SAMSUNG_PREFIX  "com.samsung."
46 #define EAPI __attribute__((visibility("default")))
47 #define DEFAULT_TIMEOUT 2.0
48 #define MAX_COLUMN 80
49
50 static struct supported_size_list {
51         int w;
52         int h;
53 } SIZE_LIST[NR_OF_SIZE_LIST] = {
54         { 175, 175 }, /*!< 1x1 */
55         { 354, 175 }, /*!< 2x1 */
56         { 354, 354 }, /*!< 2x2 */
57         { 712, 175 }, /*!< 4x1 */
58         { 712, 354 }, /*!< 4x2 */
59         { 712, 533 }, /*!< 4x3 */
60         { 712, 712 }, /*!< 4x4 */
61         { 712, 891 }, /*!< 4x5 */
62         { 712, 1070 }, /*!< 4x6 */
63         { 207, 207 }, /*!< 21x21 */
64         { 645, 207 }, /*!< 23x21 */
65         { 645, 645 }, /*!< 23x23 */
66         { 720, 1280 }, /*!< 0x0 */
67 };
68
69 static struct info {
70         sqlite3 *handle;
71         const char *dbfile;
72         const char *conf_file;
73         int init_count;
74         int res_resolved;
75 } s_info = {
76         .handle = NULL,
77         .dbfile = "/opt/dbspace/.livebox.db", 
78         .conf_file = "/usr/share/data-provider-master/resolution.ini",
79         .init_count = 0,
80         .res_resolved = 0,
81 };
82
83 static inline int update_info(int width_type, int height_type, int width, int height)
84 {
85         int idx;
86
87         if (width_type == 1 && height_type == 1) {
88                 DbgPrint("1x1 Updated to %dx%d\n", width, height);
89                 idx = 0;
90         } else if (width_type == 2 && height_type == 1) {
91                 DbgPrint("2x1 Updated to %dx%d\n", width, height);
92                 idx = 1;
93         } else if (width_type == 2 && height_type == 2) {
94                 DbgPrint("2x2 Updated to %dx%d\n", width, height);
95                 idx = 2;
96         } else if (width_type == 4 && height_type == 1) {
97                 DbgPrint("4x1 Updated to %dx%d\n", width, height);
98                 idx = 3;
99         } else if (width_type == 4 && height_type == 2) {
100                 DbgPrint("4x2 Updated to %dx%d\n", width, height);
101                 idx = 4;
102         } else if (width_type == 4 && height_type == 3) {
103                 DbgPrint("4x3 Updated to %dx%d\n", width, height);
104                 idx = 5;
105         } else if (width_type == 4 && height_type == 4) {
106                 DbgPrint("4x4 Updated to %dx%d\n", width, height);
107                 idx = 6;
108         } else if (width_type == 4 && height_type == 5) {
109                 DbgPrint("4x5 Updated to %dx%d\n", width, height);
110                 idx = 7;
111         } else if (width_type == 4 && height_type == 6) {
112                 DbgPrint("4x6 Updated to %dx%d\n", width, height);
113                 idx = 8;
114         } else if (width_type == 21 && height_type == 21) {
115                 DbgPrint("Easy 1x1 Updated to %dx%d\n", width, height);
116                 idx = 9;
117         } else if (width_type == 23 && height_type == 21) {
118                 DbgPrint("Easy 3x1 Updated to %dx%d\n", width, height);
119                 idx = 10;
120         } else if (width_type == 23 && height_type == 23) {
121                 DbgPrint("Easy 3x3 Updated to %dx%d\n", width, height);
122                 idx = 11;
123         } else if (width_type == 0 && height_type == 0) {
124                 DbgPrint("Special 0x0 Updated to %dx%d\n", width, height);
125                 idx = 12;
126         } else {
127                 ErrPrint("Unknown size type: %dx%d (%dx%d)\n", width_type, height_type, width, height);
128                 return 0;
129         }
130
131         SIZE_LIST[idx].w = width;
132         SIZE_LIST[idx].h = height;
133         return 1;
134 }
135
136 static inline int update_from_file(void)
137 {
138         FILE *fp;
139         int updated;
140         int width_type;
141         int height_type;
142         int width;
143         int height;
144         char buffer[MAX_COLUMN];
145         int ch;
146         int idx;
147         enum status {
148                 START = 0x0,
149                 TYPE = 0x01,
150                 SIZE = 0x02,
151                 COMMENT = 0x03,
152                 ERROR = 0x04,
153                 EOL = 0x05,
154                 TYPE_END = 0x06,
155                 SIZE_START = 0x07,
156         } status;
157
158         fp = fopen(s_info.conf_file, "r");
159         if (!fp) {
160                 ErrPrint("Open failed: %s\n", strerror(errno));
161                 return LB_STATUS_ERROR_IO;
162         }
163
164         updated = 0;
165         status = START;
166         idx = 0;
167         do {
168                 ch = fgetc(fp);
169
170                 if (idx == MAX_COLUMN) {
171                         ErrPrint("Buffer overflow. Too long line. LINE MUST BE SHOT THAN %d\n", MAX_COLUMN);
172                         status = ERROR;
173                 }
174
175                 switch (status) {
176                 case START:
177                         if (isspace(ch) || ch == EOF)
178                                 continue;
179
180                         if (ch == '#') {
181                                 status = COMMENT;
182                         } else {
183                                 status = TYPE;
184                                 idx = 0;
185                                 ungetc(ch, fp);
186                         }
187                         break;
188                 case TYPE:
189                         if (isblank(ch)) {
190                                 buffer[idx] = '\0';
191                                 status = TYPE_END;
192                                 if (sscanf(buffer, "%dx%d", &width_type, &height_type) != 2) {
193                                         ErrPrint("Invalid syntax: [%s]\n", buffer);
194                                         status = ERROR;
195                                 }
196                                 break;
197                         } else if (ch == '=') {
198                                 buffer[idx] = '\0';
199                                 status = SIZE_START;
200                                 if (sscanf(buffer, "%dx%d", &width_type, &height_type) != 2) {
201                                         ErrPrint("Invalid syntax: [%s]\n", buffer);
202                                         status = ERROR;
203                                 }
204                                 break;
205                         } else if (ch == EOF) {
206                                 ErrPrint("Invalid Syntax\n");
207                                 status = ERROR;
208                                 continue;
209                         }
210                         buffer[idx++] = ch;
211                         break;
212                 case TYPE_END:
213                         if (ch == '=')
214                                 status = SIZE_START;
215                         break;
216                 case SIZE_START:
217                         if (isspace(ch) || ch == EOF)
218                                 continue;
219
220                         status = SIZE;
221                         idx = 0;
222                         ungetc(ch, fp);
223                         break;
224                 case SIZE:
225                         if (isspace(ch) || ch == EOF) {
226                                 buffer[idx] = '\0';
227                                 status = EOL;
228
229                                 if (sscanf(buffer, "%dx%d", &width, &height) != 2) {
230                                         ErrPrint("Invalid syntax: [%s]\n", buffer);
231                                         status = ERROR;
232                                 } else if (ch == EOF) {
233                                         updated += update_info(width_type, height_type, width, height);
234                                 }
235                                 break;
236                         }
237                         buffer[idx++] = ch;
238                         break;
239                 case EOL:
240                         updated += update_info(width_type, height_type, width, height);
241                         status = START;
242                         ungetc(ch, fp);
243                         break;
244                 case ERROR:
245                         if (ch == '\n' || ch == '\r' || ch == '\f')
246                                 status = START;
247                         break;
248                 case COMMENT:
249                         if (ch == '\n' || ch == '\r' || ch == '\f')
250                                 status = START;
251                         break;
252                 default:
253                         ErrPrint("Unknown status. couldn't be reach to here\n");
254                         break;
255                 }
256         } while (!feof(fp));
257         fclose(fp);
258
259         return NR_OF_SIZE_LIST - updated;
260 }
261
262 static int update_resolution(void)
263 {
264         Display *disp;
265         Window root;
266         Window dummy;
267         int x, y;
268         unsigned int width;
269         unsigned int height;
270         unsigned int border;
271         unsigned int depth;
272         register int i;
273
274         if (s_info.res_resolved)
275                 return LB_STATUS_SUCCESS;
276
277         disp = XOpenDisplay(NULL);
278         if (!disp) {
279                 ErrPrint("Failed to open a display\n");
280                 return LB_STATUS_ERROR_FAULT;
281         }
282
283         root = XDefaultRootWindow(disp);
284         if (!XGetGeometry(disp, root, &dummy, &x, &y, &width, &height, &border, &depth)) {
285                 XCloseDisplay(disp);
286                 return LB_STATUS_ERROR_FAULT;
287         }
288
289         if (update_from_file() == 0)
290                 DbgPrint("Resolution info is all updated by file\n");
291
292         DbgPrint("Screen resolution: %dx%d\n", width, height);
293         for (i = 0; i < NR_OF_SIZE_LIST; i++) {
294                 SIZE_LIST[i].w = (unsigned int)((double)SIZE_LIST[i].w * (double)width / 720.0f);
295                 SIZE_LIST[i].h = (unsigned int)((double)SIZE_LIST[i].h * (double)width / 720.0f);
296                 DbgPrint("(Ratio)Size is updated [%d] %dx%d\n", i, SIZE_LIST[i].w, SIZE_LIST[i].h);
297         }
298
299         XCloseDisplay(disp);
300         s_info.res_resolved = 1;
301         return LB_STATUS_SUCCESS;
302 }
303
304 static inline sqlite3 *open_db(void)
305 {
306         sqlite3 *handle;
307
308         if (!s_info.handle) {
309                 int ret;
310
311                 ret = db_util_open(s_info.dbfile, &handle, DB_UTIL_REGISTER_HOOK_METHOD);
312                 if (ret != SQLITE_OK) {
313                         ErrPrint("Failed to open a DB\n");
314                         return NULL;
315                 }
316         } else {
317                 handle = s_info.handle;
318         }
319
320         return handle;
321 }
322
323 static inline void close_db(sqlite3 *handle)
324 {
325         if (!s_info.handle)
326                 db_util_close(handle);
327 }
328
329 static inline int convert_size_from_type(enum livebox_size_type type, int *width, int *height)
330 {
331         int idx;
332
333         switch (type) {
334         case LB_SIZE_TYPE_1x1: /*!< 175x175 */
335                 idx = 0;
336                 break;
337         case LB_SIZE_TYPE_2x1: /*!< 354x175 */
338                 idx = 1;
339                 break;
340         case LB_SIZE_TYPE_2x2: /*!< 354x354 */
341                 idx = 2;
342                 break;
343         case LB_SIZE_TYPE_4x1: /*!< 712x175 */
344                 idx = 3;
345                 break;
346         case LB_SIZE_TYPE_4x2: /*!< 712x354 */
347                 idx = 4;
348                 break;
349         case LB_SIZE_TYPE_4x3: /*!< 712x533 */
350                 idx = 5;
351                 break;
352         case LB_SIZE_TYPE_4x4: /*!< 712x712 */
353                 idx = 6;
354                 break;
355         case LB_SIZE_TYPE_4x5: /*!< 712x891 */
356                 idx = 7;
357                 break;
358         case LB_SIZE_TYPE_4x6: /*!< 712x1070 */
359                 idx = 8;
360                 break;
361         case LB_SIZE_TYPE_EASY_1x1: /*< 207x207 */
362                 idx = 9;
363                 break;
364         case LB_SIZE_TYPE_EASY_3x1: /*!< 645x207 */
365                 idx = 10;
366                 break;
367         case LB_SIZE_TYPE_EASY_3x3: /*!< 645x645 */
368                 idx = 11;
369                 break;
370         case LB_SIZE_TYPE_0x0: /*!< 720x1280 */
371                 idx = 12;
372                 break;
373         default:
374                 return LB_STATUS_ERROR_INVALID;
375         }
376
377         if (update_resolution() < 0)
378                 ErrPrint("Failed to update resolution\n");
379
380         *width = SIZE_LIST[idx].w;
381         *height = SIZE_LIST[idx].h;
382         return LB_STATUS_SUCCESS;
383 }
384
385 EAPI int livebox_service_change_period(const char *pkgname, const char *id, double period)
386 {
387         struct packet *packet;
388         struct packet *result;
389         char *uri;
390         int ret;
391
392         if (!pkgname || !id || period < 0.0f) {
393                 ErrPrint("Invalid argument\n");
394                 return LB_STATUS_ERROR_INVALID;
395         }
396
397         uri = util_id_to_uri(id);
398         if (!uri)
399                 return LB_STATUS_ERROR_MEMORY;
400
401         packet = packet_create("service_change_period", "ssd", pkgname, uri, period);
402         free(uri);
403         if (!packet) {
404                 ErrPrint("Failed to create a packet for period changing\n");
405                 return LB_STATUS_ERROR_FAULT;
406         }
407
408         result = com_core_packet_oneshot_send(SERVICE_SOCKET, packet, DEFAULT_TIMEOUT);
409         packet_unref(packet);
410
411         if (result) {
412                 if (packet_get(result, "i", &ret) != 1) {
413                         ErrPrint("Failed to parse a result packet\n");
414                         ret = LB_STATUS_ERROR_INVALID;
415                 }
416                 packet_unref(result);
417         } else {
418                 ErrPrint("Failed to get result packet\n");
419                 ret = LB_STATUS_ERROR_FAULT;
420         }
421
422         return ret;
423 }
424
425 EAPI int livebox_service_trigger_update(const char *pkgname, const char *id, const char *cluster, const char *category, int force)
426 {
427         struct packet *packet;
428         struct packet *result;
429         char *uri;
430         int ret;
431
432         if (!pkgname) {
433                 ErrPrint("Invalid argument\n");
434                 return LB_STATUS_ERROR_INVALID;
435         }
436
437         if (!force && access("/tmp/.live.paused", R_OK) == 0) {
438                 DbgPrint("Provider is paused\n");
439                 return LB_STATUS_ERROR_CANCEL;
440         }
441
442         uri = util_id_to_uri(id);
443         if (!uri)
444                 return LB_STATUS_ERROR_MEMORY;
445
446         if (!cluster)
447                 cluster = "user,created";
448
449         if (!category)
450                 category = "default";
451
452         packet = packet_create("service_update", "ssss", pkgname, uri, cluster, category);
453         free(uri);
454         if (!packet) {
455                 ErrPrint("Failed to create a packet for service_update\n");
456                 return LB_STATUS_ERROR_FAULT;
457         }
458
459         result = com_core_packet_oneshot_send(SERVICE_SOCKET, packet, DEFAULT_TIMEOUT);
460         packet_unref(packet);
461
462         if (result) {
463                 if (packet_get(result, "i", &ret) != 1) {
464                         ErrPrint("Failed to parse a result packet\n");
465                         ret = LB_STATUS_ERROR_INVALID;
466                 }
467
468                 packet_unref(result);
469         } else {
470                 ErrPrint("Failed to get result packet\n");
471                 ret = LB_STATUS_ERROR_FAULT;
472         }
473
474         return ret;
475 }
476
477 EAPI int livebox_service_get_pkglist(int (*cb)(const char *appid, const char *pkgname, int is_prime, void *data), void *data)
478 {
479         int ret;
480         sqlite3_stmt *stmt;
481         char *appid;
482         char *pkgid;
483         int is_prime;
484         sqlite3 *handle;
485
486         if (!cb)
487                 return LB_STATUS_ERROR_INVALID;
488
489         handle = open_db();
490         if (!handle)
491                 return LB_STATUS_ERROR_IO;
492
493         ret = sqlite3_prepare_v2(handle, "SELECT appid, pkgid, prime FROM pkgmap", -1, &stmt, NULL);
494         if (ret != SQLITE_OK) {
495                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
496                 ret = LB_STATUS_ERROR_IO;
497                 goto out;
498         }
499
500         ret = 0;
501         while (sqlite3_step(stmt) == SQLITE_ROW) {
502                 appid = (char *)sqlite3_column_text(stmt, 0);
503                 if (!appid || !strlen(appid)) {
504                         ErrPrint("APPID is not valid\n");
505                         continue;
506                 }
507
508                 pkgid = (char *)sqlite3_column_text(stmt, 1);
509                 if (!pkgid || !strlen(pkgid)) {
510                         ErrPrint("pkgid is not valid\n");
511                         continue;
512                 }
513
514                 is_prime = sqlite3_column_int(stmt, 2);
515
516                 ret++;
517
518                 if (cb(appid, pkgid, is_prime, data) < 0) {
519                         DbgPrint("Callback stopped package crawling\n");
520                         break;
521                 }
522         }
523
524         sqlite3_reset(stmt);
525         sqlite3_finalize(stmt);
526
527 out:
528         close_db(handle);
529         return ret;
530 }
531
532 EAPI int livebox_service_get_pkglist_by_pkgid(const char *pkgid, int (*cb)(const char *lbid, int is_prime, void *data), void *data)
533 {
534         int ret;
535         sqlite3_stmt *stmt;
536         const char *lbid;
537         int is_prime;
538         sqlite3 *handle;
539
540         if (!cb)
541                 return LB_STATUS_ERROR_INVALID;
542
543         handle = open_db();
544         if (!handle)
545                 return LB_STATUS_ERROR_IO;
546
547         ret = sqlite3_prepare_v2(handle, "SELECT pkgid, prime FROM pkgmap WHERE appid = ?", -1, &stmt, NULL);
548         if (ret != SQLITE_OK) {
549                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
550                 ret = LB_STATUS_ERROR_IO;
551                 goto out;
552         }
553
554         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
555         if (ret != SQLITE_OK) {
556                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
557                 sqlite3_reset(stmt);
558                 sqlite3_finalize(stmt);
559                 ret = LB_STATUS_ERROR_IO;
560                 goto out;
561         }
562
563         ret = 0;
564         while (sqlite3_step(stmt) == SQLITE_ROW) {
565                 lbid = (const char *)sqlite3_column_text(stmt, 0);
566                 if (!lbid || !strlen(lbid)) {
567                         ErrPrint("LBID is not valid\n");
568                         continue;
569                 }
570
571                 is_prime = sqlite3_column_int(stmt, 1);
572
573                 ret++;
574
575                 if (cb(lbid, is_prime, data) < 0) {
576                         DbgPrint("Callback stopped package crawling\n");
577                         break;
578                 }
579         }
580
581         sqlite3_reset(stmt);
582         sqlite3_finalize(stmt);
583
584 out:
585         close_db(handle);
586         return ret;
587 }
588
589 struct pkgmgr_cbdata {
590         const char *lbid;
591         void (*cb)(const char *lbid, const char *appid, void *data);
592         void *cbdata;
593 };
594
595 static int pkgmgr_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
596 {
597         struct pkgmgr_cbdata *cbdata = (struct pkgmgr_cbdata *)user_data;
598         char *appid;
599         int ret;
600
601         ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
602         if (ret < 0)
603                 ErrPrint("Unable to get appid\n");
604         else
605                 cbdata->cb(cbdata->lbid, appid, cbdata->cbdata);
606
607         return 0;
608 }
609
610 static inline char *pkgmgr_get_mainapp(const char *pkgid)
611 {
612         pkgmgrinfo_pkginfo_h handle;
613         char *ret = NULL;
614
615         if (pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle) != PMINFO_R_OK) {
616                 ErrPrint("Unable to get mainapp: %s\n", pkgid);
617                 return NULL;
618         }
619
620         if (pkgmgrinfo_pkginfo_get_mainappid(handle, &ret) == PMINFO_R_OK) {
621                 ret = strdup(ret);
622         } else {
623                 ErrPrint("Failed to get mainappid\n");
624                 ret = NULL; /* I cannot believe the pkgmgrinfo_pkginfo_get_mainappid. it maybe able to touch my "ret" even though it fails */
625         
626         }
627
628         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
629         return ret;
630 }
631
632 static inline int pkgmgr_get_applist(const char *pkgid, const char *lbid, void (*cb)(const char *lbid, const char *appid, void *data), void *data)
633 {
634         struct pkgmgr_cbdata cbdata;
635         pkgmgrinfo_pkginfo_h handle;
636         int ret;
637
638         ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
639         if (ret < 0) {
640                 ErrPrint("Unable to get pkginfo: %s\n", pkgid);
641                 return ret;
642         }
643
644         cbdata.lbid = lbid;
645         cbdata.cb = cb;
646         cbdata.cbdata = data;
647
648         ret = pkgmgrinfo_appinfo_get_list(handle, PM_UI_APP, pkgmgr_cb, &cbdata);
649         if (ret < 0)
650                 ErrPrint("Failed to get applist\n");
651
652         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
653         return ret;
654 }
655
656 EAPI int livebox_service_get_applist(const char *lbid, void (*cb)(const char *lbid, const char *appid, void *data), void *data)
657 {
658         sqlite3_stmt *stmt;
659         const char *tmp;
660         char *pkgid;
661         sqlite3 *handle;
662         int ret;
663
664         if (!lbid || !cb)
665                 return LB_STATUS_ERROR_INVALID;
666
667         handle = open_db();
668         if (!handle)
669                 return LB_STATUS_ERROR_IO;
670
671         ret = sqlite3_prepare_v2(handle, "SELECT appid FROM pkgmap WHERE (pkgid = ?) or (appid = ?)", -1, &stmt, NULL);
672         if (ret != SQLITE_OK) {
673                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
674                 ret = LB_STATUS_ERROR_IO;
675                 goto out;
676         }
677
678         ret = sqlite3_bind_text(stmt, 1, lbid, -1, SQLITE_TRANSIENT);
679         if (ret != SQLITE_OK) {
680                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
681                 ret = LB_STATUS_ERROR_IO;
682                 goto out;
683         }
684
685         ret = sqlite3_bind_text(stmt, 2, lbid, -1, SQLITE_TRANSIENT);
686         if (ret != SQLITE_OK) {
687                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
688                 ret = LB_STATUS_ERROR_IO;
689                 goto out;
690         }
691
692         if (sqlite3_step(stmt) != SQLITE_ROW) {
693                 ret = LB_STATUS_ERROR_INVALID;
694                 sqlite3_reset(stmt);
695                 sqlite3_finalize(stmt);
696                 goto out;
697         }
698
699         tmp = (const char *)sqlite3_column_text(stmt, 0);
700         if (!tmp || !strlen(tmp)) {
701                 ErrPrint("Invalid package name (%s)\n", lbid);
702                 ret = LB_STATUS_ERROR_INVALID;
703                 sqlite3_reset(stmt);
704                 sqlite3_finalize(stmt);
705                 goto out;
706         }
707
708         pkgid = strdup(tmp);
709         if (!pkgid) {
710                 ErrPrint("Error: %s\n", strerror(errno));
711                 ret = LB_STATUS_ERROR_MEMORY;
712                 sqlite3_reset(stmt);
713                 sqlite3_finalize(stmt);
714                 goto out;
715         }
716
717         sqlite3_reset(stmt);
718         sqlite3_finalize(stmt);
719
720         ret = pkgmgr_get_applist(pkgid, lbid, cb, data);
721         free(pkgid);
722
723 out:
724         close_db(handle);
725         return ret;
726 }
727
728 EAPI char *livebox_service_mainappid(const char *lbid)
729 {
730         sqlite3_stmt *stmt;
731         const char *tmp;
732         const char *pkgid;
733         sqlite3 *handle;
734         char *ret = NULL;
735
736         if (!lbid)
737                 return NULL;
738
739         handle = open_db();
740         if (!handle)
741                 return NULL;
742
743         if (sqlite3_prepare_v2(handle, "SELECT appid, uiapp FROM pkgmap WHERE (pkgid = ?) or (appid = ? and prime = 1)", -1, &stmt, NULL) != SQLITE_OK) {
744                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
745                 goto out;
746         }
747
748         if (sqlite3_bind_text(stmt, 1, lbid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
749                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
750                 goto out;
751         }
752
753         if (sqlite3_bind_text(stmt, 2, lbid, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
754                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
755                 goto out;
756         }
757
758         if (sqlite3_step(stmt) != SQLITE_ROW) {
759                 sqlite3_reset(stmt);
760                 sqlite3_finalize(stmt);
761                 goto out;
762         }
763
764         tmp = (const char *)sqlite3_column_text(stmt, 0);
765         if (!tmp || !strlen(tmp)) {
766                 ErrPrint("Invalid package name (%s)\n", lbid);
767                 sqlite3_reset(stmt);
768                 sqlite3_finalize(stmt);
769                 goto out;
770         }
771
772         pkgid = (const char *)sqlite3_column_text(stmt, 1);
773         if (!pkgid || !strlen(pkgid)) {
774                 /*
775                  * This record has no uiapp.
776                  * Try to find the main ui-app id.
777                  */
778                 ret = pkgmgr_get_mainapp(tmp);
779         } else {
780                 ret = strdup(pkgid);
781                 if (!ret)
782                         ErrPrint("Error: %s\n", strerror(errno));
783         }
784
785         sqlite3_reset(stmt);
786         sqlite3_finalize(stmt);
787
788 out:
789         close_db(handle);
790         return ret;
791 }
792
793 EAPI int livebox_service_get_supported_size_types(const char *pkgid, int *cnt, int *types)
794 {
795         sqlite3_stmt *stmt;
796         sqlite3 *handle;
797         int size;
798         int ret;
799
800         if (!types || !cnt || !pkgid)
801                 return LB_STATUS_ERROR_INVALID;
802
803         handle = open_db();
804         if (!handle)
805                 return LB_STATUS_ERROR_IO;
806
807         ret = sqlite3_prepare_v2(handle, "SELECT size_type FROM box_size WHERE pkgid = ? ORDER BY size_type ASC", -1, &stmt, NULL);
808         if (ret != SQLITE_OK) {
809                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
810                 ret = LB_STATUS_ERROR_IO;
811                 goto out;
812         }
813
814         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
815         if (ret != SQLITE_OK) {
816                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
817                 sqlite3_reset(stmt);
818                 sqlite3_finalize(stmt);
819                 ret = LB_STATUS_ERROR_IO;
820                 goto out;
821         }
822
823         if (*cnt > NR_OF_SIZE_LIST)
824                 *cnt = NR_OF_SIZE_LIST;
825
826         ret = 0;
827         while (sqlite3_step(stmt) == SQLITE_ROW && ret < *cnt) {
828                 size = sqlite3_column_int(stmt, 0);
829                 types[ret] = size;
830                 ret++;
831         }
832
833         *cnt = ret;
834         sqlite3_reset(stmt);
835         sqlite3_finalize(stmt);
836         ret = 0;
837 out:
838         close_db(handle);
839         return ret;
840 }
841
842 static inline char *cur_locale(void)
843 {
844         char *language;
845         language = vconf_get_str(VCONFKEY_LANGSET);
846         if (language) {
847                 char *ptr;
848
849                 ptr = language;
850                 while (*ptr) {
851                         if (*ptr == '.') {
852                                 *ptr = '\0';
853                                 break;
854                         }
855
856                         if (*ptr == '_')
857                                 *ptr = '-';
858
859                         ptr++;
860                 }
861         } else {
862                 language = strdup("en-us");
863                 if (!language)
864                         ErrPrint("Heap: %s\n", strerror(errno));
865         }
866
867         return language;
868 }
869
870 static inline char *get_default_name(const char *pkgid)
871 {
872         sqlite3_stmt *stmt;
873         sqlite3 *handle;
874         char *name = NULL;
875         int ret;
876
877         handle = open_db();
878         if (!handle)
879                 return NULL;
880
881         ret = sqlite3_prepare_v2(handle, "SELECT name FROM client WHERE pkgid = ?", -1, &stmt, NULL);
882         if (ret != SQLITE_OK) {
883                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
884                 close_db(handle);
885                 return NULL;
886         }
887
888         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
889         if (ret != SQLITE_OK) {
890                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
891                 goto out;
892         }
893
894         ret = sqlite3_step(stmt);
895         if (ret ==  SQLITE_ROW) {
896                 const char *tmp;
897
898                 tmp = (const char *)sqlite3_column_text(stmt, 0);
899                 if (tmp && strlen(tmp)) {
900                         name = strdup(tmp);
901                         if (!name)
902                                 ErrPrint("Heap: %s\n", strerror(errno));
903                 }
904         }
905
906 out:
907         sqlite3_reset(stmt);
908         sqlite3_finalize(stmt);
909         close_db(handle);
910         return name;
911 }
912
913 static inline char *get_default_icon(const char *pkgid)
914 {
915         sqlite3_stmt *stmt;
916         sqlite3 *handle;
917         char *icon = NULL;
918         int ret;
919
920         handle = open_db();
921         if (!handle)
922                 return NULL;
923
924         ret = sqlite3_prepare_v2(handle, "SELECT icon FROM client WHERE pkgid = ?", -1, &stmt, NULL);
925         if (ret != SQLITE_OK) {
926                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
927                 close_db(handle);
928                 return NULL;
929         }
930
931         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
932         if (ret != SQLITE_OK) {
933                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
934                 goto out;
935         }
936
937         ret = sqlite3_step(stmt);
938         if (ret == SQLITE_ROW) {
939                 const char *tmp;
940
941                 tmp = (const char *)sqlite3_column_text(stmt, 0);
942                 if (tmp && strlen(tmp)) {
943                         icon = strdup(tmp);
944                         if (!icon)
945                                 ErrPrint("Heap: %s\n", strerror(errno));
946                 }
947         }
948
949 out:
950         sqlite3_reset(stmt);
951         sqlite3_finalize(stmt);
952         close_db(handle);
953         return icon;
954 }
955
956 EAPI char *livebox_service_content(const char *pkgid)
957 {
958         sqlite3_stmt *stmt;
959         sqlite3 *handle;
960         char *content = NULL;
961         int ret;
962
963         handle = open_db();
964         if (!handle)
965                 return NULL;
966
967         ret = sqlite3_prepare_v2(handle, "SELECT content FROM client WHERE pkgid = ?", -1, &stmt, NULL);
968         if (ret != SQLITE_OK) {
969                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
970                 close_db(handle);
971                 return NULL;
972         }
973
974         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
975         if (ret != SQLITE_OK) {
976                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
977                 goto out;
978         }
979
980         ret = sqlite3_step(stmt);
981         if (ret == SQLITE_ROW) {
982                 const char *tmp;
983
984                 tmp = (const char *)sqlite3_column_text(stmt, 0);
985                 if (tmp && strlen(tmp)) {
986                         content = strdup(tmp);
987                         if (!content)
988                                 ErrPrint("Heap: %s\n", strerror(errno));
989                 }
990         }
991
992 out:
993         sqlite3_reset(stmt);
994         sqlite3_finalize(stmt);
995         close_db(handle);
996         return content;
997 }
998
999 EAPI char *livebox_service_setup_appid(const char *lbid)
1000 {
1001         sqlite3_stmt *stmt;
1002         sqlite3 *handle;
1003         int ret;
1004         char *appid;
1005
1006         handle = open_db();
1007         if (!handle)
1008                 return NULL;
1009
1010         ret = sqlite3_prepare_v2(handle, "SELECT setup FROM client WHERE pkgid = ?", -1, &stmt, NULL);
1011         if (ret != SQLITE_OK) {
1012                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1013                 close_db(handle);
1014                 return NULL;
1015         }
1016
1017         appid = NULL;
1018         ret = sqlite3_bind_text(stmt, 1, lbid, -1, SQLITE_TRANSIENT);
1019         if (ret != SQLITE_OK) {
1020                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1021                 goto out;
1022         }
1023
1024         ret = sqlite3_step(stmt);
1025         if (ret == SQLITE_ROW) {
1026                 const char *tmp;
1027
1028                 tmp = (const char *)sqlite3_column_text(stmt, 0);
1029                 if (!tmp || !strlen(tmp))
1030                         goto out;
1031
1032                 appid = strdup(tmp);
1033                 if (!appid)
1034                         ErrPrint("Error: %s\n", strerror(errno));
1035         }
1036
1037 out:
1038         sqlite3_reset(stmt);
1039         sqlite3_finalize(stmt);
1040         close_db(handle);
1041         return appid;
1042 }
1043
1044 EAPI int livebox_service_nodisplay(const char *pkgid)
1045 {
1046         sqlite3_stmt *stmt;
1047         sqlite3 *handle;
1048         int ret;
1049
1050         handle = open_db();
1051         if (!handle)
1052                 return 0;
1053
1054         ret = sqlite3_prepare_v2(handle, "SELECT nodisplay FROM client WHERE pkgid = ?", -1, &stmt, NULL);
1055         if (ret != SQLITE_OK) {
1056                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1057                 close_db(handle);
1058                 return 0;
1059         }
1060
1061         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1062         if (ret != SQLITE_OK) {
1063                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1064                 ret = 0;
1065                 goto out;
1066         }
1067
1068         ret = sqlite3_step(stmt);
1069         if (ret == SQLITE_ROW)
1070                 ret = !!sqlite3_column_int(stmt, 0);
1071         else
1072                 ret = 0;
1073
1074 out:
1075         sqlite3_reset(stmt);
1076         sqlite3_finalize(stmt);
1077         close_db(handle);
1078         return ret;
1079 }
1080
1081 static inline char *get_lb_pkgname_by_appid(const char *appid)
1082 {
1083         sqlite3_stmt *stmt;
1084         char *pkgid;
1085         char *tmp;
1086         sqlite3 *handle;
1087         int ret;
1088
1089         if (!appid)
1090                 return NULL;
1091
1092         pkgid = NULL;
1093         handle = open_db();
1094         if (!handle)
1095                 return NULL;
1096
1097         ret = sqlite3_prepare_v2(handle, "SELECT pkgid FROM pkgmap WHERE (appid = ? AND prime = 1) OR pkgid = ?", -1, &stmt, NULL);
1098         if (ret != SQLITE_OK) {
1099                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1100                 close_db(handle);
1101                 return NULL;
1102         }
1103
1104         ret = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT);
1105         if (ret != SQLITE_OK) {
1106                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1107                 goto out;
1108         }
1109
1110         ret = sqlite3_bind_text(stmt, 2, appid, -1, SQLITE_TRANSIENT);
1111         if (ret != SQLITE_OK) {
1112                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1113                 goto out;
1114         }
1115
1116         if (sqlite3_step(stmt) != SQLITE_ROW) {
1117                 ErrPrint("Error: %s (has no record? - %s)\n", sqlite3_errmsg(handle), appid);
1118                 goto out;
1119         }
1120
1121         tmp = (char *)sqlite3_column_text(stmt, 0);
1122         if (tmp && strlen(tmp)) {
1123                 pkgid = strdup(tmp);
1124                 if (!pkgid)
1125                         ErrPrint("Heap: %s\n", strerror(errno));
1126         }
1127
1128 out:
1129         sqlite3_reset(stmt);
1130         sqlite3_finalize(stmt);
1131         close_db(handle);
1132         return pkgid;
1133 }
1134
1135 EAPI int livebox_service_need_frame(const char *pkgid, int size_type)
1136 {
1137         char *lbid;
1138         sqlite3_stmt *stmt;
1139         sqlite3 *handle;
1140         int ret;
1141
1142         handle = open_db();
1143         if (!handle) {
1144                 ErrPrint("Unable to open a DB\n");
1145                 return 0;
1146         }
1147
1148         ret = sqlite3_prepare_v2(handle, "SELECT need_frame FROM box_size WHERE pkgid = ? AND size_type = ?", -1, &stmt, NULL);
1149         if (ret != SQLITE_OK) {
1150                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1151                 close_db(handle);
1152                 return 0;
1153         }
1154
1155         /*!
1156          */
1157         lbid = livebox_service_pkgname(pkgid);
1158         if (!lbid) {
1159                 ErrPrint("Invalid appid (%s)\n", pkgid);
1160                 ret = 0;
1161                 goto out;
1162         }
1163
1164         ret = sqlite3_bind_text(stmt, 1, lbid, -1, SQLITE_TRANSIENT);
1165         free(lbid);
1166         if (ret != SQLITE_OK) {
1167                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1168                 ret = 0;
1169                 goto out;
1170         }
1171
1172         ret = sqlite3_bind_int(stmt, 2, size_type);
1173         if (ret != SQLITE_OK) {
1174                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1175                 ret = 0;
1176                 goto out;
1177         }
1178
1179         ret = sqlite3_step(stmt);
1180         if (ret == SQLITE_ROW) {
1181                 ret = !!sqlite3_column_int(stmt, 0);
1182         } else {
1183                 ret = 0;
1184                 ErrPrint("There is no such result\n");
1185         }
1186 out:
1187         sqlite3_reset(stmt);
1188         sqlite3_finalize(stmt);
1189         close_db(handle);
1190         return ret;
1191 }
1192
1193 EAPI int livebox_service_touch_effect(const char *pkgid, int size_type)
1194 {
1195         char *lbid;
1196         sqlite3_stmt *stmt;
1197         sqlite3 *handle;
1198         int ret;
1199
1200         handle = open_db();
1201         if (!handle) {
1202                 ErrPrint("Unable to open a DB\n");
1203                 return 1;
1204         }
1205
1206         ret = sqlite3_prepare_v2(handle, "SELECT touch_effect FROM box_size WHERE pkgid = ? AND size_type = ?", -1, &stmt, NULL);
1207         if (ret != SQLITE_OK) {
1208                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1209                 close_db(handle);
1210                 return 1;
1211         }
1212
1213         /*!
1214          * \note
1215          * This function will validate the "pkgid"
1216          * call the exported API in the exported API is not recomended
1217          * but... I used.
1218          */
1219         lbid = livebox_service_pkgname(pkgid);
1220         if (!lbid) {
1221                 ErrPrint("Invalid appid (%s)\n", pkgid);
1222                 ret = 1;
1223                 goto out;
1224         }
1225
1226         ret = sqlite3_bind_text(stmt, 1, lbid, -1, SQLITE_TRANSIENT);
1227         free(lbid);
1228         if (ret != SQLITE_OK) {
1229                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1230                 ret = 1;
1231                 goto out;
1232         }
1233
1234         ret = sqlite3_bind_int(stmt, 2, size_type);
1235         if (ret != SQLITE_OK) {
1236                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1237                 ret = 1;
1238                 goto out;
1239         }
1240
1241         ret = sqlite3_step(stmt);
1242         if (ret == SQLITE_ROW) {
1243                 ret = !!sqlite3_column_int(stmt, 0);
1244         } else {
1245                 ret = 1; /*!< Default true: In this case the DB is corrupted. */
1246                 ErrPrint("There is no result\n");
1247         }
1248
1249 out:
1250         sqlite3_reset(stmt);
1251         sqlite3_finalize(stmt);
1252         close_db(handle);
1253         return ret;
1254 }
1255
1256 EAPI int livebox_service_mouse_event(const char *pkgid)
1257 {
1258         sqlite3_stmt *stmt;
1259         sqlite3 *handle;
1260         char *lbid;
1261         int ret;
1262
1263         handle = open_db();
1264         if (!handle)
1265                 return 0;
1266
1267         ret = sqlite3_prepare_v2(handle, "SELECT mouse_event FROM client WHERE pkgid = ?", -1, &stmt, NULL);
1268         if (ret != SQLITE_OK) {
1269                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1270                 close_db(handle);
1271                 return 0;
1272         }
1273
1274         lbid = livebox_service_pkgname(pkgid);
1275         if (!lbid) {
1276                 ErrPrint("Failed to get lbid: %s\n", pkgid);
1277                 ret = 0;
1278                 goto out;
1279         }
1280
1281         ret = sqlite3_bind_text(stmt, 1, lbid, -1, SQLITE_TRANSIENT);
1282         free(lbid);
1283         if (ret != SQLITE_OK) {
1284                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1285                 ret = 0;
1286                 goto out;
1287         }
1288
1289         ret = sqlite3_step(stmt);
1290         if (ret == SQLITE_ROW) {
1291                 ret = !!sqlite3_column_int(stmt, 0);
1292         } else {
1293                 ret = 0; /*!< Default is false, In this case the DB is corrupted */
1294                 ErrPrint("There is no result.\n");
1295         }
1296
1297 out:
1298         sqlite3_reset(stmt);
1299         sqlite3_finalize(stmt);
1300         close_db(handle);
1301         return ret;
1302 }
1303
1304 EAPI char *livebox_service_preview(const char *pkgid, int size_type)
1305 {
1306         sqlite3_stmt *stmt;
1307         sqlite3 *handle;
1308         int ret;
1309         char *preview = NULL;
1310
1311         handle = open_db();
1312         if (!handle)
1313                 return NULL;
1314
1315         ret = sqlite3_prepare_v2(handle, "SELECT preview FROM box_size WHERE pkgid = ? AND size_type = ?", -1, &stmt, NULL);
1316         if (ret != SQLITE_OK) {
1317                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1318                 close_db(handle);
1319                 return NULL;
1320         }
1321
1322         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1323         if (ret != SQLITE_OK) {
1324                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1325                 goto out;
1326         }
1327
1328         ret = sqlite3_bind_int(stmt, 2, size_type);
1329         if (ret != SQLITE_OK) {
1330                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1331                 goto out;
1332         }
1333
1334         ret = sqlite3_step(stmt);
1335         if (ret == SQLITE_ROW) {
1336                 const char *tmp;
1337                 tmp = (const char *)sqlite3_column_text(stmt, 0);
1338                 if (tmp && strlen(tmp)) {
1339                         preview = strdup(tmp);
1340                         if (!preview)
1341                                 ErrPrint("Heap: %s\n", strerror(errno));
1342                 }
1343         }
1344
1345 out:
1346         sqlite3_reset(stmt);
1347         sqlite3_finalize(stmt);
1348         close_db(handle);
1349         return preview;
1350 }
1351
1352 EAPI char *livebox_service_i18n_icon(const char *pkgid, const char *lang)
1353 {
1354         sqlite3_stmt *stmt;
1355         sqlite3 *handle;
1356         char *language;
1357         char *icon = NULL;
1358         int ret;
1359
1360         if (lang) {
1361                 language = strdup(lang);
1362                 if (!language) {
1363                         ErrPrint("Heap: %s\n", strerror(errno));
1364                         return NULL;
1365                 }
1366         } else {
1367                 language = cur_locale();
1368                 if (!language)
1369                         return NULL;
1370         }
1371
1372         handle = open_db();
1373         if (!handle) {
1374                 free(language);
1375                 return NULL;
1376         }
1377
1378         ret = sqlite3_prepare_v2(handle, "SELECT icon FROM i18n WHERE pkgid = ? AND lang = ?", -1, &stmt, NULL);
1379         if (ret != SQLITE_OK) {
1380                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1381                 close_db(handle);
1382                 free(language);
1383                 return NULL;
1384         }
1385
1386         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1387         if (ret != SQLITE_OK) {
1388                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1389                 goto out;
1390         }
1391
1392         ret = sqlite3_bind_text(stmt, 2, language, -1, SQLITE_TRANSIENT);
1393         if (ret != SQLITE_OK) {
1394                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1395                 goto out;
1396         }
1397
1398         ret = sqlite3_step(stmt);
1399         if (ret == SQLITE_ROW) {
1400                 const char *tmp;
1401                 tmp = (const char *)sqlite3_column_text(stmt, 0);
1402                 if (!tmp || !strlen(tmp)) {
1403                         icon = get_default_icon(pkgid);
1404                 } else {
1405                         icon = strdup(tmp);
1406                         if (!icon)
1407                                 ErrPrint("Heap: %s\n", strerror(errno));
1408                 }
1409         } else {
1410                 icon = get_default_icon(pkgid);
1411         }
1412
1413 out:
1414         sqlite3_reset(stmt);
1415         sqlite3_finalize(stmt);
1416         close_db(handle);
1417         free(language);
1418         return icon;
1419 }
1420
1421 EAPI char *livebox_service_i18n_name(const char *pkgid, const char *lang)
1422 {
1423         sqlite3_stmt *stmt;
1424         sqlite3 *handle;
1425         char *language;
1426         char *name = NULL;
1427         int ret;
1428
1429         if (lang) {
1430                 language = strdup(lang);
1431                 if (!language) {
1432                         ErrPrint("Error: %s\n", strerror(errno));
1433                         return NULL;
1434                 }
1435         } else {
1436                 language = cur_locale();
1437                 if (!language)
1438                         return NULL;
1439         }
1440
1441         handle = open_db();
1442         if (!handle) {
1443                 free(language);
1444                 return NULL;
1445         }
1446
1447         ret = sqlite3_prepare_v2(handle, "SELECT name FROM i18n WHERE pkgid = ? AND lang = ?", -1, &stmt, NULL);
1448         if (ret != SQLITE_OK) {
1449                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1450                 close_db(handle);
1451                 free(language);
1452                 return NULL;
1453         }
1454
1455         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1456         if (ret != SQLITE_OK) {
1457                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1458                 goto out;
1459         }
1460
1461         ret = sqlite3_bind_text(stmt, 2, language, -1, SQLITE_TRANSIENT);
1462         if (ret != SQLITE_OK) {
1463                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1464                 goto out;
1465         }
1466
1467         ret = sqlite3_step(stmt);
1468         if (ret == SQLITE_ROW) {
1469                 const char *tmp;
1470                 tmp = (const char *)sqlite3_column_text(stmt, 0);
1471                 if (!tmp || !strlen(tmp)) {
1472                         name = get_default_name(pkgid);
1473                 } else {
1474                         name = strdup(tmp);
1475                         if (!name)
1476                                 ErrPrint("Heap: %s\n", strerror(errno));
1477                 }
1478         } else {
1479                 name = get_default_name(pkgid);
1480         }
1481
1482 out:
1483         sqlite3_reset(stmt);
1484         sqlite3_finalize(stmt);
1485         close_db(handle);
1486         free(language);
1487         return name;
1488 }
1489
1490 EAPI int livebox_service_get_supported_sizes(const char *pkgid, int *cnt, int *w, int *h)
1491 {
1492         sqlite3_stmt *stmt;
1493         sqlite3 *handle;
1494         int size;
1495         int ret;
1496
1497         if (!w || !h || !cnt || !pkgid)
1498                 return LB_STATUS_ERROR_INVALID;
1499
1500         handle = open_db();
1501         if (!handle)
1502                 return LB_STATUS_ERROR_IO;
1503
1504         ret = sqlite3_prepare_v2(handle, "SELECT size_type FROM box_size WHERE pkgid = ? ORDER BY size_type ASC", -1, &stmt, NULL);
1505         if (ret != SQLITE_OK) {
1506                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1507                 ret = LB_STATUS_ERROR_IO;
1508                 goto out;
1509         }
1510
1511         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1512         if (ret != SQLITE_OK) {
1513                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1514                 sqlite3_reset(stmt);
1515                 sqlite3_finalize(stmt);
1516                 ret = LB_STATUS_ERROR_IO;
1517                 goto out;
1518         }
1519
1520         if (*cnt > NR_OF_SIZE_LIST)
1521                 *cnt = NR_OF_SIZE_LIST;
1522
1523         ret = 0;
1524         while (sqlite3_step(stmt) == SQLITE_ROW && ret < *cnt) {
1525                 size = sqlite3_column_int(stmt, 0);
1526                 ret += (convert_size_from_type(size, w + ret, h + ret) == 0);
1527         }
1528
1529         *cnt = ret;
1530         sqlite3_reset(stmt);
1531         sqlite3_finalize(stmt);
1532         ret = 0;
1533 out:
1534         close_db(handle);
1535         return ret;
1536 }
1537
1538 EAPI char *livebox_service_libexec(const char *pkgid)
1539 {
1540         sqlite3_stmt *stmt;
1541         sqlite3 *handle;
1542         int ret;
1543         char *libexec;
1544         char *appid;
1545         char *path;
1546
1547         if (!pkgid)
1548                 return NULL;
1549
1550         libexec = NULL;
1551         handle = open_db();
1552         if (!handle)
1553                 return NULL;
1554
1555         ret = sqlite3_prepare_v2(handle, "SELECT pkgmap.appid, provider.libexec FROM pkgmap, provider WHERE pkgmap.pkgid = ? AND provider.pkgid = ?", -1, &stmt, NULL);
1556         if (ret != SQLITE_OK) {
1557                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1558                 goto out;
1559         }
1560
1561         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1562         if (ret != SQLITE_OK) {
1563                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1564                 sqlite3_finalize(stmt);
1565                 goto out;
1566         }
1567
1568         ret = sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_TRANSIENT);
1569         if (ret != SQLITE_OK) {
1570                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1571                 sqlite3_finalize(stmt);
1572                 goto out;
1573         }
1574
1575         if (sqlite3_step(stmt) != SQLITE_ROW) {
1576                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1577                 sqlite3_reset(stmt);
1578                 sqlite3_finalize(stmt);
1579
1580                 libexec = util_conf_get_libexec(pkgid);
1581                 DbgPrint("Fallback to conf checker: %s\n", libexec);
1582                 goto out;
1583         }
1584
1585         appid = (char *)sqlite3_column_text(stmt, 0);
1586         if (!appid || !strlen(appid)) {
1587                 ErrPrint("Invalid appid: %s\n", sqlite3_errmsg(handle));
1588                 sqlite3_reset(stmt);
1589                 sqlite3_finalize(stmt);
1590                 goto out;
1591         }
1592
1593         path = (char *)sqlite3_column_text(stmt, 1);
1594         if (!path || !strlen(path)) {
1595                 ErrPrint("Invalid libexec: %s\n", sqlite3_errmsg(handle));
1596                 sqlite3_reset(stmt);
1597                 sqlite3_finalize(stmt);
1598                 goto out;
1599         }
1600
1601         libexec = strdup(path);
1602         if (!libexec) {
1603                 ErrPrint("Heap: %s\n", strerror(errno));
1604                 sqlite3_reset(stmt);
1605                 sqlite3_finalize(stmt);
1606                 goto out;
1607         }
1608
1609         DbgPrint("libexec: %s\n", libexec);
1610
1611         sqlite3_reset(stmt);
1612         sqlite3_finalize(stmt);
1613 out:
1614         close_db(handle);
1615         return libexec;
1616 }
1617
1618 EAPI char *livebox_service_pkgname(const char *appid)
1619 {
1620         char *lb_pkgname;
1621         pkgmgr_appinfo_h handle;
1622         int ret;
1623         char *new_appid;
1624
1625         if (!appid)
1626                 return NULL;
1627
1628         lb_pkgname = get_lb_pkgname_by_appid(appid);
1629         if (lb_pkgname)
1630                 return lb_pkgname;
1631
1632         /*!
1633          * \note
1634          * Try to get the package id using given appid
1635          */
1636         ret = pkgmgr_appinfo_get_appinfo(appid, &handle);
1637         if (ret != PKGMGR_R_OK) {
1638                 ErrPrint("Failed to get appinfo\n");
1639                 return NULL;
1640         }
1641
1642         ret = pkgmgr_appinfo_get_pkgname(handle, &new_appid);
1643         if (ret != PKGMGR_R_OK) {
1644                 pkgmgr_appinfo_destroy_appinfo(handle);
1645                 ErrPrint("Failed to get pkgname for (%s)\n", appid);
1646                 return NULL;
1647         }
1648
1649         lb_pkgname = get_lb_pkgname_by_appid(new_appid);
1650         pkgmgr_appinfo_destroy_appinfo(handle);
1651
1652         if (!lb_pkgname && util_validate_livebox_package(appid) == 0)
1653                 return strdup(appid);
1654
1655         return lb_pkgname;
1656 }
1657
1658 EAPI char *livebox_service_provider_name(const char *lbid)
1659 {
1660         char *ret;
1661         int stage = 0;
1662         int seq = 0;
1663         int idx = 0;
1664         char *str = SAMSUNG_PREFIX;
1665
1666         if (!lbid)
1667                 return NULL;
1668
1669         while (str[idx] && lbid[idx] && lbid[idx] == str[idx]) {
1670                 idx++;
1671                 if (seq < 2 && lbid[idx] == '.') {
1672                         stage = idx;
1673                         seq++;
1674                 }
1675         }
1676
1677         if (!str[idx] && lbid[idx]) {
1678                 /* Inhouse */
1679                 return strdup(lbid);
1680         } else if (seq < 2) {
1681                 while (seq < 2) {
1682                         if (lbid[idx] == '.') {
1683                                 seq++;
1684                         } else if (!lbid[idx]) {
1685                                 ErrPrint("Invalid lbid: %s\n", lbid);
1686                                 return NULL;
1687                         }
1688
1689                         idx++;
1690                 }
1691
1692                 stage = idx;
1693         } else {
1694                 stage++;
1695         }
1696
1697         ret = strdup(lbid + stage);
1698         if (!ret) {
1699                 ErrPrint("Error: %s\n", strerror(errno));
1700                 return NULL;
1701         }
1702
1703         return ret;
1704 }
1705
1706 EAPI int livebox_service_is_enabled(const char *lbid)
1707 {
1708         return 1;
1709         /*
1710         ail_appinfo_h ai;
1711         char *pkgname;
1712         bool enabled;
1713         int ret;
1714
1715         pkgname = livebox_service_appid(lbid);
1716         if (!pkgname)
1717                 return 0;
1718
1719         ret = ail_get_appinfo(pkgname, &ai);
1720         if (ret != AIL_ERROR_OK) {
1721                 free(pkgname);
1722                 return 0;
1723         }
1724
1725         if (ail_appinfo_get_bool(ai, AIL_PROP_X_SLP_ENABLED_BOOL, &enabled) != AIL_ERROR_OK)
1726                 enabled = false;
1727
1728         ail_destroy_appinfo(ai);
1729         free(pkgname);
1730         return enabled == true;
1731         */
1732 }
1733
1734 EAPI int livebox_service_is_primary(const char *lbid)
1735 {
1736         sqlite3_stmt *stmt;
1737         sqlite3 *handle;
1738         int ret = 0;
1739
1740         if (!lbid)
1741                 return 0;
1742
1743         handle = open_db();
1744         if (!handle)
1745                 return 0;
1746
1747         ret = sqlite3_prepare_v2(handle, "SELECT prime FROM pkgmap WHERE pkgid = ?", -1, &stmt, NULL);
1748         if (ret != SQLITE_OK) {
1749                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1750                 close_db(handle);
1751                 return 0;
1752         }
1753
1754         ret = sqlite3_bind_text(stmt, 1, lbid, -1, SQLITE_TRANSIENT);
1755         if (ret != SQLITE_OK) {
1756                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1757                 goto out;
1758         }
1759
1760         ret = sqlite3_step(stmt);
1761         if (ret != SQLITE_ROW) {
1762                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1763                 goto out;
1764         }
1765
1766         ret = sqlite3_column_int(stmt, 0);
1767
1768 out:
1769         sqlite3_reset(stmt);
1770         sqlite3_finalize(stmt);
1771         close_db(handle);
1772         return ret;
1773 }
1774
1775 /*!
1776  * appid == Package ID
1777  * pkgid == Livebox ID
1778  */
1779 EAPI char *livebox_service_appid(const char *pkgname)
1780 {
1781         sqlite3_stmt *stmt;
1782         char *appid;
1783         char *tmp;
1784         sqlite3 *handle;
1785         int is_prime __attribute__((__unused__));
1786         int ret;
1787
1788         if (!pkgname)
1789                 return NULL;
1790
1791         appid = NULL;
1792         handle = open_db();
1793         if (!handle)
1794                 return NULL;
1795
1796         ret = sqlite3_prepare_v2(handle, "SELECT appid, prime FROM pkgmap WHERE pkgid = ? OR appid = ?", -1, &stmt, NULL);
1797         if (ret != SQLITE_OK) {
1798                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1799                 goto out;
1800         }
1801
1802         ret = sqlite3_bind_text(stmt, 1, pkgname, -1, SQLITE_TRANSIENT);
1803         if (ret != SQLITE_OK) {
1804                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1805                 sqlite3_reset(stmt);
1806                 sqlite3_finalize(stmt);
1807                 goto out;
1808         }
1809
1810         ret = sqlite3_bind_text(stmt, 2, pkgname, -1, SQLITE_TRANSIENT);
1811         if (ret != SQLITE_OK) {
1812                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1813                 sqlite3_reset(stmt);
1814                 sqlite3_finalize(stmt);
1815                 goto out;
1816         }
1817
1818         ret = sqlite3_step(stmt);
1819         if (ret != SQLITE_ROW) {
1820                 pkgmgr_appinfo_h pkg_handle;
1821                 char *new_appid;
1822
1823                 ErrPrint("Has no record?: %s\n", sqlite3_errmsg(handle));
1824                 sqlite3_reset(stmt);
1825                 sqlite3_finalize(stmt);
1826
1827                 ret = pkgmgr_appinfo_get_appinfo(pkgname, &pkg_handle);
1828                 if (ret != PKGMGR_R_OK) {
1829                         ErrPrint("Failed to get appinfo: %s\n", pkgname);
1830                         goto out;
1831                 }
1832
1833                 ret = pkgmgr_appinfo_get_pkgname(pkg_handle, &new_appid);
1834                 if (ret != PKGMGR_R_OK) {
1835                         ErrPrint("Failed to get pkgname for (%s)\n", appid);
1836                         pkgmgr_appinfo_destroy_appinfo(pkg_handle);
1837                         goto out;
1838                 }
1839
1840                 appid = strdup(new_appid);
1841                 if (!appid)
1842                         ErrPrint("Heap: %s\n", strerror(errno));
1843
1844                 pkgmgr_appinfo_destroy_appinfo(pkg_handle);
1845                 goto out;
1846         }
1847
1848         tmp = (char *)sqlite3_column_text(stmt, 0);
1849         if (!tmp || !strlen(tmp)) {
1850                 ErrPrint("APPID is NIL\n");
1851                 sqlite3_reset(stmt);
1852                 sqlite3_finalize(stmt);
1853                 goto out;
1854         }
1855
1856         appid = strdup(tmp);
1857         if (!appid) {
1858                 ErrPrint("Heap: %s\n", strerror(errno));
1859                 sqlite3_reset(stmt);
1860                 sqlite3_finalize(stmt);
1861                 goto out;
1862         }
1863
1864         is_prime = sqlite3_column_int(stmt, 1);
1865
1866         sqlite3_reset(stmt);
1867         sqlite3_finalize(stmt);
1868 out:
1869         close_db(handle);
1870         return appid;
1871 }
1872
1873 EAPI char *livebox_service_lb_script_path(const char *pkgid)
1874 {
1875         sqlite3_stmt *stmt;
1876         sqlite3 *handle;
1877         int ret;
1878         char *path;
1879         char *appid;
1880         char *lb_src;
1881
1882         if (!pkgid)
1883                 return NULL;
1884
1885         path = NULL;
1886         handle = open_db();
1887         if (!handle)
1888                 return NULL;
1889
1890         ret = sqlite3_prepare_v2(handle, "SELECT pkgmap.appid, provider.box_src FROM provider, pkgmap WHERE pkgmap.pkgid = ? AND provider.pkgid = ?", -1, &stmt, NULL);
1891         if (ret != SQLITE_OK) {
1892                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1893                 goto out;
1894         }
1895
1896         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1897         if (ret != SQLITE_OK) {
1898                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1899                 sqlite3_finalize(stmt);
1900                 goto out;
1901         }
1902
1903         ret = sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_TRANSIENT);
1904         if (ret != SQLITE_OK) {
1905                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1906                 sqlite3_finalize(stmt);
1907                 goto out;
1908         }
1909
1910         ret = sqlite3_step(stmt);
1911         if (ret != SQLITE_ROW) {
1912                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1913                 sqlite3_reset(stmt);
1914                 sqlite3_finalize(stmt);
1915                 goto out;
1916         }
1917
1918         appid = (char *)sqlite3_column_text(stmt, 0);
1919         if (!appid || !strlen(appid)) {
1920                 ErrPrint("Invalid appid : %s\n", sqlite3_errmsg(handle));
1921                 sqlite3_reset(stmt);
1922                 sqlite3_finalize(stmt);
1923                 goto out;
1924         }
1925
1926         lb_src = (char *)sqlite3_column_text(stmt, 1);
1927         if (!lb_src || !strlen(lb_src)) {
1928                 ErrPrint("No records for lb src : %s\n", sqlite3_errmsg(handle));
1929                 sqlite3_reset(stmt);
1930                 sqlite3_finalize(stmt);
1931                 goto out;
1932         }
1933
1934         path = strdup(lb_src);
1935         if (!path) {
1936                 ErrPrint("Heap: %s\n", strerror(errno));
1937                 sqlite3_reset(stmt);
1938                 sqlite3_finalize(stmt);
1939                 goto out;
1940         }
1941
1942         DbgPrint("LB Src: %s\n", path);
1943
1944         sqlite3_reset(stmt);
1945         sqlite3_finalize(stmt);
1946 out:
1947         close_db(handle);
1948         return path;
1949 }
1950
1951 EAPI char *livebox_service_lb_script_group(const char *pkgid)
1952 {
1953         sqlite3_stmt *stmt;
1954         sqlite3 *handle;
1955         int ret;
1956         char *group;
1957         char *tmp;
1958
1959         if (!pkgid)
1960                 return NULL;
1961
1962         group = NULL;
1963         handle = open_db();
1964         if (!handle)
1965                 return NULL;
1966
1967         ret = sqlite3_prepare_v2(handle, "SELECT box_group FROM provider WHERE pkgid = ?", -1, &stmt, NULL);
1968         if (ret != SQLITE_OK) {
1969                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1970                 goto out;
1971         }
1972
1973         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1974         if (ret != SQLITE_OK) {
1975                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1976                 sqlite3_finalize(stmt);
1977                 goto out;
1978         }
1979
1980         ret = sqlite3_step(stmt);
1981         if (ret != SQLITE_ROW) {
1982                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
1983                 sqlite3_reset(stmt);
1984                 sqlite3_finalize(stmt);
1985                 goto out;
1986         }
1987
1988         tmp = (char *)sqlite3_column_text(stmt, 0);
1989         if (tmp && strlen(tmp)) {
1990                 group = strdup(tmp);
1991                 if (!group)
1992                         ErrPrint("Heap: %s\n", strerror(errno));
1993         }
1994
1995         sqlite3_reset(stmt);
1996         sqlite3_finalize(stmt);
1997 out:
1998         close_db(handle);
1999         return group;
2000 }
2001
2002 EAPI char *livebox_service_pd_script_path(const char *pkgid)
2003 {
2004         sqlite3_stmt *stmt;
2005         sqlite3 *handle;
2006         int ret;
2007         char *path;
2008         char *pd_src;
2009         const char *appid;
2010
2011         if (!pkgid)
2012                 return NULL;
2013
2014         path = NULL;
2015         handle = open_db();
2016         if (!handle)
2017                 return NULL;
2018
2019         ret = sqlite3_prepare_v2(handle, "SELECT pkgmap.appid, provider.pd_src FROM provider, pkgmap WHERE provider.pkgid = ? AND pkgmap.pkgid = ?", -1, &stmt, NULL);
2020         if (ret != SQLITE_OK) {
2021                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
2022                 goto out;
2023         }
2024
2025         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
2026         if (ret != SQLITE_OK) {
2027                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
2028                 sqlite3_finalize(stmt);
2029                 goto out;
2030         }
2031
2032         ret = sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_TRANSIENT);
2033         if (ret != SQLITE_OK) {
2034                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
2035                 sqlite3_finalize(stmt);
2036                 goto out;
2037         }
2038
2039         ret = sqlite3_step(stmt);
2040         if (ret != SQLITE_ROW) {
2041                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
2042                 sqlite3_reset(stmt);
2043                 sqlite3_finalize(stmt);
2044                 goto out;
2045         }
2046
2047         appid = (char *)sqlite3_column_text(stmt, 0);
2048         if (!appid || !strlen(appid)) {
2049                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
2050                 sqlite3_reset(stmt);
2051                 sqlite3_finalize(stmt);
2052                 goto out;
2053         }
2054
2055         pd_src = (char *)sqlite3_column_text(stmt, 1);
2056         if (!pd_src || !strlen(pd_src)) {
2057                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
2058                 sqlite3_reset(stmt);
2059                 sqlite3_finalize(stmt);
2060                 goto out;
2061         }
2062
2063         path = strdup(pd_src);
2064         if (!path) {
2065                 ErrPrint("Heap: %s\n", strerror(errno));
2066                 sqlite3_reset(stmt);
2067                 sqlite3_finalize(stmt);
2068                 goto out;
2069         }
2070
2071         DbgPrint("PD Src: %s\n", path);
2072         sqlite3_reset(stmt);
2073         sqlite3_finalize(stmt);
2074 out:
2075         close_db(handle);
2076         return path;
2077 }
2078
2079 EAPI char *livebox_service_pd_script_group(const char *pkgid)
2080 {
2081         sqlite3_stmt *stmt;
2082         sqlite3 *handle;
2083         int ret;
2084         char *group;
2085         char *tmp;
2086
2087         if (!pkgid)
2088                 return NULL;
2089
2090         group = NULL;
2091         handle = open_db();
2092         if (!handle)
2093                 return NULL;
2094
2095         ret = sqlite3_prepare_v2(handle, "SELECT pd_group FROM provider WHERE pkgid = ?", -1, &stmt, NULL);
2096         if (ret != SQLITE_OK) {
2097                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
2098                 goto out;
2099         }
2100
2101         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
2102         if (ret != SQLITE_OK) {
2103                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
2104                 sqlite3_finalize(stmt);
2105                 goto out;
2106         }
2107
2108         ret = sqlite3_step(stmt);
2109         if (ret != SQLITE_ROW) {
2110                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
2111                 sqlite3_reset(stmt);
2112                 sqlite3_finalize(stmt);
2113                 goto out;
2114         }
2115
2116         tmp = (char *)sqlite3_column_text(stmt, 0);
2117         if (tmp && strlen(tmp)) {
2118                 group = strdup(tmp);
2119                 if (!group)
2120                         ErrPrint("Heap: %s\n", strerror(errno));
2121         }
2122         sqlite3_reset(stmt);
2123         sqlite3_finalize(stmt);
2124 out:
2125         close_db(handle);
2126         return group;
2127 }
2128
2129 EAPI int livebox_service_enumerate_cluster_list(int (*cb)(const char *cluster, void *data), void *data)
2130 {
2131         sqlite3_stmt *stmt;
2132         sqlite3 *handle;
2133         const char *cluster;
2134         int cnt;
2135         int ret;
2136
2137         if (!cb)
2138                 return LB_STATUS_ERROR_INVALID;
2139
2140         handle = open_db();
2141         if (!handle)
2142                 return LB_STATUS_ERROR_IO;
2143
2144         cnt = 0;
2145         ret = sqlite3_prepare_v2(handle, "SELECT DISTINCT cluster FROM groupinfo", -1, &stmt, NULL);
2146         if (ret != SQLITE_OK) {
2147                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
2148                 cnt = LB_STATUS_ERROR_IO;
2149                 goto out;
2150         }
2151
2152         while (sqlite3_step(stmt) == SQLITE_ROW) {
2153                 cluster = (const char *)sqlite3_column_text(stmt, 0);
2154                 if (!cluster || !strlen(cluster))
2155                         continue;
2156
2157                 if (cb(cluster, data) < 0)
2158                         break;
2159
2160                 cnt++;
2161         }
2162
2163         sqlite3_reset(stmt);
2164         sqlite3_finalize(stmt);
2165 out:
2166         close_db(handle);
2167         return cnt;
2168 }
2169
2170 EAPI int livebox_service_enumerate_category_list(const char *cluster, int (*cb)(const char *cluster, const char *category, void *data), void *data)
2171 {
2172         sqlite3_stmt *stmt;
2173         sqlite3 *handle;
2174         const char *category;
2175         int cnt;
2176         int ret;
2177
2178         if (!cluster || !cb)
2179                 return LB_STATUS_ERROR_INVALID;
2180
2181         handle = open_db();
2182         if (!handle)
2183                 return LB_STATUS_ERROR_IO;
2184
2185         ret = sqlite3_prepare_v2(handle, "SELECT DISTINCT category FROM groupinfo WHERE cluster = ?", -1, &stmt, NULL);
2186         if (ret != SQLITE_OK) {
2187                 ErrPrint("Error: %s\n", sqlite3_errmsg(handle));
2188                 cnt = LB_STATUS_ERROR_IO;
2189                 goto out;
2190         }
2191
2192         cnt = 0;
2193         while (sqlite3_step(stmt) == SQLITE_ROW) {
2194                 category = (const char *)sqlite3_column_text(stmt, 0);
2195                 if (!category || !strlen(category))
2196                         continue;
2197
2198                 if (cb(cluster, category, data) < 0)
2199                         break;
2200
2201                 cnt++;
2202         }
2203
2204         sqlite3_reset(stmt);
2205         sqlite3_finalize(stmt);
2206 out:
2207         close_db(handle);
2208         return cnt;
2209 }
2210
2211 EAPI int livebox_service_init(void)
2212 {
2213         if (s_info.handle) {
2214                 DbgPrint("Already initialized\n");
2215                 s_info.init_count++;
2216                 return 0;
2217         }
2218
2219         s_info.handle = open_db();
2220         if (s_info.handle) {
2221                 s_info.init_count++;
2222                 return 0;
2223         }
2224
2225         return LB_STATUS_ERROR_IO;
2226 }
2227
2228 EAPI int livebox_service_fini(void)
2229 {
2230         if (!s_info.handle || s_info.init_count <= 0) {
2231                 ErrPrint("Service is not initialized\n");
2232                 return LB_STATUS_ERROR_IO;
2233         }
2234
2235         s_info.init_count--;
2236         if (s_info.init_count > 0) {
2237                 DbgPrint("Init count %d\n", s_info.init_count);
2238                 return 0;
2239         }
2240
2241         db_util_close(s_info.handle);
2242         s_info.handle = NULL;
2243         return 0;
2244 }
2245
2246 EAPI int livebox_service_get_size(int type, int *width, int *height)
2247 {
2248         int _width;
2249         int _height;
2250
2251         if (!width)
2252                 width = &_width;
2253
2254         if (!height)
2255                 height = &_height;
2256
2257         return convert_size_from_type(type, width, height);
2258 }
2259
2260 EAPI int livebox_service_size_type(int width, int height)
2261 {
2262         int idx;
2263
2264         if (update_resolution() < 0)
2265                 ErrPrint("Failed to update the size list\n");
2266
2267         for (idx = 0; idx < NR_OF_SIZE_LIST; idx++) {
2268                 if (SIZE_LIST[idx].w == width && SIZE_LIST[idx].h == height)
2269                         break;
2270         }
2271
2272         switch (idx) {
2273         case 0:
2274                 return LB_SIZE_TYPE_1x1;
2275         case 1:
2276                 return LB_SIZE_TYPE_2x1;
2277         case 2:
2278                 return LB_SIZE_TYPE_2x2;
2279         case 3:
2280                 return LB_SIZE_TYPE_4x1;
2281         case 4:
2282                 return LB_SIZE_TYPE_4x2;
2283         case 5:
2284                 return LB_SIZE_TYPE_4x3;
2285         case 6:
2286                 return LB_SIZE_TYPE_4x4;
2287         case 7:
2288                 return LB_SIZE_TYPE_4x5;
2289         case 8:
2290                 return LB_SIZE_TYPE_4x6;
2291         case 9:
2292                 return LB_SIZE_TYPE_EASY_1x1;
2293         case 10:
2294                 return LB_SIZE_TYPE_EASY_3x1;
2295         case 11:
2296                 return LB_SIZE_TYPE_EASY_3x3;
2297         case 12:
2298                 return LB_SIZE_TYPE_0x0;
2299         default:
2300                 break;
2301         }
2302
2303         return LB_SIZE_TYPE_UNKNOWN;
2304 }
2305
2306 /* End of a file */