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