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);
81 static void __on_connected(rpc_port_proxy_vc_setting_proxy_vc_setting_h h, void* user_data)
83 unsigned int pid = (intptr_t)user_data;
85 vc_setting_tidl_info_s* info = __get_tidl_info_s(pid);
86 RETM_IF(NULL == info, TAG_VCC, "[ERROR] Fail to get tidl info");
88 info->connected = true;
89 info->connection_requesting = false;
90 info->register_notify_callback_invoked = false;
92 SLOG(LOG_INFO, TAG_VCC, "[INFO] Connected to server");
95 static void __on_disconnected(rpc_port_proxy_vc_setting_proxy_vc_setting_h h, void* user_data)
97 unsigned int pid = (intptr_t)user_data;
99 vc_setting_tidl_info_s* info = __get_tidl_info_s(pid);
100 RETM_IF(NULL == info, TAG_VCC, "[ERROR] Fail to get tidl info");
102 info->connected = false;
103 info->connection_requesting = false;
104 info->register_notify_callback_invoked = false;
106 /* retry to connect */
107 SLOG(LOG_INFO, TAG_VCC, "[INFO] Disconnected to server");
110 static void __on_rejected(rpc_port_proxy_vc_setting_proxy_vc_setting_h h, void* user_data)
112 unsigned int pid = (intptr_t)user_data;
114 vc_setting_tidl_info_s* info = __get_tidl_info_s(pid);
115 RETM_IF(NULL == info, TAG_VCC, "[ERROR] Fail to get tidl info");
117 info->connection_requesting = false;
118 info->register_notify_callback_invoked = false;
120 SLOG(LOG_INFO, TAG_VCC, "[INFO] Rejected from server(%d)", pid);
124 static rpc_port_proxy_vc_setting_proxy_vc_setting_h __create_rpc_port(int pid, const char* engine_app_id)
126 SLOG(LOG_INFO, TAG_VCC, "[INFO] vc setting __create_rpc_port");
128 rpc_port_proxy_vc_setting_proxy_vc_setting_callback_s rpc_callback = {
129 .connected = __on_connected,
130 .disconnected = __on_disconnected,
131 .rejected = __on_rejected
134 rpc_port_proxy_vc_setting_proxy_vc_setting_h handle = NULL;
135 intptr_t ptr_pid = pid;
136 if (0 != rpc_port_proxy_vc_setting_proxy_vc_setting_create(engine_app_id, &rpc_callback, (void*)ptr_pid, &handle)) {
137 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail rpc_port_proxy_vc_setting_proxy_vc_setting_create");
140 SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] Succeed rpc_port_proxy_vc_setting_proxy_vc_setting_create");
145 static void __request_tidl_connect(vc_setting_tidl_info_s* info)
147 if (info->connection_requesting) {
148 SLOG(LOG_INFO, TAG_VCC, "[TIDL] Already connection is requested. Skip to call rpc_port_proxy_vc_setting_proxy_vc_setting_connect().");
152 int ret = rpc_port_proxy_vc_setting_proxy_vc_setting_connect_sync(info->rpc_h);
154 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request connection to stub. ret(%d)", ret);
158 SLOG(LOG_INFO, TAG_VCC, "[INFO] Request connection to stub. ret(%d)", ret);
159 info->connection_requesting = true;
162 static void __notify_cb(void* user_data, int pid, bundle* msg)
164 // corresponding to listener_event_callback
167 SLOG(LOG_DEBUG, TAG_VCC, "__notify_cb is invoked pid(%d)", pid);
169 bundle_get_str(msg, VC_BUNDLE_METHOD, &method);
171 if (0 == strncmp(VCD_METHOD_HELLO, method, strlen(VCD_METHOD_HELLO))) {
172 SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] HELLO received");
173 } /* VCD_METHOD_HELLO */
175 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid msg");
179 static int __create_notify_callback_handle(vc_setting_tidl_info_s* info)
181 if (NULL != info->notify_cb_h) {
182 rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_dispose(info->rpc_h, info->notify_cb_h);
183 info->notify_cb_h = NULL;
186 if (RPC_PORT_ERROR_NONE != rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_create(&info->notify_cb_h)) {
187 return VC_ERROR_OUT_OF_MEMORY;
190 rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_set_callback(info->notify_cb_h, __notify_cb, NULL);
191 rpc_port_proxy_vc_setting_proxy_vc_setting_notify_cb_set_once(info->notify_cb_h, false);
193 return VC_ERROR_NONE;
196 static int __invoke_register_notify_callback(int pid, vc_setting_tidl_info_s* info)
198 if (info->register_notify_callback_invoked) {
199 SLOG(LOG_ERROR, TAG_VCC, "[INFO] Already register callback is invoked");
200 return VC_ERROR_NONE;
203 int ret = __create_notify_callback_handle(info);
204 if (VC_ERROR_NONE != ret) {
205 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to create callback handle. ret(%d)", ret);
206 return VC_ERROR_OPERATION_FAILED;
209 rpc_port_proxy_vc_setting_proxy_vc_setting_invoke_register_notify_cb(info->rpc_h, pid, info->notify_cb_h);
210 info->register_notify_callback_invoked = true;
211 return VC_ERROR_NONE;
214 int vc_setting_tidl_open_connection()
216 SLOG(LOG_INFO, TAG_VCC, "[TIDL] vc_setting_tidl_open_connection");
218 vc_setting_tidl_info_s* info = (vc_setting_tidl_info_s*)calloc(1, sizeof(vc_setting_tidl_info_s));
220 SLOG(LOG_ERROR, TAG_VCC, "[TIDL ERROR] Fail to create tidl_info_s");
221 return VC_ERROR_OUT_OF_MEMORY;
225 char* engine_appid = __get_engine_appid();
227 info->rpc_h = __create_rpc_port(pid, engine_appid);
228 if (NULL == info->rpc_h) {
229 SLOG(LOG_ERROR, TAG_VCC, "[TIDL ERROR] Fail to create proxy");
232 return VC_ERROR_OPERATION_FAILED;
236 g_tidl_infos = g_list_append(g_tidl_infos, info);
238 SLOG(LOG_ERROR, TAG_VCC, "[TIDL] pid(%d) rpc_h(%p), engine_appid(%s)", pid, info->rpc_h, info->engine_appid);
241 return VC_ERROR_NONE;
245 int vc_setting_tidl_close_connection()
247 SLOG(LOG_INFO, TAG_VCC, "[TIDL] vc_setting_tidl_close_connection");
250 vc_setting_tidl_info_s* info = __get_tidl_info_s(pid);
251 RETVM_IF(NULL == info, VC_ERROR_INVALID_PARAMETER, TAG_VCC, "[ERROR] Fail to get tidl info");
253 if (0 != rpc_port_proxy_vc_setting_proxy_vc_setting_destroy(info->rpc_h)) {
254 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to disconnect");
255 return VC_ERROR_OPERATION_FAILED;
259 info->notify_cb_h = NULL;
261 g_tidl_infos = g_list_remove(g_tidl_infos, info);
264 return VC_ERROR_NONE;
267 int vc_setting_tidl_request_hello()
269 SLOG(LOG_INFO, TAG_VCC, "[TIDL] vc_tidl_request_hello");
272 vc_setting_tidl_info_s* info = __get_tidl_info_s(pid);
273 RETVM_IF(NULL == info, VC_ERROR_INVALID_PARAMETER, TAG_VCC, "[ERROR] Fail to get tidl info");
275 __request_tidl_connect(info);
277 if (!info->connected) {
278 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Not Connected.");
279 return VC_ERROR_OPERATION_FAILED;
282 SLOG(LOG_DEBUG, TAG_VCC, ">>>>> VCC Hello");
283 if (VC_ERROR_NONE != __invoke_register_notify_callback(pid, info)) {
284 SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to invoke register callback");
285 return VC_ERROR_OPERATION_FAILED;
288 SLOG(LOG_DEBUG, TAG_VCC, "<<<<");
289 return VC_ERROR_NONE;
293 static int __convert_unhandled_error(int ret)
295 if (RPC_PORT_ERROR_IO_ERROR == ret || RPC_PORT_ERROR_OUT_OF_MEMORY == ret) {
296 return VC_ERROR_OPERATION_FAILED;
302 int vc_setting_tidl_request_set_language(int pid, const char* language)
304 SLOG(LOG_INFO, TAG_VCC, "[TIDL] vc_setting_tidl_request_set_language");
306 vc_setting_tidl_info_s* info = __get_tidl_info_s(pid);
307 RETVM_IF(NULL == info, VC_ERROR_INVALID_PARAMETER, TAG_VCC, "[ERROR] Fail to get tidl info");
308 RETVM_IF(false == info->connected, VC_ERROR_OPERATION_FAILED, TAG_VCC, "[ERROR] Not Connected");
310 int ret = rpc_port_proxy_vc_setting_proxy_vc_setting_invoke_set_language(info->rpc_h, pid, language);
311 int exception = get_last_result();
312 if (RPC_PORT_ERROR_NONE != exception) {
313 ret = __convert_unhandled_error(exception);
316 if (VC_ERROR_NONE != ret) {
317 SLOG(LOG_ERROR, TAG_VCC, ">>>> Request vc setting set language : Fail to invoke message (%d)", ret);
321 SLOG(LOG_DEBUG, TAG_VCC, "@@ vc setting set language : pid(%d), language(%s)", pid, language);
323 return VC_ERROR_NONE;