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.
29 #include <mm_sound_private.h>
30 #include <sound_manager.h>
31 #include <wav_player.h>
32 #include <libsyscommon/ini-parser.h>
33 #include <libsyscommon/list.h>
35 #include "feedback-ids.h"
39 #include "feedback-config.h"
40 #include "sound-parser.h"
41 #include "sound-theme-manager.h"
44 #ifndef VCONFKEY_SETAPPL_BUTTON_SOUNDS_BOOL
45 #define VCONFKEY_SETAPPL_BUTTON_SOUNDS_BOOL "db/setting/sound/button_sounds"
49 static int touch_sndstatus;
50 static int keytone_sndstatus;
51 static unsigned int current_theme_id = 0;
53 static char *get_data(feedback_pattern_e pattern)
57 if (pattern <= FEEDBACK_PATTERN_NONE ||
58 pattern >= profile->max_pattern)
61 data = profile->get_path(pattern);
65 data = sound_thememan_get_pattern_sound_path(current_theme_id, pattern);
67 _E("Not supported pattern : %d", pattern);
72 inline int is_sound_mode(void)
77 inline int is_touch_sndstatus(void)
79 return touch_sndstatus;
82 inline int is_keytone_sndstatus(void)
84 return keytone_sndstatus;
87 //LCOV_EXCL_START Not called Callback
88 static void feedback_sndstatus_cb(keynode_t *key, void* data)
90 sndstatus = vconf_keynode_get_bool(key);
93 static void feedback_touch_sndstatus_cb(keynode_t *key, void* data)
95 touch_sndstatus = vconf_keynode_get_bool(key);
98 static void feedback_keytone_sndstatus_cb(keynode_t *key, void* data)
100 keytone_sndstatus = vconf_keynode_get_bool(key);
105 static void feedback_sound_theme_changed_cb(keynode_t *key, void* data)
107 int vconf_sound_theme_id = vconf_keynode_get_int(key);
109 if (vconf_sound_theme_id <= 0) {
110 current_theme_id = 0;
114 current_theme_id = vconf_keynode_get_int(key);
118 static void sound_init(void)
122 current_theme_id = 0;
124 ret = sound_thememan_init();
126 _E("Failed to initialize sound theme manager(%d)", ret);
127 sound_thememan_exit();
130 ret = sound_parser_init();
132 _E("Failed to parsing sound config file(%d)", ret);
133 sound_thememan_exit();
137 sound_thememan_get_default_sound_theme_id(¤t_theme_id);
138 ret = vconf_set_int(VCONFKEY_SETAPPL_ACCESSIBILITY_SOUND_FEEDBACK_THEME, current_theme_id);
140 /* check sound status */
141 if (vconf_get_bool(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, &touch_sndstatus) < 0)
142 _W("VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL ==> FAIL!!"); //LCOV_EXCL_LINE
144 if (vconf_get_bool(VCONFKEY_SETAPPL_BUTTON_SOUNDS_BOOL, &keytone_sndstatus) < 0)
145 _W("VCONFKEY_SETAPPL_BUTTON_SOUNDS_BOOL ==> FAIL!!"); //LCOV_EXCL_LINE
147 if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sndstatus) < 0) {
148 _D("fail to get sound status, will work as turning off"); //LCOV_EXCL_LINE
149 sndstatus = 0; //LCOV_EXCL_LINE
152 /* add watch for status value */
153 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, feedback_sndstatus_cb, NULL);
155 _W("Add watch for VCONFKEY_SETAPPL_SOUND_STATUS_BOOL failed"); //LCOV_EXCL_LINE
156 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, feedback_touch_sndstatus_cb, NULL);
158 _W("Add watch for VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL failed"); //LCOV_EXCL_LINE
159 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_BUTTON_SOUNDS_BOOL, feedback_keytone_sndstatus_cb, NULL);
161 _W("Add watch for VCONFKEY_SETAPPL_BUTTON_SOUNDS_BOOL failed"); //LCOV_EXCL_LINE
162 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_SOUND_FEEDBACK_THEME, feedback_sound_theme_changed_cb, NULL);
164 _W("Add watch for VCONFKEY_SETAPPL_ACCESSIBILITY_SOUND_FEEDBACK_THEME failed"); //LCOV_EXCL_LINE
167 static void sound_exit(void)
172 sound_thememan_exit();
175 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, feedback_sndstatus_cb);
177 _W("Remove watch for VCONFKEY_SETAPPL_SOUND_STATUS_BOOL failed"); //LCOV_EXCL_LINE
179 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, feedback_touch_sndstatus_cb);
181 _W("Remove watch for VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL failed"); //LCOV_EXCL_LINE
182 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_BUTTON_SOUNDS_BOOL, feedback_keytone_sndstatus_cb);
184 _W("Remove watch for VCONFKEY_SETAPPL_BUTTON_SOUNDS_BOOL failed"); //LCOV_EXCL_LINE
185 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_SOUND_FEEDBACK_THEME, feedback_sound_theme_changed_cb);
187 _W("Remove watch for VCONFKEY_SETAPPL_ACCESSIBILITY_SOUND_FEEDBACK_THEME failed"); //LCOV_EXCL_LINE
192 static void play_completed(int id, void *data)
195 sound_stream_info_h stream_info = (sound_stream_info_h)data;
197 ret = sound_manager_destroy_stream_information(stream_info);
198 if (ret != SOUND_MANAGER_ERROR_NONE)
199 _E("Failed to set session to play sound(%d)", ret); //LCOV_EXCL_LINE
203 static int sound_play(feedback_pattern_e pattern, bool always)
206 int retry = FEEDBACK_RETRY_CNT, ret;
207 sound_stream_info_h stream_info;
211 if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sndstatus) < 0) {
212 _D("fail to get sound status, will work as turning off"); //LCOV_EXCL_LINE
213 sndstatus = 0; //LCOV_EXCL_LINE
217 _W("Always on condition(pattern %s)", profile->str_pattern(pattern)); //LCOV_EXCL_LINE
221 if (sndstatus == 0 && profile->get_always_alert_case &&
222 !profile->get_always_alert_case(FEEDBACK_TYPE_SOUND, pattern)) {
223 _D("Sound condition is OFF (sndstatus : %d)", sndstatus); //LCOV_EXCL_LINE
227 if (sndstatus && profile->get_always_off_case &&
228 profile->get_always_off_case(FEEDBACK_TYPE_SOUND, pattern)) {
229 _D("Sound always off condition(pattern %s)", profile->str_pattern(pattern)); //LCOV_EXCL_LINE
234 /* get sound file path */
235 path = get_data(pattern);
236 if (!path || stat(path, &buf)) {
238 _E("Not supported sound pattern(pattern %d)", pattern); //LCOV_EXCL_LINE
243 /* play sound file */
244 if (profile->is_notification_type && profile->is_notification_type(pattern)) {
245 ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_NOTIFICATION,
246 NULL, NULL, &stream_info);
247 if (ret != SOUND_MANAGER_ERROR_NONE) {
249 _E("Failed to set session to play sound(%d)", ret);
254 ret = wav_player_start_new(path, stream_info, play_completed, stream_info, NULL);
255 if (ret == WAV_PLAYER_ERROR_NONE) {
256 _D("Wav Play success! SND filename is %s", path); //LCOV_EXCL_LINE
259 _E("Failed to play sound file (%d, %s)", ret, path); //LCOV_EXCL_LINE
260 } while (retry--); //LCOV_EXCL_LINE
263 if (profile->get_strength_type)
264 level = profile->get_strength_type(FEEDBACK_TYPE_SOUND, pattern);
266 level = VOLUME_TYPE_SYSTEM;
268 ret = mm_sound_play_keysound(path, level);
269 if (ret == MM_ERROR_NONE) {
270 _D("Play success! %s(%s)", profile->str_pattern(pattern), path);
273 _E("mm_sound_play_keysound() returned error(%d)", ret); //LCOV_EXCL_LINE
274 } while (retry--); //LCOV_EXCL_LINE
280 static int sound_play_path(feedback_pattern_e pattern, const char *soundpath, bool always)
283 int retry = FEEDBACK_RETRY_CNT, ret;
284 sound_stream_info_h stream_info;
287 if (!soundpath || stat(soundpath, &buf)) {
288 if (!soundpath) //LCOV_EXCL_LINE
289 _E("Not supported sound pattern(pattern %d)", pattern); //LCOV_EXCL_LINE
291 _E("Not supported sound pattern(soundpath %s of pattern %s)", soundpath, profile->str_pattern(pattern)); //LCOV_EXCL_LINE
292 return -ENOTSUP; //LCOV_EXCL_LINE
295 if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sndstatus) < 0) {
296 _D("fail to get sound status, will work as turning off"); //LCOV_EXCL_LINE
297 sndstatus = 0; //LCOV_EXCL_LINE
301 _W("Always on condition(pattern %s)", profile->str_pattern(pattern)); //LCOV_EXCL_LINE
305 if (sndstatus == 0 && profile->get_always_alert_case &&
306 !profile->get_always_alert_case(FEEDBACK_TYPE_SOUND, pattern)) {
307 _D("Sound condition is OFF (sndstatus : %d)", sndstatus); //LCOV_EXCL_LINE
311 if (sndstatus && profile->get_always_off_case &&
312 profile->get_always_off_case(FEEDBACK_TYPE_SOUND, pattern)) {
313 _D("Sound always off condition(pattern %s)", profile->str_pattern(pattern)); //LCOV_EXCL_LINE
318 /* play sound file */
319 if (profile->is_notification_type && profile->is_notification_type(pattern)) {
320 ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_NOTIFICATION,
321 NULL, NULL, &stream_info);
322 if (ret != SOUND_MANAGER_ERROR_NONE) {
323 _E("Failed to set session to play sound(%d)", ret); //LCOV_EXCL_LINE
327 ret = wav_player_start_new(soundpath, stream_info, play_completed, stream_info, NULL);
328 if (ret == WAV_PLAYER_ERROR_NONE) {
329 _D("Wav Play success! SND filename is %s", soundpath); //LCOV_EXCL_LINE
330 return 0; //LCOV_EXCL_LINE
332 _E("Failed to play sound file (%d, %s)", ret, soundpath); //LCOV_EXCL_LINE
333 } while (retry--); //LCOV_EXCL_LINE
336 if (profile->get_strength_type)
337 level = profile->get_strength_type(FEEDBACK_TYPE_SOUND, pattern);
339 level = VOLUME_TYPE_SYSTEM;
341 ret = mm_sound_play_keysound(soundpath, level);
342 if (ret == MM_ERROR_NONE) {
343 _D("Play success! %s(%s)", profile->str_pattern(pattern), soundpath);
346 _E("mm_sound_play_keysound(\'%s\') returned error(%d)", soundpath, ret); //LCOV_EXCL_LINE
347 } while (retry--); //LCOV_EXCL_LINE
353 static int sound_is_supported(feedback_pattern_e pattern, bool *supported)
360 _E("Invalid parameter : supported(NULL)"); //LCOV_EXCL_LINE
361 return -EINVAL; //LCOV_EXCL_LINE
364 /* get sound file path */
365 path = get_data(pattern);
366 if (!path || stat(path, &buf)) {
367 _D("%d is not presents", pattern);
375 static int sound_stop(void)
380 * @param filename [in] keytone filename to stop (can be null if whole exist keytones needs stops)
381 * int mm_sound_stop_keysound(const char *filename);
383 ret = mm_sound_stop_keysound(NULL);
384 if (ret == MM_ERROR_NONE) {
388 _E("mm_sound_stop_keysound() returned error(%d)", ret); //LCOV_EXCL_LINE
389 return ret; //LCOV_EXCL_LINE
392 //LCOV_EXCL_START Not used function
393 static int sound_get_path(feedback_pattern_e pattern, char *buf, unsigned int buflen)
398 if (!buf || buflen == 0)
401 /* get sound file path */
402 cur_path = get_data(pattern);
404 _E("This pattern(%s) in sound type is not supported to play",
405 profile->str_pattern(pattern));
410 snprintf(buf, buflen, "%s", cur_path);
416 static int sound_get_count_of_theme(unsigned int *count_of_theme)
422 ret = sound_thememan_get_number_of_theme(count_of_theme);
430 static int sound_get_theme_id(unsigned int *id_of_theme)
435 *id_of_theme = current_theme_id;
441 static int sound_set_theme_id(unsigned int id_of_theme)
445 if (!sound_thememan_is_sound_theme_id_exist(id_of_theme))
448 ret = vconf_set_int(VCONFKEY_SETAPPL_ACCESSIBILITY_SOUND_FEEDBACK_THEME, id_of_theme);
450 _E("Failed to set vconf value for VCONFKEY_SETAPPL_ACCESSIBILITY_SOUND_FEEDBACK_THEME");
454 current_theme_id = id_of_theme;
460 static int sound_get_theme_ids(unsigned int *count_of_theme, unsigned int **theme_ids)
464 if (!count_of_theme || !theme_ids)
467 ret = sound_thememan_get_sound_theme_ids(count_of_theme, theme_ids);
474 static const struct device_ops sound_device_ops = {
475 .type = FEEDBACK_TYPE_SOUND,
480 .play_path = sound_play_path,
482 .is_supported = sound_is_supported,
483 .get_path = sound_get_path,
485 .get_count_of_theme = sound_get_count_of_theme,
486 .get_theme_id = sound_get_theme_id,
487 .set_theme_id = sound_set_theme_id,
488 .get_theme_ids = sound_get_theme_ids,
491 DEVICE_OPS_REGISTER(&sound_device_ops);