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