2 * Copyright (c) 2020 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.
20 #include "gesture_client_dbus.h"
25 #define LOG_TAG "GESTURE_CLIENT_DBUS"
27 static int is_server_started = 0;
29 static hand_gesture_handtype_e g_hand_type = HAND_GESTURE_LEFT_HAND;
30 static hand_gesture_workmode_e g_work_mode = HAND_GESTURE_WORK_MODE_ONE_WAY;
31 static hand_gesture_option_e g_option = HAND_GESTURE_OPTION_DEFAULT;
32 static int g_sensitivity = 1;
34 static char *g_engine_app_id;
35 static char *g_engine_name;
38 static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data)
40 LOGD("name : %s, name_owner : %s", name, name_owner);
43 static void _server_vanished_cb(GDBusConnection *connection, const gchar *name, gpointer user_data)
45 LOGD("name : %s", name);
48 static int _dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id)
52 if (*gdbus_connection == NULL) {
53 GDBusConnection *conn = NULL;
54 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
57 LOGE("g_bus_get_sync error message = %s", error->message);
60 return HAND_GESTURE_ERROR_OPERATION_FAILED;
62 *gdbus_connection = conn;
65 LOGD("Connected bus name : %s", g_dbus_connection_get_unique_name(*gdbus_connection));
66 if (*server_watcher_id == 0) {
67 *server_watcher_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
69 G_BUS_NAME_WATCHER_FLAGS_NONE,
75 LOGD("server_watcher_id : %d", *server_watcher_id);
76 if (*server_watcher_id == 0) {
77 LOGE("Failed to get identifier");
78 return HAND_GESTURE_ERROR_OPERATION_FAILED;
81 return HAND_GESTURE_ERROR_NONE;
85 static void _handle_gesture_cb(GDBusConnection *connection,
86 const gchar *sender_name,
87 const gchar *object_path,
88 const gchar *interface_name,
89 const gchar *signal_name,
93 LOGD("own_name : %s, signal_name : %s", g_dbus_connection_get_unique_name(connection), signal_name);
94 hand_gesture_h _handle = (hand_gesture_h)user_data;
96 if (_handle == NULL) {
97 LOGE("handle is not available");
101 if (parameters == NULL) {
102 LOGE("failed to get gesture info");
106 if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_RESULT) == 0) {
107 LOGD("[GESTURE_CLIENT_SIGNAL_GET_RESULT] called");
113 g_variant_get(parameters, "(iiiii)", &event, &gesture_type, <ype, &levent, &lcount);
115 char *printmsg = g_variant_print(parameters, true);
116 LOGD("start parameter print : %s", printmsg);
118 LOGD("[event = %d] [gesture_type = %d] [ltype = %d] [levent = %d] [lcount = %d]", event, gesture_type, ltype, levent, lcount);
120 if (_handle->recog_cb) {
121 LOGD("[CLIENT DBUS] Send recognition result. gesture_type(%d)", gesture_type);
122 _handle->recog_cb(_handle, gesture_type, 0, HAND_GESTURE_ERROR_NONE, _handle->recog_user_data);
125 else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_ERROR) == 0) {
127 char* err_msg = NULL;
128 g_variant_get(parameters, "(is)", &error, err_msg);
129 LOGD("[CLIENT DBUS] error(%d)", error);
131 if (_handle->error_cb) {
132 LOGD("[CLIENT DBUS] Send error");
133 _handle->error_cb(_handle, (hand_gesture_error_e)error, err_msg, _handle->error_user_data);
135 LOGW("[CLIENT DBUS] There is no error callback");
138 else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_MOTION_STATUS) == 0) {
141 else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_ENGINE_INFO) == 0) {
142 g_variant_get(parameters, "(ss)", &g_engine_app_id, &g_engine_name);
144 char *printmsg = g_variant_print(parameters, true);
145 LOGD("[engineInfo]start parameter print : %s", printmsg);
147 LOGE("[engineInfo][g_engine_app_id = %s] [g_engine_name = %s]", g_engine_app_id, g_engine_name);
153 static int _dbus_signal_init(GDBusConnection *gdbus_connection, int *monitor_id, CLIENT_LIB lib, void *data)
155 int ret = HAND_GESTURE_ERROR_NONE;
156 if (*monitor_id == 0) {
158 if (lib == GESTURE_CLIENT_LIB_GESTURE) {
159 id = g_dbus_connection_signal_subscribe(gdbus_connection,
161 GESTURE_CLIENT_INTERFACE_NAME,
165 G_DBUS_SIGNAL_FLAGS_NONE,
169 } else if (lib == GESTURE_CLIENT_LIB_ENGINE) {
170 LOGD("Fail to come for ENGINE lib");
172 LOGD("Fail to Not CLIENT lib");
177 ret = HAND_GESTURE_ERROR_OPERATION_FAILED;
178 LOGE("g_dbus_connection_signal_subscribe() failed");
187 static GDBusMessage *gdbus_make_message(GVariant *body, const char *cmd)
189 LOGD("gdbus_make_message : cmd = %s", cmd);
190 GDBusMessage *message = NULL;
191 message = g_dbus_message_new_method_call(
194 GESTURE_INTERFACE_NAME,
198 LOGE("Failed to create a new gdbus message");
200 g_variant_unref(body);
205 g_dbus_message_set_body(message, body);
210 static int _send_message_with_sync(GDBusConnection *gdbus_connection, GDBusMessage *msg, GDBusMessage **reply, const char *cmd)
212 LOGD("_send_message_with_sync : cmd = %s", cmd);
213 int ret = HAND_GESTURE_ERROR_NONE;
216 gchar *printmsg = g_dbus_message_print (msg, 1);
217 LOGD("[sync] before send to server, print : %s", printmsg);
220 *reply = g_dbus_connection_send_message_with_reply_sync(
223 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
230 ret = HAND_GESTURE_ERROR_OPERATION_FAILED;
232 LOGE("Error occurred when sending message(%s) : %s", cmd, err->message);
233 if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
234 ret = HAND_GESTURE_ERROR_PERMISSION_DENIED;
240 if (g_dbus_message_to_gerror(*reply, &err)) {
241 LOGE("error message = %s, code = %d", err->message, err->code);
242 if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
243 ret = HAND_GESTURE_ERROR_PERMISSION_DENIED;
250 printmsg = g_dbus_message_print (*reply, 1);
251 LOGD("[sync] reply from server, print : %s", printmsg);
254 GVariant *result = NULL;
255 result = g_dbus_message_get_body(*reply);
256 if (result != NULL) {
257 printmsg = g_variant_print(result, true);
258 LOGD("Result msg print : %s", printmsg);
262 return HAND_GESTURE_ERROR_NONE;
265 static int gdbus_send_message_with_sync(GDBusConnection *gdbus_connection, GVariant *body, GDBusMessage **reply, char *cmd)
267 LOGD("gdbus_send_message_with_sync start : cmd = %s", cmd);
269 int ret = HAND_GESTURE_ERROR_NONE;
270 GDBusMessage *msg = NULL;
272 msg = gdbus_make_message(body, cmd);
274 return HAND_GESTURE_ERROR_OPERATION_FAILED;
276 ret = _send_message_with_sync(gdbus_connection, msg, reply, cmd);
284 static void _async_cb(GDBusConnection *connection, GAsyncResult *res, gpointer user_data)
286 LOGD("_async_cb start");
287 GDBusMessage *reply = NULL;
289 // hand_gesture_data_h gesturedata = (hand_gesture_data_h)user_data;
291 reply = g_dbus_connection_send_message_with_reply_finish(connection, res, &err);
293 if (g_dbus_message_to_gerror(reply, &err)) {
294 LOGE("error message = %s, code = %d", err->message, err->code);
299 GVariant *result = g_dbus_message_get_body(reply);
300 gchar *printmsg = g_variant_print (result, true);
301 LOGD("[async] _async_cb, print : %s", printmsg);
306 LOGE("There is no reply");
311 g_object_unref(reply);
316 static int gdbus_send_message_with_async(GDBusConnection *gdbus_connection, GVariant *body, char *cmd, hand_gesture_data_h gesture_data)
318 LOGD("gdbus_send_message_with_async start : cmd = %s", cmd);
319 int ret = HAND_GESTURE_ERROR_NONE;
320 GDBusMessage *msg = NULL;
322 msg = gdbus_make_message(body, cmd);
324 return HAND_GESTURE_ERROR_OPERATION_FAILED;
326 g_dbus_connection_send_message_with_reply(
329 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
333 (GAsyncReadyCallback)_async_cb,
342 static int _monitor_register(GDBusConnection *gdbus_connection, const char *uid, const char *smack_label)
345 GDBusMessage *reply = NULL;
346 GVariant *client_body = NULL;
348 char appid[1024] = {0, };
350 ret = aul_app_get_appid_bypid(pid, appid, sizeof(appid));
352 LOGE("aul_app_get_appid_bypid() failed : %d", ret);
355 LOGI("[INFO] appid(%s), pid(%d), uid(%s), smack_label(%s)", appid, pid, uid, smack_label);
357 client_body = g_variant_new("(iisiss)", 11, GESTURE_CLIENT_LIB_GESTURE, appid, pid, uid, smack_label);
359 ret = gdbus_send_message_with_sync(gdbus_connection, client_body, &reply, GESTURE_MSG_SERVICE_REGISTER);
361 g_object_unref(reply);
364 g_variant_unref(client_body);
366 if (ret != HAND_GESTURE_ERROR_NONE) {
367 LOGE("gdbus_send_message_with_sync() failed : %d", ret);
371 is_server_started = 1;
375 static void _on_name_appeared(GDBusConnection *connection,
377 const gchar *name_owner,
380 struct hand_gesture_s *_struct = user_data;
382 if (is_server_started == 0) {
383 LOGI("uid(%s), smack_label(%s)", _struct->uid, _struct->smack_label);
384 _monitor_register(connection, _struct->uid, _struct->smack_label);
388 static void _on_name_vanished(GDBusConnection *connection,
392 is_server_started = 0;
395 int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id,
396 int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, const char *uid, const char *smack_label, void *data)
398 LOGD("gesture_client_dbus_init start");
402 ret = _dbus_init(gdbus_connection, server_watcher_id);
403 if (ret != HAND_GESTURE_ERROR_NONE) {
404 LOGE("_dbus_init() failed : %d", ret);
408 ret = _dbus_signal_init(*gdbus_connection, monitor_id, lib, data);
409 if (ret != HAND_GESTURE_ERROR_NONE) {
410 LOGE("_dbus_signal_init() failed : %d", ret);
414 ret = _monitor_register(*gdbus_connection, uid, smack_label);
415 if (ret != HAND_GESTURE_ERROR_NONE) {
416 LOGE("_monitor_register() failed : %d", ret);
420 if (*server_monitor_id == 0) {
421 *server_monitor_id = g_bus_watch_name_on_connection(
424 G_BUS_NAME_WATCHER_FLAGS_NONE,
429 if (*server_monitor_id == 0) {
430 g_dbus_connection_signal_unsubscribe(*gdbus_connection, *monitor_id);
432 LOGE("Failed to get identifier");
433 return HAND_GESTURE_ERROR_OPERATION_FAILED;
437 return HAND_GESTURE_ERROR_NONE;
440 int gesture_client_dbus_shutdown(GDBusConnection *gdbus_connection, int *server_monitor_id, int *monitor_id)
442 if (*server_monitor_id) {
443 g_bus_unwatch_name(*server_monitor_id);
444 *server_monitor_id = 0;
448 g_dbus_connection_signal_unsubscribe(gdbus_connection, *monitor_id);
452 return HAND_GESTURE_ERROR_NONE;
455 int gesture_client_dbus_initialize_engine(GDBusConnection *gdbus_connection)
458 GDBusMessage *reply = NULL;
459 GVariant *body = NULL;
461 body = g_variant_new("()");
462 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_INITIALIZE_ENGINE);
463 if (ret != HAND_GESTURE_ERROR_NONE)
464 LOGE("failed to initialize");
467 g_variant_unref(body);
470 g_object_unref(reply);
476 int gesture_client_dbus_deinitialize_engine(GDBusConnection *gdbus_connection)
479 GDBusMessage *reply = NULL;
480 GVariant *body = NULL;
482 body = g_variant_new("()");
483 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_DEINITIALIZE_ENGINE);
484 if (ret != HAND_GESTURE_ERROR_NONE)
485 LOGE("failed to deinitialize");
488 g_variant_unref(body);
491 g_object_unref(reply);
497 int gesture_client_dbus_set_handtype(GDBusConnection *gdbus_connection, hand_gesture_handtype_e hand_type)
499 int ret = HAND_GESTURE_ERROR_NONE;
500 if (hand_type > HAND_GESTURE_RIGHT_HAND || hand_type < HAND_GESTURE_NO_SELECTED_HAND) {
501 LOGE("Invalid Parmeter");
502 return HAND_GESTURE_ERROR_INVALID_PARAMETER;
504 g_hand_type = hand_type;
509 int gesture_client_dbus_set_workmode(GDBusConnection *gdbus_connection, hand_gesture_workmode_e work_mode)
511 int ret = HAND_GESTURE_ERROR_NONE;
512 if (work_mode > HAND_GESTURE_WORK_MODE_UNDEFINED || work_mode < HAND_GESTURE_WORK_MODE_ONE_WAY) {
513 LOGE("Invalid Parmeter");
514 return HAND_GESTURE_ERROR_INVALID_PARAMETER;
516 g_work_mode = work_mode;
521 int gesture_client_dbus_set_option(GDBusConnection *gdbus_connection, hand_gesture_option_e option)
523 int ret = HAND_GESTURE_ERROR_NONE;
524 if (option > HAND_GESTURE_OPTION_ALWAYS_ON || option < HAND_GESTURE_OPTION_DEFAULT) {
525 LOGE("Invalid Parmeter");
526 return HAND_GESTURE_ERROR_INVALID_PARAMETER;
533 int gesture_client_dbus_set_sensitivity(GDBusConnection *gdbus_connection, int sensitivity)
535 int ret = HAND_GESTURE_ERROR_NONE;
536 g_sensitivity = sensitivity;
541 int gesture_client_dbus_start_recognition(GDBusConnection *gdbus_connection, hand_gesture_type_e gesture_type, hand_gesture_data_h gesture_data, hand_gesture_recognition_cb callback)
543 LOGD("gesture_client_dbus_start_recognition start");
544 LOGD("client busname: %s", g_dbus_connection_get_unique_name(gdbus_connection));
546 GVariant *body = NULL;
547 body = g_variant_new("(iiiii)", gesture_type, g_hand_type, g_work_mode, g_option, g_sensitivity);
549 gdbus_send_message_with_async(gdbus_connection, body, GESTURE_CLIENT_MSG_START_RECOGNITION, gesture_data);
552 g_variant_unref(body);
554 return HAND_GESTURE_ERROR_NONE;
557 int gesture_client_dbus_stop_recognition(GDBusConnection *gdbus_connection)
560 GDBusMessage *reply = NULL;
561 GVariant *body = NULL;
563 body = g_variant_new("()");
564 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_STOP_RECOGNITION);
565 if (ret != HAND_GESTURE_ERROR_NONE)
566 LOGE("failed to stop gesture");
569 g_variant_unref(body);
572 g_object_unref(reply);
578 int gesture_client_dbus_foreach_result_time(GDBusConnection *gdbus_connection)
581 GDBusMessage *reply = NULL;
582 GVariant *body = NULL;
584 body = g_variant_new("()");
585 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_FOREACH_RESULT_TIME);
586 if (ret != HAND_GESTURE_ERROR_NONE)
587 LOGE("failed to foreach_result_time");
590 g_variant_unref(body);
593 g_object_unref(reply);
599 int gesture_client_dbus_foreach_supported_type(GDBusConnection *gdbus_connection)
602 GDBusMessage *reply = NULL;
603 GVariant *body = NULL;
605 body = g_variant_new("()");
606 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_FOREACH_SUPPORTED_TYPE);
607 if (ret != HAND_GESTURE_ERROR_NONE)
608 LOGE("failed to foreach_supported_type");
611 g_variant_unref(body);
614 g_object_unref(reply);
620 int gesture_client_dbus_is_support_gesture_type(GDBusConnection *gdbus_connection, hand_gesture_type_e gesture, bool* supported)
623 GDBusMessage *reply = NULL;
624 GVariant *body = NULL;
626 body = g_variant_new("(i)", gesture);
627 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_IS_SUPPORT_GESTURE_TYPE);
628 if (ret != HAND_GESTURE_ERROR_NONE || NULL == reply) {
629 LOGE("failed to is_supported_gesture_type");
631 LOGD("Check reply from server");
632 GVariant *reply_body = g_dbus_message_get_body(reply);
633 if (NULL == reply_body) {
634 LOGE("There is no return value");
635 ret = HAND_GESTURE_ERROR_OPERATION_FAILED;
637 g_variant_get(reply_body, "(b)", supported);
638 LOGD("supported(%d)", *supported);
643 g_variant_unref(body);
646 g_object_unref(reply);
652 int gesture_client_dbus_get_engine_info(GDBusConnection *gdbus_connection, char** engine_app_id, char** engine_name)
655 GDBusMessage *reply = NULL;
656 GVariant *body = NULL;
658 body = g_variant_new("()");
659 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_ENGINE_GET_INFO);
660 if (ret != HAND_GESTURE_ERROR_NONE)
661 LOGE("Fail to send message");
663 GVariant *reply_body = g_dbus_message_get_body(reply);
664 if (NULL == reply_body) {
665 LOGE("There is no return value");
666 ret = HAND_GESTURE_ERROR_OPERATION_FAILED;
668 g_variant_get(reply_body, "(ss)", engine_app_id, engine_name);
669 if (NULL == engine_app_id || NULL == engine_name) {
670 LOGE("Fail to get engine info");
671 ret = HAND_GESTURE_ERROR_OPERATION_FAILED;
673 if (NULL != g_engine_app_id) {
674 free(g_engine_app_id);
677 if (NULL != g_engine_name) {
681 g_engine_app_id = *engine_app_id;
682 g_engine_name = *engine_name;
683 LOGD("APP ID(%s), Name(%s)", *engine_app_id, *engine_name);
688 g_variant_unref(body);
691 g_object_unref(reply);