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