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;
28 static hand_gesture_recognition_cb g_callback;
29 static hand_gesture_data_h g_gesture_data;
31 static hand_gesture_handtype_e g_hand_type = HAND_GESTURE_LEFT_HAND;
32 static hand_gesture_workmode_e g_work_mode = HAND_GESTURE_WORK_MODE_ONE_WAY;
33 static hand_gesture_option_e g_option = HAND_GESTURE_OPTION_DEFAULT;
34 static int g_sensitivity = 1;
36 static char *g_engine_app_id;
37 static char *g_engine_name;
39 static void _free_gesture_data(hand_gesture_data_h gesture_data)
45 static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data)
47 LOGD("name : %s, name_owner : %s", name, name_owner);
50 static void _server_vanished_cb(GDBusConnection *connection, const gchar *name, gpointer user_data)
52 LOGD("name : %s", name);
55 static int _dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id)
59 if (*gdbus_connection == NULL) {
60 GDBusConnection *conn = NULL;
61 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
64 LOGE("g_bus_get_sync error message = %s", error->message);
67 return HAND_GESTURE_ERROR_OPERATION_FAILED;
69 *gdbus_connection = conn;
72 LOGD("Connected bus name : %s", g_dbus_connection_get_unique_name(*gdbus_connection));
73 if (*server_watcher_id == 0) {
74 *server_watcher_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
76 G_BUS_NAME_WATCHER_FLAGS_NONE,
82 LOGD("server_watcher_id : %d", *server_watcher_id);
83 if (*server_watcher_id == 0) {
84 LOGE("Failed to get identifier");
85 return HAND_GESTURE_ERROR_OPERATION_FAILED;
88 return HAND_GESTURE_ERROR_NONE;
92 static void _handle_gesture_cb(GDBusConnection *connection,
93 const gchar *sender_name,
94 const gchar *object_path,
95 const gchar *interface_name,
96 const gchar *signal_name,
100 LOGD("own_name : %s, signal_name : %s", g_dbus_connection_get_unique_name(connection), signal_name);
101 hand_gesture_h _handle = (hand_gesture_h)user_data;
103 if (_handle == NULL) {
104 LOGE("handle is not available");
108 if (parameters == NULL) {
109 LOGE("failed to get gesture info");
113 if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_RESULT) == 0) {
114 LOGD("[GESTURE_CLIENT_SIGNAL_GET_RESULT] called");
120 g_variant_get(parameters, "(iiiii)", &event, &gesture_type, <ype, &levent, &lcount);
122 char *printmsg = g_variant_print(parameters, true);
123 LOGD("start parameter print : %s", printmsg);
125 LOGD("[event = %d] [gesture_type = %d] [ltype = %d] [levent = %d] [lcount = %d]", event, gesture_type, ltype, levent, lcount);
127 if (g_gesture_data == NULL){
128 LOGD("Can't send the result to Client because g_gesture_data is NULL");
131 LOGD("address = %p", g_gesture_data);
132 g_gesture_data->gesture_type = ltype;
133 g_gesture_data->event = levent;
134 g_gesture_data->detected_Count = lcount;
136 // g_callback(gesture_type, g_gesture_data, 0, HAND_GESTURE_ERROR_NONE, user_data);
137 if (_handle->recog_cb) {
138 LOGD("[CLIENT DBUS] Send recognition result. gesture_type(%d)", gesture_type);
139 _handle->recog_cb(_handle, gesture_type, 0, HAND_GESTURE_ERROR_NONE, _handle->recog_user_data);
142 else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_ERROR) == 0) {
144 char* err_msg = NULL;
145 g_variant_get(parameters, "(is)", &error, err_msg);
146 LOGD("[CLIENT DBUS] error(%d)", error);
148 if (_handle->error_cb) {
149 LOGD("[CLIENT DBUS] Send error");
150 _handle->error_cb(_handle, (hand_gesture_error_e)error, err_msg, _handle->error_user_data);
152 LOGW("[CLIENT DBUS] There is no error callback");
155 else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_MOTION_STATUS) == 0) {
158 else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_ENGINE_INFO) == 0) {
159 g_variant_get(parameters, "(ss)", &g_engine_app_id, &g_engine_name);
161 char *printmsg = g_variant_print(parameters, true);
162 LOGD("[engineInfo]start parameter print : %s", printmsg);
164 LOGE("[engineInfo][g_engine_app_id = %s] [g_engine_name = %s]", g_engine_app_id, g_engine_name);
170 static int _dbus_signal_init(GDBusConnection *gdbus_connection, int *monitor_id, CLIENT_LIB lib, void *data)
172 int ret = HAND_GESTURE_ERROR_NONE;
173 if (*monitor_id == 0) {
175 if (lib == GESTURE_CLIENT_LIB_GESTURE) {
176 id = g_dbus_connection_signal_subscribe(gdbus_connection,
178 GESTURE_CLIENT_INTERFACE_NAME,
182 G_DBUS_SIGNAL_FLAGS_NONE,
186 } else if (lib == GESTURE_CLIENT_LIB_ENGINE) {
187 LOGD("Fail to come for ENGINE lib");
189 LOGD("Fail to Not CLIENT lib");
194 ret = HAND_GESTURE_ERROR_OPERATION_FAILED;
195 LOGE("g_dbus_connection_signal_subscribe() failed");
204 static GDBusMessage *gdbus_make_message(GVariant *body, const char *cmd)
206 LOGD("gdbus_make_message : cmd = %s", cmd);
207 GDBusMessage *message = NULL;
208 message = g_dbus_message_new_method_call(
211 GESTURE_INTERFACE_NAME,
215 LOGE("Failed to create a new gdbus message");
217 g_variant_unref(body);
222 g_dbus_message_set_body(message, body);
227 static int _send_message_with_sync(GDBusConnection *gdbus_connection, GDBusMessage *msg, GDBusMessage **reply, const char *cmd)
229 LOGD("_send_message_with_sync : cmd = %s", cmd);
230 int ret = HAND_GESTURE_ERROR_NONE;
233 gchar *printmsg = g_dbus_message_print (msg, 1);
234 LOGD("[sync] before send to server, print : %s", printmsg);
237 *reply = g_dbus_connection_send_message_with_reply_sync(
240 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
247 ret = HAND_GESTURE_ERROR_OPERATION_FAILED;
249 LOGE("Error occurred when sending message(%s) : %s", cmd, err->message);
250 if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
251 ret = HAND_GESTURE_ERROR_PERMISSION_DENIED;
257 if (g_dbus_message_to_gerror(*reply, &err)) {
258 LOGE("error message = %s, code = %d", err->message, err->code);
259 if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
260 ret = HAND_GESTURE_ERROR_PERMISSION_DENIED;
267 printmsg = g_dbus_message_print (*reply, 1);
268 LOGD("[sync] reply from server, print : %s", printmsg);
271 GVariant *result = NULL;
272 result = g_dbus_message_get_body(*reply);
273 if (result != NULL) {
274 printmsg = g_variant_print(result, true);
275 LOGD("Result msg print : %s", printmsg);
279 return HAND_GESTURE_ERROR_NONE;
282 static int gdbus_send_message_with_sync(GDBusConnection *gdbus_connection, GVariant *body, GDBusMessage **reply, char *cmd)
284 LOGD("gdbus_send_message_with_sync start : cmd = %s", cmd);
286 int ret = HAND_GESTURE_ERROR_NONE;
287 GDBusMessage *msg = NULL;
289 msg = gdbus_make_message(body, cmd);
291 return HAND_GESTURE_ERROR_OPERATION_FAILED;
293 ret = _send_message_with_sync(gdbus_connection, msg, reply, cmd);
301 static void _async_cb(GDBusConnection *connection, GAsyncResult *res, gpointer user_data)
303 LOGD("_async_cb start");
304 GDBusMessage *reply = NULL;
306 // hand_gesture_data_h gesturedata = (hand_gesture_data_h)user_data;
308 reply = g_dbus_connection_send_message_with_reply_finish(connection, res, &err);
310 if (g_dbus_message_to_gerror(reply, &err)) {
311 LOGE("error message = %s, code = %d", err->message, err->code);
316 GVariant *result = g_dbus_message_get_body(reply);
317 gchar *printmsg = g_variant_print (result, true);
318 LOGD("[async] _async_cb, print : %s", printmsg);
323 LOGE("There is no reply");
328 g_object_unref(reply);
333 static int gdbus_send_message_with_async(GDBusConnection *gdbus_connection, GVariant *body, char *cmd, hand_gesture_data_h gesture_data)
335 LOGD("gdbus_send_message_with_async start : cmd = %s", cmd);
336 int ret = HAND_GESTURE_ERROR_NONE;
337 GDBusMessage *msg = NULL;
339 msg = gdbus_make_message(body, cmd);
341 return HAND_GESTURE_ERROR_OPERATION_FAILED;
343 g_dbus_connection_send_message_with_reply(
346 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
350 (GAsyncReadyCallback)_async_cb,
359 static int _monitor_register(GDBusConnection *gdbus_connection)
362 GDBusMessage *reply = NULL;
363 GVariant *client_body = NULL;
365 char appid[1024] = {0, };
366 ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
368 LOGE("aul_app_get_appid_bypid() failed : %d", ret);
371 client_body = g_variant_new("(iis)", 11, GESTURE_CLIENT_LIB_GESTURE, appid);
373 ret = gdbus_send_message_with_sync(gdbus_connection, client_body, &reply, GESTURE_MSG_SERVICE_REGISTER);
375 g_object_unref(reply);
378 g_variant_unref(client_body);
380 if (ret != HAND_GESTURE_ERROR_NONE) {
381 LOGE("gdbus_send_message_with_sync() failed : %d", ret);
385 is_server_started = 1;
389 static void _on_name_appeared(GDBusConnection *connection,
391 const gchar *name_owner,
394 if (is_server_started == 0)
395 _monitor_register(connection);
398 static void _on_name_vanished(GDBusConnection *connection,
402 is_server_started = 0;
405 int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id,
406 int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data)
408 LOGD("gesture_client_dbus_init start");
412 ret = _dbus_init(gdbus_connection, server_watcher_id);
413 if (ret != HAND_GESTURE_ERROR_NONE) {
414 LOGE("_dbus_init() failed : %d", ret);
418 ret = _dbus_signal_init(*gdbus_connection, monitor_id, lib, data);
419 if (ret != HAND_GESTURE_ERROR_NONE) {
420 LOGE("_dbus_signal_init() failed : %d", ret);
424 ret = _monitor_register(*gdbus_connection);
425 if (ret != HAND_GESTURE_ERROR_NONE) {
426 LOGE("_monitor_register() failed : %d", ret);
430 if (*server_monitor_id == 0) {
431 *server_monitor_id = g_bus_watch_name_on_connection(
434 G_BUS_NAME_WATCHER_FLAGS_NONE,
439 if (*server_monitor_id == 0) {
440 g_dbus_connection_signal_unsubscribe(*gdbus_connection, *monitor_id);
442 LOGE("Failed to get identifier");
443 return HAND_GESTURE_ERROR_OPERATION_FAILED;
447 return HAND_GESTURE_ERROR_NONE;
450 int gesture_client_dbus_shutdown(GDBusConnection *gdbus_connection, int *server_monitor_id, int *monitor_id)
452 if (*server_monitor_id) {
453 g_bus_unwatch_name(*server_monitor_id);
454 *server_monitor_id = 0;
458 g_dbus_connection_signal_unsubscribe(gdbus_connection, *monitor_id);
462 return HAND_GESTURE_ERROR_NONE;
465 int gesture_client_dbus_initialize_engine(GDBusConnection *gdbus_connection)
468 GDBusMessage *reply = NULL;
469 GVariant *body = NULL;
471 body = g_variant_new("()");
472 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_INITIALIZE_ENGINE);
473 if (ret != HAND_GESTURE_ERROR_NONE)
474 LOGE("failed to initialize");
477 g_variant_unref(body);
480 g_object_unref(reply);
486 int gesture_client_dbus_deinitialize_engine(GDBusConnection *gdbus_connection)
489 GDBusMessage *reply = NULL;
490 GVariant *body = NULL;
492 body = g_variant_new("()");
493 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_DEINITIALIZE_ENGINE);
494 if (ret != HAND_GESTURE_ERROR_NONE)
495 LOGE("failed to deinitialize");
498 g_variant_unref(body);
501 g_object_unref(reply);
507 int gesture_client_dbus_set_handtype(GDBusConnection *gdbus_connection, hand_gesture_handtype_e hand_type)
509 int ret = HAND_GESTURE_ERROR_NONE;
510 if (hand_type > HAND_GESTURE_RIGHT_HAND || hand_type < HAND_GESTURE_NO_SELECTED_HAND) {
511 LOGE("Invalid Parmeter");
512 return HAND_GESTURE_ERROR_INVALID_PARAMETER;
514 g_hand_type = hand_type;
519 int gesture_client_dbus_set_workmode(GDBusConnection *gdbus_connection, hand_gesture_workmode_e work_mode)
521 int ret = HAND_GESTURE_ERROR_NONE;
522 if (work_mode > HAND_GESTURE_WORK_MODE_UNDEFINED || work_mode < HAND_GESTURE_WORK_MODE_ONE_WAY) {
523 LOGE("Invalid Parmeter");
524 return HAND_GESTURE_ERROR_INVALID_PARAMETER;
526 g_work_mode = work_mode;
531 int gesture_client_dbus_set_option(GDBusConnection *gdbus_connection, hand_gesture_option_e option)
533 int ret = HAND_GESTURE_ERROR_NONE;
534 if (option > HAND_GESTURE_OPTION_ALWAYS_ON || option < HAND_GESTURE_OPTION_DEFAULT) {
535 LOGE("Invalid Parmeter");
536 return HAND_GESTURE_ERROR_INVALID_PARAMETER;
543 int gesture_client_dbus_set_sensitivity(GDBusConnection *gdbus_connection, int sensitivity)
545 int ret = HAND_GESTURE_ERROR_NONE;
546 g_sensitivity = sensitivity;
551 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)
553 LOGD("gesture_client_dbus_start_recognition start");
554 LOGD("client busname: %s", g_dbus_connection_get_unique_name(gdbus_connection));
555 g_callback = callback;
556 g_gesture_data = gesture_data;
558 GVariant *body = NULL;
559 body = g_variant_new("(iiiii)", gesture_type, g_hand_type, g_work_mode, g_option, g_sensitivity);
561 gdbus_send_message_with_async(gdbus_connection, body, GESTURE_CLIENT_MSG_START_RECOGNITION, gesture_data);
564 g_variant_unref(body);
566 return HAND_GESTURE_ERROR_NONE;
569 int gesture_client_dbus_stop_recognition(GDBusConnection *gdbus_connection)
572 GDBusMessage *reply = NULL;
573 GVariant *body = NULL;
575 /* free for gesture data struct */
576 _free_gesture_data(g_gesture_data);
578 body = g_variant_new("()");
579 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_STOP_RECOGNITION);
580 if (ret != HAND_GESTURE_ERROR_NONE)
581 LOGE("failed to stop gesture");
584 g_variant_unref(body);
587 g_object_unref(reply);
593 int gesture_client_dbus_foreach_result_time(GDBusConnection *gdbus_connection)
596 GDBusMessage *reply = NULL;
597 GVariant *body = NULL;
599 body = g_variant_new("()");
600 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_FOREACH_RESULT_TIME);
601 if (ret != HAND_GESTURE_ERROR_NONE)
602 LOGE("failed to foreach_result_time");
605 g_variant_unref(body);
608 g_object_unref(reply);
614 int gesture_client_dbus_foreach_supported_type(GDBusConnection *gdbus_connection)
617 GDBusMessage *reply = NULL;
618 GVariant *body = NULL;
620 body = g_variant_new("()");
621 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_FOREACH_SUPPORTED_TYPE);
622 if (ret != HAND_GESTURE_ERROR_NONE)
623 LOGE("failed to foreach_supported_type");
626 g_variant_unref(body);
629 g_object_unref(reply);
635 int gesture_client_dbus_is_support_gesture_type(GDBusConnection *gdbus_connection, hand_gesture_type_e gesture, bool* supported)
638 GDBusMessage *reply = NULL;
639 GVariant *body = NULL;
641 body = g_variant_new("()");
642 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_IS_SUPPORT_GESTURE_TYPE);
643 if (ret != HAND_GESTURE_ERROR_NONE)
644 LOGE("failed to is_supported_gesture_type");
647 g_variant_unref(body);
650 g_object_unref(reply);
656 int gesture_client_dbus_get_engine_info(GDBusConnection *gdbus_connection, char** engine_app_id, char** engine_name)
659 GDBusMessage *reply = NULL;
660 GVariant *body = NULL;
661 g_engine_app_id = *engine_app_id;
662 g_engine_name = *engine_name;
664 body = g_variant_new("()");
665 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_ENGINE_GET_INFO);
666 if (ret != HAND_GESTURE_ERROR_NONE)
667 LOGE("failed to engine_get_info");
670 g_variant_unref(body);
673 g_object_unref(reply);