haptic: A haptic handle is independent of other handle 29/133429/2
authorpr.jung <pr.jung@samsung.com>
Mon, 12 Jun 2017 07:24:04 +0000 (16:24 +0900)
committerpr.jung <pr.jung@samsung.com>
Wed, 14 Jun 2017 06:05:42 +0000 (15:05 +0900)
- Only the same handle with which plays vibration can stop vibration
- Needs to remove duration_timer when stopping vibration

Change-Id: I291e90e3248bdb647cdc08b1594aebf4681e5b9d
Signed-off-by: pr.jung <pr.jung@samsung.com>
src/haptic/circle.c
src/haptic/haptic.c
src/haptic/haptic.h
src/haptic/standard-vibcore.c
src/haptic/standard-vibcore.h
src/haptic/standard.c

index d78ddba..c0737e3 100644 (file)
@@ -35,6 +35,8 @@
 #define CIRCLE_ON_PATH             "/sys/class/sec/motor/motor_on"
 #define CIRCLE_OFF_PATH            "/sys/class/sec/motor/motor_off"
 
+#define BUF_SIZE                  8
+
 static int fd_play = -1, fd_stop = -1;
 static dd_list *handle_list;
 static Ecore_Timer *stop_timer;
@@ -56,10 +58,28 @@ static bool find_from_list(int handle)
 static Eina_Bool timer_cb(void *data)
 {
        int device_handle = (int)(long)data;
+       int ret;
+       char buf[BUF_SIZE];
+       bool found;
+
        _I("stop vibration by timer");
 
+       found = find_from_list(device_handle);
+       if (!found)
+               return ECORE_CALLBACK_CANCEL;
+
        /* stop previous vibration */
-       stop_device(device_handle);
+       if (fd_stop < 0) {
+               fd_stop = open(CIRCLE_OFF_PATH, O_RDONLY);
+               if (fd_stop < 0)
+                       return ECORE_CALLBACK_CANCEL;
+       }
+       ret = read(fd_stop, buf, BUF_SIZE);
+       if (ret < 0) {
+               _E("failed to stop");
+               return ECORE_CALLBACK_CANCEL;
+       }
+       stop_timer = NULL;
 
        return ECORE_CALLBACK_CANCEL;
 }
@@ -172,7 +192,7 @@ static int close_device(int device_handle)
 static int vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle)
 {
        int ret;
-       char buf[8];
+       char buf[BUF_SIZE];
        bool found;
 
        found = find_from_list(device_handle);
@@ -193,7 +213,7 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p
                stop_device(device_handle);
 
        /* play vibration */
-       ret = read(fd_play, buf, 8);
+       ret = read(fd_play, buf, BUF_SIZE);
        if (ret < 0) {
                _E("failed to play");
                return -errno;
@@ -220,19 +240,27 @@ static int vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, i
 static int stop_device(int device_handle)
 {
        int ret;
-       char buf[8];
+       char buf[BUF_SIZE];
        bool found;
 
        found = find_from_list(device_handle);
        if (!found)
                return -EINVAL;
 
+       if (vibration_handle > 0 && vibration_handle != device_handle) {
+               _E("Only same handle can stop current vibration");
+               return -EPERM;
+       }
+
+       /* Remove duration_timer for vibrate_effect */
+       standard_vibrate_close();
+
        if (fd_stop < 0) {
                fd_stop = open(CIRCLE_OFF_PATH, O_RDONLY);
                if (fd_stop < 0)
                        return -ENODEV;
        }
-       ret = read(fd_stop, buf, 8);
+       ret = read(fd_stop, buf, BUF_SIZE);
        if (ret < 0) {
                _E("failed to stop");
                return -errno;
index 1b78083..2f52e62 100644 (file)
@@ -918,6 +918,9 @@ void haptic_init(void)
        /* add watch for sound capturing value */
        if (haptic_conf.sound_capture)
                vconf_notify_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb, NULL);
+
+       /* Initialize vibration_handle (Use vibration now) */
+       vibration_handle = INVALID_HANDLE;
 }
 
 void haptic_exit(void)
index 26056a5..7ab6a7f 100644 (file)
@@ -46,6 +46,10 @@ struct haptic_ops {
        void (*release)(void);
 };
 
+#define INVALID_HANDLE -1
+
+int vibration_handle;
+
 void add_haptic(const struct haptic_ops *ops);
 void remove_haptic(const struct haptic_ops *ops);
 
index e80d145..4cebcf7 100644 (file)
@@ -24,6 +24,7 @@
 #include "core/log.h"
 #include "core/list.h"
 #include "core/config-parser.h"
+#include "haptic.h"
 #include "standard-vibcore.h"
 
 #define VIBRATION_CONF_PATH        "/usr/share/feedback/vibration.conf"
@@ -179,14 +180,16 @@ static Eina_Bool haptic_duration_play(void *data)
        struct duration_data *node;
        int ret = 0;
 
-       if (!data)
-               goto out;
-
        if (duration_timer) {
                ecore_timer_del(duration_timer);
                duration_timer = NULL;
        }
 
+       if (!data) {
+               vibration_handle = INVALID_HANDLE;
+               goto out;
+       }
+
        h_data = (struct haptic_data *)data;
        if (h_data->stop) {
                h_data->stop = false;
@@ -205,7 +208,8 @@ static Eina_Bool haptic_duration_play(void *data)
                if (node->wait && next) {
                        h_data->vibration_data = next;
                        duration_timer = ecore_timer_add((node->duration + node->wait)/1000.0f, haptic_duration_play, (void *)h_data);
-               }
+               } else
+                       duration_timer = ecore_timer_add((node->duration + node->wait)/1000.0f, haptic_duration_play, NULL);
 
                ret = real_vibrate_monotone(h_data->handle, node->duration, h_data->level, h_data->priority, NULL);
                if (!next) {
@@ -256,6 +260,7 @@ int standard_vibrate_effect(int device_handle, const char *pattern, int feedback
                data->level = feedback;
                data->priority = priority;
                data->stop = false;
+               vibration_handle = device_handle;
                _D("Play %s", conf->pattern);
                haptic_duration_play((void *)data);
                break;
@@ -266,7 +271,10 @@ int standard_vibrate_effect(int device_handle, const char *pattern, int feedback
 
 int standard_vibrate_close()
 {
+       vibration_handle = INVALID_HANDLE;
+
        if (duration_timer) {
+               _I("Remove duration_timer");
                ecore_timer_del(duration_timer);
                duration_timer = NULL;
        }
index 9f792b1..a55d7d2 100644 (file)
 
 typedef int (*t_vibrate_monotone)(int device_handle, int duration, int feedback, int priority, int *effect_handle);
 
-int standard_config_parse();
+int standard_config_parse(void);
 int standard_is_supported(const char *pattern);
 int standard_vibrate_effect(int device_handle, const char *pattern, int feedback, int priority);
 int standard_set_vib_function(t_vibrate_monotone func);
-int standard_vibrate_close();
+int standard_vibrate_close(void);
 
 #endif  /* __FEEDBACKD_STANDARD_VIBCORE_H__ */
index 008bdcd..74658d0 100644 (file)
@@ -590,6 +590,14 @@ static int stop_device(int device_handle)
        if (!check_fd(&ff_fd))
                return -ENODEV;
 
+       if (vibration_handle > 0 && vibration_handle != info->handle) {
+               _E("Only same handle can stop current vibration");
+               return -EPERM;
+       }
+
+       /* Remove duration_timer for vibrate_effect */
+       standard_vibrate_close();
+
        /* stop effect */
        r = ff_stop(ff_fd, &info->effect);
        if (r < 0)