--- /dev/null
+/*
+ * 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 <unistd.h>
+
+#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
--- /dev/null
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <linux/limits.h>
+#include <ctype.h>
+#include <sqlite3.h>
+#include <glib.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <vconf.h>
+
+#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;
+}
+