From 2ac7e22abdf003279401415233c4b3af6598d003 Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Wed, 16 Jan 2019 15:30:24 +0900 Subject: [PATCH] Use idler callback for VibrateMonotone - Return immdiately after parameters checked Change-Id: I21b37f0eeb7c7a99454039a8004a97724c064c43 Signed-off-by: pr.jung --- src/haptic/circle.c | 6 +-- src/haptic/emulator.c | 7 +-- src/haptic/external.c | 6 ++- src/haptic/gpio_haptic.c | 5 +- src/haptic/haptic-plugin-intf.h | 2 +- src/haptic/haptic.c | 61 ++++++++++++++++++++---- src/haptic/haptic.h | 1 + src/haptic/standard-vibcore.c | 3 +- src/haptic/standard-vibcore.h | 2 +- src/haptic/standard.c | 102 +++++++++++++++++++++++++--------------- 10 files changed, 128 insertions(+), 67 deletions(-) diff --git a/src/haptic/circle.c b/src/haptic/circle.c index 30d3d0d..f17007a 100644 --- a/src/haptic/circle.c +++ b/src/haptic/circle.c @@ -177,7 +177,7 @@ static int close_device(int device_handle) return 0; } -static int vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle) +static int vibrate_monotone(int device_handle, int duration, int feedback, int priority) { int ret; char buf[BUF_SIZE]; @@ -212,12 +212,10 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p stop_timer = g_timeout_add(duration, timer_cb, (void *)(long)device_handle); if (!stop_timer) - _E("Failed to add timer callback"); + _E("Handle %d Failed to add timer callback", device_handle); } _D("device handle %d %dms", device_handle, duration); - if (effect_handle) - *effect_handle = device_handle; return 0; } diff --git a/src/haptic/emulator.c b/src/haptic/emulator.c index fdcc2e2..326444c 100644 --- a/src/haptic/emulator.c +++ b/src/haptic/emulator.c @@ -24,8 +24,6 @@ #include "core/list.h" #include "haptic.h" -#define DEFAULT_EFFECT_HANDLE 0xFFFA - static dd_list *handle_list; static int unique_number = 0; @@ -69,7 +67,7 @@ static int close_device(int device_handle) return 0; } -static int vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle) +static int vibrate_monotone(int device_handle, int duration, int feedback, int priority) { dd_list *elem; @@ -77,9 +75,6 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p if (!elem) return -EINVAL; - if (effect_handle) - *effect_handle = DEFAULT_EFFECT_HANDLE; - return 0; } diff --git a/src/haptic/external.c b/src/haptic/external.c index 32eb6b3..3e4b4e0 100644 --- a/src/haptic/external.c +++ b/src/haptic/external.c @@ -36,10 +36,12 @@ static const struct haptic_plugin_ops *plugin_intf; static bool is_valid(void) { struct stat buf; + int ret; const struct haptic_plugin_ops *(*get_haptic_plugin_interface) () = NULL; - if (stat(HAPTIC_MODULE_PATH, &buf)) { - _E("file(%s) is not presents", HAPTIC_MODULE_PATH); + ret = stat(HAPTIC_MODULE_PATH, &buf); + if (ret < 0) { + _E("stat file(%s) error : %d", HAPTIC_MODULE_PATH, errno); goto error; } diff --git a/src/haptic/gpio_haptic.c b/src/haptic/gpio_haptic.c index da213a3..8b7ff7b 100644 --- a/src/haptic/gpio_haptic.c +++ b/src/haptic/gpio_haptic.c @@ -206,7 +206,7 @@ static int gpio_haptic_close_device(int handle) return 0; } -static int gpio_haptic_vibrate_monotone(int handle, int duration, int level, int priority, int *e_handle) +static int gpio_haptic_vibrate_monotone(int handle, int duration, int level, int priority) { bool found; @@ -243,9 +243,6 @@ static int gpio_haptic_vibrate_monotone(int handle, int duration, int level, int } _D("device handle %d %dms", handle, duration); - if (e_handle) - *e_handle = handle; - return 0; } diff --git a/src/haptic/haptic-plugin-intf.h b/src/haptic/haptic-plugin-intf.h index f3d0e11..cd6c6bf 100644 --- a/src/haptic/haptic-plugin-intf.h +++ b/src/haptic/haptic-plugin-intf.h @@ -26,7 +26,7 @@ struct haptic_plugin_ops { int (*get_device_count) (int*); int (*open_device) (int, int*); int (*close_device) (int); - int (*vibrate_monotone) (int, int, int, int, int*); + int (*vibrate_monotone) (int, int, int, int); int (*vibrate_effect) (int, const char*, int, int); int (*is_supported) (const char*); int (*stop_device) (int); diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index 4a60b85..b01cd96 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -82,6 +82,13 @@ struct vibrate_effect_info { int priority; }; +struct vibrate_monotone_info { + unsigned int handle; + int duration; + int level; + int priority; +}; + /* for playing */ static int g_handle; @@ -219,6 +226,11 @@ static struct haptic_info *add_haptic_info(const char *sender) return NULL; info->sender = strdup(sender); + if (!info->sender) { + free(info); + return NULL; + } + DD_LIST_APPEND(haptic_handle_list, info); info->id_watch = dbus_handle_watch_name(sender, NULL, haptic_name_owner_changed, info, NULL); @@ -344,12 +356,26 @@ exit: return g_variant_new("(i)", ret); } +static void vibrate_monotone_idler_cb(void *data) +{ + struct vibrate_monotone_info *vibrate_info = (struct vibrate_monotone_info *)data; + int ret; + + ret = device_power_request_lock(POWER_LOCK_CPU, vibrate_info->duration); + if (ret != DEVICE_ERROR_NONE) + _E("Failed to request power lock"); + h_ops->vibrate_monotone(vibrate_info->handle, vibrate_info->duration, + vibrate_info->level, vibrate_info->priority); + free(vibrate_info); +} + GVariant *hdbus_vibrate_monotone(GDBusConnection *conn, const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { + struct vibrate_monotone_info *vibrate_info; unsigned int handle; - int duration, level, priority, e_handle, ret = 0; + int duration, level, priority, ret = 0; if (!CHECK_VALID_OPS(h_ops, ret)) goto exit; @@ -371,10 +397,25 @@ GVariant *hdbus_vibrate_monotone(GDBusConnection *conn, else if (priority > PRIORITY_TOP) priority = PRIORITY_TOP; - ret = h_ops->vibrate_monotone(handle, duration, level, priority, &e_handle); - if (ret >= 0) - ret = e_handle; + if (duration <= 0) { + _E("Skip vibrate handle %d requested less than 0", handle); + ret = -EINVAL; + goto exit; + } + + vibrate_info = calloc(1, sizeof(struct vibrate_monotone_info)); + if (!vibrate_info) { + _E("failed to allocate memory for vibrate_info"); + ret = -errno; + goto exit; + } + + vibrate_info->handle = handle; + vibrate_info->duration = duration; + vibrate_info->level = level; + vibrate_info->priority = priority; + ret = add_idle_request(vibrate_monotone_idler_cb, (void *)vibrate_info); exit: return g_variant_new("(i)", ret); } @@ -452,8 +493,10 @@ GVariant *hdbus_stop_device(GDBusConnection *conn, if (!CHECK_VALID_OPS(h_ops, ret)) goto exit; - if (haptic_disabled) + if (haptic_disabled) { + _I("Haptic disabled"); goto exit; + } g_variant_get(param, "(u)", &handle); @@ -548,7 +591,7 @@ static void haptic_hardkey_changed_cb(GDBusConnection *conn, GVariant *param, gpointer data) { - int level, status, e_handle, ret; + int level, status, ret; if (!CHECK_VALID_OPS(h_ops, ret)) { ret = haptic_module_load(); @@ -579,7 +622,7 @@ static void haptic_hardkey_changed_cb(GDBusConnection *conn, } ret = h_ops->vibrate_monotone(g_handle, HARDKEY_VIB_DURATION, - level*HAPTIC_FEEDBACK_STEP, PRIORITY_HIGH, &e_handle); + level*HAPTIC_FEEDBACK_STEP, PRIORITY_HIGH); if (ret < 0) _E("fail to vibrate buffer : %d", ret); @@ -595,7 +638,7 @@ static void haptic_poweroff_cb(GDBusConnection *conn, gpointer data) { int type = POWER_OFF_NONE; - int e_handle, ret; + int ret; struct timespec time = {0,}; g_variant_get(param, "(i)", &type); @@ -618,7 +661,7 @@ static void haptic_poweroff_cb(GDBusConnection *conn, _I("Handle %d dur %dms pri %d level %d", g_handle, POWER_OFF_VIB_DURATION, PRIORITY_HIGH, POWER_VIB_FEEDBACK); ret = h_ops->vibrate_monotone(g_handle, POWER_OFF_VIB_DURATION, - POWER_VIB_FEEDBACK, PRIORITY_HIGH, &e_handle); + POWER_VIB_FEEDBACK, PRIORITY_HIGH); if (ret < 0) { _E("fail to vibrate_monotone : %d", ret); return; diff --git a/src/haptic/haptic.h b/src/haptic/haptic.h index 7951d4b..c77d64c 100644 --- a/src/haptic/haptic.h +++ b/src/haptic/haptic.h @@ -20,6 +20,7 @@ #ifndef __FEEDBACKD_HAPTIC_H__ #define __FEEDBACKD_HAPTIC_H__ +#include #include #include "core/common.h" #include "core/list.h" diff --git a/src/haptic/standard-vibcore.c b/src/haptic/standard-vibcore.c index 3f4d851..3e7d0d1 100644 --- a/src/haptic/standard-vibcore.c +++ b/src/haptic/standard-vibcore.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "core/log.h" #include "core/list.h" @@ -479,7 +478,7 @@ static gboolean haptic_duration_play(void *data) duration_timer = g_timeout_add((node->duration + node->wait), haptic_duration_play, (void *)next); - ret = real_vibrate_monotone(cur_h_data.handle, node->duration, level, cur_h_data.priority, NULL); + ret = real_vibrate_monotone(cur_h_data.handle, node->duration, level, cur_h_data.priority); break; } diff --git a/src/haptic/standard-vibcore.h b/src/haptic/standard-vibcore.h index 0d4f254..5f731ba 100644 --- a/src/haptic/standard-vibcore.h +++ b/src/haptic/standard-vibcore.h @@ -20,7 +20,7 @@ #ifndef __FEEDBACKD_STANDARD_VIBCORE_H__ #define __FEEDBACKD_STANDARD_VIBCORE_H__ -typedef int (*t_vibrate_monotone)(int device_handle, int duration, int feedback, int priority, int *effect_handle); +typedef int (*t_vibrate_monotone)(int device_handle, int duration, int feedback, int priority); void standard_config_parse(void); int standard_is_supported(const char *pattern); diff --git a/src/haptic/standard.c b/src/haptic/standard.c index c73840f..4831c06 100644 --- a/src/haptic/standard.c +++ b/src/haptic/standard.c @@ -119,21 +119,25 @@ static bool check_fd(int *fd) return true; } -static int ff_stop(int fd, struct ff_effect *effect); +static int ff_stop(const char *func, int fd, struct ff_effect *effect); static gboolean timer_cb(void *data) { struct ff_info *info = (struct ff_info *)data; - if (!info) + if (!info) { + _E("Failed to check info"); return G_SOURCE_REMOVE; + } - if (!check_valid_handle(info)) + if (!check_valid_handle(info)) { + _E("Failed to check valied info"); return G_SOURCE_REMOVE; + } _I("stop vibration by timer : id(%d)", info->effect.id); /* stop previous vibration */ - ff_stop(ff_fd, &info->effect); + ff_stop(__func__, ff_fd, &info->effect); /* reset timer */ info->timer = 0; @@ -165,8 +169,10 @@ static int ff_find_device(void) snprintf(ev_path, sizeof(ev_path), "%s/%s", DEV_INPUT, dent->d_name); fd = open(ev_path, O_RDWR); - if (fd < 0) + if (fd < 0) { + _E("Failed to open %s(%d)", ev_path, errno); continue; + } /* get force feedback device */ memset(features, 0, sizeof(features)); @@ -236,22 +242,22 @@ static int ff_set_effect(struct ff_effect *effect, int length, int level) return 0; } -static int ff_play(int fd, struct ff_effect *effect) +static int ff_play(const char *func, int fd, struct ff_effect *effect) { struct input_event play; int ret; if (fd < 0 || !effect) { if (fd < 0) - _E("fail to check fd"); + _E("%s: failed to check fd", func); else - _E("fail to check effect"); + _E("%s: failed to check effect", func); return -EINVAL; } /* upload an effect */ if (ioctl(fd, EVIOCSFF, effect) == -1) { - _E("fail to ioctl"); + _E("%s: failed to ioctl", func); return -errno; } @@ -262,19 +268,19 @@ static int ff_play(int fd, struct ff_effect *effect) ret = write(fd, (const void *)&play, sizeof(play)); if (ret == -1) { - _E("fail to write"); + _E("%s: failed to write", func); return -errno; } return 0; } -static int ff_stop(int fd, struct ff_effect *effect) +static int ff_stop(const char *func, int fd, struct ff_effect *effect) { struct input_event stop; int ret; - if (fd < 0) + if (fd < 0 || !effect) return -EINVAL; /* Stop vibration */ @@ -363,14 +369,20 @@ static int close_device(int device_handle) int n; info = read_from_list(device_handle); - if (!info) - return -EINVAL; + if (!info) { + _E("Handle %d failed to check info", device_handle); + return -ENOENT; /* 2 */ + } - if (!check_valid_handle(info)) - return -EINVAL; + if (!check_valid_handle(info)) { + _E("Handle %d failed to check valid handle", device_handle); + return -EINVAL; /* 22 */ + } - if (!check_fd(&ff_fd)) - return -ENODEV; + if (!check_fd(&ff_fd)) { + _E("Handle %d failed to check fd", device_handle); + return -ENODEV; /* 19 */ + } /* stop vibration */ stop_device(device_handle); @@ -394,32 +406,42 @@ static int close_device(int device_handle) return 0; } -static int vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle) +static int vibrate_monotone(int device_handle, int duration, int feedback, int priority) { struct ff_info *info; int ret; + if (priority < cur_h_data.priority) { + _I("Handle %d skip low priority(pre:%d now:%d)", device_handle, cur_h_data.priority, priority); + return 0; + } + info = read_from_list(device_handle); if (!info) { - _E("fail to check list"); + _E("Handle %d failed to check list", device_handle); return -EINVAL; } if (!check_valid_handle(info)) { - _E("fail to check handle"); + _E("Handle %d failed to check handle", device_handle); return -EINVAL; } if (!check_fd(&ff_fd)) return -ENODEV; + if (duration <= 0) { + _I("Handle %d skip requests with duration 0", device_handle); + return 0; + } + /* Zero(0) is the infinitely vibration value */ if (duration == HAPTIC_MODULE_DURATION_UNLIMITED) duration = 0; /* unregister existing timer */ if (info->timer) { - ff_stop(ff_fd, &info->effect); + ff_stop(__func__, ff_fd, &info->effect); g_source_remove(info->timer); info->timer = 0; } @@ -428,16 +450,16 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p ff_init_effect(&info->effect); ret = ff_set_effect(&info->effect, duration, feedback); if (ret < 0) { - _E("failed to set effect(duration:%d, feedback:%d) : %d", - duration, feedback, ret); + _E("Handle %d fail to set effect(duration:%d, feedback:%d) : %d", + device_handle, duration, feedback, ret); return ret; } /* play effect as per arguments */ - ret = ff_play(ff_fd, &info->effect); + ret = ff_play(__func__, ff_fd, &info->effect); if (ret < 0) { - _E("failed to play haptic effect(fd:%d id:%d) : %d", - ff_fd, info->effect.id, ret); + _E("Handle %d fail to play haptic effect(fd:%d id:%d) : %d", + device_handle, ff_fd, info->effect.id, ret); return ret; } @@ -445,12 +467,10 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p if (duration) { info->timer = g_timeout_add(duration, timer_cb, info); if (!info->timer) - _E("Failed to add timer callback"); + _E("Handle %d failed to add timer callback", device_handle); } - _D("device handle %d effect id : %d %dms", device_handle, info->effect.id, duration); - if (effect_handle) - *effect_handle = info->effect.id; + _D("Handle %d effect id : %d %dms", device_handle, info->effect.id, duration); return 0; } @@ -461,14 +481,20 @@ static int stop_device(int device_handle) int r; info = read_from_list(device_handle); - if (!info) - return -EINVAL; + if (!info) { + _E("Handle %d fail to check info", device_handle); + return -ENOENT; /* 2 */ + } - if (!check_valid_handle(info)) - return -EINVAL; + if (!check_valid_handle(info)) { + _E("Handle %d fail to check handle", device_handle); + return -EINVAL; /* 22 */ + } - if (!check_fd(&ff_fd)) - return -ENODEV; + if (!check_fd(&ff_fd)) { + _E("Handle %d fail to check fd", device_handle); + return -ENODEV; /* 19 */ + } if (cur_h_data.handle > 0 && cur_h_data.handle != info->handle) { _E("Only same handle can stop current vibration"); @@ -479,7 +505,7 @@ static int stop_device(int device_handle) standard_vibrate_close(); /* stop effect */ - r = ff_stop(ff_fd, &info->effect); + r = ff_stop(__func__, ff_fd, &info->effect); if (r < 0) _E("failed to stop effect(id:%d) : %d", info->effect.id, r); else -- 2.7.4