Receive signal when deviced-vibrator initiated 50/98450/2 accepted/tizen/3.0/common/20161123.140531 accepted/tizen/3.0/ivi/20161123.082816 accepted/tizen/3.0/mobile/20161123.082723 accepted/tizen/3.0/tv/20161123.082741 accepted/tizen/3.0/wearable/20161123.082754 submit/tizen_3.0/20161121.105249
authorpr.jung <pr.jung@samsung.com>
Thu, 17 Nov 2016 09:57:57 +0000 (18:57 +0900)
committerpr.jung <pr.jung@samsung.com>
Fri, 18 Nov 2016 04:31:07 +0000 (13:31 +0900)
- 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 <pr.jung@samsung.com>
CMakeLists.txt
packaging/libfeedback.spec
src/dbus.c
src/dbus.h
src/feedback.c

index 8995d6f..9b4a3b0 100644 (file)
@@ -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}")
index 13cbfda..06d4ba1 100644 (file)
@@ -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)
index 9123f59..6e61a28 100644 (file)
  */
 #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;
+}
index 65bf222..7d7d9f7 100644 (file)
@@ -21,6 +21,7 @@
 #define __DBUS_H__
 
 #include <gio/gio.h>
+#include <glib.h>
 
 /*
  * 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
index 6b08557..f0ebded 100644 (file)
@@ -25,6 +25,7 @@
 #include "profiles.h"
 #include "devices.h"
 #include "log.h"
+#include "dbus.h"
 
 #ifndef API
 #define API __attribute__ ((visibility("default")))
 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();