Fix build error on gcc-13 Build
[platform/core/uifw/voice-control.git] / client / vc_widget_tidl.c
1 /*
2 * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17 #include <pthread.h>
18 #include <rpc-port.h>
19
20 #include "vc_main.h"
21 #include "vc_widget_client.h"
22 #include "vc_widget_tidl.h"
23 #include "vc_widget_proxy.h"
24 #include "vc_widget_stub.h"
25
26 typedef struct {
27         bool connected;
28         bool connection_requesting;
29         bool register_callback_invoked;
30         rpc_port_proxy_vc_widget_proxy_vc_widget_h rpc_h;
31         rpc_port_proxy_vc_widget_proxy_vc_widget_notify_cb_h notify_cb_h;
32 } vc_widget_tidl_info_s;
33
34 typedef struct {
35         bool connected;
36         bool register_callback_requesting;
37 } vcd_widget_tidl_info_s;
38
39 static vc_widget_tidl_info_s* g_proxy_tidl_info = NULL;
40
41 static vcd_widget_tidl_info_s* g_stub_tidl_info = NULL;
42
43 static pthread_mutex_t g_w_tidl_mutex = PTHREAD_MUTEX_INITIALIZER;
44 static pthread_mutex_t g_w_init_mutex = PTHREAD_MUTEX_INITIALIZER;
45
46 static rpc_port_stub_vc_widget_stub_vcd_widget_callback_s g_widget_callback;
47
48 extern int __vc_widget_cb_error(int reason, int daemon_pid, char* msg);
49
50 extern void __vc_widget_cb_show_tooltip(int pid, bool show);
51
52 extern void __vc_widget_cb_result();
53
54 extern bool __vc_widget_cb_asr_result(int event, const char* asr_result);
55
56 extern int __vc_widget_cb_service_state(int state);
57
58 static void __notify_cb(void *user_data, bundle *msg)
59 {
60         char* method = NULL;
61         char* val = NULL;
62         SLOG(LOG_DEBUG, TAG_VCW, "__notify_cb is invoked");
63
64         bundle_get_str(msg, VC_BUNDLE_METHOD, &method);
65
66         if (0 == strncmp(VCD_WIDGET_METHOD_HELLO, method, strlen(VCD_WIDGET_METHOD_HELLO))) {
67                 SLOG(LOG_INFO, TAG_VCW, "@@@ Get widget hello");
68                 bundle_get_str(msg, VC_BUNDLE_PID, &val);
69                 if (val) {
70                         SLOG(LOG_DEBUG, TAG_VCW, "@@ vc widget get hello : pid(%d) ", atoi(val));
71                 } else {
72                         SLOG(LOG_ERROR, TAG_VCW, "@@ vc widget get hello : invalid pid ");
73                 }
74         } /* VCD_METHOD_HELLO */
75
76         else if (0 == strncmp(VCD_METHOD_SET_SERVICE_STATE, method, strlen(VCD_METHOD_SET_SERVICE_STATE))) {
77                 bundle_get_str(msg, VC_BUNDLE_SERVICE_STATE, &val);
78                 int state = 0;
79                 if (val) {
80                         state = atoi(val);
81                         SLOG(LOG_INFO, TAG_VCW, "@@ service state changed : %d", state);
82                         __vc_widget_cb_service_state(state);
83                 }
84         } /* VCD_METHOD_SET_SERVICE_STATE */
85
86         else if (0 == strncmp(VCD_WIDGET_METHOD_SHOW_TOOLTIP, method, strlen(VCD_WIDGET_METHOD_SHOW_TOOLTIP))) {
87                 SLOG(LOG_DEBUG, TAG_VCW, "@@@ Show / Hide tooltip");
88                 char* temp_show = NULL;
89                 bundle_get_str(msg, VC_BUNDLE_PID, &val);
90                 bundle_get_str(msg, VC_BUNDLE_SHOW, &temp_show);
91                 int pid = 0;
92                 int show = 0;
93
94                 if (val) {
95                         pid = atoi(val);
96                 }
97                 if (temp_show) {
98                         show = atoi(temp_show);
99                 }
100
101                 if(pid > 0){
102                         SLOG(LOG_DEBUG, TAG_VCW, "@@ vc widget show tooltip : pid(%d), show(%d)", pid, show);
103                         __vc_widget_cb_show_tooltip(pid, (bool)show);
104                 } else {
105                         SLOG(LOG_ERROR, TAG_VCW, "@@ vc widget show tooltip : invalid pid");
106                 }
107         } /* VCD_WIDGET_METHOD_SHOW_TOOLTIP */
108
109         else if (0 == strncmp(VCD_WIDGET_METHOD_RESULT, method, strlen(VCD_WIDGET_METHOD_RESULT))) {
110                 SLOG(LOG_DEBUG, TAG_VCW, "@@@ Get widget result");
111
112                 __vc_widget_cb_result();
113         } /* VCD_WIDGET_METHOD_RESULT */
114
115         else if (0 == strncmp(VCD_WIDGET_METHOD_ERROR, method, strlen(VCD_WIDGET_METHOD_ERROR))) {
116                 SLOG(LOG_INFO, TAG_VCW, "@@@ Get Pre Result");
117                 char* temp_reason = NULL;
118                 char* temp_daemon_pid = NULL;
119                 char* err_msg = NULL;
120
121                 bundle_get_str(msg, VC_BUNDLE_REASON, &temp_reason);
122                 bundle_get_str(msg, VC_BUNDLE_DAEMON_PID, &temp_daemon_pid);
123                 bundle_get_str(msg, VC_BUNDLE_ERR_MSG, &err_msg);
124                 int reason = 0;
125                 int daemon_pid = 0;
126
127                 if (NULL != temp_reason) {
128                         reason = atoi(temp_reason);
129                 }
130                 if (NULL != temp_daemon_pid) {
131                         daemon_pid = atoi(temp_daemon_pid);
132                 }
133
134                 SLOG(LOG_DEBUG, TAG_VCW, "@@ vc widget get error message : reason(%d), daemon_pid(%d), msg(%s)", reason, daemon_pid, err_msg);
135                 __vc_widget_cb_error(reason, daemon_pid, err_msg);
136         } /* VCD_WIDGET_METHOD_ERROR */
137
138         else {
139                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid msg");
140         }
141
142         SLOG(LOG_DEBUG, TAG_VCW, "@@@ __notify_cb DONE");
143 }
144
145 static void __on_connected(rpc_port_proxy_vc_widget_proxy_vc_widget_h h, void *user_data)
146 {
147         RETM_IF(NULL == g_proxy_tidl_info, TAG_VCW, "[ERROR] Fail to get tidl info");
148
149         g_proxy_tidl_info->connected = true;
150         g_proxy_tidl_info->connection_requesting = false;
151         g_proxy_tidl_info->register_callback_invoked = false;
152
153         SLOG(LOG_INFO, TAG_VCW, "Connected to server");
154 }
155
156 static void __on_disconnected(rpc_port_proxy_vc_widget_proxy_vc_widget_h h, void *user_data)
157 {
158         RETM_IF(NULL == g_proxy_tidl_info, TAG_VCW, "[ERROR] Fail to get tidl info");
159
160         g_proxy_tidl_info->connected = false;
161         g_proxy_tidl_info->connection_requesting = false;
162         g_proxy_tidl_info->register_callback_invoked = false;
163
164         SLOG(LOG_INFO, TAG_VCW, "Disonnected to server");
165
166         __vc_widget_cb_error(VC_ERROR_SERVICE_RESET, -1, "Server Disconnected");
167 }
168
169 static void __on_rejected(rpc_port_proxy_vc_widget_proxy_vc_widget_h h, void *user_data)
170 {
171         RETM_IF(NULL == g_proxy_tidl_info, TAG_VCW, "[ERROR] Fail to get tidl info");
172
173         g_proxy_tidl_info->connection_requesting = false;
174         g_proxy_tidl_info->register_callback_invoked = false;
175
176         SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Rejected from server");
177 }
178
179
180 static rpc_port_proxy_vc_widget_proxy_vc_widget_h __create_rpc_port(const char* engine_app_id)
181 {
182         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] __create_rpc_port");
183         rpc_port_proxy_vc_widget_proxy_vc_widget_callback_s rpc_callback = {
184                 .connected = __on_connected,
185                 .disconnected = __on_disconnected,
186                 .rejected = __on_rejected
187         };
188
189         rpc_port_proxy_vc_widget_proxy_vc_widget_h handle = NULL;
190         if (0 != rpc_port_proxy_vc_widget_proxy_vc_widget_create(engine_app_id, &rpc_callback, NULL, &handle)) {
191                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Fail to create proxy");
192                 return NULL;
193         }
194
195         return handle;
196 }
197
198 static void __vcd_widget_create_cb(rpc_port_stub_vc_widget_stub_vcd_widget_context_h context, void *user_data)
199 {
200         RETM_IF(NULL == g_stub_tidl_info, TAG_VCW, "[ERROR] Fail to get tidl stub info");
201
202         g_stub_tidl_info->connected = true;
203         g_stub_tidl_info->register_callback_requesting = false;
204
205         SLOG(LOG_DEBUG, TAG_VCW, "Connected to server");
206
207         char *sender = NULL;
208
209         rpc_port_stub_vc_widget_stub_vcd_widget_context_get_sender(context, &sender);
210         if (!sender) {
211                 SLOG(LOG_ERROR, TAG_VCW, "@@@ Sender is NULL");
212                 return;
213         }
214
215         SLOG(LOG_DEBUG, TAG_VCW, "@@@ Server connect. appid(%s)", sender);
216         free(sender);
217 }
218
219 static void __vcd_widget_terminate_cb(rpc_port_stub_vc_widget_stub_vcd_widget_context_h context, void *user_data)
220 {
221         RETM_IF(NULL == g_stub_tidl_info, TAG_VCW, "[ERROR] Fail to get tidl stub info");
222
223         g_stub_tidl_info->connected = false;
224         g_stub_tidl_info->register_callback_requesting = false;
225
226         rpc_port_stub_vc_widget_stub_vcd_widget_context_set_tag(context, NULL);
227
228         char *sender = NULL;
229         rpc_port_stub_vc_widget_stub_vcd_widget_context_get_sender(context, &sender);
230         if (!sender)
231                 return;
232
233         SLOG(LOG_INFO, TAG_VCW, "@@@ Server disconnect. appid(%s)", sender);
234         free(sender);
235 }
236
237 static int __vcd_widget_asr_result_cb(rpc_port_stub_vc_widget_stub_vcd_widget_context_h context, int pid, int event, const char *asr_result, bool *is_consumed, void *user_data)
238 {
239         SLOG(LOG_DEBUG, TAG_VCW, "@@@ Get widget asr result");
240
241         bool result = false;
242         result = __vc_widget_cb_asr_result(event, asr_result);
243         *is_consumed = result;
244
245         return VC_ERROR_NONE;
246 }
247
248 static void __register_stub_callback()
249 {
250         RETM_IF(NULL == g_stub_tidl_info, TAG_VCW, "[TIDL ERROR] g_stub_tidl_info is not allocated");
251
252         if (g_stub_tidl_info->register_callback_requesting) {
253                 return;
254         }
255
256         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] __register_stub_callback");
257
258         g_widget_callback.create = __vcd_widget_create_cb;
259         g_widget_callback.terminate = __vcd_widget_terminate_cb;
260         g_widget_callback.send_asr_result = __vcd_widget_asr_result_cb;
261
262         int ret = -1;
263         ret = rpc_port_stub_vc_widget_stub_vcd_widget_register(&g_widget_callback, NULL);
264         if (0 == ret) {
265                 SLOG(LOG_DEBUG, TAG_VCW, "register callback");
266                 g_stub_tidl_info->register_callback_requesting = true;
267                 return;
268         }
269
270         SLOG(LOG_ERROR, TAG_VCW, "Fail to rister callback(%d)", ret);
271         return;
272 }
273
274 int vc_widget_tidl_open_connection()
275 {
276         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_open_connection");
277         pthread_mutex_lock(&g_w_tidl_mutex);
278
279         if (NULL != g_proxy_tidl_info) {
280                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] g_proxy_tidl_info already created");
281                 pthread_mutex_unlock(&g_w_tidl_mutex);
282                 return VC_ERROR_NONE;
283         }
284
285         g_proxy_tidl_info = (vc_widget_tidl_info_s*)calloc(1, sizeof(vc_widget_tidl_info_s));
286
287         if (NULL == g_proxy_tidl_info) {
288                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Fail to create vc_widget_tidl_info_s");
289                 pthread_mutex_unlock(&g_w_tidl_mutex);
290                 return VC_ERROR_OUT_OF_MEMORY;
291         }
292
293         char* engine_app_id = vconf_get_str(VC_ENGINE_DB_DEFAULT);
294         if (NULL == engine_app_id) {
295                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL] vconf not found");
296                 free(g_proxy_tidl_info);
297                 g_proxy_tidl_info = NULL;
298                 pthread_mutex_unlock(&g_w_tidl_mutex);
299                 return VC_ERROR_ENGINE_NOT_FOUND;
300         }
301
302         g_proxy_tidl_info->rpc_h = __create_rpc_port(engine_app_id);
303         if (NULL == g_proxy_tidl_info->rpc_h) {
304                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Fail to create proxy");
305                 free(engine_app_id);
306                 free(g_proxy_tidl_info);
307                 g_proxy_tidl_info = NULL;
308                 pthread_mutex_unlock(&g_w_tidl_mutex);
309                 return VC_ERROR_OPERATION_FAILED;
310         }
311
312         SLOG(LOG_INFO, TAG_VCW, "[TIDL] rpc_h(%p), engine_app_id(%s)", g_proxy_tidl_info->rpc_h, engine_app_id);
313         free(engine_app_id);
314
315         g_stub_tidl_info = (vcd_widget_tidl_info_s*)calloc(1, sizeof(vcd_widget_tidl_info_s));
316
317         if (NULL == g_stub_tidl_info) {
318                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Fail to create vcd_widget_tidl_info_s");
319                 pthread_mutex_unlock(&g_w_tidl_mutex);
320                 return VC_ERROR_OUT_OF_MEMORY;
321         }
322
323         __register_stub_callback();
324
325         pthread_mutex_unlock(&g_w_tidl_mutex);
326
327         return VC_ERROR_NONE;
328 }
329
330 int vc_widget_tidl_close_connection()
331 {
332         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_close_connection");
333         pthread_mutex_lock(&g_w_tidl_mutex);
334
335         if (NULL == g_proxy_tidl_info) {
336                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
337                 pthread_mutex_unlock(&g_w_tidl_mutex);
338                 return VC_ERROR_OPERATION_FAILED;
339         }
340
341         if (0 != rpc_port_proxy_vc_widget_proxy_vc_widget_destroy(g_proxy_tidl_info->rpc_h)) {
342                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Fail to destroy tidl handle");
343                 pthread_mutex_unlock(&g_w_tidl_mutex);
344                 return VC_ERROR_OPERATION_FAILED;
345         }
346
347         g_proxy_tidl_info->rpc_h = NULL;
348         g_proxy_tidl_info->notify_cb_h = NULL;
349
350         free(g_proxy_tidl_info);
351         g_proxy_tidl_info = NULL;
352
353         if (0 != rpc_port_stub_vc_widget_stub_vcd_widget_unregister()) {
354                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Fail to unregister stub");
355                 pthread_mutex_unlock(&g_w_tidl_mutex);
356                 return VC_ERROR_OPERATION_FAILED;
357         }
358
359         free(g_stub_tidl_info);
360         g_stub_tidl_info = NULL;
361
362         pthread_mutex_unlock(&g_w_tidl_mutex);
363
364         return VC_ERROR_NONE;
365 }
366
367 static int __convert_unhandled_error(int ret)
368 {
369         if (RPC_PORT_ERROR_IO_ERROR == ret || RPC_PORT_ERROR_OUT_OF_MEMORY == ret) {
370                 return VC_ERROR_OPERATION_FAILED;
371         }
372
373         return ret;
374 }
375
376 static void __request_tidl_connect()
377 {
378         if (g_proxy_tidl_info->connection_requesting) {
379                 return;
380         }
381
382         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_connect(g_proxy_tidl_info->rpc_h);
383         SLOG(LOG_INFO, TAG_VCW, "[INFO] Request connection to stub. ret(%d)", ret);
384
385         if (0 == ret) {
386                 g_proxy_tidl_info->connection_requesting = true;
387         }
388 }
389
390 static int __create_callback_handles()
391 {
392         if (NULL != g_proxy_tidl_info->notify_cb_h) {
393                 rpc_port_proxy_vc_widget_proxy_vc_widget_notify_cb_dispose(g_proxy_tidl_info->rpc_h, g_proxy_tidl_info->notify_cb_h);
394                 g_proxy_tidl_info->notify_cb_h = NULL;
395         }
396
397         if (RPC_PORT_ERROR_NONE != rpc_port_proxy_vc_widget_proxy_vc_widget_notify_cb_create(&g_proxy_tidl_info->notify_cb_h)) {
398                 return VC_ERROR_OUT_OF_MEMORY;
399         }
400
401         rpc_port_proxy_vc_widget_proxy_vc_widget_notify_cb_set_callback(g_proxy_tidl_info->notify_cb_h, __notify_cb, NULL);
402
403         rpc_port_proxy_vc_widget_proxy_vc_widget_notify_cb_set_once(g_proxy_tidl_info->notify_cb_h, false);
404
405         return VC_ERROR_NONE;
406 }
407
408 static int __invoke_register_callback()
409 {
410         if (g_proxy_tidl_info->register_callback_invoked) {
411                 SLOG(LOG_ERROR, TAG_VCW, "[INFO] Already register callback is invoked");
412                 return VC_ERROR_NONE;
413         }
414
415         int ret = __create_callback_handles(g_proxy_tidl_info);
416         if (VC_ERROR_NONE != ret) {
417                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to create callback handle. ret(%d)", ret);
418                 return VC_ERROR_OPERATION_FAILED;
419         }
420
421         rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_register_cb(g_proxy_tidl_info->rpc_h, getpid(), g_proxy_tidl_info->notify_cb_h);
422         g_proxy_tidl_info->register_callback_invoked = true;
423         return VC_ERROR_NONE;
424 }
425
426 int vc_widget_tidl_request_hello()
427 {
428         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_hello");
429
430         if (NULL == g_proxy_tidl_info) {
431                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get proxy tidl info");
432                 return VC_ERROR_OPERATION_FAILED;
433         }
434
435         if (!g_proxy_tidl_info->connected) {
436                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Proxy Not Connected");
437                 __request_tidl_connect();
438                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Engine not loaded, sleep 500ms");
439                 usleep(500000);
440                 return VC_ERROR_OPERATION_FAILED;
441         }
442
443         if (VC_ERROR_NONE != __invoke_register_callback()) {
444                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to invoke register callback");
445                 return VC_ERROR_OPERATION_FAILED;
446         }
447
448         if (NULL == g_stub_tidl_info) {
449                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get stub tidl info");
450                 return VC_ERROR_OPERATION_FAILED;
451         }
452
453         if (!g_stub_tidl_info->connected) {
454                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Stub Not Connected");
455                 __register_stub_callback();
456                 return VC_ERROR_OPERATION_FAILED;
457         }
458
459         SLOG(LOG_DEBUG, TAG_VCW, ">>>>> VCW Hello");
460
461         SLOG(LOG_DEBUG, TAG_VCW, "<<<<");
462
463         return VC_ERROR_NONE;
464 }
465
466 int vc_widget_tidl_request_initialize(int pid, int* service_state, int* daemon_pid)
467 {
468         pthread_mutex_lock(&g_w_init_mutex);
469         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_initialize");
470
471         if (NULL == g_proxy_tidl_info) {
472                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
473                 pthread_mutex_unlock(&g_w_init_mutex);
474                 return VC_ERROR_OPERATION_FAILED;
475         }
476
477         int temp_service_state = 0;
478         int temp_daemon_pid = 0;
479         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_initialize(g_proxy_tidl_info->rpc_h, pid, &temp_service_state, &temp_daemon_pid);
480         int exception = get_last_result();
481         if (RPC_PORT_ERROR_NONE != exception) {
482                 ret = __convert_unhandled_error(exception);
483         }
484
485         if (VC_ERROR_NONE != ret) {
486                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget initialize : Fail to invoke message, error(%d)", ret);
487                 pthread_mutex_unlock(&g_w_init_mutex);
488                 return ret;
489         }
490
491         *service_state = temp_service_state;
492         *daemon_pid = temp_daemon_pid;
493
494         pthread_mutex_unlock(&g_w_init_mutex);
495         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc widget initialize: service_state(%d), daemon_pid(%d)", *service_state, *daemon_pid);
496
497         return VC_ERROR_NONE;
498 }
499
500 int vc_widget_tidl_request_finalize(int pid)
501 {
502         pthread_mutex_lock(&g_w_init_mutex);
503         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_finalize");
504
505         if (NULL == g_proxy_tidl_info) {
506                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
507                 pthread_mutex_unlock(&g_w_init_mutex);
508                 return VC_ERROR_OPERATION_FAILED;
509         }
510
511         if (!g_proxy_tidl_info->connected) {
512                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
513                 pthread_mutex_unlock(&g_w_init_mutex);
514                 return VC_ERROR_OPERATION_FAILED;
515         }
516
517         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_finalize(g_proxy_tidl_info->rpc_h, pid);
518         int exception = get_last_result();
519         if (RPC_PORT_ERROR_NONE != exception) {
520                 ret = __convert_unhandled_error(exception);
521         }
522
523         if (VC_ERROR_NONE != ret) {
524                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget finalize : Fail to invoke finalize, error(%d)", ret);
525                 pthread_mutex_unlock(&g_w_init_mutex);
526                 return ret;
527         }
528
529         ret = rpc_port_proxy_vc_widget_proxy_vc_widget_disconnect(g_proxy_tidl_info->rpc_h);
530         exception = get_last_result();
531         if (RPC_PORT_ERROR_NONE != exception) {
532                 ret = __convert_unhandled_error(exception);
533         }
534
535         if (VC_ERROR_NONE != ret) {
536                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget finalize : Fail to disconnect, error(%d)", ret);
537                 pthread_mutex_unlock(&g_w_init_mutex);
538                 return ret;
539         }
540
541         pthread_mutex_unlock(&g_w_init_mutex);
542         return VC_ERROR_NONE;
543 }
544
545 int vc_widget_tidl_request_start_recording(int pid, bool command)
546 {
547         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_start_recording");
548
549         if (NULL == g_proxy_tidl_info) {
550                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
551                 return VC_ERROR_OPERATION_FAILED;
552         }
553
554         if (!g_proxy_tidl_info->connected) {
555                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
556                 return VC_ERROR_OPERATION_FAILED;
557         }
558
559         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_start_recording(g_proxy_tidl_info->rpc_h, pid, (int)command);
560         int exception = get_last_result();
561         if (RPC_PORT_ERROR_NONE != exception) {
562                 ret = __convert_unhandled_error(exception);
563         }
564
565         if (VC_ERROR_NONE != ret) {
566                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget start recording : Fail to invoke message, error(%d)", ret);
567                 return ret;
568         }
569
570         return VC_ERROR_NONE;
571 }
572
573 int vc_widget_tidl_set_foreground(int pid, bool value)
574 {
575         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_set_foreground");
576
577         if (NULL == g_proxy_tidl_info) {
578                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
579                 return VC_ERROR_OPERATION_FAILED;
580         }
581
582         if (!g_proxy_tidl_info->connected) {
583                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
584                 return VC_ERROR_OPERATION_FAILED;
585         }
586
587         // TODO: Error tolerance cannot be applied because this function is asynchronous.
588         rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_set_foreground(g_proxy_tidl_info->rpc_h, pid, (int)value);
589
590         return VC_ERROR_NONE;
591 }
592
593 int vc_widget_tidl_request_enable_asr_result(int pid, bool enable)
594 {
595         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_enable_asr_result");
596
597         if (NULL == g_proxy_tidl_info) {
598                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
599                 return VC_ERROR_OPERATION_FAILED;
600         }
601
602         if (!g_proxy_tidl_info->connected) {
603                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
604                 return VC_ERROR_OPERATION_FAILED;
605         }
606
607         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_enable_asr_result(g_proxy_tidl_info->rpc_h, pid, (int)enable);
608         int exception = get_last_result();
609         if (RPC_PORT_ERROR_NONE != exception) {
610                 ret = __convert_unhandled_error(exception);
611         }
612
613         if (VC_ERROR_NONE != ret) {
614                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget enable asr result : Fail to invoke message, error(%d)", ret);
615                 return ret;
616         }
617
618         return VC_ERROR_NONE;
619 }
620
621 int vc_widget_tidl_request_start(int pid, int silence)
622 {
623         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_start");
624
625         if (NULL == g_proxy_tidl_info) {
626                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
627                 return VC_ERROR_OPERATION_FAILED;
628         }
629
630         if (!g_proxy_tidl_info->connected) {
631                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
632                 return VC_ERROR_OPERATION_FAILED;
633         }
634
635         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_start(g_proxy_tidl_info->rpc_h, pid, silence);
636         int exception = get_last_result();
637         if (RPC_PORT_ERROR_NONE != exception) {
638                 ret = __convert_unhandled_error(exception);
639         }
640
641         if (VC_ERROR_NONE != ret) {
642                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget start : Fail to invoke message, error(%d)", ret);
643                 return ret;
644         }
645
646         return VC_ERROR_NONE;
647 }
648
649 int vc_widget_tidl_request_stop(int pid)
650 {
651         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_stop");
652
653         if (NULL == g_proxy_tidl_info) {
654                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
655                 return VC_ERROR_OPERATION_FAILED;
656         }
657
658         if (!g_proxy_tidl_info->connected) {
659                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
660                 return VC_ERROR_OPERATION_FAILED;
661         }
662
663         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_stop(g_proxy_tidl_info->rpc_h, pid);
664         int exception = get_last_result();
665         if (RPC_PORT_ERROR_NONE != exception) {
666                 ret = __convert_unhandled_error(exception);
667         }
668
669         if (VC_ERROR_NONE != ret) {
670                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget stop : Fail to invoke message, error(%d)", ret);
671                 return ret;
672         }
673
674         return VC_ERROR_NONE;
675 }
676
677 int vc_widget_tidl_request_cancel(int pid)
678 {
679         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_cancel");
680
681         if (NULL == g_proxy_tidl_info) {
682                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
683                 return VC_ERROR_OPERATION_FAILED;
684         }
685
686         if (!g_proxy_tidl_info->connected) {
687                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
688                 return VC_ERROR_OPERATION_FAILED;
689         }
690
691         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_cancel(g_proxy_tidl_info->rpc_h, pid);
692         int exception = get_last_result();
693         if (RPC_PORT_ERROR_NONE != exception) {
694                 ret = __convert_unhandled_error(exception);
695         }
696
697         if (VC_ERROR_NONE != ret) {
698                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget cancel : Fail to invoke message, error(%d)", ret);
699                 return ret;
700         }
701
702         return VC_ERROR_NONE;
703 }