Fix tidl error handling codes
[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_WIDGET_METHOD_SET_SERVICE_STATE, method, strlen(VCD_WIDGET_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_WIDGET_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         g_proxy_tidl_info->connected = true;
148         g_proxy_tidl_info->connection_requesting = false;
149         g_proxy_tidl_info->register_callback_invoked = false;
150
151         SLOG(LOG_INFO, TAG_VCW, "Connected to server");
152 }
153
154 static void __on_disconnected(rpc_port_proxy_vc_widget_proxy_vc_widget_h h, void *user_data)
155 {
156         g_proxy_tidl_info->connected = false;
157         g_proxy_tidl_info->connection_requesting = false;
158         g_proxy_tidl_info->register_callback_invoked = false;
159
160         SLOG(LOG_INFO, TAG_VCW, "Disonnected to server");
161
162         SLOG(LOG_INFO, TAG_VCW, "Re-connection start");
163         __vc_widget_cb_error(VC_ERROR_SERVICE_RESET, -1, "Server Disconnected, re-launch");
164 }
165
166 static void __on_rejected(rpc_port_proxy_vc_widget_proxy_vc_widget_h h, void *user_data)
167 {
168         g_proxy_tidl_info->connection_requesting = false;
169         g_proxy_tidl_info->register_callback_invoked = false;
170
171         SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Rejected from server");
172 }
173
174
175 static rpc_port_proxy_vc_widget_proxy_vc_widget_h __create_rpc_port(const char* engine_app_id)
176 {
177         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] __create_rpc_port");
178         rpc_port_proxy_vc_widget_proxy_vc_widget_callback_s rpc_callback = {
179                 .connected = __on_connected,
180                 .disconnected = __on_disconnected,
181                 .rejected = __on_rejected
182         };
183
184         rpc_port_proxy_vc_widget_proxy_vc_widget_h handle = NULL;
185         if (0 != rpc_port_proxy_vc_widget_proxy_vc_widget_create(engine_app_id, &rpc_callback, NULL, &handle)) {
186                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Fail to create proxy");
187                 return NULL;
188         }
189
190         return handle;
191 }
192
193 static void __vcd_widget_create_cb(rpc_port_stub_vc_widget_stub_vcd_widget_context_h context, void *user_data)
194 {
195         g_stub_tidl_info->connected = true;
196         g_stub_tidl_info->register_callback_requesting = false;
197
198         SLOG(LOG_DEBUG, TAG_VCW, "Connected to server");
199
200         char *sender = NULL;
201
202         rpc_port_stub_vc_widget_stub_vcd_widget_context_get_sender(context, &sender);
203         if (!sender) {
204                 SLOG(LOG_ERROR, TAG_VCW, "@@@ Sender is NULL");
205                 return;
206         }
207
208         SLOG(LOG_DEBUG, TAG_VCW, "@@@ Server connect. appid(%s)", sender);
209         free(sender);
210 }
211
212 static void __vcd_widget_terminate_cb(rpc_port_stub_vc_widget_stub_vcd_widget_context_h context, void *user_data)
213 {
214         g_stub_tidl_info->connected = false;
215         g_stub_tidl_info->register_callback_requesting = false;
216
217         rpc_port_stub_vc_widget_stub_vcd_widget_context_set_tag(context, NULL);
218
219         char *sender = NULL;
220         rpc_port_stub_vc_widget_stub_vcd_widget_context_get_sender(context, &sender);
221         if (!sender)
222                 return;
223
224         SLOG(LOG_INFO, TAG_VCW, "@@@ Server disconnect. appid(%s)", sender);
225         free(sender);
226 }
227
228 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)
229 {
230         SLOG(LOG_DEBUG, TAG_VCW, "@@@ Get widget asr result");
231
232         bool result = false;
233         result = __vc_widget_cb_asr_result(event, asr_result);
234         *is_consumed = result;
235
236         return VC_ERROR_NONE;
237 }
238
239 static void __register_stub_callback()
240 {
241         if (g_stub_tidl_info->register_callback_requesting) {
242                 return;
243         }
244
245         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] __register_stub_callback");
246
247         g_widget_callback.create = __vcd_widget_create_cb;
248         g_widget_callback.terminate = __vcd_widget_terminate_cb;
249         g_widget_callback.send_asr_result = __vcd_widget_asr_result_cb;
250
251         int ret = -1;
252         ret = rpc_port_stub_vc_widget_stub_vcd_widget_register(&g_widget_callback, NULL);
253         if (0 == ret) {
254                 SLOG(LOG_DEBUG, TAG_VCW, "register callback");
255                 g_stub_tidl_info->register_callback_requesting = true;
256                 return;
257         }
258
259         SLOG(LOG_ERROR, TAG_VCW, "Fail to rister callback(%d)", ret);
260         return;
261 }
262
263 int vc_widget_tidl_open_connection()
264 {
265         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_open_connection");
266         pthread_mutex_lock(&g_w_tidl_mutex);
267
268         if (NULL != g_proxy_tidl_info) {
269                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] g_proxy_tidl_info already created");
270                 pthread_mutex_unlock(&g_w_tidl_mutex);
271                 return VC_ERROR_NONE;
272         }
273
274         g_proxy_tidl_info = (vc_widget_tidl_info_s*)calloc(1, sizeof(vc_widget_tidl_info_s));
275
276         if (NULL == g_proxy_tidl_info) {
277                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Fail to create vc_widget_tidl_info_s");
278                 pthread_mutex_unlock(&g_w_tidl_mutex);
279                 return VC_ERROR_OUT_OF_MEMORY;
280         }
281
282         char* engine_app_id = vconf_get_str(VC_ENGINE_DB_DEFAULT);
283         if (NULL == engine_app_id) {
284                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL] vconf not found");
285                 free(g_proxy_tidl_info);
286                 g_proxy_tidl_info = NULL;
287                 pthread_mutex_unlock(&g_w_tidl_mutex);
288                 return VC_ERROR_ENGINE_NOT_FOUND;
289         }
290
291         g_proxy_tidl_info->rpc_h = __create_rpc_port(engine_app_id);
292         if (NULL == g_proxy_tidl_info->rpc_h) {
293                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Fail to create proxy");
294                 free(engine_app_id);
295                 free(g_proxy_tidl_info);
296                 g_proxy_tidl_info = NULL;
297                 pthread_mutex_unlock(&g_w_tidl_mutex);
298                 return VC_ERROR_OPERATION_FAILED;
299         }
300
301         SLOG(LOG_INFO, TAG_VCW, "[TIDL] rpc_h(%p), engine_app_id(%s)", g_proxy_tidl_info->rpc_h, engine_app_id);
302         free(engine_app_id);
303
304         g_stub_tidl_info = (vcd_widget_tidl_info_s*)calloc(1, sizeof(vcd_widget_tidl_info_s));
305
306         if (NULL == g_stub_tidl_info) {
307                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Fail to create vcd_widget_tidl_info_s");
308                 pthread_mutex_unlock(&g_w_tidl_mutex);
309                 return VC_ERROR_OUT_OF_MEMORY;
310         }
311
312         __register_stub_callback();
313
314         pthread_mutex_unlock(&g_w_tidl_mutex);
315
316         return VC_ERROR_NONE;
317 }
318
319 int vc_widget_tidl_close_connection()
320 {
321         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_close_connection");
322         pthread_mutex_lock(&g_w_tidl_mutex);
323
324         if (NULL == g_proxy_tidl_info) {
325                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
326                 pthread_mutex_unlock(&g_w_tidl_mutex);
327                 return VC_ERROR_OPERATION_FAILED;
328         }
329
330         if (0 != rpc_port_proxy_vc_widget_proxy_vc_widget_destroy(g_proxy_tidl_info->rpc_h)) {
331                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Fail to destroy tidl handle");
332                 pthread_mutex_unlock(&g_w_tidl_mutex);
333                 return VC_ERROR_OPERATION_FAILED;
334         }
335
336         g_proxy_tidl_info->rpc_h = NULL;
337         g_proxy_tidl_info->notify_cb_h = NULL;
338
339         free(g_proxy_tidl_info);
340         g_proxy_tidl_info = NULL;
341
342         free(g_stub_tidl_info);
343         g_stub_tidl_info = NULL;
344
345         pthread_mutex_unlock(&g_w_tidl_mutex);
346
347         return VC_ERROR_NONE;
348 }
349
350 static int __convert_unhandled_error(int ret)
351 {
352         if (RPC_PORT_ERROR_IO_ERROR == ret || RPC_PORT_ERROR_OUT_OF_MEMORY == ret) {
353                 return VC_ERROR_OPERATION_FAILED;
354         }
355
356         return ret;
357 }
358
359 static void __request_tidl_connect()
360 {
361         if (g_proxy_tidl_info->connection_requesting) {
362                 return;
363         }
364
365         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_connect(g_proxy_tidl_info->rpc_h);
366         SLOG(LOG_INFO, TAG_VCW, "[INFO] Request connection to stub. ret(%d)", ret);
367
368         if (0 == ret) {
369                 g_proxy_tidl_info->connection_requesting = true;
370         }
371 }
372
373 static int __create_callback_handles()
374 {
375         if (NULL != g_proxy_tidl_info->notify_cb_h) {
376                 rpc_port_proxy_vc_widget_proxy_vc_widget_notify_cb_dispose(g_proxy_tidl_info->rpc_h, g_proxy_tidl_info->notify_cb_h);
377                 g_proxy_tidl_info->notify_cb_h = NULL;
378         }
379
380         if (RPC_PORT_ERROR_NONE != rpc_port_proxy_vc_widget_proxy_vc_widget_notify_cb_create(&g_proxy_tidl_info->notify_cb_h)) {
381                 return VC_ERROR_OUT_OF_MEMORY;
382         }
383
384         rpc_port_proxy_vc_widget_proxy_vc_widget_notify_cb_set_callback(g_proxy_tidl_info->notify_cb_h, __notify_cb, NULL);
385
386         rpc_port_proxy_vc_widget_proxy_vc_widget_notify_cb_set_once(g_proxy_tidl_info->notify_cb_h, false);
387
388         return VC_ERROR_NONE;
389 }
390
391 static int __invoke_register_callback()
392 {
393         if (g_proxy_tidl_info->register_callback_invoked) {
394                 SLOG(LOG_ERROR, TAG_VCW, "[INFO] Already register callback is invoked");
395                 return VC_ERROR_NONE;
396         }
397
398         int ret = __create_callback_handles(g_proxy_tidl_info);
399         if (VC_ERROR_NONE != ret) {
400                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to create callback handle. ret(%d)", ret);
401                 return VC_ERROR_OPERATION_FAILED;
402         }
403
404         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);
405         g_proxy_tidl_info->register_callback_invoked = true;
406         return VC_ERROR_NONE;
407 }
408
409 int vc_widget_tidl_request_hello()
410 {
411         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_hello");
412
413         if (NULL == g_proxy_tidl_info) {
414                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get proxy tidl info");
415                 return VC_ERROR_OPERATION_FAILED;
416         }
417
418         if (!g_proxy_tidl_info->connected) {
419                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Proxy Not Connected");
420                 __request_tidl_connect();
421                 return VC_ERROR_OPERATION_FAILED;
422         }
423
424         if (VC_ERROR_NONE != __invoke_register_callback()) {
425                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to invoke register callback");
426                 return VC_ERROR_OPERATION_FAILED;
427         }
428
429         if (NULL == g_stub_tidl_info) {
430                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get stub tidl info");
431                 return VC_ERROR_OPERATION_FAILED;
432         }
433
434         if (!g_stub_tidl_info->connected) {
435                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Stub Not Connected");
436                 __register_stub_callback();
437                 return VC_ERROR_OPERATION_FAILED;
438         }
439
440         SLOG(LOG_DEBUG, TAG_VCW, ">>>>> VCW Hello");
441
442         SLOG(LOG_DEBUG, TAG_VCW, "<<<<");
443
444         return VC_ERROR_NONE;
445 }
446
447 int vc_widget_tidl_request_initialize(int pid, int* service_state, int* daemon_pid)
448 {
449         pthread_mutex_lock(&g_w_init_mutex);
450         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_initialize");
451
452         if (NULL == g_proxy_tidl_info) {
453                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
454                 pthread_mutex_unlock(&g_w_init_mutex);
455                 return VC_ERROR_OPERATION_FAILED;
456         }
457
458         int temp_service_state = 0;
459         int temp_daemon_pid = 0;
460         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);
461         int exception = get_last_result();
462         if (RPC_PORT_ERROR_NONE != exception) {
463                 ret = __convert_unhandled_error(exception);
464         }
465
466         if (VC_ERROR_NONE != ret) {
467                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget initialize : Fail to invoke message, error(%d)", ret);
468                 pthread_mutex_unlock(&g_w_init_mutex);
469                 return ret;
470         }
471
472         *service_state = temp_service_state;
473         *daemon_pid = temp_daemon_pid;
474
475         pthread_mutex_unlock(&g_w_init_mutex);
476         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc widget initialize: service_state(%d), daemon_pid(%d)", *service_state, *daemon_pid);
477
478         return VC_ERROR_NONE;
479 }
480
481 int vc_widget_tidl_request_finalize(int pid)
482 {
483         pthread_mutex_lock(&g_w_init_mutex);
484         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_finalize");
485
486         if (NULL == g_proxy_tidl_info) {
487                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
488                 pthread_mutex_unlock(&g_w_init_mutex);
489                 return VC_ERROR_OPERATION_FAILED;
490         }
491
492         if (!g_proxy_tidl_info->connected) {
493                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
494                 pthread_mutex_unlock(&g_w_init_mutex);
495                 return VC_ERROR_OPERATION_FAILED;
496         }
497
498         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_finalize(g_proxy_tidl_info->rpc_h, pid);
499         int exception = get_last_result();
500         if (RPC_PORT_ERROR_NONE != exception) {
501                 ret = __convert_unhandled_error(exception);
502         }
503
504         if (VC_ERROR_NONE != ret) {
505                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget finalize : Fail to invoke message, error(%d)", ret);
506                 pthread_mutex_unlock(&g_w_init_mutex);
507                 return ret;
508         }
509
510         pthread_mutex_unlock(&g_w_init_mutex);
511         return VC_ERROR_NONE;
512 }
513
514 int vc_widget_tidl_request_start_recording(int pid, bool command)
515 {
516         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_start_recording");
517
518         if (NULL == g_proxy_tidl_info) {
519                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
520                 return VC_ERROR_OPERATION_FAILED;
521         }
522
523         if (!g_proxy_tidl_info->connected) {
524                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
525                 return VC_ERROR_OPERATION_FAILED;
526         }
527
528         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_start_recording(g_proxy_tidl_info->rpc_h, pid, (int)command);
529         int exception = get_last_result();
530         if (RPC_PORT_ERROR_NONE != exception) {
531                 ret = __convert_unhandled_error(exception);
532         }
533
534         if (VC_ERROR_NONE != ret) {
535                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget start recording : Fail to invoke message, error(%d)", ret);
536                 return ret;
537         }
538
539         return VC_ERROR_NONE;
540 }
541
542 int vc_widget_tidl_set_foreground(int pid, bool value)
543 {
544         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_set_foreground");
545
546         if (NULL == g_proxy_tidl_info) {
547                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
548                 return VC_ERROR_OPERATION_FAILED;
549         }
550
551         if (!g_proxy_tidl_info->connected) {
552                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
553                 return VC_ERROR_OPERATION_FAILED;
554         }
555
556         // TODO: Error tolerance cannot be applied because this function is asynchronous.
557         rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_set_foreground(g_proxy_tidl_info->rpc_h, pid, (int)value);
558
559         return VC_ERROR_NONE;
560 }
561
562 int vc_widget_tidl_request_enable_asr_result(int pid, bool enable)
563 {
564         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_enable_asr_result");
565
566         if (NULL == g_proxy_tidl_info) {
567                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
568                 return VC_ERROR_OPERATION_FAILED;
569         }
570
571         if (!g_proxy_tidl_info->connected) {
572                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
573                 return VC_ERROR_OPERATION_FAILED;
574         }
575
576         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_enable_asr_result(g_proxy_tidl_info->rpc_h, pid, (int)enable);
577         int exception = get_last_result();
578         if (RPC_PORT_ERROR_NONE != exception) {
579                 ret = __convert_unhandled_error(exception);
580         }
581
582         if (VC_ERROR_NONE != ret) {
583                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget enable asr result : Fail to invoke message, error(%d)", ret);
584                 return ret;
585         }
586
587         return VC_ERROR_NONE;
588 }
589
590 int vc_widget_tidl_request_start(int pid, int silence)
591 {
592         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_start");
593
594         if (NULL == g_proxy_tidl_info) {
595                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
596                 return VC_ERROR_OPERATION_FAILED;
597         }
598
599         if (!g_proxy_tidl_info->connected) {
600                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
601                 return VC_ERROR_OPERATION_FAILED;
602         }
603
604         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_start(g_proxy_tidl_info->rpc_h, pid, silence);
605         int exception = get_last_result();
606         if (RPC_PORT_ERROR_NONE != exception) {
607                 ret = __convert_unhandled_error(exception);
608         }
609
610         if (VC_ERROR_NONE != ret) {
611                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget start : Fail to invoke message, error(%d)", ret);
612                 return ret;
613         }
614
615         return VC_ERROR_NONE;
616 }
617
618 int vc_widget_tidl_request_stop(int pid)
619 {
620         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_stop");
621
622         if (NULL == g_proxy_tidl_info) {
623                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
624                 return VC_ERROR_OPERATION_FAILED;
625         }
626
627         if (!g_proxy_tidl_info->connected) {
628                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
629                 return VC_ERROR_OPERATION_FAILED;
630         }
631
632         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_stop(g_proxy_tidl_info->rpc_h, pid);
633         int exception = get_last_result();
634         if (RPC_PORT_ERROR_NONE != exception) {
635                 ret = __convert_unhandled_error(exception);
636         }
637
638         if (VC_ERROR_NONE != ret) {
639                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget stop : Fail to invoke message, error(%d)", ret);
640                 return ret;
641         }
642
643         return VC_ERROR_NONE;
644 }
645
646 int vc_widget_tidl_request_cancel(int pid)
647 {
648         SLOG(LOG_DEBUG, TAG_VCW, "[TIDL] vc_widget_tidl_request_cancel");
649
650         if (NULL == g_proxy_tidl_info) {
651                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get tidl info");
652                 return VC_ERROR_OPERATION_FAILED;
653         }
654
655         if (!g_proxy_tidl_info->connected) {
656                 SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Not Connected");
657                 return VC_ERROR_OPERATION_FAILED;
658         }
659
660         int ret = rpc_port_proxy_vc_widget_proxy_vc_widget_invoke_cancel(g_proxy_tidl_info->rpc_h, pid);
661         int exception = get_last_result();
662         if (RPC_PORT_ERROR_NONE != exception) {
663                 ret = __convert_unhandled_error(exception);
664         }
665
666         if (VC_ERROR_NONE != ret) {
667                 SLOG(LOG_ERROR, TAG_VCW, "[TIDL ERROR] Request vc widget cancel : Fail to invoke message, error(%d)", ret);
668                 return ret;
669         }
670
671         return VC_ERROR_NONE;
672 }