Apply next HAL architecture (hal api + backend) 79/251379/3 submit/tizen/20210126.055732 submit/tizen/20210126.064541 submit/tizen/20210126.081759
authorYunmi Ha <yunmi.ha@samsung.com>
Wed, 13 Jan 2021 08:23:51 +0000 (17:23 +0900)
committerYunmi Ha <yunmi.ha@samsung.com>
Fri, 22 Jan 2021 01:51:13 +0000 (10:51 +0900)
Change-Id: I47a0b94cbf5ed7a5eae45ab06a7d32766c6b64b7
Signed-off-by: Yunmi Ha <yunmi.ha@samsung.com>
14 files changed:
CMakeLists.txt
packaging/feedbackd.spec
src/core/haptic.c [new file with mode: 0644]
src/core/haptic.h [new file with mode: 0644]
src/core/main.c
src/driver/emulator.c [deleted file]
src/driver/external.c [deleted file]
src/driver/gpio_haptic.c [deleted file]
src/driver/haptic-dev.c [deleted file]
src/driver/haptic-dev.h [deleted file]
src/driver/haptic-interface.h [deleted file]
src/driver/haptic.c [deleted file]
src/driver/haptic.h [deleted file]
src/driver/standard.c [deleted file]

index 61437e4ae4a0cc6141a8da212a9bea2436fa6043..a8ce79a8aa9131faa2cb9ed0b94c7c83e2f40029 100644 (file)
@@ -9,11 +9,10 @@ SET(VERSION 0.1.0)
 
 SET(SRCS
        src/core/main.c
+       src/core/haptic.c
        src/shared/common.c
        src/shared/device-idler.c
        src/shared/log.c
-       src/driver/haptic.c
-       src/driver/haptic-dev.c
 )
 
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src)
@@ -29,6 +28,8 @@ SET(PKG_MODULES
        libsyscommon
        libsystemd
        capi-system-device
+       hal-api-device
+       hal-api-common
 )
 
 INCLUDE(FindPkgConfig)
@@ -44,44 +45,11 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -lrt -fPIE")
 SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie")
 
 ADD_DEFINITIONS("-DDEBUG")
-ADD_DEFINITIONS("-DLIBPATH=\"${LIB_INSTALL_DIR}\"")
 
 ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs2_LDFLAGS} "-ldl" "-lm")
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
 
-SET(LIB_PREFIX haptic_)
-SET(DRIVER_PKG_MODULES
-       dlog
-       capi-system-info
-       glib-2.0
-       libsyscommon
-)
-
-INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs_driver REQUIRED ${DRIVER_PKG_MODULES})
-
-FOREACH(flag_driver ${pkgs_driver_CFLAGS})
-       SET(DRIVER_CFLAGS "${DRIVER_CFLAGS} ${flag_driver}")
-ENDFOREACH(flag_driver)
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${DRIVER_CFLAGS} -fvisibility=hidden -Werror -g -fno-omit-frame-pointer -finstrument-functions -pie")
-
-ADD_LIBRARY(emul MODULE src/driver/emulator.c)
-TARGET_LINK_LIBRARIES(emul ${pkgs_driver_LDFLAGS} "-ldl")
-SET_TARGET_PROPERTIES(emul PROPERTIES PREFIX ${LIB_PREFIX})
-INSTALL(TARGETS emul DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
-
-ADD_LIBRARY(gpio MODULE src/driver/gpio_haptic.c)
-TARGET_LINK_LIBRARIES(gpio ${pkgs_driver_LDFLAGS} "-lcapi-system-peripheral-io -ldl")
-SET_TARGET_PROPERTIES(gpio PROPERTIES PREFIX ${LIB_PREFIX})
-INSTALL(TARGETS gpio DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
-
-ADD_LIBRARY(standard MODULE src/driver/standard.c)
-TARGET_LINK_LIBRARIES(standard ${pkgs_driver_LDFLAGS} "-ldl")
-SET_TARGET_PROPERTIES(standard PROPERTIES PREFIX ${LIB_PREFIX})
-INSTALL(TARGETS standard DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
-
 INSTALL(FILES ${CMAKE_SOURCE_DIR}/conf/feedbackd.conf DESTINATION /etc/dbus-1/system.d)
 INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/system
        FILES_MATCHING
index b812d64b914497b6622ddf5c26aa17c2eea3e46a..7272b6949a6192bdc01d874f5c39a210cfdfb979 100644 (file)
@@ -20,10 +20,11 @@ BuildRequires:  pkgconfig(gio-2.0)
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(gio-unix-2.0)
 BuildRequires:  pkgconfig(capi-system-info)
-BuildRequires:  pkgconfig(capi-system-peripheral-io)
 BuildRequires:  pkgconfig(libsyscommon)
 BuildRequires:  pkgconfig(libsystemd)
 BuildRequires:  pkgconfig(capi-system-device)
+BuildRequires:  pkgconfig(hal-api-device)
+BuildRequires:  pkgconfig(hal-api-common)
 
 Requires(post): /usr/bin/vconftool
 
@@ -42,30 +43,6 @@ Group:      main
 %description feedbackd
 feedback daemon.
 
-%package driver-emulator
-Summary:       Haptic driver targeting emulator plugin
-Provides:      %{name}-compat = %{version}-%{release}
-Conflicts:     %{name}-driver-gpio
-Conflicts:     %{name}-driver-standard
-%description driver-emulator
-Emulator device driver. Required by main feedbackd package.
-
-%package driver-gpio
-Summary:       Haptic driver targeting emulator plugin
-Provides:      %{name}-compat = %{version}-%{release}
-Conflicts:     %{name}-driver-emulator
-Conflicts:     %{name}-driver-standard
-%description driver-gpio
-Gpio haptic device driver. Required by main feedbackd package.
-
-%package driver-standard
-Summary:       Haptic driver targeting emulator plugin
-Provides:      %{name}-compat = %{version}-%{release}
-Conflicts:     %{name}-driver-emulator
-Conflicts:     %{name}-driver-gpio
-%description driver-standard
-Standard haptic device driver. Required by main feedbackd package.
-
 %package conf-level3
 Summary:       Feedbackd level configuration file
 Provides:      configuration-compat = %{version}-%{release}
@@ -112,42 +89,12 @@ fi
 %postun
 systemctl daemon-reload
 
-%post driver-emulator
-mkdir -p %{_libdir}/feedbackd
-mv %{_libdir}/haptic_emul.so %{_libdir}/feedbackd/haptic.so
-
-%post driver-gpio
-mkdir -p %{_libdir}/feedbackd
-mv %{_libdir}/haptic_gpio.so %{_libdir}/feedbackd/haptic.so
-
-%post driver-standard
-mkdir -p %{_libdir}/feedbackd
-mv %{_libdir}/haptic_standard.so %{_libdir}/feedbackd/haptic.so
-
 %post conf-level3
 mv %{_sysconfdir}/feedbackd/haptic-level3.conf %{_sysconfdir}/feedbackd/haptic.conf
 
 %post conf-level6
 mv %{_sysconfdir}/feedbackd/haptic-level6.conf %{_sysconfdir}/feedbackd/haptic.conf
 
-%preun driver-emulator
-mv %{_libdir}/feedbackd/haptic.so %{_libdir}/haptic_emul.so
-if [ "$1" == "0" ]; then
-    systemctl stop feedbackd.service
-fi
-
-%preun driver-gpio
-mv %{_libdir}/feedbackd/haptic.so %{_libdir}/haptic_gpio.so
-if [ "$1" == "0" ]; then
-    systemctl stop feedbackd.service
-fi
-
-%preun driver-standard
-mv %{_libdir}/feedbackd/haptic.so %{_libdir}/haptic_standard.so
-if [ "$1" == "0" ]; then
-    systemctl stop feedbackd.service
-fi
-
 %files -n feedbackd
 %manifest %{name}.manifest
 %license LICENSE.Apache-2.0
@@ -157,18 +104,6 @@ fi
 %{_datadir}/dbus-1/system-services/org.tizen.system.vibrator.service
 %{_bindir}/feedbackd
 
-%files driver-emulator
-%license LICENSE.Apache-2.0
-%{_libdir}/haptic_emul.so
-
-%files driver-gpio
-%license LICENSE.Apache-2.0
-%{_libdir}/haptic_gpio.so
-
-%files driver-standard
-%license LICENSE.Apache-2.0
-%{_libdir}/haptic_standard.so
-
 %files conf-level3
 %license LICENSE.Apache-2.0
 %manifest %{name}.manifest
diff --git a/src/core/haptic.c b/src/core/haptic.c
new file mode 100644 (file)
index 0000000..3f955ea
--- /dev/null
@@ -0,0 +1,1386 @@
+/*
+ * feedbackd
+ *
+ * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <dlfcn.h>
+#include <assert.h>
+#include <vconf.h>
+#include <time.h>
+#include <string.h>
+#include <libsyscommon/dbus-system.h>
+#include <libsyscommon/list.h>
+#include <libsyscommon/ini-parser.h>
+#include <hal/device/hal-haptic.h>
+
+#include "shared/log.h"
+#include "shared/common.h"
+#include "shared/device-idler.h"
+#include "haptic.h"
+
+#define FEEDBACK_BASE_PATH         "/usr/share/feedback/"
+#define STANDARD_FILE_PATH         FEEDBACK_BASE_PATH"vibration/"
+#define VIBRATION_CONF_PATH        FEEDBACK_BASE_PATH"vibration.conf"
+
+#define HAPTIC_CONF_PATH                "/etc/feedbackd/haptic.conf"
+#define SIGNAL_POWEROFF_STATE           "ChangeState"
+#define SIGNAL_VIBRATOR_INITIATED       "InitiateVibrator"
+
+/* hardkey vibration variable */
+#define HARDKEY_VIB_ITERATION          1
+#define HARDKEY_VIB_FEEDBACK           3
+#define HARDKEY_VIB_DURATION           30
+#define HAPTIC_FEEDBACK_STEP           20
+#define DEFAULT_FEEDBACK_LEVEL         3
+#define HIGH_FEEDBACK_LEVEL            100
+#define LOW_FEEDBACK_LEVEL             0
+
+/* power on, power off vibration variable */
+#define POWER_ON_VIB_DURATION                  300
+#define POWER_OFF_VIB_DURATION                 300
+#define POWER_VIB_FEEDBACK                     100
+
+#define MAX_EFFECT_BUFFER                      (64*1024)
+
+#ifndef VCONFKEY_RECORDER_STATE
+#define VCONFKEY_RECORDER_STATE "memory/recorder/state"
+#define VCONFKEY_RECORDER_STATE_RECORDING      2
+#endif
+
+#define RETRY_CNT      3
+
+#define INTENSITY_BASE_RATE        (10000)
+#define VALUE_MAX_LEN              10
+#define VIB_LOCK_TIMEOUT_MAX       (300000) /* 5minutes */
+
+/*
+               1,A_W or A,A_W or 250D250W250D750W
+
+               85,10000,
+               90,0,
+               105,10000,
+               0,end
+*/
+struct vibration_config {
+       char *pattern; /* pattern name */
+       char *standard; /* assigned standard pattern name */
+       GList *data; /* duration_data list */
+       unsigned int pattern_duration;
+       int unlimit;
+};
+
+struct duration_data {
+       int duration;
+       int intensity;
+       int frequency;
+       int overdrive;
+       int wait;
+};
+
+enum poweroff_type {
+       POWER_OFF_NONE = 0,
+       POWER_OFF_POPUP,
+       POWER_OFF_DIRECT,
+       POWER_OFF_RESTART,
+};
+
+struct haptic_info {
+       char *sender;
+       GList *handle_list;
+       guint id_watch;
+};
+
+struct vibrate_pattern_info {
+       unsigned int handle;
+       char *pattern;
+       int level;
+       int priority;
+};
+
+struct vibrate_monotone_info {
+       unsigned int handle;
+       int duration;
+       int level;
+       int intensity;
+       int priority;
+};
+
+/* for playing */
+static int g_handle;
+
+/* pattern configuration list */
+static GList *vib_conf_list;
+
+static guint duration_timer;
+
+/* haptic operation variable */
+static GList *haptic_handle_list;
+
+static bool haptic_disabled;
+
+struct haptic_config {
+       int level;
+       int *level_arr;
+       int sound_capture;
+};
+
+static struct haptic_config haptic_conf;
+
+static int haptic_start(void);
+static int haptic_stop(void);
+static int remove_haptic_info(struct haptic_info *info);
+
+struct haptic_data cur_h_data;
+
+static int insert_conf_data(GList **conf_data, struct duration_data *update)
+{
+       struct duration_data *data;
+
+       data = (struct duration_data *)calloc(1, sizeof(struct duration_data));
+       if (!data) {
+               _E("Not enough memory.");
+               return -ENOMEM;
+       }
+       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->overdrive, data->wait);
+       SYS_G_LIST_APPEND(*conf_data, data);
+       return 0;
+}
+
+static void get_pattern_property(char **iter, char property, int *value)
+{
+       char *check;
+       unsigned long int val;
+
+       check = strchr(*iter, property);
+       if (!check)
+               return;
+
+       *check = '\0';
+       val = strtoul(*iter, NULL, 10);
+       if (errno == EINVAL || errno == ERANGE) {
+               val = 0;
+               _E("Failed to get value of %s: %d", *iter, errno);
+       }
+       if (val > VIB_LOCK_TIMEOUT_MAX)
+               val = VIB_LOCK_TIMEOUT_MAX;
+
+       *value = (int)val;
+
+       *iter = check + 1;
+}
+
+/* [A]xxxDxxxIxxxFxxxOxxxW format */
+static int insert_raw_data_format(GList **conf_data, char *value)
+{
+       struct duration_data update = {0, };
+       char *iter;
+       char *end;
+       int pattern_duration = 0;
+
+       if (!value)
+               return insert_conf_data(conf_data, &update);
+       if (!conf_data) {
+               _E("Invalid parameter: Configuration list is null");
+               return -EINVAL;
+       }
+
+       iter = value;
+       end = iter + strlen(iter);
+       while (iter < end) {
+               memset(&update, 0, sizeof(struct duration_data));
+
+               get_pattern_property(&iter, 'D', &update.duration);
+               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) {
+                       _D("Pattern duration is zero.");
+                       break;
+               }
+
+               pattern_duration += (update.duration + update.wait);
+               if (pattern_duration > VIB_LOCK_TIMEOUT_MAX) {
+                       _D("Max pattern duration.");
+                       pattern_duration = VIB_LOCK_TIMEOUT_MAX;
+               }
+
+               if (insert_conf_data(conf_data, &update) < 0)
+                       return -EINVAL;
+       }
+
+       return pattern_duration;
+}
+
+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 > 4 || count <= 0) {
+               _E("Invalid parameter: count is invalid");
+               return -EINVAL;
+       }
+
+       if (!packed || !val || !pattern_duration || !update) {
+               _E("Invalid parameter: %p %p %p %p", packed, val, pattern_duration, update);
+               return -EINVAL;
+       }
+
+       get_pattern_property(&val, 'C', &value);
+
+       ret = count;
+       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;
+               }
+               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;
+               }
+               ret = 0;
+               break;
+       default:
+               break;
+       }
+       return ret;
+}
+
+/*
+       duration, intensity, frequency, overdrive
+       waiting duration, intensity=0, frequency, overdrive
+       85,10000,
+       90,0,
+       105,10000,
+       0,end
+*/
+static int load_standard_format(const char *pattern)
+{
+       struct duration_data update = {0, };
+       bool packed = false;
+       struct vibration_config *conf;
+       int ret = 0, count = 0, end = 2;
+       int index = 0;
+       int fd;
+       char path[PATH_MAX], elem, val[VALUE_MAX_LEN] = {0, };
+
+       snprintf(path, sizeof(path), STANDARD_FILE_PATH"%s", pattern);
+       fd = open(path, O_RDONLY);
+       if (fd < 0)
+               return -ENOENT;
+
+       conf = (struct vibration_config *)calloc(1, sizeof(struct vibration_config));
+       if (!conf) {
+               _E("Failed to alloc.");
+               ret = -errno;
+               goto error_out;
+       }
+
+       conf->pattern = strdup(pattern);
+       if (!conf->pattern) {
+               _E("Failed to copy pattern data(%s).", pattern);
+               ret = -errno;
+               goto error_out;
+       }
+
+       /* make feedback pattern(xDxIxFxOxW) format from d,i,f,o, */
+       while (read(fd, &elem, 1) != 0) {
+               if (end == 0) {
+                       if (insert_conf_data(&conf->data, &update) < 0)
+                               goto error_out;
+                       break;
+               }
+               if (elem == 'e' || elem == 'n' || elem == 'd') {
+                       end--;
+                       continue;
+               }
+               if (elem == '\n') {
+                       count = 0;
+                       continue;
+               }
+               if (elem == ',') {
+                       count++;
+                       val[index] = 'C';
+                       index = 0;
+
+                       ret = get_config_data(count, &packed, val, &(conf->pattern_duration), &update);
+                       if (ret < 0) {
+                               if (ret == -EINVAL)
+                                       break;
+                               if (insert_conf_data(&conf->data, &update) < 0)
+                                       goto error_out;
+                               memset(&update, 0, sizeof(struct duration_data));
+                       } else
+                               count = ret;
+               } else {
+                       if (index < (VALUE_MAX_LEN - 2)) /* Temporal limit */
+                               val[index++] = elem;
+                       else
+                               _E("Pattern(%s) is out of bound: %s", pattern, val);
+               }
+       }
+       close(fd);
+       SYS_G_LIST_APPEND(vib_conf_list, conf);
+       return ret;
+
+error_out:
+       if (fd >= 0)
+               close(fd);
+       if (conf) {
+               if (conf->pattern)
+                       free(conf->pattern);
+               free(conf);
+       }
+       return -ENOENT;
+}
+
+static int vibration_load_config(struct parse_result *result, void *user_data)
+{
+       struct vibration_config *conf;
+       char *value;
+       char *check;
+       int len;
+       int duration;
+
+       if (!result)
+               return 0;
+
+       if (!MATCH(result->section, "Vibration"))
+               return 0;
+
+
+       if (!result->name || !result->value)
+               return 0;
+
+       conf = (struct vibration_config *)calloc(1, sizeof(struct vibration_config));
+       if (!conf) {
+               _E("Failed to alloc.");
+               return -ENOMEM;
+       }
+
+       conf->pattern_duration = 0;
+       conf->pattern = strdup(result->name);
+       if (!conf->pattern) {
+               _E("Failed to copy pattern data(%s).", result->name);
+               goto error_out;
+       }
+
+       value = result->value;
+       len = strlen(value);
+
+       if (len == 0) {
+               if (insert_raw_data_format(&conf->data, NULL) < 0)
+                       goto error_out;
+               SYS_G_LIST_APPEND(vib_conf_list, conf);
+               return 0;
+       }
+
+       /* Load Standard Pattern Name */
+       /* value: 1,A_W or A,A_W */
+       if ((check = strchr(value, ','))) {
+               *check = '\0';
+               if (strncmp(value, "A", 1) == 0)
+                       conf->unlimit = 1;
+               value = check + 1;
+               conf->standard = strdup(value);
+               if (!conf->standard) {
+                       _E("Failed to copy standard name.");
+                       goto error_out;
+               }
+               SYS_G_LIST_APPEND(vib_conf_list, conf);
+               return 0;
+       }
+
+       /* value : A100D or 100D0W or 250D250W250D750W */
+       /* Load Vibration Pattern Data */
+       check = strchr(value, 'A');
+       if (check) {
+               *check = '\0';
+               conf->unlimit = 1;
+               if (!value)
+                       len = len - 1;
+               else
+                       len = len - strlen(value) - 1;
+               value = check + 1;
+       }
+       duration = insert_raw_data_format(&conf->data, value);
+       if (duration < 0) {
+               conf->pattern_duration = 0;
+               goto error_out;
+       } else
+               conf->pattern_duration = duration;
+       SYS_G_LIST_APPEND(vib_conf_list, conf);
+
+       return 0;
+
+error_out:
+       if (conf) {
+               if (conf->pattern)
+                       free(conf->pattern);
+               if (conf->standard)
+                       free(conf->standard);
+       }
+       return -ENOMEM;
+}
+
+static void load_standard_vibration_patterns(void)
+{
+       DIR *dir;
+       struct dirent *dent;
+       int ret;
+
+       dir = opendir(STANDARD_FILE_PATH);
+       if (!dir) {
+               _E("Failed to load '%s' Use default value.", STANDARD_FILE_PATH);
+               return;
+       }
+       while ((dent = readdir(dir))) {
+               if (dent->d_type == DT_DIR)
+                       continue;
+               ret = load_standard_format(dent->d_name);
+               if (ret < 0)
+                       _E("Failed to parse %s: %d", dent->d_name, ret);
+       }
+       closedir(dir);
+       _D("Success to load '%s'", STANDARD_FILE_PATH);
+}
+
+void pattern_config_parse(void)
+{
+       int ret;
+
+       ret = config_parse(VIBRATION_CONF_PATH, vibration_load_config, NULL);
+       if (ret < 0)
+               _E("Failed to load '%s'. Use default value: %d", VIBRATION_CONF_PATH, ret);
+
+       load_standard_vibration_patterns();
+}
+
+static int haptic_module_load(void)
+{
+       int r;
+
+       pattern_config_parse();
+
+       r = hal_device_haptic_get_backend();
+       if (r < 0) {
+               _E("Failed to load device. ret=%d", r);
+               return r;
+       }
+
+       /* solution bug
+        * we do not use internal vibration except power off.
+        * if the last handle is closed during the playing of vibration,
+        * solution makes unlimited vibration.
+        * so we need at least one handle. */
+       r = hal_device_haptic_open_device(&g_handle);
+       if (r < 0) {
+               _E("Failed to open device. ret=%d", r);
+               return r;
+       }
+
+       return 0;
+}
+
+/*
+static int convert_magnitude_by_conf(int level)
+{
+       int i, step;
+
+       if (level < LOW_FEEDBACK_LEVEL)
+               level = LOW_FEEDBACK_LEVEL;
+       else if (level > HIGH_FEEDBACK_LEVEL)
+               level = HIGH_FEEDBACK_LEVEL;
+
+       step = 100 / (haptic_conf.level-1);
+       for (i = 0; i < haptic_conf.level; ++i) {
+               if (level <= i*step) {
+                       _D("Level changed. %d -> %d", level, haptic_conf.level_arr[i]);
+                       return haptic_conf.level_arr[i];
+               }
+       }
+
+       _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)
+{
+       int ret, val;
+
+       ret = hal_device_haptic_get_device_count(&val);
+       if (ret >= 0)
+               ret = val;
+
+       return g_variant_new("(i)", ret);
+}
+
+void haptic_name_owner_changed(GDBusConnection *connection,
+       const gchar     *name,
+       gpointer         user_data)
+{
+       GList *n;
+       struct haptic_info *info = user_data;
+       int handle;
+
+       _I("%s (sender=%s)", __func__, name);
+
+       if (!info)
+               return;
+
+       for (n = info->handle_list; n; n = n->next) {
+               handle = (int)(long)n->data;
+               hal_device_haptic_stop_device(handle);
+               hal_device_haptic_close_device(handle);
+       }
+
+       remove_haptic_info(info);
+}
+
+static struct haptic_info *add_haptic_info(const char *sender)
+{
+       struct haptic_info *info;
+
+       assert(sender);
+
+       info = calloc(1, sizeof(struct haptic_info));
+       if (!info)
+               return NULL;
+
+       info->sender = strdup(sender);
+       if (!info->sender) {
+               free(info);
+               return NULL;
+       }
+
+       SYS_G_LIST_APPEND(haptic_handle_list, info);
+
+       info->id_watch = dbus_handle_watch_name(sender, NULL, haptic_name_owner_changed, info, NULL);
+
+       return info;
+}
+
+static int remove_haptic_info(struct haptic_info *info)
+{
+       assert(info);
+
+       dbus_handle_unwatch_name(info->id_watch);
+
+       SYS_G_LIST_REMOVE(haptic_handle_list, info);
+       SYS_G_LIST_FREE_LIST(info->handle_list);
+       if (info->sender) {
+               free(info->sender);
+       }
+       free(info);
+
+       return 0;
+}
+
+static struct haptic_info *get_matched_haptic_info(const char *sender)
+{
+       GList *n;
+       struct haptic_info *info;
+       int len;
+
+       assert(sender);
+
+       len = strlen(sender) + 1;
+       SYS_G_LIST_FOREACH(haptic_handle_list, n, info) {
+               if (!strncmp(info->sender, sender, len))
+                       return info;
+       }
+
+       return NULL;
+}
+
+GVariant *hdbus_open_device(GDBusConnection *conn,
+                                                       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+                                                       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int index, handle, ret;
+       struct haptic_info *info;
+
+       /* Load haptic module before booting done */
+       if (hal_device_haptic_check_backend() < 0) {
+               ret = hal_device_haptic_get_backend();
+               if (ret < 0)
+                       goto exit;
+       }
+
+       g_variant_get(param, "(i)", &index);
+
+       ret = hal_device_haptic_open_device(&handle);
+       if (ret < 0)
+               goto exit;
+
+       if (!sender) {
+               ret = -EPERM;
+               hal_device_haptic_close_device(handle);
+               goto exit;
+       }
+
+       info = get_matched_haptic_info(sender);
+       if (!info) {
+               info = add_haptic_info(sender);
+               if (!info) {
+                       _E("Failed to create haptic information.");
+                       ret = -EPERM;
+                       hal_device_haptic_close_device(handle);
+                       goto exit;
+               }
+       }
+
+       SYS_G_LIST_APPEND(info->handle_list, (gpointer)(long)handle);
+
+       ret = handle;
+
+exit:
+       return g_variant_new("(i)", ret);
+}
+
+int clear_current_data(void)
+{
+       cur_h_data.handle = INVALID_HANDLE;
+       cur_h_data.priority = PRIORITY_MIN;
+
+       if (duration_timer) {
+               _I("Remove duration_timer.");
+               g_source_remove(duration_timer);
+               duration_timer = 0;
+       }
+
+       return 0;
+}
+
+GVariant *hdbus_close_device(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       unsigned int handle;
+       int ret;
+       struct haptic_info *info;
+       int cnt;
+
+       g_variant_get(param, "(u)", &handle);
+
+       if (!sender) {
+               _E("Failed to get sender from dbus message.");
+               ret = -EPERM;
+               goto exit;
+       }
+
+       ret = hal_device_haptic_close_device(handle);
+       if (ret < 0)
+               goto exit;
+
+       if (cur_h_data.handle == handle) {
+               /* Remove duration_timer for vibrate_effect */
+               clear_current_data();
+       }
+
+       info = get_matched_haptic_info(sender);
+       if (!info) {
+               _E("Failed to find the matched haptic info.");
+               goto exit;
+       }
+
+       SYS_G_LIST_REMOVE(info->handle_list, (gpointer)(long)handle);
+       cnt = SYS_G_LIST_LENGTH(info->handle_list);
+       if (cnt == 0)
+               remove_haptic_info(info);
+
+exit:
+       return g_variant_new("(i)", ret);
+}
+
+static gboolean _cb(void *data)
+{
+       if (duration_timer) {
+               g_source_remove(duration_timer);
+               duration_timer = 0;
+       }
+
+       cur_h_data.handle = INVALID_HANDLE;
+       cur_h_data.priority = PRIORITY_MIN;
+
+       return G_SOURCE_REMOVE;
+}
+
+static void vibrate_monotone_idler_cb(void *data)
+{
+       struct vibrate_monotone_info *vibrate_info;
+       int ret;
+
+       if (!data)
+               return;
+
+       vibrate_info = (struct vibrate_monotone_info *)data;
+
+       if (vibrate_info->priority < cur_h_data.priority) {
+               _I("Handle(%d) skip low priority. pre=%d now=%d", vibrate_info->handle, cur_h_data.priority, vibrate_info->priority);
+               free(vibrate_info);
+               return;
+       }
+
+       if (duration_timer) {
+               g_source_remove(duration_timer);
+               duration_timer = 0;
+       }
+
+       cur_h_data.vibration_data = NULL;
+       cur_h_data.handle = vibrate_info->handle;
+       cur_h_data.level = vibrate_info->level;
+       cur_h_data.priority = vibrate_info->priority;
+       cur_h_data.stop = false;
+       cur_h_data.unlimit = false;
+
+       ret = device_power_request_lock(POWER_LOCK_CPU, vibrate_info->duration);
+       if (ret != DEVICE_ERROR_NONE)
+               _E("Failed to request power lock.");
+
+       _D("Handle(%d) play=%dms, level=%d, intensity=%d, frequency=0)",
+                       cur_h_data.handle, vibrate_info->duration, cur_h_data.level,
+                       vibrate_info->intensity);
+
+       duration_timer = g_timeout_add(vibrate_info->duration, _cb, NULL);
+       hal_device_haptic_vibrate(cur_h_data.handle, vibrate_info->duration, 0, 0, cur_h_data.level, vibrate_info->intensity, cur_h_data.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, intensity, priority, ret = 0;
+
+       if ((ret = hal_device_haptic_check_backend()) < 0)
+               goto exit;
+
+       if (haptic_disabled)
+               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;
+               goto exit;
+       }
+
+       if (priority < PRIORITY_MIN)
+               priority = PRIORITY_MIN;
+       else if (priority > PRIORITY_TOP)
+               priority = PRIORITY_TOP;
+
+       if (duration <= 0) {
+               _E("Skip vibrate handle(%d) requested less than 0.", handle);
+               ret = -EINVAL;
+               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.");
+               ret = -errno;
+               goto exit;
+       }
+
+       vibrate_info->handle = handle;
+       vibrate_info->duration = duration;
+       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);
+exit:
+       return g_variant_new("(i)", ret);
+}
+
+static gboolean haptic_duration_play(void *data)
+{
+       GList *head, *n, *next;
+       struct duration_data *node;
+       int ret = 0;
+
+       if (duration_timer) {
+               g_source_remove(duration_timer);
+               duration_timer = 0;
+       }
+
+       if (!data) {
+               if (cur_h_data.unlimit) /* In case of unlimit pattern, do not stop */
+                       head = cur_h_data.vibration_data;
+               else {
+                       cur_h_data.handle = INVALID_HANDLE;
+                       cur_h_data.priority = PRIORITY_MIN;
+                       goto out;
+               }
+       } else
+               head = (GList *)data;
+
+       if (cur_h_data.stop) {
+               _I("Stop currunt vibration.");
+               cur_h_data.stop = false;
+               cur_h_data.handle = INVALID_HANDLE;
+               cur_h_data.priority = PRIORITY_MIN;
+               goto out;
+       }
+
+       SYS_G_LIST_FOREACH_SAFE(head, n, next, node) {
+               _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) {
+                       if (!cur_h_data.unlimit) {
+                               cur_h_data.handle = INVALID_HANDLE;
+                               cur_h_data.priority = PRIORITY_MIN;
+                               break;
+                       } else {
+                               next = cur_h_data.vibration_data;
+                               continue;
+                       }
+               }
+
+               duration_timer = g_timeout_add((node->duration + node->wait), haptic_duration_play, (void *)next);
+
+               ret = hal_device_haptic_vibrate(cur_h_data.handle, node->duration, node->frequency, node->overdrive, cur_h_data.level, node->intensity, cur_h_data.priority);
+
+               break;
+       }
+       if (ret != 0) {
+               _D("Auto stop vibration.");
+               cur_h_data.stop = true;
+       }
+out:
+       return G_SOURCE_REMOVE;
+}
+
+static void vibrate_pattern_idler_cb(void *data)
+{
+       struct vibrate_pattern_info *vibrate_info;
+       GList *elem;
+       struct vibration_config *conf;
+       char pattern[PATH_MAX];
+       int ret;
+       int unlimit = 0;
+
+       if (!data)
+               return;
+
+       vibrate_info = (struct vibrate_pattern_info *)data;
+
+       if (!(vibrate_info->pattern)) {
+               free(vibrate_info);
+               return;
+       }
+
+       /* Same or higher priority pattern should be played */
+       if (vibrate_info->priority < cur_h_data.priority) {
+               _I("Handle(%d) skip low priority. pre=%d now=%d", vibrate_info->handle, cur_h_data.priority, vibrate_info->priority);
+               goto out;
+       }
+
+       snprintf(pattern, sizeof(pattern), "%s", vibrate_info->pattern);
+       SYS_G_LIST_FOREACH(vib_conf_list, elem, conf) {
+               if (!conf->pattern)
+                       continue;
+               if (strcmp(conf->pattern, pattern))
+                       continue;
+               if (conf->standard) {
+                       unlimit = conf->unlimit;
+                       snprintf(pattern, sizeof(pattern), "%s", conf->standard);
+                       continue;
+               }
+
+               if (unlimit)
+                       cur_h_data.unlimit = unlimit;
+               else
+                       cur_h_data.unlimit = conf->unlimit;
+               cur_h_data.vibration_data = conf->data;
+               cur_h_data.handle = vibrate_info->handle;
+               cur_h_data.level = vibrate_info->level;
+               cur_h_data.priority = vibrate_info->priority;
+               cur_h_data.stop = false;
+               _I("Handle(%d) play=%s pri=%d %s", cur_h_data.handle, conf->pattern, cur_h_data.priority,
+                               cur_h_data.unlimit ? "Unlimit" : "Once");
+
+               if (conf->pattern_duration <= 0)
+                       break;
+
+               if (!cur_h_data.unlimit && conf->pattern_duration > 0) {
+                       ret = device_power_request_lock(POWER_LOCK_CPU, (int)conf->pattern_duration);
+                       if (ret != DEVICE_ERROR_NONE)
+                               _E("Failed to request power lock.");
+               }
+               haptic_duration_play((void *)cur_h_data.vibration_data);
+               goto out;
+       }
+       _E("Handle(%d) %s is not supported.", vibrate_info->handle, pattern);
+
+out:
+       free(vibrate_info->pattern);
+       free(vibrate_info);
+}
+
+GVariant *hdbus_vibrate_pattern(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       struct vibrate_pattern_info *vibrate_info;
+       unsigned int handle;
+       char *pattern = NULL;
+       int level, priority, ret = 0;
+
+       if ((ret = hal_device_haptic_check_backend()) < 0)
+               goto exit;
+
+       if (haptic_disabled)
+               goto exit;
+
+       g_variant_get(param, "(usii)",  &handle, &pattern, &level, &priority);
+
+       if (level < 0) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       if (priority < PRIORITY_MIN)
+               priority = PRIORITY_MIN;
+       else if (priority > PRIORITY_TOP)
+               priority = PRIORITY_TOP;
+
+       vibrate_info = calloc(1, sizeof(struct vibrate_pattern_info));
+       if (!vibrate_info) {
+               _E("Failed to allocate memory for vibrate_info.");
+               ret = -errno;
+               goto exit;
+       }
+       vibrate_info->handle = handle;
+       vibrate_info->pattern = pattern;
+       pattern = NULL;
+       if (!vibrate_info->pattern) {
+               _E("Failed to allocate memory for pattern.");
+               ret = -errno;
+               free(vibrate_info);
+               goto exit;
+       }
+       vibrate_info->level = level;
+       vibrate_info->priority = priority;
+
+       ret = add_idle_request(vibrate_pattern_idler_cb, (void *)vibrate_info);
+
+exit:
+       g_free(pattern);
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *hdbus_stop_device(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       unsigned int handle;
+       int ret = 0;
+
+       if ((ret = hal_device_haptic_check_backend()) < 0)
+               goto exit;
+
+       if (haptic_disabled) {
+               _I("Haptic disabled.");
+               goto exit;
+       }
+
+       g_variant_get(param, "(u)", &handle);
+
+       if (cur_h_data.handle != handle) {
+               _D("Not the request from current vibration handle(%d). Skip.", handle);
+               goto exit;
+       }
+
+       ret = hal_device_haptic_stop_device(handle);
+       _I("Stop the device(handle=%u) :%d", handle, ret);
+
+       /* Remove duration_timer for vibrate_effect */
+       clear_current_data();
+
+exit:
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *hdbus_show_handle_list(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       GList *n;
+       GList *elem;
+       struct haptic_info *info;
+
+       _D("Sender Handle");
+       SYS_G_LIST_FOREACH(haptic_handle_list, n, info) {
+               for (elem = info->handle_list; elem; elem = elem->next)
+                       _D("%s %d", info->sender, (int)(long)elem->data);
+       }
+
+       return g_variant_new_tuple(NULL, 0);
+}
+
+int pattern_is_supported(const char *pattern)
+{
+       GList *elem;
+       struct vibration_config *conf;
+       int ret;
+
+       if (!pattern)
+               return -EINVAL;
+
+       ret = 0;
+       SYS_G_LIST_FOREACH(vib_conf_list, elem, conf) {
+               if (!conf->pattern)
+                       continue;
+               if (!strcmp(conf->pattern, pattern)) {
+                       ret = true;
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+GVariant *hdbus_pattern_is_supported(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+
+{
+       char *data = NULL;
+       int ret = 0;
+
+       if ((ret = hal_device_haptic_check_backend()) < 0)
+               goto exit;
+
+       if (haptic_disabled)
+               goto exit;
+
+       g_variant_get(param, "(s)", &data);
+
+       ret = pattern_is_supported(data);
+
+       _I("%s is supported: %d", data, ret);
+
+exit:
+       g_free(data);
+       return g_variant_new("(i)", ret);
+}
+
+static void haptic_poweroff_cb(GDBusConnection  *conn,
+       const gchar      *sender,
+       const gchar      *path,
+       const gchar      *iface,
+       const gchar      *name,
+       GVariant         *param,
+       gpointer          data)
+{
+       int type = POWER_OFF_NONE;
+       int ret, level;
+       struct timespec time = {0,};
+
+       if (!g_variant_get_safe(param, "(i)", &type)) {
+               _E("Failed to get params from gvariant. expected:%s, type:%s", "(i)", g_variant_get_type_string(param));
+               return;
+       }
+
+       if (type != POWER_OFF_DIRECT && type != POWER_OFF_RESTART)
+               return;
+
+       _D("Poweroff: %d", type);
+
+       if (hal_device_haptic_check_backend() < 0) {
+               if (haptic_module_load() < 0)
+                       return ;
+       }
+
+       if (!g_handle) {
+               if (hal_device_haptic_open_device(&g_handle) < 0)
+                       return ;
+       }
+
+       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 intensity=%d frequency=0",
+               g_handle, POWER_OFF_VIB_DURATION, PRIORITY_HIGH, level,
+               POWER_VIB_FEEDBACK * 100);
+       ret = hal_device_haptic_vibrate(g_handle, POWER_OFF_VIB_DURATION, 0, 0,
+                       level, POWER_VIB_FEEDBACK * 100, PRIORITY_HIGH);
+       if (ret < 0) {
+               _E("Failed to vibrate_monotone: %d", ret);
+               return;
+       }
+
+       /* sleep for vibration */
+       time.tv_nsec = POWER_OFF_VIB_DURATION * NANO_SECOND_MULTIPLIER;
+       nanosleep(&time, NULL);
+       return;
+}
+
+static void sound_capturing_cb(keynode_t *key, void *data)
+{
+       int status;
+
+       status = vconf_keynode_get_int(key);
+
+       /* if sound capture is in use, this value is 1(true). */
+       if (status == VCONFKEY_RECORDER_STATE_RECORDING)
+               haptic_stop();
+       else
+               haptic_start();
+}
+
+static int parse_section(struct parse_result *result, void *user_data, int index)
+{
+       struct haptic_config *conf = (struct haptic_config *)user_data;
+
+       if (!result)
+               return 0;
+
+       if (!result->section || !result->name || !result->value)
+               return 0;
+
+       if (MATCH(result->name, "sound_capture")) {
+               conf->sound_capture = atoi(result->value);
+       } else if (MATCH(result->name, "level")) {
+               conf->level = atoi(result->value);
+               if (conf->level < 0 || conf->level >= INT_MAX - 1) {
+                       _E("You must set level with positive number in integer range.");
+                       return -EINVAL;
+               }
+               conf->level_arr = calloc(sizeof(int), conf->level);
+               if (!conf->level_arr) {
+                       _E("Failed to allocate memory for level.");
+                       return -errno;
+               }
+       } else if (MATCH(result->name, "value")) {
+               if (index < 0)
+                       return -EINVAL;
+               conf->level_arr[index] = atoi(result->value);
+       }
+
+       return 0;
+}
+
+static int haptic_load_config(struct parse_result *result, void *user_data)
+{
+       struct haptic_config *conf = (struct haptic_config *)user_data;
+       char name[NAME_MAX];
+       int ret;
+       static int index;
+
+       if (!result)
+               return 0;
+
+       if (!result->section || !result->name || !result->value)
+               return 0;
+
+       // Parsing 'Haptic' section
+       if (MATCH(result->section, "Haptic")) {
+               ret = parse_section(result, user_data, -1);
+               if (ret < 0) {
+                       _E("Failed to parse 'Haptic' section: %d", ret);
+                       return ret;
+               }
+               goto out;
+       }
+
+       // Parsing 'level' section
+       for (index = 0; index < conf->level; ++index) {
+               snprintf(name, sizeof(name), "level%d", index);
+               if (MATCH(result->section, name)) {
+                       ret = parse_section(result, user_data, index);
+                       if (ret < 0) {
+                               _E("Failed to parse 'level' section: %d", ret);
+                               return ret;
+                       }
+                       goto out;
+               }
+       }
+
+out:
+       return 0;
+}
+
+static const dbus_method_s hdbus_methods[] = {
+       { "GetCount",          NULL,   "i", hdbus_get_count },            // device_haptic_get_count
+       { "OpenDevice",         "i",   "i", hdbus_open_device },          // device_haptic_open, feedback_initialize
+       { "CloseDevice",        "u",   "i", hdbus_close_device },         // device_haptic_close, feedback_deinitialize
+       { "StopDevice",         "u",   "i", hdbus_stop_device },          // device_haptic_stop, feedback_stop
+       { "VibrateMonotone", "uiii",   "i", hdbus_vibrate_monotone },     // device_haptic_vibrate
+       { "VibratePattern",  "usii",   "i", hdbus_vibrate_pattern },      // feedback_play*
+       { "ShowHandleList",    NULL,  NULL, hdbus_show_handle_list },
+       { "IsSupported",        "s",   "i", hdbus_pattern_is_supported }, // feedback_is_supported_pattern
+       /* Add methods here */
+};
+
+static const dbus_interface_u dbus_interface = {
+       .name = VIBRATOR_INTERFACE_HAPTIC,
+       .methods = hdbus_methods,
+       .nr_methods = ARRAY_SIZE(hdbus_methods),
+};
+
+int haptic_probe(void)
+{
+       /**
+        * load haptic module.
+        * if there is no haptic module,
+        * feedbackd does not activate a haptic interface.
+        */
+       return haptic_module_load();
+}
+
+static guint id_sig_pwr_off_state;
+
+void haptic_init(void)
+{
+       int r;
+
+       /* get haptic data from configuration file */
+       r = config_parse(HAPTIC_CONF_PATH, haptic_load_config, &haptic_conf);
+       if (r < 0) {
+               _E("Failed to load configuration file(%s): %d", HAPTIC_CONF_PATH, r);
+               safe_free(haptic_conf.level_arr);
+       }
+
+       /* init dbus interface */
+       r = dbus_handle_register_dbus_object(NULL, VIBRATOR_PATH_HAPTIC, &dbus_interface);
+       if (r < 0)
+               _E("Failed to init hdbus interface and method: %d", r);
+
+       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);
+               return;
+       }
+
+       dbus_handle_emit_dbus_signal(NULL,
+                       VIBRATOR_PATH_HAPTIC,
+                       VIBRATOR_INTERFACE_HAPTIC,
+                       SIGNAL_VIBRATOR_INITIATED,
+                       NULL);
+
+       /* add watch for sound capturing value */
+       if (haptic_conf.sound_capture) {
+               r = vconf_notify_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb, NULL);
+               if (r != 0)
+                       _W("Add watch for VCONFKEY_RECORDER_STATE failed.");
+       }
+
+       /* Initialize vibration_handle (Use vibration now) */
+       cur_h_data.handle = INVALID_HANDLE;
+       cur_h_data.priority = PRIORITY_MIN;
+}
+
+void haptic_exit(void)
+{
+       int r;
+
+       /* remove watch */
+       if (haptic_conf.sound_capture) {
+               r = vconf_ignore_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb);
+               if (r != 0)
+                       _W("Remove watch for VCONFKEY_RECORDER_STATE failed.");
+       }
+
+       /* unregister notifier for below each event */
+       unsubscribe_dbus_signal(NULL, id_sig_pwr_off_state);
+
+       /* release haptic data memory */
+       safe_free(haptic_conf.level_arr);
+
+       /* haptic exit for feedbackd */
+       hal_device_haptic_close_device(g_handle);
+       hal_device_haptic_put_backend();
+}
+
+static int haptic_start(void)
+{
+       _I("Start");
+       haptic_disabled = false;
+       return 0;
+}
+
+static int haptic_stop(void)
+{
+       _I("Stop");
+       haptic_disabled = true;
+       return 0;
+}
diff --git a/src/core/haptic.h b/src/core/haptic.h
new file mode 100644 (file)
index 0000000..54b92d5
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * feedbackd
+ *
+ * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __FEEDBACKD_HAPTIC_H__
+#define __FEEDBACKD_HAPTIC_H__
+
+#include <stdbool.h>
+#include <glib.h>
+#include <device/power.h>
+#include "shared/common.h"
+
+enum priority_level {
+       PRIORITY_MIN = 0,
+       PRIORITY_MIDDLE,
+       PRIORITY_HIGH,
+       PRIORITY_TOP,
+};
+
+struct haptic_data {
+       GList *vibration_data;
+       unsigned int handle;
+       int level;
+       int priority;
+       bool stop;
+       int unlimit;
+};
+
+#define INVALID_HANDLE 0
+
+int haptic_probe(void);
+void haptic_init(void);
+void haptic_exit(void);
+
+#endif /* __FEEDBACKD_HAPTIC_H__ */
index 0fe52ca46fcd4309274a0b3fbfd14b2cacd3e6ec..a6760e90be396449f25f6be22f697ca09f63b1d4 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "shared/log.h"
 #include "shared/common.h"
-#include "driver/haptic.h"
+#include "haptic.h"
 
 #define VIBRATION_FEATURE              "http://tizen.org/feature/feedback.vibration"
 
diff --git a/src/driver/emulator.c b/src/driver/emulator.c
deleted file mode 100644 (file)
index bca8790..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * feedbackd
- *
- * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <stdio.h>
-#include <errno.h>
-#include <libsyscommon/list.h>
-
-#include "shared/common.h"
-#include "shared/log.h"
-#include "haptic-dev.h"
-
-static GList *handle_list;
-static int unique_number = 0;
-
-/* START: Haptic Module APIs */
-static int get_device_count(int *count)
-{
-       if (count)
-               *count = 1;
-
-       return 0;
-}
-
-static int open_device(int device_index, int *device_handle)
-{
-       GList *elem;
-       int handle;
-       bool found = false;
-
-       if (unique_number == INT_MAX)
-               unique_number = 0;
-
-       while (found != true) {
-               ++unique_number;
-               elem = SYS_G_LIST_FIND(handle_list, (gpointer)(long)unique_number);
-               if (!elem)
-                       found = true;
-       }
-       handle = unique_number;
-       SYS_G_LIST_APPEND(handle_list, (gpointer)(long)handle);
-
-       if (device_handle)
-               *device_handle = handle;
-
-       return 0;
-}
-
-static int close_device(int device_handle)
-{
-       SYS_G_LIST_REMOVE(handle_list, (gpointer)(long)device_handle);
-
-       return 0;
-}
-
-static int vibrate_monotone(int device_handle, int duration, int frequency, int overdrive, int level, int intensity, int priority)
-{
-       GList *elem;
-
-       elem = SYS_G_LIST_FIND(handle_list, (gpointer)(long)device_handle);
-       if (!elem)
-               return -EINVAL;
-
-       return 0;
-}
-
-static int stop_device(int device_handle)
-{
-       GList *elem;
-
-       elem = SYS_G_LIST_FIND(handle_list, (gpointer)(long)device_handle);
-       if (!elem)
-               return -EINVAL;
-
-       return 0;
-}
-/* END: Haptic Module APIs */
-
-static const struct haptic_plugin_ops default_plugin = {
-       .get_device_count    = get_device_count,
-       .open_device         = open_device,
-       .close_device        = close_device,
-       .vibrate_monotone    = vibrate_monotone,
-       .stop_device         = stop_device,
-};
-
-static bool is_valid(void)
-{
-       if (is_emulator()) {
-               _I("Support emulator haptic device.");
-               return true;
-       }
-
-       _E("Do not support emulator haptic device.");
-       return false;
-}
-
-static const struct haptic_plugin_ops *load(void)
-{
-       return &default_plugin;
-}
-
-static const struct haptic_ops emul_ops = {
-       .is_valid = is_valid,
-       .load     = load,
-};
-
-EXPORT_GET_VAR_HAPTIC_OPS(&emul_ops)
diff --git a/src/driver/external.c b/src/driver/external.c
deleted file mode 100644 (file)
index 2c610d2..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * feedbackd
- *
- * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <dlfcn.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-#include "shared/log.h"
-#include "haptic.h"
-
-#define HAPTIC_MODULE_PATH                     "/usr/lib/libhaptic-module.so"
-
-/* Haptic Plugin Interface */
-static void *dlopen_handle;
-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;
-
-       ret = stat(HAPTIC_MODULE_PATH, &buf);
-       if (ret < 0) {
-               _E("Failed to stat file(%s): %d", HAPTIC_MODULE_PATH, errno);
-               goto error;
-       }
-
-       dlopen_handle = dlopen(HAPTIC_MODULE_PATH, RTLD_NOW);
-       if (!dlopen_handle) {
-               _E("Failed to dlopen.");
-               goto error;
-       }
-
-       get_haptic_plugin_interface = dlsym(dlopen_handle, "get_haptic_plugin_interface");
-       if (!get_haptic_plugin_interface) {
-               _E("Failed to dlsym.");
-               goto error;
-       }
-
-       plugin_intf = get_haptic_plugin_interface();
-       if (!plugin_intf) {
-               _E("Failed to get_haptic_plugin_interface().");
-               goto error;
-       }
-
-       _I("Support external haptic device.");
-       return true;
-
-error:
-       if (dlopen_handle) {
-               dlclose(dlopen_handle);
-               dlopen_handle = NULL;
-       }
-
-       _I("Do not support external haptic device.");
-       return false;
-}
-
-static const struct haptic_plugin_ops *load(void)
-{
-       return plugin_intf;
-}
-
-static void release(void)
-{
-       if (dlopen_handle) {
-               dlclose(dlopen_handle);
-               dlopen_handle = NULL;
-       }
-
-       plugin_intf = NULL;
-}
-
-static const struct haptic_ops ext_ops = {
-       .type     = HAPTIC_EXTERNAL,
-       .is_valid = is_valid,
-       .load     = load,
-       .release  = release,
-};
-
-HAPTIC_OPS_REGISTER(&ext_ops)
diff --git a/src/driver/gpio_haptic.c b/src/driver/gpio_haptic.c
deleted file mode 100644 (file)
index fb175cd..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * feedbackd
- *
- * Copyright (c) 2016 - 2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <glib.h>
-#include <libsyscommon/list.h>
-
-#include "shared/common.h"
-#include "shared/log.h"
-#include "haptic-interface.h"
-#include "peripheral_io.h"
-
-#define GPIO_I2C_BUS_INDEX             1
-#define MAX_HAPIC                              1
-#define DRV2605L_DEFAULT_ADDR  0x5A
-
-#define START_CMD_CODE 1
-#define STOP_CMD_CODE  0
-
-#define DRV2605L_REGISTER_STATUS       0x00
-#define DRV2605L_REGISTER_MODE         0x01
-#define DRV2605L_REGISTER_RTPINPUT     0x02
-#define DRV2605L_REGISTER_LIBRARY      0x03
-#define DRV2605L_REGISTER_WAVESEQ1     0x04
-#define DRV2605L_REGISTER_WAVESEQ2     0x05
-#define DRV2605L_REGISTER_WAVESEQ3     0x06
-#define DRV2605L_REGISTER_WAVESEQ4     0x07
-#define DRV2605L_REGISTER_WAVESEQ5     0x08
-#define DRV2605L_REGISTER_WAVESEQ6     0x09
-#define DRV2605L_REGISTER_WAVESEQ7     0x0A
-#define DRV2605L_REGISTER_WAVESEQ8     0x0B
-#define DRV2605L_REGISTER_GO           0x0C
-
-/**
- * Mode register
- */
-#define MODE_INTERNAL_TRIGGER          0
-#define MODE_EXTERNAL_TRIGGER_EDGE     1
-#define MODE_EXTERNAL_TRIGGER_LEVEL    2
-#define MODE_PWM_INPUT_ANALOG_INPUT    3
-#define MODE_AUDIO_TO_VIBE                     4
-#define MODE_REALTIME_PLAYBACK         5
-#define MODE_DIAGNOSTICS                       6
-#define MODE_AUTO_CALIBRATION          7
-/**
- * Library register
- */
-#define EMPTY_LIBRARY          0
-#define TS2200_LIBRARY_A       1
-#define TS2200_LIBRARY_B       2
-#define TS2200_LIBRARY_C       3
-#define TS2200_LIBRARY_D       4
-#define TS2200_LIBRARY_E       5
-#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 GList *handle_list;
-static int unique_number;
-
-static bool state = false;
-//static bool is_playing = false;
-static guint stop_timer = 0;
-
-static int gpio_haptic_stop_device(int handle);
-
-static bool find_from_list(int handle)
-{
-       GList *elem;
-
-       elem = SYS_G_LIST_FIND(handle_list, (gpointer)(long)handle);
-       if (elem)
-               return true;
-
-       return false;
-}
-
-/* START: Haptic Module APIs */
-static gboolean gpio_haptic_timer_cb(void *data)
-{
-       int handle = (int)(long)data;
-       bool found;
-
-       _I("Stop vibration by timer.");
-
-       found = find_from_list(handle);
-       if (!found)
-               return G_SOURCE_REMOVE;
-
-       if (device_handle == NULL) {
-               if (peripheral_i2c_open(GPIO_I2C_BUS_INDEX, DRV2605L_DEFAULT_ADDR, &device_handle) < PERIPHERAL_ERROR_NONE) {
-                       _E("Failed to open I2C.");
-                       return -EIO;
-               }
-       }
-
-       /*  stop playing */
-       peripheral_i2c_write_register_byte(device_handle, DRV2605L_REGISTER_MODE, MODE_INTERNAL_TRIGGER);
-
-       stop_timer = 0;
-       return G_SOURCE_REMOVE;
-}
-
-static int gpio_haptic_get_device_count(int *count)
-{
-       _I("HAL: The max number of DRV2605L is %d.", (int)MAX_HAPIC);
-       if (count)
-               *count = MAX_HAPIC;
-
-       return 0;
-}
-
-/**
- * Only one handle
- * return  device_handle
- */
-static int gpio_haptic_open_device(int device_index, int *handle)
-{
-       int n;
-       bool found = false;
-       GList *elem;
-
-       if (!handle)
-               return -EINVAL;
-
-       /* if it is the first element */
-       n = SYS_G_LIST_LENGTH(handle_list);
-       if (n == 0) {
-               _I("Peripheral Device Open.");
-               if (device_handle == NULL) {
-                       if (peripheral_i2c_open(GPIO_I2C_BUS_INDEX, DRV2605L_DEFAULT_ADDR, &device_handle) < PERIPHERAL_ERROR_NONE) {
-                               _E("Failed to open I2C.");
-                               return -EIO;
-                       }
-               }
-       }
-
-       if (unique_number == INT_MAX)
-               unique_number = 0;
-
-       while (found != true) {
-               ++unique_number;
-               elem = SYS_G_LIST_FIND(handle_list, (gpointer)(long)unique_number);
-               if (!elem)
-                       found = true;
-       }
-
-       /* add info to local list */
-       SYS_G_LIST_APPEND(handle_list, (gpointer)(long)unique_number);
-
-       *handle = unique_number;
-       return 0;
-}
-
-static int gpio_haptic_close_device(int handle)
-{
-       int r, n;
-       bool found;
-
-       found = find_from_list(handle);
-       if (!found)
-               return -EINVAL;
-
-       if (device_handle == NULL) {
-               if (peripheral_i2c_open(GPIO_I2C_BUS_INDEX, DRV2605L_DEFAULT_ADDR, &device_handle) < PERIPHERAL_ERROR_NONE) {
-                       _E("Failed to open I2C.");
-                       return -EIO;
-               }
-       }
-
-       /* stop vibration */
-       r = gpio_haptic_stop_device(handle);
-       if (r < 0)
-               _I("Already stopped or failed to stop effect: %d", r);
-
-       _D("Handle(%d) is closed and timer deleted.", handle);
-       SYS_G_LIST_REMOVE(handle_list, (gpointer)(long)handle);
-
-       /* if it is the last element */
-       n = SYS_G_LIST_LENGTH(handle_list);
-       if (n == 0) {
-               _I("Peripheral Device Close.");
-               if (device_handle != NULL) {
-                       if (peripheral_i2c_close(device_handle) < PERIPHERAL_ERROR_NONE) {
-                               _E("Failed to close peripheral I2C.");
-                               return -EIO;
-                       }
-                       device_handle = NULL;
-               }
-       }
-       return 0;
-}
-
-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)
-               return -EINVAL;
-
-       if (device_handle == NULL) {
-               if (peripheral_i2c_open(GPIO_I2C_BUS_INDEX, DRV2605L_DEFAULT_ADDR, &device_handle) < PERIPHERAL_ERROR_NONE) {
-                       _E("Failed to open I2C.");
-                       return -EIO;
-               }
-       }
-
-       /* Zero(0) is the infinitely vibration value */
-       if (duration == HAPTIC_MODULE_DURATION_UNLIMITED)
-               duration = 0;
-
-       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)feedback);
-
-       /* register timer */
-       if (duration) {
-         //stop_timer = ecore_timer_add(duration/1000.f, gpio_haptic_timer_cb, (void *)(long)handle);
-         stop_timer = g_timeout_add(duration, gpio_haptic_timer_cb, (void *)(long)handle);
-               if (!stop_timer)
-                       _E("Failed to add timer callback.");
-       }
-       _D("Device handle(%d) %dms", handle, duration);
-
-       return 0;
-}
-
-static int gpio_haptic_stop_device(int handle)
-{
-       bool found;
-
-       found = find_from_list(handle);
-       if (!found)
-               return -EINVAL;
-
-       if (device_handle == NULL) {
-               if (peripheral_i2c_open(GPIO_I2C_BUS_INDEX, DRV2605L_DEFAULT_ADDR, &device_handle) < PERIPHERAL_ERROR_NONE) {
-                       _E("Failed to open I2C.");
-                       return -EIO;
-               }
-       }
-
-       /*  stop playing */
-       peripheral_i2c_write_register_byte(device_handle, DRV2605L_REGISTER_MODE, MODE_INTERNAL_TRIGGER);
-
-       if (stop_timer) {
-               //ecore_timer_del(stop_timer);
-               g_source_remove(stop_timer);
-               stop_timer = 0;
-       }
-
-       return 0;
-}
-/* END: Haptic Module APIs */
-
-static const struct haptic_plugin_ops default_plugin = {
-       .get_device_count               = gpio_haptic_get_device_count,
-       .open_device                    = gpio_haptic_open_device,
-       .close_device                   = gpio_haptic_close_device,
-       .vibrate_monotone               = gpio_haptic_vibrate_monotone,
-       .stop_device                    = gpio_haptic_stop_device,
-};
-
-static bool is_valid(void)
-{
-       uint8_t result;
-       peripheral_i2c_h handle;
-
-       if (peripheral_i2c_open(GPIO_I2C_BUS_INDEX, DRV2605L_DEFAULT_ADDR, &handle) < PERIPHERAL_ERROR_NONE) {
-               _E("Failed to open I2C.");
-               state = false;
-               return false;
-       }
-       if (peripheral_i2c_read_register_byte(handle, DRV2605L_REGISTER_STATUS, &result) < PERIPHERAL_ERROR_NONE) {
-               _E("Failed to read peripheral I2C.");
-               if (peripheral_i2c_close(handle) < PERIPHERAL_ERROR_NONE)
-                       _E("Failed to close peripheral I2C.");
-               state = false;
-               return false;
-       }
-       if (peripheral_i2c_close(handle) < PERIPHERAL_ERROR_NONE) {
-               _E("Failed to close peripheral I2C.");
-               state = false;
-               return false;
-       }
-
-       state = true;
-       _I("Support gpio haptic device.");
-       return true;
-}
-
-static const struct haptic_plugin_ops *load(void)
-{
-       _I("Gpio haptic device module loaded.");
-       return &default_plugin;
-}
-
-static const struct haptic_ops gpio_haptic_ops = {
-       .is_valid = is_valid,
-       .load    = load,
-};
-
-EXPORT_GET_VAR_HAPTIC_OPS(&gpio_haptic_ops)
diff --git a/src/driver/haptic-dev.c b/src/driver/haptic-dev.c
deleted file mode 100644 (file)
index 05c4d84..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * feedbackd
- *
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unlessnn required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <dlfcn.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-#include "shared/log.h"
-#include "haptic.h"
-#include "haptic-dev.h"
-
-#ifndef LIBPATH
-#error LIBPATH is not defined.
-#endif
-#define HAPTIC_MODULE_PATH                     LIBPATH"/feedbackd/haptic.so"
-
-#define CHECK_NO_DEVICE(dev)   \
-       do {                                            \
-               if (!dev)                               \
-                       return -ENODEV;         \
-       }while(0)                                       \
-
-/* Haptic Plugin Interface */
-static void *haptic_handle;
-static const struct haptic_plugin_ops *plugin_ops;
-static const struct haptic_ops *haptic_ops;
-static const struct haptic_ops* (*fp_get_var_haptic_ops)(void);
-
-int haptic_load_device(void)
-{
-       struct stat buf;
-       int ret;
-
-       ret = stat(HAPTIC_MODULE_PATH, &buf);
-       if (ret < 0) {
-               _E("Failed to stat file(%s): %d", HAPTIC_MODULE_PATH, errno);
-               goto error;
-       }
-
-       haptic_handle = dlopen(HAPTIC_MODULE_PATH, RTLD_NOW);
-       if (!haptic_handle) {
-               _E("Failed to open file(%s): %s.", HAPTIC_MODULE_PATH, dlerror());
-               goto error;
-       }
-
-       fp_get_var_haptic_ops = dlsym(haptic_handle, "get_var_haptic_ops");
-       if (!fp_get_var_haptic_ops) {
-               _E("Failed to get \'get_var_haptic_ops\' function.");
-               goto error;
-       }
-
-       haptic_ops = fp_get_var_haptic_ops();
-       if (!haptic_ops) {
-               _E("Failed to call get_var_haptic_ops");
-               goto error;
-       }
-
-       if (haptic_ops->is_valid && haptic_ops->is_valid()) {
-               if (haptic_ops->load)
-                       plugin_ops = haptic_ops->load();
-       }
-
-       if (!plugin_ops) {
-               _E("Failed to load haptic device.");
-               goto error;
-       }
-
-       return 0;
-
-error:
-       if (haptic_handle) {
-               dlclose(haptic_handle);
-               haptic_handle = NULL;
-               haptic_ops = NULL;
-       }
-
-       return -ENODEV;
-}
-
-void haptic_release_device()
-{
-       if (haptic_ops) {
-               if (haptic_ops->is_valid && haptic_ops->is_valid()) {
-                       if (haptic_ops->release)
-                               haptic_ops->release();
-               }
-       }
-
-       if (haptic_handle)
-               dlclose(haptic_handle);
-
-       haptic_handle = NULL;
-       haptic_ops = NULL;
-       plugin_ops = NULL;
-}
-
-int haptic_open_device(int *dev_handle)
-{
-       CHECK_NO_DEVICE(plugin_ops);
-
-       if (!dev_handle)
-               return -EINVAL;
-
-       return plugin_ops->open_device(HAPTIC_MODULE_DEVICE_ALL, dev_handle);
-}
-
-int haptic_close_device(int dev_handle)
-{
-       CHECK_NO_DEVICE(plugin_ops);
-
-       return plugin_ops->close_device(dev_handle);
-}
-
-int haptic_check_device()
-{
-       CHECK_NO_DEVICE(plugin_ops);
-
-       return 0;
-}
-
-int haptic_vibrate_device(int device_handle, int duration, int frequency,
-                                               int overdrive, int level, int intensity, int priority)
-{
-       CHECK_NO_DEVICE(plugin_ops);
-
-       return plugin_ops->vibrate_monotone(device_handle, duration, frequency, overdrive,
-                               level, intensity, priority);
-
-}
-
-int haptic_get_count_device(int *count)
-{
-       CHECK_NO_DEVICE(plugin_ops);
-
-       if (!count)
-               return -EINVAL;
-
-       return plugin_ops->get_device_count(count);
-}
-
-int haptic_stop_device(int handle)
-{
-       CHECK_NO_DEVICE(plugin_ops);
-
-       return plugin_ops->stop_device(handle);
-}
-
diff --git a/src/driver/haptic-dev.h b/src/driver/haptic-dev.h
deleted file mode 100644 (file)
index 208a5a1..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * feedbackd
- *
-i * Copyright (c) 2012 - 2020 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef __FEEDBACKD_HAPTIC_DEV_H__
-#define __FEEDBACKD_HAPTIC_DEV_H__
-
-#include <stdbool.h>
-#include "haptic-interface.h"
-
-int haptic_load_device(void);
-void haptic_release_device();
-int haptic_open_device(int *dev_handle);
-int haptic_check_device();
-int haptic_close_device(int dev_handle);
-
-int haptic_vibrate_device(int device_handle, int duration, int frequency, int overdrive, int level, int intensity, int priority);
-
-int haptic_get_count_device(int *count);
-int haptic_stop_device(int handle);
-
-#endif /* __FEEDBACKD_HAPTIC_DEV_H__ */
diff --git a/src/driver/haptic-interface.h b/src/driver/haptic-interface.h
deleted file mode 100644 (file)
index de1d6c4..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * deviced
- *
- * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef __FEEDBACKD_HAPTIC_INTERFACE_H__
-#define __FEEDBACKD_HAPTIC_INTERFACE_H__
-
-#include <stdio.h>
-
-enum haptic_type {
-    HAPTIC_STANDARD,
-    HAPTIC_EXTERNAL,
-};
-
-/**
- * @brief Enumerations of device id for the Haptic Module API.
- * @details We support two motors now.
- */
-typedef enum {
-    HAPTIC_MODULE_DEVICE_0 = 0x0,             /**< 1st motor */
-    HAPTIC_MODULE_DEVICE_1 = 0x1,             /**< 2nd motor */
-    HAPTIC_MODULE_DEVICE_ALL = 0x4,           /**< both of them */
-} haptic_module_device;
-
-/**
- * @brief Enumerations of unlimited duration for the Haptic Module API.
- */
-typedef enum {
-    HAPTIC_MODULE_DURATION_UNLIMITED = 0x7FFFFFFF,
-} haptic_module_duration;
-
-struct haptic_ops {
-    enum haptic_type type;
-    bool (*is_valid)(void);
-    const struct haptic_plugin_ops *(*load)(void);
-    void (*release)(void);
-};
-
-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, int);
-       int (*stop_device) (int);
-};
-
-#define EXPORT_GET_VAR_HAPTIC_OPS(ops) \
-const struct haptic_ops __attribute__((visibility("default")))* get_var_haptic_ops(void)       \
-{      \
-       return ops;     \
-}      \
-
-const struct haptic_ops *get_var_haptic_ops();
-#endif /* __FEEDBACKD_HAPTIC_INTERFACE_H__ */
diff --git a/src/driver/haptic.c b/src/driver/haptic.c
deleted file mode 100644 (file)
index 19c4145..0000000
+++ /dev/null
@@ -1,1396 +0,0 @@
-/*
- * feedbackd
- *
- * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <dlfcn.h>
-#include <assert.h>
-#include <vconf.h>
-#include <time.h>
-#include <string.h>
-#include <libsyscommon/dbus-system.h>
-#include <libsyscommon/list.h>
-#include <libsyscommon/ini-parser.h>
-
-#include "shared/log.h"
-#include "shared/common.h"
-#include "shared/device-idler.h"
-#include "haptic.h"
-#include "haptic-dev.h"
-
-#define FEEDBACK_BASE_PATH         "/usr/share/feedback/"
-#define STANDARD_FILE_PATH         FEEDBACK_BASE_PATH"vibration/"
-#define VIBRATION_CONF_PATH        FEEDBACK_BASE_PATH"vibration.conf"
-
-#define HAPTIC_CONF_PATH                "/etc/feedbackd/haptic.conf"
-#define SIGNAL_POWEROFF_STATE           "ChangeState"
-#define SIGNAL_VIBRATOR_INITIATED       "InitiateVibrator"
-
-/* hardkey vibration variable */
-#define HARDKEY_VIB_ITERATION          1
-#define HARDKEY_VIB_FEEDBACK           3
-#define HARDKEY_VIB_DURATION           30
-#define HAPTIC_FEEDBACK_STEP           20
-#define DEFAULT_FEEDBACK_LEVEL         3
-#define HIGH_FEEDBACK_LEVEL            100
-#define LOW_FEEDBACK_LEVEL             0
-
-/* power on, power off vibration variable */
-#define POWER_ON_VIB_DURATION                  300
-#define POWER_OFF_VIB_DURATION                 300
-#define POWER_VIB_FEEDBACK                     100
-
-#define MAX_EFFECT_BUFFER                      (64*1024)
-
-#ifndef VCONFKEY_RECORDER_STATE
-#define VCONFKEY_RECORDER_STATE "memory/recorder/state"
-#define VCONFKEY_RECORDER_STATE_RECORDING      2
-#endif
-
-#define RETRY_CNT      3
-
-#define INTENSITY_BASE_RATE        (10000)
-#define VALUE_MAX_LEN              10
-#define VIB_LOCK_TIMEOUT_MAX       (300000) /* 5minutes */
-
-/*
-               1,A_W or A,A_W or 250D250W250D750W
-
-               85,10000,
-               90,0,
-               105,10000,
-               0,end
-*/
-struct vibration_config {
-       char *pattern; /* pattern name */
-       char *standard; /* assigned standard pattern name */
-       GList *data; /* duration_data list */
-       unsigned int pattern_duration;
-       int unlimit;
-};
-
-struct duration_data {
-       int duration;
-       int intensity;
-       int frequency;
-       int overdrive;
-       int wait;
-};
-
-enum poweroff_type {
-       POWER_OFF_NONE = 0,
-       POWER_OFF_POPUP,
-       POWER_OFF_DIRECT,
-       POWER_OFF_RESTART,
-};
-
-struct haptic_info {
-       char *sender;
-       GList *handle_list;
-       guint id_watch;
-};
-
-struct vibrate_pattern_info {
-       unsigned int handle;
-       char *pattern;
-       int level;
-       int priority;
-};
-
-struct vibrate_monotone_info {
-       unsigned int handle;
-       int duration;
-       int level;
-       int intensity;
-       int priority;
-};
-
-/* for playing */
-static int g_handle;
-
-/* pattern configuration list */
-static GList *vib_conf_list;
-
-static guint duration_timer;
-
-/* haptic operation variable */
-static GList *haptic_handle_list;
-
-static bool haptic_disabled;
-
-struct haptic_config {
-       int level;
-       int *level_arr;
-       int sound_capture;
-};
-
-static struct haptic_config haptic_conf;
-
-static int haptic_start(void);
-static int haptic_stop(void);
-static int remove_haptic_info(struct haptic_info *info);
-
-struct haptic_data cur_h_data;
-
-static int insert_conf_data(GList **conf_data, struct duration_data *update)
-{
-       struct duration_data *data;
-
-       data = (struct duration_data *)calloc(1, sizeof(struct duration_data));
-       if (!data) {
-               _E("Not enough memory.");
-               return -ENOMEM;
-       }
-       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->overdrive, data->wait);
-       SYS_G_LIST_APPEND(*conf_data, data);
-       return 0;
-}
-
-static void get_pattern_property(char **iter, char property, int *value)
-{
-       char *check;
-       unsigned long int val;
-
-       check = strchr(*iter, property);
-       if (!check)
-               return;
-
-       *check = '\0';
-       val = strtoul(*iter, NULL, 10);
-       if (errno == EINVAL || errno == ERANGE) {
-               val = 0;
-               _E("Failed to get value of %s: %d", *iter, errno);
-       }
-       if (val > VIB_LOCK_TIMEOUT_MAX)
-               val = VIB_LOCK_TIMEOUT_MAX;
-
-       *value = (int)val;
-
-       *iter = check + 1;
-}
-
-/* [A]xxxDxxxIxxxFxxxOxxxW format */
-static int insert_raw_data_format(GList **conf_data, char *value)
-{
-       struct duration_data update = {0, };
-       char *iter;
-       char *end;
-       int pattern_duration = 0;
-
-       if (!value)
-               return insert_conf_data(conf_data, &update);
-       if (!conf_data) {
-               _E("Invalid parameter: Configuration list is null");
-               return -EINVAL;
-       }
-
-       iter = value;
-       end = iter + strlen(iter);
-       while (iter < end) {
-               memset(&update, 0, sizeof(struct duration_data));
-
-               get_pattern_property(&iter, 'D', &update.duration);
-               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) {
-                       _D("Pattern duration is zero.");
-                       break;
-               }
-
-               pattern_duration += (update.duration + update.wait);
-               if (pattern_duration > VIB_LOCK_TIMEOUT_MAX) {
-                       _D("Max pattern duration.");
-                       pattern_duration = VIB_LOCK_TIMEOUT_MAX;
-               }
-
-               if (insert_conf_data(conf_data, &update) < 0)
-                       return -EINVAL;
-       }
-
-       return pattern_duration;
-}
-
-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 > 4 || count <= 0) {
-               _E("Invalid parameter: count is invalid");
-               return -EINVAL;
-       }
-
-       if (!packed || !val || !pattern_duration || !update) {
-               _E("Invalid parameter: %p %p %p %p", packed, val, pattern_duration, update);
-               return -EINVAL;
-       }
-
-       get_pattern_property(&val, 'C', &value);
-
-       ret = count;
-       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;
-               }
-               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;
-               }
-               ret = 0;
-               break;
-       default:
-               break;
-       }
-       return ret;
-}
-
-/*
-       duration, intensity, frequency, overdrive
-       waiting duration, intensity=0, frequency, overdrive
-       85,10000,
-       90,0,
-       105,10000,
-       0,end
-*/
-static int load_standard_format(const char *pattern)
-{
-       struct duration_data update = {0, };
-       bool packed = false;
-       struct vibration_config *conf;
-       int ret = 0, count = 0, end = 2;
-       int index = 0;
-       int fd;
-       char path[PATH_MAX], elem, val[VALUE_MAX_LEN] = {0, };
-
-       snprintf(path, sizeof(path), STANDARD_FILE_PATH"%s", pattern);
-       fd = open(path, O_RDONLY);
-       if (fd < 0)
-               return -ENOENT;
-
-       conf = (struct vibration_config *)calloc(1, sizeof(struct vibration_config));
-       if (!conf) {
-               _E("Failed to alloc.");
-               ret = -errno;
-               goto error_out;
-       }
-
-       conf->pattern = strdup(pattern);
-       if (!conf->pattern) {
-               _E("Failed to copy pattern data(%s).", pattern);
-               ret = -errno;
-               goto error_out;
-       }
-
-       /* make feedback pattern(xDxIxFxOxW) format from d,i,f,o, */
-       while (read(fd, &elem, 1) != 0) {
-               if (end == 0) {
-                       if (insert_conf_data(&conf->data, &update) < 0)
-                               goto error_out;
-                       break;
-               }
-               if (elem == 'e' || elem == 'n' || elem == 'd') {
-                       end--;
-                       continue;
-               }
-               if (elem == '\n') {
-                       count = 0;
-                       continue;
-               }
-               if (elem == ',') {
-                       count++;
-                       val[index] = 'C';
-                       index = 0;
-
-                       ret = get_config_data(count, &packed, val, &(conf->pattern_duration), &update);
-                       if (ret < 0) {
-                               if (ret == -EINVAL)
-                                       break;
-                               if (insert_conf_data(&conf->data, &update) < 0)
-                                       goto error_out;
-                               memset(&update, 0, sizeof(struct duration_data));
-                       } else
-                               count = ret;
-               } else {
-                       if (index < (VALUE_MAX_LEN - 2)) /* Temporal limit */
-                               val[index++] = elem;
-                       else
-                               _E("Pattern(%s) is out of bound: %s", pattern, val);
-               }
-       }
-       close(fd);
-       SYS_G_LIST_APPEND(vib_conf_list, conf);
-       return ret;
-
-error_out:
-       if (fd >= 0)
-               close(fd);
-       if (conf) {
-               if (conf->pattern)
-                       free(conf->pattern);
-               free(conf);
-       }
-       return -ENOENT;
-}
-
-static int vibration_load_config(struct parse_result *result, void *user_data)
-{
-       struct vibration_config *conf;
-       char *value;
-       char *check;
-       int len;
-       int duration;
-
-       if (!result)
-               return 0;
-
-       if (!MATCH(result->section, "Vibration"))
-               return 0;
-
-
-       if (!result->name || !result->value)
-               return 0;
-
-       conf = (struct vibration_config *)calloc(1, sizeof(struct vibration_config));
-       if (!conf) {
-               _E("Failed to alloc.");
-               return -ENOMEM;
-       }
-
-       conf->pattern_duration = 0;
-       conf->pattern = strdup(result->name);
-       if (!conf->pattern) {
-               _E("Failed to copy pattern data(%s).", result->name);
-               goto error_out;
-       }
-
-       value = result->value;
-       len = strlen(value);
-
-       if (len == 0) {
-               if (insert_raw_data_format(&conf->data, NULL) < 0)
-                       goto error_out;
-               SYS_G_LIST_APPEND(vib_conf_list, conf);
-               return 0;
-       }
-
-       /* Load Standard Pattern Name */
-       /* value: 1,A_W or A,A_W */
-       if ((check = strchr(value, ','))) {
-               *check = '\0';
-               if (strncmp(value, "A", 1) == 0)
-                       conf->unlimit = 1;
-               value = check + 1;
-               conf->standard = strdup(value);
-               if (!conf->standard) {
-                       _E("Failed to copy standard name.");
-                       goto error_out;
-               }
-               SYS_G_LIST_APPEND(vib_conf_list, conf);
-               return 0;
-       }
-
-       /* value : A100D or 100D0W or 250D250W250D750W */
-       /* Load Vibration Pattern Data */
-       check = strchr(value, 'A');
-       if (check) {
-               *check = '\0';
-               conf->unlimit = 1;
-               if (!value)
-                       len = len - 1;
-               else
-                       len = len - strlen(value) - 1;
-               value = check + 1;
-       }
-       duration = insert_raw_data_format(&conf->data, value);
-       if (duration < 0) {
-               conf->pattern_duration = 0;
-               goto error_out;
-       } else
-               conf->pattern_duration = duration;
-       SYS_G_LIST_APPEND(vib_conf_list, conf);
-
-       return 0;
-
-error_out:
-       if (conf) {
-               if (conf->pattern)
-                       free(conf->pattern);
-               if (conf->standard)
-                       free(conf->standard);
-       }
-       return -ENOMEM;
-}
-
-static void load_standard_vibration_patterns(void)
-{
-       DIR *dir;
-       struct dirent *dent;
-       int ret;
-
-       dir = opendir(STANDARD_FILE_PATH);
-       if (!dir) {
-               _E("Failed to load '%s' Use default value.", STANDARD_FILE_PATH);
-               return;
-       }
-       while ((dent = readdir(dir))) {
-               if (dent->d_type == DT_DIR)
-                       continue;
-               ret = load_standard_format(dent->d_name);
-               if (ret < 0)
-                       _E("Failed to parse %s: %d", dent->d_name, ret);
-       }
-       closedir(dir);
-       _D("Success to load '%s'", STANDARD_FILE_PATH);
-}
-
-void pattern_config_parse(void)
-{
-       int ret;
-
-       ret = config_parse(VIBRATION_CONF_PATH, vibration_load_config, NULL);
-       if (ret < 0)
-               _E("Failed to load '%s'. Use default value: %d", VIBRATION_CONF_PATH, ret);
-
-       load_standard_vibration_patterns();
-}
-
-static int haptic_module_load(void)
-{
-       int r;
-
-       pattern_config_parse();
-
-       r = haptic_load_device();
-       if (r < 0) {
-               _E("Failed to load device. ret=%d", r);
-               return r;
-       }
-
-       /* solution bug
-        * we do not use internal vibration except power off.
-        * if the last handle is closed during the playing of vibration,
-        * solution makes unlimited vibration.
-        * so we need at least one handle. */
-       r = haptic_open_device(&g_handle);
-       if (r < 0) {
-               _E("Failed to open device. ret=%d", r);
-               return r;
-       }
-
-       return 0;
-}
-
-/*
-static int convert_magnitude_by_conf(int level)
-{
-       int i, step;
-
-       if (level < LOW_FEEDBACK_LEVEL)
-               level = LOW_FEEDBACK_LEVEL;
-       else if (level > HIGH_FEEDBACK_LEVEL)
-               level = HIGH_FEEDBACK_LEVEL;
-
-       step = 100 / (haptic_conf.level-1);
-       for (i = 0; i < haptic_conf.level; ++i) {
-               if (level <= i*step) {
-                       _D("Level changed. %d -> %d", level, haptic_conf.level_arr[i]);
-                       return haptic_conf.level_arr[i];
-               }
-       }
-
-       _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)
-{
-       int ret, val;
-
-       if ((ret = haptic_check_device()) < 0)
-               goto exit;
-
-       ret = haptic_get_count_device(&val);
-       if (ret >= 0)
-               ret = val;
-
-exit:
-       return g_variant_new("(i)", ret);
-}
-
-void haptic_name_owner_changed(GDBusConnection *connection,
-       const gchar     *name,
-       gpointer         user_data)
-{
-       GList *n;
-       struct haptic_info *info = user_data;
-       int handle;
-
-       _I("%s (sender=%s)", __func__, name);
-
-       if (!info)
-               return;
-
-       for (n = info->handle_list; n; n = n->next) {
-               handle = (int)(long)n->data;
-               haptic_stop_device(handle);
-               haptic_close_device(handle);
-       }
-
-       remove_haptic_info(info);
-}
-
-static struct haptic_info *add_haptic_info(const char *sender)
-{
-       struct haptic_info *info;
-
-       assert(sender);
-
-       info = calloc(1, sizeof(struct haptic_info));
-       if (!info)
-               return NULL;
-
-       info->sender = strdup(sender);
-       if (!info->sender) {
-               free(info);
-               return NULL;
-       }
-
-       SYS_G_LIST_APPEND(haptic_handle_list, info);
-
-       info->id_watch = dbus_handle_watch_name(sender, NULL, haptic_name_owner_changed, info, NULL);
-
-       return info;
-}
-
-static int remove_haptic_info(struct haptic_info *info)
-{
-       assert(info);
-
-       dbus_handle_unwatch_name(info->id_watch);
-
-       SYS_G_LIST_REMOVE(haptic_handle_list, info);
-       SYS_G_LIST_FREE_LIST(info->handle_list);
-       if (info->sender) {
-               free(info->sender);
-       }
-       free(info);
-
-       return 0;
-}
-
-static struct haptic_info *get_matched_haptic_info(const char *sender)
-{
-       GList *n;
-       struct haptic_info *info;
-       int len;
-
-       assert(sender);
-
-       len = strlen(sender) + 1;
-       SYS_G_LIST_FOREACH(haptic_handle_list, n, info) {
-               if (!strncmp(info->sender, sender, len))
-                       return info;
-       }
-
-       return NULL;
-}
-
-GVariant *hdbus_open_device(GDBusConnection *conn,
-                                                       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
-                                                       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
-{
-       int index, handle, ret;
-       struct haptic_info *info;
-
-       /* Load haptic module before booting done */
-       if (haptic_check_device() < 0) {
-               ret = haptic_module_load();
-               if (ret < 0)
-                       goto exit;
-       }
-
-       g_variant_get(param, "(i)", &index);
-
-       ret = haptic_open_device(&handle);
-       if (ret < 0)
-               goto exit;
-
-       if (!sender) {
-               ret = -EPERM;
-               haptic_close_device(handle);
-               goto exit;
-       }
-
-       info = get_matched_haptic_info(sender);
-       if (!info) {
-               info = add_haptic_info(sender);
-               if (!info) {
-                       _E("Failed to create haptic information.");
-                       ret = -EPERM;
-                       haptic_close_device(handle);
-                       goto exit;
-               }
-       }
-
-       SYS_G_LIST_APPEND(info->handle_list, (gpointer)(long)handle);
-
-       ret = handle;
-
-exit:
-       return g_variant_new("(i)", ret);
-}
-
-int clear_current_data(void)
-{
-       cur_h_data.handle = INVALID_HANDLE;
-       cur_h_data.priority = PRIORITY_MIN;
-
-       if (duration_timer) {
-               _I("Remove duration_timer.");
-               g_source_remove(duration_timer);
-               duration_timer = 0;
-       }
-
-       return 0;
-}
-
-GVariant *hdbus_close_device(GDBusConnection *conn,
-       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
-       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
-{
-       unsigned int handle;
-       int ret;
-       struct haptic_info *info;
-       int cnt;
-
-       if ((ret = haptic_check_device()) < 0)
-               goto exit;
-
-       g_variant_get(param, "(u)", &handle);
-
-       if (!sender) {
-               _E("Failed to get sender from dbus message.");
-               ret = -EPERM;
-               goto exit;
-       }
-
-       ret = haptic_close_device(handle);
-       if (ret < 0)
-               goto exit;
-
-       if (cur_h_data.handle == handle) {
-               /* Remove duration_timer for vibrate_effect */
-               clear_current_data();
-       }
-
-       info = get_matched_haptic_info(sender);
-       if (!info) {
-               _E("Failed to find the matched haptic info.");
-               goto exit;
-       }
-
-       SYS_G_LIST_REMOVE(info->handle_list, (gpointer)(long)handle);
-       cnt = SYS_G_LIST_LENGTH(info->handle_list);
-       if (cnt == 0)
-               remove_haptic_info(info);
-
-exit:
-       return g_variant_new("(i)", ret);
-}
-
-static gboolean _cb(void *data)
-{
-       if (duration_timer) {
-               g_source_remove(duration_timer);
-               duration_timer = 0;
-       }
-
-       cur_h_data.handle = INVALID_HANDLE;
-       cur_h_data.priority = PRIORITY_MIN;
-
-       return G_SOURCE_REMOVE;
-}
-
-static void vibrate_monotone_idler_cb(void *data)
-{
-       struct vibrate_monotone_info *vibrate_info;
-       int ret;
-
-       if (!data)
-               return;
-
-       vibrate_info = (struct vibrate_monotone_info *)data;
-
-       if (vibrate_info->priority < cur_h_data.priority) {
-               _I("Handle(%d) skip low priority. pre=%d now=%d", vibrate_info->handle, cur_h_data.priority, vibrate_info->priority);
-               free(vibrate_info);
-               return;
-       }
-
-       if (duration_timer) {
-               g_source_remove(duration_timer);
-               duration_timer = 0;
-       }
-
-       cur_h_data.vibration_data = NULL;
-       cur_h_data.handle = vibrate_info->handle;
-       cur_h_data.level = vibrate_info->level;
-       cur_h_data.priority = vibrate_info->priority;
-       cur_h_data.stop = false;
-       cur_h_data.unlimit = false;
-
-       ret = device_power_request_lock(POWER_LOCK_CPU, vibrate_info->duration);
-       if (ret != DEVICE_ERROR_NONE)
-               _E("Failed to request power lock.");
-
-       _D("Handle(%d) play=%dms, level=%d, intensity=%d, frequency=0)",
-                       cur_h_data.handle, vibrate_info->duration, cur_h_data.level,
-                       vibrate_info->intensity);
-
-       duration_timer = g_timeout_add(vibrate_info->duration, _cb, NULL);
-       haptic_vibrate_device(cur_h_data.handle, vibrate_info->duration, 0, 0, cur_h_data.level, vibrate_info->intensity, cur_h_data.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, intensity, priority, ret = 0;
-
-       if ((ret = haptic_check_device()) < 0)
-               goto exit;
-
-       if (haptic_disabled)
-               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;
-               goto exit;
-       }
-
-       if (priority < PRIORITY_MIN)
-               priority = PRIORITY_MIN;
-       else if (priority > PRIORITY_TOP)
-               priority = PRIORITY_TOP;
-
-       if (duration <= 0) {
-               _E("Skip vibrate handle(%d) requested less than 0.", handle);
-               ret = -EINVAL;
-               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.");
-               ret = -errno;
-               goto exit;
-       }
-
-       vibrate_info->handle = handle;
-       vibrate_info->duration = duration;
-       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);
-exit:
-       return g_variant_new("(i)", ret);
-}
-
-static gboolean haptic_duration_play(void *data)
-{
-       GList *head, *n, *next;
-       struct duration_data *node;
-       int ret = 0;
-
-       if (duration_timer) {
-               g_source_remove(duration_timer);
-               duration_timer = 0;
-       }
-
-       if (!data) {
-               if (cur_h_data.unlimit) /* In case of unlimit pattern, do not stop */
-                       head = cur_h_data.vibration_data;
-               else {
-                       cur_h_data.handle = INVALID_HANDLE;
-                       cur_h_data.priority = PRIORITY_MIN;
-                       goto out;
-               }
-       } else
-               head = (GList *)data;
-
-       if (cur_h_data.stop) {
-               _I("Stop currunt vibration.");
-               cur_h_data.stop = false;
-               cur_h_data.handle = INVALID_HANDLE;
-               cur_h_data.priority = PRIORITY_MIN;
-               goto out;
-       }
-
-       SYS_G_LIST_FOREACH_SAFE(head, n, next, node) {
-               _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) {
-                       if (!cur_h_data.unlimit) {
-                               cur_h_data.handle = INVALID_HANDLE;
-                               cur_h_data.priority = PRIORITY_MIN;
-                               break;
-                       } else {
-                               next = cur_h_data.vibration_data;
-                               continue;
-                       }
-               }
-
-               duration_timer = g_timeout_add((node->duration + node->wait), haptic_duration_play, (void *)next);
-
-               ret = haptic_vibrate_device(cur_h_data.handle, node->duration, node->frequency, node->overdrive, cur_h_data.level, node->intensity, cur_h_data.priority);
-
-               break;
-       }
-       if (ret != 0) {
-               _D("Auto stop vibration.");
-               cur_h_data.stop = true;
-       }
-out:
-       return G_SOURCE_REMOVE;
-}
-
-static void vibrate_pattern_idler_cb(void *data)
-{
-       struct vibrate_pattern_info *vibrate_info;
-       GList *elem;
-       struct vibration_config *conf;
-       char pattern[PATH_MAX];
-       int ret;
-       int unlimit = 0;
-
-       if (!data)
-               return;
-
-       vibrate_info = (struct vibrate_pattern_info *)data;
-
-       if (!(vibrate_info->pattern)) {
-               free(vibrate_info);
-               return;
-       }
-
-       /* Same or higher priority pattern should be played */
-       if (vibrate_info->priority < cur_h_data.priority) {
-               _I("Handle(%d) skip low priority. pre=%d now=%d", vibrate_info->handle, cur_h_data.priority, vibrate_info->priority);
-               goto out;
-       }
-
-       snprintf(pattern, sizeof(pattern), "%s", vibrate_info->pattern);
-       SYS_G_LIST_FOREACH(vib_conf_list, elem, conf) {
-               if (!conf->pattern)
-                       continue;
-               if (strcmp(conf->pattern, pattern))
-                       continue;
-               if (conf->standard) {
-                       unlimit = conf->unlimit;
-                       snprintf(pattern, sizeof(pattern), "%s", conf->standard);
-                       continue;
-               }
-
-               if (unlimit)
-                       cur_h_data.unlimit = unlimit;
-               else
-                       cur_h_data.unlimit = conf->unlimit;
-               cur_h_data.vibration_data = conf->data;
-               cur_h_data.handle = vibrate_info->handle;
-               cur_h_data.level = vibrate_info->level;
-               cur_h_data.priority = vibrate_info->priority;
-               cur_h_data.stop = false;
-               _I("Handle(%d) play=%s pri=%d %s", cur_h_data.handle, conf->pattern, cur_h_data.priority,
-                               cur_h_data.unlimit ? "Unlimit" : "Once");
-
-               if (conf->pattern_duration <= 0)
-                       break;
-
-               if (!cur_h_data.unlimit && conf->pattern_duration > 0) {
-                       ret = device_power_request_lock(POWER_LOCK_CPU, (int)conf->pattern_duration);
-                       if (ret != DEVICE_ERROR_NONE)
-                               _E("Failed to request power lock.");
-               }
-               haptic_duration_play((void *)cur_h_data.vibration_data);
-               goto out;
-       }
-       _E("Handle(%d) %s is not supported.", vibrate_info->handle, pattern);
-
-out:
-       free(vibrate_info->pattern);
-       free(vibrate_info);
-}
-
-GVariant *hdbus_vibrate_pattern(GDBusConnection *conn,
-       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
-       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
-{
-       struct vibrate_pattern_info *vibrate_info;
-       unsigned int handle;
-       char *pattern = NULL;
-       int level, priority, ret = 0;
-
-       if ((ret = haptic_check_device()) < 0)
-               goto exit;
-
-       if (haptic_disabled)
-               goto exit;
-
-       g_variant_get(param, "(usii)",  &handle, &pattern, &level, &priority);
-
-       if (level < 0) {
-               ret = -EINVAL;
-               goto exit;
-       }
-
-       if (priority < PRIORITY_MIN)
-               priority = PRIORITY_MIN;
-       else if (priority > PRIORITY_TOP)
-               priority = PRIORITY_TOP;
-
-       vibrate_info = calloc(1, sizeof(struct vibrate_pattern_info));
-       if (!vibrate_info) {
-               _E("Failed to allocate memory for vibrate_info.");
-               ret = -errno;
-               goto exit;
-       }
-       vibrate_info->handle = handle;
-       vibrate_info->pattern = pattern;
-       pattern = NULL;
-       if (!vibrate_info->pattern) {
-               _E("Failed to allocate memory for pattern.");
-               ret = -errno;
-               free(vibrate_info);
-               goto exit;
-       }
-       vibrate_info->level = level;
-       vibrate_info->priority = priority;
-
-       ret = add_idle_request(vibrate_pattern_idler_cb, (void *)vibrate_info);
-
-exit:
-       g_free(pattern);
-       return g_variant_new("(i)", ret);
-}
-
-GVariant *hdbus_stop_device(GDBusConnection *conn,
-       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
-       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
-{
-       unsigned int handle;
-       int ret = 0;
-
-       if ((ret = haptic_check_device()) < 0)
-               goto exit;
-
-       if (haptic_disabled) {
-               _I("Haptic disabled.");
-               goto exit;
-       }
-
-       g_variant_get(param, "(u)", &handle);
-
-       if (cur_h_data.handle != handle) {
-               _D("Not the request from current vibration handle(%d). Skip.", handle);
-               goto exit;
-       }
-
-       ret = haptic_stop_device(handle);
-       _I("Stop the device(handle=%u) :%d", handle, ret);
-
-       /* Remove duration_timer for vibrate_effect */
-       clear_current_data();
-
-exit:
-       return g_variant_new("(i)", ret);
-}
-
-GVariant *hdbus_show_handle_list(GDBusConnection *conn,
-       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
-       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
-{
-       GList *n;
-       GList *elem;
-       struct haptic_info *info;
-
-       _D("Sender Handle");
-       SYS_G_LIST_FOREACH(haptic_handle_list, n, info) {
-               for (elem = info->handle_list; elem; elem = elem->next)
-                       _D("%s %d", info->sender, (int)(long)elem->data);
-       }
-
-       return g_variant_new_tuple(NULL, 0);
-}
-
-int pattern_is_supported(const char *pattern)
-{
-       GList *elem;
-       struct vibration_config *conf;
-       int ret;
-
-       if (!pattern)
-               return -EINVAL;
-
-       ret = 0;
-       SYS_G_LIST_FOREACH(vib_conf_list, elem, conf) {
-               if (!conf->pattern)
-                       continue;
-               if (!strcmp(conf->pattern, pattern)) {
-                       ret = true;
-                       break;
-               }
-       }
-
-       return ret;
-}
-
-GVariant *hdbus_pattern_is_supported(GDBusConnection *conn,
-       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
-       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
-
-{
-       char *data = NULL;
-       int ret = 0;
-
-       if ((ret = haptic_check_device()) < 0)
-               goto exit;
-
-       if (haptic_disabled)
-               goto exit;
-
-       g_variant_get(param, "(s)", &data);
-
-       ret = pattern_is_supported(data);
-
-       _I("%s is supported: %d", data, ret);
-
-exit:
-       g_free(data);
-       return g_variant_new("(i)", ret);
-}
-
-static void haptic_poweroff_cb(GDBusConnection  *conn,
-       const gchar      *sender,
-       const gchar      *path,
-       const gchar      *iface,
-       const gchar      *name,
-       GVariant         *param,
-       gpointer          data)
-{
-       int type = POWER_OFF_NONE;
-       int ret, level;
-       struct timespec time = {0,};
-
-       if (!g_variant_get_safe(param, "(i)", &type)) {
-               _E("Failed to get params from gvariant. expected:%s, type:%s", "(i)", g_variant_get_type_string(param));
-               return;
-       }
-
-       if (type != POWER_OFF_DIRECT && type != POWER_OFF_RESTART)
-               return;
-
-       _D("Poweroff: %d", type);
-
-       if (haptic_check_device() < 0) {
-               if (haptic_module_load() < 0)
-                       return ;
-       }
-
-       if (!g_handle) {
-               if (haptic_open_device(&g_handle) < 0)
-                       return ;
-       }
-
-       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 intensity=%d frequency=0",
-               g_handle, POWER_OFF_VIB_DURATION, PRIORITY_HIGH, level,
-               POWER_VIB_FEEDBACK * 100);
-       ret = haptic_vibrate_device(g_handle, POWER_OFF_VIB_DURATION, 0, 0,
-                       level, POWER_VIB_FEEDBACK * 100, PRIORITY_HIGH);
-       if (ret < 0) {
-               _E("Failed to vibrate_monotone: %d", ret);
-               return;
-       }
-
-       /* sleep for vibration */
-       time.tv_nsec = POWER_OFF_VIB_DURATION * NANO_SECOND_MULTIPLIER;
-       nanosleep(&time, NULL);
-       return;
-}
-
-static void sound_capturing_cb(keynode_t *key, void *data)
-{
-       int status;
-
-       status = vconf_keynode_get_int(key);
-
-       /* if sound capture is in use, this value is 1(true). */
-       if (status == VCONFKEY_RECORDER_STATE_RECORDING)
-               haptic_stop();
-       else
-               haptic_start();
-}
-
-static int parse_section(struct parse_result *result, void *user_data, int index)
-{
-       struct haptic_config *conf = (struct haptic_config *)user_data;
-
-       if (!result)
-               return 0;
-
-       if (!result->section || !result->name || !result->value)
-               return 0;
-
-       if (MATCH(result->name, "sound_capture")) {
-               conf->sound_capture = atoi(result->value);
-       } else if (MATCH(result->name, "level")) {
-               conf->level = atoi(result->value);
-               if (conf->level < 0 || conf->level >= INT_MAX - 1) {
-                       _E("You must set level with positive number in integer range.");
-                       return -EINVAL;
-               }
-               conf->level_arr = calloc(sizeof(int), conf->level);
-               if (!conf->level_arr) {
-                       _E("Failed to allocate memory for level.");
-                       return -errno;
-               }
-       } else if (MATCH(result->name, "value")) {
-               if (index < 0)
-                       return -EINVAL;
-               conf->level_arr[index] = atoi(result->value);
-       }
-
-       return 0;
-}
-
-static int haptic_load_config(struct parse_result *result, void *user_data)
-{
-       struct haptic_config *conf = (struct haptic_config *)user_data;
-       char name[NAME_MAX];
-       int ret;
-       static int index;
-
-       if (!result)
-               return 0;
-
-       if (!result->section || !result->name || !result->value)
-               return 0;
-
-       // Parsing 'Haptic' section
-       if (MATCH(result->section, "Haptic")) {
-               ret = parse_section(result, user_data, -1);
-               if (ret < 0) {
-                       _E("Failed to parse 'Haptic' section: %d", ret);
-                       return ret;
-               }
-               goto out;
-       }
-
-       // Parsing 'level' section
-       for (index = 0; index < conf->level; ++index) {
-               snprintf(name, sizeof(name), "level%d", index);
-               if (MATCH(result->section, name)) {
-                       ret = parse_section(result, user_data, index);
-                       if (ret < 0) {
-                               _E("Failed to parse 'level' section: %d", ret);
-                               return ret;
-                       }
-                       goto out;
-               }
-       }
-
-out:
-       return 0;
-}
-
-static const dbus_method_s hdbus_methods[] = {
-       { "GetCount",          NULL,   "i", hdbus_get_count },            // device_haptic_get_count
-       { "OpenDevice",         "i",   "i", hdbus_open_device },          // device_haptic_open, feedback_initialize
-       { "CloseDevice",        "u",   "i", hdbus_close_device },         // device_haptic_close, feedback_deinitialize
-       { "StopDevice",         "u",   "i", hdbus_stop_device },          // device_haptic_stop, feedback_stop
-       { "VibrateMonotone", "uiii",   "i", hdbus_vibrate_monotone },     // device_haptic_vibrate
-       { "VibratePattern",  "usii",   "i", hdbus_vibrate_pattern },      // feedback_play*
-       { "ShowHandleList",    NULL,  NULL, hdbus_show_handle_list },
-       { "IsSupported",        "s",   "i", hdbus_pattern_is_supported }, // feedback_is_supported_pattern
-       /* Add methods here */
-};
-
-static const dbus_interface_u dbus_interface = {
-       .name = VIBRATOR_INTERFACE_HAPTIC,
-       .methods = hdbus_methods,
-       .nr_methods = ARRAY_SIZE(hdbus_methods),
-};
-
-int haptic_probe(void)
-{
-       /**
-        * load haptic module.
-        * if there is no haptic module,
-        * feedbackd does not activate a haptic interface.
-        */
-       return haptic_module_load();
-}
-
-static guint id_sig_pwr_off_state;
-
-void haptic_init(void)
-{
-       int r;
-
-       /* get haptic data from configuration file */
-       r = config_parse(HAPTIC_CONF_PATH, haptic_load_config, &haptic_conf);
-       if (r < 0) {
-               _E("Failed to load configuration file(%s): %d", HAPTIC_CONF_PATH, r);
-               safe_free(haptic_conf.level_arr);
-       }
-
-       /* init dbus interface */
-       r = dbus_handle_register_dbus_object(NULL, VIBRATOR_PATH_HAPTIC, &dbus_interface);
-       if (r < 0)
-               _E("Failed to init hdbus interface and method: %d", r);
-
-       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);
-               return;
-       }
-
-       dbus_handle_emit_dbus_signal(NULL,
-                       VIBRATOR_PATH_HAPTIC,
-                       VIBRATOR_INTERFACE_HAPTIC,
-                       SIGNAL_VIBRATOR_INITIATED,
-                       NULL);
-
-       /* add watch for sound capturing value */
-       if (haptic_conf.sound_capture) {
-               r = vconf_notify_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb, NULL);
-               if (r != 0)
-                       _W("Add watch for VCONFKEY_RECORDER_STATE failed.");
-       }
-
-       /* Initialize vibration_handle (Use vibration now) */
-       cur_h_data.handle = INVALID_HANDLE;
-       cur_h_data.priority = PRIORITY_MIN;
-}
-
-void haptic_exit(void)
-{
-       int r;
-
-       /* remove watch */
-       if (haptic_conf.sound_capture) {
-               r = vconf_ignore_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb);
-               if (r != 0)
-                       _W("Remove watch for VCONFKEY_RECORDER_STATE failed.");
-       }
-
-       /* unregister notifier for below each event */
-       unsubscribe_dbus_signal(NULL, id_sig_pwr_off_state);
-
-       /* release haptic data memory */
-       safe_free(haptic_conf.level_arr);
-
-       if (haptic_check_device() < 0)
-               return;
-
-       /* haptic exit for feedbackd */
-       haptic_close_device(g_handle);
-       haptic_release_device();
-}
-
-static int haptic_start(void)
-{
-       _I("Start");
-       haptic_disabled = false;
-       return 0;
-}
-
-static int haptic_stop(void)
-{
-       _I("Stop");
-       haptic_disabled = true;
-       return 0;
-}
diff --git a/src/driver/haptic.h b/src/driver/haptic.h
deleted file mode 100644 (file)
index 54b92d5..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * feedbackd
- *
- * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef __FEEDBACKD_HAPTIC_H__
-#define __FEEDBACKD_HAPTIC_H__
-
-#include <stdbool.h>
-#include <glib.h>
-#include <device/power.h>
-#include "shared/common.h"
-
-enum priority_level {
-       PRIORITY_MIN = 0,
-       PRIORITY_MIDDLE,
-       PRIORITY_HIGH,
-       PRIORITY_TOP,
-};
-
-struct haptic_data {
-       GList *vibration_data;
-       unsigned int handle;
-       int level;
-       int priority;
-       bool stop;
-       int unlimit;
-};
-
-#define INVALID_HANDLE 0
-
-int haptic_probe(void);
-void haptic_init(void);
-void haptic_exit(void);
-
-#endif /* __FEEDBACKD_HAPTIC_H__ */
diff --git a/src/driver/standard.c b/src/driver/standard.c
deleted file mode 100644 (file)
index 310bd3e..0000000
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * feedbackd
- *
- * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <linux/input.h>
-#include <libsyscommon/list.h>
-
-#include "shared/common.h"
-#include "shared/log.h"
-#include "haptic-interface.h"
-
-#define MAX_MAGNITUDE                  0xFFFF
-#define PERIODIC_MAX_MAGNITUDE 0x7FFF  /* 0.5 * MAX_MAGNITUDE */
-#define RUMBLE_MAX_MAGNITUDE   0xFFFF
-
-#define DEV_INPUT   "/dev/input"
-#define EVENT          "event"
-
-#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;
-       int ff_info_data_count;
-};
-
-struct ff_info_data {
-       int type;/* play, stop etc */
-       int magnitude; /* strength */
-       int length; /* in ms for stop, play*/
-};
-
-struct ff_info_buffer {
-       struct ff_info_header header;
-       struct ff_info_data data[MAX_DATA];
-};
-
-struct ff_info {
-       int handle;
-       guint timer;
-       struct ff_effect effect;
-       struct ff_info_buffer *ffinfobuffer;
-       int currentindex;
-};
-
-static int ff_fd;
-static GList *ff_list;
-static GList *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);
-
-struct ff_info *read_from_list(int handle)
-{
-       struct ff_info *temp;
-       GList *elem;
-
-       SYS_G_LIST_FOREACH(ff_list, elem, temp) {
-               if (temp->handle == handle)
-                       return temp;
-       }
-       return NULL;
-}
-
-static bool check_valid_handle(struct ff_info *info)
-{
-       struct ff_info *temp;
-       GList *elem;
-
-       SYS_G_LIST_FOREACH(ff_list, elem, temp) {
-               if (temp == info)
-                       break;
-       }
-
-       if (!temp)
-               return false;
-       return true;
-}
-
-static bool check_fd(int *fd)
-{
-       int ffd;
-
-       if (*fd > 0)
-               return true;
-
-       ffd = open(ff_path, O_RDWR);
-       if (ffd < 0)
-               return false;
-
-       *fd = ffd;
-       return true;
-}
-
-static int ff_stop(int fd, struct ff_effect *effect);
-static gboolean timer_cb(void *data)
-{
-       struct ff_info *info = (struct ff_info *)data;
-
-       if (!info) {
-               _E("Failed to check info.");
-               return G_SOURCE_REMOVE;
-       }
-
-       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);
-
-       /* reset timer */
-       info->timer = 0;
-
-       return G_SOURCE_REMOVE;
-}
-
-static int ff_find_device(void)
-{
-       DIR *dir;
-       struct dirent *dent;
-       char ev_path[PATH_MAX];
-       unsigned long features[1+FF_MAX/sizeof(unsigned long)];
-       int fd, ret;
-
-       dir = opendir(DEV_INPUT);
-       if (!dir)
-               return -errno;
-
-       while (1) {
-               dent = readdir(dir);
-               if (dent == NULL)
-                       break;
-
-               if (dent->d_type == DT_DIR ||
-                       !strstr(dent->d_name, "event"))
-                       continue;
-
-               snprintf(ev_path, sizeof(ev_path), "%s/%s", DEV_INPUT, dent->d_name);
-
-               fd = open(ev_path, O_RDWR);
-               if (fd < 0) {
-                       _E("Failed to open '%s'.: %d", ev_path, errno);
-                       continue;
-               }
-
-               /* get force feedback device */
-               memset(features, 0, sizeof(features));
-               ret = ioctl(fd, EVIOCGBIT(EV_FF, sizeof(features)), features);
-               if (ret == -1) {
-                       close(fd);
-                       continue;
-               }
-
-               if (test_bit(FF_CONSTANT, features))
-                       _D("'%s' type: constant", ev_path);
-               if (test_bit(FF_PERIODIC, features))
-                       _D("'%s' type: periodic", ev_path);
-               if (test_bit(FF_SPRING, features))
-                       _D("'%s' type: spring", ev_path);
-               if (test_bit(FF_FRICTION, features))
-                       _D("'%s' type: friction", ev_path);
-               if (test_bit(FF_RUMBLE, features))
-                       _D("'%s' type: rumble", ev_path);
-
-               if (test_bit(FF_RUMBLE, features)) {
-                       memcpy(ff_path, ev_path, strlen(ev_path)+1);
-                       close(fd);
-                       closedir(dir);
-                       return 0;
-               }
-
-               close(fd);
-       }
-
-       closedir(dir);
-       return -1;
-}
-
-static int ff_init_effect(struct ff_effect *effect)
-{
-       if (!effect)
-               return -EINVAL;
-
-       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 duration, int level, int intensity, int frequency, int overdrive)
-{
-       if (!effect) {
-               _E("There is no valid effect.");
-               return -EINVAL;
-       }
-
-       /*
-               __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);
-
-       effect->u.rumble.weak_magnitude = frequency;
-       SET_LEVEL_BIT(effect->u.rumble.weak_magnitude, level);
-
-       /* set member variables in effect struct */
-       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;
-}
-
-static int ff_play(int fd, struct ff_effect *effect)
-{
-       struct input_event play;
-       int ret;
-
-       if (fd < 0 || !effect) {
-               _E("Fd(%d) or effect(%s) is invalid", fd, effect ? "not null" : "null");
-               return -EINVAL;
-       }
-
-       /* upload an effect */
-       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;
-       play.code = effect->id;
-       play.value = 1; /* 1 : PLAY, 0 : STOP */
-
-       ret = write(fd, (const void *)&play, sizeof(play));
-       if (ret == -1) {
-               _E("Failed to write");
-               return -errno;
-       }
-
-       return 0;
-}
-
-static int ff_stop(int fd, struct ff_effect *effect)
-{
-       struct input_event stop;
-       int ret;
-
-       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;
-       stop.value = 0; /* 1 : PLAY, 0 : STOP */
-       ret = write(fd, (const void *)&stop, sizeof(stop));
-       if (ret == -1)
-               return -errno;
-
-       /* removing an effect from the device */
-       if (ioctl(fd, EVIOCRMFF, effect->id) == -1)
-               return -errno;
-
-       /* reset effect id */
-       effect->id = -1;
-       current_effect_id = -1;
-
-       return 0;
-}
-
-/* START: Haptic Module APIs */
-static int get_device_count(int *count)
-{
-       /* suppose there is just one haptic device */
-       if (count)
-               *count = 1;
-
-       return 0;
-}
-
-static int open_device(int device_index, int *device_handle)
-{
-       struct ff_info *info;
-       int n;
-       bool found = false;
-       GList *elem;
-
-       if (!device_handle)
-               return -EINVAL;
-
-       /* if it is the first element */
-       n = SYS_G_LIST_LENGTH(ff_list);
-       if (n == 0 && !ff_fd) {
-               _I("First element: open ff driver");
-               /* open ff driver */
-               ff_fd = open(ff_path, O_RDWR);
-               if (ff_fd < 0) {
-                       _E("Failed to open %s : %d", ff_path, errno);
-                       return -errno;
-               }
-       }
-
-       /* allocate memory */
-       info = calloc(sizeof(struct ff_info), 1);
-       if (!info) {
-               _E("Failed to allocate memory : %d", errno);
-               return -errno;
-       }
-
-       /* initialize ff_effect structure */
-       ff_init_effect(&info->effect);
-
-       if (unique_number == INT_MAX)
-               unique_number = 0;
-
-       while (found != true) {
-               ++unique_number;
-               elem = SYS_G_LIST_FIND(handle_list, (gpointer)(long)unique_number);
-               if (!elem)
-                       found = true;
-       }
-
-       info->handle = unique_number;
-
-       /* add info to local list */
-       SYS_G_LIST_APPEND(ff_list, info);
-       SYS_G_LIST_APPEND(handle_list, (gpointer)(long)info->handle);
-
-       *device_handle = info->handle;
-       return 0;
-}
-
-static int close_device(int device_handle)
-{
-       struct ff_info *info;
-       int n;
-
-       info = read_from_list(device_handle);
-       if (!info) {
-               _E("Handle %d failed to check info", device_handle);
-               return -ENOENT; /* 2 */
-       }
-
-       if (!check_valid_handle(info)) {
-               _E("Handle %d failed to check valid handle", device_handle);
-               return -EINVAL; /* 22 */
-       }
-
-       if (!check_fd(&ff_fd)) {
-               _E("Handle %d failed to check fd", device_handle);
-               return -ENODEV; /* 19 */
-       }
-
-       /* stop vibration */
-       stop_device(device_handle);
-
-       SYS_G_LIST_REMOVE(handle_list, (gpointer)(long)info->handle);
-
-       safe_free(info->ffinfobuffer);
-       /* remove info from local list */
-       SYS_G_LIST_REMOVE(ff_list, info);
-       safe_free(info);
-
-       /* if it is the last element */
-       n = SYS_G_LIST_LENGTH(ff_list);
-       if (n == 0 && ff_fd) {
-               _I("Last element: close ff driver");
-               /* close ff driver */
-               close(ff_fd);
-               ff_fd = 0;
-       }
-
-       return 0;
-}
-
-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);
-               return -EINVAL;
-       }
-
-       if (!check_valid_handle(info)) {
-               _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);
-               g_source_remove(info->timer);
-               info->timer = 0;
-       }
-
-       /* set effect as per arguments */
-       ff_init_effect(&info->effect);
-       ret = ff_set_effect(&info->effect, duration, level, intensity, frequency, overdrive);
-       if (ret < 0) {
-               _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;
-       }
-
-       /* play effect as per arguments */
-       ret = ff_play(ff_fd, &info->effect);
-       if (ret < 0) {
-               _E("Handle %d fail to play haptic effect(fd:%d id:%d) : %d",
-                               device_handle, ff_fd, info->effect.id, ret);
-               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);
-               if (!info->timer)
-                       _E("Handle %d failed to add timer callback", device_handle);
-       }
-
-       return 0;
-}
-
-static int stop_device(int device_handle)
-{
-       struct ff_info *info;
-       int r;
-
-       info = read_from_list(device_handle);
-       if (!info) {
-               _E("Handle %d fail to check info", device_handle);
-               return -ENOENT; /* 2 */
-       }
-
-       if (!check_fd(&ff_fd)) {
-               _E("Handle %d fail to check fd", device_handle);
-               return -ENODEV; /* 19 */
-       }
-
-       /* stop effect */
-       r = ff_stop(ff_fd, &info->effect);
-       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.id);
-
-       /* unregister existing timer */
-       if (r >= 0 && info->timer) {
-               g_source_remove(info->timer);
-               info->timer = 0;
-       }
-
-       return 0;
-}
-/* END: Haptic Module APIs */
-
-static const struct haptic_plugin_ops default_plugin = {
-       .get_device_count    = get_device_count,
-       .open_device         = open_device,
-       .close_device        = close_device,
-       .vibrate_monotone    = vibrate_monotone,
-       .stop_device         = stop_device,
-};
-
-static bool is_valid(void)
-{
-       int ret;
-
-       ret = ff_find_device();
-       if (ret < 0) {
-               _E("Do not support standard haptic device");
-               return false;
-       }
-
-       _I("Support standard haptic device");
-       return true;
-}
-
-static const struct haptic_plugin_ops *load(void)
-{
-       return &default_plugin;
-}
-
-static const struct haptic_ops std_ops = {
-       .type     = HAPTIC_STANDARD,
-       .is_valid = is_valid,
-       .load     = load,
-};
-
-EXPORT_GET_VAR_HAPTIC_OPS(&std_ops)