Clean Code
[platform/core/appfw/ail.git] / src / ail_desktop.c
1 /*
2  * ail
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22
23
24 #define _GNU_SOURCE
25 #include <errno.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <time.h>
31 #include <sys/types.h>
32 #include <sys/wait.h>
33 #include <xdgmime.h>
34
35 #include <vconf.h>
36 #include <glib.h>
37 #include <grp.h>
38 #include <pwd.h>
39
40 #include "ail_private.h"
41 #include "ail_db.h"
42 #include "ail_sql.h"
43 #include "ail.h"
44
45 #define BUFSIZE 4096
46 #define GLOBAL_USER 0
47
48 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
49 #define argsdelimiter   " \t"
50
51 #define SQL_INSERT_LOCALNAME_STR "insert into localname (package, locale, name) values "
52 #define SQL_INSERT_LOCALNAME_STR_LEN (sizeof(SQL_INSERT_LOCALNAME_STR)-1)
53
54 #define SQL_INSERT_LOCALNAME_INIT_STR  SQL_INSERT_LOCALNAME_STR"( ?, ?, ?) "
55
56 #define SQL_LOCALNAME_TRIPLET_STR  ", ( ?, ?, ?)"
57 #define SQL_LOCALNAME_TRIPLET_STR_LEN (sizeof(SQL_LOCALNAME_TRIPLET_STR)-1)
58
59 typedef enum {
60         NOTI_ADD,
61         NOTI_UPDATE,
62         NOTI_REMOVE,
63         NOTI_MAX,
64 } noti_type;
65
66 struct entry_parser {
67         const char *field;
68         ail_error_e (*value_cb)(void *data, char *tag, char *value);
69 };
70
71 inline static char *_ltrim(char *str)
72 {
73         if (!str) return NULL;
74
75         while (*str == ' ' || *str == '\t' || *str == '\n') str ++;
76
77         return str;
78 }
79
80
81
82 inline static int _rtrim(char *str)
83 {
84         int len;
85
86         len = strlen(str);
87         while (--len >= 0 && (str[len] == ' ' || str[len] == '\n' || str[len] == '\t')) str[len] = '\0';
88
89         return len;
90 }
91
92 struct name_item {
93         char *locale;
94         char *name;
95 };
96
97 typedef struct {
98         const char*     package;
99         char*           exec;
100         char*           name;
101         char*           type;
102         char*           icon;
103         char*           categories;
104         char*           version;
105         char*           mimetype;
106         char*           x_slp_service;
107         char*           x_slp_packagetype;
108         char*           x_slp_packagecategories;
109         char*           x_slp_packageid;
110         char*           x_slp_uri;
111         char*           x_slp_svc;
112         char*           x_slp_exe_path;
113         char*           x_slp_appid;
114         char*           x_slp_pkgid;
115         char*           x_slp_domain;
116         char*           x_slp_submodemainid;
117         char*           x_slp_installedstorage;
118         int             x_slp_baselayoutwidth;
119         int             x_slp_installedtime;
120         int             nodisplay;
121         int             x_slp_taskmanage;
122         int             x_slp_multiple;
123         int             x_slp_removable;
124         int             x_slp_ishorizontalscale;
125         int             x_slp_enabled;
126         int             x_slp_submode;
127         char*           desktop;
128         GSList*         localname;
129 } desktop_info_s;
130
131
132
133 static ail_error_e _read_exec(void *data, char *tag, char *value)
134 {
135         desktop_info_s *info = data;
136         char *token_exe_path;
137         char *save_ptr;
138         char *temp_exec;
139
140         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
141         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
142
143         SAFE_FREE_AND_STRDUP(value, info->exec);
144         retv_if(!info->exec, AIL_ERROR_OUT_OF_MEMORY);
145
146         temp_exec = strdup(value);
147         if(!temp_exec) {
148                 free(info->exec);
149                 return AIL_ERROR_OUT_OF_MEMORY;
150         }
151
152         token_exe_path = strtok_r(temp_exec, argsdelimiter, &save_ptr);
153
154         info->x_slp_exe_path = strdup(token_exe_path);
155         if(!info->x_slp_exe_path) {
156                 free(info->exec);
157                 info->exec = NULL;
158                 free(temp_exec);
159                 return AIL_ERROR_OUT_OF_MEMORY;
160         }
161
162         free(temp_exec);
163
164         return AIL_ERROR_OK;
165 }
166
167
168
169 static ail_error_e _read_name(void *data, char *tag, char *value)
170 {
171         desktop_info_s *info = data;
172
173         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
174         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
175         retv_if(0 == strlen(value), AIL_ERROR_FAIL);
176
177         if (tag && strlen(tag) > 0) {
178                 struct name_item *item;
179                 item = (struct name_item *)calloc(1, sizeof(struct name_item));
180                 retv_if (NULL == item, AIL_ERROR_OUT_OF_MEMORY);
181
182                 SAFE_FREE_AND_STRDUP(tag, item->locale);
183                 if(NULL == item->locale) {
184                         _E("(NULL == item->locale) return\n");
185                         free(item);
186                         return AIL_ERROR_OUT_OF_MEMORY;
187                 }
188
189                 SAFE_FREE_AND_STRDUP(value, item->name);
190                 if(NULL == item->name) {
191                         _E("(NULL == item->name) return\n");
192                         free(item->locale);
193                         free(item);
194                         return AIL_ERROR_OUT_OF_MEMORY;
195                 }
196
197                 info->localname = g_slist_append(info->localname, item);
198
199                 return AIL_ERROR_OK;
200         } else {
201                 SAFE_FREE_AND_STRDUP(value, info->name);
202                 retv_if (!info->name, AIL_ERROR_OUT_OF_MEMORY);
203
204                 return AIL_ERROR_OK;
205         }
206 }
207
208
209
210 static ail_error_e _read_type(void *data, char *tag, char *value)
211 {
212         desktop_info_s *info = data;
213
214         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
215         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
216
217         SAFE_FREE_AND_STRDUP(value, info->type);
218         retv_if (!info->type, AIL_ERROR_OUT_OF_MEMORY);
219
220         return AIL_ERROR_OK;
221 }
222
223
224 static char*
225 _get_package_from_icon(char* icon)
226 {
227         char* package;
228         char* extension;
229
230         retv_if(!icon, NULL);
231
232         package = strdup(icon);
233         retv_if(!package, NULL);
234         extension = rindex(package, '.');
235         if (extension) {
236                 *extension = '\0';
237         } else {
238                 _E("cannot extract from icon [%s] to package.", icon);
239         }
240
241         return package;
242 }
243
244
245 static char*
246 _get_icon_with_path(char* icon, uid_t uid)
247 {
248         retv_if(!icon, NULL);
249
250         if (index(icon, '/') == NULL) {
251                 char* package;
252                 char* theme = NULL;
253                 char* icon_with_path = NULL;
254                 int len;
255                 char *app_path = NULL;
256
257                 package = _get_package_from_icon(icon);
258                 retv_if(!package, NULL);
259
260 /* "db/setting/theme" is not exist */
261 #if 0
262                 theme = vconf_get_str("db/setting/theme");
263                 if (!theme) {
264                         theme = strdup("default");
265                         if(!theme) {
266                                 free(package);
267                                 return NULL;
268                         }
269                 }
270 #else
271                 theme = strdup("default");
272 #endif
273
274                 len = (0x01 << 7) + strlen(icon) + strlen(package) + strlen(theme);
275                 icon_with_path = malloc(len);
276                 if(icon_with_path == NULL) {
277                         _E("icon_with_path == NULL\n");
278                         free(package);
279                         free(theme);
280                         return NULL;
281                 }
282
283                 memset(icon_with_path, 0, len);
284                 if (uid != GLOBAL_USER)
285                         sqlite3_snprintf( len, icon_with_path, "%s%q", ail_get_icon_path(uid), icon);
286                 else
287                         sqlite3_snprintf( len, icon_with_path, "%s/%q/small/%q", ail_get_icon_path(GLOBAL_USER), theme, icon);
288                         
289                 if (access (icon_with_path, F_OK)) {
290                         app_path = tzplatform_getenv(TZ_SYS_RW_APP);
291                         if (app_path)
292                                 sqlite3_snprintf( len, icon_with_path, "%s/%q/res/icons/%q/small/%q",app_path, package, theme, icon);
293                         if (access (icon_with_path, F_OK))
294                                 _E("Cannot find icon path");
295                 }
296                 free(theme);
297                 free(package);
298                 _D("Icon path : %s", icon_with_path);
299                 return icon_with_path;
300         } else {
301                 char* confirmed_icon = NULL;
302
303                 confirmed_icon = strdup(icon);
304                 retv_if(!confirmed_icon, NULL);
305                 return confirmed_icon;
306         }
307 }
308
309
310 static ail_error_e _read_icon(void *data, char *tag, char *value, uid_t uid)
311 {
312         desktop_info_s *info = data;
313
314         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
315         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
316
317         info->icon = _get_icon_with_path(value, uid);
318
319         retv_if (!info->icon, AIL_ERROR_OUT_OF_MEMORY);
320
321         return AIL_ERROR_OK;
322 }
323
324
325
326 static ail_error_e _read_categories(void *data, char *tag, char *value)
327 {
328         desktop_info_s *info = data;
329
330         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
331         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
332
333         SAFE_FREE_AND_STRDUP(value, info->categories);
334         retv_if (!info->categories, AIL_ERROR_OUT_OF_MEMORY);
335
336         return AIL_ERROR_OK;
337 }
338
339
340
341 static ail_error_e _read_version(void *data, char *tag, char *value)
342 {
343         desktop_info_s *info = data;
344
345         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
346         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
347
348         SAFE_FREE_AND_STRDUP(value, info->version);
349         retv_if (!info->version, AIL_ERROR_OUT_OF_MEMORY);
350
351         return AIL_ERROR_OK;
352 }
353
354
355
356 static ail_error_e _read_mimetype(void *data, char *tag, char *value)
357 {
358         desktop_info_s *info = data;
359         int size, total_len = 0;
360         char *mimes_origin, *mimes_changed, *token_unalias, *save_ptr;
361
362         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
363         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
364         retv_if(!strlen(value), AIL_ERROR_FAIL);
365
366         mimes_origin = strdup(value);
367         retv_if(!mimes_origin, AIL_ERROR_OUT_OF_MEMORY);
368
369         size = getpagesize();
370         mimes_changed = calloc(1, size);
371         if(mimes_changed == NULL) {
372                 _E("(mimes_changed == NULL) return\n");
373                 free(mimes_origin);
374                 return AIL_ERROR_OUT_OF_MEMORY;
375         }
376
377         token_unalias = strtok_r(mimes_origin, ";", &save_ptr);
378
379         while (token_unalias) {
380                 int token_len;
381                 const char *token_alias;
382
383                 _rtrim(token_unalias);
384                 token_unalias = _ltrim(token_unalias);
385
386                 token_alias = xdg_mime_unalias_mime_type(token_unalias);
387                 if (!token_alias) continue;
388
389                 token_len = strlen(token_alias);
390                 if (total_len + token_len + (1<<1) >= size) {
391                         char *tmp;
392                         size *= 2;
393                         tmp = realloc(mimes_changed, size);
394                         if(!tmp) {
395                                 free(mimes_changed);
396                                 return AIL_ERROR_OUT_OF_MEMORY;
397                         }
398                         mimes_changed = tmp;
399                 }
400
401                 strncat(mimes_changed, token_alias, size-1);
402                 total_len += token_len;
403
404                 token_unalias = strtok_r(NULL, ";", &save_ptr);
405                 if (token_unalias) {
406                         strncat(mimes_changed, ";", size-strlen(mimes_changed)-1);
407                 }
408         }
409
410         SAFE_FREE(info->mimetype);
411         info->mimetype = mimes_changed;
412
413         return AIL_ERROR_OK;
414 }
415
416
417
418 static ail_error_e _read_nodisplay(void *data, char *tag, char *value)
419 {
420         desktop_info_s* info = data;
421
422         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
423         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
424
425         info->nodisplay = !strcasecmp(value, "true");
426
427         return AIL_ERROR_OK;
428 }
429
430
431
432 static ail_error_e _read_x_slp_service(void *data, char *tag, char *value)
433 {
434         desktop_info_s *info = data;
435
436         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
437         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
438
439         SAFE_FREE_AND_STRDUP(value, info->x_slp_service);
440         retv_if(!info->x_slp_service, AIL_ERROR_OUT_OF_MEMORY);
441
442         return AIL_ERROR_OK;
443 }
444
445
446
447 static ail_error_e _read_x_slp_packagetype(void *data, char *tag, char *value)
448 {
449         desktop_info_s *info = data;
450
451         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
452         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
453
454         SAFE_FREE_AND_STRDUP(value, info->x_slp_packagetype);
455         retv_if(!info->x_slp_packagetype, AIL_ERROR_OUT_OF_MEMORY);
456
457         return AIL_ERROR_OK;
458 }
459
460
461
462 static ail_error_e _read_x_slp_packagecategories(void *data, char *tag, char *value)
463 {
464         desktop_info_s *info = data;
465
466         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
467         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
468
469         SAFE_FREE_AND_STRDUP(value, info->x_slp_packagecategories);
470         retv_if(!info->x_slp_packagecategories, AIL_ERROR_OUT_OF_MEMORY);
471
472         return AIL_ERROR_OK;
473 }
474
475
476
477 static ail_error_e _read_x_slp_packageid(void *data, char *tag, char *value)
478 {
479         desktop_info_s *info = data;
480
481         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
482         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
483
484         SAFE_FREE_AND_STRDUP(value, info->x_slp_packageid);
485         retv_if(!info->x_slp_packageid, AIL_ERROR_OUT_OF_MEMORY);
486
487         return AIL_ERROR_OK;
488 }
489
490 static ail_error_e _read_x_slp_submodemainid(void *data, char *tag, char *value)
491 {
492         desktop_info_s *info = data;
493
494         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
495         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
496
497         SAFE_FREE_AND_STRDUP(value, info->x_slp_submodemainid);
498         retv_if(!info->x_slp_submodemainid, AIL_ERROR_OUT_OF_MEMORY);
499
500         return AIL_ERROR_OK;
501 }
502
503 static ail_error_e _read_x_slp_installedstorage(void *data, char *tag, char *value)
504 {
505         desktop_info_s *info = data;
506
507         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
508         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
509
510         SAFE_FREE_AND_STRDUP(value, info->x_slp_installedstorage);
511         retv_if(!info->x_slp_installedstorage, AIL_ERROR_OUT_OF_MEMORY);
512
513         return AIL_ERROR_OK;
514 }
515
516 static ail_error_e _read_x_slp_uri(void *data, char *tag, char *value)
517 {
518         desktop_info_s *info = data;
519
520         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
521         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
522
523         SAFE_FREE_AND_STRDUP(value, info->x_slp_uri);
524         retv_if(!info->x_slp_uri, AIL_ERROR_OUT_OF_MEMORY);
525
526         return AIL_ERROR_OK;
527 }
528
529
530
531 static ail_error_e _read_x_slp_svc(void *data, char *tag, char *value)
532 {
533         desktop_info_s *info = data;
534
535         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
536         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
537
538         SAFE_FREE_AND_STRDUP(value, info->x_slp_svc);
539         retv_if(!info->x_slp_svc, AIL_ERROR_OUT_OF_MEMORY);
540
541         return AIL_ERROR_OK;
542 }
543
544
545
546 static ail_error_e _read_x_slp_taskmanage(void *data, char *tag, char *value)
547 {
548         desktop_info_s *info = data;
549
550         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
551         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
552
553         info->x_slp_taskmanage = !strcasecmp(value, "true");
554
555         return AIL_ERROR_OK;
556 }
557
558
559
560 static ail_error_e _read_x_slp_multiple(void *data, char *tag, char *value)
561 {
562         desktop_info_s *info = data;
563
564         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
565         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
566
567         info->x_slp_multiple = !strcasecmp(value, "true");
568
569         return AIL_ERROR_OK;
570 }
571
572
573
574 static ail_error_e _read_x_slp_removable(void *data, char *tag, char *value)
575 {
576         desktop_info_s *info = data;
577
578         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
579         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
580
581         info->x_slp_removable = !strcasecmp(value, "true");
582
583         return AIL_ERROR_OK;
584 }
585
586
587 static ail_error_e _read_x_slp_submode(void *data, char *tag, char *value)
588 {
589         desktop_info_s *info = data;
590
591         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
592         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
593
594         info->x_slp_submode = !strcasecmp(value, "true");
595
596         return AIL_ERROR_OK;
597 }
598
599 static ail_error_e _read_x_slp_appid(void *data, char *tag, char *value)
600 {
601         desktop_info_s *info = data;
602
603         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
604         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
605
606         SAFE_FREE_AND_STRDUP(value, info->x_slp_appid);
607         retv_if(!info->x_slp_appid, AIL_ERROR_OUT_OF_MEMORY);
608
609         return AIL_ERROR_OK;
610 }
611
612
613 static ail_error_e _read_x_slp_pkgid(void *data, char *tag, char *value)
614 {
615         desktop_info_s *info = data;
616
617         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
618         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
619
620         SAFE_FREE_AND_STRDUP(value, info->x_slp_pkgid);
621         retv_if(!info->x_slp_pkgid, AIL_ERROR_OUT_OF_MEMORY);
622
623         return AIL_ERROR_OK;
624 }
625
626
627 static ail_error_e _read_x_slp_domain(void *data, char *tag, char *value)
628 {
629         desktop_info_s *info = data;
630
631         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
632         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
633
634         SAFE_FREE_AND_STRDUP(value, info->x_slp_domain);
635         retv_if(!info->x_slp_appid, AIL_ERROR_OUT_OF_MEMORY);
636
637         return AIL_ERROR_OK;
638 }
639
640
641 static ail_error_e _read_x_slp_enabled(void *data, char *tag, char *value)
642 {
643         desktop_info_s *info = data;
644
645         retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
646         retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
647
648         info->x_slp_enabled = !strcasecmp(value, "true");
649
650         return AIL_ERROR_OK;
651 }
652
653
654 static struct entry_parser entry_parsers[] = {
655         {
656                 .field = "exec",
657                 .value_cb = _read_exec,
658         },
659         {
660                 .field = "name",
661                 .value_cb = _read_name,
662         },
663         {
664                 .field = "type",
665                 .value_cb = _read_type,
666         },
667         {
668                 .field = "icon",
669                 .value_cb = _read_icon,
670         },
671         {
672                 .field = "categories",
673                 .value_cb = _read_categories,
674         },
675         {
676                 .field = "version",
677                 .value_cb = _read_version,
678         },
679         {
680                 .field = "mimetype",
681                 .value_cb = _read_mimetype,
682         },
683         {
684                 .field = "x-tizen-service",
685                 .value_cb = _read_x_slp_service,
686         },
687         {
688                 .field = "x-tizen-packagetype",
689                 .value_cb = _read_x_slp_packagetype,
690         },
691         {
692                 .field = "x-tizen-packagecategories",
693                 .value_cb = _read_x_slp_packagecategories,
694         },
695         {
696                 .field = "x-tizen-packageid",
697                 .value_cb = _read_x_slp_packageid,
698         },
699         {
700                 .field = "x-tizen-submodemainid",
701                 .value_cb = _read_x_slp_submodemainid,
702         },
703         {
704                 .field = "x-tizen-installedstorage",
705                 .value_cb = _read_x_slp_installedstorage,
706         },
707         {
708                 .field = "x-tizen-uri",
709                 .value_cb = _read_x_slp_uri,
710         },
711         {
712                 .field = "x-tizen-svc",
713                 .value_cb = _read_x_slp_svc,
714         },
715         {
716                 .field = "nodisplay",
717                 .value_cb = _read_nodisplay,
718         },
719         {
720                 .field = "x-tizen-taskmanage",
721                 .value_cb = _read_x_slp_taskmanage,
722         },
723         {
724                 .field = "x-tizen-enabled",
725                 .value_cb = _read_x_slp_enabled,
726         },
727         {
728                 .field = "x-tizen-submode",
729                 .value_cb = _read_x_slp_submode,
730         },
731         {
732                 .field = "x-tizen-multiple",
733                 .value_cb = _read_x_slp_multiple,
734         },
735         {
736                 .field = "x-tizen-removable",
737                 .value_cb = _read_x_slp_removable,
738         },
739         {
740                 .field = "x-tizen-appid",
741                 .value_cb = _read_x_slp_appid,
742         },
743         {
744                 .field = "x-tizen-pkgid",
745                 .value_cb = _read_x_slp_pkgid,
746         },
747         {
748                 .field = "x-tizen-domain",
749                 .value_cb = _read_x_slp_domain,
750         },
751         {
752                 .field = "x-tizen-enabled",
753                 .value_cb = _read_x_slp_domain,
754         },
755         {
756                 .field = NULL,
757                 .value_cb = NULL,
758         },
759 };
760
761
762
763 /* Utility functions */
764 static int _count_all(uid_t uid)
765 {
766         ail_error_e ret;
767         int count;
768
769         if (uid != GLOBAL_USER)
770                 ret = ail_filter_count_usr_appinfo(NULL, &count, uid);
771         else
772                 ret = ail_filter_count_appinfo(NULL, &count);   
773         if(ret != AIL_ERROR_OK) {
774                 _E("cannot count appinfo");
775                 count = -1;
776         }
777
778         retv_if(ret != AIL_ERROR_OK, -1);
779
780         return count;
781 }
782
783 char *_pkgname_to_desktop(const char *package, uid_t uid)
784 {
785         char *desktop;
786         char *desktop_path;
787         int size;
788
789         retv_if(!package, NULL);
790
791   desktop_path = al_get_desktop_path(uid);
792
793         size = strlen(desktop_path) + strlen(package) + 10;
794         desktop = malloc(size);
795         retv_if(!desktop, NULL);
796
797   snprintf(desktop, size, "%s/%s.desktop", desktop_path, package);
798
799   _D("uid: %d / desktop: [%s]\n",  uid, desktop);
800
801         return desktop;
802 }
803
804 static inline int _bind_local_info(desktop_info_s* info, sqlite3_stmt * stmt)
805 {
806         int ret = 0;
807         unsigned long i = 0;
808         struct name_item *item;
809         GSList* localname;
810         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
811         retv_if(!info->localname, AIL_ERROR_INVALID_PARAMETER);
812         retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
813         localname = info->localname;
814         while (localname) {
815                 item = (struct name_item *)     localname->data;
816                 if (item && item->locale && item->name) {
817                         // Bind values for a triplet : package, locale, name
818                         retv_if(db_bind_text(stmt, i+1, info->package) != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
819                         retv_if(db_bind_text(stmt, i+2, item->locale) != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
820                         retv_if(db_bind_text(stmt, i+3, item->name) != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
821                         i += 3;
822                 }
823                 localname = g_slist_next(localname);
824         }
825         return AIL_ERROR_OK;
826 }
827
828
829 static inline int _len_local_info(desktop_info_s* info)
830 {
831         int len = 0;
832         struct name_item *item;
833         GSList* localname;
834         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
835         if(info->localname)     {
836                 localname = info->localname;
837                 while (localname) {
838                         item = (struct name_item *)     localname->data;
839                         if (item && item->locale && item->name)
840                                 len ++;
841                         localname = g_slist_next(localname);
842                 }
843         }
844         return len;
845 }
846
847
848 static inline int _insert_local_info(desktop_info_s* info, uid_t uid)
849 {
850         int len_query = SQL_INSERT_LOCALNAME_STR_LEN;
851         int nb_locale_args;
852         char *query;
853         int ret = AIL_ERROR_OK;
854         sqlite3_stmt *stmt = NULL;
855         int i = 0;
856         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
857         retv_if(!info->localname, AIL_ERROR_INVALID_PARAMETER);
858
859         nb_locale_args = _len_local_info(info);
860
861         retv_if(!nb_locale_args, AIL_ERROR_INVALID_PARAMETER);
862
863         len_query += SQL_LOCALNAME_TRIPLET_STR_LEN*nb_locale_args +1;
864
865         query = (char *) malloc(len_query);
866         retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
867         stpncpy(query, SQL_INSERT_LOCALNAME_INIT_STR, len_query);
868         for (i = 0; i <  nb_locale_args - 1; i++)
869                 strcat(query, SQL_LOCALNAME_TRIPLET_STR);
870
871         do {
872                 if(uid != GLOBAL_USER)
873                         ret = db_prepare_rw(query, &stmt);
874                 else 
875                         ret = db_prepare_globalrw(query, &stmt);
876                 if (ret < 0) break;
877
878                 ret = _bind_local_info(info, stmt);
879                 if (ret < 0) {
880                         _E("Can't bind locale information to this query - %s. ",query);
881                         db_finalize(stmt);
882                         break;
883                 }
884                 ret = db_step(stmt);
885                 if (ret != AIL_ERROR_NO_DATA) {
886                         /* Insert Request doesn't return any data.
887                          * db_step should returns AIL_ERROR_NO_DATA in this case. */
888                         _E("Can't execute this query - %s. ",query);
889                         db_finalize(stmt);
890                         break;
891                 }
892                 ret = db_finalize(stmt);
893         } while(0);
894
895         free(query);
896         return ret;
897 }
898
899 static inline int _strlen_desktop_info(desktop_info_s* info)
900 {
901         int len = 0;
902
903         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
904
905         if (info->package) len += strlen(info->package);
906         if (info->exec) len += strlen(info->exec);
907         if (info->name) len += strlen(info->name);
908         if (info->type) len += strlen(info->type);
909         if (info->icon) len += strlen(info->icon);
910         if (info->categories) len += strlen(info->categories);
911         if (info->version) len += strlen(info->version);
912         if (info->mimetype) len += strlen(info->mimetype);
913         if (info->x_slp_service) len += strlen(info->x_slp_service);
914         if (info->x_slp_packagetype) len += strlen(info->x_slp_packagetype);
915         if (info->x_slp_packagecategories) len += strlen(info->x_slp_packagecategories);
916         if (info->x_slp_packageid) len += strlen(info->x_slp_packageid);
917         if (info->x_slp_uri) len += strlen(info->x_slp_uri);
918         if (info->x_slp_svc) len += strlen(info->x_slp_svc);
919         if (info->x_slp_exe_path) len += strlen(info->x_slp_exe_path);
920         if (info->x_slp_appid) len += strlen(info->x_slp_appid);
921         if (info->desktop) len += strlen(info->desktop);
922         if (info->x_slp_submodemainid) len += strlen(info->x_slp_submodemainid);
923         if (info->x_slp_installedstorage) len += strlen(info->x_slp_installedstorage);
924
925         return len;
926 }
927
928
929 int __is_ail_initdb(void)
930 {
931         if( getenv("AIL_INITDB") || getenv("INITDB") )
932                 return 1;
933         else
934                 return 0;
935 }
936
937 /* Manipulating desktop_info functions */
938 static ail_error_e _init_desktop_info(desktop_info_s *info, const char *package, uid_t uid)
939 {
940         static int is_initdb = -1;
941
942   _D("package - [%s].", package);
943
944         if(is_initdb == -1)
945                 is_initdb = __is_ail_initdb();
946
947         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
948         retv_if(!package, AIL_ERROR_INVALID_PARAMETER);
949
950         /* defaults */
951         info->package = package;
952
953         info->x_slp_taskmanage = 1;
954         info->x_slp_removable = 1;
955         info->x_slp_submode = 0;
956
957         if(is_initdb)
958                 info->x_slp_installedtime = 0;
959         else
960                 info->x_slp_installedtime = time(NULL);
961
962 #ifdef PKGTYPE
963         info->x_slp_packagetype = strdup(PKGTYPE);
964 #else
965         info->x_slp_packagetype = strdup("rpm");
966 #endif
967         retv_if(!info->x_slp_packagetype, AIL_ERROR_OUT_OF_MEMORY);
968
969         info->x_slp_packageid = strdup(package);
970         retv_if(!info->x_slp_packageid, AIL_ERROR_OUT_OF_MEMORY);
971         info->x_slp_appid = strdup(package);
972         retv_if(!info->x_slp_appid, AIL_ERROR_OUT_OF_MEMORY);
973
974         info->x_slp_enabled = 1;
975
976         info->desktop = _pkgname_to_desktop(package, uid);
977         retv_if(!info->desktop, AIL_ERROR_FAIL);
978
979   _D("desktop - [%s].", info->desktop);
980
981         return AIL_ERROR_OK;
982 }
983
984
985
986 static ail_error_e _read_desktop_info(desktop_info_s* info)
987 {
988         char *line = NULL;
989         FILE *fp;
990         size_t size = 0;
991         ssize_t read;
992
993         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
994
995         fp = fopen(info->desktop, "r");
996         retv_if(!fp, AIL_ERROR_FAIL);
997
998         while ((read = getline(&line, &size, fp)) != -1) {
999                 int len, idx;
1000                 char *tmp, *field, *field_name, *tag, *value;
1001
1002                 tmp = _ltrim(line);
1003                 if(tmp == NULL) continue;
1004                 if (*tmp == '#') continue;
1005                 if (_rtrim(tmp) <= 0) continue;
1006
1007                 len = strlen(line) + 1;
1008                 field = calloc(1, len);
1009                 field_name = calloc(1, len);
1010                 tag = calloc(1, len);
1011                 value = calloc(1, len);
1012
1013                 if (!field || !field_name || !tag || !value) {
1014                         goto NEXT;
1015                 }
1016
1017                 sscanf(tmp, "%[^=]=%[^\n]", field, value);
1018                 _rtrim(field);
1019                 tmp = _ltrim(value);
1020
1021                 sscanf(field, "%[^[][%[^]]]", field_name, tag);
1022
1023                 if (!field_name || !strlen(field_name)){
1024                         goto NEXT;
1025                 }
1026
1027                 for (idx = 0; entry_parsers[idx].field; idx ++) {
1028                         if (!g_ascii_strcasecmp(entry_parsers[idx].field, field_name) && entry_parsers[idx].value_cb) {
1029                                 if (entry_parsers[idx].value_cb(info, tag, tmp) != AIL_ERROR_OK) {
1030                                         _E("field - [%s] is wrong.", field_name);
1031                                 }
1032                                 break;
1033                         }
1034                 }
1035 NEXT:
1036                 SAFE_FREE(field);
1037                 SAFE_FREE(field_name);
1038                 SAFE_FREE(tag);
1039                 SAFE_FREE(value);
1040         }
1041
1042         _D("Read (%s).", info->package);
1043         fclose(fp);
1044
1045         return AIL_ERROR_OK;
1046 }
1047
1048
1049 static ail_error_e _retrieve_all_column_to_desktop_info(desktop_info_s* info, sqlite3_stmt *stmt)
1050 {
1051         int i, j;
1052         ail_error_e err;
1053         char **values;
1054         char *col;
1055
1056         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
1057
1058         values = calloc(NUM_OF_PROP, sizeof(char *));
1059         retv_if(!values, AIL_ERROR_OUT_OF_MEMORY);
1060
1061         for (i = 0; i < NUM_OF_PROP; i++) {
1062                 err = db_column_str(stmt, i, &col);
1063                 if (AIL_ERROR_OK != err)
1064                         break;
1065
1066                 if (!col) {
1067                         values[i] = NULL;
1068                 } else {
1069                         values[i] = strdup(col);
1070                         if (!values[i]) {
1071                                 err = AIL_ERROR_OUT_OF_MEMORY;
1072                                 goto NEXT;
1073                         }
1074                 }
1075         }
1076
1077         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_EXEC_STR], info->exec);
1078         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_NAME_STR], info->name);
1079         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_TYPE_STR], info->type);
1080         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_ICON_STR], info->icon);
1081         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_CATEGORIES_STR], info->categories);
1082         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_VERSION_STR], info->version);
1083         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_MIMETYPE_STR], info->mimetype);
1084         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_SERVICE_STR], info->x_slp_service);
1085         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_PACKAGETYPE_STR], info->x_slp_packagetype);
1086         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_PACKAGECATEGORIES_STR], info->x_slp_packagecategories);
1087         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_PACKAGEID_STR], info->x_slp_packageid);
1088         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_URI_STR], info->x_slp_uri);
1089         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_SVC_STR], info->x_slp_svc);
1090         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_EXE_PATH], info->x_slp_exe_path);
1091         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_APPID_STR], info->x_slp_appid);
1092         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_PKGID_STR], info->x_slp_pkgid);
1093         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_DOMAIN_STR], info->x_slp_domain);
1094         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_SUBMODEMAINID_STR], info->x_slp_submodemainid);
1095         SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_INSTALLEDSTORAGE_STR], info->x_slp_installedstorage);
1096
1097         info->x_slp_installedtime = atoi(values[E_AIL_PROP_X_SLP_INSTALLEDTIME_INT]);
1098
1099         info->nodisplay = atoi(values[E_AIL_PROP_NODISPLAY_BOOL]);
1100         info->x_slp_taskmanage = atoi(values[E_AIL_PROP_X_SLP_TASKMANAGE_BOOL]);
1101         info->x_slp_multiple = atoi(values[E_AIL_PROP_X_SLP_MULTIPLE_BOOL]);
1102         info->x_slp_removable = atoi(values[E_AIL_PROP_X_SLP_REMOVABLE_BOOL]);
1103         info->x_slp_ishorizontalscale = atoi(values[E_AIL_PROP_X_SLP_ISHORIZONTALSCALE_BOOL]);
1104         info->x_slp_enabled = atoi(values[E_AIL_PROP_X_SLP_ENABLED_BOOL]);
1105         info->x_slp_submode = atoi(values[E_AIL_PROP_X_SLP_SUBMODE_BOOL]);
1106
1107         err = AIL_ERROR_OK;
1108
1109 NEXT:
1110         for (j = 0; j < i; ++j) {
1111                 if (values[j])
1112                         free(values[j]);
1113         }
1114         if (values)
1115                 free(values);
1116         return err;
1117 }
1118
1119
1120 static ail_error_e _load_desktop_info(desktop_info_s* info, uid_t uid)
1121 {
1122         ail_error_e ret;
1123         char query[AIL_SQL_QUERY_MAX_LEN];
1124         sqlite3_stmt *stmt = NULL;
1125         char w[AIL_SQL_QUERY_MAX_LEN];
1126
1127         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
1128
1129         snprintf(w, sizeof(w), sql_get_filter(E_AIL_PROP_X_SLP_APPID_STR), info->package);
1130
1131         snprintf(query, sizeof(query), "SELECT %s FROM %s WHERE %s",SQL_FLD_APP_INFO, SQL_TBL_APP_INFO, w);
1132
1133         do {
1134                 ret = db_open(DB_OPEN_RO, uid);
1135                 if (ret < 0) break;
1136 //is_admin
1137                 ret = db_prepare(query, &stmt);
1138                 //ret = db_prepare_globalro(query, &stmt);
1139                 if (ret < 0) break;
1140
1141                 ret = db_step(stmt);
1142                 if (ret < 0) {
1143                         db_finalize(stmt);
1144                         break;
1145                 }
1146
1147                 ret = _retrieve_all_column_to_desktop_info(info, stmt);
1148                 if (ret < 0) {
1149                         db_finalize(stmt);
1150                         break;
1151                 }
1152
1153                 ret = db_finalize(stmt);
1154                 if (ret < 0) break;
1155
1156                 return AIL_ERROR_OK;
1157         } while(0);
1158
1159         return ret;
1160 }
1161
1162 static ail_error_e _modify_desktop_info_bool(desktop_info_s* info,
1163                                                   const char *property,
1164                                                   bool value)
1165 {
1166         ail_prop_bool_e prop;
1167         int val;
1168
1169         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
1170         retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
1171
1172         prop = _ail_convert_to_prop_bool(property);
1173
1174         if (prop < E_AIL_PROP_BOOL_MIN || prop > E_AIL_PROP_BOOL_MAX)
1175                 return AIL_ERROR_INVALID_PARAMETER;
1176
1177         switch (prop) {
1178                 case E_AIL_PROP_X_SLP_ENABLED_BOOL:
1179                         info->x_slp_enabled = (int)value;
1180                         break;
1181                 default:
1182                         return AIL_ERROR_FAIL;
1183         }
1184
1185         return AIL_ERROR_OK;
1186 }
1187
1188
1189 static ail_error_e _modify_desktop_info_str(desktop_info_s* info,
1190                                                   const char *property,
1191                                                   const char *value)
1192 {
1193         ail_prop_bool_e prop;
1194         int val;
1195
1196         retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
1197         retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
1198
1199         prop = _ail_convert_to_prop_str(property);
1200
1201         if (prop < E_AIL_PROP_STR_MIN || prop > E_AIL_PROP_STR_MAX)
1202                 return AIL_ERROR_INVALID_PARAMETER;
1203
1204         switch (prop) {
1205                 case E_AIL_PROP_NAME_STR:
1206                         SAFE_FREE_AND_STRDUP(value, info->name);
1207                         retv_if (!info->name, AIL_ERROR_OUT_OF_MEMORY);
1208                         break;
1209                 case E_AIL_PROP_X_SLP_SVC_STR:
1210                         SAFE_FREE_AND_STRDUP(value, info->x_slp_svc);
1211                         retv_if (!info->x_slp_svc, AIL_ERROR_OUT_OF_MEMORY);
1212                         break;
1213                 case E_AIL_PROP_X_SLP_INSTALLEDSTORAGE_STR:
1214                         SAFE_FREE_AND_STRDUP(value, info->x_slp_installedstorage);
1215                         retv_if (!info->x_slp_installedstorage, AIL_ERROR_OUT_OF_MEMORY);
1216                         break;
1217                 default:
1218                         _E("prop[%d] is not defined\n", prop);
1219                         return AIL_ERROR_FAIL;
1220         }
1221
1222         return AIL_ERROR_OK;
1223 }
1224
1225
1226 static inline void _insert_localname(gpointer data, gpointer user_data, uid_t uid)
1227 {
1228         char query[512];
1229
1230         struct name_item *item = (struct name_item *)data;
1231         desktop_info_s *info = (desktop_info_s *)user_data;
1232
1233         sqlite3_snprintf(sizeof(query), query, "insert into localname (package, locale, name, x_slp_pkgid) "
1234                         "values ('%q', '%q', '%q', '%q');",
1235                         info->package, item->locale, item->name, info->x_slp_pkgid);
1236         if(uid != GLOBAL_USER) {
1237                 if (db_exec_usr_rw(query) < 0)
1238                         _E("Failed to insert local name of package[%s]",info->package);
1239         } else {
1240                 if (db_exec_glo_rw(query) < 0)
1241                         _E("Failed to insert local name of package[%s]",info->package);
1242         }
1243 }
1244
1245 static ail_error_e _insert_desktop_info(desktop_info_s *info, uid_t uid)
1246 {
1247         char *query;
1248         int len;
1249         ail_error_e ret;
1250
1251         len = _strlen_desktop_info(info) + (0x01 << 10);
1252         query = calloc(1, len);
1253         retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
1254
1255         sqlite3_snprintf(len, query, "insert into app_info ("
1256                 "package, "
1257                 "exec, name, "
1258                 "type, "
1259                 "icon, "
1260                 "categories, "
1261                 "version, "
1262                 "mimetype, "
1263                 "x_slp_service, "
1264                 "x_slp_packagetype, "
1265                 "x_slp_packagecategories, "
1266                 "x_slp_packageid, "
1267                 "x_slp_uri, "
1268                 "x_slp_svc, "
1269                 "x_slp_exe_path, "
1270                 "x_slp_appid, "
1271                 "x_slp_pkgid, "
1272                 "x_slp_domain, "
1273                 "x_slp_submodemainid, "
1274                 "x_slp_installedstorage, "
1275                 "x_slp_baselayoutwidth, "
1276                 "x_slp_installedtime, "
1277                 "nodisplay, "
1278                 "x_slp_taskmanage, "
1279                 "x_slp_multiple, "
1280                 "x_slp_removable, "
1281                 "x_slp_ishorizontalscale, "
1282                 "x_slp_enabled, "
1283                 "x_slp_submode, "
1284                 "desktop) "
1285                 "values "
1286                 "('%q', '%q', '%q', '%q', '%q', "
1287                 "'%q', '%q', '%q', '%q', '%q', "
1288                 "'%q', '%q', '%q', '%q', '%q', "
1289                 "'%q', '%q', '%q', '%q', '%q', "
1290                 "%d, %d, %d, %d, %d, %d, %d,"
1291                 "%d, %d, "
1292                 "'%q');",
1293                 info->package,
1294                 info->exec,
1295                 info->name,
1296                 info->type,
1297                 info->icon,
1298                 info->categories,
1299                 info->version,
1300                 info->mimetype,
1301                 info->x_slp_service,
1302                 info->x_slp_packagetype,
1303                 info->x_slp_packagecategories,
1304                 info->x_slp_packageid,
1305                 info->x_slp_uri,
1306                 info->x_slp_svc,
1307                 info->x_slp_exe_path,
1308                 info->x_slp_appid,
1309                 info->x_slp_pkgid,
1310                 info->x_slp_domain,
1311                 info->x_slp_submodemainid,
1312                 info->x_slp_installedstorage,
1313                 info->x_slp_baselayoutwidth,
1314                 info->x_slp_installedtime,
1315                 info->nodisplay,
1316                 info->x_slp_taskmanage,
1317                 info->x_slp_multiple,
1318                 info->x_slp_removable,
1319                 info->x_slp_ishorizontalscale,
1320                 info->x_slp_enabled,
1321                 info->x_slp_submode,
1322                 info->desktop
1323                 );
1324
1325         ret = db_open(DB_OPEN_RW, uid);
1326         if(ret != AIL_ERROR_OK) {
1327                 _E("(tmp == NULL) return\n");
1328                 free(query);
1329                 return AIL_ERROR_DB_FAILED;
1330         }
1331         if (uid != GLOBAL_USER)
1332                 ret = db_exec_usr_rw(query);
1333         else
1334                 ret = db_exec_glo_rw(query);
1335         
1336         free(query);
1337         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
1338
1339         if (info->localname)
1340                 _insert_local_info(info, uid);
1341
1342         _D("Add (%s).", query);
1343
1344         return AIL_ERROR_OK;
1345 }
1346
1347
1348
1349 static ail_error_e _update_desktop_info(desktop_info_s *info, uid_t uid)
1350 {
1351         char *query;
1352         int len;
1353
1354         retv_if (NULL == info, AIL_ERROR_INVALID_PARAMETER);
1355
1356         if (db_open(DB_OPEN_RW, uid) < 0) {
1357                 return AIL_ERROR_DB_FAILED;
1358         }
1359
1360         len = _strlen_desktop_info(info) + (0x01 << 10);
1361         query = calloc(1, len);
1362         retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
1363
1364         sqlite3_snprintf ( len, query, "update app_info set "
1365                 "exec='%q', "
1366                 "name='%q', "
1367                 "type='%q', "
1368                 "icon='%q', "
1369                 "categories='%q', "
1370                 "version='%q', "
1371                 "mimetype='%q', "
1372                 "x_slp_service='%q', "
1373                 "x_slp_packagetype='%q', "
1374                 "x_slp_packagecategories='%q', "
1375                 "x_slp_packageid='%q', "
1376                 "x_slp_uri='%q', "
1377                 "x_slp_svc='%q', "
1378                 "x_slp_exe_path='%q', "
1379                 "x_slp_appid='%q', "
1380                 "x_slp_pkgid='%q', "
1381                 "x_slp_domain='%q', "
1382                 "x_slp_submodemainid='%q', "
1383                 "x_slp_installedstorage='%q', "
1384                 "x_slp_baselayoutwidth=%d, "
1385                 "x_slp_installedtime=%d, "
1386                 "nodisplay=%d, "
1387                 "x_slp_taskmanage=%d, "
1388                 "x_slp_multiple=%d, "
1389                 "x_slp_removable=%d, "
1390                 "x_slp_ishorizontalscale=%d, "
1391                 "x_slp_enabled=%d, "
1392                 "x_slp_submode=%d, "
1393                 "desktop='%q'"
1394                 "where package='%q'",
1395                 info->exec,
1396                 info->name,
1397                 info->type,
1398                 info->icon,
1399                 info->categories,
1400                 info->version,
1401                 info->mimetype,
1402                 info->x_slp_service,
1403                 info->x_slp_packagetype,
1404                 info->x_slp_packagecategories,
1405                 info->x_slp_packageid,
1406                 info->x_slp_uri,
1407                 info->x_slp_svc,
1408                 info->x_slp_exe_path,
1409                 info->x_slp_appid,
1410                 info->x_slp_pkgid,
1411                 info->x_slp_domain,
1412                 info->x_slp_submodemainid,
1413                 info->x_slp_installedstorage,
1414                 info->x_slp_baselayoutwidth,
1415                 info->x_slp_installedtime,
1416                 info->nodisplay,
1417                 info->x_slp_taskmanage,
1418                 info->x_slp_multiple,
1419                 info->x_slp_removable,
1420                 info->x_slp_ishorizontalscale,
1421                 info->x_slp_enabled,
1422                 info->x_slp_submode,
1423                 info->desktop,
1424                 info->package);
1425
1426         if(uid != GLOBAL_USER) {
1427                 if (db_exec_usr_rw(query) < 0) {
1428                         free (query);
1429                         return AIL_ERROR_DB_FAILED;
1430                 }
1431         } else {
1432                 if (db_exec_glo_rw(query) < 0) {
1433                         free (query);
1434                         return AIL_ERROR_DB_FAILED;
1435                 }
1436         }
1437         snprintf(query, len, "delete from localname where package = '%s'", info->package);
1438         if (uid != GLOBAL_USER) {
1439                 if (db_exec_usr_rw(query) < 0) {
1440                         free (query);
1441                         return AIL_ERROR_DB_FAILED;
1442                 }
1443         } else {
1444                 if (db_exec_glo_rw(query) < 0) {
1445                         free (query);
1446                         return AIL_ERROR_DB_FAILED;
1447                 }
1448         }
1449         if (info->localname)
1450                 _insert_local_info(info, uid);
1451
1452         _D("Update (%s).", info->package);
1453
1454         free(query);
1455
1456         return AIL_ERROR_OK;
1457 }
1458
1459
1460
1461 static ail_error_e _remove_package(const char* package, uid_t uid)
1462 {
1463         char *query;
1464         int size;
1465
1466         retv_if(!package, AIL_ERROR_INVALID_PARAMETER);
1467
1468         if (db_open(DB_OPEN_RW, uid) < 0) {
1469                 return AIL_ERROR_DB_FAILED;
1470         }
1471
1472         size = strlen(package) + (0x01 << 10);
1473         query = calloc(1, size);
1474         retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
1475
1476         snprintf(query, size, "delete from app_info where package = '%s'", package);
1477
1478         if(uid != GLOBAL_USER) {
1479                 if (db_exec_usr_rw(query) < 0) {
1480                         free(query);
1481                         return AIL_ERROR_DB_FAILED;
1482                 }
1483         } else {
1484                 if (db_exec_glo_rw(query) < 0) {
1485                         free(query);
1486                         return AIL_ERROR_DB_FAILED;
1487                 }
1488         }
1489         snprintf(query, size, "delete from localname where package = '%s'", package);
1490         _D("query=%s",query);
1491         
1492         if(uid != GLOBAL_USER) {
1493                 if (db_exec_usr_rw(query) < 0) {
1494                         free(query);
1495                         return AIL_ERROR_DB_FAILED;
1496                 }
1497         } else {
1498                 if (db_exec_glo_rw(query) < 0) {
1499                         free(query);
1500                         return AIL_ERROR_DB_FAILED;
1501                 }
1502         }
1503         _D("Remove (%s).", package);
1504         free(query);
1505
1506         return AIL_ERROR_OK;
1507 }
1508
1509 static ail_error_e _clean_pkgid_data(const char* pkgid, uid_t uid)
1510 {
1511         char *query;
1512         int size;
1513
1514         retv_if(!pkgid, AIL_ERROR_INVALID_PARAMETER);
1515
1516         if (db_open(DB_OPEN_RW, uid) ){
1517                 return AIL_ERROR_DB_FAILED;
1518         }
1519
1520         size = strlen(pkgid) + (0x01 << 10);
1521         query = calloc(1, size);
1522         retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
1523
1524         snprintf(query, size, "delete from app_info where x_slp_pkgid = '%s'", pkgid);
1525
1526         if(uid != GLOBAL_USER) {
1527                 if (db_exec_usr_rw(query) < 0) {
1528                         free(query);
1529                         return AIL_ERROR_DB_FAILED;
1530                 }
1531         } else {
1532                 if (db_exec_glo_rw(query) < 0) {
1533                         free(query);
1534                         return AIL_ERROR_DB_FAILED;
1535                 }
1536         }
1537         snprintf(query, size, "delete from localname where x_slp_pkgid = '%s'", pkgid);
1538         _D("query=%s",query);
1539
1540         if(uid != GLOBAL_USER) {
1541                 if (db_exec_usr_rw(query) < 0) {
1542                         free(query);
1543                         return AIL_ERROR_DB_FAILED;
1544                 }
1545         } else {
1546                 if (db_exec_glo_rw(query) < 0) {
1547                         free(query);
1548                         return AIL_ERROR_DB_FAILED;
1549                 }       
1550         }
1551         _D("Clean pkgid data (%s).", pkgid);
1552         free(query);
1553
1554         return AIL_ERROR_OK;
1555 }
1556
1557 static ail_error_e _send_db_done_noti(noti_type type, const char *package)
1558 {
1559         char *type_string, *noti_string;
1560         int size;
1561
1562         retv_if(!package, AIL_ERROR_INVALID_PARAMETER);
1563
1564         switch (type) {
1565                 case NOTI_ADD:
1566                         type_string = "create";
1567                         break;
1568                 case NOTI_UPDATE:
1569                         type_string = "update";
1570                         break;
1571                 case NOTI_REMOVE:
1572                         type_string = "delete";
1573                         break;
1574                 default:
1575                         return AIL_ERROR_FAIL;
1576         }
1577
1578         size = snprintf(NULL, 0, "%s:%s:%u", type_string, package, getuid());
1579         noti_string = (char*) calloc(size + 1, sizeof(char));
1580         retv_if(!noti_string, AIL_ERROR_OUT_OF_MEMORY);
1581
1582         snprintf(noti_string, size + 1, "%s:%s:%u", type_string, package, getuid());
1583         vconf_set_str(VCONFKEY_AIL_INFO_STATE, noti_string);
1584         vconf_set_str(VCONFKEY_MENUSCREEN_DESKTOP, noti_string); // duplicate, will be removed
1585         _D("Noti : %s", noti_string);
1586
1587         free(noti_string);
1588
1589         return AIL_ERROR_OK;
1590 }
1591
1592
1593 static void inline _name_item_free_func(gpointer data)
1594 {
1595         struct name_item *item = (struct name_item *)data;
1596         if (item){
1597                 SAFE_FREE(item->locale);
1598                 item->locale = NULL;
1599                 SAFE_FREE(item->name);
1600                 item->name = NULL;
1601         }
1602         SAFE_FREE(item);
1603 }
1604
1605 static void _fini_desktop_info(desktop_info_s *info)
1606 {
1607         SAFE_FREE(info->exec);
1608         SAFE_FREE(info->name);
1609         SAFE_FREE(info->type);
1610         SAFE_FREE(info->icon);
1611         SAFE_FREE(info->categories);
1612         SAFE_FREE(info->version);
1613         SAFE_FREE(info->mimetype);
1614         SAFE_FREE(info->x_slp_service);
1615         SAFE_FREE(info->x_slp_packagetype);
1616         SAFE_FREE(info->x_slp_packagecategories);
1617         SAFE_FREE(info->x_slp_packageid);
1618         SAFE_FREE(info->x_slp_uri);
1619         SAFE_FREE(info->x_slp_svc);
1620         SAFE_FREE(info->x_slp_exe_path);
1621         SAFE_FREE(info->x_slp_appid);
1622         SAFE_FREE(info->x_slp_pkgid);
1623         SAFE_FREE(info->x_slp_domain);
1624         SAFE_FREE(info->x_slp_submodemainid);
1625         SAFE_FREE(info->x_slp_installedstorage);
1626         SAFE_FREE(info->desktop);
1627         if (info->localname) {
1628                 g_slist_free_full(info->localname, _name_item_free_func);
1629                 info->localname = NULL;
1630         }
1631
1632         return;
1633 }
1634
1635 static int __is_authorized()
1636 {
1637         uid_t uid = getuid();
1638         if ((uid_t) 0 == uid )
1639                 return 1;
1640         else
1641                 return 0;
1642 }
1643
1644
1645 /* Public functions */
1646 EXPORT_API ail_error_e ail_usr_desktop_add(const char *appid, uid_t uid)
1647 {
1648         desktop_info_s info = {0,};
1649         ail_error_e ret;
1650
1651         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1652
1653         ret = _init_desktop_info(&info, appid, uid);
1654         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1655
1656         ret = _read_desktop_info(&info);
1657         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1658
1659         ret = _insert_desktop_info(&info, uid);
1660         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1661
1662         ret = _send_db_done_noti(NOTI_ADD, appid);
1663         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1664
1665         _fini_desktop_info(&info);
1666
1667         return AIL_ERROR_OK;
1668 }
1669
1670 EXPORT_API ail_error_e ail_desktop_add(const char *appid)
1671 {
1672         return ail_usr_desktop_add(appid,GLOBAL_USER);
1673 }
1674
1675 EXPORT_API ail_error_e ail_usr_desktop_update(const char *appid, uid_t uid)
1676 {
1677         desktop_info_s info = {0,};
1678         ail_error_e ret;
1679
1680         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1681
1682         ret = _init_desktop_info(&info, appid, uid);
1683         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1684
1685         ret = _read_desktop_info(&info);
1686         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1687
1688         ret = _update_desktop_info(&info, uid);
1689         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1690
1691         ret = _send_db_done_noti(NOTI_UPDATE, appid);
1692         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1693
1694         _fini_desktop_info(&info);
1695
1696         return AIL_ERROR_OK;
1697 }
1698
1699 EXPORT_API ail_error_e ail_desktop_update(const char *appid)
1700 {
1701         return ail_usr_desktop_update(appid,GLOBAL_USER);
1702 }
1703
1704
1705 EXPORT_API ail_error_e ail_usr_desktop_remove(const char *appid, uid_t uid)
1706 {
1707         ail_error_e ret;
1708
1709         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1710
1711         ret = _remove_package(appid, uid);
1712         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1713
1714         ret = _send_db_done_noti(NOTI_REMOVE, appid);
1715         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1716
1717         return AIL_ERROR_OK;
1718 }
1719
1720 EXPORT_API ail_error_e ail_desktop_remove(const char *appid)
1721 {
1722         return ail_usr_desktop_remove(appid, GLOBAL_USER);
1723 }
1724
1725
1726 EXPORT_API ail_error_e ail_usr_desktop_clean(const char *pkgid, uid_t uid)
1727 {
1728         ail_error_e ret;
1729
1730         retv_if(!pkgid, AIL_ERROR_INVALID_PARAMETER);
1731
1732         _D("ail_desktop_clean=%s",pkgid);
1733
1734         ret = _clean_pkgid_data(pkgid, uid);
1735         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1736
1737         return AIL_ERROR_OK;
1738 }
1739
1740 EXPORT_API ail_error_e ail_desktop_clean(const char *pkgid)
1741 {
1742         return ail_usr_desktop_clean(pkgid, GLOBAL_USER);
1743 }
1744
1745 EXPORT_API ail_error_e ail_usr_desktop_fota(const char *appid, uid_t uid)
1746 {
1747         desktop_info_s info = {0,};
1748         ail_error_e ret;
1749
1750         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1751
1752         ret = _init_desktop_info(&info, appid, uid);
1753         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1754
1755         ret = _read_desktop_info(&info);
1756         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1757
1758         ret = _insert_desktop_info(&info, uid);
1759         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1760
1761         _fini_desktop_info(&info);
1762
1763         return AIL_ERROR_OK;
1764 }
1765
1766 EXPORT_API ail_error_e ail_desktop_fota(const char *appid)
1767 {
1768         return ail_usr_desktop_fota(appid, GLOBAL_USER);
1769 }
1770
1771
1772 EXPORT_API ail_error_e ail_desktop_appinfo_modify_usr_bool(const char *appid,
1773                                                              const char *property,
1774                                                              bool value,
1775                                                              bool broadcast, uid_t uid)
1776 {
1777         desktop_info_s info = {0,};
1778         ail_error_e ret;
1779
1780         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1781
1782         retv_if(strcmp(property, AIL_PROP_X_SLP_ENABLED_BOOL),
1783                 AIL_ERROR_INVALID_PARAMETER);
1784
1785         ret = _init_desktop_info(&info, appid, uid);
1786         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1787
1788         ret = _load_desktop_info(&info, uid);
1789         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1790
1791         ret = _modify_desktop_info_bool(&info, property, value);
1792         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1793
1794         ret = _update_desktop_info(&info, uid);
1795         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1796
1797         if (broadcast) {
1798                 ret = _send_db_done_noti(NOTI_UPDATE, appid);
1799                 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1800         }
1801
1802         _fini_desktop_info(&info);
1803
1804         return AIL_ERROR_OK;
1805 }
1806
1807 EXPORT_API ail_error_e ail_desktop_appinfo_modify_bool(const char *appid,
1808                                                              const char *property,
1809                                                              bool value,
1810                                                              bool broadcast)
1811 {
1812         return ail_desktop_appinfo_modify_usr_bool(appid, property, value, broadcast,
1813                         GLOBAL_USER);
1814 }
1815
1816
1817 EXPORT_API ail_error_e ail_desktop_appinfo_modify_usr_str(const char *appid, uid_t uid,
1818                                                              const char *property,
1819                                                              const char *value,
1820                                                              bool broadcast)
1821 {
1822         desktop_info_s info = {0,};
1823         ail_error_e ret;
1824
1825         retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1826
1827         ret = _init_desktop_info(&info, appid, uid);
1828         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1829
1830         ret = _load_desktop_info(&info, uid);
1831         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1832
1833         _D("info.name [%s], value [%s]", info.name, value);
1834         ret = _modify_desktop_info_str(&info, property, value);
1835         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1836         _D("info.name [%s], value [%s]", info.name, value);
1837
1838         ret = _update_desktop_info(&info, uid);
1839         retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1840
1841         if (broadcast) {
1842                 ret = _send_db_done_noti(NOTI_UPDATE, appid);
1843                 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1844         }
1845
1846         _fini_desktop_info(&info);
1847
1848         return AIL_ERROR_OK;
1849 }
1850
1851 EXPORT_API ail_error_e ail_desktop_appinfo_modify_str(const char *appid,
1852                                                              const char *property,
1853                                                              const char *value,
1854                                                              bool broadcast)
1855 {
1856         return ail_desktop_appinfo_modify_usr_str(appid, GLOBAL_USER, property, value,
1857                                 broadcast);
1858 }
1859
1860 // End of File