2 * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "vc_command.h"
18 #include "vc_setting_tidl.h"
19 #include "vc_setting_proxy.h"
27 bool connection_requesting;
28 bool register_notify_callback_invoked;
30 rpc_port_proxy_vc_setting_proxy_vc_setting_h rpc_h;
31 rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_h notify_cb_h;
34 } vc_setting_tidl_info_s;
36 static GList* g_tidl_infos = NULL;
39 static vc_setting_tidl_info_s* __get_tidl_info_s(int pid)
41 // TODO: Hmm.... is this necessary...??
43 vc_setting_tidl_info_s* info = NULL;
45 if (g_list_length(g_tidl_infos) > 0) {
46 /* Get a first item */
47 iter = g_list_first(g_tidl_infos);
49 while (NULL != iter) {
52 if (info->pid == pid) {
57 iter = g_list_next(iter);
64 static char* __get_engine_appid(void)
66 char* engine_name = vconf_get_str(VC_ENGINE_DB_DEFAULT);
67 if (NULL == engine_name) {
68 SLOG(LOG_WARN, TAG_VCC, "[WARNING] Fail to get engine name. Please use default engine name.");
69 engine_name = strdup("org.tizen.vc-engine-default");
72 char* appid = strdup(engine_name);
74 SLOG(LOG_INFO, TAG_VCC, "[INFO] VC engine appid(%s)", appid);
79 static void __on_connected(rpc_port_proxy_vc_setting_proxy_vc_setting_h h, void* user_data)
81 unsigned int pid = (uintptr_t)user_data;
83 vc_setting_tidl_info_s* info = __get_tidl_info_s(pid);
84 RETM_IF(NULL == info, "[ERROR] Fail to get tidl info");
86 info->connected = true;
87 info->connection_requesting = false;
88 info->register_notify_callback_invoked = false;
90 SLOG(LOG_INFO, TAG_VCC, "[INFO] Connected to server");
93 static void __on_disconnected(rpc_port_proxy_vc_setting_proxy_vc_setting_h h, void* user_data)
95 unsigned int pid = (uintptr_t)user_data;
97 vc_setting_tidl_info_s* info = __get_tidl_info_s(pid);
98 RETM_IF(NULL == info, "[ERROR] Fail to get tidl info");
100 info->connected = false;
101 info->connection_requesting = false;
102 info->register_notify_callback_invoked = false;
104 /* retry to connect */
105 SLOG(LOG_INFO, TAG_VCC, "[INFO] Disconnected to server");
108 static void __on_rejected(rpc_port_proxy_vc_setting_proxy_vc_setting_h h, void* user_data)
110 unsigned int pid = (uintptr_t)user_data;
112 vc_setting_tidl_info_s* info = __get_tidl_info_s(pid);
113 RETM_IF(NULL == info, "[ERROR] Fail to get tidl info");
115 info->connection_requesting = false;
116 info->register_notify_callback_invoked = false;
118 SLOG(LOG_INFO, TAG_VCC, "[INFO] Rejected from server(%d)", pid);
122 static rpc_port_proxy_vc_setting_proxy_vc_setting_h __create_rpc_port(int pid, const char* engine_app_id)
124 SLOG(LOG_INFO, TAG_VCC, "[INFO] vc setting __create_rpc_port");
126 rpc_port_proxy_vc_setting_proxy_vc_setting_callback_s rpc_callback = {
127 .connected = __on_connected,
128 .disconnected = __on_disconnected,
129 .rejected = __on_rejected
132 rpc_port_proxy_vc_setting_proxy_vc_setting_h handle = NULL;
133 uintptr_t ptr_pid = pid;
134 if (0 != rpc_port_proxy_vc_setting_proxy_vc_setting_create(engine_app_id, &rpc_callback, (void*)ptr_pid, &handle)) {
135 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail rpc_port_proxy_vc_setting_proxy_vc_setting_create");
138 SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] Succeed rpc_port_proxy_vc_setting_proxy_vc_setting_create");
143 static void __request_tidl_connect(vc_setting_tidl_info_s* info)
145 if (info->connection_requesting) {
146 SLOG(LOG_INFO, TAG_VCC, "[TIDL] Already connection is requested. Skip to call rpc_port_proxy_vc_setting_proxy_vc_setting_connect().");
150 int ret = rpc_port_proxy_vc_setting_proxy_vc_setting_connect(info->rpc_h);
152 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request connection to stub. ret(%d)", ret);
156 SLOG(LOG_INFO, TAG_VCC, "[INFO] Request connection to stub. ret(%d)", ret);
157 info->connection_requesting = true;
160 static void __notify_cb(void* user_data, int pid, bundle* msg)
162 // corresponding to listener_event_callback
165 SLOG(LOG_DEBUG, TAG_VCC, "__notify_cb is invoked pid(%d)", pid);
167 bundle_get_str(msg, VC_BUNDLE_METHOD, &method);
169 if (0 == strncmp(VCD_METHOD_HELLO, method, strlen(VCD_METHOD_HELLO))) {
170 SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] HELLO received");
171 } /* VCD_METHOD_HELLO */
173 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid msg");
177 static int __create_notify_callback_handle(vc_setting_tidl_info_s* info)
179 if (NULL != info->notify_cb_h) {
180 rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_dispose(info->rpc_h, info->notify_cb_h);
181 info->notify_cb_h = NULL;
184 if (RPC_PORT_ERROR_NONE != rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_create(&info->notify_cb_h)) {
185 return VC_ERROR_OUT_OF_MEMORY;
188 rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_set_callback(info->notify_cb_h, __notify_cb, NULL);
189 rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_set_once(info->notify_cb_h, false);
191 return VC_ERROR_NONE;
194 static int __invoke_register_notify_callback(int pid, vc_setting_tidl_info_s* info)
196 if (info->register_notify_callback_invoked) {
197 SLOG(LOG_ERROR, TAG_VCC, "[INFO] Already register callback is invoked");
198 return VC_ERROR_NONE;
201 int ret = __create_notify_callback_handle(info);
202 if (VC_ERROR_NONE != ret) {
203 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to create callback handle. ret(%d)", ret);
204 return VC_ERROR_OPERATION_FAILED;
207 rpc_port_proxy_vc_setting_proxy_vc_setting_invoke_register_notify_cb(info->rpc_h, pid, info->notify_cb_h);
208 info->register_notify_callback_invoked = true;
209 return VC_ERROR_NONE;
212 int vc_setting_tidl_open_connection()
214 SLOG(LOG_INFO, TAG_VCC, "[TIDL] vc_setting_tidl_open_connection");
216 vc_setting_tidl_info_s* info = (vc_setting_tidl_info_s*)calloc(1, sizeof(vc_setting_tidl_info_s));
218 SLOG(LOG_ERROR, TAG_VCC, "[TIDL ERROR] Fail to create tidl_info_s");
219 return VC_ERROR_OUT_OF_MEMORY;
223 char* engine_appid = __get_engine_appid();
225 info->rpc_h = __create_rpc_port(pid, engine_appid);
226 if (NULL == info->rpc_h) {
227 SLOG(LOG_ERROR, TAG_VCC, "[TIDL ERROR] Fail to create proxy");
229 return VC_ERROR_OPERATION_FAILED;
233 g_tidl_infos = g_list_append(g_tidl_infos, info);
235 SLOG(LOG_ERROR, TAG_VCC, "[TIDL] pid(%d) rpc_h(%p), engine_appid(%s)", pid, info->rpc_h, info->engine_appid);
236 return VC_ERROR_NONE;
240 int vc_setting_tidl_close_connection()
242 SLOG(LOG_INFO, TAG_VCC, "[TIDL] vc_setting_tidl_close_connection");
245 vc_setting_tidl_info_s* info = __get_tidl_info_s(pid);
246 RETVM_IF(NULL == info, VC_ERROR_INVALID_PARAMETER, "[ERROR] Fail to get tidl info");
248 if (0 != rpc_port_proxy_vc_setting_proxy_vc_setting_destroy(info->rpc_h)) {
249 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to disconnect");
250 return VC_ERROR_OPERATION_FAILED;
254 info->notify_cb_h = NULL;
256 g_tidl_infos = g_list_remove(g_tidl_infos, info);
259 return VC_ERROR_NONE;
262 int vc_setting_tidl_request_hello()
264 SLOG(LOG_INFO, TAG_VCC, "[TIDL] vc_tidl_request_hello");
267 vc_setting_tidl_info_s* info = __get_tidl_info_s(pid);
268 RETVM_IF(NULL == info, VC_ERROR_INVALID_PARAMETER, "[ERROR] Fail to get tidl info");
270 if (!info->connected) {
271 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Not Connected. Call __request_tidl_connect()");
272 __request_tidl_connect(info);
273 return VC_ERROR_OPERATION_FAILED;
276 SLOG(LOG_DEBUG, TAG_VCC, ">>>>> VCC Hello");
277 if (VC_ERROR_NONE != __invoke_register_notify_callback(pid, info)) {
278 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to invoke register callback");
279 return VC_ERROR_OPERATION_FAILED;
282 SLOG(LOG_DEBUG, TAG_VCC, "<<<<");
283 return VC_ERROR_NONE;
287 static int __covert_unhandled_error(int ret)
289 if (RPC_PORT_ERROR_IO_ERROR == ret || RPC_PORT_ERROR_OUT_OF_MEMORY == ret) {
290 return VC_ERROR_OPERATION_FAILED;
296 int vc_setting_tidl_request_set_language(int pid, const char* language)
298 SLOG(LOG_INFO, TAG_VCC, "[TIDL] vc_setting_tidl_request_set_language");
300 vc_setting_tidl_info_s* info = __get_tidl_info_s(pid);
301 RETVM_IF(NULL == info, VC_ERROR_INVALID_PARAMETER, "[ERROR] Fail to get tidl info");
302 RETVM_IF(false == info->connected, VC_ERROR_OPERATION_FAILED, "[ERROR] Not Connected");
304 int ret = rpc_port_proxy_vc_setting_proxy_vc_setting_invoke_set_language(info->rpc_h, pid, language);
305 if (RPC_PORT_ERROR_NONE != ret) {
306 SLOG(LOG_ERROR, TAG_VCC, ">>>> Request vc setting set language : Fail to invoke message");
307 return __covert_unhandled_error(ret);
310 SLOG(LOG_DEBUG, TAG_VCC, "@@ vc setting set language : pid(%d), language(%s)", pid, language);
312 return VC_ERROR_NONE;