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