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