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