*/
#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;
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)
{
/**
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,
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;
+}
#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
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();
API int feedback_deinitialize(void)
{
+ int ret;
+
pthread_mutex_lock(&fmutex);
if (!init_cnt) {
pthread_mutex_unlock(&fmutex);
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();