From: Hwankyu Jhun Date: Tue, 16 Apr 2019 04:52:23 +0000 (+0900) Subject: Add new functions for getting component information X-Git-Tag: accepted/tizen/unified/20190417.050117~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=07daceb9ac5e2ab3e9af61e4ad0bd0ebe06f284a;p=platform%2Fcore%2Fappfw%2Faul-1.git Add new functions for getting component information Adds: - aul_comp_info_create() - aul_comp_info_create_usr() - aul_comp_info_destroy() - aul_comp_info_clone() - aul_comp_info_get_app_id() - aul_comp_info_get_comp_id() - aul_comp_info_get_type() - aul_comp_info_get_launch_mode() - aul_comp_info_is_main_comp() - aul_comp_info_is_icon_display() - aul_comp_info_is_taskmanage() - aul_comp_info_get_icon() - aul_comp_info_get_label() - aul_comp_info_get_localed_label() - aul_comp_info_get_usr_localed_label() - aul_comp_info_foreach() - aul_comp_info_foreach_usr() Change-Id: Iec3882fffe488dd413cd40faa0a3eeda60690e3f Signed-off-by: Hwankyu Jhun --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b5dd6c..07a1cfe 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,7 @@ SET(HEADERS_LIB_AUL aul_key.h aul_comp_status.h aul_app_group.h + aul_comp_info.h ) # Install headers, other files diff --git a/include/aul_comp_info.h b/include/aul_comp_info.h new file mode 100644 index 0000000..1dd04ea --- /dev/null +++ b/include/aul_comp_info.h @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The component information handle. + * @since_tizen 5.5 + */ +typedef void *aul_comp_info_h; + +/** + * @brief Called to get the component information once for each installed component. + * @since_tizen 5.5 + * + * @param[in] handle The component information handle + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, \n + * otherwise @ false to break out of the loop + * @see aul_comp_info_foreach() + * @see aul_comp_info_usr_foreach() + */ +typedef bool (*aul_comp_info_cb)(aul_comp_info_h handle, void *user_data); + +/** + * @brief Creates the component information handle. + * @since_tizen 5.5 + * @remarks You MUST release @a handle using aul_comp_info_destroy(). + * + * @param[in] comp_id The component ID + * @param[out] handle The component information handle + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_create(const char *comp_id, aul_comp_info_h *handle); + +/** + * @brief Creates the component information handle. + * @since_tizen 5.5 + * @remarks You MUST release @a handle using aul_comp_info_destroy(). + * + * @param[in] comp_id The component ID + * @param[in] uid The user ID + * @param[out] handle The component information handle + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_create_usr(const char *comp_id, uid_t uid, + aul_comp_info_h *handle); + +/** + * @brief Destroys the component information handle. + * @since_tizen 5.5 + * + * @param[in] handle The component information handle + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_destroy(aul_comp_info_h handle); + +/** + * @brief Clones the component information handle. + * @since_tizen 5.5 + * @remarks You MUST release @a clone using aul_comp_info_destroy(). + * + * @param[in] handle The component information handle + * @param[out] clone A newly created component information handle, if successfully cloned + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_clone(aul_comp_info_h handle, aul_comp_info_h *clone); + +/** + * @brief Gets the application ID of the component. + * @since_tizen 5.5 + * @remarks You MUST NOT release @a app_id using free(). + * + * @param[in] handle The component information handle + * @param[out] app_id The application ID of the component + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_get_app_id(aul_comp_info_h handle, const char **app_id); + +/** + * @brief Gets the ID of the component. + * @since_tizen 5.5 + * @remarks You MUST NOT release @a comp_id using free(). + * + * @param[in] handle The component information handle + * @param[out] comp_id The ID of the component + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_get_comp_id(aul_comp_info_h handle, const char **comp_id); + +/** + * @brief Gets the type of the component. + * @since_tizen 5.5 + * @remarks You MUST NOT release @a type using free(). + * + * @param[in] handle The component information handle + * @param[out] type The type of the component + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_get_type(aul_comp_info_h handle, const char **type); + +/** + * @brief Gets the launch mode of the component. + * @since_tizen 5.5 + * @remarks You MUST NOT release @a launch_mode using free(). + * + * @param[in] handle The component information handle + * @param[out] launch_mode The launch mode of the component + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_get_launch_mode(aul_comp_info_h handle, + const char **launch_mode); + +/** + * @brief Checks whether the component is the main component or not. + * @since_tizen 5.5 + * + * @param[in] handle The component information handle + * @param[out] main_comp @c true if the component is the main component, \n + * otherwise @c false + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_is_main_comp(aul_comp_info_h handle, bool *main_comp); + +/** + * @brief Checks whether the icon of the component should be displayed or not. + * @since_tizen 5.5 + * + * @param[in] handle The component information handle + * @param[out] icon_display @c true if the icon should be displayed, \n + * otherwise @c false + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_is_icon_display(aul_comp_info_h handle, bool *icon_display); + +/** + * @brief Checks whether the component should be managed by task-manager or not. + * @since_tizen 5.5 + * + * @param[in] handle The component information handle + * @param[out] taskmanage @c true if the component should be managed by task-manager, \n + * otherwise @c false + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_is_taskmanage(aul_comp_info_h handle, bool *taskmanage); + +/** + * @brief Gets the icon path of the component. + * @since_tizen 5.5 + * @remarks You MUST NOT release @a icon using free(). + * + * @param[in] handle The component information handle + * @param[out] icon The icon path of the component + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_get_icon(aul_comp_info_h handle, const char **icon); + +/** + * @brief Gets the label of the component. + * @since_tizen 5.5 + * @remarks You MUST NOT release @a label using free(). + * + * @param[in] handle The component information handle + * @param[out] label The label of the component + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_get_label(aul_comp_info_h handle, const char **label); + +/** + * @brief Gets the localed label of the component. + * @since_tizen 5.5 + * @remarks You MUST release @a label using free(). + * + * @param[in] comp_id The component ID + * @param[in] locale The locale information + * @param[out] label The localed label of the component + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_get_localed_label(const char *comp_id, const char *locale, + char **label); + +/** + * @brief Gets the localed label of the component. + * @since_tizen 5.5 + * @remarks You MUST release @a label using free(). + * + * @param[in] comp_id The component ID + * @param[in] locale The locale information + * @param[in] uid The user ID + * @param[out] label The localed label of the component + * @return @c 0 on success, + * otherwise a negative error value + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_get_usr_localed_label(const char *comp_id, const char *locale, + uid_t uid, char **label); + +/** + * @brief Retrieves all installed components information of the specified application. + * @since_tizen 5.5 + * + * @param[in] app_id The application ID + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @see aul_comp_info_cb() + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_foreach(const char *app_id, aul_comp_info_cb callback, + void *user_data); + +/** + * @brief Retrieves all installed components information of the specified application. + * @since_tizen 5.5 + * + * @param[in] app_id The application ID + * @param[in] uid The user ID + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @see aul_comp_info_cb() + * + * @remarks This function is only for App Framework internally. + */ +int aul_comp_info_foreach_usr(const char *app_id, uid_t uid, + aul_comp_info_cb callback, void *user_data); + +#ifdef __cplusplus +} +#endif diff --git a/src/aul_comp_info.c b/src/aul_comp_info.c new file mode 100644 index 0000000..4c052e0 --- /dev/null +++ b/src/aul_comp_info.c @@ -0,0 +1,724 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "aul_comp_info.h" +#include "aul_util.h" +#include "aul_sock.h" +#include "aul_api.h" +#include "aul.h" + +#define ROOT_UID 0 +#define DEFAULT_LOCALE "No Locale" +#define BUSY_WAITING_USEC 50000 +#define BUSY_WAITING_MAX 40 + +#define AUL_COMP_INFO_START 0 +enum aul_comp_info_e { + AUL_COMP_INFO_APP_ID = AUL_COMP_INFO_START, + AUL_COMP_INFO_COMP_ID, + AUL_COMP_INFO_TYPE, + AUL_COMP_INFO_LAUNCH_MODE, + AUL_COMP_INFO_MAIN_COMP, + AUL_COMP_INFO_ICON_DISPLAY, + AUL_COMP_INFO_TASKMANAGE, + AUL_COMP_INFO_ICON, + AUL_COMP_INFO_LABEL, + AUL_COMP_INFO_MAX, +}; + +struct aul_comp_info_s { + char *value[AUL_COMP_INFO_MAX]; +}; + +static char *__get_system_locale(void) +{ + char *lang; + char *locale; + + lang = vconf_get_str(VCONFKEY_LANGSET); + if (lang == NULL) { + locale = strdup(DEFAULT_LOCALE); + if (locale == NULL) { + LOGE("out of memory"); + return NULL; + } + return locale; + } + + locale = malloc(sizeof(char) * 6); + if (locale == NULL) { + LOGE("out of memory"); + free(lang); + return NULL; + } + + strncpy(locale, lang, 2); + locale[2] = '-'; + locale[3] = tolower(lang[3]); + locale[4] = tolower(lang[4]); + locale[5] = '\0'; + + free(lang); + + return locale; +} + +static char *__get_db_path(uid_t uid) +{ + char db_path[PATH_MAX]; + const char *path; + + path = tzplatform_getenv(TZ_SYS_DB); + if (!path) { + _E("Failed to get TZ_SYS_DB path"); + return NULL; + } + + if (uid == ROOT_UID || uid == GLOBAL_USER) { + snprintf(db_path, sizeof(db_path), "%s/.component.db", path); + } else { + snprintf(db_path, sizeof(db_path), "%s/user/%u/.component.db", + path, uid); + } + + return strdup(db_path); +} + +static void __save_column_str(sqlite3_stmt *stmt, int idx, char **str) +{ + const char *val; + + val = (const char *)sqlite3_column_text(stmt, idx); + if (val) + *str = strdup(val); +} + +static bool __get_boolean_value(const char *str) +{ + if (str && !strcmp(str, "true")) + return true; + + return false; +} + +static int __db_busy_handler(void *data, int count) +{ + if (count < BUSY_WAITING_MAX) { + usleep(BUSY_WAITING_USEC); + return 1; + } + + LOGE("Database is busy"); + + return 0; +} + +static sqlite3 *__open_db(const char *path) +{ + sqlite3 *db = NULL; + int ret; + + ret = sqlite3_open_v2(path, &db, SQLITE_OPEN_READONLY, NULL); + if (ret != SQLITE_OK) { + LOGE("sqlite3_open_v2() is failed. error(%d)", ret); + if (db) + sqlite3_close_v2(db); + return NULL; + } + + ret = sqlite3_busy_handler(db, __db_busy_handler, NULL); + if (ret != SQLITE_OK) { + LOGE("Failed to register busy handler. error(%s)", + sqlite3_errmsg(db)); + sqlite3_close_v2(db); + return NULL; + } + + return db; +} + +static void __destroy_comp_info(gpointer data) +{ + struct aul_comp_info_s *info = (struct aul_comp_info_s *)data; + int idx; + + if (!info) + return; + + for (idx = AUL_COMP_INFO_START; idx < AUL_COMP_INFO_MAX; idx++) { + if (info->value[idx]) + free(info->value[idx]); + } + + free(info); +} + +static struct aul_comp_info_s *__clone_comp_info(struct aul_comp_info_s *info) +{ + struct aul_comp_info_s *comp_info; + int idx; + + comp_info = calloc(1, sizeof(struct aul_comp_info_s)); + if (!comp_info) { + _E("Out of memory"); + return NULL; + } + + for (idx = AUL_COMP_INFO_START; idx < AUL_COMP_INFO_MAX; idx++) { + comp_info->value[idx] = strdup(info->value[idx]); + if (!comp_info->value[idx]) { + _E("Out of memory"); + __destroy_comp_info(info); + return NULL; + } + } + + return comp_info; +} + +static int __create_comp_info(const char *comp_id, const char *locale, + uid_t uid, struct aul_comp_info_s **comp_info) +{ + static const char query_raw[] = "SELECT DISTINCT ci.app_id, " + "ci.component_id, ci.component_type, ci.component_launch_mode, " + "ci.component_main, ci.component_icon_display, ci.component_taskmanage, " + "COALESCE((SELECT component_label FROM component_localized_info " + "WHERE ci.component_id=component_id AND component_locale=%Q), " + "(SELECT component_label FROM component_localized_info " + "WHERE ci.component_id=component_id AND component_locale='No Locale')), " + "COALESCE((SELECT component_icon FROM component_localized_info " + "WHERE ci.component_id=component_id AND component_locale=%Q), " + "(SELECT component_icon FROM component_localized_info " + "WHERE ci.component_id=component_id AND component_locale='No Locale')) " + "FROM component_info as ci WHERE component_id=%Q"; + sqlite3_stmt *stmt = NULL; + sqlite3 *db = NULL; + char *query = NULL; + char *db_path; + int idx; + struct aul_comp_info_s *info; + int ret; + + db_path = __get_db_path(uid); + if (!db_path) { + _E("Failed to get db path"); + return AUL_R_ERROR; + } + + db = __open_db(db_path); + if (!db) { + _E("Failed to open db(%s)", db_path); + free(db_path); + return AUL_R_ERROR; + } + free(db_path); + + query = sqlite3_mprintf(query_raw, locale, locale, comp_id); + if (!query) { + _E("Out of memory"); + ret = AUL_R_ERROR; + goto end; + } + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + _E("sqlite3_prepare_v2() is failed. error(%s)", + sqlite3_errmsg(db)); + ret = AUL_R_ERROR; + goto end; + } + + ret = sqlite3_step(stmt); + if (ret != SQLITE_ROW) { + _E("sqlite3_step() is failed"); + ret = AUL_R_ENOENT; + goto end; + } + + info = calloc(1, sizeof(struct aul_comp_info_s)); + if (!info) { + _E("Out of memory"); + ret = AUL_R_ERROR; + goto end; + } + + for (idx = AUL_COMP_INFO_START; idx < AUL_COMP_INFO_MAX; idx++) + __save_column_str(stmt, idx, &info->value[idx]); + + *comp_info = info; + ret = AUL_R_OK; + +end: + if (stmt) + sqlite3_finalize(stmt); + if (query) + sqlite3_free(query); + if (db) + sqlite3_close_v2(db); + return ret; +} + +API int aul_comp_info_create(const char *comp_id, aul_comp_info_h *handle) +{ + return aul_comp_info_create_usr(comp_id, getuid(), handle); +} + +API int aul_comp_info_create_usr(const char *comp_id, uid_t uid, + aul_comp_info_h *handle) { + struct aul_comp_info_s *info; + char *locale; + int ret; + + if (!comp_id || !handle) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + locale = __get_system_locale(); + if (!locale) + return AUL_R_ERROR; + + ret = __create_comp_info(comp_id, locale, uid, &info); + if (ret != AUL_R_OK && uid != GLOBAL_USER) + ret = __create_comp_info(comp_id, locale, GLOBAL_USER, &info); + + free(locale); + if (ret != AUL_R_OK) + return ret; + + *handle = (aul_comp_info_h)info; + + return AUL_R_OK; +} + +API int aul_comp_info_destroy(aul_comp_info_h handle) +{ + struct aul_comp_info_s *info = (struct aul_comp_info_s *)handle; + + if (!handle) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + __destroy_comp_info(info); + + return AUL_R_OK; +} + +API int aul_comp_info_clone(aul_comp_info_h handle, aul_comp_info_h *clone) +{ + struct aul_comp_info_s *info = (struct aul_comp_info_s *)handle; + struct aul_comp_info_s *new_info; + + if (!handle || !clone) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + new_info = __clone_comp_info(info); + if (!new_info) { + _E("Failed to clone comp info"); + return AUL_R_ERROR; + } + + *clone = (aul_comp_info_h)new_info; + + return AUL_R_OK; +} + +API int aul_comp_info_get_app_id(aul_comp_info_h handle, const char **app_id) +{ + struct aul_comp_info_s *info = (struct aul_comp_info_s *)handle; + + if (!handle || !app_id) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *app_id = info->value[AUL_COMP_INFO_APP_ID]; + + return AUL_R_OK; +} + +API int aul_comp_info_get_comp_id(aul_comp_info_h handle, const char **comp_id) +{ + struct aul_comp_info_s *info = (struct aul_comp_info_s *)handle; + + if (!handle || !comp_id) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *comp_id = info->value[AUL_COMP_INFO_COMP_ID]; + + return AUL_R_OK; +} + +API int aul_comp_info_get_type(aul_comp_info_h handle, const char **type) +{ + struct aul_comp_info_s *info = (struct aul_comp_info_s *)handle; + + if (!handle || !type) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *type = info->value[AUL_COMP_INFO_TYPE]; + + return AUL_R_OK; +} + +API int aul_comp_info_get_launch_mode(aul_comp_info_h handle, + const char **launch_mode) +{ + struct aul_comp_info_s *info = (struct aul_comp_info_s *)handle; + + if (!handle || !launch_mode) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *launch_mode = info->value[AUL_COMP_INFO_LAUNCH_MODE]; + + return AUL_R_OK; +} + +API int aul_comp_info_is_main_comp(aul_comp_info_h handle, bool *main_comp) +{ + struct aul_comp_info_s *info = (struct aul_comp_info_s *)handle; + + if (!handle || !main_comp) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *main_comp = __get_boolean_value(info->value[AUL_COMP_INFO_MAIN_COMP]); + + return AUL_R_OK; +} + +API int aul_comp_info_is_icon_display(aul_comp_info_h handle, + bool *icon_display) +{ + struct aul_comp_info_s *info = (struct aul_comp_info_s *)handle; + + if (!handle || !icon_display) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *icon_display = + __get_boolean_value(info->value[AUL_COMP_INFO_ICON_DISPLAY]); + + return AUL_R_OK; +} + +API int aul_comp_info_is_taskmanage(aul_comp_info_h handle, bool *taskmanage) +{ + struct aul_comp_info_s *info = (struct aul_comp_info_s *)handle; + + if (!handle || !taskmanage) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *taskmanage = + __get_boolean_value(info->value[AUL_COMP_INFO_TASKMANAGE]); + + return AUL_R_OK; +} + +API int aul_comp_info_get_icon(aul_comp_info_h handle, const char **icon) +{ + struct aul_comp_info_s *info = (struct aul_comp_info_s *)handle; + + if (!handle || !icon) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *icon = info->value[AUL_COMP_INFO_ICON]; + + return AUL_R_OK; +} + +API int aul_comp_info_get_label(aul_comp_info_h handle, const char **label) +{ + struct aul_comp_info_s *info = (struct aul_comp_info_s *)handle; + + if (!handle || !label) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *label = info->value[AUL_COMP_INFO_LABEL]; + + return AUL_R_OK; +} + +static int __get_localed_label(const char *comp_id, const char *locale, + uid_t uid, char **label) +{ + static const char query_raw[] = + "SELECT component_label from component_localed_info " + "WHERE component_id=%Q AND component_locale=%Q"; + sqlite3_stmt *stmt = NULL; + sqlite3 *db = NULL; + char *query = NULL; + char *db_path; + const char *val; + int ret; + + db_path = __get_db_path(uid); + if (!db_path) { + _E("Failed to get db path"); + return AUL_R_ERROR; + } + + db = __open_db(db_path); + if (!db) { + _E("Failed to open db(%s)", db_path); + free(db_path); + return AUL_R_ERROR; + } + free(db_path); + + query = sqlite3_mprintf(query_raw, comp_id, locale); + if (!query) { + _E("Out of memory"); + ret = AUL_R_ERROR; + goto end; + } + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("sqlite3_prepare_v2() is failed."); + ret = AUL_R_ERROR; + goto end; + } + + ret = sqlite3_step(stmt); + if (ret == SQLITE_ROW) { + val = (const char *)sqlite3_column_text(stmt, 0); + if (val) { + *label = strdup(val); + if (*label == NULL) + ret = AUL_R_ERROR; + else + ret = AUL_R_OK; + } else { + ret = AUL_R_ERROR; + } + } else { + ret = AUL_R_ENOENT; + } +end: + if (stmt) + sqlite3_finalize(stmt); + if (query) + sqlite3_free(query); + if (db) + sqlite3_close(db); + + return ret; +} + +API int aul_comp_info_get_localed_label(const char *comp_id, const char *locale, + char **label) +{ + return aul_comp_info_get_usr_localed_label(comp_id, locale, getuid(), + label); +} + +API int aul_comp_info_get_usr_localed_label(const char *comp_id, + const char *locale, uid_t uid, char **label) +{ + char *value; + int ret; + + if (!comp_id || !locale || !label) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + ret = __get_localed_label(comp_id, locale, uid, &value); + if (ret != AUL_R_OK) + ret = __get_localed_label(comp_id, DEFAULT_LOCALE, uid, &value); + + if (ret != AUL_R_OK) { + ret = __get_localed_label(comp_id, locale, GLOBAL_USER, &value); + if (ret != AUL_R_OK) { + ret = __get_localed_label(comp_id, DEFAULT_LOCALE, + GLOBAL_USER, &value); + } + } + + if (ret != AUL_R_OK) + return ret; + + *label = value; + + return AUL_R_OK; +} + +static int __get_comp_info_list(const char *app_id, const char *locale, + uid_t uid, GList **list) +{ + static const char query_raw[] = "SELECT DISTINCT ci.app_id, " + "ci.component_id, ci.component_type, ci.component_launch_mode, " + "ci.component_main, ci.component_icon_display, ci.component_taskmanage, " + "COALESCE((SELECT component_label FROM component_localized_info " + "WHERE ci.component_id=component_id AND component_locale=%Q), " + "(SELECT component_label FROM component_localized_info " + "WHERE ci.component_id=component_id AND component_locale='No Locale')), " + "COALESCE((SELECT component_icon FROM component_localized_info " + "WHERE ci.component_id=component_id AND component_locale=%Q), " + "(SELECT component_icon FROM component_localized_info " + "WHERE ci.component_id=component_id AND component_locale='No Locale')) " + "FROM component_info as ci WHERE app_id=%Q"; + sqlite3_stmt *stmt = NULL; + sqlite3 *db = NULL; + char *query = NULL; + char *db_path; + int idx; + struct aul_comp_info_s *info; + int ret; + + db_path = __get_db_path(uid); + if (!db_path) { + _E("Failed to get db path"); + return AUL_R_ERROR; + } + + db = __open_db(db_path); + if (!db) { + _E("Failed to open db(%s)", db_path); + free(db_path); + return AUL_R_ERROR; + } + free(db_path); + + query = sqlite3_mprintf(query_raw, locale, locale, app_id); + if (!query) { + _E("Out of memory"); + ret = AUL_R_ERROR; + goto end; + } + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + _E("sqlite3_prepare_v2() is failed. error(%s)", + sqlite3_errmsg(db)); + ret = AUL_R_ERROR; + goto end; + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + info = calloc(1, sizeof(struct aul_comp_info_s)); + if (!info) { + _E("Out of memory"); + if (*list) { + g_list_free_full(*list, __destroy_comp_info); + *list = NULL; + } + ret = AUL_R_ERROR; + goto end; + } + + for (idx = AUL_COMP_INFO_START; idx < AUL_COMP_INFO_MAX; idx++) + __save_column_str(stmt, idx, &info->value[idx]); + + *list = g_list_append(*list, info); + } + + if (*list == NULL) + ret = AUL_R_ENOENT; + else + ret = AUL_R_OK; + +end: + if (stmt) + sqlite3_finalize(stmt); + if (query) + sqlite3_free(query); + if (db) + sqlite3_close_v2(db); + + return ret; +} + +API int aul_comp_info_foreach(const char *app_id, aul_comp_info_cb callback, + void *user_data) +{ + return aul_comp_info_foreach_usr(app_id, getuid(), callback, user_data); +} + +API int aul_comp_info_foreach_usr(const char *app_id, uid_t uid, + aul_comp_info_cb callback, void *user_data) +{ + struct aul_comp_info_s *info; + GList *list = NULL; + GList *iter; + char *locale; + int ret; + + if (!app_id || !callback) { + LOGE("Invalid parameter"); + return AUL_R_EINVAL; + } + + locale = __get_system_locale(); + if (!locale) { + _E("Failed to get system locale"); + return AUL_R_ERROR; + } + + ret = __get_comp_info_list(app_id, locale, uid, &list); + if (ret != AUL_R_OK && uid != GLOBAL_USER) + ret = __get_comp_info_list(app_id, locale, GLOBAL_USER, &list); + + free(locale); + if (ret != AUL_R_OK) { + _E("Failed to get comp infos"); + return ret; + } + + iter = list; + while (iter) { + info = (struct aul_comp_info_s *)iter->data; + if (!callback((aul_comp_info_h)info, user_data)) + break; + iter = g_list_next(iter); + } + + g_list_free_full(list, __destroy_comp_info); + + return AUL_R_OK; +} +