From: sooyeon Date: Mon, 27 Jun 2022 08:12:33 +0000 (+0900) Subject: Replace IPC of vc_setting X-Git-Tag: submit/tizen/20220801.042437~15 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d1f51c35b4ec554a34fc4fa2101b26bd6254825d;p=platform%2Fcore%2Fuifw%2Fvoice-control.git Replace IPC of vc_setting Change-Id: I58f30103efd851762c01e6f2730087364c1b8cf8 Signed-off-by: sooyeon --- diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 63ced4a..b5ddb82 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -15,7 +15,9 @@ SET(SRCS ) SET(SETTING_SRCS - vc_setting_dbus.c +# vc_setting_dbus.c + vc_setting_tidl.c + vc_setting_proxy.c vc_setting.c ../common/vc_config_mgr.c ../common/vc_config_parser.c diff --git a/client/vc_setting.c b/client/vc_setting.c index 238480f..c415a77 100644 --- a/client/vc_setting.c +++ b/client/vc_setting.c @@ -17,7 +17,8 @@ #include "vc_config_mgr.h" #include "vc_main.h" -#include "vc_setting_dbus.h" +// #include "vc_setting_dbus.h" +#include "vc_setting_tidl.h" #include "voice_control_common.h" #include "voice_control_setting.h" @@ -319,19 +320,20 @@ int vc_setting_set_language(const char* language) if (0 != ret) { SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Result : %d", ret); } else { - if (0 != vc_setting_dbus_open_connection()) { + // TODO: Need to reorder. + if (0 != vc_setting_tidl_open_connection()) { SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Fail to open connection"); return VC_ERROR_OPERATION_FAILED; } - if (0 != vc_setting_dbus_request_hello()) { + if (0 != vc_setting_tidl_request_hello()) { SLOG(LOG_DEBUG, TAG_VCS, "[DEBUG] Daemon is not available"); } else { - ret = vc_setting_dbus_request_set_language(getpid(), language); + ret = vc_setting_tidl_request_set_language(getpid(), language); SLOG(LOG_DEBUG, TAG_VCS, "[DEBUG] Set default language (%d)", ret); } - if (0 != vc_setting_dbus_close_connection()) { + if (0 != vc_setting_tidl_close_connection()) { SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Fail to close connection"); return VC_ERROR_OPERATION_FAILED; } diff --git a/client/vc_setting_tidl.c b/client/vc_setting_tidl.c new file mode 100755 index 0000000..240ef70 --- /dev/null +++ b/client/vc_setting_tidl.c @@ -0,0 +1,323 @@ +/* +* Copyright (c) 2011-2015 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. +*/ + +#include "vc_command.h" +#include "vc_setting_tidl.h" +#include "vc_setting_proxy.h" +#include "vc_main.h" + +#include + +typedef struct { + int pid; + bool connected; + bool connection_requesting; + bool register_notify_callback_invoked; + + rpc_port_proxy_vc_setting_proxy_vc_setting_h rpc_h; + rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_h notify_cb_h; + + char* engine_appid; +} vc_setting_tidl_info_s; + +static GList* g_tidl_infos = NULL; + +extern int __vc_cb_service_state(int state); + + +static vc_setting_tidl_info_s* __get_tidl_info_s(int pid) +{ + // TODO: Hmm.... is this necessary...?? + GList* iter = NULL; + vc_setting_tidl_info_s* info = NULL; + + if (g_list_length(g_tidl_infos) > 0) { + /* Get a first item */ + iter = g_list_first(g_tidl_infos); + + while (NULL != iter) { + info = iter->data; + + if (info->pid == pid) { + return info; + } + + /* Next item */ + iter = g_list_next(iter); + } + } + + return NULL; +} + +static char* __get_engine_appid(void) +{ + char* engine_name = vconf_get_str(VC_ENGINE_DB_DEFAULT); + if (NULL == engine_name) { + SLOG(LOG_WARN, TAG_VCC, "[WARNING] Fail to get engine name. Please use default engine name."); + engine_name = strdup("org.tizen.vc-engine-default"); + } + + char* appid = strdup(engine_name); + + SLOG(LOG_INFO, TAG_VCC, "[INFO] VC engine appid(%s)", appid); + + return appid; +} + +static void __on_connected(rpc_port_proxy_vc_setting_proxy_vc_setting_h h, void* user_data) +{ + unsigned int pid = (uintptr_t)user_data; + + vc_setting_tidl_info_s* info = __get_tidl_info_s(pid); + RETM_IF(NULL == info, "[ERROR] Fail to get tidl info"); + + info->connected = true; + info->connection_requesting = false; + info->register_notify_callback_invoked = false; + + SLOG(LOG_INFO, TAG_VCC, "[INFO] Connected to server"); +} + +static void __on_disconnected(rpc_port_proxy_vc_setting_proxy_vc_setting_h h, void* user_data) +{ + unsigned int pid = (uintptr_t)user_data; + + vc_setting_tidl_info_s* info = __get_tidl_info_s(pid); + RETM_IF(NULL == info, "[ERROR] Fail to get tidl info"); + + info->connected = false; + info->connection_requesting = false; + info->register_notify_callback_invoked = false; + + /* retry to connect */ + SLOG(LOG_INFO, TAG_VCC, "[INFO] Disconnected to server"); +} + +static void __on_rejected(rpc_port_proxy_vc_setting_proxy_vc_setting_h h, void* user_data) +{ + unsigned int pid = (uintptr_t)user_data; + + vc_setting_tidl_info_s* info = __get_tidl_info_s(pid); + RETM_IF(NULL == info, "[ERROR] Fail to get tidl info"); + + info->connection_requesting = false; + info->register_notify_callback_invoked = false; + + SLOG(LOG_INFO, TAG_VCC, "[INFO] Rejected from server(%d)", pid); +} + + +static rpc_port_proxy_vc_setting_proxy_vc_setting_h __create_rpc_port(int pid, const char* engine_app_id) +{ + SLOG(LOG_INFO, TAG_VCC, "[INFO] vc setting __create_rpc_port"); + + rpc_port_proxy_vc_setting_proxy_vc_setting_callback_s rpc_callback = { + .connected = __on_connected, + .disconnected = __on_disconnected, + .rejected = __on_rejected + }; + + rpc_port_proxy_vc_setting_proxy_vc_setting_h handle = NULL; + uintptr_t ptr_pid = pid; + if (0 != rpc_port_proxy_vc_setting_proxy_vc_setting_create(engine_app_id, &rpc_callback, (void*)ptr_pid, &handle)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail rpc_port_proxy_vc_setting_proxy_vc_setting_create"); + return NULL; + } + SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] Succeed rpc_port_proxy_vc_setting_proxy_vc_setting_create"); + + return handle; +} + +static void __request_tidl_connect(vc_setting_tidl_info_s* info) +{ + if (info->connection_requesting) { + SLOG(LOG_INFO, TAG_VCC, "[TIDL] Already connection is requested. Skip to call rpc_port_proxy_vc_setting_proxy_vc_setting_connect()."); + return ; + } + + int ret = rpc_port_proxy_vc_setting_proxy_vc_setting_connect(info->rpc_h); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request connection to stub. ret(%d)", ret); + return ; + } + + SLOG(LOG_INFO, TAG_VCC, "[INFO] Request connection to stub. ret(%d)", ret); + info->connection_requesting = true; +} + +static void __notify_cb(void* user_data, int pid, bundle* msg) +{ + // corresponding to listener_event_callback + char* method = NULL; + + SLOG(LOG_DEBUG, TAG_VCC, "__notify_cb is invoked pid(%d)", pid); + + bundle_get_str(msg, VC_BUNDLE_METHOD, &method); + + if (0 == strncmp(VCD_METHOD_HELLO, method, strlen(VCD_METHOD_HELLO))) { + } /* VCD_METHOD_HELLO */ + else if (0 == strncmp(VCD_METHOD_SET_SERVICE_STATE, method, strlen(VCD_METHOD_SET_SERVICE_STATE))) { + /* signal!!! */ + char* state = NULL; + bundle_get_str(msg, VC_BUNDLE_SERVICE_STATE, &state); + if (state) { + __vc_cb_service_state(atoi(state)); + } + } /* VCD_METHOD_SET_SERVICE_STATE */ + else { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid msg"); + } +} + +static int __create_notify_callback_handle(vc_setting_tidl_info_s* info) +{ + if (NULL != info->notify_cb_h) { + rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_dispose(info->rpc_h, info->notify_cb_h); + info->notify_cb_h = NULL; + } + + if (RPC_PORT_ERROR_NONE != rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_create(&info->notify_cb_h)) { + return VC_ERROR_OUT_OF_MEMORY; + } + + rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_set_callback(info->notify_cb_h, __notify_cb, NULL); + rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_set_once(info->notify_cb_h, false); + + return VC_ERROR_NONE; +} + +static int __invoke_register_notify_callback(int pid, vc_setting_tidl_info_s* info) +{ + if (info->register_notify_callback_invoked) { + SLOG(LOG_ERROR, TAG_VCC, "[INFO] Already register callback is invoked"); + return VC_ERROR_NONE; + } + + int ret = __create_notify_callback_handle(info); + if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to create callback handle. ret(%d)", ret); + return VC_ERROR_OPERATION_FAILED; + } + + rpc_port_proxy_vc_setting_proxy_vc_setting_invoke_register_notify_cb(info->rpc_h, pid, info->notify_cb_h); + info->register_notify_callback_invoked = true; + return VC_ERROR_NONE; +} + +int vc_setting_tidl_open_connection() +{ + SLOG(LOG_INFO, TAG_VCC, "[TIDL] vc_setting_tidl_open_connection"); + + vc_setting_tidl_info_s* info = (vc_setting_tidl_info_s*)calloc(1, sizeof(vc_setting_tidl_info_s)); + if (NULL == info) { + SLOG(LOG_ERROR, TAG_VCC, "[TIDL ERROR] Fail to create tidl_info_s"); + return VC_ERROR_OUT_OF_MEMORY; + } + + int pid = getpid(); + char* engine_appid = __get_engine_appid(); + + info->rpc_h = __create_rpc_port(pid, engine_appid); + if (NULL == info->rpc_h) { + SLOG(LOG_ERROR, TAG_VCC, "[TIDL ERROR] Fail to create proxy"); + free(info); + return VC_ERROR_OPERATION_FAILED; + } + + info->pid = pid; + g_tidl_infos = g_list_append(g_tidl_infos, info); + + SLOG(LOG_ERROR, TAG_VCC, "[TIDL] pid(%d) rpc_h(%p), engine_appid(%s)", pid, info->rpc_h, info->engine_appid); + return VC_ERROR_NONE; + +} + +int vc_setting_tidl_close_connection() +{ + SLOG(LOG_INFO, TAG_VCC, "[TIDL] vc_setting_tidl_close_connection"); + + int pid = getpid(); + vc_setting_tidl_info_s* info = __get_tidl_info_s(pid); + RETVM_IF(NULL == info, VC_ERROR_INVALID_PARAMETER, "[ERROR] Fail to get tidl info"); + + if (0 != rpc_port_proxy_vc_setting_proxy_vc_setting_destroy(info->rpc_h)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to disconnect"); + return VC_ERROR_OPERATION_FAILED; + } + + info->rpc_h = NULL; + info->notify_cb_h = NULL; + + g_tidl_infos = g_list_remove(g_tidl_infos, info); + free(info); + + return VC_ERROR_NONE; +} + +int vc_setting_tidl_request_hello() +{ + SLOG(LOG_INFO, TAG_VCC, "[TIDL] vc_tidl_request_hello"); + + int pid = getpid(); + vc_setting_tidl_info_s* info = __get_tidl_info_s(pid); + RETVM_IF(NULL == info, VC_ERROR_INVALID_PARAMETER, "[ERROR] Fail to get tidl info"); + + if (!info->connected) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Not Connected. Call __request_tidl_connect()"); + __request_tidl_connect(info); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCC, ">>>>> VCC Hello"); + if (VC_ERROR_NONE != __invoke_register_notify_callback(pid, info)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to invoke register callback"); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCC, "<<<<"); + return VC_ERROR_NONE; + +} + +static int __covert_unhandled_error(int ret) +{ + if (RPC_PORT_ERROR_IO_ERROR == ret || RPC_PORT_ERROR_OUT_OF_MEMORY == ret) { + return VC_ERROR_OPERATION_FAILED; + } + + return ret; +} + +int vc_setting_tidl_request_set_language(int pid, const char* language) +{ + SLOG(LOG_INFO, TAG_VCC, "[TIDL] vc_setting_tidl_request_set_language"); + + vc_setting_tidl_info_s* info = __get_tidl_info_s(pid); + RETVM_IF(NULL == info, VC_ERROR_INVALID_PARAMETER, "[ERROR] Fail to get tidl info"); + RETVM_IF(false == info->connected, VC_ERROR_OPERATION_FAILED, "[ERROR] Not Connected"); + + int ret = rpc_port_proxy_vc_setting_proxy_vc_setting_invoke_set_language(info->rpc_h, pid, language); + if (RPC_PORT_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCC, ">>>> Request vc setting set language : Fail to invoke message"); + return __covert_unhandled_error(ret); + } + + SLOG(LOG_DEBUG, TAG_VCC, "@@ vc setting set language : pid(%d), language(%s)", pid, language); + + return VC_ERROR_NONE; +} + diff --git a/client/vc_setting_tidl.h b/client/vc_setting_tidl.h new file mode 100755 index 0000000..7cd3cd4 --- /dev/null +++ b/client/vc_setting_tidl.h @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2011-2015 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. +*/ + + +#ifndef __VC_SETTING_TIDL_H_ +#define __VC_SETTING_TIDL_H_ + +#include "voice_control_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int vc_setting_tidl_open_connection(); + +int vc_setting_tidl_close_connection(); + + +int vc_setting_tidl_request_hello(); + +int vc_setting_tidl_request_set_language(int pid, const char* language); + + +#ifdef __cplusplus +} +#endif + +#endif /* __VC_SETTING_TIDL_H_ */ diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index 30bfc62..7ee6ece 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -118,6 +118,9 @@ cp %{SOURCE1001} %{SOURCE1002} . tidlc -p -l C -i tidl/vc.tidl -o vc_proxy -n tidlc -s -l C -i tidl/vc.tidl -o vcd_stub -n +tidlc -p -l C -i tidl/vc_setting.tidl -o vc_setting_proxy -n +tidlc -s -l C -i tidl/vc_setting.tidl -o vcd_setting_stub -n + tidlc -p -l C -i tidl/vc_mgr.tidl -o vc_mgr_proxy -n tidlc -s -l C -i tidl/vc_mgr.tidl -o vcd_mgr_stub -n tidlc -s -l C -i tidl/vcd_mgr.tidl -o vc_mgr_stub -n diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 2cda660..65e8713 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -17,6 +17,7 @@ SET(SRCS vcd_mgr_proxy.c vcd_widget_stub.c vcd_widget_proxy.c + vcd_setting_stub.c vcd_engine_agent.c # vcd_main.c vcd_recorder.c diff --git a/server/vcd_client_data.c b/server/vcd_client_data.c index 25b8882..31332db 100644 --- a/server/vcd_client_data.c +++ b/server/vcd_client_data.c @@ -40,6 +40,9 @@ static manager_tidl_info_s* g_mgr_tidl_info = NULL; /* Widget IPC info */ static GSList* g_widget_tidl_info_list = NULL; +/* Setting IPC info list */ +static GSList* g_setting_tidl_info_list = NULL; + /* Command list */ static current_commands_list_s g_cur_cmd_list; @@ -2180,3 +2183,214 @@ void vcd_client_update_foreground_pid() vcd_config_set_foreground(VC_RUNTIME_INFO_NO_FOREGROUND, true); return; } + +/* +* setting API +*/ +GSList* __get_setting_tidl_info_item(const int pid) +{ + GSList *iter = NULL; + setting_tidl_info_s *data = NULL; + + int count = g_slist_length(g_setting_tidl_info_list); + int i; + + if (0 < count) { + iter = g_slist_nth(g_setting_tidl_info_list, 0); + for (i = 0; i < count; i++) { + if (NULL == iter) + break; + + data = iter->data; + if (NULL != data) { + if (pid == data->pid) + return iter; + } + + iter = g_slist_next(iter); + } + } + + return NULL; +} + +setting_tidl_info_s* __get_setting_tidl_info_element(int pid) +{ + GSList *iter = NULL; + setting_tidl_info_s *data = NULL; + + int count = g_slist_length(g_setting_tidl_info_list); + int i; + + if (0 < count) { + iter = g_slist_nth(g_setting_tidl_info_list, 0); + for (i = 0; i < count; i++) { + if (NULL == iter) + break; + + data = iter->data; + + if (NULL != data) { + if (pid == data->pid) + return data; + } + + iter = g_slist_next(iter); + } + } + + return NULL; +} + +int vcd_client_setting_add_tidl_info(int pid) +{ + /*Check pid is duplicated*/ + setting_tidl_info_s* info = NULL; + info = __get_setting_tidl_info_element(pid); + + if (NULL != info) { + SLOG(LOG_WARN, TAG_VCD, "[Setting Data] Setting tidl info pid is already registered"); + return VCD_ERROR_NONE; + } + + SLOG(LOG_INFO, TAG_VCD, "[Setting Data] There is no tidl info of pid(%d). Create new one.", pid); + info = (setting_tidl_info_s*)calloc(1, sizeof(setting_tidl_info_s)); + if (NULL == info) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory"); + return VCD_ERROR_OUT_OF_MEMORY; + } + + info->pid = pid; + info->notify_cb = NULL; + info->notify_cb_user_data = NULL; + + g_setting_tidl_info_list = g_slist_append(g_setting_tidl_info_list, info); + if (NULL == g_setting_tidl_info_list) { + SLOG(LOG_ERROR, TAG_VCD, "[Setting Data ERROR] Fail to add new setting client tidl info"); + + free(info); + info = NULL; + + return -1; + } else { + SLOG(LOG_INFO, TAG_VCD, "[Setting Data SUCCESS] Add new setting client tidl info. pid(%d)", pid); + } + + return VCD_ERROR_NONE; +} + +int vcd_client_setting_set_tidl_notify_cb(int pid, rpc_port_stub_vcd_setting_stub_vc_setting_notify_cb_h callback, void* user_data) +{ + /*Check pid*/ + setting_tidl_info_s* info = NULL; + info = __get_setting_tidl_info_element(pid); + + if (NULL == info) { + SLOG(LOG_ERROR, TAG_VCD, "[Setting Data ERROR] There is no tidl info in the list. pid(%d)", pid); + return VCD_ERROR_INVALID_PARAMETER; + } + + int ret = -1; + ret = rpc_port_stub_vcd_setting_stub_vc_setting_notify_cb_clone(callback, &(info->notify_cb)); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Setting Data ERROR] Fail to clone notify callback. ret(%d)", ret); + } else { + SLOG(LOG_INFO, TAG_VCD, "[Setting Data] Succeed to clone notify callback. ret(%d)", ret); + } + info->notify_cb_user_data = user_data; + + return VCD_ERROR_NONE; +} + +int vcd_client_setting_unset_tidl_notify_cb(int pid) +{ + /*Check pid*/ + setting_tidl_info_s* info = NULL; + info = __get_setting_tidl_info_element(pid); + + if (NULL == info) { + SLOG(LOG_ERROR, TAG_VCD, "[Setting Data ERROR] There is no tidl info in the list. pid(%d)", pid); + return VCD_ERROR_INVALID_PARAMETER; + } + + int ret = -1; + ret = rpc_port_stub_vcd_setting_stub_vc_setting_notify_cb_destroy(info->notify_cb); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Setting Data ERROR] Fail to destroy notify callback. ret(%d)", ret); + } else { + SLOG(LOG_INFO, TAG_VCD, "[Setting Data] Succeed to destroy notify callback. ret(%d)", ret); + } + info->notify_cb = NULL; + info->notify_cb_user_data = NULL; + + return VCD_ERROR_NONE; +} + +int vcd_client_setting_delete_tidl_info(int pid) +{ + GSList *tmp = NULL; + setting_tidl_info_s* setting_tidl_info = NULL; + + /*Get handle*/ + tmp = __get_setting_tidl_info_item(pid); + if (NULL == tmp) { + SLOG(LOG_ERROR, TAG_VCD, "[Setting Data ERROR] pid(%d) is NOT valid", pid); + return VCD_ERROR_INVALID_PARAMETER; + } + + /*Free setting client structure*/ + setting_tidl_info = tmp->data; + if (NULL != setting_tidl_info) { + free(setting_tidl_info); + } + + /*Remove handle from list*/ + g_setting_tidl_info_list = g_slist_remove_link(g_setting_tidl_info_list, tmp); + + return 0; +} + +setting_tidl_info_s* vcd_client_setting_get_tidl_info(int pid) +{ + return __get_setting_tidl_info_element(pid); +} + +int vcd_client_setting_get_tidl_list(int** pids, int* pid_count) +{ + if (NULL == pids || NULL == pid_count) + return -1; + + int count = g_slist_length(g_setting_tidl_info_list); + + if (0 == count) + return -1; + + int *tmp; + tmp = (int*)calloc(count, sizeof(int)); + if (NULL == tmp) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory"); + return VCD_ERROR_OUT_OF_MEMORY; + } + + GSList *iter = NULL; + setting_tidl_info_s *data = NULL; + int i = 0; + + iter = g_slist_nth(g_setting_tidl_info_list, 0); + + while (NULL != iter) { + data = iter->data; + + if (NULL != data) { + tmp[i] = data->pid; + } + + iter = g_slist_next(iter); + i++; + } + + *pids = tmp; + *pid_count = count; + + return 0; +} diff --git a/server/vcd_client_data.h b/server/vcd_client_data.h index 3b2f55c..4c7fbdc 100644 --- a/server/vcd_client_data.h +++ b/server/vcd_client_data.h @@ -22,6 +22,7 @@ #include "vc_command.h" #include "vc_info_parser.h" #include "vcd_stub.h" +#include "vcd_setting_stub.h" #include "vcd_mgr_stub.h" #include "vcd_mgr_proxy.h" #include "vcd_widget_stub.h" @@ -103,6 +104,13 @@ typedef struct { rpc_port_proxy_vcd_widget_proxy_vcd_widget_h rpc_h; } widget_tidl_info_s; +typedef struct { + int pid; + rpc_port_stub_vcd_setting_stub_vc_setting_notify_cb_h notify_cb; + void* notify_cb_user_data; +} setting_tidl_info_s; + + typedef enum { VCD_RECOGNITION_MODE_STOP_BY_SILENCE, /**< Default mode */ VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT, /**< Restart recognition after rejected result */ @@ -265,6 +273,21 @@ widget_tidl_info_s* vcd_client_widget_get_tidl_info(int pid); GSList* vcd_client_widget_get_tidl_info_list(); +/* +* setting API +*/ +int vcd_client_setting_add_tidl_info(int pid); + +int vcd_client_setting_set_tidl_notify_cb(int pid, rpc_port_stub_vcd_setting_stub_vc_setting_notify_cb_h callback, void* user_data); + +int vcd_client_setting_unset_tidl_notify_cb(int pid); + +int vcd_client_setting_delete_tidl_info(int pid); + +setting_tidl_info_s* vcd_client_setting_get_tidl_info(int pid); + +int vcd_client_setting_get_tidl_list(int** pids, int* pid_count); + #ifdef __cplusplus } #endif diff --git a/server/vcd_tidl.c b/server/vcd_tidl.c index e5905ba..f9b43c9 100644 --- a/server/vcd_tidl.c +++ b/server/vcd_tidl.c @@ -21,6 +21,7 @@ #include "vcd_tidl.h" #include "vcd_stub.h" +#include "vcd_setting_stub.h" #include "vcd_mgr_stub.h" #include "vcd_mgr_proxy.h" #include "vcd_widget_stub.h" @@ -39,6 +40,10 @@ static rpc_port_stub_vcd_stub_vc_callback_s g_client_callback; static pthread_mutex_t g_client_tidl_info_mutex = PTHREAD_MUTEX_INITIALIZER; +static rpc_port_stub_vcd_setting_stub_vc_setting_callback_s g_setting_callback; + +static pthread_mutex_t g_setting_tidl_info_mutex = PTHREAD_MUTEX_INITIALIZER; + static int g_volume_count = 0; int vcd_client_tidl_open_connection(); @@ -47,6 +52,8 @@ int vcd_mgr_tidl_open_connection(); int vcd_mgr_tidl_close_connection(); int vcd_widget_tidl_open_connection(); int vcd_widget_tidl_close_connection(); +int vcd_setting_tidl_open_connection(); +int vcd_setting_tidl_close_connection(); @@ -326,6 +333,40 @@ static void __vc_create_cb(rpc_port_stub_vcd_stub_vc_context_h context, void *us static void __vc_terminate_cb(rpc_port_stub_vcd_stub_vc_context_h context, void *user_data) { SLOG(LOG_INFO, TAG_VCD, "[TIDL] __vc_terminate_cb"); + + void* tag = NULL; + rpc_port_stub_vcd_stub_vc_context_get_tag(context, &tag); + + if (NULL != tag) { + int pid = (uintptr_t)tag; + SLOG(LOG_DEBUG, TAG_VCD, "@@@ VC FINALIZE. pid(%u)", pid); + + pthread_mutex_lock(&g_client_tidl_info_mutex); + client_tidl_info_s* tidl_info = vcd_client_get_tidl_info(pid); + if (NULL == tidl_info) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Fail to get client tidl info."); + pthread_mutex_unlock(&g_client_tidl_info_mutex); + return; + } + + if (0 != vcd_client_unset_tidl_notify_cb(pid)) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Fail to unset notify callback"); + } + if (0 != vcd_client_unset_tidl_feedback_cb(pid)) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Fail to unset feedback callback"); + } + + if (0 != vcd_client_delete_tidl_info(pid)) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Fail to delete client tidl info"); + } + tidl_info = NULL; + + SLOG(LOG_DEBUG, TAG_VCD, "@@@"); + + pthread_mutex_unlock(&g_client_tidl_info_mutex); + + } + rpc_port_stub_vcd_stub_vc_context_set_tag(context, NULL); } static void __vc_register_notify_cb_cb(rpc_port_stub_vcd_stub_vc_context_h context, int pid, rpc_port_stub_vcd_stub_vc_notify_cb_h callback, void *user_data) @@ -434,6 +475,9 @@ static int __vc_initialize_cb(rpc_port_stub_vcd_stub_vc_context_h context, int p int ret = VCD_ERROR_OPERATION_FAILED; + uintptr_t ptr_pid = pid; + rpc_port_stub_vcd_stub_vc_context_set_tag(context, (void*)ptr_pid); + ret = vcd_server_initialize(pid); *service_state = vcd_server_get_service_state(); *daemon_pid = getpid(); @@ -904,6 +948,11 @@ int vcd_tidl_open_connection() return VCD_ERROR_OPERATION_FAILED; } + if (0 != vcd_setting_tidl_open_connection()) { + SLOG(LOG_ERROR, TAG_VCD, "Fail to open connection to setting"); + return VCD_ERROR_OPERATION_FAILED; + } + return VCD_ERROR_NONE; } @@ -926,6 +975,11 @@ int vcd_tidl_close_connection() return VCD_ERROR_OPERATION_FAILED; } + if (0 != vcd_setting_tidl_close_connection()) { + SLOG(LOG_ERROR, TAG_VCD, "Fail to close connection to setting"); + return VCD_ERROR_OPERATION_FAILED; + } + return VCD_ERROR_NONE; } @@ -2560,3 +2614,159 @@ int vcd_widget_tidl_close_connection() return VCD_ERROR_NONE; } + +/** + * TIDL functions for VC setting client + */ +static void __vc_setting_create_cb(rpc_port_stub_vcd_setting_stub_vc_setting_context_h context, void *user_data) +{ + SLOG(LOG_INFO, TAG_VCD, "[TIDL] __vc_setting_create_cb"); + + char *sender = NULL; + + rpc_port_stub_vcd_setting_stub_vc_setting_context_get_sender(context, &sender); + if (!sender) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Sender is NULL"); + return ; + } + + SLOG(LOG_INFO, TAG_VCD, "[TIDL] sender(%s)", sender); // sender (app_id) + free(sender); +} + +static void __vc_setting_terminate_cb(rpc_port_stub_vcd_setting_stub_vc_setting_context_h context, void *user_data) +{ + SLOG(LOG_INFO, TAG_VCD, "[TIDL] __vc_setting_terminate_cb"); + void* tag = NULL; + rpc_port_stub_vcd_setting_stub_vc_setting_context_get_tag(context, &tag); + + if (NULL != tag) { + int pid = (intptr_t)tag; + SLOG(LOG_DEBUG, TAG_VCD, "@@@ VC SETTING FINALIZE. pid(%u)", pid); + + pthread_mutex_lock(&g_setting_tidl_info_mutex); + setting_tidl_info_s* setting_tidl_info = vcd_client_setting_get_tidl_info(pid); + if (NULL == setting_tidl_info) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Fail to get setting tidl info."); + pthread_mutex_unlock(&g_setting_tidl_info_mutex); + return; + } + + if (0 != vcd_client_setting_unset_tidl_notify_cb(pid)) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Fail to unset notify callback"); + } + + if (0 != vcd_client_setting_delete_tidl_info(pid)) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Fail to delete setting tidl info"); + } + setting_tidl_info = NULL; + + SLOG(LOG_DEBUG, TAG_VCD, "@@@"); + + pthread_mutex_unlock(&g_setting_tidl_info_mutex); + } + rpc_port_stub_vcd_setting_stub_vc_setting_context_set_tag(context, NULL); +} + +static void __vc_setting_register_notify_cb_cb(rpc_port_stub_vcd_setting_stub_vc_setting_context_h context, int pid, rpc_port_stub_vcd_setting_stub_vc_setting_notify_cb_h callback, void *user_data) +{ + SLOG(LOG_INFO, TAG_VCD, "[TIDL] __vc_setting_register_notify_cb_cb. pid(%d)", pid); + + if (NULL == callback) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] callback is null."); + return ; + } + + int ret = -1; + ret = vcd_client_setting_add_tidl_info(pid); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Fail to add tidl info."); + return ; + } + + ret = vcd_client_setting_set_tidl_notify_cb(pid, callback, user_data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Fail to set notify callback."); + } else { + SLOG(LOG_INFO, TAG_VCD, "[TIDL] Succeed to set notify callback."); + } +} + +static int __vc_setting_register_notify_cb_sync_cb(rpc_port_stub_vcd_setting_stub_vc_setting_context_h context, int pid, rpc_port_stub_vcd_setting_stub_vc_setting_notify_cb_h callback, void *user_data) +{ + SLOG(LOG_INFO, TAG_VCD, "[TIDL] __vc_setting_register_notify_cb_sync_cb. pid(%d)", pid); + + if (NULL == callback) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] callback is null."); + return VCD_ERROR_INVALID_PARAMETER; + } + + int ret = -1; + ret = vcd_client_setting_add_tidl_info(pid); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Fail to add tidl info."); + return ret; + } + + ret = vcd_client_setting_set_tidl_notify_cb(pid, callback, user_data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Fail to set notify callback."); + } else { + SLOG(LOG_INFO, TAG_VCD, "[TIDL] Succeed to set notify callback."); + } + + return ret; +} + +int __vc_setting_set_language_cb(rpc_port_stub_vcd_setting_stub_vc_setting_context_h context, int pid, const char *language, void *user_data) +{ + if (NULL == language) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Invalid parameter"); + return VCD_ERROR_INVALID_PARAMETER; + } + + SLOG(LOG_INFO, TAG_VCD, "[IN] vcd server set language : language(%s)", language); + + int ret = vcd_server_set_language(language); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[TIDL ERROR] Fail to set language(%d).", ret); + } else { + SLOG(LOG_INFO, TAG_VCD, "[TIDL] Succeed to set language."); + } + + return ret; +} + +int vcd_setting_tidl_open_connection() +{ + SLOG(LOG_DEBUG, TAG_VCD, "[TIDL] vcd_setting_tidl_open_connection"); + + g_setting_callback.create = __vc_setting_create_cb; + g_setting_callback.terminate = __vc_setting_terminate_cb; + g_setting_callback.register_notify_cb = __vc_setting_register_notify_cb_cb; + g_setting_callback.register_notify_cb_sync = __vc_setting_register_notify_cb_sync_cb; + g_setting_callback.set_language = __vc_setting_set_language_cb; + + int ret = -1; + int count = 0; + while (VC_RETRY_MIN_COUNT >= count) { + ret = rpc_port_stub_vcd_setting_stub_vc_setting_register(&g_setting_callback, NULL); + if (0 == ret) { + SLOG(LOG_DEBUG, TAG_VCD, "register callback"); + return VCD_ERROR_NONE; + } + usleep(100000); + count++; + } + + SLOG(LOG_ERROR, TAG_VCD, "Fail to register callback(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; +} + +int vcd_setting_tidl_close_connection() +{ + SLOG(LOG_DEBUG, TAG_VCD, "[TIDL] Close connection"); + rpc_port_stub_vcd_setting_stub_vc_setting_unregister(); + + return VCD_ERROR_NONE; +} diff --git a/tidl/vc_setting.tidl b/tidl/vc_setting.tidl new file mode 100755 index 0000000..bb46f65 --- /dev/null +++ b/tidl/vc_setting.tidl @@ -0,0 +1,8 @@ +interface vc_setting { + void notify_cb(int pid, bundle msg) delegate; + + void register_notify_cb(int pid, notify_cb callback) async; + int register_notify_cb_sync(int pid, notify_cb callback); + + int set_language(in int pid, in string language); +}