SET(SRCS
src/devices.c
+ src/sound.c
src/feedback.c
src/feedback-internal.c
src/xmlparser.c)
void devices_init(void);
void devices_exit(void);
+void devices_play(int pattern);
+
+#ifndef __CONSTRUCTOR__
+#define __CONSTRUCTOR__ __attribute__ ((constructor))
+#endif
+
+#ifndef __DESTRUCTOR__
+#define __DESTRUCTOR__ __attribute__ ((destructor))
+#endif
#define DEVICE_OPS_REGISTER(dev) \
static void __CONSTRUCTOR__ module_init(void) \
#ifndef __FEEDBACK_FILE_H__
#define __FEEDBACK_FILE_H__
-#define FEEDBACK_DATA_DIR "/opt/usr/share/feedback"
-#define FEEDBACK_ORIGIN_DATA_DIR "/usr/share/feedback"
-
-#define FEEDBACK_SOUND_DIR FEEDBACK_DATA_DIR"/sound"
-#define FEEDBACK_SOUND_TOUCH_DIR FEEDBACK_SOUND_DIR"/touch"
-#define FEEDBACK_SOUND_OPER_DIR FEEDBACK_SOUND_DIR"/operation"
+#include "feedback-internal.h"
#define FEEDBACK_HAPTIC_DIR FEEDBACK_DATA_DIR"/haptic"
#define FEEDBACK_HAPTIC_TOUCH_DIR FEEDBACK_HAPTIC_DIR"/touch"
#define FEEDBACK_HAPTIC_NOTI_DIR FEEDBACK_HAPTIC_DIR"/notification"
#define FEEDBACK_HAPTIC_DEFAULT_DIR FEEDBACK_HAPTIC_DIR"/default"
-const char* snd_file[] = {
- /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : GENERAL */
- FEEDBACK_SOUND_TOUCH_DIR"/touch.wav",
- /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : TEXT_NUMERIC_INPUT */
- FEEDBACK_SOUND_TOUCH_DIR"/sip.wav",
- FEEDBACK_SOUND_TOUCH_DIR"/sip_backspace.wav",
- FEEDBACK_SOUND_TOUCH_DIR"/sip.wav",
- /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : DAILER */
- FEEDBACK_SOUND_TOUCH_DIR"/key0.wav",
- FEEDBACK_SOUND_TOUCH_DIR"/key1.wav",
- FEEDBACK_SOUND_TOUCH_DIR"/key2.wav",
- FEEDBACK_SOUND_TOUCH_DIR"/key3.wav",
- FEEDBACK_SOUND_TOUCH_DIR"/key4.wav",
- FEEDBACK_SOUND_TOUCH_DIR"/key5.wav",
- FEEDBACK_SOUND_TOUCH_DIR"/key6.wav",
- FEEDBACK_SOUND_TOUCH_DIR"/key7.wav",
- FEEDBACK_SOUND_TOUCH_DIR"/key8.wav",
- FEEDBACK_SOUND_TOUCH_DIR"/key9.wav",
- FEEDBACK_SOUND_TOUCH_DIR"/keyasterisk.wav",
- FEEDBACK_SOUND_TOUCH_DIR"/keysharp.wav",
- /* TOUCH : H/W OR SOFT TOUCH : HOLD(TAP & HOLD) */
- NULL,
- /* TOUCH : H/W OR SOFT TOUCH : MULTI TAP */
- NULL,
- /* TOUCH : H/W OR SOFT TOUCH : TAP */
- NULL,
- /* TOUCH : H/W OR SOFT TOUCH : TAP & HOLD */
- NULL,
-
- /* NOTIFICATION : INCOMING : MESSAGE */
- NULL,
- /* NOTIFICATION : INCOMING : MESSAGE ALERT ON CALL */
- NULL,
- /* NOTIFICATION : INCOMING : EMAIL */
- NULL,
- /* NOTIFICATION : INCOMING : EMAIL ALERT ON CALL */
- NULL,
- /* NOTIFICATION : ALARM : WAKEUP */
- NULL,
- /* NOTIFICATION : ALARM : WAKEUP ALERT ON CALL */
- NULL,
- /* NOTIFICATION : ALARM : SCHEDULE */
- NULL,
- /* NOTIFICATION : ALARM : SCHEDULE ALERT ON CALL */
- NULL,
- /* NOTIFICATION : ALARM : TIMER */
- NULL,
- /* NOTIFICATION : ALARM : TIMER ALERT ON CALL */
- NULL,
- /* NOTIFICATION : GENERAL(TICKER/IM/SMS ETC) */
- FEEDBACK_SOUND_OPER_DIR"/call_connect.wav",
- /* NOTIFICATION : GENERAL(TICKER/IM/SMS ETC) ALERT ON CALL */
- FEEDBACK_SOUND_OPER_DIR"/call_connect.wav",
-
- /* OPERATION : POWER ON/OFF */
- FEEDBACK_SOUND_OPER_DIR"/power_on.wav",
- NULL,
- /* OPERATION : CHARGECONN */
- FEEDBACK_SOUND_OPER_DIR"/charger_connection.wav",
- /* OPERATION : CHARGECONN ALERT ON CALL */
- FEEDBACK_SOUND_OPER_DIR"/charger_connection.wav",
- /* OPERATION : FULLCHAREGED */
- FEEDBACK_SOUND_OPER_DIR"/fully_charged.wav",
- /* OPERATION : FULLCHAREGED ALERT ON CALL */
- FEEDBACK_SOUND_OPER_DIR"/fully_charged.wav",
- /* OPERATION : LOW BATTERY */
- FEEDBACK_SOUND_OPER_DIR"/low_battery.wav",
- /* OPERATION : LOW BATTERY ALERT ON CALL */
- FEEDBACK_SOUND_OPER_DIR"/low_battery.wav",
- /* OPERATION : LOCK/UNLOCK */
- FEEDBACK_SOUND_OPER_DIR"/lock.wav",
- FEEDBACK_SOUND_OPER_DIR"/unlock.wav",
- /* OPERATION : CALL CONNECT/ DISCONNECT */
- FEEDBACK_SOUND_OPER_DIR"/call_connect.wav",
- FEEDBACK_SOUND_OPER_DIR"/call_disconnect.wav",
- /* OPERATION : MINUTE MINDER */
- FEEDBACK_SOUND_OPER_DIR"/minute_minder.wav",
- /* OPERATION : VIBRATION */
- NULL,
- /* OPERATION : CAMERA SHUTTER / SCREEN CAPTURE */
- FEEDBACK_SOUND_OPER_DIR"/shutter.wav",
- /* OPERATION : LIST RE-ORDER */
- FEEDBACK_SOUND_OPER_DIR"/list_reorder.wav",
- /* OPERATION : LIST SLIDER */
- FEEDBACK_SOUND_OPER_DIR"/slider_sweep.wav",
- /* OPERATION : VOLUME KEY */
- FEEDBACK_SOUND_OPER_DIR"/volume_control.wav",
-};
-
const char* haptic_file[] = {
/* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : GENERAL */
NULL,
* @brief This file contains the feedback legacy API
*/
+#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_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
dev->exit();
}
}
+
+void devices_play(int pattern)
+{
+ dd_list *elem;
+ const struct device_ops *dev;
+
+ DD_LIST_FOREACH(dev_head, elem, dev) {
+ if (dev->play)
+ dev->play(pattern);
+ }
+}
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <mm_sound_private.h>
#include <vconf.h>
#include <haptic.h>
#include <fcntl.h>
xmlDocPtr v_doc;
} FEEDBACK_HANDLE;
-static int sndstatus;
-static int touch_sndstatus;
-static int soundon;
static int vibstatus;
static int vib_level;
static int noti_level;
-static int callstatus;
-
-static void feedback_sndstatus_cb(keynode_t *key, void* data)
-{
- sndstatus = vconf_keynode_get_bool(key);
-}
-
-static void feedback_touch_sndstatus_cb(keynode_t *key, void* data)
-{
- touch_sndstatus = vconf_keynode_get_bool(key);
-}
-
-static void feedback_soundon_cb(keynode_t *key, void* data)
-{
- soundon = vconf_keynode_get_int(key);
-}
+int callstatus;
static void feedback_vibstatus_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);
}
-static feedback_pattern_e feedback_get_alert_on_call_key(feedback_pattern_e pattern)
+feedback_pattern_e feedback_get_alert_on_call_key(feedback_pattern_e pattern)
{
switch(pattern) {
case FEEDBACK_PATTERN_MESSAGE:
return HAPTIC_PRIORITY_MIDDLE;
}
-static volume_type_t feedback_get_volume_type(feedback_pattern_e pattern)
-{
- if (pattern == FEEDBACK_PATTERN_TAP)
- return VOLUME_TYPE_SYSTEM|VOLUME_GAIN_TOUCH;
- else if (pattern >= FEEDBACK_PATTERN_KEY0 && pattern <= FEEDBACK_PATTERN_KEY_SHARP)
- return VOLUME_TYPE_SYSTEM|VOLUME_GAIN_DIALER;
- else if (pattern == FEEDBACK_PATTERN_VOLUME_KEY)
- return VOLUME_TYPE_RINGTONE;
-
- return VOLUME_TYPE_SYSTEM;
-}
-
static int feedback_get_haptic_level(feedback_pattern_e pattern)
{
int level = -1;
return FEEDBACK_ERROR_INVALID_PARAMETER;
}
- if (type == FEEDBACK_TYPE_SOUND) {
- cur_path = snd_file[pattern];
- } else {
+ if (type == FEEDBACK_TYPE_VIBRATION) {
cur_path = haptic_file[pattern];
}
xmlDocPtr v_doc;
int ret;
- /* Sound Init */
- if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sndstatus) < 0) {
- FEEDBACK_ERROR("vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sndstatus) ==> FAIL!!");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- if (vconf_get_bool(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, &touch_sndstatus) < 0) {
- FEEDBACK_ERROR("vconf_get_bool(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, &touch_sndstatus) ==> FAIL!!");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
- if (vconf_get_int(VCONFKEY_SOUND_STATUS, &soundon) < 0) {
- FEEDBACK_ERROR("vconf_get_int(VCONFKEY_SOUND_STATUS, &soundon) ==> FAIL!!");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
/* 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!!");
}
/* add watch for status value */
- vconf_notify_key_changed(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, feedback_sndstatus_cb, NULL);
- vconf_notify_key_changed(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, feedback_touch_sndstatus_cb, NULL);
- vconf_notify_key_changed(VCONFKEY_SOUND_STATUS, feedback_soundon_cb, NULL);
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_SOUND_STATUS_BOOL, &sndstatus) ==> %d", sndstatus);
- FEEDBACK_LOG("vconf_get_bool(VCONFKEY_SETAPPL_....UNDS_BOOL, &touch_sndstatus) ==> %d", touch_sndstatus);
- FEEDBACK_LOG("vconf_get_int(VCONFKEY_SOUND_STATUS, &soundon) ==> %d", soundon);
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);
free(phandle);
- vconf_ignore_key_changed(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, feedback_sndstatus_cb);
- vconf_ignore_key_changed(VCONFKEY_SOUND_STATUS, feedback_soundon_cb);
- vconf_ignore_key_changed(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, feedback_touch_sndstatus_cb);
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);
return FEEDBACK_ERROR_NONE;
}
-int feedback_play_sound(feedback_h handle, feedback_pattern_e pattern)
-{
- int ret = -1;
- int retry = FEEDBACK_RETRY_CNT;
- struct stat buf;
-
- if (!handle) {
- FEEDBACK_ERROR("Invalid parameter : handle(NULL)");
- return FEEDBACK_ERROR_INVALID_PARAMETER;
- }
-
- if (sndstatus == 0 && !feedback_get_always_alert_case(pattern)) {
- FEEDBACK_LOG("Sound condition is OFF (sndstatus : %d)", sndstatus);
- return FEEDBACK_ERROR_NONE;
- }
-
- if (soundon == 1 && pattern >= FEEDBACK_PATTERN_TAP && pattern <= FEEDBACK_PATTERN_HW_HOLD) {
- FEEDBACK_LOG("Touch feedback sound doesn't work during playing sound");
- return FEEDBACK_ERROR_NONE;
- }
-
- if (touch_sndstatus == 0 && pattern >= FEEDBACK_PATTERN_TAP && pattern <= FEEDBACK_PATTERN_HW_HOLD) {
- FEEDBACK_LOG("Touch Sound condition is OFF and pattern is touch type (touch_sndstatus : %d, pattern : %s)", touch_sndstatus, str_pattern[pattern]);
- 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]);
- }
-
- if (snd_file[pattern] == NULL) {
- FEEDBACK_LOG("This case(%s) does not play sound", str_pattern[pattern]);
- return FEEDBACK_ERROR_NONE;
- }
-
- if (stat(snd_file[pattern], &buf)) {
- FEEDBACK_ERROR("%s is not presents", snd_file[pattern]);
- ret = feedback_restore_default_file(FEEDBACK_TYPE_SOUND, pattern);
- if (FEEDBACK_FAILED(ret)) {
- FEEDBACK_ERROR("feedback_restore_default_file(%s) error", str_pattern[pattern]);
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
- FEEDBACK_LOG("%s is restored", snd_file[pattern]);
- }
-
- do {
- ret = mm_sound_play_keysound(snd_file[pattern], feedback_get_volume_type(pattern));
- if (ret == MM_ERROR_NONE) {
- FEEDBACK_LOG("Play success! SND filename is %s", snd_file[pattern]);
- return FEEDBACK_ERROR_NONE;
- }
- FEEDBACK_ERROR("mm_sound_play_keysound() returned error(%d)", ret);
- } while(retry--);
-
- return FEEDBACK_ERROR_OPERATION_FAILED;
-}
-
int feedback_play_vibration(feedback_h handle, feedback_pattern_e pattern)
{
FEEDBACK_HANDLE *phandle = (FEEDBACK_HANDLE *)handle;
return FEEDBACK_ERROR_INVALID_PARAMETER;
}
- if (type == FEEDBACK_TYPE_SOUND) {
- cur_path = snd_file[pattern];
- } else {
+ if (type == FEEDBACK_TYPE_VIBRATION) {
cur_path = haptic_file[pattern];
}
return FEEDBACK_ERROR_INVALID_PARAMETER;
}
- if (type == FEEDBACK_TYPE_SOUND) {
- cur_path = snd_file[pattern];
- } else {
+ if (type == FEEDBACK_TYPE_VIBRATION) {
cur_path = haptic_file[pattern];
}
#include "feedback.h"
#include "feedback-internal.h"
#include "feedback-log.h"
+#include "devices.h"
#define MAX_PATH_LENGTH 256
#define NOT_ASSIGNED NULL
return FEEDBACK_ERROR_NONE;
}
+ /* initialize device */
+ devices_init();
+
err = feedback_init(&feedback_handle);
if (FEEDBACK_FAILED(err)) {
FEEDBACK_ERROR("feedback_init is failed");
return FEEDBACK_ERROR_NOT_INITIALIZED;
}
+ /* deinitialize device */
+ devices_exit();
+
err = feedback_fini(feedback_handle);
if (FEEDBACK_FAILED(err)) {
FEEDBACK_ERROR("feedback_fini is failed");
return FEEDBACK_ERROR_NONE;
}
- err = feedback_play_sound(feedback_handle, pattern);
- if (FEEDBACK_FAILED(err)) {
- FEEDBACK_ERROR("feedback_play_sound is failed");
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
+ /* play all device */
+ devices_play(pattern);
err = feedback_play_vibration(feedback_handle, pattern);
if (FEEDBACK_FAILED(err)) {
API int feedback_play_type(feedback_type_e type, feedback_pattern_e pattern)
{
+ const struct device_ops *dev;
int err = -1;
if (feedback_handle == NOT_ASSIGNED) {
switch(type) {
case FEEDBACK_TYPE_SOUND:
- err = feedback_play_sound(feedback_handle, pattern);
+ 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;
}
- if (FEEDBACK_FAILED(err)) {
- FEEDBACK_ERROR("feedback_play(type:%d) is failed", type);
- return FEEDBACK_ERROR_OPERATION_FAILED;
- }
-
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,};
return FEEDBACK_ERROR_INVALID_PARAMETER;
}
- err = feedback_get_path(type, pattern, buf, MAX_PATH_LENGTH);
+ 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;
}
*path = strdup(buf);
-
return FEEDBACK_ERROR_NONE;
}
API int feedback_set_resource_path(feedback_type_e type, feedback_pattern_e pattern, char* path)
{
+ const struct device_ops *dev;
int err = -1;
if (path == NULL) {
return FEEDBACK_ERROR_INVALID_PARAMETER;
}
- err = feedback_set_path(type, pattern, path);
+ 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;
--- /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 <mm_sound_private.h>
+
+#include "feedback.h"
+#include "feedback-internal.h"
+#include "feedback-str.h"
+#include "feedback-log.h"
+#include "devices.h"
+
+#define FEEDBACK_SOUND_DIR FEEDBACK_DATA_DIR"/sound"
+#define FEEDBACK_SOUND_TOUCH_DIR FEEDBACK_SOUND_DIR"/touch"
+#define FEEDBACK_SOUND_OPER_DIR FEEDBACK_SOUND_DIR"/operation"
+
+static const char* sound_file[] = {
+ /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : GENERAL */
+ FEEDBACK_SOUND_TOUCH_DIR"/touch.wav",
+ /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : TEXT_NUMERIC_INPUT */
+ FEEDBACK_SOUND_TOUCH_DIR"/sip.wav",
+ FEEDBACK_SOUND_TOUCH_DIR"/sip_backspace.wav",
+ FEEDBACK_SOUND_TOUCH_DIR"/sip.wav",
+ /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : DAILER */
+ FEEDBACK_SOUND_TOUCH_DIR"/key0.wav",
+ FEEDBACK_SOUND_TOUCH_DIR"/key1.wav",
+ FEEDBACK_SOUND_TOUCH_DIR"/key2.wav",
+ FEEDBACK_SOUND_TOUCH_DIR"/key3.wav",
+ FEEDBACK_SOUND_TOUCH_DIR"/key4.wav",
+ FEEDBACK_SOUND_TOUCH_DIR"/key5.wav",
+ FEEDBACK_SOUND_TOUCH_DIR"/key6.wav",
+ FEEDBACK_SOUND_TOUCH_DIR"/key7.wav",
+ FEEDBACK_SOUND_TOUCH_DIR"/key8.wav",
+ FEEDBACK_SOUND_TOUCH_DIR"/key9.wav",
+ FEEDBACK_SOUND_TOUCH_DIR"/keyasterisk.wav",
+ FEEDBACK_SOUND_TOUCH_DIR"/keysharp.wav",
+ /* TOUCH : H/W OR SOFT TOUCH : HOLD(TAP & HOLD) */
+ NULL,
+ /* TOUCH : H/W OR SOFT TOUCH : MULTI TAP */
+ NULL,
+ /* TOUCH : H/W OR SOFT TOUCH : TAP */
+ NULL,
+ /* TOUCH : H/W OR SOFT TOUCH : TAP & HOLD */
+ NULL,
+
+ /* NOTIFICATION : INCOMING : MESSAGE */
+ NULL,
+ /* NOTIFICATION : INCOMING : MESSAGE ALERT ON CALL */
+ NULL,
+ /* NOTIFICATION : INCOMING : EMAIL */
+ NULL,
+ /* NOTIFICATION : INCOMING : EMAIL ALERT ON CALL */
+ NULL,
+ /* NOTIFICATION : ALARM : WAKEUP */
+ NULL,
+ /* NOTIFICATION : ALARM : WAKEUP ALERT ON CALL */
+ NULL,
+ /* NOTIFICATION : ALARM : SCHEDULE */
+ NULL,
+ /* NOTIFICATION : ALARM : SCHEDULE ALERT ON CALL */
+ NULL,
+ /* NOTIFICATION : ALARM : TIMER */
+ NULL,
+ /* NOTIFICATION : ALARM : TIMER ALERT ON CALL */
+ NULL,
+ /* NOTIFICATION : GENERAL(TICKER/IM/SMS ETC) */
+ FEEDBACK_SOUND_OPER_DIR"/call_connect.wav",
+ /* NOTIFICATION : GENERAL(TICKER/IM/SMS ETC) ALERT ON CALL */
+ FEEDBACK_SOUND_OPER_DIR"/call_connect.wav",
+
+ /* OPERATION : POWER ON/OFF */
+ FEEDBACK_SOUND_OPER_DIR"/power_on.wav",
+ NULL,
+ /* OPERATION : CHARGECONN */
+ FEEDBACK_SOUND_OPER_DIR"/charger_connection.wav",
+ /* OPERATION : CHARGECONN ALERT ON CALL */
+ FEEDBACK_SOUND_OPER_DIR"/charger_connection.wav",
+ /* OPERATION : FULLCHAREGED */
+ FEEDBACK_SOUND_OPER_DIR"/fully_charged.wav",
+ /* OPERATION : FULLCHAREGED ALERT ON CALL */
+ FEEDBACK_SOUND_OPER_DIR"/fully_charged.wav",
+ /* OPERATION : LOW BATTERY */
+ FEEDBACK_SOUND_OPER_DIR"/low_battery.wav",
+ /* OPERATION : LOW BATTERY ALERT ON CALL */
+ FEEDBACK_SOUND_OPER_DIR"/low_battery.wav",
+ /* OPERATION : LOCK/UNLOCK */
+ FEEDBACK_SOUND_OPER_DIR"/lock.wav",
+ FEEDBACK_SOUND_OPER_DIR"/unlock.wav",
+ /* OPERATION : CALL CONNECT/ DISCONNECT */
+ FEEDBACK_SOUND_OPER_DIR"/call_connect.wav",
+ FEEDBACK_SOUND_OPER_DIR"/call_disconnect.wav",
+ /* OPERATION : MINUTE MINDER */
+ FEEDBACK_SOUND_OPER_DIR"/minute_minder.wav",
+ /* OPERATION : VIBRATION */
+ NULL,
+ /* OPERATION : CAMERA SHUTTER / SCREEN CAPTURE */
+ FEEDBACK_SOUND_OPER_DIR"/shutter.wav",
+ /* OPERATION : LIST RE-ORDER */
+ FEEDBACK_SOUND_OPER_DIR"/list_reorder.wav",
+ /* OPERATION : LIST SLIDER */
+ FEEDBACK_SOUND_OPER_DIR"/slider_sweep.wav",
+ /* OPERATION : VOLUME KEY */
+ FEEDBACK_SOUND_OPER_DIR"/volume_control.wav",
+};
+
+static int sndstatus;
+static int touch_sndstatus;
+static int soundon;
+
+static void feedback_sndstatus_cb(keynode_t *key, void* data)
+{
+ sndstatus = vconf_keynode_get_bool(key);
+}
+
+static void feedback_touch_sndstatus_cb(keynode_t *key, void* data)
+{
+ touch_sndstatus = vconf_keynode_get_bool(key);
+}
+
+static void feedback_soundon_cb(keynode_t *key, void* data)
+{
+ soundon = vconf_keynode_get_int(key);
+}
+
+static volume_type_t get_volume_type(feedback_pattern_e pattern)
+{
+ if (pattern == FEEDBACK_PATTERN_TAP)
+ return VOLUME_TYPE_SYSTEM|VOLUME_GAIN_TOUCH;
+ else if (pattern >= FEEDBACK_PATTERN_KEY0 && pattern <= FEEDBACK_PATTERN_KEY_SHARP)
+ return VOLUME_TYPE_SYSTEM|VOLUME_GAIN_DIALER;
+ else if (pattern == FEEDBACK_PATTERN_VOLUME_KEY)
+ return VOLUME_TYPE_RINGTONE;
+
+ return VOLUME_TYPE_SYSTEM;
+}
+
+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 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 = sound_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 sound_init(void)
+{
+ /* Sound Init */
+ if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sndstatus) < 0)
+ FEEDBACK_ERROR("vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sndstatus) ==> FAIL!!");
+
+ if (vconf_get_bool(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, &touch_sndstatus) < 0)
+ FEEDBACK_ERROR("vconf_get_bool(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, &touch_sndstatus) ==> FAIL!!");
+
+ if (vconf_get_int(VCONFKEY_SOUND_STATUS, &soundon) < 0)
+ FEEDBACK_ERROR("vconf_get_int(VCONFKEY_SOUND_STATUS, &soundon) ==> FAIL!!");
+
+ /* add watch for status value */
+ vconf_notify_key_changed(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, feedback_sndstatus_cb, NULL);
+ vconf_notify_key_changed(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, feedback_touch_sndstatus_cb, NULL);
+ vconf_notify_key_changed(VCONFKEY_SOUND_STATUS, feedback_soundon_cb, NULL);
+}
+
+static void sound_exit(void)
+{
+ /* remove watch */
+ vconf_ignore_key_changed(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, feedback_sndstatus_cb);
+ vconf_ignore_key_changed(VCONFKEY_SOUND_STATUS, feedback_soundon_cb);
+ vconf_ignore_key_changed(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, feedback_touch_sndstatus_cb);
+}
+
+static int sound_play(feedback_pattern_e pattern)
+{
+ struct stat buf;
+ int retry = FEEDBACK_RETRY_CNT, ret;
+
+ if (sndstatus == 0 && !get_always_alert_case(pattern)) {
+ FEEDBACK_LOG("Sound condition is OFF (sndstatus : %d)", sndstatus);
+ return 0;
+ }
+
+ if (soundon == 1 && pattern >= FEEDBACK_PATTERN_TAP && pattern <= FEEDBACK_PATTERN_HW_HOLD) {
+ FEEDBACK_LOG("Touch feedback sound doesn't work during playing sound");
+ return 0;
+ }
+
+ if (touch_sndstatus == 0 && pattern >= FEEDBACK_PATTERN_TAP && pattern <= FEEDBACK_PATTERN_HW_HOLD) {
+ FEEDBACK_LOG("Touch Sound condition is OFF and pattern is touch type (touch_sndstatus : %d, pattern : %s)", touch_sndstatus, str_pattern[pattern]);
+ 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;
+ }
+
+ if (stat(sound_file[pattern], &buf)) {
+ FEEDBACK_ERROR("%s is not presents", sound_file[pattern]);
+ ret = restore_default_file(pattern);
+ if (ret < 0) {
+ FEEDBACK_ERROR("restore_default_file(%s) error", str_pattern[pattern]);
+ return -EPERM;
+ }
+ FEEDBACK_LOG("%s is restored", sound_file[pattern]);
+ }
+
+ do {
+ ret = mm_sound_play_keysound(sound_file[pattern], get_volume_type(pattern));
+ if (ret == MM_ERROR_NONE) {
+ FEEDBACK_LOG("Play success! SND filename is %s", sound_file[pattern]);
+ return 0;
+ }
+ FEEDBACK_ERROR("mm_sound_play_keysound() returned error(%d)", ret);
+ } while(retry--);
+
+ return -EPERM;
+}
+
+static int sound_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 = sound_file[pattern];
+ if (cur_path == NULL) {
+ FEEDBACK_ERROR("This pattern(%s) in sound 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 sound_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 = sound_file[pattern];
+ if (cur_path == NULL) {
+ FEEDBACK_ERROR("This pattern(%s) in sound 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 sound_device_ops = {
+ .type = FEEDBACK_TYPE_SOUND,
+ .init = sound_init,
+ .exit = sound_exit,
+ .play = sound_play,
+ .get_path = sound_get_path,
+ .set_path = sound_set_path,
+};
+
+DEVICE_OPS_REGISTER(&sound_device_ops);