4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
30 #include <sys/types.h>
37 #include "ail_private.h"
42 #define OPT_DESKTOP_DIRECTORY "/opt/share/applications"
43 #define USR_DESKTOP_DIRECTORY "/usr/share/applications"
46 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
47 #define argsdelimiter " \t"
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)
52 #define SQL_INSERT_LOCALNAME_INIT_STR SQL_INSERT_LOCALNAME_STR"( ?, ?, ?) "
54 #define SQL_LOCALNAME_TRIPLET_STR ", ( ?, ?, ?)"
55 #define SQL_LOCALNAME_TRIPLET_STR_LEN (sizeof(SQL_LOCALNAME_TRIPLET_STR)-1)
66 ail_error_e (*value_cb)(void *data, char *tag, char *value);
69 inline static char *_ltrim(char *str)
71 if (!str) return NULL;
73 while (*str == ' ' || *str == '\t' || *str == '\n') str ++;
80 inline static int _rtrim(char *str)
85 while (--len >= 0 && (str[len] == ' ' || str[len] == '\n' || str[len] == '\t')) str[len] = '\0';
105 char* x_slp_packagetype;
106 char* x_slp_packagecategories;
107 char* x_slp_packageid;
110 char* x_slp_exe_path;
114 int x_slp_baselayoutwidth;
115 int x_slp_installedtime;
117 int x_slp_taskmanage;
120 int x_slp_ishorizontalscale;
128 static ail_error_e _read_exec(void *data, char *tag, char *value)
130 desktop_info_s *info = data;
131 char *token_exe_path;
135 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
136 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
138 SAFE_FREE_AND_STRDUP(value, info->exec);
139 retv_if(!info->exec, AIL_ERROR_OUT_OF_MEMORY);
141 temp_exec = strdup(value);
144 return AIL_ERROR_OUT_OF_MEMORY;
147 token_exe_path = strtok_r(temp_exec, argsdelimiter, &save_ptr);
149 info->x_slp_exe_path = strdup(token_exe_path);
150 if(!info->x_slp_exe_path) {
154 return AIL_ERROR_OUT_OF_MEMORY;
164 static ail_error_e _read_name(void *data, char *tag, char *value)
166 desktop_info_s *info = data;
168 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
169 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
170 retv_if(0 == strlen(value), AIL_ERROR_FAIL);
172 if (tag && strlen(tag) > 0) {
173 struct name_item *item;
174 item = (struct name_item *)calloc(1, sizeof(struct name_item));
175 retv_if (NULL == item, AIL_ERROR_OUT_OF_MEMORY);
177 SAFE_FREE_AND_STRDUP(tag, item->locale);
178 if(NULL == item->locale) {
179 _E("(NULL == item->locale) return\n");
181 return AIL_ERROR_OUT_OF_MEMORY;
184 SAFE_FREE_AND_STRDUP(value, item->name);
185 if(NULL == item->name) {
186 _E("(NULL == item->name) return\n");
189 return AIL_ERROR_OUT_OF_MEMORY;
192 info->localname = g_slist_append(info->localname, item);
196 SAFE_FREE_AND_STRDUP(value, info->name);
197 retv_if (!info->name, AIL_ERROR_OUT_OF_MEMORY);
205 static ail_error_e _read_type(void *data, char *tag, char *value)
207 desktop_info_s *info = data;
209 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
210 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
212 SAFE_FREE_AND_STRDUP(value, info->type);
213 retv_if (!info->type, AIL_ERROR_OUT_OF_MEMORY);
220 _get_package_from_icon(char* icon)
225 retv_if(!icon, NULL);
227 package = strdup(icon);
228 retv_if(!package, NULL);
229 extension = rindex(package, '.');
233 _E("cannot extract from icon [%s] to package.", icon);
241 _get_icon_with_path(char* icon)
243 retv_if(!icon, NULL);
245 if (index(icon, '/') == NULL) {
248 char* icon_with_path = NULL;
251 package = _get_package_from_icon(icon);
252 retv_if(!package, NULL);
254 theme = vconf_get_str("db/setting/theme");
256 theme = strdup("default");
263 len = (0x01 << 7) + strlen(icon) + strlen(package) + strlen(theme);
264 icon_with_path = malloc(len);
265 if(icon_with_path == NULL) {
266 _E("(icon_with_path == NULL) return\n");
272 memset(icon_with_path, 0, len);
274 sqlite3_snprintf( len, icon_with_path,"/opt/share/icons/%q/small/%q", theme, icon);
276 if (access(icon_with_path, R_OK) == 0) break;
277 sqlite3_snprintf( len, icon_with_path,"/usr/share/icons/%q/small/%q", theme, icon);
278 if (access(icon_with_path, R_OK) == 0) break;
279 _D("cannot find icon %s", icon_with_path);
280 sqlite3_snprintf( len, icon_with_path, "/opt/share/icons/default/small/%q", icon);
281 if (access(icon_with_path, R_OK) == 0) break;
282 sqlite3_snprintf( len, icon_with_path, "/usr/share/icons/default/small/%q", icon);
283 if (access(icon_with_path, R_OK) == 0) break;
285 #if 1 /* this will be remove when finish the work for moving icon path */
286 _E("icon file must be moved to %s", icon_with_path);
287 sqlite3_snprintf( len, icon_with_path, "/opt/apps/%q/res/icons/%q/small/%q", package, theme, icon);
288 if (access(icon_with_path, R_OK) == 0) break;
289 sqlite3_snprintf( len, icon_with_path, "/usr/apps/%q/res/icons/%q/small/%q", package, theme, icon);
290 if (access(icon_with_path, R_OK) == 0) break;
291 _D("cannot find icon %s", icon_with_path);
292 sqlite3_snprintf( len, icon_with_path, "/opt/apps/%q/res/icons/default/small/%q", package, icon);
293 if (access(icon_with_path, R_OK) == 0) break;
294 sqlite3_snprintf( len, icon_with_path, "/usr/apps/%q/res/icons/default/small/%q", package, icon);
295 if (access(icon_with_path, R_OK) == 0) break;
302 _D("Icon path : %s ---> %s", icon, icon_with_path);
304 return icon_with_path;
306 char* confirmed_icon = NULL;
308 confirmed_icon = strdup(icon);
309 retv_if(!confirmed_icon, NULL);
310 return confirmed_icon;
315 static ail_error_e _read_icon(void *data, char *tag, char *value)
317 desktop_info_s *info = data;
319 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
320 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
322 info->icon = _get_icon_with_path(value);
324 retv_if (!info->icon, AIL_ERROR_OUT_OF_MEMORY);
331 static ail_error_e _read_categories(void *data, char *tag, char *value)
333 desktop_info_s *info = data;
335 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
336 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
338 SAFE_FREE_AND_STRDUP(value, info->categories);
339 retv_if (!info->categories, AIL_ERROR_OUT_OF_MEMORY);
346 static ail_error_e _read_version(void *data, char *tag, char *value)
348 desktop_info_s *info = data;
350 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
351 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
353 SAFE_FREE_AND_STRDUP(value, info->version);
354 retv_if (!info->version, AIL_ERROR_OUT_OF_MEMORY);
361 static ail_error_e _read_mimetype(void *data, char *tag, char *value)
363 desktop_info_s *info = data;
364 int size, total_len = 0;
365 char *mimes_origin, *mimes_changed, *token_unalias, *save_ptr;
367 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
368 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
369 retv_if(!strlen(value), AIL_ERROR_FAIL);
371 mimes_origin = strdup(value);
372 retv_if(!mimes_origin, AIL_ERROR_OUT_OF_MEMORY);
374 size = getpagesize();
375 mimes_changed = calloc(1, size);
376 if(mimes_changed == NULL) {
377 _E("(mimes_changed == NULL) return\n");
379 return AIL_ERROR_OUT_OF_MEMORY;
382 token_unalias = strtok_r(mimes_origin, ";", &save_ptr);
384 while (token_unalias) {
386 const char *token_alias;
388 _rtrim(token_unalias);
389 token_unalias = _ltrim(token_unalias);
391 token_alias = xdg_mime_unalias_mime_type(token_unalias);
392 if (!token_alias) continue;
394 token_len = strlen(token_alias);
395 if (total_len + token_len + (1<<1) >= size) {
398 tmp = realloc(mimes_changed, size);
401 return AIL_ERROR_OUT_OF_MEMORY;
406 strncat(mimes_changed, token_alias, size-1);
407 total_len += token_len;
409 token_unalias = strtok_r(NULL, ";", &save_ptr);
411 strncat(mimes_changed, ";", size-strlen(mimes_changed)-1);
415 SAFE_FREE(info->mimetype);
416 info->mimetype = mimes_changed;
423 static ail_error_e _read_nodisplay(void *data, char *tag, char *value)
425 desktop_info_s* info = data;
427 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
428 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
430 info->nodisplay = !strcasecmp(value, "true");
437 static ail_error_e _read_x_slp_service(void *data, char *tag, char *value)
439 desktop_info_s *info = data;
441 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
442 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
444 SAFE_FREE_AND_STRDUP(value, info->x_slp_service);
445 retv_if(!info->x_slp_service, AIL_ERROR_OUT_OF_MEMORY);
452 static ail_error_e _read_x_slp_packagetype(void *data, char *tag, char *value)
454 desktop_info_s *info = data;
456 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
457 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
459 SAFE_FREE_AND_STRDUP(value, info->x_slp_packagetype);
460 retv_if(!info->x_slp_packagetype, AIL_ERROR_OUT_OF_MEMORY);
467 static ail_error_e _read_x_slp_packagecategories(void *data, char *tag, char *value)
469 desktop_info_s *info = data;
471 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
472 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
474 SAFE_FREE_AND_STRDUP(value, info->x_slp_packagecategories);
475 retv_if(!info->x_slp_packagecategories, AIL_ERROR_OUT_OF_MEMORY);
482 static ail_error_e _read_x_slp_packageid(void *data, char *tag, char *value)
484 desktop_info_s *info = data;
486 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
487 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
489 SAFE_FREE_AND_STRDUP(value, info->x_slp_packageid);
490 retv_if(!info->x_slp_packageid, AIL_ERROR_OUT_OF_MEMORY);
497 static ail_error_e _read_x_slp_uri(void *data, char *tag, char *value)
499 desktop_info_s *info = data;
501 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
502 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
504 SAFE_FREE_AND_STRDUP(value, info->x_slp_uri);
505 retv_if(!info->x_slp_uri, AIL_ERROR_OUT_OF_MEMORY);
512 static ail_error_e _read_x_slp_svc(void *data, char *tag, char *value)
514 desktop_info_s *info = data;
516 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
517 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
519 SAFE_FREE_AND_STRDUP(value, info->x_slp_svc);
520 retv_if(!info->x_slp_svc, AIL_ERROR_OUT_OF_MEMORY);
527 static ail_error_e _read_x_slp_taskmanage(void *data, char *tag, char *value)
529 desktop_info_s *info = data;
531 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
532 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
534 info->x_slp_taskmanage = !strcasecmp(value, "true");
541 static ail_error_e _read_x_slp_multiple(void *data, char *tag, char *value)
543 desktop_info_s *info = data;
545 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
546 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
548 info->x_slp_multiple = !strcasecmp(value, "true");
555 static ail_error_e _read_x_slp_removable(void *data, char *tag, char *value)
557 desktop_info_s *info = data;
559 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
560 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
562 info->x_slp_removable = !strcasecmp(value, "true");
568 static ail_error_e _read_x_slp_appid(void *data, char *tag, char *value)
570 desktop_info_s *info = data;
572 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
573 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
575 SAFE_FREE_AND_STRDUP(value, info->x_slp_appid);
576 retv_if(!info->x_slp_appid, AIL_ERROR_OUT_OF_MEMORY);
582 static ail_error_e _read_x_slp_pkgid(void *data, char *tag, char *value)
584 desktop_info_s *info = data;
586 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
587 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
589 SAFE_FREE_AND_STRDUP(value, info->x_slp_pkgid);
590 retv_if(!info->x_slp_pkgid, AIL_ERROR_OUT_OF_MEMORY);
596 static ail_error_e _read_x_slp_domain(void *data, char *tag, char *value)
598 desktop_info_s *info = data;
600 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
601 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
603 SAFE_FREE_AND_STRDUP(value, info->x_slp_domain);
604 retv_if(!info->x_slp_appid, AIL_ERROR_OUT_OF_MEMORY);
610 static ail_error_e _read_x_slp_enabled(void *data, char *tag, char *value)
612 desktop_info_s *info = data;
614 retv_if(!data, AIL_ERROR_INVALID_PARAMETER);
615 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
617 info->x_slp_enabled = !strcasecmp(value, "true");
623 static struct entry_parser entry_parsers[] = {
626 .value_cb = _read_exec,
630 .value_cb = _read_name,
634 .value_cb = _read_type,
638 .value_cb = _read_icon,
641 .field = "categories",
642 .value_cb = _read_categories,
646 .value_cb = _read_version,
650 .value_cb = _read_mimetype,
653 .field = "x-tizen-service",
654 .value_cb = _read_x_slp_service,
657 .field = "x-tizen-packagetype",
658 .value_cb = _read_x_slp_packagetype,
661 .field = "x-tizen-packagecategories",
662 .value_cb = _read_x_slp_packagecategories,
665 .field = "x-tizen-packageid",
666 .value_cb = _read_x_slp_packageid,
669 .field = "x-tizen-uri",
670 .value_cb = _read_x_slp_uri,
673 .field = "x-tizen-svc",
674 .value_cb = _read_x_slp_svc,
677 .field = "nodisplay",
678 .value_cb = _read_nodisplay,
681 .field = "x-tizen-taskmanage",
682 .value_cb = _read_x_slp_taskmanage,
685 .field = "x-tizen-enabled",
686 .value_cb = _read_x_slp_enabled,
689 .field = "x-tizen-multiple",
690 .value_cb = _read_x_slp_multiple,
693 .field = "x-tizen-removable",
694 .value_cb = _read_x_slp_removable,
697 .field = "x-tizen-appid",
698 .value_cb = _read_x_slp_appid,
701 .field = "x-tizen-pkgid",
702 .value_cb = _read_x_slp_pkgid,
705 .field = "x-tizen-domain",
706 .value_cb = _read_x_slp_domain,
709 .field = "x-tizen-enabled",
710 .value_cb = _read_x_slp_domain,
720 /* Utility functions */
721 static int _count_all(void)
726 ret = ail_filter_count_appinfo(NULL, &count);
727 if(ret != AIL_ERROR_OK) {
728 _E("cannot count appinfo");
732 retv_if(ret != AIL_ERROR_OK, -1);
739 char *_pkgname_to_desktop(const char *package)
744 retv_if(!package, NULL);
746 size = strlen(OPT_DESKTOP_DIRECTORY) + strlen(package) + 10;
747 desktop = malloc(size);
748 retv_if(!desktop, NULL);
750 snprintf(desktop, size, OPT_DESKTOP_DIRECTORY"/%s.desktop", package);
752 if (access(desktop, R_OK) == 0)
755 snprintf(desktop, size, USR_DESKTOP_DIRECTORY"/%s.desktop", package);
760 static inline int _bind_local_info(desktop_info_s* info, sqlite3_stmt * stmt)
764 struct name_item *item;
766 retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
767 retv_if(!info->localname, AIL_ERROR_INVALID_PARAMETER);
768 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
769 localname = info->localname;
771 item = (struct name_item *) localname->data;
772 if (item && item->locale && item->name) {
773 // Bind values for a triplet : package, locale, name
774 retv_if(db_bind_text(stmt, i+1, info->package) != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
775 retv_if(db_bind_text(stmt, i+2, item->locale) != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
776 retv_if(db_bind_text(stmt, i+3, item->name) != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
779 localname = g_slist_next(localname);
785 static inline int _len_local_info(desktop_info_s* info)
788 struct name_item *item;
790 retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
791 if(info->localname) {
792 localname = info->localname;
794 item = (struct name_item *) localname->data;
795 if (item && item->locale && item->name)
797 localname = g_slist_next(localname);
804 static inline int _insert_local_info(desktop_info_s* info)
806 int len_query = SQL_INSERT_LOCALNAME_STR_LEN;
809 int ret = AIL_ERROR_OK;
810 sqlite3_stmt *stmt = NULL;
812 retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
813 retv_if(!info->localname, AIL_ERROR_INVALID_PARAMETER);
815 nb_locale_args = _len_local_info(info);
817 retv_if(!nb_locale_args, AIL_ERROR_INVALID_PARAMETER);
819 len_query += SQL_LOCALNAME_TRIPLET_STR_LEN*nb_locale_args +1;
821 query = (char *) malloc(len_query);
822 retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
823 stpncpy(query, SQL_INSERT_LOCALNAME_INIT_STR, len_query);
824 for (i = 0; i < nb_locale_args - 1; i++)
825 strcat(query, SQL_LOCALNAME_TRIPLET_STR);
828 ret = db_prepare_rw(query, &stmt);
831 ret = _bind_local_info(info, stmt);
833 _E("Can't bind locale information to this query - %s. ",query);
838 if (ret != AIL_ERROR_NO_DATA) {
839 /* Insert Request doesn't return any data.
840 * db_step should returns AIL_ERROR_NO_DATA in this case. */
841 _E("Can't execute this query - %s. ",query);
845 ret = db_finalize(stmt);
852 static inline int _strlen_desktop_info(desktop_info_s* info)
856 retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
858 if (info->package) len += strlen(info->package);
859 if (info->exec) len += strlen(info->exec);
860 if (info->name) len += strlen(info->name);
861 if (info->type) len += strlen(info->type);
862 if (info->icon) len += strlen(info->icon);
863 if (info->categories) len += strlen(info->categories);
864 if (info->version) len += strlen(info->version);
865 if (info->mimetype) len += strlen(info->mimetype);
866 if (info->x_slp_service) len += strlen(info->x_slp_service);
867 if (info->x_slp_packagetype) len += strlen(info->x_slp_packagetype);
868 if (info->x_slp_packagecategories) len += strlen(info->x_slp_packagecategories);
869 if (info->x_slp_packageid) len += strlen(info->x_slp_packageid);
870 if (info->x_slp_uri) len += strlen(info->x_slp_uri);
871 if (info->x_slp_svc) len += strlen(info->x_slp_svc);
872 if (info->x_slp_exe_path) len += strlen(info->x_slp_exe_path);
873 if (info->x_slp_appid) len += strlen(info->x_slp_appid);
874 if (info->desktop) len += strlen(info->desktop);
880 int __is_ail_initdb(void)
882 if( getenv("AIL_INITDB") || getenv("INITDB") )
890 /* Manipulating desktop_info functions */
891 static ail_error_e _init_desktop_info(desktop_info_s *info, const char *package)
893 static int is_initdb = -1;
896 is_initdb = __is_ail_initdb();
898 retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
899 retv_if(!package, AIL_ERROR_INVALID_PARAMETER);
902 info->package = package;
904 info->x_slp_taskmanage = 1;
905 info->x_slp_removable = 1;
908 info->x_slp_installedtime = 0;
910 info->x_slp_installedtime = time(NULL);
913 info->x_slp_packagetype = strdup(PKGTYPE);
915 info->x_slp_packagetype = strdup("rpm");
917 retv_if(!info->x_slp_packagetype, AIL_ERROR_OUT_OF_MEMORY);
919 info->x_slp_packageid = strdup(package);
920 retv_if(!info->x_slp_packageid, AIL_ERROR_OUT_OF_MEMORY);
921 info->x_slp_appid = strdup(package);
922 retv_if(!info->x_slp_appid, AIL_ERROR_OUT_OF_MEMORY);
924 info->x_slp_enabled = 1;
926 info->desktop = _pkgname_to_desktop(package);
927 retv_if(!info->desktop, AIL_ERROR_FAIL);
934 static ail_error_e _read_desktop_info(desktop_info_s* info)
941 retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
943 fp = fopen(info->desktop, "r");
944 retv_if(!fp, AIL_ERROR_FAIL);
946 while ((read = getline(&line, &size, fp)) != -1) {
948 char *tmp, *field, *field_name, *tag, *value;
951 if(tmp == NULL) continue;
952 if (*tmp == '#') continue;
953 if (_rtrim(tmp) <= 0) continue;
955 len = strlen(line) + 1;
956 field = calloc(1, len);
957 field_name = calloc(1, len);
958 tag = calloc(1, len);
959 value = calloc(1, len);
961 if (!field || !field_name || !tag || !value) {
965 sscanf(tmp, "%[^=]=%[^\n]", field, value);
969 sscanf(field, "%[^[][%[^]]]", field_name, tag);
971 if (!field_name || !strlen(field_name)){
975 for (idx = 0; entry_parsers[idx].field; idx ++) {
976 if (!g_ascii_strcasecmp(entry_parsers[idx].field, field_name) && entry_parsers[idx].value_cb) {
977 if (entry_parsers[idx].value_cb(info, tag, tmp) != AIL_ERROR_OK) {
978 _E("field - [%s] is wrong.", field_name);
985 SAFE_FREE(field_name);
990 _D("Read (%s).", info->package);
997 static ail_error_e _retrieve_all_column_to_desktop_info(desktop_info_s* info, sqlite3_stmt *stmt)
1004 retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
1006 values = calloc(NUM_OF_PROP, sizeof(char *));
1007 retv_if(!values, AIL_ERROR_OUT_OF_MEMORY);
1009 for (i = 0; i < NUM_OF_PROP; i++) {
1010 err = db_column_str(stmt, i, &col);
1011 if (AIL_ERROR_OK != err)
1017 values[i] = strdup(col);
1019 err = AIL_ERROR_OUT_OF_MEMORY;
1025 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_EXEC_STR], info->exec);
1026 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_NAME_STR], info->name);
1027 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_TYPE_STR], info->type);
1028 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_ICON_STR], info->icon);
1029 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_CATEGORIES_STR], info->categories);
1030 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_VERSION_STR], info->version);
1031 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_MIMETYPE_STR], info->mimetype);
1032 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_SERVICE_STR], info->x_slp_service);
1033 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_PACKAGETYPE_STR], info->x_slp_packagetype);
1034 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_PACKAGECATEGORIES_STR], info->x_slp_packagecategories);
1035 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_PACKAGEID_STR], info->x_slp_packageid);
1036 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_URI_STR], info->x_slp_uri);
1037 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_SVC_STR], info->x_slp_svc);
1038 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_EXE_PATH], info->x_slp_exe_path);
1039 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_APPID_STR], info->x_slp_appid);
1040 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_PKGID_STR], info->x_slp_pkgid);
1041 SAFE_FREE_AND_STRDUP(values[E_AIL_PROP_X_SLP_DOMAIN_STR], info->x_slp_domain);
1043 info->x_slp_installedtime = atoi(values[E_AIL_PROP_X_SLP_INSTALLEDTIME_INT]);
1045 info->nodisplay = atoi(values[E_AIL_PROP_NODISPLAY_BOOL]);
1046 info->x_slp_taskmanage = atoi(values[E_AIL_PROP_X_SLP_TASKMANAGE_BOOL]);
1047 info->x_slp_multiple = atoi(values[E_AIL_PROP_X_SLP_MULTIPLE_BOOL]);
1048 info->x_slp_removable = atoi(values[E_AIL_PROP_X_SLP_REMOVABLE_BOOL]);
1049 info->x_slp_ishorizontalscale = atoi(values[E_AIL_PROP_X_SLP_ISHORIZONTALSCALE_BOOL]);
1050 info->x_slp_enabled = atoi(values[E_AIL_PROP_X_SLP_ENABLED_BOOL]);
1055 for (j = 0; j < i; ++j) {
1065 static ail_error_e _load_desktop_info(desktop_info_s* info)
1068 char query[AIL_SQL_QUERY_MAX_LEN];
1069 sqlite3_stmt *stmt = NULL;
1070 char w[AIL_SQL_QUERY_MAX_LEN];
1072 retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
1074 snprintf(w, sizeof(w), sql_get_filter(E_AIL_PROP_X_SLP_APPID_STR), info->package);
1076 snprintf(query, sizeof(query), "SELECT %s FROM %s WHERE %s",SQL_FLD_APP_INFO, SQL_TBL_APP_INFO, w);
1079 ret = db_open(DB_OPEN_RO);
1082 ret = db_prepare(query, &stmt);
1085 ret = db_step(stmt);
1091 ret = _retrieve_all_column_to_desktop_info(info, stmt);
1097 ret = db_finalize(stmt);
1100 return AIL_ERROR_OK;
1106 static ail_error_e _modify_desktop_info_bool(desktop_info_s* info,
1107 const char *property,
1110 ail_prop_bool_e prop;
1113 retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
1114 retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
1116 prop = _ail_convert_to_prop_bool(property);
1118 if (prop < E_AIL_PROP_BOOL_MIN || prop > E_AIL_PROP_BOOL_MAX)
1119 return AIL_ERROR_INVALID_PARAMETER;
1122 case E_AIL_PROP_X_SLP_ENABLED_BOOL:
1123 info->x_slp_enabled = (int)value;
1126 return AIL_ERROR_FAIL;
1129 return AIL_ERROR_OK;
1133 static ail_error_e _modify_desktop_info_str(desktop_info_s* info,
1134 const char *property,
1137 ail_prop_bool_e prop;
1140 retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
1141 retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
1143 prop = _ail_convert_to_prop_str(property);
1145 if (prop < E_AIL_PROP_STR_MIN || prop > E_AIL_PROP_STR_MAX)
1146 return AIL_ERROR_INVALID_PARAMETER;
1149 case E_AIL_PROP_NAME_STR:
1150 SAFE_FREE_AND_STRDUP(value, info->name);
1151 retv_if (!info->name, AIL_ERROR_OUT_OF_MEMORY);
1153 case E_AIL_PROP_X_SLP_SVC_STR:
1154 SAFE_FREE_AND_STRDUP(value, info->x_slp_svc);
1155 retv_if (!info->x_slp_svc, AIL_ERROR_OUT_OF_MEMORY);
1158 return AIL_ERROR_FAIL;
1161 return AIL_ERROR_OK;
1167 static ail_error_e _create_table(void)
1171 const char *tbls[3] = {
1172 "CREATE TABLE app_info "
1173 "(package TEXT PRIMARY KEY, "
1174 "exec TEXT DEFAULT 'No Exec', "
1175 "name TEXT DEFAULT 'No Name', "
1176 "type TEXT DEFAULT 'Application', "
1177 "icon TEXT DEFAULT 'No Icon', "
1181 "x_slp_service TEXT, "
1182 "x_slp_packagetype TEXT, "
1183 "x_slp_packagecategories TEXT, "
1184 "x_slp_packageid TEXT, "
1187 "x_slp_exe_path TEXT, "
1188 "x_slp_appid TEXT, "
1189 "x_slp_pkgid TEXT, "
1190 "x_slp_domain TEXT, "
1191 "x_slp_baselayoutwidth INTEGER DEFAULT 0, "
1192 "x_slp_installedtime INTEGER DEFAULT 0, "
1193 "nodisplay INTEGER DEFAULT 0, "
1194 "x_slp_taskmanage INTEGER DEFAULT 1, "
1195 "x_slp_multiple INTEGER DEFAULT 0, "
1196 "x_slp_removable INTEGER DEFAULT 1, "
1197 "x_slp_ishorizontalscale INTEGER DEFAULT 0, "
1198 "x_slp_enabled INTEGER DEFAULT 1, "
1199 "desktop TEXT UNIQUE NOT NULL);",
1200 "CREATE TABLE localname (package TEXT NOT NULL, "
1201 "locale TEXT NOT NULL, "
1202 "name TEXT NOT NULL, PRIMARY KEY (package, locale));",
1206 ret = db_open(DB_OPEN_RW);
1207 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
1209 for (i = 0; tbls[i] != NULL; i++) {
1210 ret = db_exec(tbls[i]);
1211 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
1214 return AIL_ERROR_OK;
1218 static inline void _insert_localname(gpointer data, gpointer user_data)
1222 struct name_item *item = (struct name_item *)data;
1223 desktop_info_s *info = (desktop_info_s *)user_data;
1225 snprintf(query, sizeof(query), "insert into localname (package, locale, name) "
1226 "values ('%s', '%s', '%s');",
1227 info->package, item->locale, item->name);
1228 if (db_exec(query) < 0)
1229 _E("Failed to insert local name of package[%s]",info->package);
1232 static ail_error_e _insert_desktop_info(desktop_info_s *info)
1238 len = _strlen_desktop_info(info) + (0x01 << 10);
1239 query = calloc(1, len);
1240 retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
1242 sqlite3_snprintf(len, query, "insert into app_info ("
1251 "x_slp_packagetype, "
1252 "x_slp_packagecategories, "
1260 "x_slp_baselayoutwidth, "
1261 "x_slp_installedtime, "
1263 "x_slp_taskmanage, "
1266 "x_slp_ishorizontalscale, "
1270 "('%q', '%q', '%q', '%q', '%q', "
1271 "'%q', '%q', '%q', '%q', '%q', "
1272 "'%q', '%q', '%q', '%q', '%q', "
1273 "'%q', '%q', '%q', "
1274 "%d, %d, %d, %d, %d, %d, "
1285 info->x_slp_service,
1286 info->x_slp_packagetype,
1287 info->x_slp_packagecategories,
1288 info->x_slp_packageid,
1291 info->x_slp_exe_path,
1295 info->x_slp_baselayoutwidth,
1296 info->x_slp_installedtime,
1298 info->x_slp_taskmanage,
1299 info->x_slp_multiple,
1300 info->x_slp_removable,
1301 info->x_slp_ishorizontalscale,
1302 info->x_slp_enabled,
1306 ret = db_open(DB_OPEN_RW);
1307 if(ret != AIL_ERROR_OK) {
1308 _E("(tmp == NULL) return\n");
1310 return AIL_ERROR_DB_FAILED;
1313 ret = db_exec(query);
1315 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
1317 if (info->localname)
1318 _insert_local_info(info);
1320 _D("Add (%s).", info->package);
1322 return AIL_ERROR_OK;
1327 static ail_error_e _update_desktop_info(desktop_info_s *info)
1332 retv_if (NULL == info, AIL_ERROR_INVALID_PARAMETER);
1334 if (db_open(DB_OPEN_RW) < 0) {
1335 return AIL_ERROR_DB_FAILED;
1338 len = _strlen_desktop_info(info) + (0x01 << 10);
1339 query = calloc(1, len);
1340 retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
1342 sqlite3_snprintf ( len, query, "update app_info set "
1350 "x_slp_service='%q', "
1351 "x_slp_packagetype='%q', "
1352 "x_slp_packagecategories='%q', "
1353 "x_slp_packageid='%q', "
1356 "x_slp_exe_path='%q', "
1357 "x_slp_appid='%q', "
1358 "x_slp_pkgid='%q', "
1359 "x_slp_domain='%q', "
1360 "x_slp_baselayoutwidth=%d, "
1361 "x_slp_installedtime=%d, "
1363 "x_slp_taskmanage=%d, "
1364 "x_slp_multiple=%d, "
1365 "x_slp_removable=%d, "
1366 "x_slp_ishorizontalscale=%d, "
1367 "x_slp_enabled=%d, "
1369 "where package='%q'",
1377 info->x_slp_service,
1378 info->x_slp_packagetype,
1379 info->x_slp_packagecategories,
1380 info->x_slp_packageid,
1383 info->x_slp_exe_path,
1387 info->x_slp_baselayoutwidth,
1388 info->x_slp_installedtime,
1390 info->x_slp_taskmanage,
1391 info->x_slp_multiple,
1392 info->x_slp_removable,
1393 info->x_slp_ishorizontalscale,
1394 info->x_slp_enabled,
1398 if (db_exec(query) < 0) {
1400 return AIL_ERROR_DB_FAILED;
1403 snprintf(query, len, "delete from localname where package = '%s'", info->package);
1405 if (db_exec(query) < 0) {
1407 return AIL_ERROR_DB_FAILED;
1410 if (info->localname)
1411 _insert_local_info(info);
1413 _D("Update (%s).", info->package);
1417 return AIL_ERROR_OK;
1422 static ail_error_e _remove_package(const char* package)
1427 retv_if(!package, AIL_ERROR_INVALID_PARAMETER);
1429 if (db_open(DB_OPEN_RW) < 0) {
1430 return AIL_ERROR_DB_FAILED;
1433 size = strlen(package) + (0x01 << 10);
1434 query = calloc(1, size);
1435 retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
1437 snprintf(query, size, "delete from app_info where package = '%s'", package);
1439 if (db_exec(query) < 0) {
1441 return AIL_ERROR_DB_FAILED;
1444 snprintf(query, size, "delete from localname where package = '%s'", package);
1445 _D("query=%s",query);
1447 if (db_exec(query) < 0) {
1449 return AIL_ERROR_DB_FAILED;
1452 _D("Remove (%s).", package);
1455 return AIL_ERROR_OK;
1460 static ail_error_e _send_db_done_noti(noti_type type, const char *package)
1462 char *type_string, *noti_string;
1465 retv_if(!package, AIL_ERROR_INVALID_PARAMETER);
1469 type_string = "create";
1472 type_string = "update";
1475 type_string = "delete";
1478 return AIL_ERROR_FAIL;
1481 size = strlen(package) + 8;
1482 noti_string = calloc(1, size);
1483 retv_if(!noti_string, AIL_ERROR_OUT_OF_MEMORY);
1485 snprintf(noti_string, size, "%s:%s", type_string, package);
1486 vconf_set_str(VCONFKEY_AIL_INFO_STATE, noti_string);
1487 vconf_set_str(VCONFKEY_MENUSCREEN_DESKTOP, noti_string); // duplicate, will be removed
1488 _D("Noti : %s", noti_string);
1492 return AIL_ERROR_OK;
1496 static void inline _name_item_free_func(gpointer data)
1498 struct name_item *item = (struct name_item *)data;
1500 SAFE_FREE(item->locale);
1501 item->locale = NULL;
1502 SAFE_FREE(item->name);
1508 static void _fini_desktop_info(desktop_info_s *info)
1510 SAFE_FREE(info->exec);
1511 SAFE_FREE(info->name);
1512 SAFE_FREE(info->type);
1513 SAFE_FREE(info->icon);
1514 SAFE_FREE(info->categories);
1515 SAFE_FREE(info->version);
1516 SAFE_FREE(info->mimetype);
1517 SAFE_FREE(info->x_slp_service);
1518 SAFE_FREE(info->x_slp_packagetype);
1519 SAFE_FREE(info->x_slp_packagecategories);
1520 SAFE_FREE(info->x_slp_packageid);
1521 SAFE_FREE(info->x_slp_uri);
1522 SAFE_FREE(info->x_slp_svc);
1523 SAFE_FREE(info->x_slp_exe_path);
1524 SAFE_FREE(info->x_slp_appid);
1525 SAFE_FREE(info->x_slp_pkgid);
1526 SAFE_FREE(info->x_slp_domain);
1527 SAFE_FREE(info->desktop);
1528 if (info->localname) {
1529 g_slist_free_full(info->localname, _name_item_free_func);
1530 info->localname = NULL;
1536 static int __is_authorized()
1538 uid_t uid = getuid();
1539 if ((uid_t) 0 == uid )
1546 /* Public functions */
1547 EXPORT_API ail_error_e ail_desktop_add(const char *appid)
1549 desktop_info_s info = {0,};
1553 retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1554 if (!__is_authorized()) {
1555 _E("You are not an authorized user on adding!\n");
1559 count = _count_all();
1561 ret = _create_table();
1562 if (ret != AIL_ERROR_OK) {
1563 _D("Cannot create a table. Maybe there is already a table.");
1567 ret = _init_desktop_info(&info, appid);
1568 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1570 ret = _read_desktop_info(&info);
1571 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1573 ret = _insert_desktop_info(&info);
1574 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1576 ret = _send_db_done_noti(NOTI_ADD, appid);
1577 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1579 _fini_desktop_info(&info);
1581 return AIL_ERROR_OK;
1586 EXPORT_API ail_error_e ail_desktop_update(const char *appid)
1588 desktop_info_s info = {0,};
1591 retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1592 if (!__is_authorized()) {
1593 _E("You are not an authorized user on updating!\n");
1597 ret = _init_desktop_info(&info, appid);
1598 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1600 ret = _read_desktop_info(&info);
1601 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1603 ret = _update_desktop_info(&info);
1604 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1606 ret = _send_db_done_noti(NOTI_UPDATE, appid);
1607 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1609 _fini_desktop_info(&info);
1611 return AIL_ERROR_OK;
1616 EXPORT_API ail_error_e ail_desktop_remove(const char *appid)
1620 retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1621 if (!__is_authorized()) {
1622 _E("You are not an authorized user on removing!\n");
1626 ret = _remove_package(appid);
1627 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1629 ret = _send_db_done_noti(NOTI_REMOVE, appid);
1630 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1632 return AIL_ERROR_OK;
1636 EXPORT_API ail_error_e ail_desktop_appinfo_modify_bool(const char *appid,
1637 const char *property,
1641 desktop_info_s info = {0,};
1644 retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1646 retv_if(strcmp(property, AIL_PROP_X_SLP_ENABLED_BOOL),
1647 AIL_ERROR_INVALID_PARAMETER);
1649 ret = _init_desktop_info(&info, appid);
1650 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1652 ret = _load_desktop_info(&info);
1653 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1655 ret = _modify_desktop_info_bool(&info, property, value);
1656 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1658 ret = _update_desktop_info(&info);
1659 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1662 ret = _send_db_done_noti(NOTI_UPDATE, appid);
1663 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1666 _fini_desktop_info(&info);
1668 return AIL_ERROR_OK;
1672 EXPORT_API ail_error_e ail_desktop_appinfo_modify_str(const char *appid,
1673 const char *property,
1677 desktop_info_s info = {0,};
1680 retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
1682 ret = _init_desktop_info(&info, appid);
1683 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1685 ret = _load_desktop_info(&info);
1686 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1688 _D("info.name [%s], value [%s]", info.name, value);
1689 ret = _modify_desktop_info_str(&info, property, value);
1690 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1691 _D("info.name [%s], value [%s]", info.name, value);
1693 ret = _update_desktop_info(&info);
1694 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1697 ret = _send_db_done_noti(NOTI_UPDATE, appid);
1698 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_FAIL);
1701 _fini_desktop_info(&info);
1703 return AIL_ERROR_OK;