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