SET(SRCS
src/devices.c
src/sound.c
- src/feedback.c
- src/feedback-internal.c
- src/xmlparser.c)
+ src/vibrator.c
+ src/xmlparser.c
+ src/feedback.c)
SET(HEADERS
SLP_FEEDBACK_PG.h
+++ /dev/null
-/*
- * libfeedback
- * Copyright (c) 2012 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 __FEEDBACK_FILE_H__
-#define __FEEDBACK_FILE_H__
-
-#include "feedback-internal.h"
-
-#define FEEDBACK_HAPTIC_DIR FEEDBACK_DATA_DIR"/haptic"
-#define FEEDBACK_HAPTIC_TOUCH_DIR FEEDBACK_HAPTIC_DIR"/touch"
-#define FEEDBACK_HAPTIC_OPER_DIR FEEDBACK_HAPTIC_DIR"/operation"
-#define FEEDBACK_HAPTIC_NOTI_DIR FEEDBACK_HAPTIC_DIR"/notification"
-#define FEEDBACK_HAPTIC_DEFAULT_DIR FEEDBACK_HAPTIC_DIR"/default"
-
-const char* haptic_file[] = {
- /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : GENERAL */
- NULL,
- /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : TEXT_NUMERIC_INPUT */
- NULL,
- NULL,
- NULL,
- /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : DAILER */
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- /* TOUCH : H/W OR SOFT TOUCH : HOLD(TAP & HOLD) */
- FEEDBACK_HAPTIC_TOUCH_DIR"/touch.tht",
- /* TOUCH : H/W OR SOFT TOUCH : MULTI TAP */
- FEEDBACK_HAPTIC_TOUCH_DIR"/touch.tht",
- /* TOUCH : H/W OR SOFT TOUCH : TAP */
- NULL,
- /* TOUCH : H/W OR SOFT TOUCH : TAP & HOLD */
- NULL,
-
- /* NOTIFICATION : INCOMING : MESSAGE */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* NOTIFICATION : INCOMING : MESSAGE ALERT ON CALL */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* NOTIFICATION : INCOMING : EMAIL */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* NOTIFICATION : INCOMING : EMAIL ALERT ON CALL */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* NOTIFICATION : ALARM : WAKEUP */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* NOTIFICATION : ALARM : WAKEUP ALERT ON CALL */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* NOTIFICATION : ALARM : SCHEDULE */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* NOTIFICATION : ALARM : SCHEDULE ALERT ON CALL */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* NOTIFICATION : ALARM : TIMER */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* NOTIFICATION : ALARM : TIMER ALERT ON CALL */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* NOTIFICATION : GENERAL(TICKER/IM/SMS ETC) */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* NOTIFICATION : GENERAL(TICKER/IM/SMS ETC) ALERT ON CALL */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
-
- /* OPERATION : POWER ON/OFF */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* OPERATION : CHARGECONN */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* OPERATION : CHARGECONN ALERT ON CALL */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* OPERATION : FULLCHAREGED */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* OPERATION : FULLCHAREGED ALERT ON CALL */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* OPERATION : LOW BATTERY */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* OPERATION : LOW BATTERY ALERT ON CALL */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* OPERATION : LOCK/UNLOCK */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* OPERATION : CALL CONNECT/ DISCONNECT */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* OPERATION : MINUTE MINDER */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* OPERATION : VIBRATION */
- FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
- /* OPERATION : CAMERA SHUTTER / SCREEN CAPTURE */
- NULL,
- /* OPERATION : LIST RE-ORDER */
- NULL,
- /* OPERATION : LIST SLIDER */
- NULL,
- /* OPERATION : VOLUME KEY */
- NULL,
-};
-
-#endif //__FEEDBACK_FILE_H__
*/
-#ifndef __FEEDBACK_LEGACY_H__
-#define __FEEDBACK_LEGACY_H__
+#ifndef __FEEDBACK_INTERNAL_H__
+#define __FEEDBACK_INTERNAL_H__
#include "feedback-ids.h"
#endif
/**
- * @file feedback-legacy.h
- * @brief This file contains the feedback legacy API
+ * @file feedback-internal.h
+ * @brief This file contains the common information
*/
#define FEEDBACK_DATA_DIR "/opt/usr/share/feedback"
#define FEEDBACK_ORIGIN_DATA_DIR "/usr/share/feedback"
#define FEEDBACK_RETRY_CNT 1
-#define MAX_FILE_PATH 512
-
-typedef void* feedback_h;
-
-int feedback_init(feedback_h *handle);
-int feedback_fini(feedback_h handle);
-int feedback_play_sound(feedback_h handle, feedback_pattern_e key);
-int feedback_play_vibration(feedback_h handle, feedback_pattern_e key);
-int feedback_set_path(feedback_type_e type, feedback_pattern_e key, char* path);
-int feedback_get_path(feedback_type_e type, feedback_pattern_e key, char* buf, unsigned int buflen);
extern int callstatus;
-feedback_pattern_e feedback_get_alert_on_call_key(feedback_pattern_e pattern);
-
#ifdef __cplusplus
}
#endif
-#endif //__SVI_H__
+#endif //__FEEDBACK_INTERNAL_H__
+++ /dev/null
-/*
- * libfeedback
- * Copyright (c) 2012 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 <unistd.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <vconf.h>
-#include <haptic.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "feedback.h"
-#include "feedback-internal.h"
-#include "feedback-file.h"
-#include "feedback-str.h"
-#include "feedback-log.h"
-#include "xmlparser.h"
-
-#define FEEDBACK_RETRY_CNT 1
-#define MAX_FILE_PATH 512
-
-#define DEFAULT_FEEDBACK_HANDLE 0x0F
-
-#define VIBRATION_XML "/usr/share/feedback/vibration.xml"
-
-typedef struct {
- haptic_device_h v_handle;
- xmlDocPtr v_doc;
-} FEEDBACK_HANDLE;
-
-static int vibstatus;
-static int vib_level;
-static int noti_level;
-int callstatus;
-
-static void feedback_vibstatus_cb(keynode_t *key, void* data)
-{
- vibstatus = vconf_keynode_get_bool(key);
-}
-
-static void feedback_vib_cb(keynode_t *key, void* data)
-{
- vib_level = vconf_keynode_get_int(key);
-}
-
-static void feedback_noti_cb(keynode_t *key, void* data)
-{
- noti_level = vconf_keynode_get_int(key);
-}
-
-static void feedback_callstatus_cb(keynode_t *key, void* data)
-{
- callstatus = vconf_keynode_get_int(key);
-}
-
-feedback_pattern_e feedback_get_alert_on_call_key(feedback_pattern_e pattern)
-{
- switch(pattern) {
- case FEEDBACK_PATTERN_MESSAGE:
- case FEEDBACK_PATTERN_EMAIL:
- case FEEDBACK_PATTERN_WAKEUP:
- case FEEDBACK_PATTERN_SCHEDULE:
- case FEEDBACK_PATTERN_TIMER:
- case FEEDBACK_PATTERN_GENERAL:
- case FEEDBACK_PATTERN_CHARGERCONN:
- case FEEDBACK_PATTERN_FULLCHARGED:
- case FEEDBACK_PATTERN_LOWBATT:
- return (feedback_pattern_e)(pattern+1);
- default:
- break;
- }
-
- return pattern;
-}
-
-static haptic_priority_e feedback_get_priority(feedback_pattern_e pattern)
-{
- if (pattern >= FEEDBACK_PATTERN_TAP && pattern <= FEEDBACK_PATTERN_HW_HOLD)
- return HAPTIC_PRIORITY_MIN;
-
- return HAPTIC_PRIORITY_MIDDLE;
-}
-
-static int feedback_get_haptic_level(feedback_pattern_e pattern)
-{
- int level = -1;
-
- if (pattern >= FEEDBACK_PATTERN_MESSAGE && pattern <= FEEDBACK_PATTERN_GENERAL_ON_CALL)
- level = noti_level;
- else
- level = vib_level;
-
- FEEDBACK_LOG("Call status : %d, pattern : %s, level : %d", callstatus, str_pattern[pattern], level);
- if (callstatus != VCONFKEY_CALL_OFF) {
- // if call status is ON, vibration magnitude is 20%
- level = (int)(level*0.2f);
- level = (level < 1) ? 1 : level;
- FEEDBACK_LOG("level changed : %d", level);
- }
-
- level = level * 20;
- return level;
-}
-
-static bool feedback_get_always_alert_case(feedback_pattern_e pattern)
-{
- switch(pattern) {
- case FEEDBACK_PATTERN_WAKEUP:
- case FEEDBACK_PATTERN_WAKEUP_ON_CALL:
- return true;
- default:
- break;
- }
- return false;
-}
-
-static int feedback_get_data(xmlDocPtr doc, feedback_pattern_e pattern, struct xmlData **data)
-{
- xmlNodePtr cur;
- struct xmlData *retData;
-
- cur = xml_find(doc, (const xmlChar*)str_pattern[pattern]);
- if (cur == NULL) {
- FEEDBACK_ERROR("xml_find fail");
- return -1;
- }
-
- retData = xml_parse(doc, cur);
- if (retData == NULL) {
- FEEDBACK_ERROR("xml_parse fail");
- return -1;
- }
-
- *data = retData;
- return 0;
-}
-
-static void feedback_release_data(struct xmlData *data)
-{
- if (data == NULL)
- return;
-
- xml_free(data);
-}
-
-static int feedback_change_symlink(const char *sym_path, const char *new_path)
-{
- struct stat buf;
-
- if (sym_path == NULL || strlen(sym_path) == 0) {
- FEEDBACK_ERROR("Invalid parameter : sym_path(NULL)");
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- if (new_path == NULL || strlen(new_path) == 0) {
- FEEDBACK_ERROR("Invalid paramter : new_path(NULL)");
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- // check symbolic link file existence
- if (stat(sym_path, &buf)) {
- FEEDBACK_ERROR("file(%s) is not presents", sym_path);
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- if (unlink(sym_path) < 0) {
- FEEDBACK_LOG("unlink(%s) : %s", sym_path, strerror(errno));
- }
-
- if (symlink(new_path, sym_path) < 0) {
- FEEDBACK_ERROR("symlink(%s) : %s", sym_path, strerror(errno));
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- return FEEDBACK_ERROR_NONE;
-}
-
-static int feedback_restore_default_file(feedback_type_e type, feedback_pattern_e pattern)
-{
- const char *cur_path = NULL;
- char default_path[MAX_FILE_PATH] = {0,};
- char *temp = NULL;
- int ret = -1;
-
- if (type <= FEEDBACK_TYPE_NONE || type >= FEEDBACK_TYPE_END) {
- FEEDBACK_ERROR("Invalid parameter : type(%s)", str_type[type]);
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- if (pattern <= FEEDBACK_PATTERN_NONE || pattern >= FEEDBACK_PATTERN_END) {
- FEEDBACK_ERROR("Invalid parameter : pattern(%s)", str_pattern[pattern]);
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- if (type == FEEDBACK_TYPE_VIBRATION) {
- cur_path = haptic_file[pattern];
- }
-
- // if there isn't cur_path, it already returns before calling this api
- if (cur_path == NULL || strlen(cur_path) == 0) {
- FEEDBACK_ERROR("Invalid parameter : cur_path(NULL)");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- temp = strcat(default_path, FEEDBACK_ORIGIN_DATA_DIR);
- strcat(temp, cur_path+strlen(FEEDBACK_DATA_DIR));
- FEEDBACK_LOG("default_path : %s", default_path);
-
- ret = feedback_change_symlink(cur_path, default_path);
- if (FEEDBACK_FAILED(ret)) {
- FEEDBACK_ERROR("change_symlink is failed");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- return FEEDBACK_ERROR_NONE;
-}
-
-int feedback_init(feedback_h *handle)
-{
- FEEDBACK_HANDLE *phandle;
- haptic_device_h v_handle;
- xmlDocPtr v_doc;
- int ret;
-
- /* check vibration status */
- if (vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibstatus) < 0) {
- FEEDBACK_ERROR("vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibstatus) ==> FAIL!!");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- /* check vib_level */
- if (vconf_get_int(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, &vib_level) < 0) {
- FEEDBACK_ERROR("vconf_get_int(VCONFKEY_FEEDBACK_VIBRATION_LEVEL_INT, &vib_level) ==> FAIL!!");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- /* check noti_level */
- if (vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, ¬i_level) < 0) {
- FEEDBACK_ERROR("vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, ¬i_level) ==> FAIL!!");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- /* check call status */
- if (vconf_get_int(VCONFKEY_CALL_STATE, &callstatus) < 0) {
- FEEDBACK_ERROR("vconf_get_int(VCONFKEY_CALL_STATE, &callstatus) ==> FAIL!!");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- /* xml Init */
- v_doc = xml_open(VIBRATION_XML);
- if (v_doc == NULL) {
- FEEDBACK_ERROR("xml_open(%s) fail", VIBRATION_XML);
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- /* Vibration Init */
- ret = haptic_open(HAPTIC_DEVICE_ALL, &v_handle);
- if (ret != HAPTIC_ERROR_NONE) {
- FEEDBACK_ERROR("haptic_open(HAPTIC_DEVICE_ALL, &v_handle) ==> FAIL!! : %d", ret);
- v_handle = (haptic_device_h)DEFAULT_FEEDBACK_HANDLE;
- }
-
- /* add watch for status value */
- vconf_notify_key_changed(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, feedback_vibstatus_cb, NULL);
- vconf_notify_key_changed(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, feedback_vib_cb, NULL);
- vconf_notify_key_changed(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, feedback_noti_cb, NULL);
- vconf_notify_key_changed(VCONFKEY_CALL_STATE, feedback_callstatus_cb, NULL);
-
- FEEDBACK_LOG("vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibstatus) ==> %d", vibstatus);
- FEEDBACK_LOG("vconf_get_int(VCONFKEY_FEEDBACK_VIBRATION_LEVEL_INT, &vib_level) ==> %d", vib_level);
- FEEDBACK_LOG("vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, ¬i_level) ==> %d", noti_level);
- FEEDBACK_LOG("vconf_get_int(VCONFKEY_CALL_STATUS, &callstatus) ==> %d", callstatus);
-
- phandle = (FEEDBACK_HANDLE *)malloc(sizeof(FEEDBACK_HANDLE));
- phandle->v_handle = v_handle;
- phandle->v_doc = v_doc;
- *handle = (feedback_h)phandle;
- FEEDBACK_LOG("handle value : %x", handle);
- return FEEDBACK_ERROR_NONE;
-}
-
-int feedback_fini(feedback_h handle)
-{
- FEEDBACK_HANDLE *phandle = (FEEDBACK_HANDLE *)handle;
- int ret = -1;
-
- if (!handle) {
- FEEDBACK_ERROR("Invalid parameter : handle(NULL)");
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- if (phandle->v_handle != DEFAULT_FEEDBACK_HANDLE) {
- ret = haptic_close(phandle->v_handle);
- if (ret != HAPTIC_ERROR_NONE) {
- FEEDBACK_ERROR("haptic_close is failed : %d", ret);
- }
- }
-
- if (phandle->v_doc) {
- xml_close(phandle->v_doc);
- }
-
- free(phandle);
-
- vconf_ignore_key_changed(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, feedback_vibstatus_cb);
- vconf_ignore_key_changed(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, feedback_vib_cb);
- vconf_ignore_key_changed(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, feedback_noti_cb);
- vconf_ignore_key_changed(VCONFKEY_CALL_STATE, feedback_callstatus_cb);
-
- return FEEDBACK_ERROR_NONE;
-}
-
-int feedback_play_vibration(feedback_h handle, feedback_pattern_e pattern)
-{
- FEEDBACK_HANDLE *phandle = (FEEDBACK_HANDLE *)handle;
- int ret;
- struct stat buf;
- struct xmlData *data;
-
- if (!handle) {
- FEEDBACK_ERROR("Invalid parameter : handle(NULL)");
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- if (handle == DEFAULT_FEEDBACK_HANDLE) {
- FEEDBACK_ERROR("haptic is not initialized");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- if (vibstatus == 0 && !feedback_get_always_alert_case(pattern)) {
- FEEDBACK_LOG("Vibration condition is OFF (vibstatus : %d)", vibstatus);
- return FEEDBACK_ERROR_NONE;
- }
-
- if (callstatus != VCONFKEY_CALL_OFF) {
- pattern = feedback_get_alert_on_call_key(pattern);
- FEEDBACK_LOG("Call status is connected or connecting. pattern changed : %s", str_pattern[pattern]);
- }
-
- ret = feedback_get_data(phandle->v_doc, pattern, &data);
- if (ret < 0) {
- FEEDBACK_ERROR("feedback_get_vibration_data fail");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- if (data->data == NULL) {
- FEEDBACK_LOG("This case(%s) does not play vibration", str_pattern[pattern]);
- feedback_release_data(data);
- return FEEDBACK_ERROR_NONE;
- }
-
- /* play haptic buffer */
- ret = haptic_vibrate_buffer_with_detail(phandle->v_handle, data->data, HAPTIC_ITERATION_ONCE,
- feedback_get_haptic_level(pattern), feedback_get_priority(pattern), NULL);
- if (ret != HAPTIC_ERROR_NONE) {
- FEEDBACK_ERROR("haptic_vibrate_buffer_with_detail is failed");
- feedback_release_data(data);
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- feedback_release_data(data);
- return FEEDBACK_ERROR_NONE;
-}
-
-int feedback_set_path(feedback_type_e type, feedback_pattern_e pattern, char* path)
-{
- const char* cur_path = NULL;
- int ret = -1;
-
- if (type <= FEEDBACK_TYPE_NONE || type >= FEEDBACK_TYPE_END) {
- FEEDBACK_ERROR("Invalid parameter : type(%s)", str_type[type]);
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- if (pattern <= FEEDBACK_PATTERN_NONE || pattern >= FEEDBACK_PATTERN_END) {
- FEEDBACK_ERROR("Invalid parameter : pattern(%s)", str_pattern[pattern]);
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- if (path == NULL) {
- FEEDBACK_ERROR("Invalid parameter : path(NULL)");
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- if (access(path, F_OK) != 0) {
- FEEDBACK_ERROR("Invalid parameter : path does not exist");
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- if (type == FEEDBACK_TYPE_VIBRATION) {
- cur_path = haptic_file[pattern];
- }
-
- if (cur_path == NULL) {
- FEEDBACK_ERROR("This pattern(%s) in this type(%s) is not supported to play", str_pattern[pattern], str_type[type]);
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- ret = feedback_change_symlink(cur_path, path);
- if (FEEDBACK_FAILED(ret)) {
- FEEDBACK_ERROR("change_symlink is failed");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- return FEEDBACK_ERROR_NONE;
-}
-
-int feedback_get_path(feedback_type_e type, feedback_pattern_e pattern, char* buf, unsigned int buflen)
-{
- const char* cur_path = NULL;
- int retry = FEEDBACK_RETRY_CNT;
-
- if (type <= FEEDBACK_TYPE_NONE || type >= FEEDBACK_TYPE_END) {
- FEEDBACK_ERROR("Invalid parameter : type(%s)", str_type[type]);
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- if (pattern <= FEEDBACK_PATTERN_NONE || pattern >= FEEDBACK_PATTERN_END) {
- FEEDBACK_ERROR("Invalid parameter : pattern(%s)", str_pattern[pattern]);
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- if (buf == NULL || buflen <= 0) {
- FEEDBACK_ERROR("Invalid parameter : buf(NULL) or bufLen(%d)", buflen);
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- if (type == FEEDBACK_TYPE_VIBRATION) {
- cur_path = haptic_file[pattern];
- }
-
- if (cur_path == NULL) {
- FEEDBACK_ERROR("This pattern(%s) in this type(%s) is not supported to play", str_pattern[pattern], str_type[type]);
- snprintf(buf, buflen, "NULL");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- do {
- if(readlink(cur_path, buf, buflen) < 0) {
- FEEDBACK_ERROR("readlink is failed : %s", strerror(errno));
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
- } while(retry--);
-
- return FEEDBACK_ERROR_NONE;
-}
#include <stdio.h>
+#include <stdbool.h>
#include <string.h>
+#include <limits.h>
+#include <vconf.h>
+
#include "feedback.h"
#include "feedback-internal.h"
+#include "feedback-str.h"
#include "feedback-log.h"
#include "devices.h"
-#define MAX_PATH_LENGTH 256
-#define NOT_ASSIGNED NULL
-
#ifndef API
#define API __attribute__ ((visibility("default")))
#endif
-static feedback_h feedback_handle = NOT_ASSIGNED;
+int callstatus;
+
+static bool binit;
+
+static void feedback_callstatus_cb(keynode_t *key, void* data)
+{
+ callstatus = vconf_keynode_get_int(key);
+}
+
+static feedback_pattern_e get_alert_on_call_key(feedback_pattern_e pattern)
+{
+ switch(pattern) {
+ case FEEDBACK_PATTERN_MESSAGE:
+ case FEEDBACK_PATTERN_EMAIL:
+ case FEEDBACK_PATTERN_WAKEUP:
+ case FEEDBACK_PATTERN_SCHEDULE:
+ case FEEDBACK_PATTERN_TIMER:
+ case FEEDBACK_PATTERN_GENERAL:
+ case FEEDBACK_PATTERN_CHARGERCONN:
+ case FEEDBACK_PATTERN_FULLCHARGED:
+ case FEEDBACK_PATTERN_LOWBATT:
+ return (feedback_pattern_e)(pattern+1);
+ default:
+ break;
+ }
+
+ return pattern;
+}
API int feedback_initialize()
{
int err = -1;
- if (feedback_handle != NOT_ASSIGNED) {
- FEEDBACK_LOG("Already initialized");
+ if (binit)
return FEEDBACK_ERROR_NONE;
- }
+
+ /* check call status */
+ if (vconf_get_int(VCONFKEY_CALL_STATE, &callstatus) < 0)
+ FEEDBACK_ERROR("vconf_get_int(VCONFKEY_CALL_STATE, &callstatus) ==> FAIL!!");
+
+ /* add watch for status value */
+ vconf_notify_key_changed(VCONFKEY_CALL_STATE, feedback_callstatus_cb, NULL);
/* initialize device */
devices_init();
- err = feedback_init(&feedback_handle);
- if (FEEDBACK_FAILED(err)) {
- FEEDBACK_ERROR("feedback_init is failed");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
+ binit = true;
return FEEDBACK_ERROR_NONE;
}
API int feedback_deinitialize()
{
- int err = -1;
-
- if (feedback_handle == NOT_ASSIGNED) {
- FEEDBACK_ERROR("Not initialized");
+ if (!binit)
return FEEDBACK_ERROR_NOT_INITIALIZED;
- }
+
+ vconf_ignore_key_changed(VCONFKEY_CALL_STATE, feedback_callstatus_cb);
/* deinitialize device */
devices_exit();
- err = feedback_fini(feedback_handle);
- if (FEEDBACK_FAILED(err)) {
- FEEDBACK_ERROR("feedback_fini is failed");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- feedback_handle = NOT_ASSIGNED;
+ binit = false;
return FEEDBACK_ERROR_NONE;
}
API int feedback_play(feedback_pattern_e pattern)
{
- int err = -1;
-
- if (feedback_handle == NOT_ASSIGNED) {
+ /* check initialize */
+ if (!binit) {
FEEDBACK_ERROR("Not initialized");
return FEEDBACK_ERROR_NOT_INITIALIZED;
}
return FEEDBACK_ERROR_NONE;
}
+ /* in case of call connected or connecting */
+ if (callstatus != VCONFKEY_CALL_OFF) {
+ pattern = get_alert_on_call_key(pattern);
+ FEEDBACK_LOG("Call status is connected or connecting. pattern changed : %s", str_pattern[pattern]);
+ }
+
/* play all device */
devices_play(pattern);
- err = feedback_play_vibration(feedback_handle, pattern);
- if (FEEDBACK_FAILED(err)) {
- FEEDBACK_ERROR("feedback_play_vibration is failed");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
return FEEDBACK_ERROR_NONE;
}
API int feedback_play_type(feedback_type_e type, feedback_pattern_e pattern)
{
const struct device_ops *dev;
- int err = -1;
+ int err;
- if (feedback_handle == NOT_ASSIGNED) {
+ /* check initialize */
+ if (!binit) {
FEEDBACK_ERROR("Not initialized");
return FEEDBACK_ERROR_NOT_INITIALIZED;
}
return FEEDBACK_ERROR_NONE;
}
- switch(type) {
- case FEEDBACK_TYPE_SOUND:
- dev = find_device(type);
- if (dev) {
- err = dev->play(pattern);
- if (err < 0)
- FEEDBACK_ERROR("feedback_play_sound is failed");
- }
- break;
- case FEEDBACK_TYPE_VIBRATION:
- err = feedback_play_vibration(feedback_handle, pattern);
- if (FEEDBACK_FAILED(err))
- FEEDBACK_ERROR("feedback_play(type:%d) is failed", type);
- break;
- default:
- FEEDBACK_ERROR("Invalid parameter : type(%d)", type);
- return FEEDBACK_ERROR_INVALID_PARAMETER;
+ /* in case of call connected or connecting */
+ if (callstatus != VCONFKEY_CALL_OFF) {
+ pattern = get_alert_on_call_key(pattern);
+ FEEDBACK_LOG("Call status is connected or connecting. pattern changed : %s", str_pattern[pattern]);
+ }
+
+ /* play proper device */
+ dev = find_device(type);
+ if (dev) {
+ err = dev->play(pattern);
+ if (err < 0)
+ FEEDBACK_ERROR("fail to play sound");
}
return FEEDBACK_ERROR_NONE;
API int feedback_get_resource_path(feedback_type_e type, feedback_pattern_e pattern, char** path)
{
const struct device_ops *dev;
- int err = -1;
- char buf[MAX_PATH_LENGTH] = {0,};
+ char buf[PATH_MAX] = {0,};
+ int err;
if (path == NULL) {
FEEDBACK_ERROR("Invalid parameter : path(NULL)");
return FEEDBACK_ERROR_INVALID_PARAMETER;
}
- if (type == FEEDBACK_TYPE_SOUND) {
- dev = find_device(type);
- if (dev)
- err = dev->get_path(pattern, buf, sizeof(buf));
- } else if (type == FEEDBACK_TYPE_VIBRATION)
- err = feedback_get_path(type, pattern, buf, MAX_PATH_LENGTH);
-
- if (FEEDBACK_FAILED(err)) {
- FEEDBACK_ERROR("feedback_get_path is failed");
- return FEEDBACK_ERROR_OPERATION_FAILED;
+ /* proper device get path */
+ dev = find_device(type);
+ if (dev) {
+ err = dev->get_path(pattern, buf, sizeof(buf));
+ if (err < 0)
+ return FEEDBACK_ERROR_OPERATION_FAILED;
}
*path = strdup(buf);
return FEEDBACK_ERROR_NONE;
}
-API int feedback_set_resource_path(feedback_type_e type, feedback_pattern_e pattern, char* path)
+API int feedback_set_resource_path(feedback_type_e type, feedback_pattern_e pattern, char *path)
{
const struct device_ops *dev;
- int err = -1;
+ int err;
if (path == NULL) {
FEEDBACK_ERROR("Invalid parameter : path(NULL)");
return FEEDBACK_ERROR_INVALID_PARAMETER;
}
- if (type == FEEDBACK_TYPE_SOUND) {
- dev = find_device(type);
- if (dev)
- err = dev->set_path(pattern, path);
- } else if (type == FEEDBACK_TYPE_VIBRATION)
- err = feedback_set_path(type, pattern, path);
-
- if (FEEDBACK_FAILED(err)) {
- FEEDBACK_ERROR("feedback_set_path is failed");
- return FEEDBACK_ERROR_OPERATION_FAILED;
+ /* proper device set path */
+ dev = find_device(type);
+ if (dev) {
+ err = dev->set_path(pattern, path);
+ if (err < 0)
+ return FEEDBACK_ERROR_OPERATION_FAILED;
}
return FEEDBACK_ERROR_NONE;
return 0;
}
- if (callstatus != VCONFKEY_CALL_OFF) {
- pattern = feedback_get_alert_on_call_key(pattern);
- FEEDBACK_LOG("Call status is connected or connecting. pattern changed : %s", str_pattern[pattern]);
- }
-
if (sound_file[pattern] == NULL) {
FEEDBACK_LOG("This case(%s) does not play sound", str_pattern[pattern]);
return 0;
--- /dev/null
+/*
+ * libfeedback
+ * Copyright (c) 2012 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 <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <assert.h>
+#include <limits.h>
+#include <vconf.h>
+#include <haptic.h>
+
+#include "feedback.h"
+#include "feedback-internal.h"
+#include "feedback-str.h"
+#include "feedback-log.h"
+#include "xmlparser.h"
+#include "devices.h"
+
+#define FEEDBACK_HAPTIC_DIR FEEDBACK_DATA_DIR"/haptic"
+#define FEEDBACK_HAPTIC_TOUCH_DIR FEEDBACK_HAPTIC_DIR"/touch"
+#define FEEDBACK_HAPTIC_OPER_DIR FEEDBACK_HAPTIC_DIR"/operation"
+#define FEEDBACK_HAPTIC_NOTI_DIR FEEDBACK_HAPTIC_DIR"/notification"
+#define FEEDBACK_HAPTIC_DEFAULT_DIR FEEDBACK_HAPTIC_DIR"/default"
+
+static const char* haptic_file[] = {
+ /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : GENERAL */
+ NULL,
+ /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : TEXT_NUMERIC_INPUT */
+ NULL,
+ NULL,
+ NULL,
+ /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : DAILER */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ /* TOUCH : H/W OR SOFT TOUCH : HOLD(TAP & HOLD) */
+ FEEDBACK_HAPTIC_TOUCH_DIR"/touch.tht",
+ /* TOUCH : H/W OR SOFT TOUCH : MULTI TAP */
+ FEEDBACK_HAPTIC_TOUCH_DIR"/touch.tht",
+ /* TOUCH : H/W OR SOFT TOUCH : TAP */
+ NULL,
+ /* TOUCH : H/W OR SOFT TOUCH : TAP & HOLD */
+ NULL,
+
+ /* NOTIFICATION : INCOMING : MESSAGE */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* NOTIFICATION : INCOMING : MESSAGE ALERT ON CALL */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* NOTIFICATION : INCOMING : EMAIL */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* NOTIFICATION : INCOMING : EMAIL ALERT ON CALL */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* NOTIFICATION : ALARM : WAKEUP */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* NOTIFICATION : ALARM : WAKEUP ALERT ON CALL */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* NOTIFICATION : ALARM : SCHEDULE */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* NOTIFICATION : ALARM : SCHEDULE ALERT ON CALL */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* NOTIFICATION : ALARM : TIMER */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* NOTIFICATION : ALARM : TIMER ALERT ON CALL */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* NOTIFICATION : GENERAL(TICKER/IM/SMS ETC) */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* NOTIFICATION : GENERAL(TICKER/IM/SMS ETC) ALERT ON CALL */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+
+ /* OPERATION : POWER ON/OFF */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* OPERATION : CHARGECONN */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* OPERATION : CHARGECONN ALERT ON CALL */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* OPERATION : FULLCHAREGED */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* OPERATION : FULLCHAREGED ALERT ON CALL */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* OPERATION : LOW BATTERY */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* OPERATION : LOW BATTERY ALERT ON CALL */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* OPERATION : LOCK/UNLOCK */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* OPERATION : CALL CONNECT/ DISCONNECT */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* OPERATION : MINUTE MINDER */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* OPERATION : VIBRATION */
+ FEEDBACK_HAPTIC_DEFAULT_DIR"/Basic_call.tht",
+ /* OPERATION : CAMERA SHUTTER / SCREEN CAPTURE */
+ NULL,
+ /* OPERATION : LIST RE-ORDER */
+ NULL,
+ /* OPERATION : LIST SLIDER */
+ NULL,
+ /* OPERATION : VOLUME KEY */
+ NULL,
+};
+
+#define VIBRATION_XML "/usr/share/feedback/vibration.xml"
+
+static int vibstatus;
+static int vib_level;
+static int noti_level;
+
+static haptic_device_h v_handle;
+static xmlDocPtr v_doc;
+
+static void feedback_vibstatus_cb(keynode_t *key, void* data)
+{
+ vibstatus = vconf_keynode_get_bool(key);
+}
+
+static void feedback_vib_cb(keynode_t *key, void* data)
+{
+ vib_level = vconf_keynode_get_int(key);
+}
+
+static void feedback_noti_cb(keynode_t *key, void* data)
+{
+ noti_level = vconf_keynode_get_int(key);
+}
+
+static haptic_priority_e get_priority(feedback_pattern_e pattern)
+{
+ if (pattern >= FEEDBACK_PATTERN_TAP && pattern <= FEEDBACK_PATTERN_HW_HOLD)
+ return HAPTIC_PRIORITY_MIN;
+
+ return HAPTIC_PRIORITY_MIDDLE;
+}
+
+static int get_haptic_level(feedback_pattern_e pattern)
+{
+ int level;
+
+ if (pattern >= FEEDBACK_PATTERN_MESSAGE && pattern <= FEEDBACK_PATTERN_GENERAL_ON_CALL)
+ level = noti_level;
+ else
+ level = vib_level;
+
+ FEEDBACK_LOG("Call status : %d, pattern : %s, level : %d", callstatus, str_pattern[pattern], level);
+ if (callstatus != VCONFKEY_CALL_OFF) {
+ // if call status is ON, vibration magnitude is 20%
+ level = (int)(level*0.2f);
+ level = (level < 1) ? 1 : level;
+ FEEDBACK_LOG("level changed : %d", level);
+ }
+
+ level = level * 20;
+ return level;
+}
+
+static bool get_always_alert_case(feedback_pattern_e pattern)
+{
+ switch(pattern) {
+ case FEEDBACK_PATTERN_WAKEUP:
+ case FEEDBACK_PATTERN_WAKEUP_ON_CALL:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+static int get_xml_data(xmlDocPtr doc, feedback_pattern_e pattern, struct xmlData **data)
+{
+ xmlNodePtr cur;
+ struct xmlData *retData;
+
+ cur = xml_find(doc, (const xmlChar*)str_pattern[pattern]);
+ if (cur == NULL) {
+ FEEDBACK_ERROR("xml_find fail");
+ return -1;
+ }
+
+ retData = xml_parse(doc, cur);
+ if (retData == NULL) {
+ FEEDBACK_ERROR("xml_parse fail");
+ return -1;
+ }
+
+ *data = retData;
+ return 0;
+}
+
+static void release_xml_data(struct xmlData *data)
+{
+ if (data == NULL)
+ return;
+
+ xml_free(data);
+}
+
+static int change_symlink(const char *sym_path, const char *new_path)
+{
+ struct stat buf;
+
+ assert(sym_path != NULL && strlen(sym_path));
+ assert(new_path != NULL && strlen(new_path));
+
+ /* check symbolic link file existence */
+ if (stat(sym_path, &buf)) {
+ FEEDBACK_ERROR("file(%s) is not presents", sym_path);
+ return -EPERM;
+ }
+
+ if (unlink(sym_path) < 0)
+ FEEDBACK_LOG("unlink(%s) : %s", sym_path, strerror(errno));
+
+ if (symlink(new_path, sym_path) < 0) {
+ FEEDBACK_ERROR("symlink(%s) : %s", sym_path, strerror(errno));
+ return -EPERM;
+ }
+
+ return 0;
+}
+
+static int restore_default_file(feedback_pattern_e pattern)
+{
+ char default_path[PATH_MAX] = {0,};
+ const char *cur_path;
+ char *temp;
+ int ret;
+
+ cur_path = haptic_file[pattern];
+ // if there isn't cur_path, it already returns before calling this api
+ if (cur_path == NULL || strlen(cur_path) == 0) {
+ FEEDBACK_ERROR("Invalid parameter : cur_path(NULL)");
+ return -EPERM;
+ }
+
+ temp = strcat(default_path, FEEDBACK_ORIGIN_DATA_DIR);
+ strcat(temp, cur_path+strlen(FEEDBACK_DATA_DIR));
+ FEEDBACK_LOG("default_path : %s", default_path);
+
+ ret = change_symlink(cur_path, default_path);
+ if (ret < 0) {
+ FEEDBACK_ERROR("change_symlink is failed");
+ return -EPERM;
+ }
+
+ return 0;
+}
+
+static void vibrator_init(void)
+{
+ int ret;
+
+ /* xml Init */
+ v_doc = xml_open(VIBRATION_XML);
+ if (v_doc == NULL) {
+ FEEDBACK_ERROR("xml_open(%s) fail", VIBRATION_XML);
+ return;
+ }
+
+ /* Vibration Init */
+ ret = haptic_open(HAPTIC_DEVICE_ALL, &v_handle);
+ if (ret != HAPTIC_ERROR_NONE) {
+ FEEDBACK_ERROR("haptic_open(HAPTIC_DEVICE_ALL, &v_handle) ==> FAIL!! : %d", ret);
+ xml_close(v_doc);
+ v_doc = NULL;
+ return;
+ }
+
+ /* check vibration status */
+ if (vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibstatus) < 0)
+ FEEDBACK_ERROR("vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibstatus) ==> FAIL!!");
+
+ /* check vib_level */
+ if (vconf_get_int(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, &vib_level) < 0)
+ FEEDBACK_ERROR("vconf_get_int(VCONFKEY_FEEDBACK_VIBRATION_LEVEL_INT, &vib_level) ==> FAIL!!");
+
+ /* check noti_level */
+ if (vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, ¬i_level) < 0)
+ FEEDBACK_ERROR("vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, ¬i_level) ==> FAIL!!");
+
+ /* add watch for status value */
+ vconf_notify_key_changed(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, feedback_vibstatus_cb, NULL);
+ vconf_notify_key_changed(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, feedback_vib_cb, NULL);
+ vconf_notify_key_changed(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, feedback_noti_cb, NULL);
+}
+
+static void vibrator_exit(void)
+{
+ int ret;
+
+ /* remove watch */
+ vconf_ignore_key_changed(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, feedback_vibstatus_cb);
+ vconf_ignore_key_changed(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, feedback_vib_cb);
+ vconf_ignore_key_changed(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, feedback_noti_cb);
+
+ if (v_handle) {
+ ret = haptic_close(v_handle);
+ if (ret != HAPTIC_ERROR_NONE)
+ FEEDBACK_ERROR("haptic_close is failed : %d", ret);
+ v_handle = NULL;
+ }
+
+ if (v_doc) {
+ xml_close(v_doc);
+ v_doc = NULL;
+ }
+}
+
+static int vibrator_play(feedback_pattern_e pattern)
+{
+ int ret;
+ struct xmlData *data;
+
+ if (!v_handle || !v_doc) {
+ FEEDBACK_ERROR("Not initialize");
+ return -EPERM;
+ }
+
+ if (vibstatus == 0 && !get_always_alert_case(pattern)) {
+ FEEDBACK_LOG("Vibration condition is OFF (vibstatus : %d)", vibstatus);
+ return 0;
+ }
+
+ ret = get_xml_data(v_doc, pattern, &data);
+ if (ret < 0) {
+ FEEDBACK_ERROR("feedback_get_vibration_data fail");
+ return -EPERM;
+ }
+
+ if (data->data == NULL) {
+ FEEDBACK_LOG("This case(%s) does not play vibration", str_pattern[pattern]);
+ release_xml_data(data);
+ return 0;
+ }
+
+ /* play haptic buffer */
+ ret = haptic_vibrate_buffer_with_detail(v_handle, data->data, HAPTIC_ITERATION_ONCE,
+ get_haptic_level(pattern), get_priority(pattern), NULL);
+ if (ret != HAPTIC_ERROR_NONE) {
+ FEEDBACK_ERROR("haptic_vibrate_buffer_with_detail is failed");
+ release_xml_data(data);
+ return -EPERM;
+ }
+
+ release_xml_data(data);
+ return 0;
+}
+
+static int vibrator_get_path(feedback_pattern_e pattern, char *buf, unsigned int buflen)
+{
+ const char *cur_path;
+ int retry = FEEDBACK_RETRY_CNT;
+
+ assert(buf != NULL && buflen > 0);
+
+ cur_path = haptic_file[pattern];
+ if (cur_path == NULL) {
+ FEEDBACK_ERROR("This pattern(%s) in vibrator type is not supported to play", str_pattern[pattern]);
+ snprintf(buf, buflen, "NULL");
+ return -ENOENT;
+ }
+
+ do {
+ if(readlink(cur_path, buf, buflen) < 0) {
+ FEEDBACK_ERROR("readlink is failed : %s", strerror(errno));
+ return -EPERM;
+ }
+ } while(retry--);
+
+ return 0;
+}
+
+static int vibrator_set_path(feedback_pattern_e pattern, char *path)
+{
+ const char *cur_path;
+ int ret;
+
+ assert(path != NULL);
+
+ if (access(path, F_OK) != 0) {
+ FEEDBACK_ERROR("Invalid parameter : path does not exist");
+ return -ENOENT;
+ }
+
+ cur_path = haptic_file[pattern];
+ if (cur_path == NULL) {
+ FEEDBACK_ERROR("This pattern(%s) in vibrator type is not supported to play", str_pattern[pattern]);
+ return -ENOENT;
+ }
+
+ ret = change_symlink(cur_path, path);
+ if (ret < 0) {
+ FEEDBACK_ERROR("change_symlink is failed");
+ return -EPERM;
+ }
+
+ return 0;
+}
+
+static const struct device_ops vibrator_device_ops = {
+ .type = FEEDBACK_TYPE_VIBRATION,
+ .init = vibrator_init,
+ .exit = vibrator_exit,
+ .play = vibrator_play,
+ .get_path = vibrator_get_path,
+ .set_path = vibrator_set_path,
+};
+
+DEVICE_OPS_REGISTER(&vibrator_device_ops);