Replace IPC of vc_setting 64/278964/1
authorsooyeon <sooyeon.kim@samsung.com>
Mon, 27 Jun 2022 08:12:33 +0000 (17:12 +0900)
committersooyeon <sooyeon.kim@samsung.com>
Fri, 29 Jul 2022 01:25:58 +0000 (10:25 +0900)
Change-Id: I58f30103efd851762c01e6f2730087364c1b8cf8
Signed-off-by: sooyeon <sooyeon.kim@samsung.com>
client/CMakeLists.txt
client/vc_setting.c
client/vc_setting_tidl.c [new file with mode: 0755]
client/vc_setting_tidl.h [new file with mode: 0755]
packaging/voice-control.spec
server/CMakeLists.txt
server/vcd_client_data.c
server/vcd_client_data.h
server/vcd_tidl.c
tidl/vc_setting.tidl [new file with mode: 0755]

index 63ced4a..b5ddb82 100644 (file)
@@ -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
index 238480f..c415a77 100644 (file)
@@ -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 (executable)
index 0000000..240ef70
--- /dev/null
@@ -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 <vconf.h>
+
+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 (executable)
index 0000000..7cd3cd4
--- /dev/null
@@ -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_ */
index 30bfc62..7ee6ece 100644 (file)
@@ -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
index 2cda660..65e8713 100644 (file)
@@ -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
index 25b8882..31332db 100644 (file)
@@ -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;
+}
index 3b2f55c..4c7fbdc 100644 (file)
@@ -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
index e5905ba..f9b43c9 100644 (file)
@@ -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 (executable)
index 0000000..bb46f65
--- /dev/null
@@ -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);
+}