From b60487c9f5dac198ce16081961393090b57e9ef0 Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Tue, 6 Feb 2018 14:03:27 +0900 Subject: [PATCH 01/16] Rename LICENSE file as LICENSE.Apache-2.0 Change-Id: I69d89d6fa27bdfeb1c9026a8aa190fd119421efe Signed-off-by: Hyotaek Shim --- LICENSE => LICENSE.Apache-2.0 | 0 packaging/feedbackd.spec | 16 ++++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) rename LICENSE => LICENSE.Apache-2.0 (100%) diff --git a/LICENSE b/LICENSE.Apache-2.0 similarity index 100% rename from LICENSE rename to LICENSE.Apache-2.0 diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index 1dca668..b01db16 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -280,43 +280,43 @@ mv %{_sysconfdir}/feedbackd/haptic-level6.conf %{_sysconfdir}/feedbackd/haptic.c %files -n feedbackd %manifest %{name}.manifest -%license LICENSE +%license LICENSE.Apache-2.0 %config %{_sysconfdir}/dbus-1/system.d/feedbackd.conf %{_unitdir}/feedbackd.service %{_unitdir}/multi-user.target.wants/feedbackd.service %files driver-external -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %{_bindir}/feedbackd.external %files driver-emulator -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %{_bindir}/feedbackd.emulator %files driver-gpio -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %{_bindir}/feedbackd.gpio %files driver-standard -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %{_bindir}/feedbackd.standard %files driver-circle -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %{_bindir}/feedbackd.circle %files conf-level3 -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %config %{_sysconfdir}/feedbackd/haptic-level3.conf %files conf-level6 -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %config %{_sysconfdir}/feedbackd/haptic-level6.conf -- 2.7.4 From 29970885c0949d4c5421c73abae4b2c8d34bba10 Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Tue, 6 Feb 2018 14:47:12 +0900 Subject: [PATCH 02/16] Enable systemd activiation on feedbackd.service Change-Id: Ifeb475d28740839f842a60a294d1df64b8115a11 Signed-off-by: Hyotaek Shim --- CMakeLists.txt | 2 +- packaging/feedbackd.spec | 1 + systemd/org.tizen.system.vibrator.service | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 systemd/org.tizen.system.vibrator.service diff --git a/CMakeLists.txt b/CMakeLists.txt index 0900516..a509c75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,6 @@ INSTALL(FILES ${CMAKE_SOURCE_DIR}/scripts/feedbackd.conf DESTINATION /etc/dbus-1 INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/system FILES_MATCHING PATTERN "feedbackd.service") - +INSTALL(FILES ${CMAKE_SOURCE_DIR}/systemd/org.tizen.system.vibrator.service DESTINATION /usr/share/dbus-1/system-services) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/conf/haptic-level3.conf DESTINATION /etc/feedbackd) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/conf/haptic-level6.conf DESTINATION /etc/feedbackd) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index b01db16..b74c9f6 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -284,6 +284,7 @@ mv %{_sysconfdir}/feedbackd/haptic-level6.conf %{_sysconfdir}/feedbackd/haptic.c %config %{_sysconfdir}/dbus-1/system.d/feedbackd.conf %{_unitdir}/feedbackd.service %{_unitdir}/multi-user.target.wants/feedbackd.service +%{_datadir}/dbus-1/system-services/org.tizen.system.vibrator.service %files driver-external %license LICENSE.Apache-2.0 diff --git a/systemd/org.tizen.system.vibrator.service b/systemd/org.tizen.system.vibrator.service new file mode 100644 index 0000000..d3c99bf --- /dev/null +++ b/systemd/org.tizen.system.vibrator.service @@ -0,0 +1,5 @@ +[D-BUS Service] +Name=org.tizen.system.vibrator +Exec=/bin/false +User=system_fw +SystemdService=feedbackd.service -- 2.7.4 From 3dc4a167ed36965ff716bda109436ce20ffc82ee Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Thu, 8 Feb 2018 20:29:59 +0900 Subject: [PATCH 03/16] auto-test: Add auto-test for feedbackd Change-Id: Iee10703dc89bb94ecffc37424be259552c537f86 Signed-off-by: pr.jung --- CMakeLists.txt | 2 + packaging/feedbackd.spec | 11 ++ src/auto-test/CMakeLists.txt | 28 ++++ src/auto-test/haptic.c | 327 +++++++++++++++++++++++++++++++++++++++++++ src/auto-test/main.c | 74 ++++++++++ src/auto-test/result.c | 35 +++++ src/auto-test/test.c | 71 ++++++++++ src/auto-test/test.h | 99 +++++++++++++ src/core/dbus.h | 1 - src/haptic/haptic.c | 1 - src/haptic/standard.c | 2 + 11 files changed, 649 insertions(+), 2 deletions(-) create mode 100644 src/auto-test/CMakeLists.txt create mode 100755 src/auto-test/haptic.c create mode 100644 src/auto-test/main.c create mode 100644 src/auto-test/result.c create mode 100644 src/auto-test/test.c create mode 100644 src/auto-test/test.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a509c75..55c3880 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,3 +72,5 @@ INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/system INSTALL(FILES ${CMAKE_SOURCE_DIR}/systemd/org.tizen.system.vibrator.service DESTINATION /usr/share/dbus-1/system-services) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/conf/haptic-level3.conf DESTINATION /etc/feedbackd) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/conf/haptic-level6.conf DESTINATION /etc/feedbackd) + +ADD_SUBDIRECTORY(src/auto-test) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index b74c9f6..fbffb0d 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -108,6 +108,13 @@ Conflicts: %{name}-conf-level3 %description conf-level6 Feedbackd configuration file. +%package auto-test +Summary: Feedbackd auto test tool +Group: System/Utilities +%description auto-test +Feedbackd helper programs. +This package can be installed optional for auto dbus test. + %prep %setup -q @@ -321,3 +328,7 @@ mv %{_sysconfdir}/feedbackd/haptic-level6.conf %{_sysconfdir}/feedbackd/haptic.c %manifest %{name}.manifest %config %{_sysconfdir}/feedbackd/haptic-level6.conf +%files auto-test +%license LICENSE +%manifest %{name}.manifest +%{_bindir}/feedbackd-auto-test diff --git a/src/auto-test/CMakeLists.txt b/src/auto-test/CMakeLists.txt new file mode 100644 index 0000000..5e40bd7 --- /dev/null +++ b/src/auto-test/CMakeLists.txt @@ -0,0 +1,28 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(feedbackd-auto-test C) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src) + +SET(SRCS + test.c + main.c + result.c + ../core/dbus.c + haptic.c +) + +INCLUDE(FindPkgConfig) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Werror") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -lrt -fPIE") +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") + +ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs2_LDFLAGS} "-ldl" "-lm") + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin) diff --git a/src/auto-test/haptic.c b/src/auto-test/haptic.c new file mode 100755 index 0000000..7171d38 --- /dev/null +++ b/src/auto-test/haptic.c @@ -0,0 +1,327 @@ +/* + * feedbackd auto-test + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless requhapticed by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "test.h" + +#define METHOD_HAPTIC_GETCOUNT "GetCount" +#define METHOD_HAPTIC_OPENDEVICE "OpenDevice" +#define METHOD_HAPTIC_CLOSEDEVICE "CloseDevice" +#define METHOD_HAPTIC_STOPDEVICE "StopDevice" +#define METHOD_HAPTIC_VIBRATEMONOTONE "VibrateMonotone" +#define METHOD_HAPTIC_VIBRATEEFFECT "VibrateEffect" +#define METHOD_HAPTIC_GETSTATE "GetState" +#define METHOD_HAPTIC_SHOWHANDLELIST "ShowHandleList" +#define METHOD_HAPTIC_ISSUPPORTED "IsSupported" + +static bool request_haptic_method(const char *method, GVariant *param) +{ + GVariant *msg; + int val; + bool ret = FALSE; + + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + method, param); + + if (!msg) { + _E("fail (%s): no reply", method); + return ret; + } + + if (!dh_get_param_from_var(msg, "(i)", &val)) + _E("fail (%s): no message", method); + else { + if ((val == -ENOTSUP) || (val == -ENOSYS)) { + _I("Not supported feature! (%s): %d", method, val); + ret = TRUE; + } else if (val == -ENODEV) { + _E("fail (%s): device open fail (%d)", method, val); + } else if (val < 0) { + _E("fail (%s): returned fail (%d)", method, val); + } else { + _I("success (%s): %d", method, val); + ret = TRUE; + } + } + + g_variant_unref(msg); + return ret; +} + +static bool haptic_getcount() +{ + _D("----------------------------------------------------------------------------------"); + return request_haptic_method(METHOD_HAPTIC_GETCOUNT, NULL); +} + +static bool haptic_opendevice(int index) +{ + _D("----------------------------------------------------------------------------------"); + return request_haptic_method(METHOD_HAPTIC_OPENDEVICE, g_variant_new("(i)", index)); +} + +static bool haptic_closedevice() +{ + GVariant *msg; + int handle; + bool ret = FALSE; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + METHOD_HAPTIC_OPENDEVICE, + g_variant_new("(i)", 0)); + + if (!msg) { + _E("fail (%s): no reply", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + + if (!dh_get_param_from_var(msg, "(i)", &handle)) { + _E("fail (%s): no message", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + g_variant_unref(msg); + + return request_haptic_method(METHOD_HAPTIC_CLOSEDEVICE, g_variant_new("(u)", handle)); +} + +static bool haptic_vibratemonotone(int duration, int level, int priority) +{ + GVariant *msg; + int handle; + bool ret = FALSE; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + METHOD_HAPTIC_OPENDEVICE, + g_variant_new("(i)", 0)); + + if (!msg) { + _E("fail (%s): no reply", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + + if (!dh_get_param_from_var(msg, "(i)", &handle)) { + _E("fail (%s): no message", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + g_variant_unref(msg); + + return request_haptic_method(METHOD_HAPTIC_VIBRATEMONOTONE, g_variant_new("(uiii)", handle, duration, level, priority)); +} + +static bool haptic_vibrateeffect(char *pattern, int level, int priority) +{ + GVariant *msg; + int handle; + bool ret = FALSE; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + METHOD_HAPTIC_OPENDEVICE, + g_variant_new("(i)", 0)); + + if (!msg) { + _E("fail (%s): no reply", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + + if (!dh_get_param_from_var(msg, "(i)", &handle)) { + _E("fail (%s): no message", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + g_variant_unref(msg); + + return request_haptic_method(METHOD_HAPTIC_VIBRATEEFFECT, g_variant_new("(usii)", handle, pattern, level, priority)); +} + +static bool haptic_stopdevice() +{ + struct timespec time = {0,}; + GVariant *msg; + int handle; + bool ret = FALSE; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + METHOD_HAPTIC_OPENDEVICE, + g_variant_new("(i)", 0)); + + if (!msg) { + _E("fail (%s): no reply", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + + if (!dh_get_param_from_var(msg, "(i)", &handle)) { + _E("fail (%s): no message", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + g_variant_unref(msg); + + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + METHOD_HAPTIC_VIBRATEMONOTONE, + g_variant_new("(uiii)", handle, 1000, 100, 0)); + + if (!msg) { + _E("fail (%s): no reply", METHOD_HAPTIC_VIBRATEMONOTONE); + return ret; + } + + _D("sleep 300ms"); + time.tv_nsec = 300 * NANO_SECOND_MULTIPLIER; + nanosleep(&time, NULL); + _D("wakeup"); + + return request_haptic_method(METHOD_HAPTIC_STOPDEVICE, g_variant_new("(u)", handle)); +} + +static bool haptic_getstate(int index) +{ + _D("----------------------------------------------------------------------------------"); + return request_haptic_method(METHOD_HAPTIC_GETSTATE, g_variant_new("(i)", index)); +} + +static bool haptic_showhandlelist() +{ + GVariant *msg; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + METHOD_HAPTIC_SHOWHANDLELIST, + NULL); + + if (!msg) { + _E("fail (%s): no reply", METHOD_HAPTIC_OPENDEVICE); + return FALSE; + } + g_variant_unref(msg); + return TRUE; +} + +static bool haptic_issupported(char *pattern) +{ + _D("----------------------------------------------------------------------------------"); + return request_haptic_method(METHOD_HAPTIC_ISSUPPORTED, g_variant_new("(s)", pattern)); +} + +void haptic_test_all(int *success, int *fail) +{ + struct timespec time = {0,}; + int s = 0; + int f = 0; + + time.tv_sec = 1; + + (haptic_getcount()) ? s++ : f++; + (haptic_opendevice(0)) ? s++ : f++; + (haptic_closedevice()) ? s++ : f++; + (haptic_stopdevice()) ? s++ : f++; + nanosleep(&time, NULL); + (haptic_vibratemonotone(300, 100, 0)) ? s++ : f++; + nanosleep(&time, NULL); + (haptic_vibrateeffect("FEEDBACK_PATTERN_SIP", 100, 0)) ? s++ : f++; + nanosleep(&time, NULL); + (haptic_getstate(0)) ? s++ : f++; + (haptic_showhandlelist()) ? s++ : f++; + (haptic_issupported("FEEDBACK_PATTERN_SIP")) ? s++ : f++; + + + if (NULL != success) *success = s; + if (NULL != fail) *fail = f; +} + +static void haptic_init(void *data) +{ + int success = 0; + int fail = 0; + + _I("start test"); + + haptic_test_all(&success, &fail); + + _I("Total: %d, Success: %d, Fail: %d", success+fail, success, fail); +} + +static void haptic_exit(void *data) +{ + _I("end test"); +} + +static int haptic_unit(int argc, char **argv) +{ + struct timespec time = {0,}; + + if (argc < 2) { + int success = 0; + int fail = 0; + + _I("start test"); + haptic_test_all(&success, &fail); + _I("Total: %d, Success: %d, Fail: %d", success+fail, success, fail); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_GETCOUNT)) { + haptic_getcount(); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_OPENDEVICE)) { + haptic_opendevice(atoi(argv[2])); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_CLOSEDEVICE)) { + haptic_closedevice(); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_STOPDEVICE)) { + time.tv_sec = 1; + haptic_stopdevice(); + nanosleep(&time, NULL); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_VIBRATEMONOTONE)) { + haptic_vibratemonotone(atoi(argv[2]), atoi(argv[3]), atoi(argv[4])); + time.tv_sec = 1 + (atoi(argv[2]) / 1000); + nanosleep(&time, NULL); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_VIBRATEEFFECT)) { + haptic_vibrateeffect(argv[2], atoi(argv[3]), atoi(argv[4])); + time.tv_sec = 2; + nanosleep(&time, NULL); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_GETSTATE)) { + haptic_getstate(atoi(argv[2])); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_SHOWHANDLELIST)) { + haptic_showhandlelist(); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_ISSUPPORTED)) { + haptic_issupported(argv[2]); + } else { + _E("Unknown test case!!!"); + } + + return 0; +} + +static const struct test_ops haptic_test_ops = { + .priority = TEST_PRIORITY_NORMAL, + .name = "haptic", + .init = haptic_init, + .exit = haptic_exit, + .unit = haptic_unit, +}; + +TEST_OPS_REGISTER(&haptic_test_ops) diff --git a/src/auto-test/main.c b/src/auto-test/main.c new file mode 100644 index 0000000..85148c8 --- /dev/null +++ b/src/auto-test/main.c @@ -0,0 +1,74 @@ +/* + * feedbackd auto-test + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test.h" + +static void test_main(int argc, char **argv) +{ + _I("auto test all"); + test_init((void *)NULL); + test_exit((void *)NULL); +} + +static void unit_test(int argc, char **argv) +{ + const struct test_ops *ops; + + ops = find_test("haptic"); + if (!ops) { + _E("there is no test ops : haptic"); + return; + } + ops->unit(argc, argv); +} + +void show_usage() +{ + printf("Usage: deviced-auto-test [UNIT-METHOD] [OPTS]\n\n"); + printf("Optional arguments\nIf you don't give any optional arguments, all supported modules will be tested.\n"); + printf("All module list is as below.\nAs per profile, supported modules are different.\n"); + printf("[UNIT-METHOD] [OPTS]\n"); + printf("GetCount 0\n"); + printf("OpenDevice 0\n"); + printf("CloseDevice 0\n"); + printf("StopDevice 0\n"); + printf("VibrateMonotone duration, level, priority\n"); + printf("VibrateEffect pattern string, level, priority\n"); + printf("GetState 0\n"); + printf("ShowHandleList 0\n"); + printf("IsSupported pattern string\n"); +} + +int main(int argc, char **argv) +{ + if (argc == 2) { + if (!strncmp(argv[1], "help", strlen("help") + 1)) { + show_usage(); + return 0; + } + } + + if (argc >= 2) + unit_test(argc, argv); + else + test_main(argc, argv); + + + return 0; +} + diff --git a/src/auto-test/result.c b/src/auto-test/result.c new file mode 100644 index 0000000..c0f07fb --- /dev/null +++ b/src/auto-test/result.c @@ -0,0 +1,35 @@ +/* + * feedbackd auto-test + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "core/log.h" + +#define BUF_MAX 256 + +void _R(const char *format, ...) +{ + va_list args; + char buf[BUF_MAX]; + + va_start(args, format); + vsnprintf(buf, BUF_MAX, format, args); + va_end(args); + + _D("%s", buf); +} diff --git a/src/auto-test/test.c b/src/auto-test/test.c new file mode 100644 index 0000000..15f27be --- /dev/null +++ b/src/auto-test/test.c @@ -0,0 +1,71 @@ +/* + * feedbackd auto-test + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test.h" + +static dd_list *dd_head; + +void add_test(const struct test_ops *d) +{ + if (d->priority == TEST_PRIORITY_HIGH) + DD_LIST_PREPEND(dd_head, d); + else + DD_LIST_APPEND(dd_head, d); +} + +void remove_test(const struct test_ops *d) +{ + DD_LIST_REMOVE(dd_head, d); +} + +const struct test_ops *find_test(const char *name) +{ + dd_list *elem; + const struct test_ops *d; + + DD_LIST_FOREACH(dd_head, elem, d) { + if (!strcasecmp(d->name, name)) + return d; + } + return NULL; +} + +void test_init(void *data) +{ + dd_list *elem; + const struct test_ops *d; + + _D("test module count(%d)", DD_LIST_LENGTH(dd_head)); + DD_LIST_FOREACH(dd_head, elem, d) { + _D("[%s] initialize", d->name); + if (d->init) + d->init(data); + } +} + +void test_exit(void *data) +{ + dd_list *elem; + const struct test_ops *d; + + DD_LIST_FOREACH(dd_head, elem, d) { + _D("[%s] deinitialize", d->name); + if (d->exit) + d->exit(data); + } +} diff --git a/src/auto-test/test.h b/src/auto-test/test.h new file mode 100644 index 0000000..e5d5801 --- /dev/null +++ b/src/auto-test/test.h @@ -0,0 +1,99 @@ +/* + * feedbackd auto-test + * + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TEST_H__ +#define __TEST_H__ +#include +#include + +#include "core/list.h" +#include "core/log.h" +#include "core/dbus.h" +#include "core/common.h" + +#ifdef ENABLE_TEST_DLOG +#define ENABLE_DLOG +#endif + +//#define LOG_TAG "AUTO_TEST" + +enum test_priority { + TEST_PRIORITY_NORMAL = 0, + TEST_PRIORITY_HIGH, +}; + +struct test_ops { + enum test_priority priority; + char *name; + void (*init) (void *data); + void (*exit) (void *data); + int (*start) (void); + int (*stop) (void); + int (*status) (void); + int (*unit) (int argc, char **argv); +}; + +enum test_ops_status { + TEST_OPS_STATUS_UNINIT, + TEST_OPS_STATUS_START, + TEST_OPS_STATUS_STOP, + TEST_OPS_STATUS_MAX, +}; + +void test_init(void *data); +void test_exit(void *data); + +static inline int test_start(const struct test_ops *c) +{ + if (c && c->start) + return c->start(); + + return -EINVAL; +} + +static inline int test_stop(const struct test_ops *c) +{ + if (c && c->stop) + return c->stop(); + + return -EINVAL; +} + +static inline int test_get_status(const struct test_ops *c) +{ + if (c && c->status) + return c->status(); + + return -EINVAL; +} + +#define TEST_OPS_REGISTER(c) \ +static void __CONSTRUCTOR__ module_init(void) \ +{ \ + add_test(c); \ +} \ +static void __DESTRUCTOR__ module_exit(void) \ +{ \ + remove_test(c); \ +} +void add_test(const struct test_ops *c); +void remove_test(const struct test_ops *c); +const struct test_ops *find_test(const char *name); +void _R(const char *format, ...); +#endif diff --git a/src/core/dbus.h b/src/core/dbus.h index 4d35471..cca491a 100644 --- a/src/core/dbus.h +++ b/src/core/dbus.h @@ -176,7 +176,6 @@ typedef struct { * @since_tizen 4.0 */ typedef struct { - dbus_object_handle_h oh; const char *name; const dbus_method_s *methods; int nr_methods; diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index 231e374..e1a64e6 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -829,7 +829,6 @@ static const dbus_method_s hdbus_methods[] = { }; static const dbus_interface_u dbus_interface = { - .oh = NULL, .name = VIBRATOR_INTERFACE_HAPTIC, .methods = hdbus_methods, .nr_methods = ARRAY_SIZE(hdbus_methods), diff --git a/src/haptic/standard.c b/src/haptic/standard.c index 8e77b20..39f6866 100644 --- a/src/haptic/standard.c +++ b/src/haptic/standard.c @@ -601,6 +601,8 @@ static int stop_device(int device_handle) r = ff_stop(ff_fd, &info->effect); if (r < 0) _E("failed to stop effect(id:%d) : %d", info->effect.id, r); + else + _D("succeed to stop effect"); /* unregister existing timer */ if (r >= 0 && info->timer) { -- 2.7.4 From db8a8d06d4b555be2f0ec97eed0cb37b8871ee80 Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Tue, 13 Feb 2018 17:53:05 +0900 Subject: [PATCH 04/16] Fix build failure Change-Id: I98763329e3bdf4bcfc8971188be80caaee6a7df2 Signed-off-by: Hyotaek Shim --- packaging/feedbackd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index fbffb0d..7526934 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -329,6 +329,6 @@ mv %{_sysconfdir}/feedbackd/haptic-level6.conf %{_sysconfdir}/feedbackd/haptic.c %config %{_sysconfdir}/feedbackd/haptic-level6.conf %files auto-test -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %{_bindir}/feedbackd-auto-test -- 2.7.4 From 1a90db017ff25ec11b0babc0228cf1d1b01bc739 Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Thu, 22 Feb 2018 14:52:50 +0900 Subject: [PATCH 05/16] haptic: Change g_timeout_add_seconds to g_timeout_add - g_timeout_add interval is in milliseconds - g_timeout_add_seconds interval is in seconds Change-Id: Ide64c518d1249bd4861e5749a8e5122fadf71166 Signed-off-by: pr.jung --- src/haptic/circle.c | 2 +- src/haptic/gpio_haptic.c | 2 +- src/haptic/standard-mix.c | 8 ++++---- src/haptic/standard-vibcore.c | 4 ++-- src/haptic/standard.c | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/haptic/circle.c b/src/haptic/circle.c index 6555d40..1b63660 100644 --- a/src/haptic/circle.c +++ b/src/haptic/circle.c @@ -220,7 +220,7 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p /* register timer */ if (duration) { - stop_timer = g_timeout_add_seconds(duration/1000, timer_cb, (void *)(long)device_handle); + stop_timer = g_timeout_add(duration, timer_cb, (void *)(long)device_handle); if (!stop_timer) _E("Failed to add timer callback"); diff --git a/src/haptic/gpio_haptic.c b/src/haptic/gpio_haptic.c index c44e768..45ffdac 100644 --- a/src/haptic/gpio_haptic.c +++ b/src/haptic/gpio_haptic.c @@ -248,7 +248,7 @@ static int gpio_haptic_vibrate_monotone(int handle, int duration, int level, int /* register timer */ if (duration) { //stop_timer = ecore_timer_add(duration/1000.f, gpio_haptic_timer_cb, (void *)(long)handle); - stop_timer = g_timeout_add_seconds(duration/1000, gpio_haptic_timer_cb, (void *)(long)handle); + stop_timer = g_timeout_add(duration, gpio_haptic_timer_cb, (void *)(long)handle); if (!stop_timer) _E("Failed to add timer callback"); } diff --git a/src/haptic/standard-mix.c b/src/haptic/standard-mix.c index a234ec7..578a700 100644 --- a/src/haptic/standard-mix.c +++ b/src/haptic/standard-mix.c @@ -488,7 +488,7 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p /* register timer */ if (duration) { - info->timer = g_timeout_add_seconds(duration/1000, timer_cb, info); + info->timer = g_timeout_add(duration, timer_cb, info); if (!info->timer) _E("Failed to add timer callback"); } @@ -525,12 +525,12 @@ static gboolean _buffer_play(void *cbdata) if (info->currentindex < header->ff_info_data_count) { info->currentindex++; - info->timer = g_timeout_add_seconds(length/1000, _buffer_play, info); + info->timer = g_timeout_add(length, _buffer_play, info); } else { --header->iteration; if (header->iteration > 0) { info->currentindex = 0; - info->timer = g_timeout_add_seconds(0, _buffer_play, info); + info->timer = g_timeout_add(0, _buffer_play, info); } else info->timer = NULL; } @@ -642,7 +642,7 @@ static gboolean haptic_duration_play(void *data) time = duration + h_data->waiting_config[index]; /*duration_timer = ecore_timer_add(time/1000.0f, haptic_duration_play, (void *)h_data);*/ - duration_timer = g_timeout_add_seconds(time/1000, haptic_duration_play, (void *)h_data); + duration_timer = g_timeout_add(time, haptic_duration_play, (void *)h_data); _D("timer: %d", time); } diff --git a/src/haptic/standard-vibcore.c b/src/haptic/standard-vibcore.c index 7361bb2..f8982c9 100644 --- a/src/haptic/standard-vibcore.c +++ b/src/haptic/standard-vibcore.c @@ -197,9 +197,9 @@ static gboolean haptic_duration_play(void *data) if (next) { h_data->vibration_data = next; - duration_timer = g_timeout_add_seconds((node->duration + node->wait)/1000, haptic_duration_play, (void *)h_data); + duration_timer = g_timeout_add((node->duration + node->wait), haptic_duration_play, (void *)h_data); } else - duration_timer = g_timeout_add_seconds((node->duration + node->wait)/1000, haptic_duration_play, NULL); + duration_timer = g_timeout_add((node->duration + node->wait), haptic_duration_play, NULL); ret = real_vibrate_monotone(h_data->handle, node->duration, h_data->level, h_data->priority, NULL); if (!next) diff --git a/src/haptic/standard.c b/src/haptic/standard.c index 39f6866..6a42bd1 100644 --- a/src/haptic/standard.c +++ b/src/haptic/standard.c @@ -452,7 +452,7 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p /* register timer */ if (duration) { - info->timer = g_timeout_add_seconds(duration/1000, timer_cb, info); + info->timer = g_timeout_add(duration, timer_cb, info); if (!info->timer) _E("Failed to add timer callback"); } @@ -489,12 +489,12 @@ static gboolean _buffer_play(void *cbdata) if (info->currentindex < header->ff_info_data_count) { info->currentindex++; - info->timer = g_timeout_add_seconds(length/1000, _buffer_play, info); + info->timer = g_timeout_add(length, _buffer_play, info); } else { --header->iteration; if (header->iteration > 0) { info->currentindex = 0; - info->timer = g_timeout_add_seconds(0, _buffer_play, info); + info->timer = g_timeout_add(0, _buffer_play, info); } else info->timer = 0; } -- 2.7.4 From 92f2f8ad90387eed109b3c03f9aacca094786cbf Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Tue, 6 Mar 2018 11:12:55 +0900 Subject: [PATCH 06/16] dbus: modify dbus policy correctly Change-Id: I64eb9361c4f5ad7c3dc418ab927b53afcce589a7 Signed-off-by: sanghyeok.oh --- scripts/feedbackd.conf | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/scripts/feedbackd.conf b/scripts/feedbackd.conf index d17e13a..05f4ece 100755 --- a/scripts/feedbackd.conf +++ b/scripts/feedbackd.conf @@ -1,12 +1,21 @@ + - - - + + + + + + + + + + + + send_path="/Org/Tizen/System/Vibrator/Haptic" + privilege="http://tizen.org/privilege/haptic"/> -- 2.7.4 From f533c93a6de4df28c9c58287bb17af5eab53791a Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Wed, 21 Mar 2018 17:22:14 +0900 Subject: [PATCH 07/16] libgdbus: Move common gdbus interfaces to libsystem package Change-Id: I17034bb99d971a75a0a770861596c33f9cfbdc73 Signed-off-by: pr.jung --- CMakeLists.txt | 2 +- packaging/feedbackd.spec | 2 +- src/auto-test/CMakeLists.txt | 1 - src/auto-test/haptic.c | 14 +- src/auto-test/test.c | 1 + src/auto-test/test.h | 6 +- src/core/dbus.c | 2521 ------------------------------------------ src/core/dbus.h | 234 ---- src/core/edbus-handler.h | 1 - src/core/main.c | 4 +- src/haptic/haptic.c | 9 +- 11 files changed, 21 insertions(+), 2774 deletions(-) delete mode 100644 src/core/dbus.c delete mode 100644 src/core/dbus.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 55c3880..b2c4c8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,6 @@ SET(SRCS src/core/config-parser.c src/core/device-idler.c src/core/log.c - src/core/dbus.c src/haptic/haptic.c ) @@ -41,6 +40,7 @@ SET(PKG_MODULES gio-2.0 gio-unix-2.0 capi-system-info + libgdbus ) IF(DRIVER STREQUAL gpio) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index 7526934..c87d08a 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -18,12 +18,12 @@ BuildRequires: cmake BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(capi-base-common) -BuildRequires: pkgconfig(dbus-1) BuildRequires: pkgconfig(gio-2.0) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(gio-unix-2.0) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(capi-system-peripheral-io) +BuildRequires: pkgconfig(libgdbus) Requires(post): /usr/bin/vconftool diff --git a/src/auto-test/CMakeLists.txt b/src/auto-test/CMakeLists.txt index 5e40bd7..5547560 100644 --- a/src/auto-test/CMakeLists.txt +++ b/src/auto-test/CMakeLists.txt @@ -7,7 +7,6 @@ SET(SRCS test.c main.c result.c - ../core/dbus.c haptic.c ) diff --git a/src/auto-test/haptic.c b/src/auto-test/haptic.c index 7171d38..004d72a 100755 --- a/src/auto-test/haptic.c +++ b/src/auto-test/haptic.c @@ -33,7 +33,7 @@ static bool request_haptic_method(const char *method, GVariant *param) int val; bool ret = FALSE; - msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(VIBRATOR_BUS_NAME, VIBRATOR_PATH_HAPTIC, VIBRATOR_INTERFACE_HAPTIC, method, param); @@ -82,7 +82,7 @@ static bool haptic_closedevice() bool ret = FALSE; _D("----------------------------------------------------------------------------------"); - msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(VIBRATOR_BUS_NAME, VIBRATOR_PATH_HAPTIC, VIBRATOR_INTERFACE_HAPTIC, METHOD_HAPTIC_OPENDEVICE, @@ -109,7 +109,7 @@ static bool haptic_vibratemonotone(int duration, int level, int priority) bool ret = FALSE; _D("----------------------------------------------------------------------------------"); - msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(VIBRATOR_BUS_NAME, VIBRATOR_PATH_HAPTIC, VIBRATOR_INTERFACE_HAPTIC, METHOD_HAPTIC_OPENDEVICE, @@ -136,7 +136,7 @@ static bool haptic_vibrateeffect(char *pattern, int level, int priority) bool ret = FALSE; _D("----------------------------------------------------------------------------------"); - msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(VIBRATOR_BUS_NAME, VIBRATOR_PATH_HAPTIC, VIBRATOR_INTERFACE_HAPTIC, METHOD_HAPTIC_OPENDEVICE, @@ -164,7 +164,7 @@ static bool haptic_stopdevice() bool ret = FALSE; _D("----------------------------------------------------------------------------------"); - msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(VIBRATOR_BUS_NAME, VIBRATOR_PATH_HAPTIC, VIBRATOR_INTERFACE_HAPTIC, METHOD_HAPTIC_OPENDEVICE, @@ -181,7 +181,7 @@ static bool haptic_stopdevice() } g_variant_unref(msg); - msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(VIBRATOR_BUS_NAME, VIBRATOR_PATH_HAPTIC, VIBRATOR_INTERFACE_HAPTIC, METHOD_HAPTIC_VIBRATEMONOTONE, @@ -211,7 +211,7 @@ static bool haptic_showhandlelist() GVariant *msg; _D("----------------------------------------------------------------------------------"); - msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + msg = dbus_handle_method_sync_with_reply_var(VIBRATOR_BUS_NAME, VIBRATOR_PATH_HAPTIC, VIBRATOR_INTERFACE_HAPTIC, METHOD_HAPTIC_SHOWHANDLELIST, diff --git a/src/auto-test/test.c b/src/auto-test/test.c index 15f27be..bf0985c 100644 --- a/src/auto-test/test.c +++ b/src/auto-test/test.c @@ -16,6 +16,7 @@ * limitations under the License. */ +#include #include "test.h" static dd_list *dd_head; diff --git a/src/auto-test/test.h b/src/auto-test/test.h index e5d5801..4454d1a 100644 --- a/src/auto-test/test.h +++ b/src/auto-test/test.h @@ -17,14 +17,14 @@ */ -#ifndef __TEST_H__ -#define __TEST_H__ +#ifndef FEEDBACKD__TEST_H__ +#define FEEDBACKD__TEST_H__ #include #include +#include #include "core/list.h" #include "core/log.h" -#include "core/dbus.h" #include "core/common.h" #ifdef ENABLE_TEST_DLOG diff --git a/src/core/dbus.c b/src/core/dbus.c deleted file mode 100644 index 42137a7..0000000 --- a/src/core/dbus.c +++ /dev/null @@ -1,2521 +0,0 @@ -/* - * feedbackd - * - * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include -#include -#include -#include -#include - -#include "core/log.h" -#include "core/common.h" -#include "dbus.h" - -/* -1 is a default timeout value, it's converted to 25*1000 internally. */ -#define DBUS_REPLY_TIMEOUT (-1) - -static GBusType g_default_bus_type = G_BUS_TYPE_SYSTEM; -pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; - -void dbus_handle_set_default_bus_type(GBusType bus_type) -{ - if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) - return ; - - pthread_mutex_lock(&g_mutex); - g_default_bus_type = bus_type; - pthread_mutex_unlock(&g_mutex); -} - -GBusType dbus_handle_get_default_bus_type(void) -{ - GBusType type; - - pthread_mutex_lock(&g_mutex); - type = g_default_bus_type; - pthread_mutex_unlock(&g_mutex); - - return type; -} - -typedef struct { - const char *bus_name; - guint id; -} dbus_name; - -/* basic information */ -typedef struct { - GDBusConnection *conn; - GBusType bus_type; - gboolean priv; - GList *list_names; // dbus_name - GList *list_object; /* dbus_object_handle_s */ - pthread_mutex_t mutex;// = PTHREAD_MUTEX_INITIALIZER; -} dbus_handle_s; - -/* path + interfaces */ -typedef struct { - dbus_handle_s *dh; /* dbus handle */ - const char *path; - GList *list_ifaces; /* dbus_interface_s */ -} dbus_object_handle_s; - -typedef struct { - dbus_object_handle_s *oh; - const char *name; - GList *list_methods; // const dbus_method_s; - guint reg_id; - int modified; -} dbus_interface_s; - -#define get_dh_from_oh(oh) ((dbus_object_handle_s*)oh)->dh - -static dbus_handle_s g_dh[2]; - -static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type); - -dbus_handle_s * _dbus_handle_get_default_connection(void) -{ - return _dbus_handle_get_connection(dbus_handle_get_default_bus_type()); -} - -#define dbus_handle_lock(handle) do {\ - assert(handle);\ - pthread_mutex_lock(&((handle)->mutex));\ -} while (0); - -#define dbus_handle_unlock(handle) do {\ - assert(handle);\ - pthread_mutex_unlock(&(handle)->mutex);\ -} while (0); - -#define dcl_dbus_handle() dbus_handle_s *dh = (dbus_handle_s *)handle; -#define dcl_dbus_handle_null_check() dbus_handle_s *dh = (dbus_handle_s *)handle;\ - if (!dh) {\ - _E("dbus handle is null\n");\ - return 0;\ - } - -dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path); -dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name); -dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name); -static GVariant* _append_variant(const char *signature, const char *param[]); - -dbus_interface_s *_iface_u_to_s(const dbus_interface_u *iface_u) -{ - dbus_interface_s *iface = NULL; - - if (!iface_u || !iface_u->methods) { - _E("param is null"); - return NULL; - } - - iface = (dbus_interface_s *)calloc(1, sizeof(dbus_interface_s)); - if (!iface) { - _E("failed to calloc"); - return NULL; - } - - iface->name = iface_u->name; - iface->modified = TRUE; - - for (int i = 0 ; i < iface_u->nr_methods; ++i) { - //_D("attached %s:%p", iface_u->methods[i].member, iface_u->methods[i].func); - iface->list_methods = g_list_prepend(iface->list_methods, (void*)(iface_u->methods + i)); - } - - return iface; -} - -static GDBusConnection * _get_bus(GBusType bus_type) -{ - GDBusConnection *conn = NULL; - GError *err = NULL; - - if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { - _E("Wrong bus_type %d", bus_type); - return NULL; - } - - conn = g_bus_get_sync(bus_type, NULL, &err); - if (!conn || err) { - _E("failed to get bus:type:%d, %s\n", bus_type, err->message); - g_error_free(err); - return NULL; - } - - return conn; -} - -static GDBusConnection * _get_bus_private(GBusType bus_type) -{ - GError *err = NULL; - GDBusConnection *conn = NULL; - const char * address; - - if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { - _E("Wrong bus_type %d", bus_type); - return NULL; - } - - address = g_dbus_address_get_for_bus_sync(bus_type, NULL, &err); - if (!address || err) { - _E("failed to get bus address\n"); - g_error_free(err); - return NULL; - } - - conn = g_dbus_connection_new_for_address_sync(address, - (GDBusConnectionFlags) (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | - G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION), - NULL, /* GDBusAuthObserver */ - NULL, - &err); - if (!conn || err) { - _E("failed to get private bus\n"); - g_error_free(err); - return NULL; - } - - return conn; -} - -/* ref cout is 1 */ -static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type) -{ - int ibus = bus_type - 1; - dbus_handle_s *dh = NULL; - - if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { - _E("Unknown bus type %d", bus_type); - return NULL; - } - dh = &g_dh[ibus]; - - dbus_handle_lock(dh); - - if (!dh->conn) { - dh->conn = _get_bus(bus_type); - dh->priv = FALSE; - dh->bus_type = bus_type; - if (!dh->conn) - dh = NULL; - } - - dbus_handle_unlock(dh); - - return dh; -} - -/* ref cout is 1 */ -static dbus_handle_s *_dbus_handle_get_connection_private(GBusType bus_type) -{ - dbus_handle_s * dh; - - if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { - _E("Unknown bus type %d", bus_type); - return NULL; - } - - dh = (dbus_handle_s *)calloc(1, sizeof(dbus_handle_s)); - if (!dh) { - _E("failed to allocate memory for dbus handle"); - return NULL; - } - - dbus_handle_lock(dh); - - if (!dh->conn) { - dh->conn = _get_bus_private(bus_type); - dh->bus_type = bus_type; - if (!dh->conn) - goto err; - } - - dbus_handle_unlock(dh); - - return dh; -err: - if (dh) { - dbus_handle_unlock(dh); - free(dh); - } - return NULL; -} - -dbus_handle_h dbus_handle_get_connection(GBusType bus_type, gboolean priv) -{ - dbus_handle_s *dh = NULL; - - if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { - _E("Wrong bus_type %d\n", bus_type); - return dh; - } - - /* private */ - if (priv) - dh = _dbus_handle_get_connection_private(bus_type); - /* shared */ - else - dh = _dbus_handle_get_connection(bus_type); - - return dh; -} - -static void _dbus_handle_add_bus_name(dbus_handle_s *handle, const char *name, guint id) -{ - dbus_name *dn = NULL; - int locked = 0; - - if (!handle || !name || !id) - return ; - - dn = (dbus_name*)calloc(1, sizeof(dbus_name)); - if (!dn) { - _E("failed to calloc"); - assert(0); - } - dn->bus_name = name; - dn->id = id; - - // todo : delete lock ? - locked = pthread_mutex_trylock(&handle->mutex); - if (locked != 0 && locked != EBUSY) { - _E("failed to lock %d\n", locked); - assert(0); - } - - handle->list_names = g_list_prepend(handle->list_names, dn); - - // todo : delete lock ? - if (locked != EBUSY) - dbus_handle_unlock(handle); -} - -static gint _compare_dbus_name(gconstpointer a, gconstpointer b) -{ - const char *bus_name = ((dbus_name *)a)->bus_name; - if (!bus_name || !b) - return -1; - return strcmp(bus_name, (const char *)b); -} - -dbus_name * _dbus_handle_lookup_dbus_name(GList *list_name, const char *bus_name) -{ - if (!list_name || !bus_name) - return NULL; - - GList *item = g_list_find_custom(list_name, bus_name, _compare_dbus_name); - if (!item) - return NULL; - - return (dbus_name *)item->data; -} - -#define dh_to_ds(x) ((dbus_handle_s*)x) - -/* remove dbus_name from dbus handle */ -static void _dbus_handle_remove_bus_name(dbus_handle_s *handle, const char *bus_name) -{ - dcl_dbus_handle(); - dbus_name *dn = NULL; - - if (!bus_name) { - _E("wrong bus_name %s", bus_name); - return ; - } - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return ; - } - } - - dbus_handle_lock(dh); - dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name); - if (!dn) { - _E("failed to find dbus name %s", bus_name); - goto out; - } - dh->list_names = g_list_remove(dh->list_names, dn); - free(dn); -out: - dbus_handle_unlock(dh); -} - -static void _name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data) -{ - dbus_handle_s *dh = (dbus_handle_s *)user_data; - - _D("name %s", name); - - if (!dh) { - _E("%s:%d:dbus handle is null\n", __func__, __LINE__); - return ; - } - // todo: add bus name? - //dh->bus_name = name; -} - -static void _name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data) -{ - _E("%s:%d:%s\n", __func__, __LINE__, name); - dbus_handle_s *dh = (dbus_handle_s *)user_data; - if (!dh) { - _E("%s:%d:dbus handle is null\n", __func__, __LINE__); - return ; - } - _dbus_handle_remove_bus_name(dh, name); -} - -int dbus_handle_request_bus_name(dbus_handle_h handle, const char *bus_name) -{ - dcl_dbus_handle(); - int id = -1; - GList *item = NULL; - - if (!bus_name) { - _E("bus_name is NULL"); - return -1; - } - - /* get shared connection */ - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - } - - dbus_handle_lock(dh); - if (!dh->conn) { - _E("failed to register name: connection is null\n"); - goto out; - } - - /* todo : search name on connection */ - item = g_list_find_custom(dh->list_names, bus_name, _compare_dbus_name); - if (item) { - id = ((dbus_name*)(item->data))->id; - _E("name already exist:%u", id); - goto out; - } - - id = g_bus_own_name_on_connection(dh->conn, bus_name, G_BUS_NAME_OWNER_FLAGS_NONE, _name_acquired, _name_lost, dh, NULL); - if (!id) { - _E("failed to own name:%s\n", bus_name); - goto out; - } - - _dbus_handle_add_bus_name(dh, bus_name, id); - -out: - dbus_handle_unlock(dh); - return id; -} - -int dbus_handle_release_bus_name(dbus_handle_h handle, const char *bus_name) -{ - dcl_dbus_handle(); - dbus_name *dn = NULL; - - if (!bus_name) { - _E("Wrong bus name"); - return -1; - } - - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - } - - dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name); - if (!dn) { - _E("failed to find bus_name %s on dbus handle", bus_name); - return -1; - } - - _E("unown name %d", dn->id); - /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */ - g_bus_unown_name(dn->id); - - dbus_handle_lock(dh); - dh->list_names = g_list_remove(dh->list_names, dn); - free(dn); - dbus_handle_unlock(dh); - - return 0; -} - -int dbus_handle_free_connection(dbus_handle_h handle) -{ - dcl_dbus_handle(); - dbus_handle_s *pdh = NULL; - GError *err = NULL; - GList *item = NULL; - - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - } - - if (!dh->conn) { - _E("connection is NULL"); - return 0; - } - - pdh = dh; - - /* disable dbus handler */ - dbus_handle_lock(dh); - if (!pdh->conn) { - _E("conn is null"); - free(pdh); - return 0; - } - - /* flush everything */ - if (!g_dbus_connection_flush_sync(pdh->conn, NULL, &err)) { - _E("failed to flush %s\n", err->message); - g_error_free(err); - err = NULL; - } - - _D("list_names %u", g_list_length(pdh->list_names)); - - /* unown every well-knwon name */ - if (pdh->list_names) { - dbus_name *dn = NULL; - for (item = g_list_first(pdh->list_names); item != NULL; item = g_list_next(item)) { - dn = (dbus_name *)item->data; - if (!dn) - continue; - - /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */ - _D("unown name id : %u", dn->id); - g_bus_unown_name(dn->id); - free(dn); - } - g_list_free(pdh->list_names); - pdh->list_names = NULL; - } - - _D("list_object %u", g_list_length(pdh->list_object)); - - /* unregister every object */ - if (pdh->list_object) { - dbus_object_handle_s * oh = NULL; - //g_list_foreach(pdh->list_object, [] (gpointer data, gpointer user_data){}, NULL); - for (item = g_list_first(pdh->list_object); item != NULL; item = g_list_next(item)) { - oh = (dbus_object_handle_s *)item->data; - if (!oh || !oh->list_ifaces) - continue; - - _D("delete object path %s", oh->path); - - /* unregister every interface, method handles */ - for (GList *iface = g_list_first(oh->list_ifaces); iface != NULL; iface = g_list_next(iface)) { - dbus_interface_s *ih = (dbus_interface_s *)iface->data; - if (!ih) - continue; - - _D("delete object iface %s", ih->name); - - if (ih->reg_id) - g_dbus_connection_unregister_object(pdh->conn, ih->reg_id); - } - } - } - - /* close connection */ - if (pdh->priv) { - _E("close private connection\n"); - - if (!g_dbus_connection_close_sync(pdh->conn, NULL, &err)) { - _E("Error closing connection %s\n", err->message); - g_error_free(err); - err = NULL; - } - } - - /* _free_func_object callback free the data */ - //assert(g_list_length(pdh->list_names) == 0); - //assert(g_list_length(pdh->list_object) == 0); - - g_object_unref(pdh->conn); - - dbus_handle_unlock(dh); - - if (dh->priv) - free(dh); - - return 0; - - // todo: signal ? -} - -#define buf_cal_free_space(size, nwrite) ((size - nwrite - 1) > 0 ? (size - nwrite - 1) : 0) -#define buf_block_size 8192 - -#define buf_check_space_realloc(buf, nwrite, buf_len) do {\ - if ((nwrite >= buf_len - 1024)) {\ - if (buf_len >= buf_block_size * 10) {\ - _E("buf is too big to allocate. %d", buf_len);\ - } else {\ - _E("buf_check_space_realloc");\ - char *tmp = NULL;\ - buf_len += buf_block_size;\ - tmp = (char *)realloc(buf, buf_len);\ - if (!tmp) {\ - _E("failed to realloc");\ - } else\ - buf = tmp;\ - } \ - } \ -} while (0); - -static int _check_brace(const char * expr) -{ - int len = 0; - char qu[128]; - int qucnt = 0; - - if (!expr) - return -1; - - len = strlen(expr); - - if (expr[0] != '(' && expr[0] != '{') - return -1; - - for (int i = 0 ; i < len; ++i) { - - if (expr[i] == '(' || expr[i] == '{') { - qu[qucnt++] = expr[i]; - if (qucnt >= sizeof(qu)) { - _E("queue is too large. %s", expr); - return -1; - } - continue; - } - - if (expr[i] == ')' || expr[i] == '}') { - char ch; - - if (qucnt > 0) - ch = qu[qucnt-1]; - else - return -1; - - if (expr[i] == ')') { - if (ch == '(') { - --qucnt; - } else - return -1; - } else if (expr[i] == '}') { - if (ch == '{') { - --qucnt; - } else - return -1; - } else - return -1; - - if (qucnt == 0) { - return i + 1; - } - } - } - - return -1; -} - -static int _get_xml_from_interfaces(char **xml, const dbus_interface_s *interfaces) -{ - int nwrite = 0; - int len_args; - char *buf = NULL; - const dbus_method_s *pmethod; - int buf_len = buf_block_size; - - if (!interfaces) { - _E("interfaces is null"); - return -1; - } - - // todo : check dbus naming rule for interface name. ? - if (!interfaces->name) { - _E("wrong interface name"); - return -1; - } - if (!interfaces->list_methods) { - _E("no methods"); - return -1; - } - - buf = (char *)malloc(buf_len); - if (!buf) { - _E("buf is null. not enough memory\n"); - return -1; - } - - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), """\n""\t""""\n", interfaces->name); - - /* members */ - for (GList *item = g_list_first(interfaces->list_methods); item != NULL; item = g_list_next(item)) { - pmethod = (const dbus_method_s *)item->data; - if (!pmethod) - continue; - - /* check free space of buf */ - buf_check_space_realloc(buf, nwrite, buf_len); - - if (pmethod->signature_in == NULL && pmethod->signature_out == NULL) { - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""""\n", pmethod->member); - continue; - } - - /* */ - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""""\n", pmethod->member); - - /* in args */ - len_args = pmethod->signature_in ? strlen(pmethod->signature_in) : 0; - for (int m = 0; m < len_args; ++m) { - // todo - // array a(), as, ay ? - if (pmethod->signature_in[m] == 'a') { - int ei; //end index - ei = _check_brace(pmethod->signature_in + m + 1); - if (ei > 0) { - char tmp[128] = {0,}; - strncpy(tmp, pmethod->signature_in + m, ei + 1); - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\n", tmp, m); - m += ei; - continue; - } else { - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\n", pmethod->signature_in[m], pmethod->signature_in[m+1], m); - m += 1; - continue; - } - } - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\n", pmethod->signature_in[m], m); - } - - /* out args */ - len_args = pmethod->signature_out ? strlen(pmethod->signature_out) : 0; - for (int m = 0; m < len_args; ++m) { - // array - // todo: container type - if (pmethod->signature_out[m] == 'a') { - int ei; //end index - ei = _check_brace(pmethod->signature_out + m + 1); - if (ei > 0) { - char tmp[128] = {0,}; - strncpy(tmp, pmethod->signature_out + m, ei + 1); - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\n", tmp, m); - m += ei; - continue; - } else { - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\n", pmethod->signature_out[m], pmethod->signature_out[m+1], m); - m += 1; - continue; - } - } - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\n", pmethod->signature_out[m], m); - } - - /* */ - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""""\n"); - } - - nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t""""\n"""""); - - *xml = buf; - - return 0; -} - -static gint _compare_dbus_object(gconstpointer a, gconstpointer b) -{ - dbus_object_handle_s * pa = (dbus_object_handle_s *)a; - if (!pa->path || !((const char*)b)) - return -1; - return strcmp(pa->path, (const char*)b); -} - -static gint _compare_dbus_interface(gconstpointer a, gconstpointer b) -{ - dbus_interface_s * pa = (dbus_interface_s *)a; - if (!pa->name || !((const char*)b)) - return -1; - return strcmp(pa->name, (const char*)b); -} - -static gint _compare_dbus_interface_by_id(gconstpointer a, gconstpointer b) -{ - dbus_interface_s * pa = (dbus_interface_s *)a; - if (!pa->reg_id || !((guint*)b)) - return -1; - return !(pa->reg_id == *((guint*)b)); -} - -static gint _compare_dbus_method(gconstpointer a, gconstpointer b) -{ - dbus_method_s *pa = (dbus_method_s*)a; - if (!pa->member || !((const char*)b)) - return -1; - return strcmp(pa->member, (const char*)b); -} - -dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path) -{ - if (!list_obj || !obj_path) - return NULL; - - GList *item = g_list_find_custom(list_obj, obj_path, _compare_dbus_object); - if (!item) - return NULL; - - return (dbus_object_handle_s *)item->data; -} - -dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name) -{ - if (!list_iface || !iface_name) - return NULL; - - GList *item = g_list_find_custom(list_iface, iface_name, _compare_dbus_interface); - if (!item) - return NULL; - - return (dbus_interface_s *)item->data; -} - -dbus_interface_s * _dbus_handle_lookup_interface_by_id(GList *list_iface, guint id) -{ - if (!list_iface || !id) - return NULL; - - GList *item = g_list_find_custom(list_iface, &id, _compare_dbus_interface_by_id); - if (!item) - return NULL; - - return (dbus_interface_s *)item->data; -} - -dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name) -{ - if (!list_methods || !method_name) - return NULL; - - GList *item = g_list_find_custom(list_methods, method_name, _compare_dbus_method); - if (!item) - return NULL; - - return (dbus_method_s *)item->data; -} - -static void _free_func_object(gpointer data) -{ - dbus_interface_s *ih = (dbus_interface_s *)data; - dbus_object_handle_s *oh = NULL; - - if (!ih) { - _E("interface handle is null"); - assert(0); // something wrong - return ; - } - - /* just free list, not data(static dbus_method_s) */ - g_list_free(ih->list_methods); - - oh = ih->oh; - if (!oh) { - _E("object handle is null"); - assert(0); // something wrong - return ; - } - - /* remove ih from list_ifaces */ - oh->list_ifaces = g_list_remove(oh->list_ifaces, ih); - - /* interface_s is copy of interface_u */ - free(ih); - - /* remove oh from list_object */ - if (!oh->list_ifaces) { - oh->dh->list_object = g_list_remove(oh->dh->list_object, oh); - free(oh); - } -} - -static int _dbus_handle_attach_object(dbus_handle_s *dh, const char *obj_path, dbus_interface_s *iface) -{ - dbus_object_handle_s *oh = NULL; - - if (!dh || !obj_path || !iface) { - _E("failed to attache object. wrong parameter"); - return -1; - } - - /* find object handle */ - if (dh->list_object) - oh = _dbus_handle_lookup_object(dh->list_object, obj_path); - - if (!oh) { - oh = (dbus_object_handle_s*)calloc(1, sizeof(dbus_object_handle_s)); - if (!oh) { - _E("failed to calloc"); - return -1; - } - oh->dh = dh; - oh->path = obj_path; - - /* attach object */ - dh->list_object = g_list_prepend(dh->list_object, oh); - } - - iface->oh = oh; - /* attach interface */ - oh->list_ifaces = g_list_prepend(oh->list_ifaces, iface); - - return 0; -} - -/* libgio verify path and interface */ -static void _method_call_handler(GDBusConnection *conn, - const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, - GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) -{ - dbus_interface_s *iface_s = (dbus_interface_s *)user_data; - const dbus_method_s *methods; - GVariant *result = NULL; - - /* todo: ghash ? */ - methods = _dbus_handle_lookup_method(iface_s->list_methods, name); - if (methods) { - result = methods->func(conn, sender, path, iface, name, param, invocation, get_dh_from_oh(iface_s->oh)); - - /* async, maybe they will reply...maybe.. */ - if (!result) { - _E("finish method handle : NULL"); - return ; - } - } else { - _E("no methods"); - } - - g_dbus_method_invocation_return_value(invocation, result); - //if (g_variant_is_of_type(result, G_VARIANT_TYPE_TUPLE)) { - // //_E("TUPLE %s", g_variant_get_type_string(result)); - // g_dbus_method_invocation_return_value(invocation, result); - //} - //else if (g_variant_is_container(result)) { - // /* todo: we don't have any plan to using variant type for reply */ - // _E("CONTAINER %s", g_variant_get_type_string(result)); - // g_dbus_method_invocation_return_value(invocation, result); - // //g_dbus_method_invocation_return_value(invocation, g_variant_new("(v)", result)); - //} else { - // _E("Type is not Container : %s", g_variant_get_type_string(result)); - //} -} - -static GDBusInterfaceVTable path_vtable = {_method_call_handler}; - - -/* -before register object, attach object into dbus handle -_dbus_handle_attach_object() -*/ -static int _dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, dbus_interface_s *iface) -{ - dcl_dbus_handle(); - int ret = 0; - char *buf = NULL; - GError *err = NULL; - GDBusNodeInfo * nodeinfo = NULL; - GDBusInterfaceInfo *ifaceinfo = NULL; - - if (!obj_path || !iface) { - _E("wrong parameter\n"); - return -1; - } - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - } - if (!dh->conn) { - _E("connection is null\n"); - return -1; - } - - ret = _get_xml_from_interfaces(&buf, iface); - if (ret < 0) { - _E("failed to make xml format"); - goto err; - } - - /* todo: delete this */ -#if 0 - if (strlen(buf) <= 512) { - _E("%s", buf); - } else { - _E("%s", buf + strlen(buf) - 512); - } -#endif - - nodeinfo = g_dbus_node_info_new_for_xml(buf, &err); - if (!nodeinfo || err) { - _E("failed to make introspection data:err:%s:xml:%s\n", err->message, buf); - ret = -1; - goto err; - } - - ifaceinfo = g_dbus_node_info_lookup_interface(nodeinfo, iface->name); - if (!ifaceinfo) { - _E("failed to g_dbus_node_info_lookup_interface"); - ret = -1; - goto err; - } - - /* - path own single interface - if interface is already registered, then failed. - g_dbus_connection_register_object ref(ifaceinfo) now, unref if object is unregistered - */ - ret = g_dbus_connection_register_object(dh->conn, obj_path, ifaceinfo/*ref 2*/, &path_vtable, (void*)iface, - _free_func_object, - &err); - if (err) { - _E("failed to register object:err:%s:\n", err->message); - ret = -1; - goto err; - } - - iface->reg_id = ret; - iface->modified = FALSE; - -err: - /* todo: detach object */ - //_dbus_handle_detach_object(dh, obj_path, iface); - /* attach interface before register object */ - /*ret = _dbus_handle_detach_object(dh, obj_path, iface); - if (ret < 0) { - _E("failed to attach object"); - goto err; - }*/ - - if (nodeinfo) - g_dbus_node_info_unref(nodeinfo); - if (buf) - free(buf); - if (err) - g_error_free(err); - - return ret; -} - -/* -register same interface at once - -if interface is constructed by multiple methods, -also it is not possible to make methods struct at once, - -use dbus_handle_add_dbus_object(), dbus_handle_register_dbus_object_all(). - -return reg_id -*/ -int dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u) -{ - dcl_dbus_handle(); - int ret = 0; - dbus_interface_s *iface = NULL; - - if (!obj_path || !iface_u) { - _E("wrong parameter\n"); - return -1; - } - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - } - if (!dh->conn) { - _E("connection is null\n"); - return -1; - } - - /* check registered interface */ - if (dh->list_object) { - dbus_object_handle_s *oh = _dbus_handle_lookup_object(dh->list_object, obj_path); - if (oh) { - dbus_interface_s *ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name); - if (ih) { - _E("path %s, interface %s already registered", obj_path, iface_u->name); - return -1; - } - } - } - - iface = _iface_u_to_s(iface_u); - if (!iface) { - _E("failed to _iface_u_to_s"); - return -1; - } - - /* attach interface before register object */ - ret = _dbus_handle_attach_object(dh, obj_path, iface); - if (ret < 0) { - _E("failed to attach object"); - goto err; - } - - ret = _dbus_handle_register_dbus_object(dh, obj_path, iface); - if (ret <= 0) { - _E("failed to register dbus object%d", ret); - goto err; - } -err: - return ret; -} - -int dbus_handle_unregister_dbus_object(dbus_handle_h handle, const char *obj_path) -{ - dcl_dbus_handle(); - dbus_object_handle_s *oh = NULL; - int ret = 0; - - if (!obj_path) { - return -1; - } - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - } - if (!dh->list_object) { - _E("list_object is empty"); - return 0; - } - - oh = _dbus_handle_lookup_object(dh->list_object, obj_path); - if (!oh) { - _E("no object with name %s", obj_path); - return -1; - } - - /* unregister every interface of object*/ - for (GList *item = g_list_first(oh->list_ifaces); item != NULL; item = g_list_next(item)) { - dbus_interface_s *ih = item->data; - if (!ih) { - _E("this is error"); - assert(0); - } - - /* remove ih from list_ifaces */ - if (!ih->reg_id) { - item = g_list_previous(item); - - /* remove and free link */ - oh->list_ifaces = g_list_remove(oh->list_ifaces, ih); - - /* free list_methods */ - g_list_free(ih->list_methods); - - /* free data */ - free(ih); - continue; - } - - /* unregister object by id */ - ret = g_dbus_connection_unregister_object(dh->conn, ih->reg_id); - if (!ret) - _E("failed to unregister object %s, interface %s, regid %d", oh->path, ih->name, ih->reg_id); - } - - return 0; -} - -/* -add object temporarily. -dbus_handle_register_dbus_object_all will register every objects on connection. - -return registered method count -*/ -int dbus_handle_add_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u) -{ - dcl_dbus_handle(); - dbus_object_handle_s *oh = NULL; - dbus_interface_s *ih = NULL; - int cnt; - - if (!obj_path || !iface_u) { - _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u); - return -1; - } - if (iface_u && (!iface_u->name || !iface_u->methods)) { - _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u); - return -1; - } - - cnt = iface_u->nr_methods; - - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - } - - if (!dh->conn) { - _E("failed to register method. connection is null\n"); - return -1; - } - - /* if there are no object list, just add */ - if (!dh->list_object) { - if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) { - _E("failed to attach object"); - return -1; - } - goto out; - } - - oh = _dbus_handle_lookup_object(dh->list_object, obj_path); - /* if there are no matched object, just add */ - if (!oh) { - if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) { - _E("failed to attach object"); - return -1; - } - goto out; - } - - /* this is an error, interface must have one or more item ? */ - if (!oh->list_ifaces) { - _E("error. list_ifaces is null\n"); - assert(0); - goto out; - } - - ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name); - /* if there are no matched interface, just add */ - if (!ih) { - if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) { - _E("failed to attach object"); - return -1; - } - goto out; - } - - /* todo: - 1. unregister interface - 2. update interface and methods - 3. register interface - */ - if (ih->reg_id) { - _E("interface already registered, ignore new interface"); - return -1; - } - - /* attach new methods */ - cnt = 0; - for (int i = 0; i < iface_u->nr_methods; ++i) { - GList *item = g_list_find_custom(g_list_first(ih->list_methods), iface_u->methods[i].member, _compare_dbus_method); - if (!item) { - //_D("attached %s", iface_u->methods[i].member); - ih->list_methods = g_list_prepend(ih->list_methods, (void*)(iface_u->methods + i)); - ++cnt; - } - } - - if (cnt) - ih->modified = TRUE; - -out: - /*todo: delete debugging log */ - //if (dh && dh->list_object) - // _D("obj list len %d", g_list_length(dh->list_object)); - //if (oh && oh->list_ifaces) - // _D("iface list len %d", g_list_length(oh->list_ifaces)); - //if (ih && ih->list_methods) - // _D("method list len %d", g_list_length(ih->list_methods)); - - return cnt; -} - -int dbus_handle_register_dbus_object_all(dbus_handle_h handle) -{ - dcl_dbus_handle(); - dbus_object_handle_s *oh = NULL; - dbus_interface_s *ih = NULL; - int ret = 0; - - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - } - if (!dh->conn) { - _E("connection is null\n"); - return -1; - } - - if (!dh->list_object) { - _E("obj list is empty"); - return -1; - } - - /*if (dh && dh->list_object) - _D("obj list len %d", g_list_length(dh->list_object));*/ - - for (GList *item = g_list_first(dh->list_object); item != NULL; item = g_list_next(item)) { - oh = (dbus_object_handle_s *)item->data; - - if (!oh) { - _E("something wrong"); - assert(0); - } - if (!oh->list_ifaces) { - _E("path %s: list_ifaces are null", oh->path); - goto err; - } - - //_D("iface list len %d", g_list_length(oh->list_ifaces)); - - for (GList *li = g_list_first(oh->list_ifaces); li != NULL; li = g_list_next(li)) { - ih = (dbus_interface_s *)li->data; - - /* if there are no modification, goto next */ - if (!ih->modified) - continue; - - /* todo: if already registered interface, unregister first */ - - /*_E("interface %s:", ih->name); - if (ih && ih->list_methods) - _D("method list len %d", g_list_length(ih->list_methods));*/ - - ret = _dbus_handle_register_dbus_object(dh, oh->path, ih); - if (ret <= 0) - _E("failed to register dbus object%d", ret); - - } - } - return 0; -err: - - // todo: delete all updates - - return -1; -} - -static void _free_func_signal(gpointer data) -{ - //_D("free signal subscribe"); -} - -guint subscribe_dbus_signal(dbus_handle_h handle, const char *path, - const char *iface, const char *name, - GDBusSignalCallback cb, void *data, - destroy_notified free_func) -{ - dcl_dbus_handle(); - - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return 0; - } - } - - if (!dh->conn) { - _E("connection is null. check bus status"); - return 0; - } - return g_dbus_connection_signal_subscribe(dh->conn, NULL, iface, name, path, NULL, G_DBUS_SIGNAL_FLAGS_NONE, cb, data, _free_func_signal); -} - -void unsubscribe_dbus_signal(dbus_handle_h handle, guint id) -{ - dcl_dbus_handle(); - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return; - } - } - - if (!dh->conn) { - _E("connection is null. check bus status"); - return; - } - - g_dbus_connection_signal_unsubscribe(dh->conn, id); -} - -int _check_type_string_is_container(const char *signature) -{ - if (!signature) - return FALSE; - - switch (signature[0]) { - case 'a': - case 'm': - case 'r': - case '(': - case '{': - case 'v': - return TRUE; - default: - return FALSE; - } - - return TRUE; -} - -GVariant *dbus_handle_make_simple_array(const char *sig, int *param) -{ - GVariantBuilder *builder = NULL; - char format[256]; - int i = 0; - - builder = g_variant_builder_new(G_VARIANT_TYPE(sig)); - if (!builder) { - _E("failed to g_variant_builder_new"); - return NULL; - } - - while (param[i]) - g_variant_builder_add(builder, "i", param[i++]); - - snprintf(format, sizeof(format) - 1, "(%s)", sig); - return g_variant_new(format, builder); -} - -/* todo: looks like garbage... */ -static GVariant* _append_variant(const char *signature, const char *param[]) -{ - char *ch; - int i; - int pi; - int int_type; - gboolean bool_type; - unsigned long long int64_type; - GVariant *ret; - int len; - char container[255];// The maximum length of a signature is 255. - const char *sig = signature; - GVariantBuilder *builder = NULL; - - if (!signature || !param) - return 0; - - /* workaround for user fault "(i) != i" but we treat this as same signature */ - /* G_VARIANT_TYPE("si") return NULL */ - /* todo: actually user have to use correct signature */ - if (!_check_type_string_is_container(signature)) { - snprintf(container, sizeof(container) - 1, "(%s)", signature); - sig = container; - } - if (!g_variant_type_is_container(G_VARIANT_TYPE(sig))) { - _E("signature (%s) is not container type", signature); - } - - builder = g_variant_builder_new(G_VARIANT_TYPE(sig)); - len = strlen(sig); - pi = 0; - for (ch = (char *)sig, i = 0; i < len; ++i, ++ch) { - switch (*ch) { - case '(': - case ')': - continue; - case 'b': - bool_type = (atoi(param[pi++]) == 0 ? FALSE : TRUE); - g_variant_builder_add(builder, "b", bool_type); - break; - case 'i': - int_type = atoi(param[pi++]); - g_variant_builder_add(builder, "i", int_type); - break; - case 'u': - int_type = strtoul(param[pi++], NULL, 10); - g_variant_builder_add(builder, "u", int_type); - break; - case 't': - int64_type = atoll(param[pi++]); - g_variant_builder_add(builder, "t", int64_type); - break; - case 's': - g_variant_builder_add(builder, "s", param[pi++]); - break; - case 'a': - ++ch; - switch (*ch) { - case 'y': - g_variant_builder_add(builder, "^ay", param[pi++]); - ++i; - break; - default: - break; - } - break; - default: - break; - } - } - ret = g_variant_builder_end(builder); - g_variant_builder_clear(builder); - g_variant_builder_unref(builder); - - return ret; -} - -int dbus_handle_broadcast_dbus_signal(const char *path, - const char *iface, const char *name, - const char *signature, const char *param[]) -{ - dbus_handle_s *dh = NULL; - GError *err = NULL; - gboolean ret = 0; - GVariant *var = NULL; - - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - - if (signature && param) - var = _append_variant(signature, param); - ret = g_dbus_connection_emit_signal(dh->conn, NULL, path, iface, name, var, &err); - if (err) { - _E("%d %s\n", ret, err ? err->message : NULL); - g_error_free(err); - } - - return ret; -} - -int dbus_handle_broadcast_dbus_signal_var(const char *path, - const char *iface, const char *name, - GVariant *param) -{ - dbus_handle_s *dh = NULL; - GError *err = NULL; - gboolean ret = 0; - - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - - ret = g_dbus_connection_emit_signal(dh->conn, NULL, path, iface, name, param, &err); - if (err) { - _E("%d %s\n", ret, err ? err->message : NULL); - g_error_free(err); - } - - return ret; -} - -GVariant *dbus_method_sync_with_reply(const char *dest, const char *path, - const char *iface, const char *method, - const char *signature, const char *param[]) -{ - GError *err = NULL; - GVariant * var = NULL; - GVariant * ret = NULL; - dbus_handle_s *dh = NULL; - - if (!dest || !path || !iface || !method) { - _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); - return NULL; - } - - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return NULL; - } - - if (signature && param) - var = _append_variant(signature, param); - - ret = g_dbus_connection_call_sync(dh->conn, - dest, path, iface, method, - var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err); - if (!ret || err) { - if (err) { - _E("failed to g_dbus_connection_call_sync:%s", err->message); - g_error_free(err); - } else { - _E("failed to g_dbus_connection_call_sync"); - g_variant_unref(var); - } - return NULL; - } - - return ret; -} - -GVariant *dbus_method_sync_with_reply_var(const char *dest, const char *path, - const char *iface, const char *method, GVariant *var) -{ - GError *err = NULL; - GVariant * ret = NULL; - dbus_handle_s *dh = NULL; - - if (!dest || !path || !iface || !method) { - _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); - if (var) - g_variant_unref(var); - return NULL; - } - - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - if (var) - g_variant_unref(var); - return NULL; - } - - ret = g_dbus_connection_call_sync(dh->conn, - dest, path, iface, method, - var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err); - if (!ret || err) { - if (err) { - _E("failed to g_dbus_connection_call_sync:%s", err->message); - g_error_free(err); - } else { - _E("failed to g_dbus_connection_call_sync"); - } - return NULL; - } - - return ret; -} - -gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size) -{ - GUnixFDList *fd_list = NULL; - int length = 0; - - fd_list = g_dbus_message_get_unix_fd_list(g_dbus_method_invocation_get_message(invocation)); - - if (!fd_list) { - _E("failed to g_unix_fd_list_get_length: fd_list is null"); - return NULL; - } - - length = g_unix_fd_list_get_length(fd_list); - if (length == 0) { - _E("failed to g_unix_fd_list_get_length: list size is 0"); - return NULL; - } - if (size) - *size = length; - - return g_unix_fd_list_steal_fds(fd_list, NULL); -} - -GVariant *dbus_method_with_unix_fd_list_sync_with_reply(const char *dest, const char *path, - const char *iface, const char *method, - const char *signature, const char *param[], - int *in_fdlist, int in_size, - int **out_fdlist, int *out_size) -{ - GError *err = NULL; - GVariant * var = NULL; - GVariant * ret = NULL; - dbus_handle_s *dh = NULL; - GDBusProxy *proxy = NULL; - GUnixFDList *g_infdlist = NULL; - GUnixFDList *g_outfdlist = NULL; - - if (!dest || !path || !iface || !method) { - _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); - return NULL; - } - if (in_fdlist && in_size == 0) { - _E("wrong in_fdlist is not null but in_size is 0"); - return NULL; - } - - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return NULL; - } - - if (signature && param) - var = _append_variant(signature, param); - - proxy = g_dbus_proxy_new_sync(dh->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dest, path, iface, NULL, &err); - if (!proxy) { - if (err) { - _E("failed to proxy_new_sync(%s)\n", err->message); - g_error_free(err); - } else { - _E("failed to proxy_new_sync\n"); - if (var) - g_variant_unref(var); - } - } - - /* append fd */ - if (in_fdlist) { - g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size); - if (!g_infdlist) { - _E("failed to g_unix_fd_list_new_from_array\n"); - goto out; - } - //g_infdlist = g_unix_fd_list_new(); - //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) { - } - - ret = g_dbus_proxy_call_with_unix_fd_list_sync(proxy, method, var, G_DBUS_CALL_FLAGS_NONE, -1, - g_infdlist, &g_outfdlist, NULL, &err); - if (!ret || err) { - if (err) { - _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:%s", err->message); - g_error_free(err); - } else { - _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:"); - if (var) - g_variant_unref(var); - if (g_infdlist) - g_object_unref(g_infdlist); - } - goto out; - } - - /* fds to out array */ - if (g_outfdlist) { - *out_size = g_unix_fd_list_get_length(g_outfdlist); - if (*out_size == 0) - goto out; - - *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL); - } - -out: - if (g_outfdlist) - g_object_unref(g_outfdlist); - if (proxy) - g_object_unref(proxy); - - return ret; -} - -GVariant *dbus_method_with_unix_fd_list_sync_with_reply_var(const char *dest, const char *path, - const char *iface, const char *method, - GVariant *param, - int *in_fdlist, int in_size, - int **out_fdlist, int *out_size) -{ - GError *err = NULL; - GVariant * ret = NULL; - dbus_handle_s *dh = NULL; - GDBusProxy *proxy = NULL; - GUnixFDList *g_infdlist = NULL; - GUnixFDList *g_outfdlist = NULL; - - if (!dest || !path || !iface || !method) { - _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); - return NULL; - } - if (in_fdlist && in_size == 0) { - _E("wrong in_fdlist is not null but in_size is 0"); - return NULL; - } - - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return NULL; - } - - proxy = g_dbus_proxy_new_sync(dh->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dest, path, iface, NULL, &err); - if (!proxy) { - if (err) { - _E("failed to proxy_new_sync(%s)\n", err->message); - g_error_free(err); - } else { - _E("failed to proxy_new_sync\n"); - if (param) - g_variant_unref(param); - } - goto out; - } - - /* append fd */ - if (in_fdlist) { - g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size); - if (!g_infdlist) { - _E("failed to g_unix_fd_list_new_from_array\n"); - goto out; - } - //g_infdlist = g_unix_fd_list_new(); - //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) { - } - - /* send message */ - ret = g_dbus_proxy_call_with_unix_fd_list_sync(proxy, method, param, G_DBUS_CALL_FLAGS_NONE, -1, - g_infdlist, &g_outfdlist, NULL, &err); - if (!ret || err) { - if (err) { - _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:%s", err->message); - g_error_free(err); - } else { - _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:"); - if (param) - g_variant_unref(param); - if (g_infdlist) - g_object_unref(g_infdlist); - } - goto out; - } - - /* copy fds to out array */ - if (g_outfdlist) { - *out_size = g_unix_fd_list_get_length(g_outfdlist); - if (*out_size == 0) - goto out; - *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL); - } -out: - if (g_outfdlist) - g_object_unref(g_outfdlist); - if (proxy) - g_object_unref(proxy); - return ret; -} - -int dbus_method_sync(const char *dest, const char *path, - const char *iface, const char *method, - const char *signature, const char *param[]) -{ - int result; - gboolean result_bool; - GVariant *reply = NULL; - - if (!dest || !path || !iface || !method) { - _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); - return -1; - } - - reply = dbus_method_sync_with_reply(dest, path, iface, method, signature, param); - if (!reply) - return -ECOMM; - - if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) { - g_variant_get(reply, "(i)", &result); - } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) { - g_variant_get(reply, "(b)", &result_bool); - result = (int)result_bool; - } else { - result = -ENOMSG; - } - - g_variant_unref(reply); - - return result; -} - -int dbus_method_sync_var(const char *dest, const char *path, - const char *iface, const char *method, GVariant *param) -{ - int result; - gboolean result_bool; - GVariant *reply = NULL; - - if (!dest || !path || !iface || !method) { - _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); - return -1; - } - - reply = dbus_method_sync_with_reply_var(dest, path, iface, method, param); - if (!reply) - return -ECOMM; - - if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) { - g_variant_get(reply, "(i)", &result); - } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) { - g_variant_get(reply, "(b)", &result_bool); - result = (int)result_bool; - } else { - result = -ENOMSG; - } - - g_variant_unref(reply); - - return result; -} - -int dbus_method_sync_timeout(const char *dest, const char *path, - const char *iface, const char *method, - const char *signature, const char *param[], int timeout) -{ - dbus_handle_s *dh = NULL; - GError *err = NULL; - GVariant * var = NULL; - GVariant * reply = NULL; - int result = 0; - - if (!dest || !path || !iface || !method) { - _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); - return -1; - } - - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -EPERM; - } - - if (signature && param) - var = _append_variant(signature, param); - - reply = g_dbus_connection_call_sync(dh->conn, - dest, path, iface, method, - var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout, NULL, &err); - if (!reply || err) { - _E("failed to g_dbus_connection_call_sync:%s", err->message); - g_error_free(err); - return -1; - } - - if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) - g_variant_get(reply, "(i)", &result); - else - result = -ENOMSG; - - g_variant_unref(reply); - - return result; -} - -int dbus_method_sync_pairs(const char *dest, const char *path, - const char *iface, const char *method, - int num, va_list args) -{ - GError *err = NULL; - GVariant * reply = NULL; - char *key, *value; - int ret = 0; - GVariant *var; - GVariantBuilder *builder; - dbus_handle_s *dh = NULL; - - if (!dest || !path || !iface || !method) { - _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); - return -1; - } - - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - - builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}")); - - for (int i = 0 ; i < num ; i = i + 2) { - key = va_arg(args, char *); - value = va_arg(args, char *); - _I("key(%s), value(%s)", key, value); - g_variant_builder_add(builder, "{ss}", key, value); - } - - var = g_variant_new("(a{ss})", builder); - - reply = g_dbus_connection_call_sync(dh->conn, - dest, path, iface, method, - var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err); - if (!reply || err) { - _E("failed to g_dbus_connection_call_sync"); - return -1; - } - - if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) - g_variant_get(reply, "(i)", &ret); - else - ret = -ENOMSG; - - g_variant_unref(reply); - - return ret; -} - -int dbus_method_async_pairs(const char *dest, const char *path, - const char *iface, const char *method, - int num, va_list args) -{ - char *key, *value; - GVariant *var; - GVariantBuilder *builder; - dbus_handle_s *dh = NULL; - - if (!dest || !path || !iface || !method) { - _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); - return -1; - } - - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - - // dict - builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}")); - - for (int i = 0 ; i < num ; i = i + 2) { - key = va_arg(args, char *); - value = va_arg(args, char *); - _I("key(%s), value(%s)", key, value); - g_variant_builder_add(builder, "{ss}", key, value); - } - - var = g_variant_new("(a{ss})", builder); - - g_dbus_connection_call(dh->conn, dest, path, iface, method, - var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, - NULL, - NULL); - - return 0; -} - -int dbus_method_async(const char *dest, const char *path, - const char *iface, const char *method, - const char *signature, const char *param[]) -{ - GVariant * var = NULL; - dbus_handle_s *dh = NULL; - - if (!dest || !path || !iface || !method) { - _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); - return -1; - } - - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - - if (signature && param) - var = _append_variant(signature, param); - - g_dbus_connection_call(dh->conn, dest, path, iface, method, - var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, - NULL, - NULL); - - return 0; -} - -int dbus_method_async_var(const char *dest, const char *path, - const char *iface, const char *method, GVariant *param) -{ - dbus_handle_s *dh = NULL; - - if (!dest || !path || !iface || !method) { - _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); - return -1; - } - - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - - g_dbus_connection_call(dh->conn, dest, path, iface, method, - param, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, - NULL, - NULL); - - return 0; -} - -/* callback should free gvariant */ -static void _cb_pending(GDBusConnection *conn, - GAsyncResult *res, - gpointer user_data) -{ - GVariant *reply = NULL; - GError *err = NULL; - pending_call_data *data = (pending_call_data *)user_data; - - reply = g_dbus_connection_call_finish(conn, res, &err); - if (!reply || err) { - if (err) { - _E("no message : [%s]", err->message); - g_error_free(err); - } else { - _E("no message"); - } - - if (data && data->func) - data->func(NULL, data->data, err); - goto out; - } - - if (data && data->func) - data->func(reply, data->data, err); -out: - if (data) - free(data); -} - -int dbus_method_async_with_reply(const char *dest, - const char *path, - const char *iface, - const char *method, - const char *signature, - const char *param[], - dbus_pending_cb cb, - int timeout_msec, - void *data) -{ - dbus_handle_s *dh = NULL; - pending_call_data *pdata = NULL; - GVariant * var = NULL; - int ret = 0; - - if (!dest || !path || !iface || !method) { - _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); - return -1; - } - - if (timeout_msec < -1) { - _E("wrong timeout %d", timeout_msec); - return -1; - } - - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -EPERM; - } - - if (signature && param) - var = _append_variant(signature, param); - - if (cb) { - pdata = (pending_call_data*)malloc(sizeof(pending_call_data)); - if (!pdata) { - ret = -ENOMEM; - goto err; - } - - pdata->func = cb; - pdata->data = data; - } - g_dbus_connection_call(dh->conn, dest, path, iface, method, - var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, - (GAsyncReadyCallback)_cb_pending, - pdata); - - return ret; -err: - if (var) - g_variant_unref(var); - return ret; -} - -int dbus_method_async_with_reply_var(const char *dest, - const char *path, - const char *iface, - const char *method, - GVariant *param, - dbus_pending_cb cb, - int timeout_msec, - void *data) -{ - dbus_handle_s *dh = NULL; - pending_call_data *pdata = NULL; - int ret = 0; - - if (!dest || !path || !iface || !method) { - _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); - return -1; - } - - if (timeout_msec < -1) { - _E("wrong timeout %d", timeout_msec); - return -1; - } - - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -EPERM; - } - - if (cb) { - pdata = (pending_call_data*)malloc(sizeof(pending_call_data)); - if (!pdata) { - ret = -ENOMEM; - goto err; - } - - pdata->func = cb; - pdata->data = data; - } - g_dbus_connection_call(dh->conn, dest, path, iface, method, - param, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, - (GAsyncReadyCallback)_cb_pending, - pdata); - - return ret; -err: - if (param) - g_variant_unref(param); - return ret; -} - -int dbus_connection_get_sender_pid(GDBusConnection *conn, const char * sender) -{ - GError *err = NULL; - GVariant *vret = NULL; - pid_t pid = 0; - - if (!conn) { - _E("connection is null"); - return -1; - } - if (!sender) { - _E("sender is null"); - return -1; - } - - vret = g_dbus_connection_call_sync(conn, - "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "GetConnectionUnixProcessID", - g_variant_new("(s)", sender), - NULL, - G_DBUS_CALL_FLAGS_NONE, - DBUS_REPLY_TIMEOUT, - NULL, - &err); - if (!vret || err) { - _E("failed to g_dbus_connection_call_sync:%s", err->message); - g_error_free(err); - return -1; - } - - g_variant_get(vret, "(u)", &pid); - g_variant_unref(vret); - - return pid; -} - -int dbus_handle_get_sender_pid(dbus_handle_h handle, const char * sender) -{ - dcl_dbus_handle(); - - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - } - if (!dh->conn) { - _E("wrong dbus handle. connection is null"); - assert(0); - return -1; - } - - return dbus_connection_get_sender_pid(dh->conn, sender); -} - -int dbus_handle_get_sender_credentials(dbus_handle_h handle, const char *name, GDBusCredentials *creds) -{ - dcl_dbus_handle(); - GVariant *vret = NULL; - GError *err = NULL; - GVariantIter *iter = NULL; - char * item; - GVariant *sub; - - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return -1; - } - } - vret = g_dbus_connection_call_sync(dh->conn, - DBUS_BUS_NAME, - DBUS_OBJECT_PATH, - DBUS_INTERFACE_NAME, - "GetConnectionCredentials", - g_variant_new("(s)", name), - NULL, - G_DBUS_CALL_FLAGS_NONE, - DBUS_REPLY_TIMEOUT, - NULL, - &err); - if (!vret || err) { - _E("failed to g_dbus_connection_call_sync:%s", err->message); - return -1; - } - - g_variant_get(vret, "(a{sv})", &iter); - - while (g_variant_iter_loop(iter, "{sv}", &item, &sub)) { - if (!g_strcmp0(item, "UnixUserID")) { - g_variant_get(sub, "u", &creds->uid); - _D("UnixUserID %u", creds->uid); - } else if (!g_strcmp0(item, "ProcessID")) { - g_variant_get(sub, "u", &creds->pid); - _D("ProcessID %u", creds->pid); - } else if (!g_strcmp0(item, "LinuxSecurityLabel")) { - g_variant_get(sub, "^ay", &creds->sec_label); - _D("%s", creds->sec_label); - } - } - - if (iter) - g_variant_iter_free(iter); - if (vret) - g_variant_unref(vret); - - return 0; -} - -void _destroy_notify_watch_name(gpointer data) -{ - /*if (data) - free(data);*/ -} - -int dbus_handle_watch_name(const char *name, - GBusNameAppearedCallback name_appeared_handler, - GBusNameVanishedCallback name_vanished_handler, - void *user_data) -{ - guint id = 0; - - if (!name) { - _E("wrong name name %s", name); - return -1; - } - if (!name_appeared_handler && !name_vanished_handler) { - _E("both function pointers are null"); - return -1; - } - - id = g_bus_watch_name(dbus_handle_get_default_bus_type(), - name, - G_BUS_NAME_WATCHER_FLAGS_NONE, - name_appeared_handler, - name_vanished_handler, - user_data, - _destroy_notify_watch_name); - if (!id) { - _E("failed to g_bus_watch_name"); - return -1; - } - - return id; -} - -void dbus_handle_unwatch_name(guint id) -{ - if (id == 0) { - _E("wrong id %d", id); - return; - } - g_bus_unwatch_name(id); -} - -int _get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size) -{ - int fd, ret; - char buf[PATH_MAX + 1]; - char *filename; - - snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid); - fd = open(buf, O_RDONLY); - if (fd < 0) { - errno = ESRCH; - return -1; - } - - ret = read(fd, buf, PATH_MAX); - close(fd); - if (ret < 0) - return -1; - - buf[PATH_MAX] = '\0'; - - filename = strrchr(buf, '/'); - if (filename == NULL) - filename = buf; - else - filename = filename + 1; - - if (cmdline_size < strlen(filename) + 1) { - errno = EOVERFLOW; - return -1; - } - - strncpy(cmdline, filename, cmdline_size - 1); - cmdline[cmdline_size - 1] = '\0'; - return 0; -} - -// g_strfreev(strv) -char **dbus_handle_get_owner_list(dbus_handle_h handle, const char *bus_name) -{ - dcl_dbus_handle(); - GError *err = NULL; - GVariant *vret = NULL; - GVariantIter *iter = NULL; - gchar **strv = NULL; - gchar *str = NULL; - int i = 0; - - if (!bus_name) { - _E("wrong parameter bus_name(%s)", bus_name); - return NULL; - } - - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return NULL; - } - } - - vret = g_dbus_connection_call_sync(dh->conn, - "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListQueuedOwners", - g_variant_new("(s)", bus_name), - NULL, - G_DBUS_CALL_FLAGS_NONE, - DBUS_REPLY_TIMEOUT, - NULL, - &err); - if (!vret || err) { - _E("failed to g_dbus_connection_call_sync:%s", err->message); - g_error_free(err); - return NULL; - } - - g_variant_get(vret, "(as)", &iter); - strv = g_new(gchar *, g_variant_iter_n_children(iter) + 1); - - i = 0; - while (g_variant_iter_loop(iter, "s", &str)) - strv[i++] = g_strdup(str); - strv[i] = NULL; - - g_variant_iter_free(iter); - g_variant_unref(vret); - - return strv; -} - -void dbush_handle_check_owner_name(dbus_handle_h handle, const char *owner_name) -{ - dcl_dbus_handle(); - char exe_name[PATH_MAX]; - int pid; - char **strv = NULL; - int i; - - if (!dh) { - dh = _dbus_handle_get_default_connection(); - if (!dh) { - _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); - return ; - } - } - - strv = dbus_handle_get_owner_list(dh, owner_name); - if (!strv) { - _E("failed to get owner list of %s", owner_name); - return ; - } - - for (i = 0; strv[i] != NULL; ++i) { - pid = dbus_handle_get_sender_pid(dh, strv[i]); - if (_get_cmdline_name(pid, exe_name, PATH_MAX) != 0) - break; - _I("%s(%d)", exe_name, pid); - } - - g_strfreev(strv); -} - -dbus_handle_h dbus_handle_init(GBusType type, const char* bus_name) -{ - dbus_handle_h handle = NULL; - int i, ret = 0; - - if (!bus_name) { - _E("Wrong bus name, %s", bus_name); - return NULL; - } - - // todo: do we need retry ? - booting time - for (i = 0 ; i < 3; ++i) { - handle = dbus_handle_get_connection(type, FALSE); - if (handle) - break; - usleep(5000); - } - ret = dbus_handle_request_bus_name(handle, bus_name); - if (ret <= 0) - goto out; - - dbush_handle_check_owner_name(NULL, bus_name); - - return handle; - -out: - return NULL; -} diff --git a/src/core/dbus.h b/src/core/dbus.h deleted file mode 100644 index cca491a..0000000 --- a/src/core/dbus.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * feedbackd - * - * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#ifndef __DBUS_H__ -#define __DBUS_H__ - -#include -#include -#include -#include -#include - -/* - * Template - * -#define XXX_BUS_NAME "org.tizen.system.XXX" -#define XXX_OBJECT_PATH "/Org/Tizen/System/XXX" -#define XXX_INTERFACE_NAME XXX_BUS_NAME -#define XXX_PATH_YYY XXX_OBJECT_PATH"/YYY" -#define XXX_INTERFACE_YYY XXX_INTERFACE_NAME".YYY" -#define XXX_SIGNAL_ZZZ "ZZZ" -#define XXX_METHOD_ZZZ "ZZZ" - */ - -/* - * DBus daemon - */ -#define DBUS_BUS_NAME "org.freedesktop.DBus" -#define DBUS_OBJECT_PATH "/org/freedesktop/DBus" -#define DBUS_INTERFACE_NAME DBUS_BUS_NAME - -/* - * Device daemon - */ -#define DEVICED_BUS_NAME "org.tizen.system.deviced" -#define DEVICED_OBJECT_PATH "/Org/Tizen/System/DeviceD" -#define DEVICED_INTERFACE_NAME DEVICED_BUS_NAME -/* Core service: get/set device status operations about device */ -#define DEVICED_PATH_CORE DEVICED_OBJECT_PATH"/Core" -#define DEVICED_INTERFACE_CORE DEVICED_INTERFACE_NAME".core" -/* Poweroff service: get power off status operations about Poweroff */ -#define DEVICED_PATH_POWEROFF DEVICED_OBJECT_PATH"/PowerOff" -#define DEVICED_INTERFACE_POWEROFF DEVICED_INTERFACE_NAME".PowerOff" -/* Key service: operations about key */ -#define DEVICED_PATH_KEY DEVICED_OBJECT_PATH"/Key" -#define DEVICED_INTERFACE_KEY DEVICED_INTERFACE_NAME".Key" - -/* - * Vibrator daemon - */ -#define VIBRATOR_BUS_NAME "org.tizen.system.vibrator" -#define VIBRATOR_OBJECT_PATH "/Org/Tizen/System/Vibrator" -#define VIBRATOR_INTERFACE_NAME VIBRATOR_BUS_NAME -/* Core service: get/set device status operations about device */ -#define VIBRATOR_PATH_CORE VIBRATOR_OBJECT_PATH"/Core" -#define VIBRATOR_INTERFACE_CORE VIBRATOR_INTERFACE_NAME".core" - -#define VIBRATOR_PATH_HAPTIC VIBRATOR_OBJECT_PATH"/Haptic" -#define VIBRATOR_INTERFACE_HAPTIC VIBRATOR_INTERFACE_NAME".haptic" - -typedef struct { - const unsigned char *data; - int size; -} dbus_byte; - -GVariant *dbus_method_sync_with_reply(const char *dest, const char *path, - const char *interface, const char *method, - const char *sig, const char *param[]); - -GVariant *dbus_method_sync_with_reply_var(const char *dest, const char *path, const char *iface, const char *method, GVariant *var); - -/* fd */ -gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size); - -GVariant *dbus_method_with_unix_fd_list_sync_with_reply(const char *dest, const char *path, - const char *iface, const char *method, - const char *signature, const char *param[], - int *in_fdlist, int in_size, - int **out_fdlist, int *out_size); -GVariant *dbus_method_with_unix_fd_list_sync_with_reply_var(const char *dest, const char *path, - const char *iface, const char *method, - GVariant *param, - int *in_fdlist, int in_size, - int **out_fdlist, int *out_size); - -int dbus_method_sync(const char *dest, const char *path, - const char *interface, const char *method, - const char *sig, const char *param[]); - -int dbus_method_sync_var(const char *dest, const char *path, const char *iface, const char *method, GVariant *param); - -int dbus_method_sync_timeout(const char *dest, const char *path, - const char *interface, const char *method, - const char *sig, const char *param[], int timeout); - -int dbus_method_sync_pairs(const char *dest, const char *path, - const char *interface, const char *method, - int num, va_list args); -int dbus_method_async_pairs(const char *dest, const char *path, - const char *interface, const char *method, - int num, va_list args); -int dbus_method_async(const char *dest, const char *path, - const char *interface, const char *method, - const char *sig, const char *param[]); - -int dbus_method_async_var(const char *dest, const char *path, const char *iface, const char *method, GVariant *param); - -typedef void (*dbus_pending_cb)(GVariant *var, void *user_data, GError *err); - -int dbus_method_async_with_reply(const char *dest, - const char *path, - const char *iface, - const char *method, - const char *signature, - const char *param[], - dbus_pending_cb cb, - int timeout_msec, - void *data); - - -int dbus_method_async_with_reply_var(const char *dest, - const char *path, - const char *iface, - const char *method, - GVariant *param, - dbus_pending_cb cb, - int timeout_msec, - void *data); - -int check_systemd_active(void); - -/** - * @brief Dbus handler which is used to register and call methods - - * @since_tizen 4.0 - */ -typedef void *dbus_handle_h; - -/** - * @brief Dbus method handler which is used to unregister dbus methods - * @since_tizen 4.0 - */ -typedef void *dbus_object_handle_h; - -/** - * @brief Structure which contains the dbus method name and callback function. - * @since_tizen 4.0 - */ -typedef struct { - const char *member; - const char *signature_in; - const char *signature_out; - GVariant *(*func)(GDBusConnection *conn, - const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, - GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data); -} dbus_method_s; - -/** - * @brief Structure which contains the dbus interface information and its methods.i - * @since_tizen 4.0 - */ -typedef struct { - const char *name; - const dbus_method_s *methods; - int nr_methods; -} dbus_interface_u; - -#define dh_get_param_from_var(gvar, signature, ...) ((g_strcmp0(signature, g_variant_get_type_string(gvar)) == 0) ? g_variant_get(gvar, signature, __VA_ARGS__), TRUE : FALSE) - -#define dbus_handle_new_g_variant_tuple() g_variant_new_tuple(NULL, 0) - -/** - * @brief Callback function which is called when the user data needs to be released. - * @since_tizen 4.0 - */ -typedef void (*destroy_notified)(void *data); - -typedef struct { - dbus_pending_cb func; - void *data; -} pending_call_data; - -int dbus_handle_request_bus_name(dbus_handle_h handle, const char *bus_name); - -dbus_handle_h dbus_handle_get_connection(GBusType bus_type, gboolean priv); - -int dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface); -int dbus_handle_unregister_dbus_object(dbus_handle_h handle, const char *obj_path); - -int dbus_handle_add_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u); -int dbus_handle_register_dbus_object_all(dbus_handle_h handle); - -guint subscribe_dbus_signal(dbus_handle_h handle, const char *path, const char *iface, const char *name, GDBusSignalCallback cb, void *data, destroy_notified free_func); -void unsubscribe_dbus_signal(dbus_handle_h handle, guint id); - -GVariant *dbus_handle_make_simple_array(const char *sig, int *param); - -int dbus_handle_broadcast_dbus_signal(const char *path, const char *iface, const char *name, const char *signature, const char *param[]); -int dbus_handle_broadcast_dbus_signal_var(const char *path, const char *iface, const char *name, GVariant *param); - -typedef struct -{ - guint pid; - guint uid; - gchar *unique_name; - gchar *sec_label; -} GDBusCredentials; - -int dbus_connection_get_sender_pid(GDBusConnection *conn, const char * sender); -int dbus_handle_get_sender_pid(dbus_handle_h handle, const char * sender); -int dbus_handle_get_sender_credentials(dbus_handle_h handle, const char *name, GDBusCredentials *creds); -int dbus_handle_watch_name(const char *name, GBusNameAppearedCallback name_appeared_handler, GBusNameVanishedCallback name_vanished_handler, void *user_data); -void dbus_handle_unwatch_name(guint id); -dbus_handle_h dbus_handle_init(GBusType type, const char* bus_name); -char** dbus_handle_get_owner_list(dbus_handle_h handle, const char *bus_name); -void dbush_handle_check_owner_name(dbus_handle_h handle, const char *owner_name); - -#endif diff --git a/src/core/edbus-handler.h b/src/core/edbus-handler.h index b1ec0ed..cdd5571 100644 --- a/src/core/edbus-handler.h +++ b/src/core/edbus-handler.h @@ -21,7 +21,6 @@ #define __FEEDBACKD_EDBUS_HANDLE_H__ #include -#include "core/dbus.h" struct edbus_method { const char *member; diff --git a/src/core/main.c b/src/core/main.c index f2e39cc..213fa10 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -21,10 +21,10 @@ #include #include #include +#include #include "core/log.h" #include "core/common.h" -#include "core/dbus.h" #include "haptic/haptic.h" static GMainLoop *mainloop = NULL; @@ -51,7 +51,7 @@ int main(int argc, char **argv) mainloop = g_main_loop_new(NULL, FALSE); - if (!dbus_handle_init(G_BUS_TYPE_SYSTEM, VIBRATOR_BUS_NAME)) { + if (!dbus_handle_init(G_BUS_TYPE_SYSTEM, VIBRATOR_BUS_NAME, NULL, NULL)) { _E("failed to init dbus connection"); } diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index e1a64e6..a352ec2 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -23,13 +23,14 @@ #include #include #include +#include +#include #include "core/log.h" #include "core/list.h" #include "core/common.h" #include "core/device-idler.h" #include "core/config-parser.h" -#include "core/dbus.h" #include "haptic.h" #define HAPTIC_CONF_PATH "/etc/feedbackd/haptic.conf" @@ -210,7 +211,7 @@ static struct haptic_info *add_haptic_info(const char *sender) info->sender = strdup(sender); DD_LIST_APPEND(haptic_handle_list, info); - info->id_watch = dbus_handle_watch_name(sender, NULL, haptic_name_owner_changed, info); + info->id_watch = dbus_handle_watch_name(sender, NULL, haptic_name_owner_changed, info, NULL); return info; } @@ -223,7 +224,9 @@ static int remove_haptic_info(struct haptic_info *info) DD_LIST_REMOVE(haptic_handle_list, info); DD_LIST_FREE_LIST(info->handle_list); - free(info->sender); + if (info->sender) { + free(info->sender); + } free(info); return 0; -- 2.7.4 From 44bf8b5b63cdb23a8a62daca695b1d277fd80ed6 Mon Sep 17 00:00:00 2001 From: lokilee73 Date: Wed, 4 Apr 2018 21:48:34 +0900 Subject: [PATCH 08/16] Refactor dbus_handle_init into two parts It's to apply a fix in deviced which timing issue happend by telephony. When telephony requests AddPoweroffWait, it fails because dbus in deviced is not ready. Change-Id: I0e0faa9dfe2b56186765903b327ece1018d6b6b0 Signed-off-by: lokilee73 --- src/core/main.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) mode change 100644 => 100755 src/core/main.c diff --git a/src/core/main.c b/src/core/main.c old mode 100644 new mode 100755 index 213fa10..d9adf24 --- a/src/core/main.c +++ b/src/core/main.c @@ -48,12 +48,13 @@ static void sig_usr1(int signo) int main(int argc, char **argv) { int ret; + dbus_handle_h handle = NULL; mainloop = g_main_loop_new(NULL, FALSE); - if (!dbus_handle_init(G_BUS_TYPE_SYSTEM, VIBRATOR_BUS_NAME, NULL, NULL)) { - _E("failed to init dbus connection"); - } + handle = dbus_handle_get_connection(G_BUS_TYPE_SYSTEM, FALSE); + if (!handle) + _E("Fail to get dbus connection");; ret = haptic_probe(); if (ret != 0) { @@ -62,6 +63,12 @@ int main(int argc, char **argv) } haptic_init(); + ret = dbus_handle_request_bus_name(handle, VIBRATOR_BUS_NAME, NULL, NULL); + if (ret <= 0) { + _E("Fail to request bus name"); + dbus_handle_check_owner_name(NULL, VIBRATOR_BUS_NAME); + } + signal(SIGTERM, sig_quit); signal(SIGUSR1, sig_usr1); -- 2.7.4 From d71ff7a4284303eb8195b5e1ec982e7cbffd461f Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Mon, 30 Apr 2018 20:34:27 +0900 Subject: [PATCH 09/16] Fix systemd-assisted dbus activation sequence Change-Id: Ic570da29e8193b56d5c4ab31687743e505d43fe3 Signed-off-by: Hyotaek Shim --- CMakeLists.txt | 1 + packaging/feedbackd.spec | 1 + src/core/main.c | 9 ++++++++- systemd/feedbackd.service | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2c4c8c..8a15676 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,7 @@ SET(PKG_MODULES gio-unix-2.0 capi-system-info libgdbus + libsystemd ) IF(DRIVER STREQUAL gpio) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index c87d08a..39ff443 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -24,6 +24,7 @@ BuildRequires: pkgconfig(gio-unix-2.0) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(capi-system-peripheral-io) BuildRequires: pkgconfig(libgdbus) +BuildRequires: pkgconfig(libsystemd) Requires(post): /usr/bin/vconftool diff --git a/src/core/main.c b/src/core/main.c index d9adf24..92fddc8 100755 --- a/src/core/main.c +++ b/src/core/main.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "core/log.h" #include "core/common.h" @@ -45,6 +46,12 @@ static void sig_usr1(int signo) } } +static void dbus_name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data) +{ + _I("sd_notify(READY=1)"); + sd_notify(0, "READY=1"); +} + int main(int argc, char **argv) { int ret; @@ -63,7 +70,7 @@ int main(int argc, char **argv) } haptic_init(); - ret = dbus_handle_request_bus_name(handle, VIBRATOR_BUS_NAME, NULL, NULL); + ret = dbus_handle_request_bus_name(handle, VIBRATOR_BUS_NAME, dbus_name_acquired, NULL); if (ret <= 0) { _E("Fail to request bus name"); dbus_handle_check_owner_name(NULL, VIBRATOR_BUS_NAME); diff --git a/systemd/feedbackd.service b/systemd/feedbackd.service index 8bd1dc9..e8071f7 100644 --- a/systemd/feedbackd.service +++ b/systemd/feedbackd.service @@ -3,7 +3,7 @@ Description=System Vibrator Daemon After=deviced.service [Service] -BusName=org.tizen.system.vibrator +Type=Notify SmackProcessLabel=System ExecStart=/usr/bin/feedbackd Restart=always -- 2.7.4 From 888bce9cc08df301e3c4af5e79c7045f2d97a916 Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Mon, 30 Apr 2018 20:41:30 +0900 Subject: [PATCH 10/16] Add .gitignore Change-Id: I4376ef23bc81e537f4c628cfae66ebd1994f9a7f Signed-off-by: Hyotaek Shim --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9306ae6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +cscope.files +cscope.out +tags -- 2.7.4 From c266e77cde725d1364540bc7f8e09bfb6ba7c295 Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Mon, 30 Apr 2018 18:39:48 +0900 Subject: [PATCH 11/16] haptic: Remove convert_magnitude_by_conf Change-Id: I47a8cd4049fd9e0b24d3f99bd0267a23854f11e9 Signed-off-by: pr.jung --- CMakeLists.txt | 2 - packaging/feedbackd.spec | 33 ------------ src/haptic/conf/haptic-level3.conf | 15 ------ src/haptic/conf/haptic-level6.conf | 24 --------- src/haptic/haptic.c | 100 +++++++------------------------------ 5 files changed, 18 insertions(+), 156 deletions(-) delete mode 100644 src/haptic/conf/haptic-level3.conf delete mode 100644 src/haptic/conf/haptic-level6.conf diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a15676..273646c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,5 @@ INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/system FILES_MATCHING PATTERN "feedbackd.service") INSTALL(FILES ${CMAKE_SOURCE_DIR}/systemd/org.tizen.system.vibrator.service DESTINATION /usr/share/dbus-1/system-services) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/conf/haptic-level3.conf DESTINATION /etc/feedbackd) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/conf/haptic-level6.conf DESTINATION /etc/feedbackd) ADD_SUBDIRECTORY(src/auto-test) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index 39ff443..8e38701 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -31,9 +31,6 @@ Requires(post): /usr/bin/vconftool Requires: %{name}-compat = %{version}-%{release} Recommends: %{name}-driver-standard = %{version}-%{release} -Requires: configuration-compat = %{version}-%{release} -Recommends: %{name}-conf-level6 = %{version}-%{release} - %description feedback daemon @@ -95,20 +92,6 @@ Conflicts: %{name}-driver-standard %description driver-circle Feedbackd binaries with circle plugin. Required by main feedbackd package -%package conf-level3 -Summary: Feedbackd configuration file -Provides: configuration-compat = %{version}-%{release} -Conflicts: %{name}-conf-level6 -%description conf-level3 -Feedbackd configuration file. - -%package conf-level6 -Summary: Feedbackd configuration file -Provides: configuration-compat = %{version}-%{release} -Conflicts: %{name}-conf-level3 -%description conf-level6 -Feedbackd configuration file. - %package auto-test Summary: Feedbackd auto test tool Group: System/Utilities @@ -280,12 +263,6 @@ if [ "$1" == "0" ]; then systemctl stop feedbackd.service fi -%post conf-level3 -mv %{_sysconfdir}/feedbackd/haptic-level3.conf %{_sysconfdir}/feedbackd/haptic.conf - -%post conf-level6 -mv %{_sysconfdir}/feedbackd/haptic-level6.conf %{_sysconfdir}/feedbackd/haptic.conf - %files -n feedbackd %manifest %{name}.manifest %license LICENSE.Apache-2.0 @@ -319,16 +296,6 @@ mv %{_sysconfdir}/feedbackd/haptic-level6.conf %{_sysconfdir}/feedbackd/haptic.c %manifest %{name}.manifest %{_bindir}/feedbackd.circle -%files conf-level3 -%license LICENSE.Apache-2.0 -%manifest %{name}.manifest -%config %{_sysconfdir}/feedbackd/haptic-level3.conf - -%files conf-level6 -%license LICENSE.Apache-2.0 -%manifest %{name}.manifest -%config %{_sysconfdir}/feedbackd/haptic-level6.conf - %files auto-test %license LICENSE.Apache-2.0 %manifest %{name}.manifest diff --git a/src/haptic/conf/haptic-level3.conf b/src/haptic/conf/haptic-level3.conf deleted file mode 100644 index 6e52318..0000000 --- a/src/haptic/conf/haptic-level3.conf +++ /dev/null @@ -1,15 +0,0 @@ -[Haptic] -# level -# how much does the vibration level to subdivide. -# The max value of vibration level fixed at 100. -# The min value of vibration level fixed at 0. -level=3 - -[level0] -value=0 - -[level1] -value=58 - -[level2] -value=100 diff --git a/src/haptic/conf/haptic-level6.conf b/src/haptic/conf/haptic-level6.conf deleted file mode 100644 index 84271f1..0000000 --- a/src/haptic/conf/haptic-level6.conf +++ /dev/null @@ -1,24 +0,0 @@ -[Haptic] -# level -# how much does the vibration level to subdivide. -# The max value of vibration level fixed at 100. -# The min value of vibration level fixed at 0. -level=6 - -[level0] -value=0 - -[level1] -value=20 - -[level2] -value=40 - -[level3] -value=60 - -[level4] -value=80 - -[level5] -value=100 diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index a352ec2..505a6de 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -33,7 +33,6 @@ #include "core/config-parser.h" #include "haptic.h" -#define HAPTIC_CONF_PATH "/etc/feedbackd/haptic.conf" #define SIGNAL_CHANGE_HARDKEY "ChangeHardkey" #define SIGNAL_POWEROFF_STATE "ChangeState" #define SIGNAL_VIBRATOR_INITIATED "InitiateVibrator" @@ -45,6 +44,8 @@ #define HARDKEY_VIB_DURATION 30 #define HAPTIC_FEEDBACK_STEP 20 #define DEFAULT_FEEDBACK_LEVEL 3 +#define HIGH_FEEDBACK_LEVEL 100 +#define LOW_FEEDBACK_LEVEL 0 /* power on, power off vibration variable */ #define POWER_ON_VIB_DURATION 300 @@ -85,8 +86,6 @@ static enum haptic_type h_type; static bool haptic_disabled; struct haptic_config { - int level; - int *level_arr; int sound_capture; }; @@ -140,28 +139,9 @@ static int haptic_module_load(void) return 0; } -static int convert_magnitude_by_conf(int level) -{ - int i, step; - - assert(level >= 0 && level <= 100); - - step = 100 / (haptic_conf.level-1); - for (i = 0; i < haptic_conf.level; ++i) { - if (level <= i*step) { - _D("level changed : %d -> %d", level, haptic_conf.level_arr[i]); - return haptic_conf.level_arr[i]; - } - } - - _D("play default level"); - return DEFAULT_FEEDBACK_LEVEL * HAPTIC_FEEDBACK_STEP; -} - GVariant *hdbus_get_count(GDBusConnection *conn, const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) - { int ret, val; @@ -349,12 +329,11 @@ GVariant *hdbus_vibrate_monotone(GDBusConnection *conn, g_variant_get(param, "(uiii)", &handle, &duration, &level, &priority); - /* convert as per conf value */ - level = convert_magnitude_by_conf(level); - if (level < 0) { - ret = -EINVAL; - goto exit; - } + if (level < LOW_FEEDBACK_LEVEL) + level = LOW_FEEDBACK_LEVEL; + else if (level > HIGH_FEEDBACK_LEVEL) + level = HIGH_FEEDBACK_LEVEL; + if (priority < PRIORITY_MIN) priority = PRIORITY_MIN; else if (priority > PRIORITY_TOP) @@ -388,12 +367,10 @@ GVariant *hdbus_vibrate_buffer(GDBusConnection *conn, data = g_variant_get_fixed_array(pvar, &size, sizeof(char)); g_variant_unref(pvar); - /* convert as per conf value */ - level = convert_magnitude_by_conf(level); - if (level < 0) { - ret = -EINVAL; - goto exit; - } + if (level < LOW_FEEDBACK_LEVEL) + level = LOW_FEEDBACK_LEVEL; + else if (level > HIGH_FEEDBACK_LEVEL) + level = HIGH_FEEDBACK_LEVEL; ret = h_ops->vibrate_buffer(handle, data, iteration, level, priority, &e_handle); if (ret >= 0) @@ -430,12 +407,10 @@ GVariant *hdbus_vibrate_effect(GDBusConnection *conn, g_variant_get(param, "(usii)", &handle, &pattern, &level, &priority); - /* convert as per conf value */ - level = convert_magnitude_by_conf(level); - if (level < 0) { - ret = -EINVAL; - goto exit; - } + if (level < LOW_FEEDBACK_LEVEL) + level = LOW_FEEDBACK_LEVEL; + else if (level > HIGH_FEEDBACK_LEVEL) + level = HIGH_FEEDBACK_LEVEL; if (priority < PRIORITY_MIN) priority = PRIORITY_MIN; else if (priority > PRIORITY_TOP) @@ -742,6 +717,7 @@ static void sound_capturing_cb(keynode_t *key, void *data) haptic_start(); } +/* Left for the case of sound_capture in use static int parse_section(struct parse_result *result, void *user_data, int index) { struct haptic_config *conf = (struct haptic_config *)user_data; @@ -754,21 +730,6 @@ static int parse_section(struct parse_result *result, void *user_data, int index if (MATCH(result->name, "sound_capture")) { conf->sound_capture = atoi(result->value); - } else if (MATCH(result->name, "level")) { - conf->level = atoi(result->value); - if (conf->level < 0 || conf->level >= INT_MAX - 1) { - _E("You must set level with positive number in integer range"); - return -EINVAL; - } - conf->level_arr = calloc(sizeof(int), conf->level); - if (!conf->level_arr) { - _E("failed to allocate memory for level"); - return -errno; - } - } else if (MATCH(result->name, "value")) { - if (index < 0) - return -EINVAL; - conf->level_arr[index] = atoi(result->value); } return 0; @@ -776,10 +737,7 @@ static int parse_section(struct parse_result *result, void *user_data, int index static int haptic_load_config(struct parse_result *result, void *user_data) { - struct haptic_config *conf = (struct haptic_config *)user_data; - char name[NAME_MAX]; int ret; - static int index; if (!result) return 0; @@ -787,7 +745,7 @@ static int haptic_load_config(struct parse_result *result, void *user_data) if (!result->section || !result->name || !result->value) return 0; - /* Parsing 'Haptic' section */ + // Parsing 'Haptic' section if (MATCH(result->section, "Haptic")) { ret = parse_section(result, user_data, -1); if (ret < 0) { @@ -797,22 +755,10 @@ static int haptic_load_config(struct parse_result *result, void *user_data) goto out; } - /* Parsing 'Level' section */ - for (index = 0; index < conf->level; ++index) { - snprintf(name, sizeof(name), "level%d", index); - if (MATCH(result->section, name)) { - ret = parse_section(result, user_data, index); - if (ret < 0) { - _E("failed to parse [level] section : %d", ret); - return ret; - } - goto out; - } - } - out: return 0; } +*/ static const dbus_method_s hdbus_methods[] = { { "GetCount", NULL, "i", hdbus_get_count }, @@ -854,13 +800,6 @@ void haptic_init(void) { int r; - /* get haptic data from configuration file */ - r = config_parse(HAPTIC_CONF_PATH, haptic_load_config, &haptic_conf); - if (r < 0) { - _E("failed to load configuration file(%s) : %d", HAPTIC_CONF_PATH, r); - safe_free(haptic_conf.level_arr); - } - /* init dbus interface */ r = dbus_handle_register_dbus_object(NULL, VIBRATOR_PATH_HAPTIC, &dbus_interface); if (r < 0) @@ -907,9 +846,6 @@ void haptic_exit(void) unsubscribe_dbus_signal(NULL, id_sig_change_hardkey); unsubscribe_dbus_signal(NULL, id_sig_pwr_off_state); - /* release haptic data memory */ - safe_free(haptic_conf.level_arr); - if (!CHECK_VALID_OPS(h_ops, r)) return; -- 2.7.4 From 65c2f634edc2646d483286e3532af3967710b8ea Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Thu, 17 May 2018 13:47:19 +0900 Subject: [PATCH 12/16] dbus-policy: change to default deny policy Change-Id: I8849c0e73c766e9b11ba004c12b7e0b5fff48fca Signed-off-by: sanghyeok.oh --- scripts/feedbackd.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/feedbackd.conf b/scripts/feedbackd.conf index 05f4ece..2ded9e1 100755 --- a/scripts/feedbackd.conf +++ b/scripts/feedbackd.conf @@ -12,6 +12,7 @@ + Date: Wed, 20 Jun 2018 18:08:57 +0900 Subject: [PATCH 13/16] haptic: Remove unused code - Remove standard_mix.c Change-Id: I8d6a567da78bf472a7a0ca72265a6325b497d733 Signed-off-by: pr.jung --- CMakeLists.txt | 2 - packaging/feedbackd.spec | 2 - src/haptic/standard-mix.c | 1085 --------------------------------------------- 3 files changed, 1089 deletions(-) delete mode 100644 src/haptic/standard-mix.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 273646c..3eeb80b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,8 +26,6 @@ ELSEIF(DRIVER STREQUAL standard) SET(SRCS ${SRCS} src/haptic/standard.c src/haptic/standard-vibcore.c) ELSEIF(DRIVER STREQUAL circle) SET(SRCS ${SRCS} src/haptic/circle.c src/haptic/standard-vibcore.c) -ELSEIF(DRIVER STREQUAL mix) - SET(SRCS ${SRCS} src/haptic/standard-mix.c) ENDIF() INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index 8e38701..d33ccfb 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -3,8 +3,6 @@ %bcond_with wayland %bcond_with emulator -%define standard_mix off - Name: feedbackd Summary: Feedbackd Version: 1.0.0 diff --git a/src/haptic/standard-mix.c b/src/haptic/standard-mix.c deleted file mode 100644 index 578a700..0000000 --- a/src/haptic/standard-mix.c +++ /dev/null @@ -1,1085 +0,0 @@ -/* - * feedbackd - * - * Copyright (c) 2016 - 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core/log.h" -#include "core/list.h" -#include "core/config-parser.h" -#include "haptic.h" - -#define MAX_MAGNITUDE 0xFFFF -#define PERIODIC_MAX_MAGNITUDE 0x7FFF /* 0.5 * MAX_MAGNITUDE */ -#define RUMBLE_MAX_MAGNITUDE 0xFFFF - -#define DEV_INPUT "/dev/input" -#define EVENT "event" - -#define BITS_PER_LONG (sizeof(long) * 8) -#define OFF(x) ((x)%BITS_PER_LONG) -#define BIT(x) (1UL<> OFF(bit)) & 1) - -#define MAX_DATA 16 -#define FF_INFO_MAGIC 0xDEADFEED - -#define VIBRATION_CONF_PATH "/usr/share/feedback/vibration_mix.conf" -#define VIBRATION_DURATION_CONF_PATH "/usr/share/feedback/vibration_duration.conf" -#define VIBRATION_WAITING_CONF_PATH "/usr/share/feedback/vibration_waiting.conf" - -struct ff_info_header { - unsigned int magic; - int iteration; - int ff_info_data_count; -}; - -struct ff_info_data { - int type;/* play, stop etc */ - int magnitude; /* strength */ - int length; /* in ms for stop, play*/ -}; - -struct ff_info_buffer { - struct ff_info_header header; - struct ff_info_data data[MAX_DATA]; -}; - -struct ff_info { - int handle; - guint timer; - struct ff_effect effect; - struct ff_info_buffer *ffinfobuffer; - int currentindex; -}; - -struct vibration_table { - char *pattern; - char *duration; - char *waiting; -}; - -struct vibration_config { - char *pattern; - int *data; - int data_len; -}; - -struct haptic_data { - unsigned int handle; - int *duration_config; - int *waiting_config; - int level; - int priority; - int duration_len; - int waiting_len; - int index; - bool stop; -}; - -static int ff_fd; -static dd_list *ff_list; -static dd_list *handle_list; -static dd_list *vib_conf_list; -static dd_list *vib_duration_conf_list; -static dd_list *vib_waiting_conf_list; -static guint duration_timer; -static char ff_path[PATH_MAX]; -static int unique_number; - -struct ff_info *read_from_list(int handle) -{ - struct ff_info *temp; - dd_list *elem; - - DD_LIST_FOREACH(ff_list, elem, temp) { - if (temp->handle == handle) - return temp; - } - return NULL; -} - -static bool check_valid_handle(struct ff_info *info) -{ - struct ff_info *temp; - dd_list *elem; - - DD_LIST_FOREACH(ff_list, elem, temp) { - if (temp == info) - break; - } - - if (!temp) - return false; - return true; -} - -static bool check_fd(int *fd) -{ - int ffd; - - if (*fd > 0) - return true; - - ffd = open(ff_path, O_RDWR); - if (ffd < 0) - return false; - - *fd = ffd; - return true; -} - -static int ff_stop(int fd, struct ff_effect *effect); -static Eina_Bool timer_cb(void *data) -{ - struct ff_info *info = (struct ff_info *)data; - - if (!info) - return G_SOURCE_REMOVE; - - if (!check_valid_handle(info)) - return G_SOURCE_REMOVE; - - _I("stop vibration by timer : id(%d)", info->effect.id); - - /* stop previous vibration */ - ff_stop(ff_fd, &info->effect); - - /* reset timer */ - info->timer = NULL; - - return G_SOURCE_REMOVE; -} - -static int ff_find_device(void) -{ - DIR *dir; - struct dirent *dent; - char ev_path[PATH_MAX]; - unsigned long features[1+FF_MAX/sizeof(unsigned long)]; - int fd, ret; - - dir = opendir(DEV_INPUT); - if (!dir) - return -errno; - - while (1) { - dent = readdir(dir); - if (dent == NULL) - break; - - if (dent->d_type == DT_DIR || - !strstr(dent->d_name, "event")) - continue; - - snprintf(ev_path, sizeof(ev_path), "%s/%s", DEV_INPUT, dent->d_name); - - fd = open(ev_path, O_RDWR); - if (fd < 0) - continue; - - /* get force feedback device */ - memset(features, 0, sizeof(features)); - ret = ioctl(fd, EVIOCGBIT(EV_FF, sizeof(features)), features); - if (ret == -1) { - close(fd); - continue; - } - - if (test_bit(FF_CONSTANT, features)) - _D("%s type : constant", ev_path); - if (test_bit(FF_PERIODIC, features)) - _D("%s type : periodic", ev_path); - if (test_bit(FF_SPRING, features)) - _D("%s type : spring", ev_path); - if (test_bit(FF_FRICTION, features)) - _D("%s type : friction", ev_path); - if (test_bit(FF_RUMBLE, features)) - _D("%s type : rumble", ev_path); - - if (test_bit(FF_RUMBLE, features)) { - memcpy(ff_path, ev_path, strlen(ev_path)); - close(fd); - closedir(dir); - return 0; - } - - close(fd); - } - - closedir(dir); - return -1; -} - -static int ff_init_effect(struct ff_effect *effect) -{ - if (!effect) - return -EINVAL; - - /*Only rumble supported as of now*/ - effect->type = FF_RUMBLE; - effect->replay.length = 0; - effect->replay.delay = 10; - effect->id = -1; - effect->u.rumble.strong_magnitude = 0x8000; - effect->u.rumble.weak_magnitude = 0xc000; - - return 0; -} - -static int ff_set_effect(struct ff_effect *effect, int length, int level) -{ - double magnitude; - - if (!effect) - return -EINVAL; - - magnitude = (double)level/HAPTIC_MODULE_FEEDBACK_MAX; - magnitude *= RUMBLE_MAX_MAGNITUDE; - - _I("info : magnitude(%d) length(%d)", (int)magnitude, length); - - /* set member variables in effect struct */ - effect->u.rumble.strong_magnitude = (int)magnitude; - effect->replay.length = length; /* length millisecond */ - - return 0; -} - -static int ff_play(int fd, struct ff_effect *effect) -{ - struct input_event play; - int ret; - - if (fd < 0 || !effect) { - if (fd < 0) - _E("fail to check fd"); - else - _E("fail to check effect"); - return -EINVAL; - } - - /* upload an effect */ - if (ioctl(fd, EVIOCSFF, effect) == -1) { - _E("fail to ioctl"); - return -errno; - } - - /* play vibration*/ - play.type = EV_FF; - play.code = effect->id; - play.value = 1; /* 1 : PLAY, 0 : STOP */ - - ret = write(fd, (const void *)&play, sizeof(play)); - if (ret == -1) { - _E("fail to write"); - return -errno; - } - - return 0; -} - -static int ff_stop(int fd, struct ff_effect *effect) -{ - struct input_event stop; - int ret; - - if (fd < 0) - return -EINVAL; - - /* Stop vibration */ - stop.type = EV_FF; - stop.code = effect->id; - stop.value = 0; /* 1 : PLAY, 0 : STOP */ - ret = write(fd, (const void *)&stop, sizeof(stop)); - if (ret == -1) - return -errno; - - /* removing an effect from the device */ - if (ioctl(fd, EVIOCRMFF, effect->id) == -1) - return -errno; - - /* reset effect id */ - effect->id = -1; - - return 0; -} - -/* START: Haptic Module APIs */ -static int get_device_count(int *count) -{ - /* suppose there is just one haptic device */ - if (count) - *count = 1; - - return 0; -} - -static int open_device(int device_index, int *device_handle) -{ - struct ff_info *info; - int n; - bool found = false; - dd_list *elem; - - if (!device_handle) - return -EINVAL; - - /* if it is the first element */ - n = DD_LIST_LENGTH(ff_list); - if (n == 0 && !ff_fd) { - _I("First element: open ff driver"); - /* open ff driver */ - ff_fd = open(ff_path, O_RDWR); - if (ff_fd < 0) { - _E("Failed to open %s : %d", ff_path, errno); - return -errno; - } - } - - /* allocate memory */ - info = calloc(sizeof(struct ff_info), 1); - if (!info) { - _E("Failed to allocate memory : %d", errno); - return -errno; - } - - /* initialize ff_effect structure */ - ff_init_effect(&info->effect); - - if (unique_number == INT_MAX) - unique_number = 0; - - while (found != true) { - ++unique_number; - elem = DD_LIST_FIND(handle_list, (gpointer)(long)unique_number); - if (!elem) - found = true; - } - - info->handle = unique_number; - - /* add info to local list */ - DD_LIST_APPEND(ff_list, info); - DD_LIST_APPEND(handle_list, (gpointer)(long)info->handle); - - *device_handle = info->handle; - return 0; -} - -static int close_device(int device_handle) -{ - struct ff_info *info; - int r, n; - - info = read_from_list(device_handle); - if (!info) - return -EINVAL; - - if (!check_valid_handle(info)) - return -EINVAL; - - if (!check_fd(&ff_fd)) - return -ENODEV; - - /* stop vibration */ - r = ff_stop(ff_fd, &info->effect); - if (r < 0) - _I("already stopped or failed to stop effect : %d", r); - - /* unregister existing timer */ - if (r >= 0 && info->timer) { - _D("device handle %d is closed and timer deleted", device_handle); - g_source_remove(info->timer); - info->timer = NULL; - } - - DD_LIST_REMOVE(handle_list, (gpointer)(long)info->handle); - - safe_free(info->ffinfobuffer); - /* remove info from local list */ - DD_LIST_REMOVE(ff_list, info); - safe_free(info); - - /* if it is the last element */ - n = DD_LIST_LENGTH(ff_list); - if (n == 0 && ff_fd) { - _I("Last element: close ff driver"); - /* close ff driver */ - close(ff_fd); - ff_fd = 0; - } - - return 0; -} - -static int vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle) -{ - struct ff_info *info; - int ret; - - info = read_from_list(device_handle); - if (!info) { - _E("fail to check list"); - return -EINVAL; - } - - if (!check_valid_handle(info)) { - _E("fail to check handle"); - return -EINVAL; - } - - if (!check_fd(&ff_fd)) - return -ENODEV; - - /* Zero(0) is the infinitely vibration value */ - if (duration == HAPTIC_MODULE_DURATION_UNLIMITED) - duration = 0; - - /* unregister existing timer */ - if (info->timer) { - ff_stop(ff_fd, &info->effect); - g_source_remove(info->timer); - info->timer = NULL; - } - - /* set effect as per arguments */ - ff_init_effect(&info->effect); - ret = ff_set_effect(&info->effect, duration, feedback); - if (ret < 0) { - _E("failed to set effect(duration:%d, feedback:%d) : %d", - duration, feedback, ret); - return ret; - } - - /* play effect as per arguments */ - ret = ff_play(ff_fd, &info->effect); - if (ret < 0) { - _E("failed to play haptic effect(fd:%d id:%d) : %d", - ff_fd, info->effect.id, ret); - return ret; - } - - /* register timer */ - if (duration) { - info->timer = g_timeout_add(duration, timer_cb, info); - if (!info->timer) - _E("Failed to add timer callback"); - } - - _D("device handle %d effect id : %d %dms", device_handle, info->effect.id, duration); - if (effect_handle) - *effect_handle = info->effect.id; - - return 0; -} - -static gboolean _buffer_play(void *cbdata) -{ - struct ff_info *info = (struct ff_info *)cbdata; - struct ff_info_header *header = &info->ffinfobuffer->header; - struct ff_info_data *data = info->ffinfobuffer->data; - int index = info->currentindex; - int play_type = (index < header->ff_info_data_count) ? data[index].type : 0; - int length = (index < header->ff_info_data_count) ? data[index].length : 1; - int ret; - - ff_set_effect(&info->effect, length, 1); - if (play_type != 0) { - _D("Going to play for %d ms", length); - ret = ff_play(ff_fd, &info->effect); - if (ret < 0) - _D("Failed to play the effect %d", ret); - } else { - _D("Going to stop for %d ms", length); - ret = ff_stop(ff_fd, &info->effect); - if (ret < 0) - _D("Failed to stop the effect %d", ret); - } - - if (info->currentindex < header->ff_info_data_count) { - info->currentindex++; - info->timer = g_timeout_add(length, _buffer_play, info); - } else { - --header->iteration; - if (header->iteration > 0) { - info->currentindex = 0; - info->timer = g_timeout_add(0, _buffer_play, info); - } else - info->timer = NULL; - } - - return G_SOURCE_REMOVE; -} - -static void print_buffer(const unsigned char *vibe_buffer) -{ - struct ff_info_buffer fb; - int i = 0; - memcpy(&fb.header, vibe_buffer, sizeof(struct ff_info_header)); - memcpy(&fb.data, (unsigned char *)vibe_buffer+sizeof(struct ff_info_header), - sizeof(struct ff_info_data) * fb.header.ff_info_data_count); - _D("\nMagic %x\niteration %d\ncount %d\n", fb.header.magic, - fb.header.iteration, fb.header.ff_info_data_count); - - for (i = 0; i < fb.header.ff_info_data_count; i++) - _D("type %d\nmagn 0x%x\nlen %d\n", fb.data[i].type, - fb.data[i].magnitude, fb.data[i].length); -} - -static int vibrate_custom_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle) -{ - struct ff_info *info; - struct ff_info_header *header; - struct ff_info_data *data; - - info = read_from_list(device_handle); - if (!info) - return -EINVAL; - - if (!check_valid_handle(info)) - return -EINVAL; - - if (!check_fd(&ff_fd)) - return -ENODEV; - - if (!info->ffinfobuffer) - info->ffinfobuffer = (struct ff_info_buffer *)calloc(sizeof(struct ff_info_buffer), 1); - if (!info->ffinfobuffer) - return -ENOMEM; - - header = &info->ffinfobuffer->header; - data = info->ffinfobuffer->data; - - memcpy(header, vibe_buffer, sizeof(struct ff_info_header)); - if (header->ff_info_data_count < 0 || header->ff_info_data_count > MAX_DATA) - return -EINVAL; - - memcpy(data, vibe_buffer+sizeof(struct ff_info_header), sizeof(struct ff_info_data) * header->ff_info_data_count); - - info->currentindex = 0; - if (info->timer) - g_source_remove(info->timer); - - if (header->iteration > 0) - _buffer_play(info); - - return 0; -} - -static gboolean haptic_duration_play(void *data) -{ - struct haptic_data *h_data; - double time; - int ret = 0; - int index; - unsigned int v_handle; - int level; - int priority; - int duration; - - - if (!data) - return G_SOURCE_REMOVE; - - if (duration_timer) { - g_source_remove(duration_timer); - duration_timer = 0; - } - - h_data = (struct haptic_data *)data; - if (h_data->stop) { - h_data->stop = false; - free(h_data); - return G_SOURCE_REMOVE; - } - - index = h_data->index; - v_handle = h_data->handle; - level = h_data->level; - priority = h_data->priority; - - if (!h_data->duration_config[index]) { - free(h_data); - return G_SOURCE_REMOVE; - } - - duration = h_data->duration_config[index]; - - h_data->index++; - if (h_data->index > h_data->duration_len - 1) - free(h_data); - else { - if (h_data->index > h_data->waiting_len - 1) - time = duration; - else - time = duration + h_data->waiting_config[index]; - - /*duration_timer = ecore_timer_add(time/1000.0f, haptic_duration_play, (void *)h_data);*/ - duration_timer = g_timeout_add(time, haptic_duration_play, (void *)h_data); - _D("timer: %d", time); - } - - _D("duration: %d", duration); - - ret = vibrate_monotone(v_handle, duration, level, priority, NULL); - if (ret != 0) { - _D("auto stop vibration"); - if (h_data) - h_data->stop = true; - } - return G_SOURCE_REMOVE; -} - -static int vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle) -{ - int magic = 0; - - if (!device_handle) - return -EINVAL; - - if (vibe_buffer) - magic = *(int *)vibe_buffer; - - if (magic == FF_INFO_MAGIC) { - print_buffer(vibe_buffer); - return vibrate_custom_buffer(device_handle, vibe_buffer, iteration, feedback, priority, effect_handle); - } else - return vibrate_monotone(device_handle, 300, feedback, priority, effect_handle); -} - -static int vibrate_effect(int device_handle, const char *pattern, int feedback, int priority) -{ - dd_list *elem1, *elem2; - struct vibration_table *conf_table; - struct vibration_config *conf_duration, *conf_waiting; - struct haptic_data *data; - char *duration = NULL, *waiting = NULL; - int len1, len2; - - if (!device_handle) - return -EINVAL; - - if (!pattern) - return -EINVAL; - - len1 = strlen(pattern) + 1; - DD_LIST_FOREACH(vib_conf_list, elem1, conf_table) { - if (!conf_table->pattern) - continue; - if (strncmp(conf_table->pattern, pattern, len1)) - continue; - duration = conf_table->duration; - waiting = conf_table->waiting; - break; - } - - if (!duration) - return -ENOTSUP; - - len1 = strlen(duration) + 1; - if (!waiting) - len2 = 0; - else - len2 = strlen(waiting) + 1; - DD_LIST_FOREACH(vib_duration_conf_list, elem1, conf_duration) { - if (!conf_duration->pattern) - continue; - if (strncmp(conf_duration->pattern, duration, len1)) - continue; - - data = (struct haptic_data *)malloc(sizeof(struct haptic_data)); - if (!data) { - _E("fail to alloc"); - return -ENOMEM; - } - data->duration_len = 0; - data->waiting_len = 0; - - DD_LIST_FOREACH(vib_waiting_conf_list, elem2, conf_waiting) { - if (!waiting) - break; - if (!conf_waiting->pattern) - continue; - if (strncmp(conf_waiting->pattern, waiting, len2)) - continue; - data->waiting_config = conf_waiting->data; - data->waiting_len = conf_waiting->data_len; - break; - } - data->handle = device_handle; - data->level = feedback; - data->priority = priority; - data->duration_config = conf_duration->data; - data->duration_len = conf_duration->data_len; - data->index = 0; - - haptic_duration_play((void *)data); - break; - } - - return 0; -} - -static int is_supported(const char *pattern) -{ - dd_list *elem; - struct vibration_table *conf; - int ret = 0; - int len; - - if (!pattern) - return -EINVAL; - - len = strlen(pattern) + 1; - DD_LIST_FOREACH(vib_conf_list, elem, conf) { - if (!conf->pattern) - continue; - if (!strncmp(conf->pattern, pattern, len)) { - ret = true; - break; - } - } - - return ret; -} - -static int stop_device(int device_handle) -{ - struct ff_info *info; - int r; - - info = read_from_list(device_handle); - if (!info) - return -EINVAL; - - if (!check_valid_handle(info)) - return -EINVAL; - - if (!check_fd(&ff_fd)) - return -ENODEV; - - /* stop effect */ - r = ff_stop(ff_fd, &info->effect); - if (r < 0) - _E("failed to stop effect(id:%d) : %d", info->effect.id, r); - - /* unregister existing timer */ - if (r >= 0 && info->timer) { - g_source_remove(info->timer); - info->timer = NULL; - } - - return 0; -} - -static int get_device_state(int device_index, int *effect_state) -{ - struct ff_info *info; - dd_list *elem; - int status = false; - - if (!effect_state) - return -EINVAL; - - /* suppose there is just one haptic device */ - DD_LIST_FOREACH(ff_list, elem, info) { - if (info->effect.id >= 0) { - status = true; - break; - } - } - - *effect_state = status; - return 0; -} - -static int create_effect(unsigned char *vibe_buffer, int max_bufsize, const haptic_module_effect_element *elem_arr, int max_elemcnt) -{ - _E("Not supported feature"); - return -EACCES; -} - -static int get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *buffer_duration) -{ - _E("Not supported feature"); - return -EACCES; -} - -static int convert_binary(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path) -{ - _E("Not supported feature"); - return -EACCES; -} -/* END: Haptic Module APIs */ - -static const struct haptic_plugin_ops default_plugin = { - .get_device_count = get_device_count, - .open_device = open_device, - .close_device = close_device, - .vibrate_monotone = vibrate_monotone, - .vibrate_buffer = vibrate_buffer, - .vibrate_effect = vibrate_effect, - .is_supported = is_supported, - .stop_device = stop_device, - .get_device_state = get_device_state, - .create_effect = create_effect, - .get_buffer_duration = get_buffer_duration, - .convert_binary = convert_binary, -}; - -static int vibration_duration_load_config(struct parse_result *result, void *user_data) -{ - struct vibration_config *conf; - char *value; - char *check; - int count = 0; - int len; - int i; - - if (!result) - return 0; - - if (!MATCH(result->section, "Vibration")) - return 0; - - - if (!result->name || !result->value) - return 0; - - conf = (struct vibration_config *)calloc(1, sizeof(struct vibration_config)); - if (!conf) { - _E("fail to alloc"); - return -ENOMEM; - } - - conf->pattern = strdup(result->name); - if (!conf->pattern) - _E("fail to copy %s pattern data", result->name); - - value = result->value; - - if (!value) - len = 0; - else - len = strlen(value); - - if (len == 0) { - DD_LIST_APPEND(vib_duration_conf_list, conf); - return 0; - } - - check = strchr(value, ','); - while (check != NULL) { - count++; - check = strchr(check + 1, ','); - } - - int *duration = (int *)malloc((count + 1) * sizeof(int)); - for (i = 0; i <= count; i++) { - duration[i] = 0; - check = strchr(value, ','); - if (check) { - *check = '\0'; - duration[i] = strtol(value, NULL, 10); - value = check + 1; - } else { - duration[i] = strtol(value, NULL, 10); - break; - } - if (duration[i] == 0) - break; - } - conf->data = duration; - conf->data_len = count + 1; - - DD_LIST_APPEND(vib_duration_conf_list, conf); - - return 0; -} - -static int vibration_waiting_load_config(struct parse_result *result, void *user_data) -{ - struct vibration_config *conf; - char *value; - char *check; - int count = 0; - int len; - int i; - - if (!result) - return 0; - - if (!MATCH(result->section, "Vibration")) - return 0; - - - if (!result->name || !result->value) - return 0; - - conf = (struct vibration_config *)calloc(1, sizeof(struct vibration_config)); - if (!conf) { - _E("fail to alloc"); - return -ENOMEM; - } - - conf->pattern = strdup(result->name); - if (!conf->pattern) - _E("fail to copy %s pattern data", result->name); - - value = result->value; - - if (!value) - len = 0; - else - len = strlen(value); - - if (len == 0) { - DD_LIST_APPEND(vib_waiting_conf_list, conf); - return 0; - } - - check = strchr(value, ','); - while (check != NULL) { - count++; - check = strchr(check + 1, ','); - } - - int *waiting = (int *)malloc((count + 1) * sizeof(int)); - for (i = 0; i <= count; i++) { - waiting[i] = 0; - check = strchr(value, ','); - if (check) { - *check = '\0'; - waiting[i] = strtol(value, NULL, 10); - value = check + 1; - } else { - waiting[i] = strtol(value, NULL, 10); - break; - } - if (waiting[i] == 0) - break; - } - conf->data = waiting; - conf->data_len = count + 1; - - DD_LIST_APPEND(vib_waiting_conf_list, conf); - - return 0; -} - -static int vibration_table_load_config(struct parse_result *result, void *user_data) -{ - struct vibration_table *conf; - char *value; - char *check; - int len; - - if (!result) - return 0; - - if (!MATCH(result->section, "Vibration")) - return 0; - - - if (!result->name || !result->value) - return 0; - - conf = (struct vibration_table *)calloc(1, sizeof(struct vibration_table)); - if (!conf) { - _E("fail to alloc"); - return -ENOMEM; - } - - conf->pattern = strdup(result->name); - if (!conf->pattern) - _E("fail to copy %s pattern data", result->name); - - value = result->value; - - if (!value) - len = 0; - else - len = strlen(value); - - if (len == 0) { - DD_LIST_APPEND(vib_conf_list, conf); - return 0; - } - - check = strchr(value, ','); - - if (check) { - *check = '\0'; - conf->duration = strdup(value); - value = check + 1; - conf->waiting = strdup(value); - } else - conf->duration = strdup(value); - - DD_LIST_APPEND(vib_conf_list, conf); - - return 0; -} - -static bool is_valid(void) -{ - int ret; - - ret = ff_find_device(); - if (ret < 0) { - _E("Do not support standard haptic device"); - return false; - } - ret = config_parse(VIBRATION_CONF_PATH, vibration_table_load_config, NULL); - if (ret < 0) - _E("failed to load configuration file(%s) : %d", VIBRATION_DURATION_CONF_PATH, ret); - ret = config_parse(VIBRATION_DURATION_CONF_PATH, vibration_duration_load_config, NULL); - if (ret < 0) - _E("failed to load configuration file(%s) : %d", VIBRATION_DURATION_CONF_PATH, ret); - ret = config_parse(VIBRATION_WAITING_CONF_PATH, vibration_waiting_load_config, NULL); - if (ret < 0) - _E("failed to load configuration file(%s) : %d", VIBRATION_WAITING_CONF_PATH, ret); - - _I("Support standard haptic device"); - return true; -} - -static const struct haptic_plugin_ops *load(void) -{ - return &default_plugin; -} - -static const struct haptic_ops std_ops = { - .type = HAPTIC_STANDARD, - .is_valid = is_valid, - .load = load, -}; - -HAPTIC_OPS_REGISTER(&std_ops) -- 2.7.4 From d5b1f88b401a759f55000e60529774847742a37f Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Fri, 29 Jun 2018 16:56:45 +0900 Subject: [PATCH 14/16] Minor fix: Type=Notify -> Type=notify Change-Id: I1a9c43235e9d063711ac8561cf01d932d27141cc Signed-off-by: Hyotaek Shim --- systemd/feedbackd.service | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/systemd/feedbackd.service b/systemd/feedbackd.service index e8071f7..5b412e6 100644 --- a/systemd/feedbackd.service +++ b/systemd/feedbackd.service @@ -3,7 +3,7 @@ Description=System Vibrator Daemon After=deviced.service [Service] -Type=Notify +Type=notify SmackProcessLabel=System ExecStart=/usr/bin/feedbackd Restart=always -- 2.7.4 From e2f013146add167d73520066fab1e7f977753ce2 Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Mon, 9 Jul 2018 17:17:42 +0900 Subject: [PATCH 15/16] Check return value for vconf_notify_key_changed and vconf_ignore_key_changed Change-Id: I1213ecda36a2aa028ef5e7eade6d542309d1a8a2 Signed-off-by: pr.jung --- src/haptic/haptic.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index 505a6de..818210c 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -824,8 +824,11 @@ void haptic_init(void) "", NULL); /* add watch for sound capturing value */ - if (haptic_conf.sound_capture) - vconf_notify_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb, NULL); + if (haptic_conf.sound_capture) { + r = vconf_notify_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb, NULL); + if (r != 0) + _W("Add watch for VCONFKEY_RECORDER_STATE failed"); + } /* Initialize vibration_handle (Use vibration now) */ cur_h_data.handle = INVALID_HANDLE; @@ -839,8 +842,11 @@ void haptic_exit(void) int r; /* remove watch */ - if (haptic_conf.sound_capture) - vconf_ignore_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb); + if (haptic_conf.sound_capture) { + r = vconf_ignore_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb); + if (r != 0) + _W("Remove watch for VCONFKEY_RECORDER_STATE failed"); + } /* unregister notifier for below each event */ unsubscribe_dbus_signal(NULL, id_sig_change_hardkey); -- 2.7.4 From b620f8911b6748c805f0f485d5da6ad7ed1693de Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Wed, 28 Nov 2018 15:25:12 +0900 Subject: [PATCH 16/16] haptic: Request power lock before vibration - When device goes suspend mode after vibration started, vibration stops immediately. To prevent this, feedbackd request power lock during vibration time. Change-Id: I04bca81481c979ffaeb8d1676c33ec562841ab69 Signed-off-by: pr.jung --- CMakeLists.txt | 1 + packaging/feedbackd.spec | 1 + src/haptic/standard-vibcore.c | 13 +++++++++++++ 3 files changed, 15 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3eeb80b..ad93c9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ SET(PKG_MODULES capi-system-info libgdbus libsystemd + capi-system-device ) IF(DRIVER STREQUAL gpio) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index d33ccfb..0c9fc13 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -23,6 +23,7 @@ BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(capi-system-peripheral-io) BuildRequires: pkgconfig(libgdbus) BuildRequires: pkgconfig(libsystemd) +BuildRequires: pkgconfig(capi-system-device) Requires(post): /usr/bin/vconftool diff --git a/src/haptic/standard-vibcore.c b/src/haptic/standard-vibcore.c index f8982c9..528875f 100644 --- a/src/haptic/standard-vibcore.c +++ b/src/haptic/standard-vibcore.c @@ -19,6 +19,7 @@ #include #include +#include #include "core/log.h" #include "core/list.h" @@ -30,6 +31,7 @@ struct vibration_config { char *pattern; + int pattern_duration; dd_list *data; }; @@ -67,6 +69,7 @@ static int vibration_load_config(struct parse_result *result, void *user_data) return -ENOMEM; } + conf->pattern_duration = 0; conf->pattern = strdup(result->name); if (!conf->pattern) { _E("fail to copy %s pattern data", result->name); @@ -111,6 +114,7 @@ static int vibration_load_config(struct parse_result *result, void *user_data) data->duration = strtol(value, NULL, 10); len = len - strlen(value) - 1; value = check + 1; + conf->pattern_duration += data->duration; } check = strchr(value, 'W'); @@ -119,6 +123,7 @@ static int vibration_load_config(struct parse_result *result, void *user_data) data->wait = strtol(value, NULL, 10); len = len - strlen(value) - 1; value = check + 1; + conf->pattern_duration += data->wait; } DD_LIST_APPEND(conf->data, data); @@ -227,6 +232,7 @@ int standard_vibrate_effect(int device_handle, const char *pattern, int feedback dd_list *elem; struct vibration_config *conf; size_t len; + int ret; if (device_handle < 0) return -EINVAL; @@ -250,6 +256,13 @@ int standard_vibrate_effect(int device_handle, const char *pattern, int feedback cur_h_data.priority = priority; cur_h_data.stop = false; _D("Play %s", conf->pattern); + + if (conf->pattern_duration <= 0) + break; + + ret = device_power_request_lock(POWER_LOCK_CPU, conf->pattern_duration); + if (ret != DEVICE_ERROR_NONE) + _E("Failed to request power lock"); haptic_duration_play((void *)&cur_h_data); break; } -- 2.7.4