diff options
author | taeyoung <ty317.kim@samsung.com> | 2015-06-10 22:57:56 +0900 |
---|---|---|
committer | taeyoung <ty317.kim@samsung.com> | 2015-06-10 23:03:59 +0900 |
commit | f0e71819ee83cd67d94be187dc301c3d9c2c83a5 (patch) | |
tree | 6aa37ca5c3652f89f60de0d78d75d801a8129dda /src | |
parent | 7780e7ea0ea03dcc8e796aa6b22ec53ec34b98d1 (diff) | |
download | libsvi-f0e71819ee83cd67d94be187dc301c3d9c2c83a5.tar.gz libsvi-f0e71819ee83cd67d94be187dc301c3d9c2c83a5.tar.bz2 libsvi-f0e71819ee83cd67d94be187dc301c3d9c2c83a5.zip |
common: code sync with Tizen 2.3
- Currently, libsvi is too old and it is necessary
to add many fixes and some features. Thus code sync
is needed
Change-Id: I0abd6ad42bf5ef74ae001a2c82aca5c6bc40ff32
Signed-off-by: taeyoung <ty317.kim@samsung.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/dbus.c | 136 | ||||
-rw-r--r-- | src/devices.c | 11 | ||||
-rw-r--r-- | src/feedback.c | 99 | ||||
-rw-r--r-- | src/sound.c | 493 | ||||
-rw-r--r-- | src/str.c | 49 | ||||
-rwxr-xr-x | src/svi.c | 330 | ||||
-rw-r--r-- | src/vibrator.c | 622 | ||||
-rw-r--r-- | src/xmlparser.c | 32 |
8 files changed, 768 insertions, 1004 deletions
diff --git a/src/dbus.c b/src/dbus.c new file mode 100644 index 0000000..f013abe --- /dev/null +++ b/src/dbus.c @@ -0,0 +1,136 @@ +/* + * feedback + * + * Copyright (c) 2012 - 2013 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 <stdlib.h> +#include <stdint.h> +#include <errno.h> + +#include "common.h" +#include "log.h" +#include "dbus.h" + +/* -1 is a default timeout value, it's converted to 25*1000 internally. */ +#define DBUS_REPLY_TIMEOUT (-1) + +static int append_variant(DBusMessageIter *iter, const char *sig, char *param[]) +{ + char *ch; + int i; + int int_type; + uint64_t int64_type; + DBusMessageIter arr; + struct dbus_byte *byte; + + if (!sig || !param) + return 0; + + for (ch = (char*)sig, i = 0; *ch != '\0'; ++i, ++ch) { + switch (*ch) { + case 'i': + int_type = atoi(param[i]); + dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type); + break; + case 'u': + int_type = strtoul(param[i], NULL, 10); + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &int_type); + break; + case 't': + int64_type = atoll(param[i]); + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &int64_type); + break; + case 's': + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, ¶m[i]); + break; + case 'a': + ++i, ++ch; + switch (*ch) { + case 'y': + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &arr); + byte = (struct dbus_byte*)param[i]; + dbus_message_iter_append_fixed_array(&arr, DBUS_TYPE_BYTE, &(byte->data), byte->size); + dbus_message_iter_close_container(iter, &arr); + break; + default: + break; + } + break; + default: + return -EINVAL; + } + } + + return 0; +} + +int dbus_method_sync(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, char *param[]) +{ + DBusConnection *conn; + DBusMessage *msg; + DBusMessageIter iter; + DBusMessage *reply; + DBusError err; + int ret, result; + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (!conn) { + _E("dbus_bus_get error"); + return -EPERM; + } + + msg = dbus_message_new_method_call(dest, path, interface, method); + if (!msg) { + _E("dbus_message_new_method_call(%s:%s-%s)", + path, interface, method); + return -EBADMSG; + } + + dbus_message_iter_init_append(msg, &iter); + ret = append_variant(&iter, sig, param); + if (ret < 0) { + _E("append_variant error(%d) %s %s:%s-%s", + ret, dest, path, interface, method); + dbus_message_unref(msg); + return ret; + } + + dbus_error_init(&err); + + reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_REPLY_TIMEOUT, &err); + dbus_message_unref(msg); + if (!reply) { + _E("dbus_connection_send error(%s:%s) %s %s:%s-%s", + err.name, err.message, dest, path, interface, method); + dbus_error_free(&err); + return -ECOMM; + } + + ret = dbus_message_get_args(reply, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID); + dbus_message_unref(reply); + if (!ret) { + _E("no message : [%s:%s] %s %s:%s-%s", + err.name, err.message, dest, path, interface, method); + dbus_error_free(&err); + return -ENOMSG; + } + + return result; +} diff --git a/src/devices.c b/src/devices.c index f87fcb1..e135e07 100644 --- a/src/devices.c +++ b/src/devices.c @@ -92,3 +92,14 @@ void devices_play(int pattern) dev->play(pattern); } } + +void devices_stop(void) +{ + dd_list *elem; + const struct device_ops *dev; + + DD_LIST_FOREACH(dev_head, elem, dev) { + if (dev->stop) + dev->stop(); + } +} diff --git a/src/feedback.c b/src/feedback.c index 6cebbb6..f14ffef 100644 --- a/src/feedback.c +++ b/src/feedback.c @@ -32,6 +32,7 @@ #endif int callstatus; +int alert_callstatus; static bool binit; @@ -40,6 +41,11 @@ static void feedback_callstatus_cb(keynode_t *key, void* data) callstatus = vconf_keynode_get_int(key); } +static void feedback_alertstatus_cb(keynode_t *key, void* data) +{ + alert_callstatus = vconf_keynode_get_int(key); +} + static feedback_pattern_e get_alert_on_call_key(feedback_pattern_e pattern) { switch(pattern) { @@ -50,6 +56,7 @@ static feedback_pattern_e get_alert_on_call_key(feedback_pattern_e pattern) case FEEDBACK_PATTERN_TIMER: case FEEDBACK_PATTERN_GENERAL: case FEEDBACK_PATTERN_CHARGERCONN: + case FEEDBACK_PATTERN_CHARGING_ERROR: case FEEDBACK_PATTERN_FULLCHARGED: case FEEDBACK_PATTERN_LOWBATT: return (feedback_pattern_e)(pattern+1); @@ -60,6 +67,20 @@ static feedback_pattern_e get_alert_on_call_key(feedback_pattern_e pattern) return pattern; } +static void __DESTRUCTOR__ module_exit(void) +{ + if (!binit) + return; + + vconf_ignore_key_changed(VCONFKEY_CALL_STATE, feedback_callstatus_cb); + vconf_ignore_key_changed(VCONFKEY_CISSAPPL_ALERT_ON_CALL_INT, feedback_alertstatus_cb); + + /* deinitialize device */ + devices_exit(); + + binit = false; +} + API int feedback_initialize() { if (binit) @@ -69,8 +90,14 @@ API int feedback_initialize() if (vconf_get_int(VCONFKEY_CALL_STATE, &callstatus) < 0) _W("VCONFKEY_CALL_STATE ==> FAIL!!"); + + /* alert option on call */ + if (vconf_get_int(VCONFKEY_CISSAPPL_ALERT_ON_CALL_INT, &alert_callstatus) < 0) + _W("VCONFKEY_CISSAPPL_ON_CALL_INT ==> FAIL!!"); + /* add watch for status value */ vconf_notify_key_changed(VCONFKEY_CALL_STATE, feedback_callstatus_cb, NULL); + vconf_notify_key_changed(VCONFKEY_CISSAPPL_ALERT_ON_CALL_INT, feedback_alertstatus_cb, NULL); /* initialize device */ devices_init(); @@ -81,15 +108,6 @@ API int feedback_initialize() API int feedback_deinitialize() { - if (!binit) - return FEEDBACK_ERROR_NOT_INITIALIZED; - - vconf_ignore_key_changed(VCONFKEY_CALL_STATE, feedback_callstatus_cb); - - /* deinitialize device */ - devices_exit(); - - binit = false; return FEEDBACK_ERROR_NONE; } @@ -155,6 +173,17 @@ API int feedback_play_type(feedback_type_e type, feedback_pattern_e pattern) _D("Call status is connected or connecting. pattern changed : %s", str_pattern[pattern]); } + /* should play led regardless of sound or vibration */ + dev = find_device(FEEDBACK_TYPE_LED); + if (dev) { + err = dev->play(pattern); + if (err < 0) + _E("feedback_play_led is failed"); + } + + if (type == FEEDBACK_TYPE_LED) + return FEEDBACK_ERROR_NONE; + /* play proper device */ dev = find_device(type); if (dev) { @@ -166,6 +195,53 @@ API int feedback_play_type(feedback_type_e type, feedback_pattern_e pattern) return FEEDBACK_ERROR_NONE; } +API int feedback_play_type_by_name(char *type, char *pattern) +{ + feedback_type_e etype; + feedback_pattern_e epattern; + + if (!type || !pattern) { + _E("Invalid parameter : type(%x), pattern(%x)", type, pattern); + return FEEDBACK_ERROR_INVALID_PARAMETER; + } + + for (etype = FEEDBACK_TYPE_NONE; etype < FEEDBACK_TYPE_END; ++etype) { + if (!strncmp(type, str_type[etype], strlen(type))) + break; + } + + if (etype == FEEDBACK_TYPE_END) { + _E("Invalid parameter : type(%s)", type); + return FEEDBACK_ERROR_INVALID_PARAMETER; + } + + for (epattern = 0; epattern < FEEDBACK_PATTERN_END; ++epattern) { + if (!strncmp(pattern, str_pattern[epattern], strlen(pattern))) + break; + } + + if (epattern == FEEDBACK_PATTERN_END) { + _E("Invalid parameter : pattern(%d)", pattern); + return FEEDBACK_ERROR_INVALID_PARAMETER; + } + + return feedback_play_type(etype, epattern); +} + +API int feedback_stop(void) +{ + /* check initialize */ + if (!binit) { + _E("Not initialized"); + return FEEDBACK_ERROR_NOT_INITIALIZED; + } + + /* stop all device */ + devices_stop(); + + 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; @@ -204,11 +280,6 @@ API int feedback_set_resource_path(feedback_type_e type, feedback_pattern_e patt const struct device_ops *dev; int err; - if (path == NULL) { - _E("Invalid parameter : path(NULL)"); - return FEEDBACK_ERROR_INVALID_PARAMETER; - } - if (type <= FEEDBACK_TYPE_NONE || type >= FEEDBACK_TYPE_END) { _E("Invalid parameter : type(%d)", type); return FEEDBACK_ERROR_INVALID_PARAMETER; diff --git a/src/sound.c b/src/sound.c index 86a1241..0d14b22 100644 --- a/src/sound.c +++ b/src/sound.c @@ -17,7 +17,6 @@ #include <stdio.h> -#include <stdlib.h> #include <stdbool.h> #include <string.h> #include <unistd.h> @@ -32,199 +31,23 @@ #include "common.h" #include "log.h" #include "devices.h" +#include "xmlparser.h" -#define FEEDBACK_SOUND_DIR FEEDBACK_DATA_DIR"/sound" -#define FEEDBACK_SOUND_TOUCH_DIR "touch" -#define FEEDBACK_SOUND_OPER_DIR "operation" -#define SCRIPT_INIT_LINK_WAV FEEDBACK_ORIGIN_DATA_DIR"/init_wav_link.sh" -#define MAX_SOUND_FILE 50 - -static const char* sound_file_default[] = { - /* 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 char* sound_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) */ - 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) */ - NULL, - /* NOTIFICATION : GENERAL(TICKER/IM/SMS ETC) ALERT ON CALL */ - NULL, - - /* OPERATION : POWER ON/OFF */ - NULL, - NULL, - /* OPERATION : CHARGECONN */ - NULL, - /* OPERATION : CHARGECONN ALERT ON CALL */ - NULL, - /* OPERATION : FULLCHAREGED */ - NULL, - /* OPERATION : FULLCHAREGED ALERT ON CALL */ - NULL, - /* OPERATION : LOW BATTERY */ - NULL, - /* OPERATION : LOW BATTERY ALERT ON CALL */ - NULL, - /* OPERATION : LOCK/UNLOCK */ - NULL, - NULL, - /* OPERATION : CALL CONNECT/ DISCONNECT */ - NULL, - NULL, - /* OPERATION : MINUTE MINDER */ - NULL, - /* OPERATION : VIBRATION */ - NULL, - /* OPERATION : CAMERA SHUTTER / SCREEN CAPTURE */ - NULL, - /* OPERATION : LIST RE-ORDER */ - NULL, - /* OPERATION : LIST SLIDER */ - NULL, - /* OPERATION : VOLUME KEY */ - NULL, -}; +#define SOUND_XML "/usr/share/feedback/sound.xml" static int sndstatus; static int touch_sndstatus; -static int soundon; +static int lock_sndstatus; +static int camerastatus; +static int shutter_sndstatus; + +static xmlDocPtr v_doc; -static void feedback_sndstatus_cb(keynode_t *key, void* data) +static char sound_file[FEEDBACK_PATTERN_END][NAME_MAX]; + +inline int is_sound_mode(void) { - sndstatus = vconf_keynode_get_bool(key); + return sndstatus; } static void feedback_touch_sndstatus_cb(keynode_t *key, void* data) @@ -232,19 +55,26 @@ 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) +static void feedback_lock_sndstatus_cb(keynode_t *key, void* data) +{ + lock_sndstatus = vconf_keynode_get_bool(key); +} + +static void feedback_camerastatus_cb(keynode_t *key, void* data) { - soundon = vconf_keynode_get_int(key); + camerastatus = 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) + else if (pattern >= FEEDBACK_PATTERN_KEY0 && pattern <= FEEDBACK_PATTERN_KEY_BACK) return VOLUME_TYPE_SYSTEM|VOLUME_GAIN_DIALER; else if (pattern == FEEDBACK_PATTERN_VOLUME_KEY) return VOLUME_TYPE_RINGTONE; + else if (camerastatus && shutter_sndstatus && pattern == FEEDBACK_PATTERN_SCREEN_CAPTURE) + return VOLUME_TYPE_FIXED; return VOLUME_TYPE_SYSTEM; } @@ -255,122 +85,121 @@ static bool get_always_alert_case(feedback_pattern_e pattern) case FEEDBACK_PATTERN_WAKEUP: case FEEDBACK_PATTERN_WAKEUP_ON_CALL: return true; + case FEEDBACK_PATTERN_MESSAGE_ON_CALL: + case FEEDBACK_PATTERN_EMAIL_ON_CALL: + case FEEDBACK_PATTERN_GENERAL_ON_CALL: + if (alert_callstatus) + return true; + break; + case FEEDBACK_PATTERN_SMART_ALERT: + case FEEDBACK_PATTERN_SEND_SOS_MESSAGE: + case FEEDBACK_PATTERN_END_SOS_MESSAGE: + case FEEDBACK_PATTERN_CMAS: + return true; + case FEEDBACK_PATTERN_SCREEN_CAPTURE: + if (camerastatus && shutter_sndstatus) + return true; + break; + case FEEDBACK_PATTERN_OUTGOING_CALL: + return true; default: break; } return false; } -static int change_symlink(const char *sym_path, const char *new_path) +static bool get_always_off_case(feedback_pattern_e pattern) { - 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)) { - _E("file(%s) is not presents", sym_path); - return -EPERM; - } - - if (unlink(sym_path) < 0) - _D("unlink(%s) : %s", sym_path, strerror(errno)); - - if (symlink(new_path, sym_path) < 0) { - _E("symlink(%s) : %s", sym_path, strerror(errno)); - return -EPERM; + switch (pattern) { + case FEEDBACK_PATTERN_TAP ... FEEDBACK_PATTERN_MAX_CHARACTER: + case FEEDBACK_PATTERN_HOLD ... FEEDBACK_PATTERN_HW_HOLD: + if (!touch_sndstatus) + return true; + break; + case FEEDBACK_PATTERN_KEY0 ... FEEDBACK_PATTERN_KEY_BACK: + break; + case FEEDBACK_PATTERN_LOCK: + case FEEDBACK_PATTERN_UNLOCK: + case FEEDBACK_PATTERN_LOCK_SWIPE: + case FEEDBACK_PATTERN_UNLOCK_SWIPE: + if (!lock_sndstatus) + return true; + break; + default: + break; } - - return 0; + return false; } -static int restore_default_file(feedback_pattern_e pattern) +static int get_xml_data(xmlDocPtr doc, feedback_pattern_e pattern, struct xmlData **data) { - char default_path[PATH_MAX] = {0,}; - const char *cur_path; - char *temp; - int ret; + xmlNodePtr cur; + struct xmlData *retData; - 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) { - _E("Invalid parameter : cur_path(NULL)"); - return -EPERM; - } - - temp = strcat(default_path, FEEDBACK_ORIGIN_DATA_DIR); - strcat(temp, cur_path+strlen(FEEDBACK_DATA_DIR)); - _D("default_path : %s", default_path); + cur = xml_find(doc, SOUND_STR, (const xmlChar*)str_pattern[pattern]); + /* This pattern does not have sound file to play */ + if (cur == NULL) + return -ENOENT; - ret = change_symlink(cur_path, default_path); - if (ret < 0) { - _E("change_symlink is failed"); + retData = xml_parse(doc, cur); + if (retData == NULL) { + _E("xml_parse fail"); return -EPERM; } + *data = retData; return 0; } -static void link_init(void) +static void release_xml_data(struct xmlData *data) { - struct stat sts; - int i,ret; - int directory = 0; - char default_path[PATH_MAX] = {0,}; - - /* Check if the directory exists; if not, create it and initialize it */ - ret = stat(FEEDBACK_DATA_DIR, &sts); - if (ret == -1 && errno == ENOENT){ - directory = 1; - } + if (data == NULL) + return; - /* init of sound array and link*/ - strcat(default_path, FEEDBACK_ORIGIN_DATA_DIR); - for( i = 0 ; i< MAX_SOUND_FILE ; i++){ - if ( sound_file_default[i] != NULL ){ - sound_file[i] = strdup(tzplatform_mkpath3(TZ_USER_SHARE,"feedback/sound",sound_file_default[i])); - if (directory == 1){ - if (symlink(default_path,sound_file[i]) < 0){ - _W("change_symlink is failed"); - } - } - } - } + xml_free(data); } static void sound_init(void) { - link_init(); - - /* Sound Init */ - if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sndstatus) < 0) - _W("VCONFKEY_SETAPPL_SOUND_STATUS_BOOL ==> FAIL!!"); + /* xml Init */ + v_doc = xml_open(SOUND_XML); + if (v_doc == NULL) { + _E("xml_open(%s) fail", SOUND_XML); + return; + } + /* check sound status */ if (vconf_get_bool(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, &touch_sndstatus) < 0) _W("VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL ==> FAIL!!"); - if (vconf_get_int(VCONFKEY_SOUND_STATUS, &soundon) < 0) - _W("VCONFKEY_SOUND_STATUS ==> FAIL!!"); + if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_LOCK_BOOL, &lock_sndstatus) < 0) + _W("VCONFKEY_SETAPPL_SOUND_LOCK_BOOL ==> FAIL!!"); + + /* check camera status */ + if (vconf_get_int(VCONFKEY_CAMERA_STATE, &camerastatus) < 0) + _W("VCONFKEY_CAMERA_STATE ==> FAIL!!"); + + /* shutter sound policy */ + // This vconf is read just once, because this value is not changed in running time. + if (vconf_get_int(VCONFKEY_CAMERA_SHUTTER_SOUND_POLICY, &shutter_sndstatus) < 0) + _W("VCONFKEY_CAMERA_SHUTTER_SOUND_POLICY ==> 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_SOUND_LOCK_BOOL, feedback_lock_sndstatus_cb, NULL); + vconf_notify_key_changed(VCONFKEY_CAMERA_STATE, feedback_camerastatus_cb, NULL); } static void sound_exit(void) { - - int i; - /* 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); + vconf_ignore_key_changed(VCONFKEY_SETAPPL_SOUND_LOCK_BOOL, feedback_lock_sndstatus_cb); + vconf_ignore_key_changed(VCONFKEY_CAMERA_STATE, feedback_camerastatus_cb); - for(i = 0 ; i< MAX_SOUND_FILE ; i++){ - free(sound_file[i]); + if (v_doc) { + xml_close(v_doc); + v_doc = NULL; } } @@ -378,97 +207,135 @@ static int sound_play(feedback_pattern_e pattern) { struct stat buf; int retry = FEEDBACK_RETRY_CNT, ret; + char *path; + struct xmlData *data = NULL; + + if (!v_doc) { + _E("Not initialize"); + return -EPERM; + } + + if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sndstatus) < 0) { + _D("fail to get sound status, will work as turning off"); + sndstatus = 0; + } if (sndstatus == 0 && !get_always_alert_case(pattern)) { _D("Sound condition is OFF (sndstatus : %d)", sndstatus); return 0; } - if (soundon == 1 && pattern >= FEEDBACK_PATTERN_TAP && pattern <= FEEDBACK_PATTERN_HW_HOLD) { - _D("Touch feedback sound doesn't work during playing sound"); + if (sndstatus && get_always_off_case(pattern)) { + _D("Sound always off condition"); return 0; } - if (touch_sndstatus == 0 && pattern >= FEEDBACK_PATTERN_TAP && pattern <= FEEDBACK_PATTERN_HW_HOLD) { - _D("Touch Sound condition is OFF and pattern is touch type (touch_sndstatus : %d, pattern : %s)", touch_sndstatus, str_pattern[pattern]); - return 0; + /* check if the state of voice recorder is recording */ + if (vconf_get_int(VCONFKEY_SOUND_STATUS, &ret) < 0) { + _D("fail to get media sound status, status will be zero"); + ret = 0; } - if (sound_file[pattern] == NULL) { - _D("This case(%s) does not play sound", str_pattern[pattern]); + if (ret & VCONFKEY_SOUND_STATUS_AVRECORDING) { + _D("voice recording status is RECORDING"); return 0; } - if (stat(sound_file[pattern], &buf)) { - _E("%s is not presents", sound_file[pattern]); - ret = restore_default_file(pattern); + /* check whether there is a user defined file */ + path = sound_file[pattern]; + + /* if not */ + if (!(*path)) { + ret = get_xml_data(v_doc, pattern, &data); + if (ret == -ENOENT) { + _D("No sound case(%s)", str_pattern[pattern]); + return 0; + } + if (ret < 0) { - _E("restore_default_file(%s) error", str_pattern[pattern]); + _E("get_xml_data fail"); return -EPERM; } - _D("%s is restored", sound_file[pattern]); + + if (!data->data) { + _D("No sound case(%s)", str_pattern[pattern]); + release_xml_data(data); + return 0; + } + + path = data->data; + } + + if (stat(path, &buf)) { + _E("%s is not presents", path); + return -ENOENT; } + /* play sound file */ do { - ret = mm_sound_play_keysound(sound_file[pattern], get_volume_type(pattern)); + ret = mm_sound_play_keysound(path, get_volume_type(pattern)); if (ret == MM_ERROR_NONE) { - _D("Play success! SND filename is %s", sound_file[pattern]); + _D("Play success! SND filename is %s", path); + release_xml_data(data); return 0; } _E("mm_sound_play_keysound() returned error(%d)", ret); } while(retry--); + release_xml_data(data); 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; + char *cur_path; + int ret = 0; + struct xmlData *data = NULL; - assert(buf != NULL && buflen > 0); + if (!buf || buflen <= 0) + return -EINVAL; cur_path = sound_file[pattern]; - if (cur_path == NULL) { - _E("This pattern(%s) in sound type is not supported to play", str_pattern[pattern]); - snprintf(buf, buflen, "NULL"); - return -ENOENT; + if (!cur_path) { + ret = get_xml_data(v_doc, pattern, &data); + if (ret >= 0 && data && data->data) + cur_path = (char*)data->data; } - do { - if(readlink(cur_path, buf, buflen) < 0) { - _E("readlink is failed : %s", strerror(errno)); - return -EPERM; - } - } while(retry--); + if (!cur_path) { + _E("This pattern(%s) in sound type is not supported to play", str_pattern[pattern]); + cur_path = "NULL"; + ret = -ENOENT; + } + snprintf(buf, buflen, "%s", cur_path); + release_xml_data(data); 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) { - _E("Invalid parameter : path does not exist"); - return -ENOENT; + struct stat buf; + char *ppath; + + /* + * check the path is valid + * if path is null, below operation is ignored + */ + if (path && stat(path, &buf)) { + _E("%s is not presents", path); + return -errno; } - cur_path = sound_file[pattern]; - if (cur_path == NULL) { - _E("This pattern(%s) in sound type is not supported to play", str_pattern[pattern]); - return -ENOENT; - } + ppath = sound_file[pattern]; - ret = change_symlink(cur_path, path); - if (ret < 0) { - _E("change_symlink is failed"); - return -EPERM; - } + /* if path is NULL, this pattern set to default file */ + if (path) + snprintf(ppath, NAME_MAX, "%s", path); + else + memset(ppath, 0, NAME_MAX); + _D("The file of pattern(%s) is changed to [%s]", str_pattern[pattern], path); return 0; } @@ -23,6 +23,7 @@ const char *str_type[] = "FEEDBACK_TYPE_NONE", "FEEDBACK_TYPE_SOUND", "FEEDBACK_TYPE_VIBRATION", + "FEEDBACK_TYPE_LED", "FEEDBACK_TYPE_END", }; @@ -31,6 +32,8 @@ const char *str_pattern[] = "FEEDBACK_PATTERN_TAP", "FEEDBACK_PATTERN_SIP", "FEEDBACK_PATTERN_SIP_BACKSPACE", + "FEEDBACK_PATTERN_SIP_FUNCTION", + "FEEDBACK_PATTERN_SIP_FJKEY", "FEEDBACK_PATTERN_MAX_CHARACTER", "FEEDBACK_PATTERN_KEY0", "FEEDBACK_PATTERN_KEY1", @@ -44,10 +47,12 @@ const char *str_pattern[] = "FEEDBACK_PATTERN_KEY9", "FEEDBACK_PATTERN_KEY_STAR", "FEEDBACK_PATTERN_KEY_SHARP", + "FEEDBACK_PATTERN_KEY_BACK", "FEEDBACK_PATTERN_HOLD", "FEEDBACK_PATTERN_MULTI_TAP", "FEEDBACK_PATTERN_HW_TAP", "FEEDBACK_PATTERN_HW_HOLD", + "FEEDBACK_PATTERN_MESSAGE", "FEEDBACK_PATTERN_MESSAGE_ON_CALL", "FEEDBACK_PATTERN_EMAIL", @@ -60,22 +65,60 @@ const char *str_pattern[] = "FEEDBACK_PATTERN_TIMER_ON_CALL", "FEEDBACK_PATTERN_GENERAL", "FEEDBACK_PATTERN_GENERAL_ON_CALL", + "FEEDBACK_PATTERN_SMART_ALERT", + "FEEDBACK_PATTERN_POWERON", "FEEDBACK_PATTERN_POWEROFF", "FEEDBACK_PATTERN_CHARGERCONN", "FEEDBACK_PATTERN_CHARGERCONN_ON_CALL", + "FEEDBACK_PATTERN_CHARGING_ERROR", + "FEEDBACK_PATTERN_CHARGING_ERROR_ON_CALL", "FEEDBACK_PATTERN_FULLCHARGED", "FEEDBACK_PATTERN_FULLCHARGED_ON_CALL", "FEEDBACK_PATTERN_LOWBATT", "FEEDBACK_PATTERN_LOWBATT_ON_CALL", "FEEDBACK_PATTERN_LOCK", "FEEDBACK_PATTERN_UNLOCK", + "FEEDBACK_PATTERN_LOCK_SWIPE", + "FEEDBACK_PATTERN_UNLOCK_SWIPE", + "FEEDBACK_PATTERN_GEOMETRIC_LOCK", "FEEDBACK_PATTERN_CALLCONNECT", "FEEDBACK_PATTERN_DISCALLCONNECT", + "FEEDBACK_PATTERN_OUTGOING_CALL", "FEEDBACK_PATTERN_MINUTEMINDER", - "FEEDBACK_PATTERN_VIBRATION", - "FEEDBACK_PATTERN_SHUTTER", + "FEEDBACK_PATTERN_VIBRATION_ON", + "FEEDBACK_PATTERN_SILENT_OFF", + "FEEDBACK_PATTERN_BT_CONNECTED", + "FEEDBACK_PATTERN_BT_DISCONNECTED", + "FEEDBACK_PATTERN_BT_PAIRING", + "FEEDBACK_PATTERN_BT_WAITING", + "FEEDBACK_PATTERN_SCREEN_CAPTURE", "FEEDBACK_PATTERN_LIST_REORDER", - "FEEDBACK_PATTERN_SLIDER_SWEEP", + "FEEDBACK_PATTERN_LIST_SLIDER", "FEEDBACK_PATTERN_VOLUME_KEY", + "FEEDBACK_PATTERN_MMS", + "FEEDBACK_PATTERN_HOURLY_ALERT", + + "FEEDBACK_PATTERN_SAFETY_ALERT", + "FEEDBACK_PATTERN_ACCIDENT_DETECT", + "FEEDBACK_PATTERN_SEND_SOS_MESSAGE", + "FEEDBACK_PATTERN_END_SOS_MESSAGE", + "FEEDBACK_PATTERN_EMERGENCY_BUZZER", + "FEEDBACK_PATTERN_SAFETY_LOW_POWER", + "FEEDBACK_PATTERN_CMAS", + "FEEDBACK_PATTERN_SPEED_UP", + "FEEDBACK_PATTERN_SLOW_DOWN", + "FEEDBACK_PATTERN_KEEP_THIS_PACE", + "FEEDBACK_PATTERN_GOAL_ACHIEVED", + "FEEDBACK_PATTERN_EXERCISE_COUNT", + "FEEDBACK_PATTERN_START_CUE", + "FEEDBACK_PATTERN_HEALTH_PACE", + "FEEDBACK_PATTERN_INACTIVE_TIME", + "FEEDBACK_PATTERN_MEASURING_SUCCESS", + "FEEDBACK_PATTERN_MEASURING_FAILURE", + "FEEDBACK_PATTERN_UV_PROCESSING", + "FEEDBACK_PATTERN_SHEALTH_START", + "FEEDBACK_PATTERN_SHEALTH_PAUSE", + "FEEDBACK_PATTERN_SHEALTH_STOP", + "FEEDBACK_PATTERN_3RD_APPLICATION", }; diff --git a/src/svi.c b/src/svi.c deleted file mode 100755 index 1f73ae6..0000000 --- a/src/svi.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * 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 "svi.h" -#include "feedback.h" -#include "svi-log.h" - -#define SVI_TEMP_HANDLE 1 - -#ifndef API -#define API __attribute__ ((visibility("default"))) -#endif - -feedback_pattern_e feedback_sound[] = { - /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : GENERAL */ - FEEDBACK_PATTERN_TAP, - FEEDBACK_PATTERN_TAP, - FEEDBACK_PATTERN_TAP, - /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : TEXT_NUMERIC_INPUT */ - FEEDBACK_PATTERN_SIP, - FEEDBACK_PATTERN_SIP_BACKSPACE, - /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : DAILER */ - FEEDBACK_PATTERN_KEY0, - FEEDBACK_PATTERN_KEY1, - FEEDBACK_PATTERN_KEY2, - FEEDBACK_PATTERN_KEY3, - FEEDBACK_PATTERN_KEY4, - FEEDBACK_PATTERN_KEY5, - FEEDBACK_PATTERN_KEY6, - FEEDBACK_PATTERN_KEY7, - FEEDBACK_PATTERN_KEY8, - FEEDBACK_PATTERN_KEY9, - FEEDBACK_PATTERN_KEY_STAR, - FEEDBACK_PATTERN_KEY_SHARP, - /* TOUCH : H/W OR SOFT TOUCH : HOLD(TAP & HOLD) */ - FEEDBACK_PATTERN_HOLD, - /* TOUCH : H/W OR SOFT TOUCH : MULTI TAP */ - FEEDBACK_PATTERN_MULTI_TAP, - /* TOUCH : H/W OR SOFT TOUCH : TAP */ - FEEDBACK_PATTERN_HW_TAP, - /* TOUCH : H/W OR SOFT TOUCH : TAP & HOLD */ - FEEDBACK_PATTERN_HW_HOLD, - - /* OPERATION : POWER ON/OFF */ - FEEDBACK_PATTERN_POWERON, - FEEDBACK_PATTERN_POWEROFF, - /* OPERATION : CHARGECONN */ - FEEDBACK_PATTERN_CHARGERCONN, - /* OPERATION : FULLCHAREGED */ - FEEDBACK_PATTERN_FULLCHARGED, - /* OPERATION : LOW BATTERY */ - FEEDBACK_PATTERN_LOWBATT, - /* OPERATION : LOCK/UNLOCK */ - FEEDBACK_PATTERN_LOCK, - FEEDBACK_PATTERN_UNLOCK, - /* OPERATION : CALL CONNECT/ DISCONNECT */ - FEEDBACK_PATTERN_CALLCONNECT, - FEEDBACK_PATTERN_DISCALLCONNECT, - /* OPERATION : MINUTE MINDER */ - FEEDBACK_PATTERN_MINUTEMINDER, - /* OPERATION : VIBRATION */ - FEEDBACK_PATTERN_VIBRATION, - /* OPERATION : BALLOON MESSAGE SEND/RECV */ - FEEDBACK_PATTERN_NONE, - FEEDBACK_PATTERN_NONE, - /* OPERATION : ON/OFF SLIDER */ - FEEDBACK_PATTERN_NONE, - /* OPERATION : CAMERA SHUTTER / SCREEN CAPTURE */ - FEEDBACK_PATTERN_SHUTTER, - /* OPERATION : LIST RE-ORDER */ - FEEDBACK_PATTERN_LIST_REORDER, - /* OPERATION : LIST SLIDER */ - FEEDBACK_PATTERN_SLIDER_SWEEP, -}; - -feedback_pattern_e feedback_vibration[] = { - /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : GENERAL */ - FEEDBACK_PATTERN_TAP, - /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : TEXT_NUMERIC_INPUT */ - FEEDBACK_PATTERN_SIP, - FEEDBACK_PATTERN_SIP_BACKSPACE, - /* TOUCH : SCREEN TOUCH : TAP(TOUCH & RELEASE) : DAILER */ - FEEDBACK_PATTERN_KEY0, - FEEDBACK_PATTERN_KEY1, - FEEDBACK_PATTERN_KEY2, - FEEDBACK_PATTERN_KEY3, - FEEDBACK_PATTERN_KEY4, - FEEDBACK_PATTERN_KEY5, - FEEDBACK_PATTERN_KEY6, - FEEDBACK_PATTERN_KEY7, - FEEDBACK_PATTERN_KEY8, - FEEDBACK_PATTERN_KEY9, - FEEDBACK_PATTERN_KEY_STAR, - FEEDBACK_PATTERN_KEY_SHARP, - /* TOUCH : H/W OR SOFT TOUCH : HOLD(TAP & HOLD) */ - FEEDBACK_PATTERN_HOLD, - /* TOUCH : H/W OR SOFT TOUCH : MULTI TAP */ - FEEDBACK_PATTERN_MULTI_TAP, - /* TOUCH : H/W OR SOFT TOUCH : TAP */ - FEEDBACK_PATTERN_HW_TAP, - /* TOUCH : H/W OR SOFT TOUCH : TAP & HOLD */ - FEEDBACK_PATTERN_HW_HOLD, - - /* NOTIFICATION : INCOMING : CALL */ - FEEDBACK_PATTERN_NONE, - FEEDBACK_PATTERN_NONE, - FEEDBACK_PATTERN_NONE, - FEEDBACK_PATTERN_NONE, - FEEDBACK_PATTERN_NONE, - FEEDBACK_PATTERN_NONE, - /* NOTIFICATION : INCOMING : MESSAGE */ - FEEDBACK_PATTERN_MESSAGE, - /* NOTIFICATION : INCOMING : EMAIL */ - FEEDBACK_PATTERN_EMAIL, - /* NOTIFICATION : ALARM : WAKEUP */ - FEEDBACK_PATTERN_WAKEUP, - /* NOTIFICATION : ALARM : SCHEDULE */ - FEEDBACK_PATTERN_SCHEDULE, - /* NOTIFICATION : ALARM : TIMER */ - FEEDBACK_PATTERN_TIMER, - /* NOTIFICATION : GENERAL(TICKER/IM/SMS ETC) */ - FEEDBACK_PATTERN_GENERAL, - - /* OPERATION : POWER ON/OFF */ - FEEDBACK_PATTERN_POWERON, - FEEDBACK_PATTERN_POWEROFF, - /* OPERATION : CHARGECONN */ - FEEDBACK_PATTERN_CHARGERCONN, - /* OPERATION : FULLCHAREGED */ - FEEDBACK_PATTERN_FULLCHARGED, - /* OPERATION : LOW BATTERY */ - FEEDBACK_PATTERN_LOWBATT, - /* OPERATION : LOCK/UNLOCK */ - FEEDBACK_PATTERN_LOCK, - FEEDBACK_PATTERN_UNLOCK, - /* OPERATION : CALL CONNECT/ DISCONNECT */ - FEEDBACK_PATTERN_CALLCONNECT, - FEEDBACK_PATTERN_DISCALLCONNECT, - /* OPERATION : MINUTE MINDER */ - FEEDBACK_PATTERN_MINUTEMINDER, - /* OPERATION : VIBRATION */ - FEEDBACK_PATTERN_VIBRATION, - /* OPERATION : BALLOON MESSAGE SEND/RECV */ - FEEDBACK_PATTERN_NONE, - FEEDBACK_PATTERN_NONE, - /* OPERATION : ON/OFF SLIDER */ - FEEDBACK_PATTERN_NONE, - /* OPERATION : CAMERA SHUTTER / SCREEN CAPTURE */ - FEEDBACK_PATTERN_SHUTTER, - /* OPERATION : LIST RE-ORDER */ - FEEDBACK_PATTERN_LIST_REORDER, - /* OPERATION : LIST SLIDER */ - FEEDBACK_PATTERN_SLIDER_SWEEP, -}; - -API int svi_init(int *handle) -{ - int ret = -1; - - if (handle == NULL) { - SVILOG("ERROR!! Invalid parameter : handle(NULL)"); - return SVI_ERROR; - } - - ret = feedback_initialize(); - if (FEEDBACK_FAILED(ret)) { - SVILOG("ERROR!! feedback_initialize is failed"); - return SVI_ERROR; - } - - *handle = SVI_TEMP_HANDLE; - return SVI_SUCCESS; -} - -API int svi_fini(int handle) -{ - int ret = -1; - - if (handle != SVI_TEMP_HANDLE) { - SVILOG("ERROR!! Invalid parameter : handle(%d)", handle); - return SVI_ERROR; - } - - ret = feedback_deinitialize(); - if (FEEDBACK_FAILED(ret)) { - SVILOG("ERROR!! feedback_deinitialize is failed"); - return SVI_ERROR; - } - - return SVI_SUCCESS; -} - -API int svi_play_sound(int handle, sound_type sound_key) -{ - int ret = -1; - feedback_pattern_e pattern = FEEDBACK_PATTERN_NONE; - - if (handle != SVI_TEMP_HANDLE) { - SVILOG("ERROR!! Invalid parameter : handle(%d)", handle); - return SVI_ERROR; - } - - if (sound_key < SVI_SND_NONE || sound_key >= SVI_SND_ENUM_END) { - SVILOG("ERROR!! Invalid parameter : sound_key(%d)", sound_key); - return SVI_ERROR; - } - - if (sound_key == SVI_SND_NONE) { - pattern = FEEDBACK_PATTERN_NONE; - SVILOG("pattern is NONE"); - } else { - pattern = feedback_sound[sound_key]; - SVILOG("sound_key : %d, pattern : %d", sound_key, pattern); - } - - ret = feedback_play_type(FEEDBACK_TYPE_SOUND, pattern); - if (FEEDBACK_FAILED(ret)) { - SVILOG("ERROR!! feedback_play_type is failed"); - return SVI_ERROR; - } - - return SVI_SUCCESS; -} - -API int svi_play_vib(int handle, vibration_type vibration_key) -{ - int ret = -1; - feedback_pattern_e pattern = FEEDBACK_PATTERN_NONE; - - if (handle != SVI_TEMP_HANDLE) { - SVILOG("ERROR!! Invalid parameter : handle(%d)", handle); - return SVI_ERROR; - } - - if (vibration_key < SVI_VIB_NONE || vibration_key >= SVI_VIB_ENUM_END) { - SVILOG("ERROR!! Invalid parameter : sound_key(%d)", vibration_key); - return SVI_ERROR; - } - - if (vibration_key == SVI_VIB_NONE) { - pattern = FEEDBACK_PATTERN_NONE; - SVILOG("pattern is NONE"); - } else { - pattern = feedback_vibration[vibration_key]; - SVILOG("vibration_key : %d, pattern : %d", vibration_key, pattern); - } - - ret = feedback_play_type(FEEDBACK_TYPE_VIBRATION, pattern); - if (FEEDBACK_FAILED(ret)) { - SVILOG("ERROR!! feedback_play_type is failed"); - return SVI_ERROR; - } - - return SVI_SUCCESS; -} - -API int svi_play(int handle, vibration_type vibration_key, sound_type sound_key) -{ - int ret_snd = svi_play_sound(handle, sound_key); - int ret_vib = svi_play_vib(handle, vibration_key); - - if (ret_snd == SVI_ERROR || ret_vib == SVI_ERROR) { - return SVI_ERROR; - } else { - return SVI_SUCCESS; - } -} - -API int svi_set_path(int svi_type, int svi_enum, char* path) -{ - SVILOG("This api is not supported"); - return SVI_ERROR; -} - -API int svi_get_path(int svi_type, int svi_enum, char* buf, unsigned int bufLen) -{ - int ret = -1; - feedback_pattern_e pattern = FEEDBACK_PATTERN_NONE; - char *path = NULL; - - if (svi_type <= SVI_TYPE_NONE || svi_type >= SVI_TYPE_END) { - SVILOG("ERROR!! Invalid parameter : svi_type(%d).", svi_type); - return SVI_ERROR; - } - - if (svi_type == SVI_TYPE_SND) { - if (svi_enum <= SVI_SND_NONE || svi_enum >= SVI_SND_ENUM_END) { - SVILOG("ERROR! invalid svi_enum(%d)", svi_enum); - return SVI_ERROR; - } - - pattern = feedback_sound[svi_enum]; - ret = feedback_get_resource_path(FEEDBACK_TYPE_SOUND, pattern, &path); - } else if (svi_type == SVI_TYPE_VIB) { - if (svi_enum <= SVI_VIB_NONE || svi_enum >= SVI_VIB_ENUM_END) { - SVILOG("ERROR! invalid svi_enum(%d)", svi_enum); - return SVI_ERROR; - } - - pattern = feedback_vibration[svi_enum]; - ret = feedback_get_resource_path(FEEDBACK_TYPE_VIBRATION, pattern, &path); - } - - if (FEEDBACK_FAILED(ret)) { - SVILOG("ERROR!! feedback_play_type is failed"); - return SVI_ERROR; - } - - snprintf(buf, bufLen, "%s", path); - free(path); - - return SVI_SUCCESS; -} diff --git a/src/vibrator.c b/src/vibrator.c index 21897c8..3441fc4 100644 --- a/src/vibrator.c +++ b/src/vibrator.c @@ -19,218 +19,168 @@ #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 <sys/stat.h> #include "feedback-ids.h" #include "common.h" #include "log.h" #include "devices.h" #include "xmlparser.h" +#include "dbus.h" + +#define DEFAULT_VIB_LEVEL 3 +#define HAPTIC_FEEDBACK_STEP 20 /**< feedback max / slider step */ -#define FEEDBACK_HAPTIC_DIR FEEDBACK_DATA_DIR"/haptic" -#define FEEDBACK_HAPTIC_TOUCH_DIR "touch" -#define FEEDBACK_HAPTIC_OPER_DIR "operation" -#define FEEDBACK_HAPTIC_NOTI_DIR "notification" -#define FEEDBACK_HAPTIC_DEFAULT_DIR "default" -#define SCRIPT_INIT_LINK_HAPTIC FEEDBACK_ORIGIN_DATA_DIR"/init_wav_link.sh" -#define MAX_HAPTIC_FILE 50 - -static const char* haptic_file_default[] = { - /* 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 HAPTIC_DEVICE 0 + +enum haptic_priority +{ + HAPTIC_PRIORITY_MIN = 0, + HAPTIC_PRIORITY_MIDDLE, + HAPTIC_PRIORITY_HIGH, }; -static 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) */ - 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) */ - NULL, - /* NOTIFICATION : GENERAL(TICKER/IM/SMS ETC) ALERT ON CALL */ - NULL, - - /* OPERATION : POWER ON/OFF */ - NULL, - NULL, - /* OPERATION : CHARGECONN */ - NULL, - /* OPERATION : CHARGECONN ALERT ON CALL */ - NULL, - /* OPERATION : FULLCHAREGED */ - NULL, - /* OPERATION : FULLCHAREGED ALERT ON CALL */ - NULL, - /* OPERATION : LOW BATTERY */ - NULL, - /* OPERATION : LOW BATTERY ALERT ON CALL */ - NULL, - /* OPERATION : LOCK/UNLOCK */ - NULL, - NULL, - /* OPERATION : CALL CONNECT/ DISCONNECT */ - NULL, - NULL, - /* OPERATION : MINUTE MINDER */ - NULL, - /* OPERATION : VIBRATION */ - NULL, - /* OPERATION : CAMERA SHUTTER / SCREEN CAPTURE */ - NULL, - /* OPERATION : LIST RE-ORDER */ - NULL, - /* OPERATION : LIST SLIDER */ - NULL, - /* OPERATION : VOLUME KEY */ - NULL, +enum haptic_iteration +{ + HAPTIC_ITERATION_ONCE = 1, + HAPTIC_ITERATION_INFINITE = 256, }; #define VIBRATION_XML "/usr/share/feedback/vibration.xml" +#define METHOD_OPEN "OpenDevice" +#define METHOD_CLOSE "CloseDevice" +#define METHOD_VIBRATE_BUFFER "VibrateBuffer" +#define METHOD_STOP "StopDevice" + static int vibstatus; static int vib_level; static int noti_level; -static haptic_device_h v_handle; +static unsigned int v_handle; static xmlDocPtr v_doc; -static void feedback_vibstatus_cb(keynode_t *key, void* data) +static char haptic_file[FEEDBACK_PATTERN_END][NAME_MAX]; + +static int haptic_open(void) +{ + char *arr[1]; + char buf_index[32]; + + snprintf(buf_index, sizeof(buf_index), "%d", HAPTIC_DEVICE); + arr[0] = buf_index; + + return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_HAPTIC, + DEVICED_INTERFACE_HAPTIC, METHOD_OPEN, + "i", arr); +} + +static int haptic_close(unsigned int handle) +{ + char *arr[1]; + char buf_handle[32]; + + snprintf(buf_handle, sizeof(buf_handle), "%u", handle); + arr[0] = buf_handle; + + return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_HAPTIC, + DEVICED_INTERFACE_HAPTIC, METHOD_CLOSE, + "u", arr); +} + +static int haptic_vibrate_buffer(unsigned int handle, + const unsigned char *buffer, + int size, + int iteration, + int feedback, + int priority) { - vibstatus = vconf_keynode_get_bool(key); + char *arr[6]; + char buf_handle[32]; + char buf_iteration[32]; + char buf_feedback[32]; + char buf_priority[32]; + struct dbus_byte bytes; + + snprintf(buf_handle, sizeof(buf_handle), "%u", handle); + arr[0] = buf_handle; + bytes.size = size; + bytes.data = buffer; + arr[2] = (char*)&bytes; + snprintf(buf_iteration, sizeof(buf_iteration), "%d", iteration); + arr[3] = buf_iteration; + snprintf(buf_feedback, sizeof(buf_feedback), "%d", feedback); + arr[4] = buf_feedback; + snprintf(buf_priority, sizeof(buf_priority), "%d", priority); + arr[5] = buf_priority; + + return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_HAPTIC, + DEVICED_INTERFACE_HAPTIC, METHOD_VIBRATE_BUFFER, + "uayiii", arr); +} + +static int haptic_vibrate_stop(unsigned int handle) +{ + char *arr[1]; + char buf_handle[32]; + + snprintf(buf_handle, sizeof(buf_handle), "%u", handle); + arr[0] = buf_handle; + + return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_HAPTIC, + DEVICED_INTERFACE_HAPTIC, METHOD_STOP, + "u", arr); +} + +static unsigned char* convert_file_to_buffer(const char *file_name, int *size) +{ + FILE *pf; + long file_size; + unsigned char *pdata = NULL; + + if (!file_name) + return NULL; + + /* Get File Stream Pointer */ + pf = fopen(file_name, "rb"); + if (!pf) { + _E("fopen failed : %s", strerror(errno)); + return NULL; + } + + if (fseek(pf, 0, SEEK_END)) + goto error; + + file_size = ftell(pf); + if (fseek(pf, 0, SEEK_SET)) + goto error; + + if (file_size < 0) + goto error; + + pdata = (unsigned char*)malloc(file_size); + if (!pdata) + goto error; + + if (fread(pdata, 1, file_size, pf) != file_size) + goto err_free; + + fclose(pf); + *size = file_size; + return pdata; + +err_free: + free(pdata); + +error: + fclose(pf); + + _E("failed to convert file to buffer (%s)", strerror(errno)); + return NULL; } static void feedback_vib_cb(keynode_t *key, void* data) @@ -243,7 +193,7 @@ 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) +static int get_priority(feedback_pattern_e pattern) { if (pattern >= FEEDBACK_PATTERN_TAP && pattern <= FEEDBACK_PATTERN_HW_HOLD) return HAPTIC_PRIORITY_MIN; @@ -255,50 +205,95 @@ 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; + if (pattern >= FEEDBACK_PATTERN_MESSAGE && pattern <= FEEDBACK_PATTERN_SMART_ALERT) + level = noti_level * HAPTIC_FEEDBACK_STEP; else - level = vib_level; + level = vib_level * HAPTIC_FEEDBACK_STEP; _D("Call status : %d, pattern : %s, level : %d", callstatus, str_pattern[pattern], level); - if (callstatus != VCONFKEY_CALL_OFF) { + if (callstatus == VCONFKEY_CALL_VOICE_ACTIVE + || callstatus == VCONFKEY_CALL_VIDEO_ACTIVE) { // if call status is ON, vibration magnitude is 20% - level = (int)(level*0.2f); - level = (level < 1) ? 1 : level; + level = 20; _D("level changed : %d", level); } - level = level * 20; return level; } static bool get_always_alert_case(feedback_pattern_e pattern) { - switch(pattern) { + switch (pattern) { + case FEEDBACK_PATTERN_KEY0 ... FEEDBACK_PATTERN_KEY_BACK: + case FEEDBACK_PATTERN_HOLD: + break; + case FEEDBACK_PATTERN_SIP: + case FEEDBACK_PATTERN_SIP_BACKSPACE: + case FEEDBACK_PATTERN_SIP_FUNCTION: + case FEEDBACK_PATTERN_SIP_FJKEY: + return true; + case FEEDBACK_PATTERN_TIMER: + case FEEDBACK_PATTERN_TIMER_ON_CALL: case FEEDBACK_PATTERN_WAKEUP: case FEEDBACK_PATTERN_WAKEUP_ON_CALL: return true; + case FEEDBACK_PATTERN_MESSAGE_ON_CALL: + case FEEDBACK_PATTERN_EMAIL_ON_CALL: + case FEEDBACK_PATTERN_GENERAL_ON_CALL: + if (alert_callstatus) + return true; + break; + case FEEDBACK_PATTERN_MESSAGE: + case FEEDBACK_PATTERN_EMAIL: + case FEEDBACK_PATTERN_3RD_APPLICATION: + case FEEDBACK_PATTERN_SMART_ALERT: + case FEEDBACK_PATTERN_SEND_SOS_MESSAGE: + case FEEDBACK_PATTERN_END_SOS_MESSAGE: + case FEEDBACK_PATTERN_CMAS: + case FEEDBACK_PATTERN_OUTGOING_CALL: + case FEEDBACK_PATTERN_MMS: + case FEEDBACK_PATTERN_HOURLY_ALERT: + return true; + case FEEDBACK_PATTERN_SPEED_UP: + case FEEDBACK_PATTERN_SLOW_DOWN: + case FEEDBACK_PATTERN_KEEP_THIS_PACE: + case FEEDBACK_PATTERN_GOAL_ACHIEVED: + case FEEDBACK_PATTERN_EXERCISE_COUNT: + case FEEDBACK_PATTERN_START_CUE: + /* except mute case */ + if (is_sound_mode() || vibstatus) + return true; + break; + case FEEDBACK_PATTERN_CHARGERCONN_ON_CALL: + case FEEDBACK_PATTERN_CHARGING_ERROR_ON_CALL: + case FEEDBACK_PATTERN_LOWBATT_ON_CALL: + /* no matter sound profile */ + return true; default: break; } return false; } +static bool get_always_off_case(feedback_pattern_e pattern) +{ + 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) { - _E("xml_find fail"); - return -1; - } + cur = xml_find(doc, VIBRATION_STR, (const xmlChar*)str_pattern[pattern]); + /* This pattern does not have sound file to play */ + if (cur == NULL) + return -ENOENT; retData = xml_parse(doc, cur); if (retData == NULL) { _E("xml_parse fail"); - return -1; + return -EPERM; } *data = retData; @@ -313,91 +308,10 @@ static void release_xml_data(struct xmlData *data) 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)) { - _E("file(%s) is not presents", sym_path); - return -EPERM; - } - - if (unlink(sym_path) < 0) - _D("unlink(%s) : %s", sym_path, strerror(errno)); - - if (symlink(new_path, sym_path) < 0) { - _E("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) { - _E("Invalid parameter : cur_path(NULL)"); - return -EPERM; - } - - temp = strcat(default_path, FEEDBACK_ORIGIN_DATA_DIR); - strcat(temp, cur_path+strlen(FEEDBACK_DATA_DIR)); - _D("default_path : %s", default_path); - - ret = change_symlink(cur_path, default_path); - if (ret < 0) { - _E("change_symlink is failed"); - return -EPERM; - } - - return 0; -} - - -static void link_init(void) -{ - struct stat sts; - int i,ret; - int directory = 0; - char default_path[PATH_MAX] = {0,}; - - /* Check if the directory exists; if not, create it and initialize it */ - ret = stat(FEEDBACK_DATA_DIR, &sts); - if (ret == -1 && errno == ENOENT){ - directory = 1; - } - - /* init of haptic array and link*/ - strcat(default_path, FEEDBACK_ORIGIN_DATA_DIR); - for( i = 0 ; i< MAX_HAPTIC_FILE ; i++){ - if ( haptic_file_default[i] != NULL ){ - haptic_file[i] = strdup(tzplatform_mkpath3(TZ_USER_SHARE,"feedback/haptic",haptic_file_default[i])); - if (directory == 1){ - if (symlink(default_path,haptic_file[i]) < 0){ - _W("change_symlink is failed"); - } - } - } - } -} - static void vibrator_init(void) { int ret; - link_init(); - /* xml Init */ v_doc = xml_open(VIBRATION_XML); if (v_doc == NULL) { @@ -406,17 +320,16 @@ static void vibrator_init(void) } /* Vibration Init */ - ret = haptic_open(HAPTIC_DEVICE_ALL, &v_handle); - if (ret != HAPTIC_ERROR_NONE) { + ret = haptic_open(); + if (ret < 0) { _E("haptic_open ==> 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) - _W("VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL ==> FAIL!!"); + /* Set vibration handle */ + v_handle = (unsigned int)ret; /* check vib_level */ if (vconf_get_int(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, &vib_level) < 0) @@ -427,72 +340,101 @@ static void vibrator_init(void) _W("VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT ==> 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,i; + 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) + if (ret < 0) _E("haptic_close is failed : %d", ret); - v_handle = NULL; + v_handle = 0; } if (v_doc) { xml_close(v_doc); v_doc = NULL; } - - for( i = 0 ; i< MAX_HAPTIC_FILE ; i++) - { - if ( haptic_file[i] != NULL ) { - free (haptic_file[i]); - } - } } static int vibrator_play(feedback_pattern_e pattern) { - int ret; + int ret, size; struct xmlData *data; + char *path; + unsigned char *buf; if (!v_handle || !v_doc) { _E("Not initialize"); return -EPERM; } + if (vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibstatus) < 0) { + _D("fail to get vibration status, will work as turning off"); + vibstatus = 0; + } + if (vibstatus == 0 && !get_always_alert_case(pattern)) { _D("Vibration condition is OFF (vibstatus : %d)", vibstatus); return 0; } + if (vibstatus && get_always_off_case(pattern)) { + _D("Vibration always off condition"); + return 0; + } + + /* if there is a file path user defined */ + path = haptic_file[pattern]; + if (*path) { + buf = convert_file_to_buffer(path, &size); + if (!buf) { + _E("convert_file_to_buffer is failed"); + return -EPERM; + } + + ret = haptic_vibrate_buffer(v_handle, buf, size, HAPTIC_ITERATION_ONCE, + get_haptic_level(pattern), get_priority(pattern)); + if (ret < 0) { + _E("haptic_vibrate_buffer is failed"); + free(buf); + return -EPERM; + } + + free(buf); + return 0; + } + ret = get_xml_data(v_doc, pattern, &data); + if (ret == -ENOENT) { + _D("No vibration case(%s)", str_pattern[pattern]); + return 0; + } + if (ret < 0) { _E("get_xml_data fail"); return -EPERM; } if (data->data == NULL) { - _D("This case(%s) does not play vibration", str_pattern[pattern]); + _D("No vibration case(%s)", 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) { - _E("haptic_vibrate_buffer_with_detail is failed"); + ret = haptic_vibrate_buffer(v_handle, (unsigned char*)data->data, data->size, HAPTIC_ITERATION_ONCE, + get_haptic_level(pattern), get_priority(pattern)); + if (ret < 0) { + _E("haptic_vibrate_buffer is failed"); release_xml_data(data); return -EPERM; } @@ -501,54 +443,65 @@ static int vibrator_play(feedback_pattern_e pattern) return 0; } +static int vibrator_stop(void) +{ + int ret; + + if (!v_handle || !v_doc) { + _E("Not initialize"); + return -EPERM; + } + + /* stop haptic device */ + ret = haptic_vibrate_stop(v_handle); + if (ret < 0) { + _E("haptic_vibrate_stop is failed"); + return -EPERM; + } + + 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) { + if (*cur_path) { _E("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) { - _E("readlink is failed : %s", strerror(errno)); - return -EPERM; - } - } while(retry--); - + snprintf(buf, buflen, "%s", cur_path); 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) { - _E("Invalid parameter : path does not exist"); - return -ENOENT; + struct stat buf; + char *ppath; + + /* + * check the path is valid + * if path is null, below operation is ignored + */ + if (path && stat(path, &buf)) { + _E("%s is not presents", path); + return -errno; } - cur_path = haptic_file[pattern]; - if (cur_path == NULL) { - _E("This pattern(%s) in vibrator type is not supported to play", str_pattern[pattern]); - return -ENOENT; - } + ppath = haptic_file[pattern]; - ret = change_symlink(cur_path, path); - if (ret < 0) { - _E("change_symlink is failed"); - return -EPERM; - } + /* if path is NULL, this pattern set to default file */ + if (path) + snprintf(ppath, NAME_MAX, "%s", path); + else + memset(ppath, 0, NAME_MAX); + _D("The file of pattern(%s) is changed to [%s]", str_pattern[pattern], path); return 0; } @@ -557,6 +510,7 @@ static const struct device_ops vibrator_device_ops = { .init = vibrator_init, .exit = vibrator_exit, .play = vibrator_play, + .stop = vibrator_stop, .get_path = vibrator_get_path, .set_path = vibrator_set_path, }; diff --git a/src/xmlparser.c b/src/xmlparser.c index 672d504..e2b09d2 100644 --- a/src/xmlparser.c +++ b/src/xmlparser.c @@ -18,6 +18,7 @@ #include <stdio.h> #include <assert.h> +#include <errno.h> #include <glib.h> #include "xmlparser.h" @@ -73,7 +74,7 @@ static int xml_compare(xmlDocPtr doc, xmlNodePtr cur, const xmlChar* expr) return 0; } -xmlNodePtr xml_find(xmlDocPtr doc, const xmlChar* expr) +xmlNodePtr xml_find(xmlDocPtr doc, const char *label, const xmlChar* expr) { xmlNodePtr root; xmlNodePtr cur; @@ -88,7 +89,7 @@ xmlNodePtr xml_find(xmlDocPtr doc, const xmlChar* expr) } for (cur = root->children; cur != NULL; cur = cur->next) { - if (xmlStrcmp(cur->name, (const xmlChar*)VIBRATION)) + if (xmlStrcmp(cur->name, (const xmlChar*)label)) continue; if (!xml_compare(doc, cur, expr)) @@ -104,8 +105,6 @@ struct xmlData *xml_parse(xmlDocPtr doc, xmlNodePtr cur) { xmlNodePtr node; struct xmlData *data; - char *b64_data; - unsigned int len; assert(doc); assert(cur); @@ -122,18 +121,31 @@ struct xmlData *xml_parse(xmlDocPtr doc, xmlNodePtr cur) data->label = (char*)xmlNodeListGetString(doc, node->children, 1); _D("label : %s", data->label); } else if (!xmlStrcmp(node->name, (const xmlChar*)data_str[XML_DATA])) { - b64_data = (char *)xmlNodeListGetString(doc, node->children, 1); - if (b64_data != NULL) { - _D("b64_data : %s", b64_data); - data->data = g_base64_decode(b64_data, &len); - xmlFree(b64_data); - } + data->data = (char*)xmlNodeListGetString(doc, node->children, 1); + data->size = strlen(data->data); } } return data; } +int xml_decode_data(struct xmlData *data) +{ + char *decode; + gsize len; + + if (!data || !data->data) + return -EINVAL; + + _D("b64_data : %s", data->data); + decode = (char*)g_base64_decode(data->data, &len); + free(data->data); + + data->data = decode; + data->size = (unsigned int)len; + return 0; +} + int xml_save(xmlDocPtr doc, const char *path) { int r; |