From 08eacf47431c45367c15fe2c8f6554e38d22c190 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 2 Jul 2019 13:46:10 +0900 Subject: [PATCH] Support permission check After this patch is applied, the packagemanager.info privilege is needed to get the component information and the running component context. If a process sends a request to get the component information, AMD checks the privilege before sending the result. If the process doesn't have a permission, the function returns AUL_R_EILLACC. The privilege is needed to use the follwing list: - aul_comp_info_create() - aul_comp_info_usr_create() - aul_comp_info_foreach_comp_info_from_app() - aul_comp_info_usr_foreach_comp_info_from_app() - aul_comp_info_foreach_comp_info() - aul_comp_info_usr_foreach_comp_info() - aul_comp_context_foreach_comp_context() - aul_comp_context_create() - aul_comp_context_usr_create() Change-Id: I1494c4d6eb7e8bbd5b8c67ae181776998b518f9c Signed-off-by: Hwankyu Jhun --- CMakeLists.txt | 1 + include/aul_cmd.h | 3 + include/aul_comp_context.h | 13 +- include/aul_comp_info.h | 49 +- include/aul_comp_info_internal.h | 371 ++++++++++++ include/aul_key.h | 50 +- src/aul_cmd.c | 4 + src/aul_comp_context.c | 6 +- src/aul_comp_info.c | 1237 +++++++++++++++++++++++++++----------- src/aul_comp_info_internal.c | 799 ++++++++++++++++++++++++ tool/compmgr_tool.c | 20 +- 11 files changed, 2167 insertions(+), 386 deletions(-) create mode 100644 include/aul_comp_info_internal.h create mode 100644 src/aul_comp_info_internal.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 551adbe..f1a8502 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,7 @@ SET(HEADERS_LIB_AUL aul_app_group.h aul_comp_info.h aul_comp_context.h + aul_comp_info_internal.h ) # Install headers, other files diff --git a/include/aul_cmd.h b/include/aul_cmd.h index d0b3ded..f7bc61c 100755 --- a/include/aul_cmd.h +++ b/include/aul_cmd.h @@ -163,6 +163,9 @@ enum app_cmd { APP_TERM_BG_INSTANCE = 129, LAUNCHPAD_CHILD_PROCESS = 130, + COMP_INFO_GET = 131, + COMP_INFO_FOREACH = 132, + APP_CMD_MAX }; diff --git a/include/aul_comp_context.h b/include/aul_comp_context.h index c0c9668..4c76958 100644 --- a/include/aul_comp_context.h +++ b/include/aul_comp_context.h @@ -40,13 +40,15 @@ typedef struct aul_comp_context_s *aul_comp_context_h; * @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_context_foreach() + * @see aul_comp_context_foreach_comp_context() */ typedef bool (*aul_comp_context_cb)(aul_comp_context_h handle, void *user_data); /** * @brief Retrieves all running components context. * @since_tizen 5.5 + * @privlevel public + * @privilege %http://tizen.org/privilege/packagemanager.info * * @param[in] callback The callback function to invoke * @param[in] user_data The user data to be passed to the callback function @@ -56,7 +58,8 @@ typedef bool (*aul_comp_context_cb)(aul_comp_context_h handle, void *user_data); * * @remarks This function is only for App Framework internally. */ -int aul_comp_context_foreach(aul_comp_context_cb callback, void *user_data); +int aul_comp_context_foreach_comp_context(aul_comp_context_cb callback, + void *user_data); /** * @brief Gets the application ID of the component. @@ -159,6 +162,8 @@ int aul_comp_context_is_sub_comp(aul_comp_context_h handle, bool *is_sub_comp); /** * @brief Creates the component context handle. * @since_tizen 5.5 + * @privlevel public + * @privilege %http://tizen.org/privilege/packagemanager.info * @remarks You MUST release @c clone using aul_comp_context_destroy(). * * @param[in] comp_id The component ID @@ -174,6 +179,8 @@ int aul_comp_context_create(const char *comp_id, aul_comp_context_h *handle); /** * @brief Creates the component context handle. * @since_tizen 5.5 + * @privlevel public + * @privilege %http://tizen.org/privilege/packagemanager.info * @remarks You MUST release @c clone using aul_comp_context_destroy(). * * @param[in] comp_id The component ID @@ -185,7 +192,7 @@ int aul_comp_context_create(const char *comp_id, aul_comp_context_h *handle); * @remarks This function is only for App Framework internally. * @see aul_comp_context_destroy() */ -int aul_comp_context_create_usr(const char *comp_id, uid_t uid, +int aul_comp_context_usr_create(const char *comp_id, uid_t uid, aul_comp_context_h *handle); /** diff --git a/include/aul_comp_info.h b/include/aul_comp_info.h index ea936d9..c711288 100644 --- a/include/aul_comp_info.h +++ b/include/aul_comp_info.h @@ -36,14 +36,16 @@ typedef void *aul_comp_info_h; * @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() + * @see aul_comp_info_foreach_comp_info() + * @see aul_comp_info_usr_foreach_comp_info() */ typedef bool (*aul_comp_info_cb)(aul_comp_info_h handle, void *user_data); /** * @brief Creates the component information handle. * @since_tizen 5.5 + * @privlevel public + * @privilege %http://tizen.org/privilege/packagemanager.info * @remarks You MUST release @a handle using aul_comp_info_destroy(). * * @param[in] comp_id The component ID @@ -58,6 +60,8 @@ int aul_comp_info_create(const char *comp_id, aul_comp_info_h *handle); /** * @brief Creates the component information handle. * @since_tizen 5.5 + * @privlevel public + * @privilege %http://tizen.org/privilege/packagemanager.info * @remarks You MUST release @a handle using aul_comp_info_destroy(). * * @param[in] comp_id The component ID @@ -68,7 +72,7 @@ int aul_comp_info_create(const char *comp_id, aul_comp_info_h *handle); * * @remarks This function is only for App Framework internally. */ -int aul_comp_info_create_usr(const char *comp_id, uid_t uid, +int aul_comp_info_usr_create(const char *comp_id, uid_t uid, aul_comp_info_h *handle); /** @@ -237,29 +241,14 @@ int aul_comp_info_get_label(aul_comp_info_h handle, const char **label); * * @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); +int aul_comp_info_get_localed_label(aul_comp_info_h handle, const char *locale, + const char **label); /** * @brief Retrieves all installed components information of the specified application. * @since_tizen 5.5 + * @privlevel public + * @privilege %http://tizen.org/privilege/packagemanager.info * * @param[in] app_id The application ID * @param[in] callback The callback function to invoke @@ -270,12 +259,14 @@ int aul_comp_info_get_usr_localed_label(const char *comp_id, const char *locale, * * @remarks This function is only for App Framework internally. */ -int aul_comp_info_foreach_from_app(const char *app_id, aul_comp_info_cb callback, - void *user_data); +int aul_comp_info_foreach_comp_info_from_app(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 + * @privlevel public + * @privilege %http://tizen.org/privilege/packagemanager.info * * @param[in] app_id The application ID * @param[in] uid The user ID @@ -287,12 +278,14 @@ int aul_comp_info_foreach_from_app(const char *app_id, aul_comp_info_cb callback * * @remarks This function is only for App Framework internally. */ -int aul_comp_info_foreach_usr_from_app(const char *app_id, uid_t uid, +int aul_comp_info_usr_foreach_comp_info_from_app(const char *app_id, uid_t uid, aul_comp_info_cb callback, void *user_data); /** * @brief Retrieves all installed components information. * @since_tizen 5.5 + * @privlevel public + * @privilege %http://tizen.org/privilege/packagemanager.info * * @param[in] callback The callback function to invoke * @param[in] user_data The user data to be passed to the callback function @@ -302,11 +295,13 @@ int aul_comp_info_foreach_usr_from_app(const char *app_id, uid_t uid, * * @remarks This function is only for App Framework internally. */ -int aul_comp_info_foreach(aul_comp_info_cb callback, void *user_data); +int aul_comp_info_foreach_comp_info(aul_comp_info_cb callback, void *user_data); /** * @brief Retrieves all installed components information. * @since_tizen 5.5 + * @privlevel public + * @privilege %http://tizen.org/privilege/packagemanager.info * * @param[in] uid The user ID * @param[in] callback The callback function to invoke @@ -317,7 +312,7 @@ int aul_comp_info_foreach(aul_comp_info_cb callback, void *user_data); * * @remarks This function is only for App Framework internally. */ -int aul_comp_info_foreach_usr(uid_t uid, aul_comp_info_cb callback, +int aul_comp_info_usr_foreach_comp_info(uid_t uid, aul_comp_info_cb callback, void *user_data); #ifdef __cplusplus diff --git a/include/aul_comp_info_internal.h b/include/aul_comp_info_internal.h new file mode 100644 index 0000000..294ba87 --- /dev/null +++ b/include/aul_comp_info_internal.h @@ -0,0 +1,371 @@ +/* + * 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_compinfo_h; + +/** + * @brief The localized information handle of the component. + * @since_tizen 5.5 + */ +typedef void *aul_compinfo_localized_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_compinfo_foreach_compinfo() + * @see aul_compinfo_usr_foreach_compinfo() + */ +typedef bool (*aul_compinfo_cb)(aul_compinfo_h handle, void *user_data); + +/** + * @brief Called to get the localized information once for each installed component. + * @since_tizen 5.5 + * + * @param[in] handle The localized_information handle of the component + * @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_compinfo_foreach_localized_info() + * @see aul_compinfo_usr_foreach_localized_info() + */ +typedef bool (*aul_compinfo_localized_info_cb)( + aul_compinfo_localized_info_h handle, void *user_data); + +/** + * @brief Creates the component information handle. + * @since_tizen 5.5 + * @remarks You MUST release @a handle using aul_compinfo_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_compinfo_create(const char *comp_id, aul_compinfo_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_compinfo_usr_create(const char *comp_id, uid_t uid, + aul_compinfo_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_compinfo_destroy(aul_compinfo_h handle); + +/** + * @brief Clones the component information handle. + * @since_tizen 5.5 + * @remarks You MUST release @a clone using aul_compinfo_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_compinfo_clone(aul_compinfo_h handle, aul_compinfo_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_compinfo_get_app_id(aul_compinfo_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_compinfo_get_comp_id(aul_compinfo_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_compinfo_get_type(aul_compinfo_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_compinfo_get_launch_mode(aul_compinfo_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_compinfo_is_main_comp(aul_compinfo_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_compinfo_is_icon_display(aul_compinfo_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_compinfo_is_taskmanage(aul_compinfo_h handle, bool *taskmanage); + +/** + * @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_compinfo_foreach_compinfo_from_app(const char *app_id, + aul_compinfo_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_compinfo_cb() + * + * @remarks This function is only for App Framework internally. + */ +int aul_compinfo_usr_foreach_compinfo_from_app(const char *app_id, uid_t uid, + aul_compinfo_cb callback, void *user_data); + +/** + * @brief Retrieves all installed components information. + * @since_tizen 5.5 + * + * @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_compinfo_cb() + * + * @remarks This function is only for App Framework internally. + */ +int aul_compinfo_foreach_compinfo(aul_compinfo_cb callback, void *user_data); + +/** + * @brief Retrieves all installed components information. + * @since_tizen 5.5 + * + * @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_compinfo_cb() + * + * @remarks This function is only for App Framework internally. + */ +int aul_compinfo_usr_foreach_compinfo(uid_t uid, aul_compinfo_cb callback, + void *user_data); + +/** + * @brief Gets the locale of the component. + * @since_tizen 5.5 + * @details The @a handle is passed from the aul_compinfo_localized_info_cb() function. + * @remarks You MUST NOT release @a locale using free(). + * + * @param[in] handle The localized information handle + * @param[out] locale The locale + * @return @c 0 on success, + * otherwise a negative error value + * @see aul_compinfo_foreach_localized_info() + * @see aul_compinfo_localized_info_cb() + * + * @remarks This function is only for App Framework insternally. + */ +int aul_compinfo_localized_info_get_locale(aul_compinfo_localized_info_h handle, + const char **locale); + +/** + * @brief Gets the icon path of the component. + * @since_tizen 5.5 + * @details The @a handle is passed from the aul_compinfo_localized_info_cb() function. + * @remarks You MUST NOT release @a icon using free(). + * + * @param[in] handle The localized information handle + * @param[out] icon The icon path + * @return @c 0 on success, + * otherwise a negative error value + * @see aul_compinfo_foreach_localized_info() + * @see aul_compinfo_localized_info_cb() + * + * @remarks This function is only for App Framework internally. + */ +int aul_compinfo_localized_info_get_icon(aul_compinfo_localized_info_h handle, + const char **icon); + +/** + * @brief Gets the label of the component. + * @since_tizen 5.5 + * @details The @a handle is passed from the aul_compinfo_localized_info_cb() function. + * @remarks You MUST NOT release @a label using free(). + * + * @param[in] handle The localized information handle + * @param[out] label The label + * @return @c 0 on success, + * otherwise a negative error value + * @see aul_compinfo_foreach_localized_info() + * @see aul_compinfo_localized_info_cb() + * + * @remarks This function is only for App Framework internally. + */ +int aul_compinfo_localized_info_get_label(aul_compinfo_localized_info_h handle, + const char **label); + +/** + * @brief Retrieves all localized information of the specified component. + * @since_tizen 5.5 + * + * @param[in] comp_id The component 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_compinfo_localized_info_cb() + * + * @remarks This function is only for App Framework internally. + */ +int aul_compinfo_foreach_localized_info(const char *comp_id, + aul_compinfo_localized_info_cb callback, void *user_data); + +/** + * @brief Retrieves all localized information of the specified component. + * @since_tizen 5.5 + * + * @param[in] comp_id The component 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_compinfo_localized_info_cb() + * + * @remarks This function is only for App Framework internally. + */ +int aul_compinfo_usr_foreach_localized_info(const char *comp_id, uid_t uid, + aul_compinfo_localized_info_cb callback, void *user_data); + +#ifdef __cplusplus +} +#endif diff --git a/include/aul_key.h b/include/aul_key.h index 9530749..85ab539 100644 --- a/include/aul_key.h +++ b/include/aul_key.h @@ -665,4 +665,52 @@ * @breif Definition for AUL: The flag if it's 'true', the component is sub component of the group. * @since_tizen 5.5 */ -#define AUL_K_IS_SUB_COMP "__AUL_IS_SUB_COMP__" +#define AUL_K_IS_SUB_COMP "__AUL_IS_SUB_COMP__" + +/** + * @brief Definition for AUL: The flag if it's 'true', the component is the main component of the application. + * @since_tizen 5.5 + */ +#define AUL_K_MAIN_COMP "__AUL_MAIN_COMP__" + +/** + * @brief Definition for AUL: The flag if it's 'true', the icon of the component should be display. + * @since_tizen 5.5 + */ +#define AUL_K_ICON_DISPLAY "__AUL_ICON_DISPLAY__" + +/** + * @brief Definition for AUL: The localized information. + * @since_tizen 5.5 + */ +#define AUL_K_LOCALIZED_INFO "__AUL_LOCALIZED_INFO__" + +/** + * @brief Definition for AUL: The size of the localized information. + * @since_tizen 5.5 + */ +#define AUL_K_LOCALIZED_INFO_SIZE "__AUL_LOCALIZED_INFO_SIZE__" + +/** + * @brief Definition for AUL: The locale. + * @since_tizen 5.5 + */ +#define AUL_K_LOCALE "__AUL_LOCALE__" + +/** + * @brief Definition for AUL: The icon path. + * @since_tizen 5.5 + */ +#define AUL_K_ICON "__AUL_ICON__" + +/** + * @brief Definition for AUL: The label. + * @since_tizen 5.5 + */ +#define AUL_K_LABEL "__AUL_LABEL__" + +/** + * @brief Definition for AUL: The launch mode. + * @since_tizen 5.5 + */ +#define AUL_K_LAUNCH_MODE "__AUL_LAUNCH_MODE__" diff --git a/src/aul_cmd.c b/src/aul_cmd.c index 64f4ec9..1b9dd1c 100755 --- a/src/aul_cmd.c +++ b/src/aul_cmd.c @@ -286,6 +286,10 @@ API const char *aul_cmd_convert_to_string(int cmd) return "APP_TERM_BG_INSTANCE"; case LAUNCHPAD_CHILD_PROCESS: return "LAUNCHPAD_CHILD_PROCESS"; + case COMP_INFO_GET: + return "COMP_INFO_GET"; + case COMP_INFO_FOREACH: + return "COMP_INFO_FOREACH"; default: return "CUSTOM_COMMAND"; } diff --git a/src/aul_comp_context.c b/src/aul_comp_context.c index 0b2b06a..3a3de37 100644 --- a/src/aul_comp_context.c +++ b/src/aul_comp_context.c @@ -180,7 +180,7 @@ static void __running_context_cb(app_pkt_t *pkt, void *user_data) *list = g_list_append(*list, context); } -API int aul_comp_context_foreach(aul_comp_context_cb callback, +API int aul_comp_context_foreach_comp_context(aul_comp_context_cb callback, void *user_data) { struct aul_comp_context_s *context; @@ -324,10 +324,10 @@ API int aul_comp_context_is_sub_comp(aul_comp_context_h context, API int aul_comp_context_create(const char *comp_id, aul_comp_context_h *handle) { - return aul_comp_context_create_usr(comp_id, getuid(), handle); + return aul_comp_context_usr_create(comp_id, getuid(), handle); } -API int aul_comp_context_create_usr(const char *comp_id, uid_t uid, +API int aul_comp_context_usr_create(const char *comp_id, uid_t uid, aul_comp_context_h *handle) { struct aul_comp_context_s *context; diff --git a/src/aul_comp_info.c b/src/aul_comp_info.c index fca342b..d71e465 100644 --- a/src/aul_comp_info.c +++ b/src/aul_comp_info.c @@ -30,6 +30,8 @@ #include "aul_comp_info.h" #include "aul_util.h" #include "aul_sock.h" +#include "aul_error.h" +#include "aul_sock.h" #include "aul_api.h" #include "aul.h" @@ -38,7 +40,9 @@ #define BUSY_WAITING_USEC 50000 #define BUSY_WAITING_MAX 40 +#define AUL_COMP_LOCALIZED_INFO_START 0 #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, @@ -47,8 +51,7 @@ enum aul_comp_info_e { AUL_COMP_INFO_MAIN_COMP, AUL_COMP_INFO_ICON_DISPLAY, AUL_COMP_INFO_TASKMANAGE, - AUL_COMP_INFO_LABEL, - AUL_COMP_INFO_ICON, + AUL_COMP_INFO_LOCALIZED_INFO, AUL_COMP_INFO_MAX, }; @@ -56,6 +59,268 @@ struct aul_comp_info_s { char *value[AUL_COMP_INFO_MAX]; }; +enum aul_comp_localized_info_e { + AUL_COMP_LOCALIZED_INFO_LOCALE = AUL_COMP_LOCALIZED_INFO_START, + AUL_COMP_LOCALIZED_INFO_ICON, + AUL_COMP_LOCALIZED_INFO_LABEL, + AUL_COMP_LOCALIZED_INFO_MAX, +}; + +struct aul_comp_localized_info_s { + char *value[AUL_COMP_LOCALIZED_INFO_MAX]; +}; + +typedef int (*aul_comp_info_add_cb)(bundle *b, + struct aul_comp_info_s *info, + void *data); +typedef void (*aul_comp_info_remove_cb)(void *data); +typedef int (*aul_comp_info_clone_cb)(struct aul_comp_info_s *info, + struct aul_comp_info_s *clone, + void *data); + +typedef struct _aul_comp_info_vft { + aul_comp_info_add_cb ctor; + aul_comp_info_remove_cb dtor; + aul_comp_info_clone_cb clnr; +} aul_comp_info_vft; + +typedef int (*aul_comp_localized_info_add_cb)(bundle *b, + struct aul_comp_localized_info_s *info, + void *data); +typedef void (*aul_comp_localized_info_remove_cb)(void *data); +typedef int (*aul_comp_localized_info_clone_cb)( + struct aul_comp_localized_info_s *info, + struct aul_comp_localized_info_s *clone, + void *data); + +typedef struct _aul_comp_localized_info_vft { + aul_comp_localized_info_add_cb ctor; + aul_comp_localized_info_remove_cb dtor; + aul_comp_localized_info_clone_cb clnr; +} aul_comp_localized_info_vft; + +static int __comp_localized_info_add_locale(bundle *b, + struct aul_comp_localized_info_s *info, + void *data) +{ + const char *locale; + + locale = bundle_get_val(b, AUL_K_LOCALE); + if (!locale) { + _E("Failed to get locale"); + return -1; + } + + info->value[AUL_COMP_LOCALIZED_INFO_LOCALE] = strdup(locale); + if (!info->value[AUL_COMP_LOCALIZED_INFO_LOCALE]) { + _E("Failed to duplicate locale"); + return -1; + } + + return 0; +} + +static int __comp_localized_info_add_icon(bundle *b, + struct aul_comp_localized_info_s *info, + void *data) +{ + const char *icon; + + icon = bundle_get_val(b, AUL_K_ICON); + if (!icon) { + _W("Failed to get icon"); + return 0; + } + + info->value[AUL_COMP_LOCALIZED_INFO_ICON] = strdup(icon); + if (!info->value[AUL_COMP_LOCALIZED_INFO_ICON]) { + _E("Failed to duplicate icon"); + return -1; + } + + return 0; +} + +static int __comp_localized_info_add_label(bundle *b, + struct aul_comp_localized_info_s *info, + void *data) +{ + const char *label; + + label = bundle_get_val(b, AUL_K_LABEL); + if (!label) { + _W("Failed to get label"); + return 0; + } + + info->value[AUL_COMP_LOCALIZED_INFO_LABEL] = strdup(label); + if (!info->value[AUL_COMP_LOCALIZED_INFO_LABEL]) { + _E("Failed to duplicate icon"); + return -1; + } + + return 0; +} + +static int __comp_localized_info_clone_locale( + struct aul_comp_localized_info_s *info, + struct aul_comp_localized_info_s *clone, + void *data) +{ + char *locale; + + if (!info->value[AUL_COMP_LOCALIZED_INFO_LOCALE]) { + _E("Invalid parameter"); + return -1; + } + + locale = strdup(info->value[AUL_COMP_LOCALIZED_INFO_LOCALE]); + if (!locale) { + _E("Failed to duplicate locale"); + return -1; + } + + clone->value[AUL_COMP_LOCALIZED_INFO_LOCALE] = locale; + + return 0; +} + +static int __comp_localized_info_clone_icon( + struct aul_comp_localized_info_s *info, + struct aul_comp_localized_info_s *clone, + void *data) +{ + char *icon; + + if (!info->value[AUL_COMP_LOCALIZED_INFO_ICON]) + return 0; + + icon = strdup(info->value[AUL_COMP_LOCALIZED_INFO_ICON]); + if (!icon) { + _E("Failed to duplicate icon"); + return -1; + } + + clone->value[AUL_COMP_LOCALIZED_INFO_ICON] = icon; + + return 0; +} + +static int __comp_localized_info_clone_label( + struct aul_comp_localized_info_s *info, + struct aul_comp_localized_info_s *clone, + void *data) +{ + char *label; + + if (!info->value[AUL_COMP_LOCALIZED_INFO_LABEL]) + return 0; + + label = strdup(info->value[AUL_COMP_LOCALIZED_INFO_LABEL]); + if (!label) { + _E("Failed to duplicate label"); + return -1; + } + + clone->value[AUL_COMP_LOCALIZED_INFO_LABEL] = label; + + return 0; +} + +static aul_comp_localized_info_vft __localized_info_table[] = { + { + .ctor = __comp_localized_info_add_locale, + .dtor = free, + .clnr = __comp_localized_info_clone_locale + }, + { + .ctor = __comp_localized_info_add_icon, + .dtor = free, + .clnr = __comp_localized_info_clone_icon + }, + { + .ctor = __comp_localized_info_add_label, + .dtor = free, + .clnr = __comp_localized_info_clone_label + }, +}; + +static void __destroy_comp_localized_info(gpointer data) +{ + struct aul_comp_localized_info_s *info; + int i; + + info = (struct aul_comp_localized_info_s *)data; + if (!info) + return; + + for (i = AUL_COMP_LOCALIZED_INFO_START; + i < AUL_COMP_LOCALIZED_INFO_MAX; + i++) { + if (__localized_info_table[i].dtor && info->value[i]) + __localized_info_table[i].dtor(info->value[i]); + } + + free(info); +} + +static struct aul_comp_localized_info_s *__create_comp_localized_info(bundle *b) +{ + struct aul_comp_localized_info_s *info; + int ret; + int i; + + info = calloc(1, sizeof(struct aul_comp_localized_info_s)); + if (!info) { + _E("Out of memory"); + return NULL; + } + + for (i = AUL_COMP_LOCALIZED_INFO_START; + i < AUL_COMP_LOCALIZED_INFO_MAX; + i++) { + if (__localized_info_table[i].ctor) { + ret = __localized_info_table[i].ctor(b, info, NULL); + if (ret < 0) { + _E("Failed to add localized info[%d]", i); + __destroy_comp_localized_info(info); + return NULL; + } + } + } + + return info; +} + +static struct aul_comp_localized_info_s *__clone_comp_localized_info( + struct aul_comp_localized_info_s *info) +{ + struct aul_comp_localized_info_s *clone; + int ret; + int i; + + clone = calloc(1, sizeof(struct aul_comp_localized_info_s)); + if (!clone) { + _E("Out of memory"); + return NULL; + } + + for (i = AUL_COMP_LOCALIZED_INFO_START; + i < AUL_COMP_LOCALIZED_INFO_MAX; + i++) { + if (__localized_info_table[i].clnr) { + ret = __localized_info_table[i].clnr(info, clone, NULL); + if (ret < 0) { + _E("Failed to clone localized info[%d]", i); + __destroy_comp_localized_info(info); + return NULL; + } + } + } + + return clone; +} + static char *__get_system_locale(void) { char *lang; @@ -89,228 +354,573 @@ static char *__get_system_locale(void) return locale; } -static char *__get_db_path(uid_t uid) +static bool __get_boolean_value(const char *str) +{ + if (str && !strcmp(str, "true")) + return true; + + return false; +} + +static void __comp_info_remove_localized_info(void *data) { - char db_path[PATH_MAX]; - const char *path; + GList *list = (GList *)data; - path = tzplatform_getenv(TZ_SYS_DB); - if (!path) { - _E("Failed to get TZ_SYS_DB path"); - return NULL; + if (!list) + return; + + g_list_free_full(list, __destroy_comp_localized_info); +} + +static int __comp_info_add_app_id(bundle *b, struct aul_comp_info_s *info, + void *data) +{ + const char *app_id; + + app_id = bundle_get_val(b, AUL_K_APPID); + if (!app_id) { + _E("Failed to get application ID"); + return -1; } - 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); + info->value[AUL_COMP_INFO_APP_ID] = strdup(app_id); + if (!info->value[AUL_COMP_INFO_APP_ID]) { + _E("Failed to duplicate application ID"); + return -1; } - return strdup(db_path); + return 0; } -static void __save_column_str(sqlite3_stmt *stmt, int idx, char **str) +static int __comp_info_add_comp_id(bundle *b, struct aul_comp_info_s *info, + void *data) { - const char *val; + const char *comp_id; + + comp_id = bundle_get_val(b, AUL_K_COMPONENT_ID); + if (!comp_id) { + _E("Failed to get component ID"); + return -1; + } - val = (const char *)sqlite3_column_text(stmt, idx); - if (val) - *str = strdup(val); + info->value[AUL_COMP_INFO_COMP_ID] = strdup(comp_id); + if (!info->value[AUL_COMP_INFO_COMP_ID]) { + _E("Failed to duplicate component ID"); + return -1; + } + + return 0; } -static bool __get_boolean_value(const char *str) +static int __comp_info_add_type(bundle *b, struct aul_comp_info_s *info, + void *data) { - if (str && !strcmp(str, "true")) - return true; + const char *type; - return false; + type = bundle_get_val(b, AUL_K_COMPONENT_TYPE); + if (!type) { + _E("Failed to get component type"); + return -1; + } + + info->value[AUL_COMP_INFO_TYPE] = strdup(type); + if (!info->value[AUL_COMP_INFO_TYPE]) { + _E("Failed to duplicate component type"); + return -1; + } + + return 0; } -static int __db_busy_handler(void *data, int count) +static int __comp_info_add_launch_mode(bundle *b, struct aul_comp_info_s *info, + void *data) { - if (count < BUSY_WAITING_MAX) { - usleep(BUSY_WAITING_USEC); - return 1; + const char *launch_mode; + + launch_mode = bundle_get_val(b, AUL_K_LAUNCH_MODE); + if (!launch_mode) { + _E("Failed to get launch mode"); + return -1; } - LOGE("Database is busy"); + info->value[AUL_COMP_INFO_LAUNCH_MODE] = strdup(launch_mode); + if (!info->value[AUL_COMP_INFO_LAUNCH_MODE]) { + _E("Failed to duplicate launch mode"); + return -1; + } return 0; } -static sqlite3 *__open_db(const char *path) +static int __comp_info_add_main_comp(bundle *b, struct aul_comp_info_s *info, + void *data) { - sqlite3 *db = NULL; - int ret; + const char *main_comp; - 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; + main_comp = bundle_get_val(b, AUL_K_MAIN_COMP); + if (!main_comp) { + _E("Failed to get main comp"); + return -1; } - 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; + info->value[AUL_COMP_INFO_MAIN_COMP] = strdup(main_comp); + if (!info->value[AUL_COMP_INFO_MAIN_COMP]) { + _E("Failed to duplicate main comp"); + return -1; } - return db; + return 0; } -static void __destroy_comp_info(gpointer data) +static int __comp_info_add_icon_display(bundle *b, struct aul_comp_info_s *info, + void *data) { - struct aul_comp_info_s *info = (struct aul_comp_info_s *)data; - int idx; + const char *icon_display; - if (!info) - return; + icon_display = bundle_get_val(b, AUL_K_ICON_DISPLAY); + if (!icon_display) { + _E("Failed to get icon display"); + return -1; + } - for (idx = AUL_COMP_INFO_START; idx < AUL_COMP_INFO_MAX; idx++) { - if (info->value[idx]) - free(info->value[idx]); + info->value[AUL_COMP_INFO_ICON_DISPLAY] = strdup(icon_display); + if (!info->value[AUL_COMP_INFO_ICON_DISPLAY]) { + _E("Failed to duplicate icon display"); + return -1; } - free(info); + return 0; } -static struct aul_comp_info_s *__clone_comp_info(struct aul_comp_info_s *info) +static int __comp_info_add_taskmanage(bundle *b, struct aul_comp_info_s *info, + void *data) { - struct aul_comp_info_s *comp_info; - int idx; + const char *taskmanage; - comp_info = calloc(1, sizeof(struct aul_comp_info_s)); - if (!comp_info) { - _E("Out of memory"); - return NULL; + taskmanage = bundle_get_val(b, AUL_K_TASK_MANAGE); + if (!taskmanage) { + _E("Failed to get taskmanage"); + return -1; } - 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; + info->value[AUL_COMP_INFO_TASKMANAGE] = strdup(taskmanage); + if (!info->value[AUL_COMP_INFO_TASKMANAGE]) { + _E("Failed to duplicate taskmanage"); + return -1; + } + + return 0; +} + +static int __comp_info_add_localized_info(bundle *b, + struct aul_comp_info_s *info, void *data) +{ + struct aul_comp_localized_info_s *localized_info; + const char **localized_info_arr; + const char **localized_info_size_arr; + GList *list = NULL; + bundle *decoded_b; + int len = 0; + int size_len = 0; + int size; + int i; + + localized_info_arr = bundle_get_str_array(b, + AUL_K_LOCALIZED_INFO, &len); + if (!localized_info_arr || len <= 0) { + _W("Failed to get localized info"); + return 0; + } + + localized_info_size_arr = bundle_get_str_array(b, + AUL_K_LOCALIZED_INFO_SIZE, &size_len); + if (!localized_info_size_arr || size_len <= 0) { + _E("Failed to get localized info size"); + return -1; + } + + if (len != size_len) { + _E("Invalid size"); + return -1; + } + + for (i = 0; i < len; ++i) { + size = atoi(localized_info_size_arr[i]); + decoded_b = bundle_decode((bundle_raw *)localized_info_arr[i], + size); + if (!decoded_b) { + _E("Failed to decode bundle"); + return -1; + } + + localized_info = __create_comp_localized_info(decoded_b); + if (!localized_info) { + __comp_info_remove_localized_info(list); + return -1; } + + list = g_list_append(list, localized_info); + bundle_free(decoded_b); } - return comp_info; + info->value[AUL_COMP_INFO_LOCALIZED_INFO] = (char *)list; + + return 0; } -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; +static int __comp_info_clone_app_id(struct aul_comp_info_s *info, + struct aul_comp_info_s *clone, void *data) +{ + const char *app_id; - db_path = __get_db_path(uid); - if (!db_path) { - _E("Failed to get db path"); - return AUL_R_ENOMEM; + app_id = info->value[AUL_COMP_INFO_APP_ID]; + if (!app_id) { + _E("Invalid parameter"); + return -1; } - db = __open_db(db_path); - if (!db) { - _E("Failed to open db(%s)", db_path); - free(db_path); - return AUL_R_ERROR; + clone->value[AUL_COMP_INFO_APP_ID] = strdup(app_id); + if (!clone->value[AUL_COMP_INFO_APP_ID]) { + _E("Failed to duplicate application ID"); + return -1; } - free(db_path); - query = sqlite3_mprintf(query_raw, locale, locale, comp_id); - if (!query) { - _E("Out of memory"); - ret = AUL_R_ENOMEM; - goto end; + return 0; +} + +static int __comp_info_clone_comp_id(struct aul_comp_info_s *info, + struct aul_comp_info_s *clone, void *data) +{ + const char *comp_id; + + comp_id = info->value[AUL_COMP_INFO_COMP_ID]; + if (!comp_id) { + _E("Invalid parameter"); + return -1; + } + + clone->value[AUL_COMP_INFO_COMP_ID] = strdup(comp_id); + if (!clone->value[AUL_COMP_INFO_COMP_ID]) { + _E("Failed to duplicate component ID"); + return -1; + } + + return 0; +} + +static int __comp_info_clone_type(struct aul_comp_info_s *info, + struct aul_comp_info_s *clone, void *data) +{ + const char *type; + + type = info->value[AUL_COMP_INFO_TYPE]; + if (!type) { + _E("Invalid parameter"); + return -1; + } + + clone->value[AUL_COMP_INFO_TYPE] = strdup(type); + if (!clone->value[AUL_COMP_INFO_TYPE]) { + _E("Failed to duplicate component type"); + return -1; } - 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; + return 0; +} + +static int __comp_info_clone_launch_mode(struct aul_comp_info_s *info, + struct aul_comp_info_s *clone, void *data) +{ + const char *launch_mode; + + launch_mode = info->value[AUL_COMP_INFO_LAUNCH_MODE]; + if (!launch_mode) { + _E("Invalid parameter"); + return -1; } - ret = sqlite3_step(stmt); - if (ret != SQLITE_ROW) { - _E("sqlite3_step() is failed"); - ret = AUL_R_ENOENT; - goto end; + clone->value[AUL_COMP_INFO_LAUNCH_MODE] = strdup(launch_mode); + if (!clone->value[AUL_COMP_INFO_LAUNCH_MODE]) { + _E("Failed to duplicate launch mode"); + return -1; } + return 0; +} + +static int __comp_info_clone_main_comp(struct aul_comp_info_s *info, + struct aul_comp_info_s *clone, void *data) +{ + const char *main_comp; + + main_comp = info->value[AUL_COMP_INFO_MAIN_COMP]; + if (!main_comp) { + _E("Invalid parameter"); + return -1; + } + + clone->value[AUL_COMP_INFO_MAIN_COMP] = strdup(main_comp); + if (!clone->value[AUL_COMP_INFO_MAIN_COMP]) { + _E("Failed to duplicate main comp"); + return -1; + } + + return 0; +} + +static int __comp_info_clone_icon_display(struct aul_comp_info_s *info, + struct aul_comp_info_s *clone, void *data) +{ + const char *icon_display; + + icon_display = info->value[AUL_COMP_INFO_ICON_DISPLAY]; + if (!icon_display) { + _E("Invalid parameter"); + return -1; + } + + clone->value[AUL_COMP_INFO_ICON_DISPLAY] = strdup(icon_display); + if (!clone->value[AUL_COMP_INFO_ICON_DISPLAY]) { + _E("Failed to duplicate icon display"); + return -1; + } + + return 0; +} + +static int __comp_info_clone_taskmanage(struct aul_comp_info_s *info, + struct aul_comp_info_s *clone, void *data) +{ + const char *taskmanage; + + taskmanage = info->value[AUL_COMP_INFO_TASKMANAGE]; + if (!taskmanage) { + _E("Invalid parameter"); + return -1; + } + + clone->value[AUL_COMP_INFO_TASKMANAGE] = strdup(taskmanage); + if (!clone->value[AUL_COMP_INFO_TASKMANAGE]) { + _E("Failed to duplicate taskmanage"); + return -1; + } + + return 0; +} + +static int __comp_info_clone_localized_info(struct aul_comp_info_s *info, + struct aul_comp_info_s *clone, void *data) +{ + struct aul_comp_localized_info_s *localized_info; + struct aul_comp_localized_info_s *clone_info; + GList *localized_info_list; + GList *list = NULL; + GList *iter; + + localized_info_list = + (GList *)info->value[AUL_COMP_INFO_LOCALIZED_INFO]; + if (!localized_info_list) + return 0; + + iter = localized_info_list; + while (iter) { + localized_info = (struct aul_comp_localized_info_s *)iter->data; + if (!localized_info) { + _E("Critical error!"); + __comp_info_remove_localized_info(list); + return -1; + } + + clone_info = __clone_comp_localized_info(localized_info); + if (!clone_info) { + __comp_info_remove_localized_info(list); + return -1; + } + + list = g_list_append(list, clone_info); + iter = g_list_next(iter); + } + + clone->value[AUL_COMP_INFO_LOCALIZED_INFO] = (char *)list; + + return 0; +} + +static aul_comp_info_vft __comp_info_table[] = { + { + .ctor = __comp_info_add_app_id, + .dtor = free, + .clnr = __comp_info_clone_app_id + }, + { + .ctor = __comp_info_add_comp_id, + .dtor = free, + .clnr = __comp_info_clone_comp_id + }, + { + .ctor = __comp_info_add_type, + .dtor = free, + .clnr = __comp_info_clone_type + }, + { + .ctor = __comp_info_add_launch_mode, + .dtor = free, + .clnr = __comp_info_clone_launch_mode + }, + { + .ctor = __comp_info_add_main_comp, + .dtor = free, + .clnr = __comp_info_clone_main_comp + }, + { + .ctor = __comp_info_add_icon_display, + .dtor = free, + .clnr = __comp_info_clone_icon_display + }, + { + .ctor = __comp_info_add_taskmanage, + .dtor = free, + .clnr = __comp_info_clone_taskmanage + }, + { + .ctor = __comp_info_add_localized_info, + .dtor = __comp_info_remove_localized_info, + .clnr = __comp_info_clone_localized_info + } +}; + +static void __destroy_comp_info(gpointer data) +{ + struct aul_comp_info_s *info = (struct aul_comp_info_s *)data; + int i; + + if (!info) + return; + + for (i = AUL_COMP_INFO_START; i < AUL_COMP_INFO_MAX; ++i) { + if (__comp_info_table[i].dtor && info->value[i]) + __comp_info_table[i].dtor(info->value[i]); + } + + free(info); +} + +static struct aul_comp_info_s *__create_comp_info(bundle *b) +{ + struct aul_comp_info_s *info; + int ret; + int i; + info = calloc(1, sizeof(struct aul_comp_info_s)); if (!info) { _E("Out of memory"); - ret = AUL_R_ENOMEM; - goto end; + return NULL; + } + + for (i = AUL_COMP_INFO_START; i < AUL_COMP_INFO_MAX; ++i) { + if (__comp_info_table[i].ctor) { + ret = __comp_info_table[i].ctor(b, info, NULL); + if (ret < 0) { + _E("Failed to add component info[%d]", i); + __destroy_comp_info(info); + return NULL; + } + } } - for (idx = AUL_COMP_INFO_START; idx < AUL_COMP_INFO_MAX; idx++) - __save_column_str(stmt, idx, &info->value[idx]); + return info; +} + +static struct aul_comp_info_s *__clone_comp_info(struct aul_comp_info_s *info) +{ + struct aul_comp_info_s *comp_info; + int ret; + int i; + + comp_info = calloc(1, sizeof(struct aul_comp_info_s)); + if (!comp_info) { + _E("Out of memory"); + return NULL; + } - *comp_info = info; - ret = AUL_R_OK; + for (i = AUL_COMP_INFO_START; i < AUL_COMP_INFO_MAX; ++i) { + if (__comp_info_table[i].clnr) { + ret = __comp_info_table[i].clnr(info, comp_info, NULL); + if (ret < 0) { + _E("Failed to clone component info[%d]", i); + __destroy_comp_info(comp_info); + return NULL; + } + } + } -end: - if (stmt) - sqlite3_finalize(stmt); - if (query) - sqlite3_free(query); - if (db) - sqlite3_close_v2(db); - return ret; + return comp_info; } 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); + return aul_comp_info_usr_create(comp_id, getuid(), handle); } -API int aul_comp_info_create_usr(const char *comp_id, uid_t uid, +API int aul_comp_info_usr_create(const char *comp_id, uid_t uid, aul_comp_info_h *handle) { struct aul_comp_info_s *info; - char *locale; + app_pkt_t *pkt = NULL; + char buf[32]; + bundle *b; int ret; + int fd; if (!comp_id || !handle) { _E("Invalid parameter"); return AUL_R_EINVAL; } - locale = __get_system_locale(); - if (!locale) + b = bundle_create(); + if (!b) { + _E("Out of memory"); return AUL_R_ENOMEM; + } - 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); + snprintf(buf, sizeof(buf), "%d", uid); + bundle_add(b, AUL_K_TARGET_UID, buf); + bundle_add(b, AUL_K_COMPONENT_ID, comp_id); - free(locale); - if (ret != AUL_R_OK) - return ret; + fd = aul_sock_send_bundle(AUL_UTIL_PID, uid, COMP_INFO_GET, + b, AUL_SOCK_ASYNC); + bundle_free(b); + if (fd < 0) { + _E("Failed to send request. error(%d)", fd); + return aul_error_convert(fd); + } + + ret = aul_sock_recv_reply_pkt(fd, &pkt); + if (ret < 0) { + _E("Failed to receive packet. error(%d)", ret); + return aul_error_convert(ret); + } + + b = NULL; + if (pkt->opt & AUL_SOCK_BUNDLE) { + b = bundle_decode(pkt->data, pkt->len); + if (!b) { + _E("Failed to decode bundle"); + return AUL_R_ENOMEM; + } + } + free(pkt); + + if (!b) { + _E("Invalid packet"); + return AUL_R_ERROR; + } + + info = __create_comp_info(b); + if (!info) { + bundle_free(b); + return AUL_R_ENOMEM; + } + bundle_free(b); *handle = (aul_comp_info_h)info; @@ -454,16 +1064,71 @@ API int aul_comp_info_is_taskmanage(aul_comp_info_h handle, bool *taskmanage) return AUL_R_OK; } +static gint __compare_locale(gconstpointer a, gconstpointer b) +{ + struct aul_comp_localized_info_s *info; + const char *locale; + + info = (struct aul_comp_localized_info_s *)a; + locale = (const char *)b; + + if (!info || !info->value[AUL_COMP_LOCALIZED_INFO_LOCALE] || !locale) + return -1; + + return strcmp(info->value[AUL_COMP_LOCALIZED_INFO_LOCALE], locale); +} + +static struct aul_comp_localized_info_s *__find_comp_localized_info( + struct aul_comp_info_s *info, const char *locale) +{ + GList *found; + GList *list; + + list = (GList *)info->value[AUL_COMP_INFO_LOCALIZED_INFO]; + if (!list) { + _E("Localized info is empty"); + return NULL; + } + + found = g_list_find_custom(list, locale, __compare_locale); + if (!found) { + found = g_list_find_custom(list, DEFAULT_LOCALE, + __compare_locale); + } + + if (!found) { + _E("Failed to find localized info"); + return NULL; + } + + return (struct aul_comp_localized_info_s *)found->data; +} + 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; + struct aul_comp_localized_info_s *localized_info; + char *locale; if (!handle || !icon) { _E("Invalid parameter"); return AUL_R_EINVAL; } - *icon = info->value[AUL_COMP_INFO_ICON]; + locale = __get_system_locale(); + if (!locale) { + _E("Failed to get system locale"); + return AUL_R_ENOMEM; + } + + localized_info = __find_comp_localized_info(info, locale); + if (!localized_info) { + free(locale); + return AUL_R_ENOENT; + } + free(locale); + + *icon = localized_info->value[AUL_COMP_LOCALIZED_INFO_ICON]; return AUL_R_OK; } @@ -471,221 +1136,132 @@ API int aul_comp_info_get_icon(aul_comp_info_h handle, const char **icon) 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; + struct aul_comp_localized_info_s *localized_info; + char *locale; 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"); + locale = __get_system_locale(); + if (!locale) { + _E("Failed to get system locale"); return AUL_R_ENOMEM; } - 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_ENOMEM; - 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_ENOMEM; - else - ret = AUL_R_OK; - } else { - ret = AUL_R_ERROR; - } - } else { - ret = AUL_R_ENOENT; + localized_info = __find_comp_localized_info(info, locale); + if (!localized_info) { + free(locale); + return AUL_R_ENOENT; } -end: - if (stmt) - sqlite3_finalize(stmt); - if (query) - sqlite3_free(query); - if (db) - sqlite3_close(db); + free(locale); - return ret; -} + *label = localized_info->value[AUL_COMP_LOCALIZED_INFO_LABEL]; -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); + return AUL_R_OK; } -API int aul_comp_info_get_usr_localed_label(const char *comp_id, - const char *locale, uid_t uid, char **label) +API int aul_comp_info_get_localed_label(aul_comp_info_h handle, + const char *locale, const char **label) { - char *value; - int ret; + struct aul_comp_info_s *info = (struct aul_comp_info_s *)handle; + struct aul_comp_localized_info_s *localized_info; - if (!comp_id || !locale || !label) { + if (!handle || !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; + localized_info = __find_comp_localized_info(info, locale); + if (!localized_info) + return AUL_R_ENOENT; - *label = value; + *label = localized_info->value[AUL_COMP_LOCALIZED_INFO_LABEL]; return AUL_R_OK; } -static int __get_comp_info_list(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"; - sqlite3_stmt *stmt = NULL; - sqlite3 *db = NULL; - char *query = NULL; - char *db_path; - int idx; +static void __comp_info_foreach_cb(app_pkt_t *pkt, void *user_data) +{ + GList **list = (GList **)user_data; struct aul_comp_info_s *info; - int ret; + bundle *b = NULL; - db_path = __get_db_path(uid); - if (!db_path) { - _E("Failed to get db path"); - return AUL_R_ERROR; + if (!pkt) { + _E("Invalid parameter"); + return; } - db = __open_db(db_path); - if (!db) { - _E("Failed to open db(%s)", db_path); - free(db_path); - return AUL_R_ERROR; + if (pkt->cmd == APP_GET_INFO_ERROR) { + _E("Failed to get component info"); + return; } - free(db_path); - query = sqlite3_mprintf(query_raw, locale, locale); - if (!query) { - _E("Out of memory"); - ret = AUL_R_ERROR; - goto end; - } + if (pkt->opt & AUL_SOCK_BUNDLE) + b = bundle_decode(pkt->data, pkt->len); - 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; + if (!b) + return; + + info = __create_comp_info(b); + if (!info) { + bundle_free(b); + return; } + bundle_free(b); - 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; - } + *list = g_list_append(*list, info); +} - for (idx = AUL_COMP_INFO_START; idx < AUL_COMP_INFO_MAX; idx++) - __save_column_str(stmt, idx, &info->value[idx]); +static int __get_comp_info_list(uid_t uid, GList **info_list) +{ + GList *list = NULL; + char buf[32]; + bundle *b; + int ret; + int fd; - *list = g_list_append(*list, info); + b = bundle_create(); + if (!b) { + _E("Out of memory"); + return AUL_R_ENOMEM; } - if (*list == NULL) - ret = AUL_R_ENOENT; - else - ret = AUL_R_OK; + snprintf(buf, sizeof(buf), "%d", uid); + bundle_add(b, AUL_K_TARGET_UID, buf); + + fd = aul_sock_send_bundle(AUL_UTIL_PID, uid, COMP_INFO_FOREACH, + b, AUL_SOCK_ASYNC); + bundle_free(b); + if (fd < 0) + return aul_error_convert(fd); -end: - if (stmt) - sqlite3_finalize(stmt); - if (query) - sqlite3_free(query); - if (db) - sqlite3_close_v2(db); + ret = aul_sock_recv_pkt_with_cb(fd, __comp_info_foreach_cb, + &list); + if (ret < 0) { + g_list_free_full(list, __destroy_comp_info); + return aul_error_convert(ret); + } + + *info_list = list; - return ret; + return AUL_R_OK; } -API int aul_comp_info_foreach_from_app(const char *app_id, +API int aul_comp_info_foreach_comp_info_from_app(const char *app_id, aul_comp_info_cb callback, void *user_data) { - return aul_comp_info_foreach_usr_from_app(app_id, getuid(), + return aul_comp_info_usr_foreach_comp_info_from_app(app_id, getuid(), callback, user_data); } -API int aul_comp_info_foreach_usr_from_app(const char *app_id, uid_t uid, - aul_comp_info_cb callback, void *user_data) +API int aul_comp_info_usr_foreach_comp_info_from_app(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) { @@ -693,31 +1269,18 @@ API int aul_comp_info_foreach_usr_from_app(const char *app_id, uid_t uid, return AUL_R_EINVAL; } - locale = __get_system_locale(); - if (!locale) { - _E("Failed to get system locale"); - return AUL_R_ENOMEM; - } - - ret = __get_comp_info_list(locale, uid, &list); - if (ret != AUL_R_OK && uid != GLOBAL_USER) - ret = __get_comp_info_list(locale, GLOBAL_USER, &list); - - free(locale); - if (ret != AUL_R_OK) { - _E("Failed to get comp infos"); + ret = __get_comp_info_list(uid, &list); + if (ret < 0) return ret; - } iter = list; while (iter) { info = (struct aul_comp_info_s *)iter->data; iter = g_list_next(iter); - if (strcmp(info->value[AUL_COMP_INFO_APP_ID], app_id) != 0) continue; - if (!callback((aul_comp_info_h)info, user_data)) + if (!callback(info, user_data)) break; } @@ -726,18 +1289,19 @@ API int aul_comp_info_foreach_usr_from_app(const char *app_id, uid_t uid, return AUL_R_OK; } -API int aul_comp_info_foreach(aul_comp_info_cb callback, void *user_data) +API int aul_comp_info_foreach_comp_info(aul_comp_info_cb callback, + void *user_data) { - return aul_comp_info_foreach_usr(getuid(), callback, user_data); + return aul_comp_info_usr_foreach_comp_info(getuid(), callback, + user_data); } -API int aul_comp_info_foreach_usr(uid_t uid, aul_comp_info_cb callback, - void *user_data) +API int aul_comp_info_usr_foreach_comp_info(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 (!callback) { @@ -745,27 +1309,16 @@ API int aul_comp_info_foreach_usr(uid_t uid, aul_comp_info_cb callback, return AUL_R_EINVAL; } - locale = __get_system_locale(); - if (!locale) { - _E("Failed to get system locale"); - return AUL_R_ENOMEM; - } - - ret = __get_comp_info_list(locale, uid, &list); - if (ret != AUL_R_OK && uid != GLOBAL_USER) - ret = __get_comp_info_list(locale, GLOBAL_USER, &list); - - free(locale); - if (ret != AUL_R_OK) { - _E("Failed to get comp infos"); + ret = __get_comp_info_list(uid, &list); + if (ret < 0) return ret; - } iter = list; while (iter) { info = (struct aul_comp_info_s *)iter->data; - if (!callback((aul_comp_info_h)info, user_data)) + if (!callback(info, user_data)) break; + iter = g_list_next(iter); } diff --git a/src/aul_comp_info_internal.c b/src/aul_comp_info_internal.c new file mode 100644 index 0000000..d0b4da8 --- /dev/null +++ b/src/aul_comp_info_internal.c @@ -0,0 +1,799 @@ +/* + * 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_internal.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_COMPINFO_LOCALIZED_INFO_START 0 +#define AUL_COMPINFO_START 0 + +enum aul_compinfo_e { + AUL_COMPINFO_APP_ID = AUL_COMPINFO_START, + AUL_COMPINFO_COMP_ID, + AUL_COMPINFO_TYPE, + AUL_COMPINFO_LAUNCH_MODE, + AUL_COMPINFO_MAIN_COMP, + AUL_COMPINFO_ICON_DISPLAY, + AUL_COMPINFO_TASKMANAGE, + AUL_COMPINFO_MAX, +}; + +struct aul_compinfo_s { + char *value[AUL_COMPINFO_MAX]; +}; + +enum aul_compinfo_localized_info_e { + AUL_COMPINFO_LOCALIZED_INFO_LOCALE = AUL_COMPINFO_LOCALIZED_INFO_START, + AUL_COMPINFO_LOCALIZED_INFO_ICON, + AUL_COMPINFO_LOCALIZED_INFO_LABEL, + AUL_COMPINFO_LOCALIZED_INFO_MAX, +}; + +struct aul_compinfo_localized_info_s { + char *value[AUL_COMPINFO_LOCALIZED_INFO_MAX]; +}; + +static void __destroy_compinfo_localized_info(gpointer data) +{ + struct aul_compinfo_localized_info_s *info; + int idx; + + info = (struct aul_compinfo_localized_info_s *)data; + if (!info) + return; + + for (idx = AUL_COMPINFO_LOCALIZED_INFO_START; + idx < AUL_COMPINFO_LOCALIZED_INFO_MAX; idx++) + free(info->value[idx]); + + free(info); +} + +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 int __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); + if (*str == NULL) { + _E("Out of memory"); + return AUL_R_ENOMEM; + } + } + + return AUL_R_OK; +} + +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_compinfo(gpointer data) +{ + struct aul_compinfo_s *info = (struct aul_compinfo_s *)data; + int idx; + + if (!info) + return; + + for (idx = AUL_COMPINFO_START; idx < AUL_COMPINFO_MAX; idx++) + free(info->value[idx]); + + free(info); +} + +static struct aul_compinfo_s *__clone_compinfo(struct aul_compinfo_s *info) +{ + struct aul_compinfo_s *compinfo; + int idx; + + compinfo = calloc(1, sizeof(struct aul_compinfo_s)); + if (!compinfo) { + _E("Out of memory"); + return NULL; + } + + for (idx = AUL_COMPINFO_START; idx < AUL_COMPINFO_MAX; idx++) { + compinfo->value[idx] = strdup(info->value[idx]); + if (!compinfo->value[idx]) { + _E("Out of memory"); + __destroy_compinfo(info); + return NULL; + } + } + + return compinfo; +} + +static int __create_compinfo(const char *comp_id, uid_t uid, + struct aul_compinfo_s **compinfo) +{ + static const char query_raw[] = "SELECT " + "app_id, component_type, component_launch_mode, " + "component_main, component_icon_display, component_taskmanage " + "FROM component_info WHERE component_id=%Q"; + sqlite3_stmt *stmt = NULL; + sqlite3 *db; + char *query; + char *db_path; + int idx; + struct aul_compinfo_s *info; + int ret; + + db_path = __get_db_path(uid); + if (!db_path) { + _E("Failed to get db path"); + return AUL_R_ENOMEM; + } + + 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); + if (!query) { + _E("Out of memory"); + ret = AUL_R_ENOMEM; + 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)); + if (ret == SQLITE_NOMEM) + ret = AUL_R_ENOMEM; + else + 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_compinfo_s)); + if (!info) { + _E("Out of memory"); + ret = AUL_R_ENOMEM; + goto end; + } + + info->value[AUL_COMPINFO_COMP_ID] = strdup(comp_id); + if (!info->value[AUL_COMPINFO_COMP_ID]) { + _E("Failed to duplicate component ID"); + __destroy_compinfo(info); + ret = AUL_R_ENOMEM; + goto end; + } + + for (idx = AUL_COMPINFO_START; idx < AUL_COMPINFO_MAX; idx++) { + if (idx == AUL_COMPINFO_COMP_ID) + continue; + + ret = __save_column_str(stmt, idx, &info->value[idx]); + if (ret != AUL_R_OK) { + __destroy_compinfo(info); + goto end; + } + } + + *compinfo = info; + ret = AUL_R_OK; + +end: + sqlite3_finalize(stmt); + sqlite3_free(query); + sqlite3_close_v2(db); + + return ret; +} + +API int aul_compinfo_create(const char *comp_id, aul_compinfo_h *handle) +{ + return aul_compinfo_usr_create(comp_id, getuid(), handle); +} + +API int aul_compinfo_usr_create(const char *comp_id, uid_t uid, + aul_compinfo_h *handle) { + struct aul_compinfo_s *info; + int ret; + + if (!comp_id || !handle) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + ret = __create_compinfo(comp_id, uid, &info); + if (ret != AUL_R_OK && uid != GLOBAL_USER) + ret = __create_compinfo(comp_id, GLOBAL_USER, &info); + + if (ret != AUL_R_OK) + return ret; + + *handle = (aul_compinfo_h)info; + + return AUL_R_OK; +} + +API int aul_compinfo_destroy(aul_compinfo_h handle) +{ + struct aul_compinfo_s *info = (struct aul_compinfo_s *)handle; + + if (!handle) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + __destroy_compinfo(info); + + return AUL_R_OK; +} + +API int aul_compinfo_clone(aul_compinfo_h handle, aul_compinfo_h *clone) +{ + struct aul_compinfo_s *info = (struct aul_compinfo_s *)handle; + struct aul_compinfo_s *new_info; + + if (!handle || !clone) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + new_info = __clone_compinfo(info); + if (!new_info) { + _E("Failed to clone comp info"); + return AUL_R_ENOMEM; + } + + *clone = (aul_compinfo_h)new_info; + + return AUL_R_OK; +} + +API int aul_compinfo_get_app_id(aul_compinfo_h handle, const char **app_id) +{ + struct aul_compinfo_s *info = (struct aul_compinfo_s *)handle; + + if (!handle || !app_id) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *app_id = info->value[AUL_COMPINFO_APP_ID]; + + return AUL_R_OK; +} + +API int aul_compinfo_get_comp_id(aul_compinfo_h handle, const char **comp_id) +{ + struct aul_compinfo_s *info = (struct aul_compinfo_s *)handle; + + if (!handle || !comp_id) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *comp_id = info->value[AUL_COMPINFO_COMP_ID]; + + return AUL_R_OK; +} + +API int aul_compinfo_get_type(aul_compinfo_h handle, const char **type) +{ + struct aul_compinfo_s *info = (struct aul_compinfo_s *)handle; + + if (!handle || !type) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *type = info->value[AUL_COMPINFO_TYPE]; + + return AUL_R_OK; +} + +API int aul_compinfo_get_launch_mode(aul_compinfo_h handle, + const char **launch_mode) +{ + struct aul_compinfo_s *info = (struct aul_compinfo_s *)handle; + + if (!handle || !launch_mode) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *launch_mode = info->value[AUL_COMPINFO_LAUNCH_MODE]; + + return AUL_R_OK; +} + +API int aul_compinfo_is_main_comp(aul_compinfo_h handle, bool *main_comp) +{ + struct aul_compinfo_s *info = (struct aul_compinfo_s *)handle; + + if (!handle || !main_comp) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *main_comp = __get_boolean_value(info->value[AUL_COMPINFO_MAIN_COMP]); + + return AUL_R_OK; +} + +API int aul_compinfo_is_icon_display(aul_compinfo_h handle, + bool *icon_display) +{ + struct aul_compinfo_s *info = (struct aul_compinfo_s *)handle; + + if (!handle || !icon_display) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *icon_display = + __get_boolean_value(info->value[AUL_COMPINFO_ICON_DISPLAY]); + + return AUL_R_OK; +} + +API int aul_compinfo_is_taskmanage(aul_compinfo_h handle, bool *taskmanage) +{ + struct aul_compinfo_s *info = (struct aul_compinfo_s *)handle; + + if (!handle || !taskmanage) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + *taskmanage = + __get_boolean_value(info->value[AUL_COMPINFO_TASKMANAGE]); + + return AUL_R_OK; +} + +static int __get_compinfo_list(uid_t uid, GList **list) +{ + static const char query[] = "SELECT " + "app_id, component_id, component_type, " + "component_launch_mode, component_main, " + "component_icon_display, component_taskmanage " + "FROM component_info"; + sqlite3_stmt *stmt = NULL; + sqlite3 *db; + char *db_path; + int idx; + struct aul_compinfo_s *info; + int ret; + + db_path = __get_db_path(uid); + if (!db_path) { + _E("Failed to get db path"); + return AUL_R_ENOMEM; + } + + 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); + + 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)); + if (ret == SQLITE_NOMEM) + ret = AUL_R_ENOMEM; + else + ret = AUL_R_ERROR; + goto end; + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + info = calloc(1, sizeof(struct aul_compinfo_s)); + if (!info) { + _E("Out of memory"); + if (*list) { + g_list_free_full(*list, __destroy_compinfo); + *list = NULL; + } + ret = AUL_R_ENOMEM; + goto end; + } + + for (idx = AUL_COMPINFO_START; idx < AUL_COMPINFO_MAX; idx++) { + ret = __save_column_str(stmt, idx, &info->value[idx]); + if (ret != AUL_R_OK) { + g_list_free_full(*list, __destroy_compinfo); + *list = NULL; + goto end; + } + } + + *list = g_list_append(*list, info); + } + + if (*list == NULL) + ret = AUL_R_ENOENT; + else + ret = AUL_R_OK; + +end: + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + + return ret; +} + +API int aul_compinfo_foreach_compinfo_from_app(const char *app_id, + aul_compinfo_cb callback, void *user_data) +{ + return aul_compinfo_usr_foreach_compinfo_from_app(app_id, getuid(), + callback, user_data); +} + +API int aul_compinfo_usr_foreach_compinfo_from_app(const char *app_id, + uid_t uid, aul_compinfo_cb callback, void *user_data) +{ + struct aul_compinfo_s *info; + GList *list = NULL; + GList *iter; + int ret; + + if (!app_id || !callback) { + LOGE("Invalid parameter"); + return AUL_R_EINVAL; + } + + ret = __get_compinfo_list(uid, &list); + if (ret != AUL_R_OK && uid != GLOBAL_USER) + ret = __get_compinfo_list(GLOBAL_USER, &list); + + if (ret != AUL_R_OK) { + _E("Failed to get comp infos"); + return ret; + } + + iter = list; + while (iter) { + info = (struct aul_compinfo_s *)iter->data; + iter = g_list_next(iter); + + if (strcmp(info->value[AUL_COMPINFO_APP_ID], app_id) != 0) + continue; + + if (!callback((aul_compinfo_h)info, user_data)) + break; + } + + g_list_free_full(list, __destroy_compinfo); + + return AUL_R_OK; +} + +API int aul_compinfo_foreach_compinfo(aul_compinfo_cb callback, + void *user_data) +{ + return aul_compinfo_usr_foreach_compinfo(getuid(), callback, user_data); +} + +API int aul_compinfo_usr_foreach_compinfo(uid_t uid, aul_compinfo_cb callback, + void *user_data) +{ + struct aul_compinfo_s *info; + GList *list = NULL; + GList *iter; + int ret; + + if (!callback) { + LOGE("Invalid parameter"); + return AUL_R_EINVAL; + } + + ret = __get_compinfo_list(uid, &list); + if (ret != AUL_R_OK && uid != GLOBAL_USER) + ret = __get_compinfo_list(GLOBAL_USER, &list); + + if (ret != AUL_R_OK) { + _E("Failed to get comp infos"); + return ret; + } + + iter = list; + while (iter) { + info = (struct aul_compinfo_s *)iter->data; + if (!callback((aul_compinfo_h)info, user_data)) + break; + + iter = g_list_next(iter); + } + + g_list_free_full(list, __destroy_compinfo); + + return AUL_R_OK; +} + +API int aul_compinfo_localized_info_get_locale( + aul_compinfo_localized_info_h handle, const char **locale) +{ + struct aul_compinfo_localized_info_s *info; + + if (!handle || !locale) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + info = (struct aul_compinfo_localized_info_s *)handle; + *locale = info->value[AUL_COMPINFO_LOCALIZED_INFO_LOCALE]; + + return AUL_R_OK; +} + +API int aul_compinfo_localized_info_get_icon( + aul_compinfo_localized_info_h handle, const char **icon) +{ + struct aul_compinfo_localized_info_s *info; + + if (!handle || !icon) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + info = (struct aul_compinfo_localized_info_s *)handle; + *icon = info->value[AUL_COMPINFO_LOCALIZED_INFO_ICON]; + + return AUL_R_OK; +} + +API int aul_compinfo_localized_info_get_label( + aul_compinfo_localized_info_h handle, const char **label) +{ + struct aul_compinfo_localized_info_s *info; + + if (!handle || !label) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + info = (struct aul_compinfo_localized_info_s *)handle; + *label = info->value[AUL_COMPINFO_LOCALIZED_INFO_LABEL]; + + return AUL_R_OK; +} + +static int __get_localized_info_list(const char *comp_id, uid_t uid, + GList **list) +{ + static const char query_raw[] = "SELECT " + "component_locale, component_icon, component_label " + "FROM component_localized_info WHERE component_id=%Q"; + sqlite3_stmt *stmt = NULL; + sqlite3 *db; + char *query; + char *db_path; + int idx; + struct aul_compinfo_localized_info_s *info; + int ret; + + db_path = __get_db_path(uid); + if (!db_path) { + _E("Failed to get db path"); + return AUL_R_ENOMEM; + } + + 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); + if (!query) { + _E("Out of memory"); + ret = AUL_R_ENOMEM; + 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)); + if (ret == SQLITE_NOMEM) + ret = AUL_R_ENOMEM; + else + ret = AUL_R_ERROR; + goto end; + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + info = calloc(1, sizeof(struct aul_compinfo_localized_info_s)); + if (!info) { + _E("Out of memory"); + if (*list) { + g_list_free_full(*list, + __destroy_compinfo_localized_info); + *list = NULL; + } + ret = AUL_R_ENOMEM; + goto end; + } + + for (idx = AUL_COMPINFO_LOCALIZED_INFO_START; + idx < AUL_COMPINFO_LOCALIZED_INFO_MAX; + idx++) { + ret = __save_column_str(stmt, idx, &info->value[idx]); + if (ret != AUL_R_OK) { + g_list_free_full(*list, + __destroy_compinfo_localized_info); + *list = NULL; + goto end; + } + } + + *list = g_list_append(*list, info); + } + + if (*list == NULL) + ret = AUL_R_ENOENT; + else + ret = AUL_R_OK; + +end: + sqlite3_finalize(stmt); + sqlite3_free(query); + sqlite3_close_v2(db); + + return ret; +} + +API int aul_compinfo_foreach_localized_info(const char *comp_id, + aul_compinfo_localized_info_cb callback, void *user_data) +{ + return aul_compinfo_usr_foreach_localized_info(comp_id, getuid(), + callback, user_data); +} + +API int aul_compinfo_usr_foreach_localized_info(const char *comp_id, + uid_t uid, aul_compinfo_localized_info_cb callback, + void *user_data) +{ + struct aul_compinfo_localized_info_s *info; + GList *list = NULL; + GList *iter; + int ret; + + if (!comp_id || !callback) { + _E("Invalid parameter"); + return AUL_R_EINVAL; + } + + ret = __get_localized_info_list(comp_id, uid, &list); + if (ret != AUL_R_OK && uid != GLOBAL_USER) + ret = __get_localized_info_list(comp_id, GLOBAL_USER, &list); + + if (ret != AUL_R_OK) { + _E("Failed to get comp infos"); + return ret; + } + + iter = list; + while (iter) { + info = (struct aul_compinfo_localized_info_s *)iter->data; + if (!callback((aul_compinfo_localized_info_h)info, user_data)) + break; + + iter = g_list_next(iter); + } + + g_list_free_full(list, __destroy_compinfo_localized_info); + + return AUL_R_OK; +} diff --git a/tool/compmgr_tool.c b/tool/compmgr_tool.c index 1d7ed4e..03b2a74 100644 --- a/tool/compmgr_tool.c +++ b/tool/compmgr_tool.c @@ -187,7 +187,7 @@ static int __cmd_common_init(void *data) aul_comp_info_h handle = NULL; int ret; - ret = aul_comp_info_create_usr(cmd_arg->comp_id, cmd_arg->uid, + ret = aul_comp_info_usr_create(cmd_arg->comp_id, cmd_arg->uid, &handle); if (ret != AUL_R_OK) { printf("Failed to create component(%s) info\n", @@ -264,8 +264,8 @@ static int __installed_list_cb(const pkgmgrinfo_appinfo_h handle, void *data) printf("----------------------------------\n"); printf("< Application : %s >\n", appid); - ret = aul_comp_info_foreach_usr_from_app(appid, uid, __comp_info_cb, - (void *)&member_count); + ret = aul_comp_info_usr_foreach_comp_info_from_app(appid, uid, + __comp_info_cb, (void *)&member_count); if (ret < 0) { fprintf(stderr, "Failed to retrieve component info. %s:%u\n", appid, uid); @@ -355,7 +355,7 @@ static int __cmd_running_list_run(void *data) int member_count = 0; int ret; - ret = aul_comp_context_foreach(__comp_context_cb, + ret = aul_comp_context_foreach_comp_context(__comp_context_cb, (void *)&member_count); if (ret == AUL_R_OK) { printf("==================================\n"); @@ -373,7 +373,7 @@ static int __cmd_get_run(void *data) int member_count = 0; int ret; - ret = aul_comp_context_create_usr(cmd_arg->comp_id, cmd_arg->uid, + ret = aul_comp_context_usr_create(cmd_arg->comp_id, cmd_arg->uid, &handle); if (ret != AUL_R_OK) { printf("Failed to find running component(%s) context\n", @@ -395,7 +395,7 @@ static int __cmd_is_running_run(void *data) bool is_running = false; int ret; - ret = aul_comp_context_create_usr(cmd_arg->comp_id, cmd_arg->uid, + ret = aul_comp_context_usr_create(cmd_arg->comp_id, cmd_arg->uid, &handle); if (ret != AUL_R_OK) { printf("Failed to find running component(%s) context\n", @@ -424,7 +424,7 @@ static int __cmd_resume_run(void *data) aul_comp_context_h handle = NULL; int ret; - ret = aul_comp_context_create_usr(cmd_arg->comp_id, cmd_arg->uid, + ret = aul_comp_context_usr_create(cmd_arg->comp_id, cmd_arg->uid, &handle); if (ret != AUL_R_OK) { printf("Failed to find running component(%s) context\n", @@ -451,7 +451,7 @@ static int __cmd_pause_run(void *data) aul_comp_context_h handle = NULL; int ret; - ret = aul_comp_context_create_usr(cmd_arg->comp_id, cmd_arg->uid, + ret = aul_comp_context_usr_create(cmd_arg->comp_id, cmd_arg->uid, &handle); if (ret != AUL_R_OK) { printf("Failed to find running component(%s) context\n", @@ -478,7 +478,7 @@ static int __cmd_terminate_bg_comp_run(void *data) aul_comp_context_h handle = NULL; int ret; - ret = aul_comp_context_create_usr(cmd_arg->comp_id, cmd_arg->uid, + ret = aul_comp_context_usr_create(cmd_arg->comp_id, cmd_arg->uid, &handle); if (ret != AUL_R_OK) { printf("Failed to find running component(%s) context\n", @@ -505,7 +505,7 @@ static int __cmd_terminate_run(void *data) aul_comp_context_h handle = NULL; int ret; - ret = aul_comp_context_create_usr(cmd_arg->comp_id, cmd_arg->uid, + ret = aul_comp_context_usr_create(cmd_arg->comp_id, cmd_arg->uid, &handle); if (ret != AUL_R_OK) { printf("Failed to find running component(%s) context\n", -- 2.7.4