2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "sound_manager.h"
18 #include "sound_manager_private.h"
19 #include <system_info.h>
21 #define FEATURE_MICROPHONE "http://tizen.org/feature/microphone"
23 _session_interrupt_info_s g_session_interrupt_cb_table = {0, 0, NULL, NULL};
24 _volume_changed_info_s g_volume_changed_cb_table = {0, NULL, NULL};
25 _device_connected_info_s g_device_connected_cb_table = {0, NULL, NULL};
26 _device_changed_info_s g_device_info_changed_cb_table = {0, NULL, NULL};
27 _focus_watch_info_s focus_watch_info_arr[SOUND_STREAM_INFO_ARR_MAX];
29 sound_session_type_e g_cached_session = -1;
30 _session_mode_e g_cached_session_mode = -1;
31 int g_cached_voip_device_id = -1;
32 extern sound_stream_info_s *g_voip_stream_info;
33 extern virtual_sound_stream_info_s *g_voip_vstream_h;
35 /* These variables will be removed when session features are deprecated. */
36 extern int g_stream_info_count;
37 extern pthread_mutex_t g_stream_info_count_mutex;
38 pthread_mutex_t g_interrupt_cb_mutex, g_device_info_cb_mutex, g_device_conn_cb_mutex, g_volume_cb_mutex;
40 int sound_manager_get_max_volume(sound_type_e type, int *max)
42 const char *volume_type = NULL;
43 unsigned int max_level = 0;
44 int ret = MM_ERROR_NONE;
46 SM_NULL_ARG_CHECK(max);
47 if (type >= SOUND_TYPE_NUM || type < 0)
48 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
50 ret = _convert_sound_type(type, &volume_type);
51 if (ret == MM_ERROR_NONE) {
52 ret = _get_volume_max_level(DIRECTION_OUT_STR, volume_type, &max_level);
53 if (ret == MM_ERROR_NONE)
54 *max = (int)max_level -1; /* actual volume step can be max step - 1 */
57 return _convert_sound_manager_error_code(__func__, ret);
60 int sound_manager_set_volume(sound_type_e type, int volume)
62 int ret = MM_ERROR_NONE;
64 if (type >= SOUND_TYPE_NUM || type < 0)
65 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
67 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
69 ret = mm_sound_volume_set_value(type, volume);
70 LOGI("type=%d, volume=%d", type, volume);
72 return _convert_sound_manager_error_code(__func__, ret);
75 int sound_manager_get_volume(sound_type_e type, int *volume)
77 int ret = MM_ERROR_NONE;
80 if (type >= SOUND_TYPE_NUM || type < 0)
81 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
83 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
85 ret = mm_sound_volume_get_value(type, &uvolume);
86 if (ret == MM_ERROR_NONE)
89 LOGI("type=%d, volume=%d", type, *volume);
91 return _convert_sound_manager_error_code(__func__, ret);
94 int sound_manager_set_current_sound_type(sound_type_e type)
96 int ret = MM_ERROR_NONE;
98 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
99 if (type >= SOUND_TYPE_NUM || type < 0)
100 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
102 ret = mm_sound_volume_primary_type_set(type);
104 return _convert_sound_manager_error_code(__func__, ret);
107 int sound_manager_get_current_sound_type(sound_type_e *type)
109 int ret = MM_ERROR_NONE;
110 volume_type_t mm_sound_vol_type = VOLUME_TYPE_UNKNOWN;
111 char *volume_type = NULL;
114 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
116 ret = mm_sound_volume_primary_type_get(&mm_sound_vol_type);
117 if (ret == MM_ERROR_NONE) {
118 if (mm_sound_vol_type == VOLUME_TYPE_UNKNOWN) {
119 /* get the volume type of the current playing stream */
120 ret = _get_current_volume_type(DIRECTION_OUT_STR, &volume_type);
121 if (ret == MM_ERROR_NONE)
122 ret = _convert_sound_type_to_enum((const char*)volume_type, type);
124 *type = mm_sound_vol_type;
127 LOGI("type=%d", *type);
129 return _convert_sound_manager_error_code(__func__, ret);
132 int sound_manager_unset_current_sound_type(void)
134 int ret = MM_ERROR_NONE;
136 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
137 ret = mm_sound_volume_primary_type_set(VOLUME_TYPE_UNKNOWN);
139 return _convert_sound_manager_error_code(__func__, ret);
142 int sound_manager_set_volume_changed_cb(sound_manager_volume_changed_cb callback, void* user_data)
144 int ret = MM_ERROR_NONE;
145 unsigned int subs_id = 0;
147 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_volume_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
149 ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data, &subs_id);
150 if (ret == MM_ERROR_NONE) {
151 g_volume_changed_cb_table.subs_id = subs_id;
152 g_volume_changed_cb_table.user_cb = (sound_manager_volume_changed_cb)callback;
153 g_volume_changed_cb_table.user_data = user_data;
156 SM_LEAVE_CRITICAL_SECTION(&g_volume_cb_mutex);
158 return _convert_sound_manager_error_code(__func__, ret);
161 int sound_manager_unset_volume_changed_cb(void)
163 int ret = MM_ERROR_NONE;
165 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_volume_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
167 if (g_volume_changed_cb_table.subs_id > 0) {
168 ret = mm_sound_remove_volume_changed_callback(g_volume_changed_cb_table.subs_id);
169 if (ret == MM_ERROR_NONE) {
170 g_volume_changed_cb_table.subs_id = 0;
171 g_volume_changed_cb_table.user_cb = NULL;
172 g_volume_changed_cb_table.user_data = NULL;
175 ret = MM_ERROR_SOUND_INTERNAL;
178 SM_LEAVE_CRITICAL_SECTION(&g_volume_cb_mutex);
180 return _convert_sound_manager_error_code(__func__, ret);
183 int sound_manager_create_stream_information(sound_stream_type_e stream_type, sound_stream_focus_state_changed_cb callback, void *user_data, sound_stream_info_h *stream_info)
185 int ret = MM_ERROR_NONE;
189 SM_NULL_ARG_CHECK(stream_info);
191 if (g_session_interrupt_cb_table.is_registered)
192 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INTERNAL);
194 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, MM_ERROR_SOUND_INTERNAL);
196 sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s));
198 ret = MM_ERROR_OUT_OF_MEMORY;
202 memset(stream_h, 0, sizeof(sound_stream_info_s));
203 ret = _convert_stream_type(stream_type, &stream_h->stream_type);
204 if (ret == MM_ERROR_NONE) {
205 ret = _make_pa_connection_and_register_focus(stream_h, callback, user_data);
206 if (ret == MM_ERROR_NONE) {
207 *stream_info = (sound_stream_info_h)stream_h;
208 SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret);
209 LOGI("stream_h(%p), index(%u), user_cb(%p), cnt(%d), ret(0x%x)", stream_h, stream_h->index, stream_h->user_cb, g_stream_info_count, ret);
217 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
219 return _convert_sound_manager_error_code(__func__, ret);
222 int sound_manager_destroy_stream_information(sound_stream_info_h stream_info)
224 int ret = MM_ERROR_NONE;
225 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
229 SM_INSTANCE_CHECK(stream_h);
231 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, MM_ERROR_SOUND_INTERNAL);
232 ret = _destroy_pa_connection_and_unregister_focus(stream_h);
233 if (ret == MM_ERROR_NONE) {
236 SM_UNREF_FOR_STREAM_INFO(g_stream_info_count);
238 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
240 LOGD("cnt(%d)", g_stream_info_count);
242 return _convert_sound_manager_error_code(__func__, ret);
245 int sound_manager_get_sound_type(sound_stream_info_h stream_info, sound_type_e *sound_type)
247 int ret = MM_ERROR_NONE;
248 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
252 SM_INSTANCE_CHECK(stream_h);
253 SM_NULL_ARG_CHECK(sound_type);
255 if (stream_h->stream_conf_info.volume_type == NULL) {
256 ret = MM_ERROR_SOUND_NO_DATA;
260 ret = _convert_sound_type_to_enum(stream_h->stream_conf_info.volume_type, sound_type);
261 LOGI("sound type(%d)", *sound_type);
264 return _convert_sound_manager_error_code(__func__, ret);
267 int sound_manager_add_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
269 int ret = MM_ERROR_NONE;
270 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
274 ret = _add_device_for_stream_routing(stream_h, device);
276 return _convert_sound_manager_error_code(__func__, ret);
279 int sound_manager_remove_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
281 int ret = MM_ERROR_NONE;
282 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
286 ret = _remove_device_for_stream_routing(stream_h, device);
288 return _convert_sound_manager_error_code(__func__, ret);
291 int sound_manager_apply_stream_routing(sound_stream_info_h stream_info)
293 int ret = MM_ERROR_NONE;
294 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
298 ret = _apply_stream_routing(stream_h);
300 return _convert_sound_manager_error_code(__func__, ret);
303 int sound_manager_set_focus_reacquisition(sound_stream_info_h stream_info, bool enable)
305 int ret = MM_ERROR_NONE;
306 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
310 SM_INSTANCE_CHECK(stream_h);
312 ret = mm_sound_set_focus_reacquisition(stream_h->index, enable);
314 return _convert_sound_manager_error_code(__func__, ret);
317 int sound_manager_get_focus_reacquisition(sound_stream_info_h stream_info, bool *enabled)
319 int ret = MM_ERROR_NONE;
320 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
324 SM_INSTANCE_CHECK(stream_h);
325 SM_NULL_ARG_CHECK(enabled);
327 ret = mm_sound_get_focus_reacquisition(stream_h->index, enabled);
329 return _convert_sound_manager_error_code(__func__, ret);
332 int sound_manager_acquire_focus(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *extra_info)
334 int ret = MM_ERROR_NONE;
335 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
339 SM_INSTANCE_CHECK(stream_h);
341 if (stream_h->is_focus_unavailable) {
342 LOGE("acquiring focus is not allowed for this strema type(%s)", stream_h->stream_type);
343 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
346 if (stream_h->user_cb == NULL) {
347 LOGE("focus state changed callback should be set before acquiring focus");
348 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
351 ret = mm_sound_acquire_focus_with_option(stream_h->index, (mm_sound_focus_type_e)focus_mask, stream_h->requesting_flags, extra_info);
352 if (ret == MM_ERROR_NONE) {
353 stream_h->acquired_focus |= focus_mask;
354 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
357 return _convert_sound_manager_error_code(__func__, ret);
360 int sound_manager_release_focus(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, const char *extra_info)
362 int ret = MM_ERROR_NONE;
363 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
367 SM_INSTANCE_CHECK(stream_h);
369 ret = mm_sound_release_focus_with_option(stream_h->index, (mm_sound_focus_type_e)focus_mask, stream_h->requesting_flags, extra_info);
370 if (ret == MM_ERROR_NONE) {
371 stream_h->acquired_focus &= ~focus_mask;
372 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
375 return _convert_sound_manager_error_code(__func__, ret);
378 int sound_manager_get_focus_state(sound_stream_info_h stream_info, sound_stream_focus_state_e *state_for_playback, sound_stream_focus_state_e *state_for_recording)
380 int ret = MM_ERROR_NONE;
381 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
385 SM_INSTANCE_CHECK(stream_h);
386 if (!state_for_playback && !state_for_recording) {
387 ret = MM_ERROR_INVALID_ARGUMENT;
391 if (state_for_playback)
392 *state_for_playback = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
393 if (state_for_recording)
394 *state_for_recording = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
396 LOGI("acquired_focus(0x%x)", stream_h->acquired_focus);
399 return _convert_sound_manager_error_code(__func__, ret);
402 int sound_manager_focus_set_requesting_behavior(sound_stream_info_h stream_info, int flags)
404 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
408 SM_INSTANCE_CHECK(stream_h);
409 SM_RANGE_ARG_CHECK(flags,
411 (SOUND_BEHAVIOR_NO_RESUME|SOUND_BEHAVIOR_FADING));
413 stream_h->requesting_flags = flags;
415 LOGI("the requesting sound behavior(0x%x) is set", stream_h->requesting_flags);
417 return SOUND_MANAGER_ERROR_NONE;
420 int sound_manager_focus_get_requesting_behavior(sound_stream_info_h stream_info, int *flags)
422 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
426 SM_INSTANCE_CHECK(stream_h);
427 SM_NULL_ARG_CHECK(flags);
429 *flags = stream_h->requesting_flags;
431 LOGI("the requesting sound behavior is (0x%x)", stream_h->requesting_flags);
433 return SOUND_MANAGER_ERROR_NONE;
436 int sound_manager_focus_get_requested_behavior(sound_stream_info_h stream_info, int *flags)
438 int ret = MM_ERROR_NONE;
439 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
440 bool is_focus_cb_thread = false;
444 SM_INSTANCE_CHECK(stream_h);
445 SM_NULL_ARG_CHECK(flags);
447 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
448 _convert_sound_manager_error_code(__func__, ret);
450 if (!is_focus_cb_thread) {
451 LOGE("this API should be called in focus state changed callback");
452 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
455 *flags = stream_h->requested_flags;
457 LOGI("requested sound behavior is (0x%x)", stream_h->requested_flags);
459 return SOUND_MANAGER_ERROR_NONE;
462 int sound_manager_get_current_playback_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
464 int ret = MM_ERROR_NONE;
465 char *stream_type_str = NULL;
466 char *extra_info_str = NULL;
468 bool is_focus_cb_thread = false;
472 SM_NULL_ARG_CHECK(acquired_by);
473 SM_NULL_ARG_CHECK(flags);
475 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
476 _convert_sound_manager_error_code(__func__, ret);
478 if (is_focus_cb_thread) {
479 LOGE("this API should not be called in focus callback");
480 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
483 ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_PLAYBACK, &stream_type_str, &option, &extra_info_str);
484 if (ret == MM_ERROR_NONE) {
485 LOGI("current acquired PLAYBACK focus : stream_type[%s]", stream_type_str);
486 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
487 if (ret == MM_ERROR_NONE) {
488 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
491 *extra_info = extra_info_str;
493 free(extra_info_str);
497 return _convert_sound_manager_error_code(__func__, ret);
500 int sound_manager_get_current_recording_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
502 int ret = MM_ERROR_NONE;
503 char *stream_type_str = NULL;
504 char *extra_info_str = NULL;
506 bool is_focus_cb_thread = false;
510 SM_NULL_ARG_CHECK(acquired_by);
511 SM_NULL_ARG_CHECK(flags);
513 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
514 _convert_sound_manager_error_code(__func__, ret);
516 if (is_focus_cb_thread) {
517 LOGE("this API should not be called in focus callback");
518 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
521 ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_RECORDING, &stream_type_str, &option, &extra_info_str);
522 if (ret == MM_ERROR_NONE) {
523 LOGI("current acquired RECORDING focus : stream_type[%s]", stream_type_str);
524 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
525 if (ret == MM_ERROR_NONE) {
526 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
529 *extra_info = extra_info_str;
531 free(extra_info_str);
535 return _convert_sound_manager_error_code(__func__, ret);
538 int sound_manager_add_focus_state_watch_cb(sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_watch_cb callback, void *user_data, int *id)
540 int ret = MM_ERROR_NONE;
545 SM_NULL_ARG_CHECK(callback);
546 SM_NULL_ARG_CHECK(id);
547 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
549 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
550 if (focus_watch_info_arr[i].id == 0)
552 if (i == SOUND_STREAM_INFO_ARR_MAX) {
553 LOGE("focus watch info array is full");
554 ret = MM_ERROR_SOUND_INTERNAL;
558 ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, user_data, id);
559 if (ret == MM_ERROR_NONE) {
560 SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret);
561 focus_watch_info_arr[i].id = *id;
562 focus_watch_info_arr[i].user_data = user_data;
563 focus_watch_info_arr[i].user_cb = callback;
567 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
569 LOGD("cnt(%d), id(%d)", g_stream_info_count, *id);
571 return _convert_sound_manager_error_code(__func__, ret);
574 int sound_manager_remove_focus_state_watch_cb(int id)
576 int ret = MM_ERROR_NONE;
581 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
583 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
584 if (focus_watch_info_arr[i].id == id)
586 if (i == SOUND_STREAM_INFO_ARR_MAX) {
587 LOGE("cound not find item in focus watch info array for this id(%d)", id);
588 ret = MM_ERROR_INVALID_ARGUMENT;
592 ret = mm_sound_unset_focus_watch_callback(id);
593 if (ret == MM_ERROR_NONE) {
594 SM_UNREF_FOR_STREAM_INFO(g_stream_info_count);
595 focus_watch_info_arr[i].id = 0;
596 focus_watch_info_arr[i].user_data = NULL;
597 focus_watch_info_arr[i].user_cb = NULL;
601 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
603 LOGD("cnt(%d)", g_stream_info_count);
605 return _convert_sound_manager_error_code(__func__, ret);
608 int sound_manager_set_session_type(sound_session_type_e type)
610 int ret = MM_ERROR_NONE;
611 int cur_session = -1;
612 int new_session = MM_SESSION_TYPE_MEDIA;
613 bool mic_enable = false;
615 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
616 LOGI(">> enter : type=%d", type);
618 if (type < SOUND_SESSION_TYPE_MEDIA || type > SOUND_SESSION_TYPE_VOIP)
619 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
621 /* If session type is VOIP but MIC is not enabled, return false */
622 if (type == SOUND_SESSION_TYPE_VOIP) {
623 ret = system_info_get_platform_bool(FEATURE_MICROPHONE, &mic_enable);
624 LOGI("system_info_platform [%s]=[%d], ret[%d]", FEATURE_MICROPHONE, mic_enable, ret);
625 if (ret != SYSTEM_INFO_ERROR_NONE || !mic_enable)
626 return _convert_sound_manager_error_code(__func__, MM_ERROR_NOT_SUPPORT_API);
629 /* it is not supported both session and stream feature at the same time */
630 if (g_stream_info_count) {
631 LOGE("Could not set this type(%d) because of being used stream feature", type);
632 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
636 case SOUND_SESSION_TYPE_MEDIA:
637 new_session = MM_SESSION_TYPE_MEDIA;
639 case SOUND_SESSION_TYPE_ALARM:
640 new_session = MM_SESSION_TYPE_ALARM;
642 case SOUND_SESSION_TYPE_NOTIFICATION:
643 new_session = MM_SESSION_TYPE_NOTIFY;
645 case SOUND_SESSION_TYPE_EMERGENCY:
646 new_session = MM_SESSION_TYPE_EMERGENCY;
648 case SOUND_SESSION_TYPE_VOIP:
649 new_session = MM_SESSION_TYPE_VOIP;
653 /* valid session check */
654 ret = mm_session_get_current_type(&cur_session);
655 if (ret == MM_ERROR_NONE) {
656 if (cur_session == MM_SESSION_TYPE_MEDIA_RECORD) {
657 if (type > SOUND_SESSION_TYPE_MEDIA) {
658 LOGE("Could not set this type(%d) during camera/recorder/audio-io(in)/radio", type);
659 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
664 if (g_session_interrupt_cb_table.is_registered) {
665 if (new_session == cur_session ||
666 ((new_session == SOUND_SESSION_TYPE_MEDIA) && (cur_session == MM_SESSION_TYPE_MEDIA_RECORD))) {
667 LOGI("already set type=%d, ret=0x%x", type, ret);
668 return SOUND_MANAGER_ERROR_NONE;
670 ret = mm_session_finish();
671 if (ret != MM_ERROR_NONE)
672 return _convert_sound_manager_error_code(__func__, ret);
674 g_session_interrupt_cb_table.is_registered = 0;
675 if (cur_session == MM_SESSION_TYPE_VOIP) {
676 g_cached_session_mode = -1;
677 g_cached_voip_device_id = -1;
678 if (g_voip_vstream_h) {
679 _stop_virtual_stream(g_voip_vstream_h);
680 _destroy_virtual_stream(g_voip_vstream_h);
681 g_voip_vstream_h = NULL;
683 /*voip stream destruction*/
684 if (g_voip_stream_info) {
685 ret = _destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
686 free(g_voip_stream_info);
687 g_voip_stream_info = NULL;
688 if (ret != MM_ERROR_NONE)
689 return _convert_sound_manager_error_code(__func__, ret);
694 ret = mm_session_init(new_session);
695 if (ret == MM_ERROR_NONE)
696 g_session_interrupt_cb_table.is_registered = 1;
698 LOGI("type=%d", type);
700 return _convert_sound_manager_error_code(__func__, ret);
703 int sound_manager_get_session_type(sound_session_type_e *type)
705 int ret = MM_ERROR_NONE;
708 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
710 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
712 ret = mm_session_get_current_type(&cur_session);
713 if (ret != MM_ERROR_NONE) {
714 LOGW("session hasn't been set, setting default session");
715 cur_session = SOUND_SESSION_TYPE_DEFAULT;
716 ret = mm_session_init(cur_session);
717 if (ret == MM_ERROR_NONE)
718 g_session_interrupt_cb_table.is_registered = 1;
720 if ((cur_session > MM_SESSION_TYPE_EMERGENCY) &&
721 (cur_session != MM_SESSION_TYPE_VOIP)) {
722 if (g_cached_session != -1)
723 cur_session = g_cached_session;
724 else /* will be never reached here. just prevent code */
725 cur_session = SOUND_SESSION_TYPE_DEFAULT;
728 switch (cur_session) {
729 case MM_SESSION_TYPE_MEDIA:
730 case MM_SESSION_TYPE_MEDIA_RECORD:
731 *type = SOUND_SESSION_TYPE_MEDIA;
733 case MM_SESSION_TYPE_ALARM:
734 *type = SOUND_SESSION_TYPE_ALARM;
736 case MM_SESSION_TYPE_NOTIFY:
737 *type = SOUND_SESSION_TYPE_NOTIFICATION;
739 case MM_SESSION_TYPE_EMERGENCY:
740 *type = SOUND_SESSION_TYPE_EMERGENCY;
742 case MM_SESSION_TYPE_VOIP:
743 *type = SOUND_SESSION_TYPE_VOIP;
750 LOGI("type=%d", *type);
752 return SOUND_MANAGER_ERROR_NONE;
755 int sound_manager_set_media_session_option(sound_session_option_for_starting_e s_option, sound_session_option_for_during_play_e d_option)
757 int ret = MM_ERROR_NONE;
759 int session_option = 0;
762 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
763 LOGI(">> enter : option for starting=%d, for during play=%d", s_option, d_option);
765 if (s_option < 0 || s_option > SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START)
766 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
767 if (d_option < 0 || d_option > SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY)
768 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
770 ret = mm_session_get_current_information(&session, &session_option);
771 if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
772 LOGW("session hasn't been set, setting default session");
773 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
775 g_session_interrupt_cb_table.is_registered = 1;
777 } else if (ret == 0 && session > MM_SESSION_TYPE_MEDIA) {
778 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
779 if (!g_session_interrupt_cb_table.is_registered) {
780 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
781 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
784 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
789 case SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START:
790 if (session_option & MM_SESSION_OPTION_PAUSE_OTHERS) {
791 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_PAUSE_OTHERS);
793 return _convert_sound_manager_error_code(__func__, ret);
798 case SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START:
799 if (!(session_option & MM_SESSION_OPTION_PAUSE_OTHERS)) {
800 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_PAUSE_OTHERS);
802 return _convert_sound_manager_error_code(__func__, ret);
810 case SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY:
811 if (session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
812 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_UNINTERRUPTIBLE);
814 return _convert_sound_manager_error_code(__func__, ret);
819 case SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY:
820 if (!(session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE)) {
821 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_UNINTERRUPTIBLE);
823 return _convert_sound_manager_error_code(__func__, ret);
833 LOGI("already set same option(%x), skip it", session_option);
835 return _convert_sound_manager_error_code(__func__, ret);
838 int sound_manager_get_media_session_option(sound_session_option_for_starting_e *s_option, sound_session_option_for_during_play_e *d_option)
840 int ret = MM_ERROR_NONE;
842 int session_options = 0;
844 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
847 if (s_option == NULL || d_option == NULL)
848 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
850 ret = mm_session_get_current_information(&session, &session_options);
852 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
854 g_session_interrupt_cb_table.is_registered = 1;
856 } else if (session > SOUND_SESSION_TYPE_MEDIA) {
857 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
858 if (!g_session_interrupt_cb_table.is_registered) {
859 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
860 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
863 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
866 if (session_options & MM_SESSION_OPTION_PAUSE_OTHERS)
867 *s_option = SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START;
869 *s_option = SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START;
871 if (session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE)
872 *d_option = SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY;
874 *d_option = SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY;
876 LOGI(" option for starting=%d, for during play=%d", *s_option, *d_option);
878 return SOUND_MANAGER_ERROR_NONE;
881 int sound_manager_set_media_session_resumption_option(sound_session_option_for_resumption_e option)
883 int ret = MM_ERROR_NONE;
885 int session_option = 0;
888 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
889 LOGI(">> enter : option for resumption=%d (0:by system, 1:by system or media paused)", option);
891 if (option < SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM || option > SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED)
892 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
894 ret = mm_session_get_current_information(&session, &session_option);
895 if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
896 LOGW("session hasn't been set, setting default session");
897 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
899 g_session_interrupt_cb_table.is_registered = 1;
901 } else if (ret == 0 && session > MM_SESSION_TYPE_MEDIA) {
902 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
903 if (!g_session_interrupt_cb_table.is_registered) {
904 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
905 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
908 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
913 case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM:
914 if (session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED) {
915 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
917 return _convert_sound_manager_error_code(__func__, ret);
922 case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED:
923 if (!(session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)) {
924 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
926 return _convert_sound_manager_error_code(__func__, ret);
936 LOGI("already set same option(0x%x), skip it", session_option);
938 return _convert_sound_manager_error_code(__func__, ret);
941 int sound_manager_get_media_session_resumption_option(sound_session_option_for_resumption_e *option)
943 int ret = MM_ERROR_NONE;
945 int session_options = 0;
947 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
951 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
953 ret = mm_session_get_current_information(&session, &session_options);
955 LOGW("session hasn't been set, setting default session");
956 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
958 g_session_interrupt_cb_table.is_registered = 1;
960 } else if (session > SOUND_SESSION_TYPE_MEDIA) {
961 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
962 if (!g_session_interrupt_cb_table.is_registered) {
963 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
964 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
967 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
970 if (session_options & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)
971 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED;
973 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM;
975 LOGI("option for resumption=%d (0:by system, 1:by system or media paused)", *option);
977 return SOUND_MANAGER_ERROR_NONE;
980 int sound_manager_set_voip_session_mode(sound_session_voip_mode_e mode)
982 int ret = MM_ERROR_NONE;
984 int session_options = 0;
986 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
987 LOGI(">> enter : mode=%d", mode);
989 ret = mm_session_get_current_information(&session, &session_options);
990 if (ret != MM_ERROR_NONE)
993 if (session != MM_SESSION_TYPE_VOIP) {
994 ret = MM_ERROR_POLICY_INTERNAL;
998 if (mode < SOUND_SESSION_VOIP_MODE_RINGTONE || mode > SOUND_SESSION_VOIP_MODE_VOICE_WITH_BLUETOOTH) {
999 ret = MM_ERROR_INVALID_ARGUMENT;
1003 ret = _set_session_mode((_session_mode_e)mode);
1005 LOGI("session=%d, mode=%d", session, mode);
1008 return _convert_sound_manager_error_code(__func__, ret);
1011 int sound_manager_get_voip_session_mode(sound_session_voip_mode_e *mode)
1013 int ret = MM_ERROR_NONE;
1015 int session_options = 0;
1017 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1019 LOGE("mode is null");
1020 ret = MM_ERROR_INVALID_ARGUMENT;
1024 ret = mm_session_get_current_information(&session, &session_options);
1025 if (ret != MM_ERROR_NONE) {
1026 LOGI("session = %d, option = %d", session, session_options);
1030 if (session != MM_SESSION_TYPE_VOIP || g_cached_session_mode == -1) {
1031 ret = MM_ERROR_POLICY_INTERNAL;
1035 *mode = (sound_session_voip_mode_e)g_cached_session_mode;
1037 LOGI("session=%d, mode=%d", session, *mode);
1040 return _convert_sound_manager_error_code(__func__, ret);
1043 int sound_manager_set_session_interrupted_cb(sound_session_interrupted_cb callback, void *user_data)
1045 int ret = MM_ERROR_NONE;
1046 unsigned int subs_id = 0;
1048 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1049 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_interrupt_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1051 if (callback == NULL) {
1052 ret = MM_ERROR_INVALID_ARGUMENT;
1056 /* it is not supported both session and stream feature at the same time */
1057 if (g_stream_info_count) {
1058 ret = MM_ERROR_POLICY_INTERNAL;
1062 if (g_session_interrupt_cb_table.user_cb == NULL) {
1063 ret = mm_sound_add_device_connected_callback(SOUND_DEVICE_ALL_MASK, (mm_sound_device_connected_cb)_device_connected_cb, NULL, &subs_id);
1066 ret = mm_sound_focus_set_session_interrupt_callback((mm_sound_focus_session_interrupt_cb)_focus_session_interrupt_cb, NULL);
1068 if (mm_sound_remove_device_connected_callback(subs_id) != MM_ERROR_NONE)
1069 LOGW("mm_sound_remove_device_connected_callback failed");
1072 g_session_interrupt_cb_table.subs_id = subs_id;
1074 g_session_interrupt_cb_table.user_cb = (sound_session_interrupted_cb)callback;
1075 g_session_interrupt_cb_table.user_data = user_data;
1078 SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex);
1080 return _convert_sound_manager_error_code(__func__, ret);
1083 int sound_manager_unset_session_interrupted_cb(void)
1085 int ret = MM_ERROR_NONE;
1087 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1088 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_interrupt_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1090 if (!g_session_interrupt_cb_table.user_cb) {
1091 ret = MM_ERROR_SOUND_INTERNAL;
1095 ret = mm_sound_focus_unset_session_interrupt_callback();
1097 if (mm_sound_remove_device_connected_callback(g_session_interrupt_cb_table.subs_id) != MM_ERROR_NONE)
1098 LOGW("mm_sound_remove_device_connected_callback failed");
1102 ret = mm_sound_remove_device_connected_callback(g_session_interrupt_cb_table.subs_id);
1106 g_session_interrupt_cb_table.subs_id = 0;
1107 g_session_interrupt_cb_table.user_cb = NULL;
1108 g_session_interrupt_cb_table.user_data = NULL;
1111 SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex);
1113 return _convert_sound_manager_error_code(__func__, ret);
1116 int sound_manager_get_current_device_list(sound_device_mask_e device_mask, sound_device_list_h *device_list)
1118 int ret = MM_ERROR_NONE;
1120 ret = mm_sound_get_current_device_list((mm_sound_device_flags_e)device_mask, device_list);
1122 return _convert_sound_manager_error_code(__func__, ret);
1125 int sound_manager_free_device_list(sound_device_list_h device_list)
1127 int ret = MM_ERROR_NONE;
1129 ret = mm_sound_free_device_list(device_list);
1131 return _convert_sound_manager_error_code(__func__, ret);
1134 int sound_manager_get_next_device(sound_device_list_h device_list, sound_device_h *device)
1136 int ret = MM_ERROR_NONE;
1138 ret = mm_sound_get_next_device(device_list, device);
1140 return _convert_sound_manager_error_code(__func__, ret);
1143 int sound_manager_get_prev_device(sound_device_list_h device_list, sound_device_h *device)
1145 int ret = MM_ERROR_NONE;
1147 ret = mm_sound_get_prev_device(device_list, device);
1149 return _convert_sound_manager_error_code(__func__, ret);
1152 int sound_manager_get_device_type(sound_device_h device, sound_device_type_e *type)
1154 int ret = MM_ERROR_NONE;
1156 ret = mm_sound_get_device_type(device, (mm_sound_device_type_e*)type);
1158 return _convert_sound_manager_error_code(__func__, ret);
1161 int sound_manager_get_device_io_direction(sound_device_h device, sound_device_io_direction_e *io_direction)
1163 int ret = MM_ERROR_NONE;
1164 mm_sound_device_io_direction_e mm_sound_io_direction;
1166 ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction);
1167 if (ret == MM_ERROR_NONE)
1168 ret = _convert_device_io_direction(mm_sound_io_direction, io_direction);
1170 return _convert_sound_manager_error_code(__func__, ret);
1173 int sound_manager_get_device_id(sound_device_h device, int *id)
1175 int ret = MM_ERROR_NONE;
1177 ret = mm_sound_get_device_id(device, id);
1179 return _convert_sound_manager_error_code(__func__, ret);
1182 int sound_manager_get_device_name(sound_device_h device, char **name)
1184 int ret = MM_ERROR_NONE;
1186 ret = mm_sound_get_device_name(device, name);
1188 return _convert_sound_manager_error_code(__func__, ret);
1191 int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *state)
1193 int ret = MM_ERROR_NONE;
1195 ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
1197 return _convert_sound_manager_error_code(__func__, ret);
1200 int sound_manager_get_bt_device_avail_modes(sound_device_h device, int *modes)
1202 int ret = MM_ERROR_NONE;
1205 sound_device_type_e device_type;
1207 if (!device || !modes)
1208 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1210 ret = mm_sound_get_device_type(device, (mm_sound_device_type_e*)&device_type);
1211 if (ret != MM_ERROR_NONE)
1213 if (device_type != SOUND_DEVICE_BLUETOOTH) {
1214 ret = MM_ERROR_INVALID_ARGUMENT;
1218 ret = mm_sound_get_device_bt_avail_mode(device, &mm_avail_mode);
1219 if (ret != MM_ERROR_NONE)
1222 if ((_avail_mode = _convert_avail_mode(mm_avail_mode)) < 0) {
1223 LOGE("Invalid avail mode %d", mm_avail_mode);
1224 ret = MM_ERROR_SOUND_INTERNAL;
1228 *modes = _avail_mode;
1231 return _convert_sound_manager_error_code(__func__, ret);
1234 int sound_manager_set_device_connected_cb(sound_device_mask_e device_mask, sound_device_connected_cb callback, void *user_data)
1236 int ret = MM_ERROR_NONE;
1237 unsigned int subs_id = 0;
1239 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1241 ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data, &subs_id);
1242 if (ret == MM_ERROR_NONE) {
1243 g_device_connected_cb_table.subs_id = subs_id;
1244 g_device_connected_cb_table.user_cb = (sound_device_connected_cb)callback;
1245 g_device_connected_cb_table.user_data = user_data;
1248 SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex);
1250 return _convert_sound_manager_error_code(__func__, ret);
1253 int sound_manager_unset_device_connected_cb(void)
1255 int ret = MM_ERROR_NONE;
1257 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1259 if (g_device_connected_cb_table.subs_id == 0) {
1260 ret = MM_ERROR_SOUND_INTERNAL;
1264 ret = mm_sound_remove_device_connected_callback(g_device_connected_cb_table.subs_id);
1265 if (ret == MM_ERROR_NONE) {
1266 g_device_connected_cb_table.subs_id = 0;
1267 g_device_connected_cb_table.user_cb = NULL;
1268 g_device_connected_cb_table.user_data = NULL;
1272 SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex);
1274 return _convert_sound_manager_error_code(__func__, ret);
1277 int sound_manager_set_device_information_changed_cb(sound_device_mask_e device_mask, sound_device_information_changed_cb callback, void *user_data)
1279 int ret = MM_ERROR_NONE;
1280 unsigned int subs_id = 0;
1282 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1284 ret = mm_sound_add_device_information_changed_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_info_changed_cb)callback, user_data, &subs_id);
1285 if (ret == MM_ERROR_NONE) {
1286 g_device_info_changed_cb_table.subs_id = subs_id;
1287 g_device_info_changed_cb_table.user_cb = (sound_device_information_changed_cb)callback;
1288 g_device_info_changed_cb_table.user_data = user_data;
1291 SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex);
1293 return _convert_sound_manager_error_code(__func__, ret);
1296 int sound_manager_unset_device_information_changed_cb(void)
1298 int ret = MM_ERROR_NONE;
1300 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1302 if (g_device_info_changed_cb_table.subs_id == 0) {
1303 ret = MM_ERROR_SOUND_INTERNAL;
1307 ret = mm_sound_remove_device_information_changed_callback(g_device_info_changed_cb_table.subs_id);
1308 if (ret == MM_ERROR_NONE) {
1309 g_device_info_changed_cb_table.subs_id = 0;
1310 g_device_info_changed_cb_table.user_cb = NULL;
1311 g_device_info_changed_cb_table.user_data = NULL;
1315 SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex);
1317 return _convert_sound_manager_error_code(__func__, ret);
1320 __attribute__ ((destructor))
1321 void __sound_manager_finalize(void)
1323 int ret = MM_ERROR_NONE;
1325 if (g_session_interrupt_cb_table.is_registered) {
1327 ret = mm_session_finish();
1328 if (ret != MM_ERROR_NONE)
1329 LOGE("[%s] failed to mm_session_finish(), ret(0x%x)", __func__, ret);
1331 g_session_interrupt_cb_table.is_registered = 0;
1336 __attribute__ ((constructor))
1337 void __sound_manager_initialize(void)