From ff90048d95619d9f2780d9be352a2e3f062304b1 Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Tue, 23 Jul 2019 11:49:30 +0900 Subject: [PATCH 01/16] Rearrange feedbackd.service from multi-user.target to delayed.target Change-Id: I587a68efa0caafac48f02fc1f5117432512b698e Signed-off-by: Hyotaek Shim --- packaging/feedbackd.spec | 4 ++-- systemd/feedbackd.service | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index 408e120..1917771 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -221,7 +221,7 @@ pushd build_circle mv %{buildroot}%{_bindir}/feedbackd %{buildroot}%{_bindir}/feedbackd.circle popd -%install_service multi-user.target.wants feedbackd.service +%install_service delayed.target.wants feedbackd.service %post systemctl daemon-reload @@ -290,7 +290,7 @@ mv %{_sysconfdir}/feedbackd/haptic-level6.conf %{_sysconfdir}/feedbackd/haptic.c %license LICENSE.Apache-2.0 %config %{_sysconfdir}/dbus-1/system.d/feedbackd.conf %{_unitdir}/feedbackd.service -%{_unitdir}/multi-user.target.wants/feedbackd.service +%{_unitdir}/delayed.target.wants/feedbackd.service %{_datadir}/dbus-1/system-services/org.tizen.system.vibrator.service %files driver-external diff --git a/systemd/feedbackd.service b/systemd/feedbackd.service index c76326f..50399c5 100644 --- a/systemd/feedbackd.service +++ b/systemd/feedbackd.service @@ -15,4 +15,4 @@ Group=system_fw SupplementaryGroups=input [Install] -WantedBy=multi-user.target +WantedBy=delayed.target -- 2.7.4 From bfe584cfafd9b71222789a03cfebce80ef09d4f9 Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Tue, 6 Aug 2019 11:20:13 +0900 Subject: [PATCH 02/16] Fix exit sequence root@localhost:~# systemctl stop feedbackd.service root@localhost:~# systemctl status feedbackd * feedbackd.service - System Vibrator Daemon Loaded: loaded (/usr/lib/systemd/system/feedbackd.service; disabled; vendor preset: enabled) Active: inactive (dead) since Mon 2018-08-13 08:11:48 KST; 4s ago Process: 804 ExecStart=/usr/bin/feedbackd (code=exited, status=0/SUCCESS) Main PID: 804 (code=exited, status=0/SUCCESS) Aug 13 08:11:47 localhost systemd[1]: Stopping System Vibrator Daemon... Aug 13 08:11:48 localhost feedbackd[804]: g_main_loop_unref: assertion 'loop != NULL' failed Aug 13 08:11:48 localhost systemd[1]: Stopped System Vibrator Daemon. Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable. Change-Id: I24178f135688a8cb5cec55c602baf79853ed37cb Signed-off-by: Hyotaek Shim --- src/core/main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 3134e63..03d1169 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -42,7 +42,6 @@ static void sig_usr1(int signo) if (mainloop) { if (g_main_loop_is_running(mainloop)) g_main_loop_quit(mainloop); - mainloop = NULL; } } @@ -84,8 +83,11 @@ int main(int argc, char **argv) _D("'Haptic' deinitialize."); haptic_exit(); - g_main_loop_unref(mainloop); - mainloop = NULL; + + if (mainloop) { + g_main_loop_unref(mainloop); + mainloop = NULL; + } return 0; } -- 2.7.4 From 1f79808468a052b0516c681530955140b59f9d59 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Wed, 14 Aug 2019 17:23:30 +0900 Subject: [PATCH 03/16] dbus: modified to use revised api Change-Id: I381bd91b255786a0023a8a40dcde068e4886cc4c Signed-off-by: sanghyeok.oh --- src/haptic/haptic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index 8a100fe..932aac5 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -1384,10 +1384,11 @@ void haptic_init(void) return; } - dbus_handle_broadcast_dbus_signal(VIBRATOR_PATH_HAPTIC, + dbus_handle_broadcast_dbus_signal(NULL, + VIBRATOR_PATH_HAPTIC, VIBRATOR_INTERFACE_HAPTIC, SIGNAL_VIBRATOR_INITIATED, - "", NULL); + NULL); /* add watch for sound capturing value */ if (haptic_conf.sound_capture) { -- 2.7.4 From 09b3aa213e8738649db258c63f890cb66c97a79d Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Fri, 16 Aug 2019 10:56:16 +0900 Subject: [PATCH 04/16] dbus: modified to use renamed api change 'dbus_handle_broadcast_dbus_signal' to 'dbus_handle_emit_dbus_signal' Change-Id: I0944bb7ab35f9688bb360612c869070f40b8fd0a Signed-off-by: sanghyeok.oh --- src/haptic/haptic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index 932aac5..3263ed5 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -1384,7 +1384,7 @@ void haptic_init(void) return; } - dbus_handle_broadcast_dbus_signal(NULL, + dbus_handle_emit_dbus_signal(NULL, VIBRATOR_PATH_HAPTIC, VIBRATOR_INTERFACE_HAPTIC, SIGNAL_VIBRATOR_INITIATED, -- 2.7.4 From dbaea2ddcf27c6d3431de4523eb0cd7ed7905715 Mon Sep 17 00:00:00 2001 From: Yunmi Ha Date: Mon, 20 Jan 2020 19:07:33 +0900 Subject: [PATCH 05/16] standard: fix infinite vibration - If feedbackd receives another vibration request without stopping the previous vibration, there's not way to stop the previous one, probably causing infinite vibration. - So, feedbackd should override the previous effect id on a new request to keep a single effect id. Change-Id: I2ab714ac4e5103ca65d3b4697e82240b09d58996 Signed-off-by: Yunmi Ha --- src/haptic/standard.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/haptic/standard.c b/src/haptic/standard.c index af43425..d27139a 100644 --- a/src/haptic/standard.c +++ b/src/haptic/standard.c @@ -73,6 +73,7 @@ static dd_list *ff_list; static dd_list *handle_list; static char ff_path[PATH_MAX]; static int unique_number; +static int current_effect_id = -1; static int stop_device(int device_handle); @@ -253,10 +254,14 @@ static int ff_play(int fd, struct ff_effect *effect) } /* upload an effect */ - if (ioctl(fd, EVIOCSFF, effect) == -1) { - _E("Failed to ioctl"); - return -errno; - } + if (current_effect_id == -1) { + if (ioctl(fd, EVIOCSFF, effect) == -1) { + _E("Failed to ioctl"); + return -errno; + } + current_effect_id = effect->id; + } else + effect->id = current_effect_id; /* play vibration*/ play.type = EV_FF; @@ -280,6 +285,12 @@ static int ff_stop(int fd, struct ff_effect *effect) if (fd < 0 || !effect) return -EINVAL; + if (effect->id == -1) { + if (current_effect_id == -1) + return 0; + effect->id = current_effect_id; + } + /* Stop vibration */ stop.type = EV_FF; stop.code = effect->id; @@ -294,6 +305,7 @@ static int ff_stop(int fd, struct ff_effect *effect) /* reset effect id */ effect->id = -1; + current_effect_id = -1; return 0; } -- 2.7.4 From ed71799f0f78b76481cb8e8910baf8d3b9fb7d8a Mon Sep 17 00:00:00 2001 From: Yunmi Ha Date: Tue, 4 Feb 2020 16:35:55 +0900 Subject: [PATCH 06/16] haptic: fix standard pattern parsing issue Change-Id: I8f5af6554b26c7262a3455dd09d7b83ec56bcdc2 Signed-off-by: Yunmi Ha --- src/haptic/haptic.c | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index 3263ed5..f34e3f3 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -246,9 +246,11 @@ static int insert_raw_data_format(dd_list **conf_data, char *value) static int get_config_data(int count, bool *packed, char *val, unsigned int *pattern_duration, struct duration_data *update) { static int duration = 0; + static int intensity = 0; int value; + int ret; - if (count > 2 || count <= 0) { + if (count > 4 || count <= 0) { _E("Invalid parameter: count is invalid"); return -EINVAL; } @@ -260,33 +262,36 @@ static int get_config_data(int count, bool *packed, char *val, unsigned int *pat get_pattern_property(&val, 'C', &value); - if (count == 1) { + ret = count; + if (count == 1) { //duration duration = value; *pattern_duration += duration; if (*pattern_duration > VIB_LOCK_TIMEOUT_MAX) { _D("Max pattern duration."); *pattern_duration = VIB_LOCK_TIMEOUT_MAX; - } - return count; - } - - if (value > INTENSITY_BASE_RATE) - value = INTENSITY_BASE_RATE; - if (*packed == false) { - update->duration = duration; - update->intensity = value; - *packed = true; - return 0; - } - if (value == 0) - update->wait = duration; - else - update->wait = 0; - *packed = false; - duration = 0; + } else if (count == 2) { + /* if intensity is 0, duration use for wait(off) time */ + if (value > INTENSITY_BASE_RATE) + value = INTENSITY_BASE_RATE; + intensity = value; + if (*packed == false) { + update->duration = duration; + update->intensity = intensity; + *packed = true; + } else { + if (intensity == 0) + update->wait = duration; + else + update->wait = 0; + *packed = false; + duration = 0; + ret = -1; + } + } else if (count == 4) + ret = 0; - return -1; + return ret; } /* -- 2.7.4 From 0a468ea1d8e39db6e56d90709ed934c392dd09ee Mon Sep 17 00:00:00 2001 From: Yunmi Ha Date: Thu, 6 Feb 2020 19:37:10 +0900 Subject: [PATCH 07/16] standard : fix svace issue Change-Id: I04decbdb6ac5abc876e266c9a7abd08a8ec2b443 Signed-off-by: Yunmi Ha --- src/haptic/standard.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/haptic/standard.c b/src/haptic/standard.c index d27139a..51d7f2a 100644 --- a/src/haptic/standard.c +++ b/src/haptic/standard.c @@ -195,6 +195,7 @@ static int ff_find_device(void) if (test_bit(FF_RUMBLE, features)) { memcpy(ff_path, ev_path, strlen(ev_path)); + ff_path[strlen(ev_path)] = '\0'; close(fd); closedir(dir); return 0; -- 2.7.4 From 5023c80e09539d854365a6b67f563f8b9ed8db48 Mon Sep 17 00:00:00 2001 From: Yunmi Ha Date: Thu, 20 Feb 2020 10:42:26 +0900 Subject: [PATCH 08/16] haptic: remove "ChangeHardkey" signal subscription Change-Id: I8ea6d7b33cb7bc4b0314c90fad7fc8746f8c4532 Signed-off-by: Yunmi Ha --- src/haptic/haptic.c | 56 ----------------------------------------------------- 1 file changed, 56 deletions(-) diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index f34e3f3..fa2e33c 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -38,7 +38,6 @@ #define VIBRATION_CONF_PATH FEEDBACK_BASE_PATH"vibration.conf" #define HAPTIC_CONF_PATH "/etc/feedbackd/haptic.conf" -#define SIGNAL_CHANGE_HARDKEY "ChangeHardkey" #define SIGNAL_POWEROFF_STATE "ChangeState" #define SIGNAL_VIBRATOR_INITIATED "InitiateVibrator" @@ -1154,52 +1153,6 @@ static int haptic_internal_exit(void) return h_ops->close_device(g_handle); } -static void haptic_hardkey_changed_cb(GDBusConnection *conn, - const gchar *sender, - const gchar *path, - const gchar *iface, - const gchar *name, - GVariant *param, - gpointer data) -{ - int level, status, ret; - - if (!CHECK_VALID_OPS(h_ops, ret)) { - ret = haptic_module_load(); - if (ret < 0) - return; - } - - if (!g_handle) - haptic_internal_init(); - - /* if haptic is stopped, do not play vibration */ - if (haptic_disabled) - return; - - if (vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &status) < 0) { - _E("Failed to get VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL."); - status = 1; - } - - /* when turn off haptic feedback option */ - if (!status) - return; - - ret = vconf_get_int(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, &level); - if (ret < 0) { - _E("Failed to get VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT."); - level = HARDKEY_VIB_FEEDBACK; - } - - ret = h_ops->vibrate_monotone(g_handle, HARDKEY_VIB_DURATION, - level*HAPTIC_FEEDBACK_STEP, PRIORITY_HIGH); - if (ret < 0) - _E("Failed to vibrate buffer: %d", ret); - - return; -} - static void haptic_poweroff_cb(GDBusConnection *conn, const gchar *sender, const gchar *path, @@ -1357,7 +1310,6 @@ int haptic_probe(void) return haptic_module_load(); } -guint id_sig_change_hardkey; guint id_sig_pwr_off_state; void haptic_init(void) @@ -1376,13 +1328,6 @@ void haptic_init(void) if (r < 0) _E("Failed to init hdbus interface and method: %d", r); - /* register notifier for below each event */ - id_sig_change_hardkey = subscribe_dbus_signal(NULL, DEVICED_PATH_KEY, DEVICED_INTERFACE_KEY, SIGNAL_CHANGE_HARDKEY, haptic_hardkey_changed_cb, NULL, NULL); - if (id_sig_change_hardkey <= 0) { - _E("Failed to register signal handler: %d", r); - return; - } - id_sig_pwr_off_state = subscribe_dbus_signal(NULL, DEVICED_PATH_POWEROFF, DEVICED_INTERFACE_POWEROFF, SIGNAL_POWEROFF_STATE, haptic_poweroff_cb, NULL, NULL); if (id_sig_pwr_off_state <= 0) { _E("Failed to register signal handler: %d", r); @@ -1421,7 +1366,6 @@ void haptic_exit(void) } /* unregister notifier for below each event */ - unsubscribe_dbus_signal(NULL, id_sig_change_hardkey); unsubscribe_dbus_signal(NULL, id_sig_pwr_off_state); /* release haptic data memory */ -- 2.7.4 From 27ce4f3718747f1d6ae4a161d63d150c29562582 Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Wed, 26 Feb 2020 19:39:06 +0900 Subject: [PATCH 09/16] Set feedback replay delay as zero for standard driver Change-Id: Id067d152f4ab2ae0540c60d4408fc59ef4555280 Signed-off-by: Hyotaek Shim --- src/haptic/standard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haptic/standard.c b/src/haptic/standard.c index 51d7f2a..07779f7 100644 --- a/src/haptic/standard.c +++ b/src/haptic/standard.c @@ -216,7 +216,7 @@ static int ff_init_effect(struct ff_effect *effect) /*Only rumble supported as of now*/ effect->type = FF_RUMBLE; effect->replay.length = 0; - effect->replay.delay = 10; + effect->replay.delay = 0; effect->id = -1; effect->u.rumble.strong_magnitude = 0; -- 2.7.4 From 5ee0ad79431301ce2b235759c2a1c83a4f626018 Mon Sep 17 00:00:00 2001 From: Yunmi Ha Date: Mon, 17 Feb 2020 19:05:07 +0900 Subject: [PATCH 10/16] standard: Support multi effect pattern - Remove rescaling code of level - Add intensity, overdrive, frequency parameters for play - Change rumble structure interface with kernel Change-Id: I68a5862ee19f7278e6b15cf947258605d299ae17 Signed-off-by: Yunmi Ha --- src/haptic/circle.c | 2 +- src/haptic/emulator.c | 2 +- src/haptic/gpio_haptic.c | 18 +++++- src/haptic/haptic-plugin-intf.h | 2 +- src/haptic/haptic.c | 133 ++++++++++++++++++++++++++++------------ src/haptic/standard.c | 45 ++++++++------ 6 files changed, 139 insertions(+), 63 deletions(-) diff --git a/src/haptic/circle.c b/src/haptic/circle.c index 02a8760..42fa1f7 100644 --- a/src/haptic/circle.c +++ b/src/haptic/circle.c @@ -180,7 +180,7 @@ static int close_device(int device_handle) return 0; } -static int vibrate_monotone(int device_handle, int duration, int feedback, int priority) +static int vibrate_monotone(int device_handle, int duration, int frequency, int overdrive, int level, int intensity, int priority) { int ret; char buf[BUF_SIZE]; diff --git a/src/haptic/emulator.c b/src/haptic/emulator.c index 31496e9..21b1dee 100644 --- a/src/haptic/emulator.c +++ b/src/haptic/emulator.c @@ -67,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) +static int vibrate_monotone(int device_handle, int duration, int frequency, int overdrive, int level, int intensity, int priority) { dd_list *elem; diff --git a/src/haptic/gpio_haptic.c b/src/haptic/gpio_haptic.c index 29b8134..2ba2b88 100644 --- a/src/haptic/gpio_haptic.c +++ b/src/haptic/gpio_haptic.c @@ -67,6 +67,9 @@ #define LRA_LIBRARY_E 6 #define TS2200_LIBRARY_F 7 +#define MAX_LEVEL 2 +#define MAX_INTENSITY 10000 + static peripheral_i2c_h device_handle = NULL; static dd_list *handle_list; @@ -205,9 +208,14 @@ static int gpio_haptic_close_device(int handle) return 0; } -static int gpio_haptic_vibrate_monotone(int handle, int duration, int level, int priority) +static int gpio_haptic_vibrate_monotone(int handle, int duration, int frequency, int overdrive, int level, int intensity, int priority) { bool found; + int feedback; + int max_level; + + if (level <= 0) + return -EINVAL; found = find_from_list(handle); if (!found) @@ -227,11 +235,17 @@ static int gpio_haptic_vibrate_monotone(int handle, int duration, int level, int if (stop_timer) gpio_haptic_stop_device(handle); + max_level = (level <= MAX_LEVEL)? MAX_LEVEL: level; + if (intensity) + feedback = ((level/max_level) * intensity) / 100; + else + feedback = ((level/max_level) * MAX_INTENSITY) / 100; + /* play vibration */ peripheral_i2c_write_register_byte(device_handle, DRV2605L_REGISTER_LIBRARY, TS2200_LIBRARY_A); /* continuously vibrate*/ peripheral_i2c_write_register_byte(device_handle, DRV2605L_REGISTER_MODE, MODE_REALTIME_PLAYBACK); - peripheral_i2c_write_register_byte(device_handle, DRV2605L_REGISTER_RTPINPUT, (uint8_t)level); + peripheral_i2c_write_register_byte(device_handle, DRV2605L_REGISTER_RTPINPUT, (uint8_t)feedback); /* register timer */ if (duration) { diff --git a/src/haptic/haptic-plugin-intf.h b/src/haptic/haptic-plugin-intf.h index 4c039a7..119c471 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 (*vibrate_monotone) (int, int, int, int, int, int, int); int (*stop_device) (int); }; diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index fa2e33c..bf7410c 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -37,6 +37,8 @@ #define STANDARD_FILE_PATH FEEDBACK_BASE_PATH"vibration/" #define VIBRATION_CONF_PATH FEEDBACK_BASE_PATH"vibration.conf" +#define PATTERN_DEFAULT_MONOTONE "FEEDBACK_PATTERN_DEFAULT" + #define HAPTIC_CONF_PATH "/etc/feedbackd/haptic.conf" #define SIGNAL_POWEROFF_STATE "ChangeState" #define SIGNAL_VIBRATOR_INITIATED "InitiateVibrator" @@ -88,6 +90,8 @@ struct vibration_config { struct duration_data { int duration; int intensity; + int frequency; + int overdrive; int wait; }; @@ -115,6 +119,7 @@ struct vibrate_monotone_info { unsigned int handle; int duration; int level; + int intensity; int priority; }; @@ -140,6 +145,7 @@ struct haptic_config { }; static struct haptic_config haptic_conf; +static struct duration_data haptic_default_data; static int haptic_start(void); static int haptic_stop(void); @@ -170,7 +176,7 @@ static int insert_conf_data(dd_list **conf_data, struct duration_data *update) memcpy(data, update, sizeof(struct duration_data)); /* insert vibration pattern data */ // to debug : - // _D("%dD%dI%dF%dO%dW", data->duration, data->intensity, data->frequency, data->overdriving, data->wait); + // _D("%dD%dI%dF%dO%dW", data->duration, data->intensity, data->frequency, data->overdrive, data->wait); DD_LIST_APPEND(*conf_data, data); return 0; } @@ -222,6 +228,7 @@ static int insert_raw_data_format(dd_list **conf_data, char *value) get_pattern_property(&iter, 'I', &update.intensity); if (update.intensity > INTENSITY_BASE_RATE) update.intensity = INTENSITY_BASE_RATE; + get_pattern_property(&iter, 'F', &update.frequency); get_pattern_property(&iter, 'W', &update.wait); if (update.duration == 0 && update.wait == 0) { @@ -262,40 +269,54 @@ static int get_config_data(int count, bool *packed, char *val, unsigned int *pat get_pattern_property(&val, 'C', &value); ret = count; - if (count == 1) { //duration + switch (count) { + case 1: /* D */ duration = value; *pattern_duration += duration; if (*pattern_duration > VIB_LOCK_TIMEOUT_MAX) { _D("Max pattern duration."); *pattern_duration = VIB_LOCK_TIMEOUT_MAX; } - } else if (count == 2) { - /* if intensity is 0, duration use for wait(off) time */ + break; + case 2: /* I or W */ if (value > INTENSITY_BASE_RATE) value = INTENSITY_BASE_RATE; intensity = value; if (*packed == false) { update->duration = duration; update->intensity = intensity; + break; + } + /* if intensity is 0, duration use for wait(off) time */ + if (intensity == 0) + update->wait = duration; + else + update->wait = 0; + *packed = false; + duration = 0; + intensity = 0; + ret = -1; + break; + case 3: /* F */ + if (intensity != 0) + update->frequency = value; + break; + case 4: /* O */ + if (intensity != 0) { + update->overdrive = value; *packed = true; - } else { - if (intensity == 0) - update->wait = duration; - else - update->wait = 0; - *packed = false; - duration = 0; - ret = -1; } - } else if (count == 4) ret = 0; - + break; + default: + break; + } return ret; } /* - duration, intensity, frequency, overdriving - waiting duration, intensity=0, frequency, overdriving + duration, intensity, frequency, overdrive + waiting duration, intensity=0, frequency, overdrive 85,10000, 90,0, 105,10000, @@ -503,6 +524,27 @@ void pattern_config_parse(void) load_standard_vibration_patterns(); } +static void get_default_haptic_data() +{ + dd_list *elem; + struct vibration_config *conf; + + memset(&haptic_default_data, 0, sizeof(struct duration_data)); + + DD_LIST_FOREACH(vib_conf_list, elem, conf) { + if (!conf->pattern) + continue; + if (strcmp(conf->pattern, PATTERN_DEFAULT_MONOTONE)) + continue; + + if (conf->data) + memcpy(&haptic_default_data, conf->data->data, sizeof(struct duration_data)); + + break; + } + _D("Default haptic data: intensity=%d, frequency=%d", haptic_default_data.intensity, haptic_default_data.frequency); +} + static int haptic_module_load(void) { struct haptic_ops *ops; @@ -510,6 +552,7 @@ static int haptic_module_load(void) int r; pattern_config_parse(); + get_default_haptic_data(); /* find valid plugin */ DD_LIST_FOREACH(h_head, elem, ops) { if (ops->is_valid && ops->is_valid()) { @@ -535,6 +578,7 @@ static int haptic_module_load(void) return 0; } +/* static int convert_magnitude_by_conf(int level) { int i, step; @@ -555,7 +599,7 @@ static int convert_magnitude_by_conf(int level) _D("Play default level."); return DEFAULT_FEEDBACK_LEVEL * HAPTIC_FEEDBACK_STEP; } - +*/ GVariant *hdbus_get_count(GDBusConnection *conn, const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) @@ -800,8 +844,12 @@ static void vibrate_monotone_idler_cb(void *data) if (ret != DEVICE_ERROR_NONE) _E("Failed to request power lock."); + _D("Handle(%d) play=%dms, level=%d, intensity=%d, frequency=%d)", + cur_h_data.handle, vibrate_info->duration, cur_h_data.level, + vibrate_info->intensity, haptic_default_data.frequency); + duration_timer = g_timeout_add(vibrate_info->duration, _cb, NULL); - h_ops->vibrate_monotone(cur_h_data.handle, vibrate_info->duration, cur_h_data.level, cur_h_data.priority); + h_ops->vibrate_monotone(cur_h_data.handle, vibrate_info->duration, haptic_default_data.frequency, 0, cur_h_data.level, vibrate_info->intensity, cur_h_data.priority); free(vibrate_info); } @@ -812,7 +860,7 @@ GVariant *hdbus_vibrate_monotone(GDBusConnection *conn, { struct vibrate_monotone_info *vibrate_info; unsigned int handle; - int duration, level, priority, ret = 0; + int duration, level, intensity, priority, ret = 0; if (!CHECK_VALID_OPS(h_ops, ret)) goto exit; @@ -820,11 +868,9 @@ GVariant *hdbus_vibrate_monotone(GDBusConnection *conn, if (haptic_disabled) goto exit; - g_variant_get(param, "(uiii)", &handle, &duration, &level, &priority); + g_variant_get(param, "(uiii)", &handle, &duration, &intensity, &priority); - /* convert as per conf value */ - level = convert_magnitude_by_conf(level); - if (level < 0) { + if (intensity < 0) { ret = -EINVAL; goto exit; } @@ -840,6 +886,12 @@ GVariant *hdbus_vibrate_monotone(GDBusConnection *conn, goto exit; } + if (vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, &level) < 0) { + _E("Failed to get '"VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT"' value."); + ret = -EINVAL; + goto exit; + } + vibrate_info = calloc(1, sizeof(struct vibrate_monotone_info)); if (!vibrate_info) { _E("Failed to allocate memory for vibrate_info."); @@ -849,7 +901,8 @@ GVariant *hdbus_vibrate_monotone(GDBusConnection *conn, vibrate_info->handle = handle; vibrate_info->duration = duration; - vibrate_info->level = level; + vibrate_info->level = (level/2) + 1; + vibrate_info->intensity = intensity * 100; // 1~100 (API spec) vibrate_info->priority = priority; ret = add_idle_request(vibrate_monotone_idler_cb, (void *)vibrate_info); @@ -861,7 +914,6 @@ static gboolean haptic_duration_play(void *data) { dd_list *head, *n, *next; struct duration_data *node; - int level; int ret = 0; if (duration_timer) { @@ -889,9 +941,9 @@ static gboolean haptic_duration_play(void *data) } DD_LIST_FOREACH_SAFE(head, n, next, node) { - _D("Handle(%d) play=%dms and Wait=%dms %s type.", + _D("Handle(%d) play=%dms and Wait=%dms %s type. (level=%d, intensity=%d, frequency=%d)", cur_h_data.handle, node->duration, node->wait, - cur_h_data.unlimit ? "Unlimit" : "Once"); + cur_h_data.unlimit ? "Unlimit" : "Once", cur_h_data.level, node->intensity, node->frequency); if ((node->duration + node->wait) <= 0) { if (!cur_h_data.unlimit) { cur_h_data.handle = INVALID_HANDLE; @@ -903,14 +955,9 @@ static gboolean haptic_duration_play(void *data) } } - if (node->intensity) - level = (cur_h_data.level * node->intensity) / INTENSITY_BASE_RATE; - else - level = cur_h_data.level; - duration_timer = g_timeout_add((node->duration + node->wait), haptic_duration_play, (void *)next); - ret = h_ops->vibrate_monotone(cur_h_data.handle, node->duration, level, cur_h_data.priority); + ret = h_ops->vibrate_monotone(cur_h_data.handle, node->duration, node->frequency, node->overdrive, cur_h_data.level, node->intensity, cur_h_data.priority); break; } @@ -1006,12 +1053,11 @@ GVariant *hdbus_vibrate_pattern(GDBusConnection *conn, g_variant_get(param, "(usii)", &handle, &pattern, &level, &priority); - /* convert as per conf value */ - level = convert_magnitude_by_conf(level); if (level < 0) { ret = -EINVAL; goto exit; } + if (priority < PRIORITY_MIN) priority = PRIORITY_MIN; else if (priority > PRIORITY_TOP) @@ -1162,7 +1208,7 @@ static void haptic_poweroff_cb(GDBusConnection *conn, gpointer data) { int type = POWER_OFF_NONE; - int ret; + int ret, level; struct timespec time = {0,}; g_variant_get(param, "(i)", &type); @@ -1181,11 +1227,18 @@ static void haptic_poweroff_cb(GDBusConnection *conn, if (!g_handle) haptic_internal_init(); + if (vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, &level) < 0) { + _E("Failed to get '"VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT"' vconf value."); + return; + } + level = (level/2) + 1; + /* power off vibration */ - _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); + _I("Handle=%d dur=%dms pri=%d level=%d intensity=%d frequency=%d", + g_handle, POWER_OFF_VIB_DURATION, PRIORITY_HIGH, level, + POWER_VIB_FEEDBACK * 100, haptic_default_data.frequency); + ret = h_ops->vibrate_monotone(g_handle, POWER_OFF_VIB_DURATION, haptic_default_data.frequency, 0, + level, POWER_VIB_FEEDBACK * 100, PRIORITY_HIGH); if (ret < 0) { _E("Failed to vibrate_monotone: %d", ret); return; diff --git a/src/haptic/standard.c b/src/haptic/standard.c index 07779f7..78e1326 100644 --- a/src/haptic/standard.c +++ b/src/haptic/standard.c @@ -43,6 +43,9 @@ #define MAX_DATA 16 #define FF_INFO_MAGIC 0xDEADFEED +#define SET_OVERDRIVE_BIT(x,value) (x |= ((value > 0)? 1: 0)<<14) +#define SET_LEVEL_BIT(x,value) (x |= (value<<13)) + struct ff_info_header { unsigned int magic; int iteration; @@ -194,8 +197,7 @@ static int ff_find_device(void) _D("'%s' type: rumble", ev_path); if (test_bit(FF_RUMBLE, features)) { - memcpy(ff_path, ev_path, strlen(ev_path)); - ff_path[strlen(ev_path)] = '\0'; + memcpy(ff_path, ev_path, strlen(ev_path)+1); close(fd); closedir(dir); return 0; @@ -213,34 +215,41 @@ static int ff_init_effect(struct ff_effect *effect) if (!effect) return -EINVAL; - /*Only rumble supported as of now*/ effect->type = FF_RUMBLE; effect->replay.length = 0; effect->replay.delay = 0; effect->id = -1; effect->u.rumble.strong_magnitude = 0; + effect->u.rumble.weak_magnitude = 0; return 0; } -static int ff_set_effect(struct ff_effect *effect, int length, int level) +static int ff_set_effect(struct ff_effect *effect, int duration, int level, int intensity, int frequency, int overdrive) { - double magnitude; - if (!effect) { _E("There is no valid effect."); return -EINVAL; } - magnitude = (double)level/HAPTIC_MODULE_FEEDBACK_MAX; - magnitude *= RUMBLE_MAX_MAGNITUDE; + /* + __u16 strong_magnitude; // strong_magnitude[15:15] = 0 (Reserved) + // strong_magnitude[14:14] = Overdrive : 0 (Off) or 1 (On) + // strong_magnitude[13:0] = Intensity Value : 0 (Stop) or 1 ~ 10000 (Intensity) + __u16 weak_magnitude; // weak_magnitude[15:13] = Intensity Level : 1 ~ 5 + // weak_magnitude[12:0] = Frequency : 0 ~ 8191 (0 ~ 819.1 Hz) + */ + + effect->u.rumble.strong_magnitude = intensity; + SET_OVERDRIVE_BIT(effect->u.rumble.strong_magnitude, overdrive); - _I("magnitude=%d length=%d", (int)magnitude, length); + effect->u.rumble.weak_magnitude = frequency; + SET_LEVEL_BIT(effect->u.rumble.weak_magnitude, level); /* set member variables in effect struct */ - effect->u.rumble.strong_magnitude = (int)magnitude; - effect->replay.length = length; /* length millisecond */ + effect->replay.length = duration; /* length millisecond */ + //_D("rumble data: strong_magnitude = 0x%x, weak_magnitude = 0x%x", effect->u.rumble.strong_magnitude, effect->u.rumble.weak_magnitude); return 0; } @@ -416,19 +425,19 @@ static int close_device(int device_handle) return 0; } -static int vibrate_monotone(int device_handle, int duration, int feedback, int priority) +static int vibrate_monotone(int device_handle, int duration, int frequency, int overdrive, int level, int intensity, int priority) { struct ff_info *info; int ret; info = read_from_list(device_handle); if (!info) { - _E("Handle %d failed to check list", device_handle); + _E("Handle %d failed to check list.", device_handle); return -EINVAL; } if (!check_valid_handle(info)) { - _E("Handle %d failed to check handle", device_handle); + _E("Handle %d failed to check handle.", device_handle); return -EINVAL; } @@ -436,7 +445,7 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p return -ENODEV; if (duration <= 0) { - _I("Handle %d skip requests with duration 0", device_handle); + _I("Handle %d skip requests with duration 0.", device_handle); return 0; } @@ -453,10 +462,10 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p /* set effect as per arguments */ ff_init_effect(&info->effect); - ret = ff_set_effect(&info->effect, duration, feedback); + ret = ff_set_effect(&info->effect, duration, level, intensity, frequency, overdrive); if (ret < 0) { - _E("Handle %d fail to set effect(duration:%d, feedback:%d) : %d", - device_handle, duration, feedback, ret); + _E("Handle %d fail to set effect(duration:%d, level:%d, intensity:%d, frequency:%d, overdrive:%d) : %d", + device_handle, duration, level, intensity, frequency, overdrive, ret); return ret; } -- 2.7.4 From 22cd53444765ca48d7f92cca668d85ba3f73b638 Mon Sep 17 00:00:00 2001 From: Yunmi Ha Date: Wed, 18 Mar 2020 11:03:38 +0900 Subject: [PATCH 11/16] Support standard pattern for default Change-Id: I13f56ab2f0e60c3a0f17a48b1cb1a9fe4c65bc20 Signed-off-by: Yunmi Ha --- src/haptic/haptic.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index bf7410c..ba00047 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -528,14 +528,21 @@ static void get_default_haptic_data() { dd_list *elem; struct vibration_config *conf; + char pattern[PATH_MAX] = {0,}; memset(&haptic_default_data, 0, sizeof(struct duration_data)); + snprintf(pattern, sizeof(pattern), "%s", PATTERN_DEFAULT_MONOTONE); DD_LIST_FOREACH(vib_conf_list, elem, conf) { if (!conf->pattern) continue; - if (strcmp(conf->pattern, PATTERN_DEFAULT_MONOTONE)) + if (strcmp(conf->pattern, pattern)) + continue; + + if (conf->standard) { + snprintf(pattern, sizeof(pattern), "%s", conf->standard); continue; + } if (conf->data) memcpy(&haptic_default_data, conf->data->data, sizeof(struct duration_data)); @@ -869,6 +876,7 @@ GVariant *hdbus_vibrate_monotone(GDBusConnection *conn, goto exit; g_variant_get(param, "(uiii)", &handle, &duration, &intensity, &priority); + _D("param (uiii): handle=%u, duration=%d, intensity=%d, priority=%d", handle, duration, intensity, priority); if (intensity < 0) { ret = -EINVAL; -- 2.7.4 From 979938abbaa6fe670fb714f5976dafe972bc545a Mon Sep 17 00:00:00 2001 From: Yunmi Ha Date: Tue, 31 Mar 2020 15:18:57 +0900 Subject: [PATCH 12/16] Check vibration feature before the running - If vibration feature is false, feedbackd will not be run. Change-Id: I6c8234c5a93bb65167b01a7257d9e16ae0f4ac8c Signed-off-by: Yunmi Ha --- src/core/main.c | 16 ++++++++++++++-- systemd/feedbackd.service | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 03d1169..be0d5db 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -19,15 +19,19 @@ #include #include -#include #include -#include +#include + +#include #include +#include #include "core/log.h" #include "core/common.h" #include "haptic/haptic.h" +#define VIBRATION_FEATURE "http://tizen.org/feature/feedback.vibration" + static GMainLoop *mainloop = NULL; static void sig_quit(int signo) @@ -55,6 +59,13 @@ int main(int argc, char **argv) { int ret; dbus_handle_h handle = NULL; + bool haptic_avail = false; + + ret = system_info_get_platform_bool(VIBRATION_FEATURE, &haptic_avail); + if ((ret < 0) || !haptic_avail) { + _I("Vibration feature is not supported."); + return 0; + } mainloop = g_main_loop_new(NULL, FALSE); @@ -65,6 +76,7 @@ int main(int argc, char **argv) ret = haptic_probe(); if (ret != 0) { _E("'Haptic' probe fail."); + g_main_loop_unref(mainloop); return ret; } haptic_init(); diff --git a/systemd/feedbackd.service b/systemd/feedbackd.service index 50399c5..7b381da 100644 --- a/systemd/feedbackd.service +++ b/systemd/feedbackd.service @@ -5,7 +5,7 @@ Description=System Vibrator Daemon Type=notify SmackProcessLabel=System ExecStart=/usr/bin/feedbackd -Restart=always +Restart=on-failure RestartSec=0 KillSignal=SIGUSR1 CapabilityBoundingSet=~CAP_MAC_ADMIN -- 2.7.4 From ef058b862059bccbf496e556551b76ea1996182f Mon Sep 17 00:00:00 2001 From: Yunmi Ha Date: Mon, 6 Apr 2020 13:47:43 +0900 Subject: [PATCH 13/16] Add log for stop_device command Change-Id: I67b7660e2040581eb2b23019171f89ec7717524f Signed-off-by: Yunmi Ha --- src/haptic/haptic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index ba00047..93c1352 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -1119,6 +1119,7 @@ GVariant *hdbus_stop_device(GDBusConnection *conn, } ret = h_ops->stop_device(handle); + _I("Stop the device(handle=%u) :%d", handle, ret); /* Remove duration_timer for vibrate_effect */ clear_current_data(); -- 2.7.4 From 6853c878260a4b60c0a47e66457431052c8948f6 Mon Sep 17 00:00:00 2001 From: Yunmi Ha Date: Wed, 8 Apr 2020 12:34:54 +0900 Subject: [PATCH 14/16] Add sd_notify code before the exit Change-Id: I990d0bf0194d1a9c6b04c9b751d8b85e52295a3c Signed-off-by: Yunmi Ha --- src/core/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/main.c b/src/core/main.c index be0d5db..ff068c8 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -64,6 +64,7 @@ int main(int argc, char **argv) ret = system_info_get_platform_bool(VIBRATION_FEATURE, &haptic_avail); if ((ret < 0) || !haptic_avail) { _I("Vibration feature is not supported."); + sd_notify(0, "READY=1"); return 0; } -- 2.7.4 From 52db7e5e70694e764ae0b59995ebe124c7b24240 Mon Sep 17 00:00:00 2001 From: Yunmi Ha Date: Mon, 13 Apr 2020 12:08:37 +0900 Subject: [PATCH 15/16] Add INFO log about play/stop vibration Change-Id: Id6587a5c93f674887e596a461af8925c94650642 Signed-off-by: Yunmi Ha --- src/haptic/haptic.c | 2 +- src/haptic/standard.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index 93c1352..b35703f 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -949,7 +949,7 @@ static gboolean haptic_duration_play(void *data) } DD_LIST_FOREACH_SAFE(head, n, next, node) { - _D("Handle(%d) play=%dms and Wait=%dms %s type. (level=%d, intensity=%d, frequency=%d)", + _I("Handle(%d) play=%dms and Wait=%dms %s type. (level=%d, intensity=%d, frequency=%d)", cur_h_data.handle, node->duration, node->wait, cur_h_data.unlimit ? "Unlimit" : "Once", cur_h_data.level, node->intensity, node->frequency); if ((node->duration + node->wait) <= 0) { diff --git a/src/haptic/standard.c b/src/haptic/standard.c index 78e1326..60b2a6d 100644 --- a/src/haptic/standard.c +++ b/src/haptic/standard.c @@ -477,6 +477,8 @@ static int vibrate_monotone(int device_handle, int duration, int frequency, int return ret; } + _I("Play vibration. Handle %d effect id : %d %dms", device_handle, info->effect.id, duration); + /* register timer */ if (duration) { info->timer = g_timeout_add(duration, timer_cb, info); @@ -484,8 +486,6 @@ static int vibrate_monotone(int device_handle, int duration, int frequency, int _E("Handle %d failed to add timer callback", device_handle); } - _D("Handle %d effect id : %d %dms", device_handle, info->effect.id, duration); - return 0; } @@ -520,7 +520,7 @@ static int stop_device(int device_handle) if (r < 0) _E("failed to stop effect(id:%d) : %d", info->effect.id, r); else - _D("succeed to stop effect"); + _I("Stop vibration by request. id(%d)", info->effect); /* unregister existing timer */ if (r >= 0 && info->timer) { -- 2.7.4 From c227f2b608c57193cbac916036281c0a6bb3e125 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Thu, 16 Apr 2020 16:03:43 +0900 Subject: [PATCH 16/16] Fix build warning Change-Id: If34bd4b0461a4a8ccd78253a4a7c1df022c5538f Signed-off-by: Youngjae Cho --- src/haptic/standard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haptic/standard.c b/src/haptic/standard.c index 60b2a6d..c8bd450 100644 --- a/src/haptic/standard.c +++ b/src/haptic/standard.c @@ -520,7 +520,7 @@ static int stop_device(int device_handle) if (r < 0) _E("failed to stop effect(id:%d) : %d", info->effect.id, r); else - _I("Stop vibration by request. id(%d)", info->effect); + _I("Stop vibration by request. id(%d)", info->effect.id); /* unregister existing timer */ if (r >= 0 && info->timer) { -- 2.7.4