haptic: Guarantee device_handle validation when device-vibrator crashs. 88/101788/4 accepted/tizen/3.0/common/20161209.094930 accepted/tizen/3.0/ivi/20161209.002548 accepted/tizen/3.0/mobile/20161209.002515 accepted/tizen/3.0/tv/20161209.002528 accepted/tizen/3.0/wearable/20161209.002538 submit/tizen_3.0/20161208.091728
authorpr.jung <pr.jung@samsung.com>
Fri, 2 Dec 2016 04:31:32 +0000 (13:31 +0900)
committerpr.jung <pr.jung@samsung.com>
Wed, 7 Dec 2016 06:31:31 +0000 (15:31 +0900)
- Add InitiateVibrator signal handler
- Return pointer of handle structure instead of integer value for device_handle

Change-Id: I0fe08ebbd252c12e02afa50d3dbc4343296f97cc
Signed-off-by: pr.jung <pr.jung@samsung.com>
src/dbus.c
src/dbus.h
src/haptic.c

index 15e7051..b5d5757 100644 (file)
 #include "dbus.h"
 
 #define DBUS_REPLY_TIMEOUT     (-1)
+#define SIGNAL_VIBRATOR_INITIATED      "InitiateVibrator"
 
 struct pending_call_data {
        dbus_pending_cb func;
        void *data;
 };
 
+static guint haptic_id = 0;
+
 //LCOV_EXCL_START System Error
 static int g_dbus_error_to_errno(int code)
 {
@@ -345,3 +348,90 @@ int dbus_method_async_with_reply(const char *dest, const char *path,
 
        return 0;
 }
+
+static void haptic_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;
+
+       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;
+
+       restart_callback();
+}
+
+int register_signal_handler(void)
+{
+       GDBusConnection *conn;
+       GError *err = NULL;
+       int result = 0;
+
+       conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+       if (!conn) {
+//LCOV_EXCL_START System Error
+               if (err) {
+                       _E("g_bus_get_sync error : (%d-%s)", err->code, err->message);
+                       result = g_dbus_error_to_errno(err->code);
+                       g_clear_error(&err);
+               }
+               return result;
+//LCOV_EXCL_STOP
+       }
+
+       haptic_id = g_dbus_connection_signal_subscribe(conn,
+                       NULL,
+                       VIBRATOR_INTERFACE_HAPTIC,
+                       NULL,
+                       VIBRATOR_PATH_HAPTIC,
+                       NULL,
+                       G_DBUS_SIGNAL_FLAGS_NONE,
+                       haptic_signal_callback,
+                       NULL,
+                       NULL);
+
+       g_object_unref(conn);
+       if (haptic_id == 0) {
+               _E("Failed to subscrive bus signal");
+               return -EPERM;
+       }
+
+       return 0;
+}
+
+int unregister_signal_handler(void)
+{
+       GDBusConnection *conn;
+       GError *err = NULL;
+       int result = 0;
+
+       conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+       if (!conn) {
+//LCOV_EXCL_START System Error
+               if (err) {
+                       _E("g_bus_get_sync error : (%d-%s)", err->code, err->message);
+                       result = g_dbus_error_to_errno(err->code);
+                       g_clear_error(&err);
+               }
+               return result;
+//LCOV_EXCL_STOP
+       }
+
+       g_dbus_connection_signal_unsubscribe(conn, haptic_id);
+       g_object_unref(conn);
+
+       return 0;
+}
index 41a8805..27a58e0 100644 (file)
@@ -77,4 +77,8 @@ int dbus_method_async_with_reply(const char *dest, const char *path,
                const char *interface, const char *method,
                const char *sig, char *param[], dbus_pending_cb cb, int timeout, void *data);
 
+void restart_callback(void);
+
+int register_signal_handler(void);
+int unregister_signal_handler(void);
 #endif
index b510ffd..2fcf096 100644 (file)
 
 #include <stdio.h>
 #include <errno.h>
+#include <stdlib.h>
 
 #include "haptic.h"
 #include "common.h"
 #include "dbus.h"
+#include "list.h"
 
 #define METHOD_GET_COUNT                       "GetCount"
 #define METHOD_OPEN_DEVICE                     "OpenDevice"
@@ -41,6 +43,13 @@ enum priority_e {
        HAPTIC_PRIORITY_HIGH,
 };
 
+struct haptic_handle {
+       int index;
+       int handle;
+};
+
+static dd_list *handle_list;
+
 int device_haptic_get_count(int *device_number)
 {
        int ret;
@@ -65,11 +74,38 @@ int device_haptic_get_count(int *device_number)
        return DEVICE_ERROR_NONE;
 }
 
+void restart_callback(void)
+{
+       dd_list *elem;
+       char str_index[32];
+       char *arr[1];
+       struct haptic_handle *temp;
+       int ret;
+
+       DD_LIST_FOREACH(handle_list, elem, temp) {
+               snprintf(str_index, sizeof(str_index), "%d", temp->index);
+               arr[0] = str_index;
+               ret = dbus_method_sync(VIBRATOR_BUS_NAME,
+                               VIBRATOR_PATH_HAPTIC, VIBRATOR_INTERFACE_HAPTIC,
+                               METHOD_OPEN_DEVICE, "i", arr);
+               if (ret < 0) {
+                       _E("Failed to open device");
+                       continue;
+               }
+               temp->handle = ret;
+       }
+
+}
+
 int device_haptic_open(int device_index, haptic_device_h *device_handle)
 {
+       dd_list *elem;
+       struct haptic_handle *handle;
+       struct haptic_handle *temp;
        char str_index[32];
        char *arr[1];
        int ret, max;
+       bool found = false;
 
        ret = device_haptic_get_count(&max);
        if (ret < 0)
@@ -91,20 +127,55 @@ int device_haptic_open(int device_index, haptic_device_h *device_handle)
        if (ret < 0)
                return errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
 
-       *device_handle = (haptic_device_h)ret;
+       DD_LIST_FOREACH(handle_list, elem, temp) {
+               if (temp->handle == ret) {
+                       found = true;
+                       temp->index = device_index;
+                       break;
+               }
+       }
+
+       if (!found) {
+               handle = (struct haptic_handle *)malloc(sizeof(struct haptic_handle));
+               handle->handle = ret;
+               handle->index = device_index;
+               DD_LIST_APPEND(handle_list, handle);
+               *device_handle = (haptic_device_h)handle;
+       }
+       if (DD_LIST_LENGTH(handle_list) == 1) {
+               ret = register_signal_handler();
+               if (ret < 0)
+                       _E("Faild to register signal handler");
+       }
+
        return DEVICE_ERROR_NONE;
 }
 
 int device_haptic_close(haptic_device_h device_handle)
 {
+       dd_list *elem;
+       struct haptic_handle *handle = (struct haptic_handle *)device_handle;
+       struct haptic_handle *temp;
        char str_handle[32];
        char *arr[1];
        int ret;
+       bool found = false;
 
        if (!device_handle)
                return DEVICE_ERROR_INVALID_PARAMETER;
 
-       snprintf(str_handle, sizeof(str_handle), "%u", (unsigned int)device_handle);
+       DD_LIST_FOREACH(handle_list, elem, temp) {
+               if (temp->handle != handle->handle)
+                       continue;
+               found = true;
+               break;
+       }
+
+       if (!found)
+               return DEVICE_ERROR_OPERATION_FAILED;
+       DD_LIST_REMOVE(handle_list, handle);
+       snprintf(str_handle, sizeof(str_handle), "%u", (unsigned int)handle->handle);
+       free(handle);
        arr[0] = str_handle;
 
        /* request to deviced to open haptic device */
@@ -114,17 +185,27 @@ int device_haptic_close(haptic_device_h device_handle)
        if (ret < 0)
                return errno_to_device_error(ret); //LCOV_EXCL_LINE System Error
 
+       if (DD_LIST_LENGTH(handle_list) == 0) {
+               ret = unregister_signal_handler();
+               if (ret < 0)
+                       _E("Failed to unregister signal handler");
+       }
+
        return DEVICE_ERROR_NONE;
 }
 
 int device_haptic_vibrate(haptic_device_h device_handle, int duration, int feedback, haptic_effect_h *effect_handle)
 {
+       dd_list *elem;
+       struct haptic_handle *handle = (struct haptic_handle *)device_handle;
+       struct haptic_handle *temp;
        char str_handle[32];
        char str_duration[32];
        char str_feedback[32];
        char str_priority[32];
        char *arr[4];
        int ret, priority;
+       bool found = false;
 
        if (!device_handle)
                return DEVICE_ERROR_INVALID_PARAMETER;
@@ -137,7 +218,16 @@ int device_haptic_vibrate(haptic_device_h device_handle, int duration, int feedb
 
        priority = HAPTIC_PRIORITY_MIN;
 
-       snprintf(str_handle, sizeof(str_handle), "%u", (unsigned int)device_handle);
+       DD_LIST_FOREACH(handle_list, elem, temp) {
+               if (temp != handle)
+                       continue;
+               found = true;
+               break;
+       }
+       if (!found)
+               return DEVICE_ERROR_INVALID_PARAMETER;
+
+       snprintf(str_handle, sizeof(str_handle), "%u", (unsigned int)handle->handle);
        arr[0] = str_handle;
        snprintf(str_duration, sizeof(str_duration), "%d", duration);
        arr[1] = str_duration;
@@ -161,15 +251,28 @@ int device_haptic_vibrate(haptic_device_h device_handle, int duration, int feedb
 
 int device_haptic_stop(haptic_device_h device_handle, haptic_effect_h effect_handle)
 {
+       dd_list *elem;
+       struct haptic_handle *handle = (struct haptic_handle *)device_handle;
+       struct haptic_handle *temp;
        char str_handle[32];
        char *arr[1];
        int ret;
+       bool found = false;
 
        if (!device_handle)
                return DEVICE_ERROR_INVALID_PARAMETER;
 
+       DD_LIST_FOREACH(handle_list, elem, temp) {
+               if (temp != handle)
+                       continue;
+               found = true;
+               break;
+       }
+       if (!found)
+               return DEVICE_ERROR_INVALID_PARAMETER;
+
        /* TODO : support to stop haptic effect */
-       snprintf(str_handle, sizeof(str_handle), "%u", (unsigned int)device_handle);
+       snprintf(str_handle, sizeof(str_handle), "%u", (unsigned int)handle->handle);
        arr[0] = str_handle;
 
        /* request to deviced to open haptic device */