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_get_changed_focus_state(sound_stream_info_h stream_info, sound_stream_focus_mask_e *focus_mask, sound_stream_focus_state_e *focus_state)
404 int ret = MM_ERROR_NONE;
405 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
406 bool is_focus_cb_thread = false;
410 SM_INSTANCE_CHECK(stream_h);
411 SM_NULL_ARG_CHECK(focus_mask);
412 SM_NULL_ARG_CHECK(focus_state);
414 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
415 return _convert_sound_manager_error_code(__func__, ret);
417 if (!is_focus_cb_thread) {
418 LOGE("this API should be called in focus state changed callback");
419 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
422 if (stream_h->changed_focus_type == FOCUS_NONE)
423 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
425 *focus_mask = (sound_stream_focus_mask_e)stream_h->changed_focus_type;
426 *focus_state = (sound_stream_focus_state_e)stream_h->changed_focus_state;
428 LOGI("changed focus(mask:0x%x, state:%d)", *focus_mask, *focus_state);
430 return _convert_sound_manager_error_code(__func__, ret);
433 int sound_manager_focus_set_requesting_behavior(sound_stream_info_h stream_info, int flags)
435 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
439 SM_INSTANCE_CHECK(stream_h);
440 SM_RANGE_ARG_CHECK(flags,
442 (SOUND_BEHAVIOR_NO_RESUME|SOUND_BEHAVIOR_FADING));
444 stream_h->requesting_flags = flags;
446 LOGI("the requesting sound behavior(0x%x) is set", stream_h->requesting_flags);
448 return SOUND_MANAGER_ERROR_NONE;
451 int sound_manager_focus_get_requesting_behavior(sound_stream_info_h stream_info, int *flags)
453 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
457 SM_INSTANCE_CHECK(stream_h);
458 SM_NULL_ARG_CHECK(flags);
460 *flags = stream_h->requesting_flags;
462 LOGI("the requesting sound behavior is (0x%x)", stream_h->requesting_flags);
464 return SOUND_MANAGER_ERROR_NONE;
467 int sound_manager_focus_get_requested_behavior(sound_stream_info_h stream_info, int *flags)
469 int ret = MM_ERROR_NONE;
470 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
471 bool is_focus_cb_thread = false;
475 SM_INSTANCE_CHECK(stream_h);
476 SM_NULL_ARG_CHECK(flags);
478 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
479 return _convert_sound_manager_error_code(__func__, ret);
481 if (!is_focus_cb_thread) {
482 LOGE("this API should be called in focus state changed callback");
483 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
486 *flags = stream_h->requested_flags;
488 LOGI("requested sound behavior is (0x%x)", stream_h->requested_flags);
490 return SOUND_MANAGER_ERROR_NONE;
493 int sound_manager_get_current_playback_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
495 int ret = MM_ERROR_NONE;
496 char *stream_type_str = NULL;
497 char *extra_info_str = NULL;
499 bool is_focus_cb_thread = false;
503 SM_NULL_ARG_CHECK(acquired_by);
504 SM_NULL_ARG_CHECK(flags);
506 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
507 return _convert_sound_manager_error_code(__func__, ret);
509 if (is_focus_cb_thread) {
510 LOGE("this API should not be called in focus callback");
511 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
514 ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_PLAYBACK, &stream_type_str, &option, &extra_info_str);
515 if (ret == MM_ERROR_NONE) {
516 LOGI("current acquired PLAYBACK focus : stream_type[%s]", stream_type_str);
517 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
518 if (ret == MM_ERROR_NONE) {
519 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
522 *extra_info = extra_info_str;
524 free(extra_info_str);
528 return _convert_sound_manager_error_code(__func__, ret);
531 int sound_manager_get_current_recording_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
533 int ret = MM_ERROR_NONE;
534 char *stream_type_str = NULL;
535 char *extra_info_str = NULL;
537 bool is_focus_cb_thread = false;
541 SM_NULL_ARG_CHECK(acquired_by);
542 SM_NULL_ARG_CHECK(flags);
544 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
545 return _convert_sound_manager_error_code(__func__, ret);
547 if (is_focus_cb_thread) {
548 LOGE("this API should not be called in focus callback");
549 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
552 ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_RECORDING, &stream_type_str, &option, &extra_info_str);
553 if (ret == MM_ERROR_NONE) {
554 LOGI("current acquired RECORDING focus : stream_type[%s]", stream_type_str);
555 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
556 if (ret == MM_ERROR_NONE) {
557 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
560 *extra_info = extra_info_str;
562 free(extra_info_str);
566 return _convert_sound_manager_error_code(__func__, ret);
569 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)
571 int ret = MM_ERROR_NONE;
576 SM_NULL_ARG_CHECK(callback);
577 SM_NULL_ARG_CHECK(id);
578 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
580 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
581 if (focus_watch_info_arr[i].id == 0)
583 if (i == SOUND_STREAM_INFO_ARR_MAX) {
584 LOGE("focus watch info array is full");
585 ret = MM_ERROR_SOUND_INTERNAL;
589 ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, user_data, id);
590 if (ret == MM_ERROR_NONE) {
591 SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret);
592 focus_watch_info_arr[i].id = *id;
593 focus_watch_info_arr[i].user_data = user_data;
594 focus_watch_info_arr[i].user_cb = callback;
598 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
600 LOGD("cnt(%d), id(%d)", g_stream_info_count, *id);
602 return _convert_sound_manager_error_code(__func__, ret);
605 int sound_manager_remove_focus_state_watch_cb(int id)
607 int ret = MM_ERROR_NONE;
612 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
614 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
615 if (focus_watch_info_arr[i].id == id)
617 if (i == SOUND_STREAM_INFO_ARR_MAX) {
618 LOGE("cound not find item in focus watch info array for this id(%d)", id);
619 ret = MM_ERROR_INVALID_ARGUMENT;
623 ret = mm_sound_unset_focus_watch_callback(id);
624 if (ret == MM_ERROR_NONE) {
625 SM_UNREF_FOR_STREAM_INFO(g_stream_info_count);
626 focus_watch_info_arr[i].id = 0;
627 focus_watch_info_arr[i].user_data = NULL;
628 focus_watch_info_arr[i].user_cb = NULL;
632 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
634 LOGD("cnt(%d)", g_stream_info_count);
636 return _convert_sound_manager_error_code(__func__, ret);
639 int sound_manager_set_session_type(sound_session_type_e type)
641 int ret = MM_ERROR_NONE;
642 int cur_session = -1;
643 int new_session = MM_SESSION_TYPE_MEDIA;
644 bool mic_enable = false;
646 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
647 LOGI(">> enter : type=%d", type);
649 if (type < SOUND_SESSION_TYPE_MEDIA || type > SOUND_SESSION_TYPE_VOIP)
650 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
652 /* If session type is VOIP but MIC is not enabled, return false */
653 if (type == SOUND_SESSION_TYPE_VOIP) {
654 ret = system_info_get_platform_bool(FEATURE_MICROPHONE, &mic_enable);
655 LOGI("system_info_platform [%s]=[%d], ret[%d]", FEATURE_MICROPHONE, mic_enable, ret);
656 if (ret != SYSTEM_INFO_ERROR_NONE || !mic_enable)
657 return _convert_sound_manager_error_code(__func__, MM_ERROR_NOT_SUPPORT_API);
660 /* it is not supported both session and stream feature at the same time */
661 if (g_stream_info_count) {
662 LOGE("Could not set this type(%d) because of being used stream feature", type);
663 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
667 case SOUND_SESSION_TYPE_MEDIA:
668 new_session = MM_SESSION_TYPE_MEDIA;
670 case SOUND_SESSION_TYPE_ALARM:
671 new_session = MM_SESSION_TYPE_ALARM;
673 case SOUND_SESSION_TYPE_NOTIFICATION:
674 new_session = MM_SESSION_TYPE_NOTIFY;
676 case SOUND_SESSION_TYPE_EMERGENCY:
677 new_session = MM_SESSION_TYPE_EMERGENCY;
679 case SOUND_SESSION_TYPE_VOIP:
680 new_session = MM_SESSION_TYPE_VOIP;
684 /* valid session check */
685 ret = mm_session_get_current_type(&cur_session);
686 if (ret == MM_ERROR_NONE) {
687 if (cur_session == MM_SESSION_TYPE_MEDIA_RECORD) {
688 if (type > SOUND_SESSION_TYPE_MEDIA) {
689 LOGE("Could not set this type(%d) during camera/recorder/audio-io(in)/radio", type);
690 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
695 if (g_session_interrupt_cb_table.is_registered) {
696 if (new_session == cur_session ||
697 ((new_session == SOUND_SESSION_TYPE_MEDIA) && (cur_session == MM_SESSION_TYPE_MEDIA_RECORD))) {
698 LOGI("already set type=%d, ret=0x%x", type, ret);
699 return SOUND_MANAGER_ERROR_NONE;
701 ret = mm_session_finish();
702 if (ret != MM_ERROR_NONE)
703 return _convert_sound_manager_error_code(__func__, ret);
705 g_session_interrupt_cb_table.is_registered = 0;
706 if (cur_session == MM_SESSION_TYPE_VOIP) {
707 g_cached_session_mode = -1;
708 g_cached_voip_device_id = -1;
709 if (g_voip_vstream_h) {
710 _stop_virtual_stream(g_voip_vstream_h);
711 _destroy_virtual_stream(g_voip_vstream_h);
712 g_voip_vstream_h = NULL;
714 /*voip stream destruction*/
715 if (g_voip_stream_info) {
716 ret = _destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
717 free(g_voip_stream_info);
718 g_voip_stream_info = NULL;
719 if (ret != MM_ERROR_NONE)
720 return _convert_sound_manager_error_code(__func__, ret);
725 ret = mm_session_init(new_session);
726 if (ret == MM_ERROR_NONE)
727 g_session_interrupt_cb_table.is_registered = 1;
729 LOGI("type=%d", type);
731 return _convert_sound_manager_error_code(__func__, ret);
734 int sound_manager_get_session_type(sound_session_type_e *type)
736 int ret = MM_ERROR_NONE;
739 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
741 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
743 ret = mm_session_get_current_type(&cur_session);
744 if (ret != MM_ERROR_NONE) {
745 LOGW("session hasn't been set, setting default session");
746 cur_session = SOUND_SESSION_TYPE_DEFAULT;
747 ret = mm_session_init(cur_session);
748 if (ret == MM_ERROR_NONE)
749 g_session_interrupt_cb_table.is_registered = 1;
751 if ((cur_session > MM_SESSION_TYPE_EMERGENCY) &&
752 (cur_session != MM_SESSION_TYPE_VOIP)) {
753 if (g_cached_session != -1)
754 cur_session = g_cached_session;
755 else /* will be never reached here. just prevent code */
756 cur_session = SOUND_SESSION_TYPE_DEFAULT;
759 switch (cur_session) {
760 case MM_SESSION_TYPE_MEDIA:
761 case MM_SESSION_TYPE_MEDIA_RECORD:
762 *type = SOUND_SESSION_TYPE_MEDIA;
764 case MM_SESSION_TYPE_ALARM:
765 *type = SOUND_SESSION_TYPE_ALARM;
767 case MM_SESSION_TYPE_NOTIFY:
768 *type = SOUND_SESSION_TYPE_NOTIFICATION;
770 case MM_SESSION_TYPE_EMERGENCY:
771 *type = SOUND_SESSION_TYPE_EMERGENCY;
773 case MM_SESSION_TYPE_VOIP:
774 *type = SOUND_SESSION_TYPE_VOIP;
781 LOGI("type=%d", *type);
783 return SOUND_MANAGER_ERROR_NONE;
786 int sound_manager_set_media_session_option(sound_session_option_for_starting_e s_option, sound_session_option_for_during_play_e d_option)
788 int ret = MM_ERROR_NONE;
790 int session_option = 0;
793 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
794 LOGI(">> enter : option for starting=%d, for during play=%d", s_option, d_option);
796 if (s_option < 0 || s_option > SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START)
797 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
798 if (d_option < 0 || d_option > SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY)
799 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
801 ret = mm_session_get_current_information(&session, &session_option);
802 if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
803 LOGW("session hasn't been set, setting default session");
804 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
806 g_session_interrupt_cb_table.is_registered = 1;
808 } else if (ret == 0 && session > MM_SESSION_TYPE_MEDIA) {
809 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
810 if (!g_session_interrupt_cb_table.is_registered) {
811 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
812 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
815 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
820 case SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START:
821 if (session_option & MM_SESSION_OPTION_PAUSE_OTHERS) {
822 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_PAUSE_OTHERS);
824 return _convert_sound_manager_error_code(__func__, ret);
829 case SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START:
830 if (!(session_option & MM_SESSION_OPTION_PAUSE_OTHERS)) {
831 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_PAUSE_OTHERS);
833 return _convert_sound_manager_error_code(__func__, ret);
841 case SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY:
842 if (session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
843 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_UNINTERRUPTIBLE);
845 return _convert_sound_manager_error_code(__func__, ret);
850 case SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY:
851 if (!(session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE)) {
852 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_UNINTERRUPTIBLE);
854 return _convert_sound_manager_error_code(__func__, ret);
864 LOGI("already set same option(%x), skip it", session_option);
866 return _convert_sound_manager_error_code(__func__, ret);
869 int sound_manager_get_media_session_option(sound_session_option_for_starting_e *s_option, sound_session_option_for_during_play_e *d_option)
871 int ret = MM_ERROR_NONE;
873 int session_options = 0;
875 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
878 if (s_option == NULL || d_option == NULL)
879 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
881 ret = mm_session_get_current_information(&session, &session_options);
883 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
885 g_session_interrupt_cb_table.is_registered = 1;
887 } else if (session > SOUND_SESSION_TYPE_MEDIA) {
888 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
889 if (!g_session_interrupt_cb_table.is_registered) {
890 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
891 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
894 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
897 if (session_options & MM_SESSION_OPTION_PAUSE_OTHERS)
898 *s_option = SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START;
900 *s_option = SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START;
902 if (session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE)
903 *d_option = SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY;
905 *d_option = SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY;
907 LOGI(" option for starting=%d, for during play=%d", *s_option, *d_option);
909 return SOUND_MANAGER_ERROR_NONE;
912 int sound_manager_set_media_session_resumption_option(sound_session_option_for_resumption_e option)
914 int ret = MM_ERROR_NONE;
916 int session_option = 0;
919 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
920 LOGI(">> enter : option for resumption=%d (0:by system, 1:by system or media paused)", option);
922 if (option < SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM || option > SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED)
923 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
925 ret = mm_session_get_current_information(&session, &session_option);
926 if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
927 LOGW("session hasn't been set, setting default session");
928 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
930 g_session_interrupt_cb_table.is_registered = 1;
932 } else if (ret == 0 && session > MM_SESSION_TYPE_MEDIA) {
933 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
934 if (!g_session_interrupt_cb_table.is_registered) {
935 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
936 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
939 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
944 case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM:
945 if (session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED) {
946 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
948 return _convert_sound_manager_error_code(__func__, ret);
953 case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED:
954 if (!(session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)) {
955 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
957 return _convert_sound_manager_error_code(__func__, ret);
967 LOGI("already set same option(0x%x), skip it", session_option);
969 return _convert_sound_manager_error_code(__func__, ret);
972 int sound_manager_get_media_session_resumption_option(sound_session_option_for_resumption_e *option)
974 int ret = MM_ERROR_NONE;
976 int session_options = 0;
978 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
982 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
984 ret = mm_session_get_current_information(&session, &session_options);
986 LOGW("session hasn't been set, setting default session");
987 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
989 g_session_interrupt_cb_table.is_registered = 1;
991 } else if (session > SOUND_SESSION_TYPE_MEDIA) {
992 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
993 if (!g_session_interrupt_cb_table.is_registered) {
994 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
995 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
998 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
1001 if (session_options & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)
1002 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED;
1004 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM;
1006 LOGI("option for resumption=%d (0:by system, 1:by system or media paused)", *option);
1008 return SOUND_MANAGER_ERROR_NONE;
1011 int sound_manager_set_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__);
1018 LOGI(">> enter : mode=%d", mode);
1020 ret = mm_session_get_current_information(&session, &session_options);
1021 if (ret != MM_ERROR_NONE)
1024 if (session != MM_SESSION_TYPE_VOIP) {
1025 ret = MM_ERROR_POLICY_INTERNAL;
1029 if (mode < SOUND_SESSION_VOIP_MODE_RINGTONE || mode > SOUND_SESSION_VOIP_MODE_VOICE_WITH_BLUETOOTH) {
1030 ret = MM_ERROR_INVALID_ARGUMENT;
1034 ret = _set_session_mode((_session_mode_e)mode);
1036 LOGI("session=%d, mode=%d", session, mode);
1039 return _convert_sound_manager_error_code(__func__, ret);
1042 int sound_manager_get_voip_session_mode(sound_session_voip_mode_e *mode)
1044 int ret = MM_ERROR_NONE;
1046 int session_options = 0;
1048 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1050 LOGE("mode is null");
1051 ret = MM_ERROR_INVALID_ARGUMENT;
1055 ret = mm_session_get_current_information(&session, &session_options);
1056 if (ret != MM_ERROR_NONE) {
1057 LOGI("session = %d, option = %d", session, session_options);
1061 if (session != MM_SESSION_TYPE_VOIP || g_cached_session_mode == -1) {
1062 ret = MM_ERROR_POLICY_INTERNAL;
1066 *mode = (sound_session_voip_mode_e)g_cached_session_mode;
1068 LOGI("session=%d, mode=%d", session, *mode);
1071 return _convert_sound_manager_error_code(__func__, ret);
1074 int sound_manager_set_session_interrupted_cb(sound_session_interrupted_cb callback, void *user_data)
1076 int ret = MM_ERROR_NONE;
1077 unsigned int subs_id = 0;
1079 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1080 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_interrupt_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1082 if (callback == NULL) {
1083 ret = MM_ERROR_INVALID_ARGUMENT;
1087 /* it is not supported both session and stream feature at the same time */
1088 if (g_stream_info_count) {
1089 ret = MM_ERROR_POLICY_INTERNAL;
1093 if (g_session_interrupt_cb_table.user_cb == NULL) {
1094 ret = mm_sound_add_device_connected_callback(SOUND_DEVICE_ALL_MASK, (mm_sound_device_connected_cb)_device_connected_cb, NULL, &subs_id);
1097 ret = mm_sound_focus_set_session_interrupt_callback((mm_sound_focus_session_interrupt_cb)_focus_session_interrupt_cb, NULL);
1099 if (mm_sound_remove_device_connected_callback(subs_id) != MM_ERROR_NONE)
1100 LOGW("mm_sound_remove_device_connected_callback failed");
1103 g_session_interrupt_cb_table.subs_id = subs_id;
1105 g_session_interrupt_cb_table.user_cb = (sound_session_interrupted_cb)callback;
1106 g_session_interrupt_cb_table.user_data = user_data;
1109 SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex);
1111 return _convert_sound_manager_error_code(__func__, ret);
1114 int sound_manager_unset_session_interrupted_cb(void)
1116 int ret = MM_ERROR_NONE;
1118 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1119 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_interrupt_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1121 if (!g_session_interrupt_cb_table.user_cb) {
1122 ret = MM_ERROR_SOUND_INTERNAL;
1126 ret = mm_sound_focus_unset_session_interrupt_callback();
1128 if (mm_sound_remove_device_connected_callback(g_session_interrupt_cb_table.subs_id) != MM_ERROR_NONE)
1129 LOGW("mm_sound_remove_device_connected_callback failed");
1133 ret = mm_sound_remove_device_connected_callback(g_session_interrupt_cb_table.subs_id);
1137 g_session_interrupt_cb_table.subs_id = 0;
1138 g_session_interrupt_cb_table.user_cb = NULL;
1139 g_session_interrupt_cb_table.user_data = NULL;
1142 SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex);
1144 return _convert_sound_manager_error_code(__func__, ret);
1147 int sound_manager_get_current_device_list(sound_device_mask_e device_mask, sound_device_list_h *device_list)
1149 int ret = MM_ERROR_NONE;
1151 ret = mm_sound_get_current_device_list((mm_sound_device_flags_e)device_mask, device_list);
1153 return _convert_sound_manager_error_code(__func__, ret);
1156 int sound_manager_free_device_list(sound_device_list_h device_list)
1158 int ret = MM_ERROR_NONE;
1160 ret = mm_sound_free_device_list(device_list);
1162 return _convert_sound_manager_error_code(__func__, ret);
1165 int sound_manager_get_next_device(sound_device_list_h device_list, sound_device_h *device)
1167 int ret = MM_ERROR_NONE;
1169 ret = mm_sound_get_next_device(device_list, device);
1171 return _convert_sound_manager_error_code(__func__, ret);
1174 int sound_manager_get_prev_device(sound_device_list_h device_list, sound_device_h *device)
1176 int ret = MM_ERROR_NONE;
1178 ret = mm_sound_get_prev_device(device_list, device);
1180 return _convert_sound_manager_error_code(__func__, ret);
1183 int sound_manager_get_device_type(sound_device_h device, sound_device_type_e *type)
1185 int ret = MM_ERROR_NONE;
1187 ret = mm_sound_get_device_type(device, (mm_sound_device_type_e*)type);
1189 return _convert_sound_manager_error_code(__func__, ret);
1192 int sound_manager_get_device_io_direction(sound_device_h device, sound_device_io_direction_e *io_direction)
1194 int ret = MM_ERROR_NONE;
1195 mm_sound_device_io_direction_e mm_sound_io_direction;
1197 ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction);
1198 if (ret == MM_ERROR_NONE)
1199 ret = _convert_device_io_direction(mm_sound_io_direction, io_direction);
1201 return _convert_sound_manager_error_code(__func__, ret);
1204 int sound_manager_get_device_id(sound_device_h device, int *id)
1206 int ret = MM_ERROR_NONE;
1208 ret = mm_sound_get_device_id(device, id);
1210 return _convert_sound_manager_error_code(__func__, ret);
1213 int sound_manager_get_device_name(sound_device_h device, char **name)
1215 int ret = MM_ERROR_NONE;
1217 ret = mm_sound_get_device_name(device, name);
1219 return _convert_sound_manager_error_code(__func__, ret);
1222 int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *state)
1224 int ret = MM_ERROR_NONE;
1226 ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
1228 return _convert_sound_manager_error_code(__func__, ret);
1231 int sound_manager_get_bt_device_avail_modes(sound_device_h device, int *modes)
1233 int ret = MM_ERROR_NONE;
1236 sound_device_type_e device_type;
1238 if (!device || !modes)
1239 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1241 ret = mm_sound_get_device_type(device, (mm_sound_device_type_e*)&device_type);
1242 if (ret != MM_ERROR_NONE)
1244 if (device_type != SOUND_DEVICE_BLUETOOTH) {
1245 ret = MM_ERROR_INVALID_ARGUMENT;
1249 ret = mm_sound_get_device_bt_avail_mode(device, &mm_avail_mode);
1250 if (ret != MM_ERROR_NONE)
1253 if ((_avail_mode = _convert_avail_mode(mm_avail_mode)) < 0) {
1254 LOGE("Invalid avail mode %d", mm_avail_mode);
1255 ret = MM_ERROR_SOUND_INTERNAL;
1259 *modes = _avail_mode;
1262 return _convert_sound_manager_error_code(__func__, ret);
1265 int sound_manager_set_device_connected_cb(sound_device_mask_e device_mask, sound_device_connected_cb callback, void *user_data)
1267 int ret = MM_ERROR_NONE;
1268 unsigned int subs_id = 0;
1270 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1272 ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data, &subs_id);
1273 if (ret == MM_ERROR_NONE) {
1274 g_device_connected_cb_table.subs_id = subs_id;
1275 g_device_connected_cb_table.user_cb = (sound_device_connected_cb)callback;
1276 g_device_connected_cb_table.user_data = user_data;
1279 SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex);
1281 return _convert_sound_manager_error_code(__func__, ret);
1284 int sound_manager_unset_device_connected_cb(void)
1286 int ret = MM_ERROR_NONE;
1288 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1290 if (g_device_connected_cb_table.subs_id == 0) {
1291 ret = MM_ERROR_SOUND_INTERNAL;
1295 ret = mm_sound_remove_device_connected_callback(g_device_connected_cb_table.subs_id);
1296 if (ret == MM_ERROR_NONE) {
1297 g_device_connected_cb_table.subs_id = 0;
1298 g_device_connected_cb_table.user_cb = NULL;
1299 g_device_connected_cb_table.user_data = NULL;
1303 SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex);
1305 return _convert_sound_manager_error_code(__func__, ret);
1308 int sound_manager_set_device_information_changed_cb(sound_device_mask_e device_mask, sound_device_information_changed_cb callback, void *user_data)
1310 int ret = MM_ERROR_NONE;
1311 unsigned int subs_id = 0;
1313 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1315 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);
1316 if (ret == MM_ERROR_NONE) {
1317 g_device_info_changed_cb_table.subs_id = subs_id;
1318 g_device_info_changed_cb_table.user_cb = (sound_device_information_changed_cb)callback;
1319 g_device_info_changed_cb_table.user_data = user_data;
1322 SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex);
1324 return _convert_sound_manager_error_code(__func__, ret);
1327 int sound_manager_unset_device_information_changed_cb(void)
1329 int ret = MM_ERROR_NONE;
1331 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1333 if (g_device_info_changed_cb_table.subs_id == 0) {
1334 ret = MM_ERROR_SOUND_INTERNAL;
1338 ret = mm_sound_remove_device_information_changed_callback(g_device_info_changed_cb_table.subs_id);
1339 if (ret == MM_ERROR_NONE) {
1340 g_device_info_changed_cb_table.subs_id = 0;
1341 g_device_info_changed_cb_table.user_cb = NULL;
1342 g_device_info_changed_cb_table.user_data = NULL;
1346 SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex);
1348 return _convert_sound_manager_error_code(__func__, ret);
1351 __attribute__ ((destructor))
1352 void __sound_manager_finalize(void)
1354 int ret = MM_ERROR_NONE;
1356 if (g_session_interrupt_cb_table.is_registered) {
1358 ret = mm_session_finish();
1359 if (ret != MM_ERROR_NONE)
1360 LOGE("[%s] failed to mm_session_finish(), ret(0x%x)", __func__, ret);
1362 g_session_interrupt_cb_table.is_registered = 0;
1367 __attribute__ ((constructor))
1368 void __sound_manager_initialize(void)