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_engine_dbus.h"
21 #include "gesture_engine_main.h"
26 #define LOG_TAG "GESTURE_ENGINE_DBUS"
28 static int is_server_started = 0;
29 static gesture_engine_request_callback_s g_basic_engine_callback;
30 static GDBusConnection *mgdbus_connection;
32 static int gdbus_send_message_with_async(GDBusConnection *gdbus_connection, GVariant *body, char *cmd);
34 static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data)
36 LOGD("name : %s, name_owner : %s", name, name_owner);
39 static void _server_vanished_cb(GDBusConnection *connection, const gchar *name, gpointer user_data)
41 LOGD("name : %s", name);
44 static int _dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id)
48 if (*gdbus_connection == NULL) {
49 GDBusConnection *conn = NULL;
50 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
53 LOGE("g_bus_get_sync error message = %s", error->message);
56 return GESTURE_ENGINE_ERROR_IO_ERROR;
58 *gdbus_connection = conn;
61 LOGD("Connected bus name : %s", g_dbus_connection_get_unique_name(*gdbus_connection));
62 if (*server_watcher_id == 0) {
63 *server_watcher_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
65 G_BUS_NAME_WATCHER_FLAGS_NONE,
71 LOGD("server_watcher_id : %d", *server_watcher_id);
72 if (*server_watcher_id == 0) {
73 LOGE("Failed to get identifier");
74 return GESTURE_ENGINE_ERROR_IO_ERROR;
77 return GESTURE_ENGINE_ERROR_NONE;
80 // callback the result data that received from engine service app.
81 // will pass this data to daemon
82 static void gesture_cb(hand_gesture_type_e gesture, const hand_gesture_data_h data, double timestamp, gesture_engine_error_e error, void *user_data)
85 LOGE("gesture cb data is NULL");
88 LOGD("gesture cb >> hand_gesture_type_e : %d", gesture);
89 LOGD("own_name : %s", g_dbus_connection_get_unique_name(mgdbus_connection));
90 gesture_engine_dbus_send_result(mgdbus_connection, GESTURE_ENGINE_RESULT_EVENT_FINAL_RESULT, gesture, data, NULL, user_data);
93 // called when daemon calls engine with g_dbus_connection_emit_signal.
94 // must send signal to the engine service app.
95 static void _handle_gesture_engine_cb(GDBusConnection *connection,
96 const gchar *sender_name,
97 const gchar *object_path,
98 const gchar *interface_name,
99 const gchar *signal_name,
100 GVariant *parameters,
104 LOGD("own_name : %s, sender_name : %s", g_dbus_connection_get_unique_name(connection), sender_name);
105 LOGD("object_path : %s, interface_name : %s", object_path, interface_name);
106 LOGD("signal_name : %s", signal_name);
107 char *printmsg = g_variant_print(parameters, true);
108 LOGD("_handle_gesture_engine_cb parameter print : %s", printmsg);
111 gesture_engine_h engine_handle = (gesture_engine_h)user_data;
113 if (engine_handle == NULL) {
114 LOGE("engine handle is not available");
118 if (parameters == NULL) {
119 LOGE("failed to get gesture info");
123 if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_ENGINE_INITIALIZE) == 0) {
124 LOGD("[engine_initialize] called");
125 g_basic_engine_callback.initialize();
127 else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_ENGINE_DEINITIALIZE) == 0) {
128 LOGD("[engine_deinitialize] called");
129 g_basic_engine_callback.deinitialize();
131 else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_ENGINE_START) == 0) {
132 LOGD("[GESTURE_ENGINE_SIGNAL_ENGINE_START] called");
133 int gesture_type = 1;
138 g_variant_get(parameters, "(iiiii)", &gesture_type, &hand_type, &work_mode, &option, &sensitivity);
139 g_basic_engine_callback.start(gesture_type, hand_type, work_mode, option, sensitivity, gesture_cb, NULL);
141 else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_ENGINE_STOP) == 0) {
142 LOGD("[GESTURE_ENGINE_SIGNAL_ENGINE_STOP] called");
143 g_basic_engine_callback.stop();
145 else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_FOREACH_RESULT_TIME) == 0) {
146 LOGD("[GESTURE_ENGINE_SIGNAL_FOREACH_RESULT_TIME] called");
147 g_basic_engine_callback.foreach_result_time(NULL, NULL, NULL);
149 else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_FOREACH_SUPPORTED_TYPE) == 0) {
150 LOGD("[GESTURE_ENGINE_SIGNAL_FOREACH_SUPPORTED_TYPE] called");
151 g_basic_engine_callback.foreach_types(NULL, NULL);
153 else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_IS_SUPPORT_GESTURE_TYPE) == 0) {
154 LOGD("[GESTURE_ENGINE_SIGNAL_IS_SUPPORT_GESTURE_TYPE] called");
156 int gesture_type = 0;
157 g_variant_get(parameters, "(ii)", &id, &gesture_type);
158 LOGD("Invocation ID(%d), Gesture Type(%d)", id, gesture_type);
160 bool is_supported = false;
161 g_basic_engine_callback.is_support_gesture_type(gesture_type, &is_supported);
162 GVariant* body = g_variant_new("(ib)", id, is_supported);
164 LOGE("Fail to create body");
168 LOGD("send message variant. ID(%d), Is supported(%d)", id, is_supported);
169 gdbus_send_message_with_async(connection, body, GESTURE_ENGINE_MSG_IS_SUPPORT_GESTURE_TYPE);
170 g_variant_unref(body);
172 else if (g_strcmp0(signal_name, GESTURE_ENGINE_SIGNAL_GET_ENGINE_INFO) == 0) {
173 LOGD("[GESTURE_ENGINE_SIGNAL_GET_ENGINE_INFO] called");
175 g_variant_get(parameters, "(i)", &id);
176 LOGD("Invocation ID(%d)", id);
178 char *engine_app_id = NULL;
179 char *engine_name = NULL;
180 g_basic_engine_callback.get_info(&engine_app_id, &engine_name);
181 if (NULL == engine_app_id || NULL == engine_name) {
182 LOGE("Fail to get engine information");
186 GVariant* body = g_variant_new("(iss)", id, engine_app_id, engine_name);
188 LOGE("Fail to create body");
192 LOGD("send message variant. APP ID(%s), Name(%s)", engine_app_id, engine_name);
193 gdbus_send_message_with_async(connection, body, GESTURE_ENGINE_MSG_GET_ENGINE_INFO);
194 g_variant_unref(body);
198 static int _dbus_signal_init(GDBusConnection *gdbus_connection, int *monitor_id, CLIENT_LIB lib, void *data)
200 int ret = GESTURE_ENGINE_ERROR_NONE;
201 if (*monitor_id == 0) {
203 if (lib == GESTURE_CLIENT_LIB_GESTURE)
204 LOGD("Fail to come for CLIENT lib");
205 else if (lib == GESTURE_CLIENT_LIB_ENGINE)
206 id = g_dbus_connection_signal_subscribe(gdbus_connection,
208 GESTURE_ENGINE_INTERFACE_NAME,
212 G_DBUS_SIGNAL_FLAGS_NONE,
213 _handle_gesture_engine_cb,
217 LOGD("Fail to Not come for Engine Lib");
221 ret = GESTURE_ENGINE_ERROR_IO_ERROR;
222 LOGE("g_dbus_connection_signal_subscribe() failed");
231 static GDBusMessage *gdbus_make_message(GVariant *body, const char *cmd)
233 LOGD("gdbus_make_message : cmd = %s", cmd);
234 GDBusMessage *message = NULL;
235 message = g_dbus_message_new_method_call(
238 GESTURE_INTERFACE_NAME,
242 LOGE("Failed to create a new gdbus message");
244 g_variant_unref(body);
249 g_dbus_message_set_body(message, body);
254 static int _send_message_with_sync(GDBusConnection *gdbus_connection, GDBusMessage *msg, GDBusMessage **reply, const char *cmd)
256 LOGD("_send_message_with_sync : cmd = %s", cmd);
257 int ret = GESTURE_ENGINE_ERROR_NONE;
260 gchar *printmsg = g_dbus_message_print (msg, 1);
261 LOGD("[sync] before send to server, print : %s", printmsg);
264 *reply = g_dbus_connection_send_message_with_reply_sync(
267 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
274 ret = GESTURE_ENGINE_ERROR_SERVICE_NOT_READY;
276 LOGE("Error occurred when sending message(%s) : %s", cmd, err->message);
277 if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
278 ret = GESTURE_ENGINE_ERROR_PERMISSION_DENIED;
284 if (g_dbus_message_to_gerror(*reply, &err)) {
285 LOGE("error message = %s, code = %d", err->message, err->code);
286 if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
287 ret = GESTURE_ENGINE_ERROR_PERMISSION_DENIED;
294 printmsg = g_dbus_message_print (*reply, 1);
295 LOGD("[sync] reply from server, print : %s", printmsg);
298 GVariant *result = NULL;
299 result = g_dbus_message_get_body(*reply);
300 if (result != NULL) {
301 printmsg = g_variant_print(result, true);
302 LOGD("Result msg print : %s", printmsg);
306 return GESTURE_ENGINE_ERROR_NONE;
309 static int gdbus_send_message_with_sync(GDBusConnection *gdbus_connection, GVariant *body, GDBusMessage **reply, char *cmd)
311 LOGD("gdbus_send_message_with_sync start : cmd = %s", cmd);
313 int ret = GESTURE_ENGINE_ERROR_NONE;
314 GDBusMessage *msg = NULL;
316 msg = gdbus_make_message(body, cmd);
318 return GESTURE_ENGINE_ERROR_IO_ERROR;
320 ret = _send_message_with_sync(gdbus_connection, msg, reply, cmd);
328 static void _async_cb(GDBusConnection *connection, GAsyncResult *res, gpointer user_data)
330 LOGD("_async_cb start");
331 GDBusMessage *reply = NULL;
334 reply = g_dbus_connection_send_message_with_reply_finish(connection, res, &err);
336 if (g_dbus_message_to_gerror(reply, &err)) {
337 LOGE("error message = %s, code = %d", err->message, err->code);
342 GVariant *result = g_dbus_message_get_body(reply);
344 gchar *printmsg = g_variant_print (result, true);
345 LOGD("[async] _async_cb, print : %s", printmsg);
348 LOGD("[async] result is null");
353 LOGE("There is no reply");
358 g_object_unref(reply);
363 static int gdbus_send_message_with_async(GDBusConnection *gdbus_connection, GVariant *body, char *cmd)
365 LOGD("gdbus_send_message_with_async start : cmd = %s", cmd);
366 int ret = GESTURE_ENGINE_ERROR_NONE;
367 GDBusMessage *msg = NULL;
369 msg = gdbus_make_message(body, cmd);
371 return GESTURE_ENGINE_ERROR_OPERATION_FAILED;
373 g_dbus_connection_send_message_with_reply(
376 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
380 (GAsyncReadyCallback)_async_cb,
389 static int _monitor_register(GDBusConnection *gdbus_connection)
391 int ret = GESTURE_ENGINE_ERROR_NONE;
392 GDBusMessage *reply = NULL;
393 GVariant *engine_body = NULL;
395 char appid[1024] = {0, };
396 ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
398 LOGE("aul_app_get_appid_bypid() failed : %d", ret);
399 return GESTURE_ENGINE_ERROR_OPERATION_FAILED;
402 engine_body = g_variant_new("(iisiss)", 22, GESTURE_CLIENT_LIB_ENGINE, appid, getpid(), "NULL", "NULL");
404 ret = gdbus_send_message_with_sync(gdbus_connection, engine_body, &reply, GESTURE_MSG_SERVICE_REGISTER);
406 g_object_unref(reply);
409 g_variant_unref(engine_body);
411 if (ret != GESTURE_ENGINE_ERROR_NONE) {
412 LOGE("gdbus_send_message_with_sync() failed : %d", ret);
416 is_server_started = 1;
420 static void _on_name_appeared(GDBusConnection *connection,
422 const gchar *name_owner,
425 if (is_server_started == 0)
426 _monitor_register(connection);
429 static void _on_name_vanished(GDBusConnection *connection,
433 is_server_started = 0;
436 int gesture_engine_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id,
437 int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data)
439 LOGD("gesture_dbus_init start");
443 ret = _dbus_init(gdbus_connection, server_watcher_id);
444 if (ret != GESTURE_ENGINE_ERROR_NONE) {
445 LOGE("_dbus_init() failed : %d", ret);
449 ret = _dbus_signal_init(*gdbus_connection, monitor_id, lib, data);
450 if (ret != GESTURE_ENGINE_ERROR_NONE) {
451 LOGE("_dbus_signal_init() failed : %d", ret);
455 ret = _monitor_register(*gdbus_connection);
456 if (ret != GESTURE_ENGINE_ERROR_NONE) {
457 LOGE("_monitor_register() failed : %d", ret);
461 if (*server_monitor_id == 0) {
462 *server_monitor_id = g_bus_watch_name_on_connection(
465 G_BUS_NAME_WATCHER_FLAGS_NONE,
470 if (*server_monitor_id == 0) {
471 g_dbus_connection_signal_unsubscribe(*gdbus_connection, *monitor_id);
473 LOGE("Failed to get identifier");
474 return GESTURE_ENGINE_ERROR_IO_ERROR;
478 return GESTURE_ENGINE_ERROR_NONE;
481 int gesture_engine_dbus_shutdown(GDBusConnection *gdbus_connection, int *server_monitor_id, int *monitor_id)
483 if (*server_monitor_id) {
484 g_bus_unwatch_name(*server_monitor_id);
485 *server_monitor_id = 0;
489 g_dbus_connection_signal_unsubscribe(gdbus_connection, *monitor_id);
493 return GESTURE_ENGINE_ERROR_NONE;
496 static void proxy_new_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
498 LOGD("proxy_new_cb clled");
500 GDBusProxy **ret = user_data;
501 GError *error = NULL;
502 *ret = g_dbus_proxy_new_finish (res, &error);
506 int gesture_engine_dbus_main_start(GDBusConnection *gdbus_connection, gesture_engine_request_callback_s *callback)
508 LOGD("gesture_engine_dbus_main_start start");
509 LOGD("engine busname: %s", g_dbus_connection_get_unique_name(gdbus_connection));
510 mgdbus_connection = gdbus_connection;
512 int ret = GESTURE_ENGINE_ERROR_NONE;
514 // store engine callback sturct;
515 g_basic_engine_callback = *callback;
517 GVariant *body = NULL;
518 body = g_variant_new("(i)", 100);
520 ret = gdbus_send_message_with_async(gdbus_connection, body, GESTURE_ENGINE_MSG_MAIN_START);
523 g_variant_unref(body);
528 int gesture_engine_dbus_send_result(GDBusConnection *gdbus_connection, gesture_engine_result_event_e event, hand_gesture_type_e gesture_type, hand_gesture_data_h result, void* time_info, void* user_data)
530 LOGD("gesture_engine_dbus_send_result start");
531 if (gesture_type) LOGD("gesture_type = %d", gesture_type);
533 int ret = GESTURE_ENGINE_ERROR_NONE;
535 GDBusMessage *reply = NULL;
536 GVariant *body = NULL;
539 LOGD("The returned hand_gesture_data_h is NULL");
540 return GESTURE_ENGINE_ERROR_OPERATION_FAILED;
543 body = g_variant_new("(iiiii)", event, gesture_type, result->gesture_type, result->event, result->detected_Count);
544 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_ENGINE_MSG_SEND_RESULT);
545 if (ret != GESTURE_ENGINE_ERROR_NONE) {
546 LOGD("Fail to send result data to daemon");
549 gchar *msg = g_dbus_message_print (reply, 1);
550 LOGD("Reply msg print : %s", msg);
555 g_variant_unref(body);
558 g_object_unref(reply);
563 int gesture_engine_dbus_send_error(GDBusConnection *gdbus_connection, gesture_engine_error_e error, const char* msg)
565 LOGE("gesture_engine_dbus_send_error start");
567 int ret = GESTURE_ENGINE_ERROR_NONE;
569 GDBusMessage *reply = NULL;
570 GVariant *body = NULL;
572 body = g_variant_new("(is)", error, msg);
574 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_ENGINE_MSG_SEND_ERROR);
576 if (ret == GESTURE_ENGINE_ERROR_NONE) {
577 gchar *msg = g_dbus_message_print (reply, 1);
578 LOGD("Reply msg print : %s", msg);
583 g_variant_unref(body);
586 g_object_unref(reply);
591 int gesture_engine_dbus_send_motion_status(GDBusConnection *gdbus_connection, gesture_engine_motion_status_e status, void* user_data)
593 LOGE("gesture_engine_dbus_send_motion_status start");
595 int ret = GESTURE_ENGINE_ERROR_NONE;
597 GDBusMessage *reply = NULL;
598 GVariant *body = NULL;
600 body = g_variant_new("(i)", status);
602 ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_ENGINE_MSG_SEND_MOTION_STATUS);
604 if (ret == GESTURE_ENGINE_ERROR_NONE) {
605 gchar *msg = g_dbus_message_print (reply, 1);
606 LOGD("Reply msg print : %s", msg);
611 g_variant_unref(body);
614 g_object_unref(reply);
619 int gesture_engine_dbus_send_engine_get_info(GDBusConnection *gdbus_connection, char* engine_app_id, char* engine_name)
621 LOGD("gesture_engine_send_engine_get_info start");
622 if (engine_app_id) LOGD("engine_app_id = %s", engine_app_id);
624 int ret = GESTURE_ENGINE_ERROR_NONE;
626 GDBusMessage *reply = NULL;
627 GVariant *body = NULL;
629 body = g_variant_new("(ss)", engine_app_id, engine_name);
630 ret = gdbus_send_message_with_sync(mgdbus_connection, body, &reply, GESTURE_ENGINE_MSG_GET_ENGINE_INFO);
631 if (ret != GESTURE_ENGINE_ERROR_NONE) {
632 LOGE("Fail to send result data to daemon");
635 gchar *msg = g_dbus_message_print (reply, 1);
636 LOGD("Reply msg print : %s", msg);
641 g_variant_unref(body);
644 g_object_unref(reply);