From 19991dc18b5fec2155707dcf326d0d9847786cba Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Thu, 17 Nov 2016 18:57:57 +0900 Subject: [PATCH] Receive signal when deviced-vibrator initiated - When deviced-vibrator restarted, all vibration handle became invalid. So after the restart, apps need to get new handle from deviced-vibrator. - deviced-vibrator let apps knows their initiate condition. Change-Id: Iebcbf4fafcafe8bb36de230d40feff7e8fb58b54 Signed-off-by: pr.jung --- CMakeLists.txt | 2 +- packaging/libfeedback.spec | 1 + src/dbus.c | 147 +++++++++++++++++++++++++++++++++++++++++++++ src/dbus.h | 5 ++ src/feedback.c | 23 +++++++ 5 files changed, 177 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8995d6f..9b4a3b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src) INCLUDE_DIRECTORIES(${FEEDBACK_PROFILE_PATH}/include) INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED vconf mm-keysound dlog glib-2.0 dbus-1) +pkg_check_modules(pkgs REQUIRED vconf mm-keysound dlog glib-2.0 dbus-1 gio-2.0) FOREACH(flag ${pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/packaging/libfeedback.spec b/packaging/libfeedback.spec index 13cbfda..06d4ba1 100644 --- a/packaging/libfeedback.spec +++ b/packaging/libfeedback.spec @@ -14,6 +14,7 @@ BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(mm-keysound) BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gio-2.0) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(dbus-1) BuildRequires: pkgconfig(libtzplatform-config) diff --git a/src/dbus.c b/src/dbus.c index 9123f59..6e61a28 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -40,6 +40,13 @@ */ #define DBUS_MAXIMUM_NAME_LENGTH 255 +#define SIGNAL_VIBRATOR_INITIATED "InitiateVibrator" + +struct feedback_restart_callback { + feedback_restart_cb func; + guint feedback_id; +}; + struct proxy_node { GDBusProxy *proxy; char *dest; @@ -51,6 +58,8 @@ static GList *proxy_pool; static pthread_mutex_t dmutex = PTHREAD_MUTEX_INITIALIZER; static int bus_init; +static dd_list *callback_list; + static int g_dbus_error_to_errno(int code) { /** @@ -165,6 +174,23 @@ static void on_name_vanished(GDBusConnection *connection, pthread_mutex_unlock(&dmutex); } +static GDBusConnection *get_dbus_connection(void) +{ + GError *err = NULL; + static GDBusConnection *conn; + + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + if (!conn) { + if (err) + _D("Fail to get dbus connection: %s", err->message); + else + _D("Fail to get dbus connection"); + return NULL; + } + + return conn; +} + static GDBusProxy *get_proxy_from_proxy_pool(const char *dest, const char *path, const char *interface, @@ -287,3 +313,124 @@ int dbus_method_sync(const char *dest, const char *path, return result; } + +static void feedback_signal_callback(GDBusConnection *conn, + const gchar *sender, + const gchar *path, + const gchar *iface, + const gchar *signal, + GVariant *params, + gpointer user_data) +{ + size_t iface_len, signal_len; + struct feedback_restart_callback *callback; + dd_list *elem; + int ret; + + if (!params || !sender || !path || !iface || !signal) + return; + + iface_len = strlen(iface) + 1; + signal_len = strlen(signal) + 1; + + if (strncmp(iface, VIBRATOR_INTERFACE_HAPTIC, iface_len)) + return; + + if (strncmp(signal, SIGNAL_VIBRATOR_INITIATED, signal_len)) + return; + + DD_LIST_FOREACH(callback_list, elem, callback) { + if (!callback->func) + continue; + ret = callback->func(); + if (ret < 0) + _E("Failed to call restart callback"); + } +} + +int register_signal_handler(feedback_restart_cb func) +{ + GDBusConnection *conn; + guint feedback_id = 0; + struct feedback_restart_callback *callback; + dd_list *elem; + + DD_LIST_FOREACH(callback_list, elem, callback) { + if (callback->func != func) + continue; + if (callback->feedback_id == 0) + continue; + + return -EEXIST; + } + + callback = (struct feedback_restart_callback *)malloc(sizeof(struct feedback_restart_callback)); + if (!callback) { +//LCOV_EXCL_START System Error + _E("malloc() failed"); + return -ENOMEM; +//LCOV_EXCL_STOP + } + + conn = get_dbus_connection(); + if (!conn) { +//LCOV_EXCL_START System Error + free(callback); + _E("Failed to get dbus connection"); + return -EPERM; +//LCOV_EXCL_STOP + } + + feedback_id = g_dbus_connection_signal_subscribe(conn, + NULL, + VIBRATOR_INTERFACE_HAPTIC, + NULL, + NULL, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + feedback_signal_callback, + NULL, + NULL); + if (feedback_id == 0) { + free(callback); + _E("Failed to subscrive bus signal"); + return -EPERM; + } + + callback->func = func; + callback->feedback_id = feedback_id; + + DD_LIST_APPEND(callback_list, callback); + + return 0; +} + +int unregister_signal_handler(feedback_restart_cb func) +{ + GDBusConnection *conn; + struct feedback_restart_callback *callback; + dd_list *elem; + + if (!func) + return -EINVAL; + + conn = get_dbus_connection(); + if (!conn) { +//LCOV_EXCL_START System Error + free(callback); + _E("Failed to get dbus connection"); + return -EPERM; +//LCOV_EXCL_STOP + } + + DD_LIST_FOREACH(callback_list, elem, callback) { + if (callback->func != func) + continue; + if (callback->feedback_id > 0) + g_dbus_connection_signal_unsubscribe(conn, callback->feedback_id); + DD_LIST_REMOVE(callback_list, callback); + free(callback); + } + + return 0; +} diff --git a/src/dbus.h b/src/dbus.h index 65bf222..7d7d9f7 100644 --- a/src/dbus.h +++ b/src/dbus.h @@ -21,6 +21,7 @@ #define __DBUS_H__ #include +#include /* * Device daemon @@ -52,4 +53,8 @@ int dbus_method_sync(const char *dest, const char *path, * Do not invoke g_variant_unref() with result. */ typedef void (*dbus_pending_cb)(void *data, GVariant *result, GError *err); + +typedef int (*feedback_restart_cb)(); +int register_signal_handler(feedback_restart_cb func); +int unregister_signal_handler(feedback_restart_cb func); #endif diff --git a/src/feedback.c b/src/feedback.c index 6b08557..f0ebded 100644 --- a/src/feedback.c +++ b/src/feedback.c @@ -25,6 +25,7 @@ #include "profiles.h" #include "devices.h" #include "log.h" +#include "dbus.h" #ifndef API #define API __attribute__ ((visibility("default"))) @@ -33,8 +34,20 @@ static unsigned int init_cnt; static pthread_mutex_t fmutex = PTHREAD_MUTEX_INITIALIZER; +static int restart_callback() +{ + const struct device_ops *dev; + + dev = find_device(FEEDBACK_TYPE_VIBRATION); + if (dev->init) + dev->init(); + return 0; +} + API int feedback_initialize(void) { + int ret; + pthread_mutex_lock(&fmutex); if (!profile) { _E("there is no valid profile module."); //LCOV_EXCL_LINE @@ -47,6 +60,10 @@ API int feedback_initialize(void) return FEEDBACK_ERROR_NONE; } + ret = register_signal_handler(restart_callback); + if (ret < 0) + _E("Fail to register signal handler: %d", ret); + /* initialize device */ devices_init(); @@ -60,6 +77,8 @@ API int feedback_initialize(void) API int feedback_deinitialize(void) { + int ret; + pthread_mutex_lock(&fmutex); if (!init_cnt) { pthread_mutex_unlock(&fmutex); @@ -71,6 +90,10 @@ API int feedback_deinitialize(void) return FEEDBACK_ERROR_NONE; } + ret = unregister_signal_handler(restart_callback); + if (ret < 0) + _E("Fail to unregister signal handler: %d", ret); + /* deinitialize device */ devices_exit(); -- 2.7.4