[ACR-1585][gesture][Initial version of codes]
[platform/core/api/gesture.git] / client / gesture_client_dbus.c
1 /*
2  * Copyright (c) 2020 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 <dlog.h>
18 #include <aul.h>
19
20 #include "gesture_client_dbus.h"
21
22 #ifdef LOG_TAG
23 #undef LOG_TAG
24 #endif
25 #define LOG_TAG "GESTURE_CLIENT_DBUS"
26
27 static int is_server_started = 0;
28 static hand_gesture_recognition_cb g_callback;
29 static hand_gesture_data_h g_gesture_data;
30
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;
35
36 static char *g_engine_app_id;
37 static char *g_engine_name;
38
39 static void _free_gesture_data(hand_gesture_data_h gesture_data)
40 {
41         free(gesture_data);
42         gesture_data = NULL;
43 }
44
45 static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data)
46 {
47         LOGD("name : %s, name_owner : %s", name, name_owner);
48 }
49
50 static void _server_vanished_cb(GDBusConnection *connection, const gchar *name, gpointer user_data)
51 {
52         LOGD("name : %s", name);
53 }
54
55 static int _dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id)
56 {
57         GError *error = NULL;
58
59         if (*gdbus_connection == NULL) {
60                 GDBusConnection *conn = NULL;
61                 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
62                 if (conn == NULL) {
63                         if (error != NULL) {
64                                 LOGE("g_bus_get_sync error message = %s", error->message);
65                                 g_error_free(error);
66                         }
67                         return HAND_GESTURE_ERROR_OPERATION_FAILED;
68                 }
69                 *gdbus_connection = conn;
70         }
71
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,
75                         GESTURE_DBUS_NAME,
76                         G_BUS_NAME_WATCHER_FLAGS_NONE,
77                         _server_appeared_cb,
78                         _server_vanished_cb,
79                         NULL, NULL);
80         }
81
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;
86         }
87
88         return HAND_GESTURE_ERROR_NONE;
89 }
90
91
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,
97                                         GVariant *parameters,
98                                         gpointer user_data)
99 {
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;
102
103         if (_handle == NULL) {
104                 LOGE("handle is not available");
105                 return;
106         }
107
108         if (parameters == NULL) {
109                 LOGE("failed to get gesture info");
110                 return;
111         }
112
113         if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_RESULT) == 0) {
114                 LOGD("[GESTURE_CLIENT_SIGNAL_GET_RESULT] called");
115                 int event;
116                 int gesture_type;
117                 int ltype;
118                 int levent;
119                 int lcount;
120                 g_variant_get(parameters, "(iiiii)", &event, &gesture_type, &ltype, &levent, &lcount);
121 #if 0
122                 char *printmsg = g_variant_print(parameters, true);
123                 LOGD("start parameter print : %s", printmsg);
124                 g_free(printmsg);
125                 LOGD("[event = %d] [gesture_type = %d] [ltype = %d] [levent = %d] [lcount = %d]", event, gesture_type, ltype, levent, lcount);
126 #endif
127                 if (g_gesture_data == NULL){
128                         LOGD("Can't send the result to Client because g_gesture_data is NULL");
129                         return;
130                 }
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;
135
136                 g_callback(gesture_type, g_gesture_data, 0, HAND_GESTURE_ERROR_NONE, user_data);
137         }
138         else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_ERROR) == 0) {
139
140         }
141         else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_MOTION_STATUS) == 0) {
142
143         }
144         else if (g_strcmp0(signal_name, GESTURE_CLIENT_SIGNAL_GET_ENGINE_INFO) == 0) {
145                 g_variant_get(parameters, "(ss)", &g_engine_app_id, &g_engine_name);
146 #if 1
147                 char *printmsg = g_variant_print(parameters, true);
148                 LOGD("[engineInfo]start parameter print : %s", printmsg);
149                 g_free(printmsg);
150                 LOGE("[engineInfo][g_engine_app_id = %s] [g_engine_name = %s]", g_engine_app_id, g_engine_name);
151 #endif
152
153         }
154 }
155
156 static int _dbus_signal_init(GDBusConnection *gdbus_connection, int *monitor_id, CLIENT_LIB lib, void *data)
157 {
158         int ret = HAND_GESTURE_ERROR_NONE;
159         if (*monitor_id == 0) {
160                 int id = 0;
161                 if (lib == GESTURE_CLIENT_LIB_GESTURE) {
162                         id = g_dbus_connection_signal_subscribe(gdbus_connection,
163                                                         GESTURE_DBUS_NAME,
164                                                         GESTURE_CLIENT_INTERFACE_NAME,
165                                                         NULL,
166                                                         GESTURE_OBJECT_PATH,
167                                                         NULL,
168                                                         G_DBUS_SIGNAL_FLAGS_NONE,
169                                                         _handle_gesture_cb,
170                                                         data,
171                                                         NULL);
172                 } else if (lib == GESTURE_CLIENT_LIB_ENGINE) {
173                         LOGD("Fail to come for ENGINE lib");
174                 } else {
175                         LOGD("Fail to Not CLIENT lib");
176                 }
177
178                 LOGD("id : %d", id);
179                 if (id == 0) {
180                         ret = HAND_GESTURE_ERROR_OPERATION_FAILED;
181                         LOGE("g_dbus_connection_signal_subscribe() failed");
182                 } else {
183                         *monitor_id = id;
184                 }
185         }
186
187         return ret;
188 }
189
190 static GDBusMessage *gdbus_make_message(GVariant *body, const char *cmd)
191 {
192         LOGD("gdbus_make_message : cmd = %s", cmd);
193         GDBusMessage *message = NULL;
194         message = g_dbus_message_new_method_call(
195         GESTURE_DBUS_NAME,
196         GESTURE_OBJECT_PATH,
197         GESTURE_INTERFACE_NAME,
198         cmd);
199
200         if (!message) {
201                 LOGE("Failed to create a new gdbus message");
202                 if (body)
203                         g_variant_unref(body);
204                 return NULL;
205         }
206
207         if (body != NULL)
208                 g_dbus_message_set_body(message, body);
209
210         return message;
211 }
212
213 static int _send_message_with_sync(GDBusConnection *gdbus_connection, GDBusMessage *msg, GDBusMessage **reply, const char *cmd)
214 {
215         LOGD("_send_message_with_sync : cmd = %s", cmd);
216         int ret = HAND_GESTURE_ERROR_NONE;
217         GError *err = NULL;
218
219         gchar *printmsg = g_dbus_message_print (msg, 1);
220         LOGD("[sync] before send to server, print : %s", printmsg);
221         g_free(printmsg);
222
223         *reply = g_dbus_connection_send_message_with_reply_sync(
224                                         gdbus_connection,
225                                         msg,
226                                         G_DBUS_SEND_MESSAGE_FLAGS_NONE,
227                                         -1,
228                                         NULL,
229                                         NULL,
230                                         &err);
231
232         if (!*reply) {
233                 ret = HAND_GESTURE_ERROR_OPERATION_FAILED;
234                 if (err != NULL) {
235                         LOGE("Error occurred when sending message(%s) : %s", cmd, err->message);
236                         if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
237                                 ret = HAND_GESTURE_ERROR_PERMISSION_DENIED;
238                         g_error_free(err);
239                 }
240                 return ret;
241         }
242
243         if (g_dbus_message_to_gerror(*reply, &err)) {
244                 LOGE("error message = %s, code = %d", err->message, err->code);
245                 if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
246                         ret = HAND_GESTURE_ERROR_PERMISSION_DENIED;
247                 else
248                         ret = err->code;
249                 g_error_free(err);
250                 return ret;
251         }
252 #if 0
253         printmsg = g_dbus_message_print (*reply, 1);
254         LOGD("[sync] reply from server, print : %s", printmsg);
255         g_free(printmsg);
256
257         GVariant *result = NULL;
258         result = g_dbus_message_get_body(*reply);
259         if (result != NULL) {
260                 printmsg = g_variant_print(result, true);
261                 LOGD("Result msg print : %s", printmsg);
262                 g_free(printmsg);
263         }
264 #endif
265         return HAND_GESTURE_ERROR_NONE;
266 }
267
268 static int gdbus_send_message_with_sync(GDBusConnection *gdbus_connection, GVariant *body, GDBusMessage **reply, char *cmd)
269 {
270         LOGD("gdbus_send_message_with_sync start : cmd = %s", cmd);
271
272         int ret = HAND_GESTURE_ERROR_NONE;
273         GDBusMessage *msg = NULL;
274
275         msg = gdbus_make_message(body, cmd);
276         if (msg == NULL)
277                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
278
279         ret = _send_message_with_sync(gdbus_connection, msg, reply, cmd);
280
281         if (msg)
282                 g_object_unref(msg);
283
284         return ret;
285 }
286
287 static void _async_cb(GDBusConnection *connection, GAsyncResult *res, gpointer user_data)
288 {
289         LOGD("_async_cb start");
290         GDBusMessage *reply = NULL;
291         GError *err = NULL;
292 //      hand_gesture_data_h gesturedata = (hand_gesture_data_h)user_data;
293
294         reply = g_dbus_connection_send_message_with_reply_finish(connection, res, &err);
295         if (reply) {
296                 if (g_dbus_message_to_gerror(reply, &err)) {
297                         LOGE("error message = %s, code = %d", err->message, err->code);
298                         g_error_free(err);
299                         return;
300                 }
301 #if 0
302                 GVariant *result = g_dbus_message_get_body(reply);
303                 gchar *printmsg = g_variant_print (result, true);
304                 LOGD("[async] _async_cb, print : %s", printmsg);
305                 g_free(printmsg);
306 #endif
307
308         } else {
309                 LOGE("There is no reply");
310                 return;
311         }
312
313         if (reply)
314                 g_object_unref(reply);
315
316         return;
317 }
318
319 static int gdbus_send_message_with_async(GDBusConnection *gdbus_connection, GVariant *body, char *cmd, hand_gesture_data_h gesture_data)
320 {
321         LOGD("gdbus_send_message_with_async start : cmd = %s", cmd);
322         int ret = HAND_GESTURE_ERROR_NONE;
323         GDBusMessage *msg = NULL;
324
325         msg = gdbus_make_message(body, cmd);
326         if (msg == NULL)
327                 return HAND_GESTURE_ERROR_OPERATION_FAILED;
328
329         g_dbus_connection_send_message_with_reply(
330                 gdbus_connection,
331                 msg,
332                 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
333                 -1,
334                 NULL,
335                 NULL,
336                 (GAsyncReadyCallback)_async_cb,
337                 gesture_data);
338
339         if (msg)
340                 g_object_unref(msg);
341
342         return ret;
343 }
344
345 static int _monitor_register(GDBusConnection *gdbus_connection)
346 {
347         int ret;
348         GDBusMessage *reply = NULL;
349         GVariant *client_body = NULL;
350
351         char appid[1024] = {0, };
352         ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
353         if (ret != 0) {
354                 LOGE("aul_app_get_appid_bypid() failed : %d", ret);
355         }
356
357         client_body = g_variant_new("(iis)", 11, GESTURE_CLIENT_LIB_GESTURE, appid);
358
359         ret = gdbus_send_message_with_sync(gdbus_connection, client_body, &reply, GESTURE_MSG_SERVICE_REGISTER);
360         if (reply)
361                 g_object_unref(reply);
362
363         if (client_body)
364                 g_variant_unref(client_body);
365
366         if (ret != HAND_GESTURE_ERROR_NONE) {
367                 LOGE("gdbus_send_message_with_sync() failed : %d", ret);
368                 return ret;
369         }
370
371         is_server_started = 1;
372         return ret;
373 }
374
375 static void _on_name_appeared(GDBusConnection *connection,
376                 const gchar     *name,
377                 const gchar     *name_owner,
378                 gpointer         user_data)
379 {
380         if (is_server_started == 0)
381         _monitor_register(connection);
382 }
383
384 static void _on_name_vanished(GDBusConnection *connection,
385                 const gchar     *name,
386                 gpointer         user_data)
387 {
388         is_server_started = 0;
389 }
390
391 int gesture_client_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id,
392                                 int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data)
393 {
394         LOGD("gesture_client_dbus_init start");
395
396         int ret;
397
398         ret = _dbus_init(gdbus_connection, server_watcher_id);
399         if (ret != HAND_GESTURE_ERROR_NONE) {
400                 LOGE("_dbus_init() failed : %d", ret);
401                 return ret;
402         }
403
404         ret = _dbus_signal_init(*gdbus_connection, monitor_id, lib, data);
405         if (ret != HAND_GESTURE_ERROR_NONE) {
406                 LOGE("_dbus_signal_init() failed : %d", ret);
407                 return ret;
408         }
409
410         ret = _monitor_register(*gdbus_connection);
411         if (ret != HAND_GESTURE_ERROR_NONE) {
412                 LOGE("_monitor_register() failed : %d", ret);
413                 return ret;
414         }
415
416         if (*server_monitor_id == 0) {
417                 *server_monitor_id = g_bus_watch_name_on_connection(
418                                 *gdbus_connection,
419                                 GESTURE_DBUS_NAME,
420                                 G_BUS_NAME_WATCHER_FLAGS_NONE,
421                                 _on_name_appeared,
422                                 _on_name_vanished,
423                                 NULL,
424                                 NULL);
425                 if (*server_monitor_id == 0) {
426                         g_dbus_connection_signal_unsubscribe(*gdbus_connection, *monitor_id);
427                         *monitor_id = 0;
428                         LOGE("Failed to get identifier");
429                         return HAND_GESTURE_ERROR_OPERATION_FAILED;
430                 }
431         }
432
433         return HAND_GESTURE_ERROR_NONE;
434 }
435
436 int gesture_client_dbus_shutdown(GDBusConnection *gdbus_connection, int *server_monitor_id, int *monitor_id)
437 {
438         if (*server_monitor_id) {
439                 g_bus_unwatch_name(*server_monitor_id);
440                 *server_monitor_id = 0;
441         }
442
443         if (*monitor_id) {
444                 g_dbus_connection_signal_unsubscribe(gdbus_connection, *monitor_id);
445                 *monitor_id = 0;
446         }
447
448         return HAND_GESTURE_ERROR_NONE;
449 }
450
451 int gesture_client_dbus_initialize_engine(GDBusConnection *gdbus_connection)
452 {
453         int ret;
454         GDBusMessage *reply = NULL;
455         GVariant *body = NULL;
456
457         body = g_variant_new("()");
458         ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_INITIALIZE_ENGINE);
459         if (ret != HAND_GESTURE_ERROR_NONE)
460                 LOGE("failed to initialize");
461
462         if (body)
463                 g_variant_unref(body);
464
465         if (reply)
466                 g_object_unref(reply);
467
468         return ret;
469
470 }
471
472 int gesture_client_dbus_deinitialize_engine(GDBusConnection *gdbus_connection)
473 {
474         int ret;
475         GDBusMessage *reply = NULL;
476         GVariant *body = NULL;
477
478         body = g_variant_new("()");
479         ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_DEINITIALIZE_ENGINE);
480         if (ret != HAND_GESTURE_ERROR_NONE)
481                 LOGE("failed to deinitialize");
482
483         if (body)
484                 g_variant_unref(body);
485
486         if (reply)
487                 g_object_unref(reply);
488
489         return ret;
490
491 }
492
493 int gesture_client_dbus_set_handtype(GDBusConnection *gdbus_connection, hand_gesture_handtype_e hand_type)
494 {
495         int ret = HAND_GESTURE_ERROR_NONE;
496         if (hand_type > HAND_GESTURE_RIGHT_HAND || hand_type < HAND_GESTURE_NO_SELECTED_HAND) {
497                 LOGE("Invalid Parmeter");
498                 return HAND_GESTURE_ERROR_INVALID_PARAMETER;
499         }
500         g_hand_type = hand_type;
501
502         return ret;
503 }
504
505 int gesture_client_dbus_set_workmode(GDBusConnection *gdbus_connection, hand_gesture_workmode_e work_mode)
506 {
507         int ret = HAND_GESTURE_ERROR_NONE;
508         if (work_mode > HAND_GESTURE_WORK_MODE_UNDEFINED || work_mode < HAND_GESTURE_WORK_MODE_ONE_WAY) {
509                 LOGE("Invalid Parmeter");
510                 return HAND_GESTURE_ERROR_INVALID_PARAMETER;
511         }
512         g_work_mode = work_mode;
513
514         return ret;
515 }
516
517 int gesture_client_dbus_set_option(GDBusConnection *gdbus_connection, hand_gesture_option_e option)
518 {
519         int ret = HAND_GESTURE_ERROR_NONE;
520         if (option > HAND_GESTURE_OPTION_ALWAYS_ON || option < HAND_GESTURE_OPTION_DEFAULT) {
521                 LOGE("Invalid Parmeter");
522                 return HAND_GESTURE_ERROR_INVALID_PARAMETER;
523         }
524         g_option = option;
525
526         return ret;
527 }
528
529 int gesture_client_dbus_set_sensitivity(GDBusConnection *gdbus_connection, int sensitivity)
530 {
531         int ret = HAND_GESTURE_ERROR_NONE;
532         g_sensitivity = sensitivity;
533
534         return ret;
535 }
536
537 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)
538 {
539         LOGD("gesture_client_dbus_start_recognition start");
540         LOGD("client busname: %s", g_dbus_connection_get_unique_name(gdbus_connection));
541         g_callback = callback;
542         g_gesture_data = gesture_data;
543
544         GVariant *body = NULL;
545         body = g_variant_new("(iiiii)", gesture_type, g_hand_type, g_work_mode, g_option, g_sensitivity);
546
547         gdbus_send_message_with_async(gdbus_connection, body, GESTURE_CLIENT_MSG_START_RECOGNITION, gesture_data);
548
549         if (body)
550                 g_variant_unref(body);
551
552         return HAND_GESTURE_ERROR_NONE;
553 }
554
555 int gesture_client_dbus_stop_recognition(GDBusConnection *gdbus_connection)
556 {
557         int ret;
558         GDBusMessage *reply = NULL;
559         GVariant *body = NULL;
560
561         /* free for gesture data struct */
562         _free_gesture_data(g_gesture_data);
563
564         body = g_variant_new("()");
565         ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_STOP_RECOGNITION);
566         if (ret != HAND_GESTURE_ERROR_NONE)
567                 LOGE("failed to stop gesture");
568
569         if (body)
570                 g_variant_unref(body);
571
572         if (reply)
573                 g_object_unref(reply);
574
575         return ret;
576
577 }
578
579 int gesture_client_dbus_foreach_result_time(GDBusConnection *gdbus_connection)
580 {
581         int ret;
582         GDBusMessage *reply = NULL;
583         GVariant *body = NULL;
584
585         body = g_variant_new("()");
586         ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_FOREACH_RESULT_TIME);
587         if (ret != HAND_GESTURE_ERROR_NONE)
588                 LOGE("failed to foreach_result_time");
589
590         if (body)
591                 g_variant_unref(body);
592
593         if (reply)
594                 g_object_unref(reply);
595
596         return ret;
597
598 }
599
600 int gesture_client_dbus_foreach_supported_type(GDBusConnection *gdbus_connection)
601 {
602         int ret;
603         GDBusMessage *reply = NULL;
604         GVariant *body = NULL;
605
606         body = g_variant_new("()");
607         ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_FOREACH_SUPPORTED_TYPE);
608         if (ret != HAND_GESTURE_ERROR_NONE)
609                 LOGE("failed to foreach_supported_type");
610
611         if (body)
612                 g_variant_unref(body);
613
614         if (reply)
615                 g_object_unref(reply);
616
617         return ret;
618
619 }
620
621 int gesture_client_dbus_is_support_gesture_type(GDBusConnection *gdbus_connection, hand_gesture_type_e gesture, bool* supported)
622 {
623         int ret;
624         GDBusMessage *reply = NULL;
625         GVariant *body = NULL;
626
627         body = g_variant_new("()");
628         ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_IS_SUPPORT_GESTURE_TYPE);
629         if (ret != HAND_GESTURE_ERROR_NONE)
630                 LOGE("failed to is_supported_gesture_type");
631
632         if (body)
633                 g_variant_unref(body);
634
635         if (reply)
636                 g_object_unref(reply);
637
638         return ret;
639
640 }
641
642 int gesture_client_dbus_engine_get_info(GDBusConnection *gdbus_connection, char** engine_app_id, char** engine_name)
643 {
644         int ret;
645         GDBusMessage *reply = NULL;
646         GVariant *body = NULL;
647         g_engine_app_id = *engine_app_id;
648         g_engine_name = *engine_name;
649
650         body = g_variant_new("()");
651         ret = gdbus_send_message_with_sync(gdbus_connection, body, &reply, GESTURE_CLIENT_MSG_ENGINE_GET_INFO);
652         if (ret != HAND_GESTURE_ERROR_NONE)
653                 LOGE("failed to engine_get_info");
654
655         if (body)
656                 g_variant_unref(body);
657
658         if (reply)
659                 g_object_unref(reply);
660
661         return ret;
662 }
663