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 <tzplatform_config.h>
34 #include "ail_private.h"
35 #include "ail_convert.h"
38 #include "ail_package.h"
40 #define LANGUAGE_LENGTH 2
41 #define DEFAULT_LOCALE "No Locale"
42 #define MAX_QUERY_LEN 4096
43 #define PKG_SD_PATH tzplatform_mkpath(TZ_SYS_STORAGE, "sdcard/app2sd/")
44 #define QUERY_GET_LOCALNAME "select name from localname where package='%s' and locale='%s'"
51 typedef struct _pkgmgr_locale_x {
55 /* get the first locale value*/
56 static int __fallback_locale_cb(void *data, int ncols, char **coltxt, char **colname)
58 pkgmgr_locale_x *info = (pkgmgr_locale_x *)data;
61 info->locale = strdup(coltxt[0]);
68 static int __check_validation_of_query_cb(void *data, int ncols, char **coltxt, char **colname)
75 static int __check_app_locale_from_app_localized_info_by_exact(const char *appid, const char *locale)
77 int result_query = -1;
78 char query[MAX_QUERY_LEN];
80 snprintf(query, MAX_QUERY_LEN, "select exists(select locale from localname where package='%s' and locale='%s')", appid, locale);
81 db_exec_sqlite_query(query, __check_validation_of_query_cb, (void *)&result_query);
86 static int __check_app_locale_from_app_localized_info_by_fallback(const char *appid, const char *locale)
88 int result_query = -1;
89 char wildcard[2] = {'%', '\0'};
90 char query[MAX_QUERY_LEN];
91 char lang[3] = {'\0'};
92 strncpy(lang, locale, LANGUAGE_LENGTH);
94 snprintf(query, MAX_QUERY_LEN, "select exists(select locale from localname where package='%s' and locale like '%s%s')", appid, lang, wildcard);
95 db_exec_sqlite_query(query, __check_validation_of_query_cb, (void *)&result_query);
100 static char* __get_app_locale_from_app_localized_info_by_fallback(const char *appid, const char *locale)
102 char wildcard[2] = {'%', '\0'};
103 char lang[3] = {'\0'};
104 char query[MAX_QUERY_LEN];
105 char *locale_new = NULL;
106 pkgmgr_locale_x *info = NULL;
108 info = (pkgmgr_locale_x *)malloc(sizeof(pkgmgr_locale_x));
110 _E("Out of Memory!!!\n");
113 memset(info, 0x00, sizeof(*info));
115 strncpy(lang, locale, 2);
116 snprintf(query, MAX_QUERY_LEN, "select locale from localname where package='%s' and locale like '%s%s'", appid, lang, wildcard);
117 db_exec_sqlite_query(query, __fallback_locale_cb, (void *)info);
118 locale_new = info->locale;
124 static char* __convert_syslocale_to_manifest_locale(const char *syslocale)
126 char *locale = malloc(6);
128 _E("Malloc Failed\n");
132 snprintf(locale, 6, "%c%c_%c%c", syslocale[0], syslocale[1], toupper(syslocale[3]), toupper(syslocale[4]));
136 static char* __get_app_locale_by_fallback(const char *appid, const char *syslocale)
142 char *locale_new = NULL;
143 int check_result = 0;
145 locale = __convert_syslocale_to_manifest_locale(syslocale);
147 /*check exact matching */
148 check_result = __check_app_locale_from_app_localized_info_by_exact(appid, locale);
151 if (check_result == 1) {
152 _D("%s find exact locale(%s)\n", appid, locale);
156 /* fallback matching */
157 check_result = __check_app_locale_from_app_localized_info_by_fallback(appid, locale);
158 if (check_result == 1) {
159 locale_new = __get_app_locale_from_app_localized_info_by_fallback(appid, locale);
160 _D("%s found (%s) language-locale in DB by fallback!\n", appid, locale_new);
162 if (locale_new == NULL)
163 locale_new = strdup(DEFAULT_LOCALE);
169 _D("%s DEFAULT_LOCALE)\n", appid);
170 return strdup(DEFAULT_LOCALE);
173 static ail_error_e __retrieve_all_column(ail_appinfo_h ai)
179 retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
180 retv_if(!ai->stmt, AIL_ERROR_INVALID_PARAMETER);
182 ai->values = calloc(NUM_OF_PROP, sizeof(char *));
183 retv_if(!ai->values, AIL_ERROR_OUT_OF_MEMORY);
185 for (i = 0; i < NUM_OF_PROP; i++) {
186 err = db_column_str(ai->stmt, i, &col);
187 if (AIL_ERROR_OK != err)
191 ai->values[i] = NULL;
193 ai->values[i] = strdup(col);
194 if (!ai->values[i]) {
195 err = AIL_ERROR_OUT_OF_MEMORY;
202 for (j = 0; j < i; ++j) {
213 int _appinfo_check_installed_storage(ail_appinfo_h ai)
216 ail_prop_str_e prop = -1;
218 char *installed_storage = NULL;
219 char buf[AIL_SQL_QUERY_MAX_LEN] = {'\0'};
221 retv_if(!ai, AIL_ERROR_OK);
224 prop = _ail_convert_to_prop_str(AIL_PROP_X_SLP_INSTALLEDSTORAGE_STR);
225 index = sql_get_app_info_idx(prop);
226 if (db_column_str(ai->stmt, index, &installed_storage) < 0)
229 prop = _ail_convert_to_prop_str(AIL_PROP_X_SLP_PKGID_STR);
230 index = sql_get_app_info_idx(prop);
231 if (db_column_str(ai->stmt, index, &pkgid) < 0)
234 prop = _ail_convert_to_prop_str(AIL_PROP_X_SLP_INSTALLEDSTORAGE_STR);
235 installed_storage = ai->values[prop];
237 prop = _ail_convert_to_prop_str(AIL_PROP_X_SLP_PKGID_STR);
238 pkgid = ai->values[prop];
241 if (strcmp(installed_storage, "installed_external") == 0) {
242 snprintf(buf, AIL_SQL_QUERY_MAX_LEN - 1, "%s%s", PKG_SD_PATH, pkgid);
243 if (access(buf, R_OK) != 0) {
244 _E("can not access [%s]", buf);
245 return AIL_ERROR_OK; /* tmep, it will be fixed to :: return AIL_ERROR_FAIL; */
252 void appinfo_set_stmt(ail_appinfo_h ai, sqlite3_stmt *stmt)
257 ail_appinfo_h appinfo_create(void)
260 ai = calloc(1, sizeof(struct ail_appinfo));
261 retv_if(ai == NULL, NULL);
267 void appinfo_destroy(ail_appinfo_h ai)
273 EXPORT_API ail_error_e ail_package_destroy_appinfo(ail_appinfo_h ai)
275 return ail_destroy_appinfo(ai);
278 EXPORT_API ail_error_e ail_destroy_appinfo(ail_appinfo_h ai)
282 retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
283 retv_if(!ai->values, AIL_ERROR_INVALID_PARAMETER);
285 for (i = 0; i < NUM_OF_PROP; i++) {
297 EXPORT_API ail_error_e ail_package_get_appinfo(const char *package, ail_appinfo_h *ai)
299 return ail_get_appinfo(package, ai);
302 EXPORT_API ail_error_e ail_package_get_usr_appinfo(const char *package, uid_t uid, ail_appinfo_h *ai)
304 return ail_get_usr_appinfo(package, uid, ai);
307 EXPORT_API ail_error_e ail_get_appinfo(const char *appid, ail_appinfo_h *ai)
310 char query[AIL_SQL_QUERY_MAX_LEN];
311 sqlite3_stmt *stmt = NULL;
312 char w[AIL_SQL_QUERY_MAX_LEN];
315 retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
316 retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
318 *ai = appinfo_create();
319 retv_if(!*ai, AIL_ERROR_OUT_OF_MEMORY);
321 filter = sql_get_filter(E_AIL_PROP_X_SLP_APPID_STR);
322 if (filter == NULL) {
323 appinfo_destroy(*ai);
324 return AIL_ERROR_FAIL;
327 snprintf(w, sizeof(w), filter, appid);
328 snprintf(query, sizeof(query), "SELECT %s FROM %s WHERE %s",
329 SQL_FLD_APP_INFO, SQL_TBL_APP_INFO, w);
332 ret = db_open(DB_OPEN_RO, GLOBAL_USER);
337 ret = db_prepare_globalro(query, &stmt);
349 ret = _appinfo_check_installed_storage(*ai);
351 db_finalize((*ai)->stmt);
355 ret = __retrieve_all_column(*ai);
357 db_finalize((*ai)->stmt);
361 ret = db_finalize((*ai)->stmt);
370 appinfo_destroy(*ai);
375 EXPORT_API ail_error_e ail_get_usr_appinfo(const char *appid, uid_t uid, ail_appinfo_h *ai)
378 char query[AIL_SQL_QUERY_MAX_LEN];
379 sqlite3_stmt *stmt = NULL;
380 char w[AIL_SQL_QUERY_MAX_LEN];
383 retv_if(!appid, AIL_ERROR_INVALID_PARAMETER);
384 retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
386 *ai = appinfo_create();
387 retv_if(!*ai, AIL_ERROR_OUT_OF_MEMORY);
389 filter = sql_get_filter(E_AIL_PROP_X_SLP_APPID_STR);
390 if (filter == NULL) {
391 appinfo_destroy(*ai);
392 return AIL_ERROR_FAIL;
395 snprintf(w, sizeof(w), filter, appid);
396 snprintf(query, sizeof(query), "SELECT %s FROM %s WHERE %s",
397 SQL_FLD_APP_INFO, SQL_TBL_APP_INFO, w);
400 ret = db_open(DB_OPEN_RO, uid);
405 ret = db_prepare(query, &stmt);
417 ret = _appinfo_check_installed_storage(*ai);
419 db_finalize((*ai)->stmt);
423 ret = __retrieve_all_column(*ai);
425 db_finalize((*ai)->stmt);
429 ret = db_finalize((*ai)->stmt);
438 appinfo_destroy(*ai);
443 EXPORT_API ail_error_e ail_appinfo_get_bool(const ail_appinfo_h ai, const char *property, bool *value)
445 ail_prop_bool_e prop;
448 retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
449 retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
450 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
452 prop = _ail_convert_to_prop_bool(property);
454 if (prop < E_AIL_PROP_BOOL_MIN || prop > E_AIL_PROP_BOOL_MAX)
455 return AIL_ERROR_INVALID_PARAMETER;
459 index = sql_get_app_info_idx(prop);
460 if (db_column_bool(ai->stmt, index, value) < 0)
461 return AIL_ERROR_DB_FAILED;
463 val = atoi(ai->values[prop]);
464 *value = (val == 0) ? false : true;
469 EXPORT_API ail_error_e ail_appinfo_get_int(const ail_appinfo_h ai, const char *property, int *value)
473 retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
474 retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
475 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
477 prop = _ail_convert_to_prop_int(property);
479 if (prop < E_AIL_PROP_INT_MIN || prop > E_AIL_PROP_INT_MAX)
480 return AIL_ERROR_INVALID_PARAMETER;
484 index = sql_get_app_info_idx(prop);
485 if (db_column_int(ai->stmt, index, value) < 0)
486 return AIL_ERROR_DB_FAILED;
488 *value = atoi(ai->values[prop]);
493 char *appinfo_get_localname(const char *package, char *locale, uid_t uid)
495 db_open(DB_OPEN_RO, uid);
501 snprintf(query, sizeof(query), QUERY_GET_LOCALNAME, package, locale);
503 if (uid != GLOBAL_USER)
504 retv_if(db_prepare(query, &stmt) < 0, NULL);
506 retv_if(db_prepare_globalro(query, &stmt) < 0, NULL);
509 if (db_step(stmt) < 0)
511 if (db_column_str(stmt, 0, &str) < 0)
514 localname = strdup(str);
527 EXPORT_API ail_error_e ail_appinfo_get_str(const ail_appinfo_h ai, const char *property, char **str)
533 char *locale, *localname;
537 retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
538 retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
539 retv_if(!str, AIL_ERROR_INVALID_PARAMETER);
541 prop = _ail_convert_to_prop_str(property);
543 if (prop < E_AIL_PROP_STR_MIN || prop > E_AIL_PROP_STR_MAX)
544 return AIL_ERROR_INVALID_PARAMETER;
548 if (E_AIL_PROP_NAME_STR == prop) {
550 if (db_column_str(ai->stmt, E_AIL_PROP_X_SLP_PACKAGETYPE_STR, &pkg_type) < 0)
551 return AIL_ERROR_DB_FAILED;
552 if (pkg_type && (strcasecmp(pkg_type, "tpk") == 0)) {
553 locale = sql_get_locale();
554 retv_if(locale == NULL, AIL_ERROR_FAIL);
556 if (db_column_str(ai->stmt, E_AIL_PROP_PACKAGE_STR, &pkg) < 0) {
558 return AIL_ERROR_DB_FAILED;
562 return AIL_ERROR_DB_FAILED;
565 locale_new = __get_app_locale_by_fallback(pkg, locale);
566 localname = (char *)appinfo_get_localname(pkg, locale_new, GLOBAL_USER);
570 if (db_column_str(ai->stmt, SQL_LOCALNAME_IDX, &localname) < 0)
571 return AIL_ERROR_DB_FAILED;
574 pkg_type = ai->values[E_AIL_PROP_X_SLP_PACKAGETYPE_STR];
575 pkg = ai->values[E_AIL_PROP_PACKAGE_STR];
576 retv_if(pkg == NULL, AIL_ERROR_FAIL);
578 locale = sql_get_locale();
579 retv_if(locale == NULL, AIL_ERROR_FAIL);
581 if (pkg_type && (strcasecmp(pkg_type, "tpk") == 0)) {
582 locale_new = __get_app_locale_by_fallback(pkg, locale);
583 localname = (char *)appinfo_get_localname(pkg, locale_new, GLOBAL_USER);
587 localname = (char *)appinfo_get_localname(pkg, locale, GLOBAL_USER);
595 if (ai->values[prop])
596 free(ai->values[prop]);
597 ai->values[prop] = localname;
606 index = sql_get_app_info_idx(prop);
607 if (db_column_str(ai->stmt, index, &value) < 0)
608 return AIL_ERROR_DB_FAILED;
612 *str = ai->values[prop];
617 EXPORT_API ail_error_e ail_appinfo_get_usr_str(const ail_appinfo_h ai, const char *property, uid_t uid, char **str)
623 char *locale, *localname;
627 retv_if(!ai, AIL_ERROR_INVALID_PARAMETER);
628 retv_if(!property, AIL_ERROR_INVALID_PARAMETER);
629 retv_if(!str, AIL_ERROR_INVALID_PARAMETER);
631 prop = _ail_convert_to_prop_str(property);
633 if (prop < E_AIL_PROP_STR_MIN || prop > E_AIL_PROP_STR_MAX)
634 return AIL_ERROR_INVALID_PARAMETER;
638 if (E_AIL_PROP_NAME_STR == prop) {
640 if (db_column_str(ai->stmt, E_AIL_PROP_X_SLP_PACKAGETYPE_STR, &pkg_type) < 0)
641 return AIL_ERROR_DB_FAILED;
642 if (pkg_type && (strcasecmp(pkg_type, "tpk") == 0)) {
643 locale = sql_get_locale();
644 retv_if(locale == NULL, AIL_ERROR_FAIL);
646 if (db_column_str(ai->stmt, E_AIL_PROP_PACKAGE_STR, &pkg) < 0) {
648 return AIL_ERROR_DB_FAILED;
652 return AIL_ERROR_DB_FAILED;
655 locale_new = __get_app_locale_by_fallback(pkg, locale);
656 localname = (char *)appinfo_get_localname(pkg, locale_new, uid);
660 if (db_column_str(ai->stmt, SQL_LOCALNAME_IDX, &localname) < 0)
661 return AIL_ERROR_DB_FAILED;
664 pkg_type = ai->values[E_AIL_PROP_X_SLP_PACKAGETYPE_STR];
665 pkg = ai->values[E_AIL_PROP_PACKAGE_STR];
666 retv_if(pkg == NULL, AIL_ERROR_FAIL);
668 locale = sql_get_locale();
669 retv_if(locale == NULL, AIL_ERROR_FAIL);
671 if (pkg_type && (strcasecmp(pkg_type, "tpk") == 0)) {
672 locale_new = __get_app_locale_by_fallback(pkg, locale);
673 localname = (char *)appinfo_get_localname(pkg, locale_new, uid);
677 localname = (char *)appinfo_get_localname(pkg, locale, uid);
685 if (ai->values[prop])
686 free(ai->values[prop]);
687 ai->values[prop] = localname;
696 index = sql_get_app_info_idx(prop);
697 if (db_column_str(ai->stmt, index, &value) < 0)
698 return AIL_ERROR_DB_FAILED;
702 *str = ai->values[prop];
707 EXPORT_API ail_error_e ail_close_appinfo_db(void)