3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
28 #include <mm_sound_private.h>
30 #include "feedback-ids.h"
34 #include "xmlparser.h"
36 #define SOUND_XML "/usr/share/feedback/sound.xml"
39 static int touch_sndstatus;
40 static int lock_sndstatus;
41 static int keytone_sndstatus;
42 static int camerastatus;
43 static int shutter_sndstatus;
45 static xmlDocPtr v_doc;
47 static char sound_file[FEEDBACK_PATTERN_END][NAME_MAX];
49 inline int is_sound_mode(void)
54 static void feedback_touch_sndstatus_cb(keynode_t *key, void* data)
56 touch_sndstatus = vconf_keynode_get_bool(key);
59 static void feedback_lock_sndstatus_cb(keynode_t *key, void* data)
61 lock_sndstatus = vconf_keynode_get_bool(key);
64 static void feedback_keytone_sndstatus_cb(keynode_t *key, void* data)
66 keytone_sndstatus = vconf_keynode_get_bool(key);
69 static void feedback_camerastatus_cb(keynode_t *key, void* data)
71 camerastatus = vconf_keynode_get_int(key);
74 static volume_type_t get_volume_type(feedback_pattern_e pattern)
76 if (pattern == FEEDBACK_PATTERN_TAP)
77 return VOLUME_TYPE_SYSTEM|VOLUME_GAIN_TOUCH;
78 else if (pattern >= FEEDBACK_PATTERN_KEY0 && pattern <= FEEDBACK_PATTERN_KEY_BACK)
79 return VOLUME_TYPE_SYSTEM|VOLUME_GAIN_DIALER;
80 else if (pattern == FEEDBACK_PATTERN_VOLUME_KEY)
81 return VOLUME_TYPE_RINGTONE;
82 else if (camerastatus && shutter_sndstatus && pattern == FEEDBACK_PATTERN_SCREEN_CAPTURE)
83 return VOLUME_TYPE_FIXED;
85 return VOLUME_TYPE_SYSTEM;
88 static bool get_always_alert_case(feedback_pattern_e pattern)
91 case FEEDBACK_PATTERN_WAKEUP:
92 case FEEDBACK_PATTERN_WAKEUP_ON_CALL:
94 case FEEDBACK_PATTERN_MESSAGE_ON_CALL:
95 case FEEDBACK_PATTERN_EMAIL_ON_CALL:
96 case FEEDBACK_PATTERN_GENERAL_ON_CALL:
100 case FEEDBACK_PATTERN_SMART_ALERT:
101 case FEEDBACK_PATTERN_SEND_SOS_MESSAGE:
102 case FEEDBACK_PATTERN_END_SOS_MESSAGE:
103 case FEEDBACK_PATTERN_CMAS:
105 case FEEDBACK_PATTERN_SCREEN_CAPTURE:
106 if (camerastatus && shutter_sndstatus)
109 case FEEDBACK_PATTERN_OUTGOING_CALL:
117 static bool get_always_off_case(feedback_pattern_e pattern)
120 case FEEDBACK_PATTERN_TAP ... FEEDBACK_PATTERN_MAX_CHARACTER:
121 case FEEDBACK_PATTERN_HOLD ... FEEDBACK_PATTERN_HW_HOLD:
122 if (!touch_sndstatus)
125 case FEEDBACK_PATTERN_KEY0 ... FEEDBACK_PATTERN_KEY_BACK:
126 if (!keytone_sndstatus)
129 case FEEDBACK_PATTERN_LOCK:
130 case FEEDBACK_PATTERN_UNLOCK:
131 case FEEDBACK_PATTERN_LOCK_SWIPE:
132 case FEEDBACK_PATTERN_UNLOCK_SWIPE:
142 static int get_xml_data(xmlDocPtr doc, feedback_pattern_e pattern, struct xmlData **data)
145 struct xmlData *retData;
147 cur = xml_find(doc, SOUND_STR, (const xmlChar*)str_pattern[pattern]);
148 /* This pattern does not have sound file to play */
152 retData = xml_parse(doc, cur);
153 if (retData == NULL) {
154 _E("xml_parse fail");
162 static void release_xml_data(struct xmlData *data)
170 static void sound_init(void)
173 v_doc = xml_open(SOUND_XML);
175 _E("xml_open(%s) fail", SOUND_XML);
179 /* check sound status */
180 if (vconf_get_bool(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, &touch_sndstatus) < 0)
181 _W("VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL ==> FAIL!!");
183 if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_LOCK_BOOL, &lock_sndstatus) < 0)
184 _W("VCONFKEY_SETAPPL_SOUND_LOCK_BOOL ==> FAIL!!");
186 if (vconf_get_bool(VCONFKEY_SETAPPL_BUTTON_SOUNDS_BOOL, &keytone_sndstatus) < 0)
187 _W("VCONFKEY_SETAPPL_BUTTON_SOUNDS_BOOL ==> FAIL!!");
189 /* check camera status */
190 if (vconf_get_int(VCONFKEY_CAMERA_STATE, &camerastatus) < 0)
191 _W("VCONFKEY_CAMERA_STATE ==> FAIL!!");
193 /* shutter sound policy */
194 // This vconf is read just once, because this value is not changed in running time.
195 if (vconf_get_int(VCONFKEY_CAMERA_SHUTTER_SOUND_POLICY, &shutter_sndstatus) < 0)
196 _W("VCONFKEY_CAMERA_SHUTTER_SOUND_POLICY ==> FAIL!!");
198 /* add watch for status value */
199 vconf_notify_key_changed(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, feedback_touch_sndstatus_cb, NULL);
200 vconf_notify_key_changed(VCONFKEY_SETAPPL_SOUND_LOCK_BOOL, feedback_lock_sndstatus_cb, NULL);
201 vconf_notify_key_changed(VCONFKEY_SETAPPL_BUTTON_SOUNDS_BOOL, feedback_keytone_sndstatus_cb, NULL);
202 vconf_notify_key_changed(VCONFKEY_CAMERA_STATE, feedback_camerastatus_cb, NULL);
205 static void sound_exit(void)
208 vconf_ignore_key_changed(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, feedback_touch_sndstatus_cb);
209 vconf_ignore_key_changed(VCONFKEY_SETAPPL_SOUND_LOCK_BOOL, feedback_lock_sndstatus_cb);
210 vconf_ignore_key_changed(VCONFKEY_SETAPPL_BUTTON_SOUNDS_BOOL, feedback_keytone_sndstatus_cb);
211 vconf_ignore_key_changed(VCONFKEY_CAMERA_STATE, feedback_camerastatus_cb);
219 static int sound_play(feedback_pattern_e pattern)
222 int retry = FEEDBACK_RETRY_CNT, ret;
224 struct xmlData *data = NULL;
227 _E("Not initialize");
231 if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sndstatus) < 0) {
232 _D("fail to get sound status, will work as turning off");
236 if (sndstatus == 0 && !get_always_alert_case(pattern)) {
237 _D("Sound condition is OFF (sndstatus : %d)", sndstatus);
241 if (sndstatus && get_always_off_case(pattern)) {
242 _D("Sound always off condition");
246 /* check if the state of voice recorder is recording */
247 if (vconf_get_int(VCONFKEY_SOUND_STATUS, &ret) < 0) {
248 _D("fail to get media sound status, status will be zero");
252 if (ret & VCONFKEY_SOUND_STATUS_AVRECORDING) {
253 _D("voice recording status is RECORDING");
257 /* check whether there is a user defined file */
258 path = sound_file[pattern];
262 ret = get_xml_data(v_doc, pattern, &data);
263 if (ret == -ENOENT) {
264 _D("No sound case(%s)", str_pattern[pattern]);
269 _E("get_xml_data fail");
274 _D("No sound case(%s)", str_pattern[pattern]);
275 release_xml_data(data);
282 if (stat(path, &buf)) {
283 _E("%s is not presents", path);
284 release_xml_data(data);
288 /* play sound file */
290 ret = mm_sound_play_keysound(path, get_volume_type(pattern));
291 if (ret == MM_ERROR_NONE) {
292 _D("Play success! SND filename is %s", path);
293 release_xml_data(data);
296 _E("mm_sound_play_keysound() returned error(%d)", ret);
299 release_xml_data(data);
303 static int sound_get_path(feedback_pattern_e pattern, char *buf, unsigned int buflen)
307 struct xmlData *data = NULL;
309 if (!buf || buflen <= 0)
312 cur_path = sound_file[pattern];
313 if (!strncmp(cur_path, "", 1)) {
314 ret = get_xml_data(v_doc, pattern, &data);
315 if (ret >= 0 && data && data->data)
316 cur_path = (char*)data->data;
320 _E("This pattern(%s) in sound type is not supported to play", str_pattern[pattern]);
325 snprintf(buf, buflen, "%s", cur_path);
326 release_xml_data(data);
330 static int sound_set_path(feedback_pattern_e pattern, char *path)
336 * check the path is valid
337 * if path is null, below operation is ignored
339 if (path && stat(path, &buf)) {
340 _E("%s is not presents", path);
344 ppath = sound_file[pattern];
346 /* if path is NULL, this pattern set to default file */
348 snprintf(ppath, NAME_MAX, "%s", path);
350 memset(ppath, 0, NAME_MAX);
352 _D("The file of pattern(%s) is changed to [%s]", str_pattern[pattern], path);
356 static const struct device_ops sound_device_ops = {
357 .type = FEEDBACK_TYPE_SOUND,
361 .get_path = sound_get_path,
362 .set_path = sound_set_path,
365 DEVICE_OPS_REGISTER(&sound_device_ops);