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 int g_cached_voip_device_id2 = -1;
33 extern sound_stream_info_s *g_voip_stream_info;
34 extern sound_stream_info_s *g_voip_ringtone_stream_info;
35 extern virtual_sound_stream_info_s *g_voip_vstream_h;
36 extern virtual_sound_stream_info_s *g_voip_ringtone_vstream_h;
38 /* These variables will be removed when session features are deprecated. */
39 extern int g_stream_info_count;
40 extern pthread_mutex_t g_stream_info_count_mutex;
41 pthread_mutex_t g_session_mutex = PTHREAD_MUTEX_INITIALIZER;
42 pthread_mutex_t g_interrupt_cb_mutex = PTHREAD_MUTEX_INITIALIZER;
43 pthread_mutex_t g_device_info_cb_mutex = PTHREAD_MUTEX_INITIALIZER;
44 pthread_mutex_t g_device_conn_cb_mutex = PTHREAD_MUTEX_INITIALIZER;
45 pthread_mutex_t g_volume_cb_mutex = PTHREAD_MUTEX_INITIALIZER;
47 int sound_manager_get_max_volume(sound_type_e type, int *max)
49 const char *volume_type = NULL;
50 unsigned int max_level = 0;
51 int ret = MM_ERROR_NONE;
53 SM_NULL_ARG_CHECK(max);
54 if (type >= SOUND_TYPE_NUM || type < 0)
55 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
57 ret = _convert_sound_type(type, &volume_type);
58 if (ret == MM_ERROR_NONE) {
59 ret = _get_volume_max_level(DIRECTION_OUT_STR, volume_type, &max_level);
60 if (ret == MM_ERROR_NONE)
61 *max = (int)max_level -1; /* actual volume step can be max step - 1 */
64 return _convert_sound_manager_error_code(__func__, ret);
67 int sound_manager_set_volume(sound_type_e type, int volume)
69 int ret = MM_ERROR_NONE;
71 if (type >= SOUND_TYPE_NUM || type < 0)
72 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
74 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
76 ret = mm_sound_volume_set_value(type, volume);
77 LOGI("type=%d, volume=%d", type, volume);
79 return _convert_sound_manager_error_code(__func__, ret);
82 int sound_manager_get_volume(sound_type_e type, int *volume)
84 int ret = MM_ERROR_NONE;
87 if (type >= SOUND_TYPE_NUM || type < 0)
88 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
90 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
92 ret = mm_sound_volume_get_value(type, &uvolume);
93 if (ret == MM_ERROR_NONE)
96 LOGI("type=%d, volume=%d", type, *volume);
98 return _convert_sound_manager_error_code(__func__, ret);
101 int sound_manager_set_current_sound_type(sound_type_e type)
103 int ret = MM_ERROR_NONE;
105 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
106 if (type >= SOUND_TYPE_NUM || type < 0)
107 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
109 ret = mm_sound_volume_primary_type_set(type);
111 return _convert_sound_manager_error_code(__func__, ret);
114 int sound_manager_get_current_sound_type(sound_type_e *type)
116 int ret = MM_ERROR_NONE;
117 volume_type_t mm_sound_vol_type = VOLUME_TYPE_UNKNOWN;
118 char *volume_type = NULL;
121 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
123 ret = mm_sound_volume_primary_type_get(&mm_sound_vol_type);
124 if (ret == MM_ERROR_NONE) {
125 if (mm_sound_vol_type == VOLUME_TYPE_UNKNOWN) {
126 /* get the volume type of the current playing stream */
127 ret = _get_current_volume_type(DIRECTION_OUT_STR, &volume_type);
128 if (ret == MM_ERROR_NONE)
129 ret = _convert_sound_type_to_enum((const char*)volume_type, type);
131 *type = mm_sound_vol_type;
134 LOGI("type=%d", *type);
136 return _convert_sound_manager_error_code(__func__, ret);
139 int sound_manager_unset_current_sound_type(void)
141 int ret = MM_ERROR_NONE;
143 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
144 ret = mm_sound_volume_primary_type_set(VOLUME_TYPE_UNKNOWN);
146 return _convert_sound_manager_error_code(__func__, ret);
149 int sound_manager_set_volume_changed_cb(sound_manager_volume_changed_cb callback, void* user_data)
151 int ret = MM_ERROR_NONE;
152 unsigned int subs_id = 0;
154 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
155 "Use sound_manager_add_volume_changed_cb() instead.", __func__);
157 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_volume_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
159 ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data, &subs_id);
160 if (ret == MM_ERROR_NONE) {
161 g_volume_changed_cb_table.subs_id = subs_id;
162 g_volume_changed_cb_table.user_cb = (sound_manager_volume_changed_cb)callback;
163 g_volume_changed_cb_table.user_data = user_data;
166 SM_LEAVE_CRITICAL_SECTION(&g_volume_cb_mutex);
168 return _convert_sound_manager_error_code(__func__, ret);
171 int sound_manager_unset_volume_changed_cb(void)
173 int ret = MM_ERROR_NONE;
175 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
176 "Use sound_manager_remove_volume_changed_cb() instead.", __func__);
178 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_volume_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
180 if (g_volume_changed_cb_table.subs_id > 0) {
181 ret = mm_sound_remove_volume_changed_callback(g_volume_changed_cb_table.subs_id);
182 if (ret == MM_ERROR_NONE) {
183 g_volume_changed_cb_table.subs_id = 0;
184 g_volume_changed_cb_table.user_cb = NULL;
185 g_volume_changed_cb_table.user_data = NULL;
188 ret = MM_ERROR_SOUND_INTERNAL;
191 SM_LEAVE_CRITICAL_SECTION(&g_volume_cb_mutex);
193 return _convert_sound_manager_error_code(__func__, ret);
196 int sound_manager_add_volume_changed_cb(sound_manager_volume_changed_cb callback, void *user_data, int *id)
198 int ret = MM_ERROR_NONE;
200 if (!callback || !id)
201 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
203 ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data, (unsigned int*)id);
205 return _convert_sound_manager_error_code(__func__, ret);
208 int sound_manager_remove_volume_changed_cb(int id)
210 int ret = MM_ERROR_NONE;
213 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
215 ret = mm_sound_remove_volume_changed_callback(id);
217 return _convert_sound_manager_error_code(__func__, ret);
220 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)
222 int ret = MM_ERROR_NONE;
226 SM_NULL_ARG_CHECK(stream_info);
228 if (g_session_interrupt_cb_table.is_registered)
229 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INTERNAL);
231 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, MM_ERROR_SOUND_INTERNAL);
233 sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s));
235 ret = MM_ERROR_OUT_OF_MEMORY;
239 memset(stream_h, 0, sizeof(sound_stream_info_s));
240 ret = _convert_stream_type(stream_type, &stream_h->stream_type);
241 if (ret == MM_ERROR_NONE) {
242 ret = _make_pa_connection_and_register_focus(stream_h, false, callback, user_data);
243 if (ret == MM_ERROR_NONE) {
244 *stream_info = (sound_stream_info_h)stream_h;
245 SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret);
246 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);
252 SM_SAFE_FREE(stream_h);
254 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
256 return _convert_sound_manager_error_code(__func__, ret);
259 int sound_manager_destroy_stream_information(sound_stream_info_h stream_info)
261 int ret = MM_ERROR_NONE;
262 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
266 SM_INSTANCE_CHECK(stream_h);
268 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, MM_ERROR_SOUND_INTERNAL);
269 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
270 ret = _destroy_pa_connection_and_unregister_focus(stream_h);
271 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
272 if (ret == MM_ERROR_NONE) {
273 SM_SAFE_FREE(stream_h);
274 SM_UNREF_FOR_STREAM_INFO(g_stream_info_count);
276 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
278 LOGD("cnt(%d)", g_stream_info_count);
280 return _convert_sound_manager_error_code(__func__, ret);
283 int sound_manager_get_sound_type(sound_stream_info_h stream_info, sound_type_e *sound_type)
285 int ret = MM_ERROR_NONE;
286 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
290 SM_INSTANCE_CHECK(stream_h);
291 SM_NULL_ARG_CHECK(sound_type);
293 if (stream_h->stream_conf_info.volume_type == NULL) {
294 ret = MM_ERROR_SOUND_NO_DATA;
298 ret = _convert_sound_type_to_enum(stream_h->stream_conf_info.volume_type, sound_type);
299 LOGI("sound type(%d)", *sound_type);
302 return _convert_sound_manager_error_code(__func__, ret);
305 int sound_manager_add_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
307 int ret = MM_ERROR_NONE;
308 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
312 ret = _add_device_for_stream_routing(stream_h, device);
314 return _convert_sound_manager_error_code(__func__, ret);
317 int sound_manager_remove_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
319 int ret = MM_ERROR_NONE;
320 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
324 ret = _remove_device_for_stream_routing(stream_h, device);
326 return _convert_sound_manager_error_code(__func__, ret);
329 int sound_manager_apply_stream_routing(sound_stream_info_h stream_info)
331 int ret = MM_ERROR_NONE;
332 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
336 ret = _apply_stream_routing(stream_h);
338 return _convert_sound_manager_error_code(__func__, ret);
341 int sound_manager_set_focus_reacquisition(sound_stream_info_h stream_info, bool enable)
343 int ret = MM_ERROR_NONE;
344 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
348 SM_INSTANCE_CHECK(stream_h);
350 ret = mm_sound_set_focus_reacquisition(stream_h->index, enable);
352 LOGI("enable(%d)", enable);
354 return _convert_sound_manager_error_code(__func__, ret);
357 int sound_manager_get_focus_reacquisition(sound_stream_info_h stream_info, bool *enabled)
359 int ret = MM_ERROR_NONE;
360 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
364 SM_INSTANCE_CHECK(stream_h);
365 SM_NULL_ARG_CHECK(enabled);
367 ret = mm_sound_get_focus_reacquisition(stream_h->index, enabled);
369 LOGI("enabled(%d)", *enabled);
371 return _convert_sound_manager_error_code(__func__, ret);
374 int sound_manager_acquire_focus(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, int sound_behavior, const char *extra_info)
376 int ret = MM_ERROR_NONE;
377 bool is_focus_cb_thread = false;
378 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
382 SM_INSTANCE_CHECK(stream_h);
384 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
385 return _convert_sound_manager_error_code(__func__, ret);
387 if (stream_h->is_focus_unavailable) {
388 LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
389 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
392 if (stream_h->user_cb == NULL) {
393 LOGE("focus state changed callback should be set before acquiring focus");
394 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
397 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
399 if (stream_h->acquired_focus & focus_mask) {
400 LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
401 ret = MM_ERROR_SOUND_INVALID_STATE;
405 if (is_focus_cb_thread && ((stream_h->prev_acquired_focus | ~stream_h->acquired_focus) & SOUND_STREAM_FOCUS_FOR_BOTH) != focus_mask) {
406 LOGE("just lost focus in this callback, it is not allowed to acquire the focus[0x%x] again. acquired_focus[0x%x], prev[0x%x]",
407 focus_mask, stream_h->acquired_focus, stream_h->prev_acquired_focus);
408 ret = MM_ERROR_POLICY_INTERNAL;
412 ret = mm_sound_acquire_focus_with_option(stream_h->index, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
413 if (ret == MM_ERROR_NONE) {
414 stream_h->acquired_focus |= focus_mask;
415 stream_h->prev_acquired_focus |= focus_mask;
416 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
419 LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
422 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
424 return _convert_sound_manager_error_code(__func__, ret);
427 int sound_manager_release_focus(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, int sound_behavior, const char *extra_info)
429 int ret = MM_ERROR_NONE;
430 bool is_focus_cb_thread = false;
431 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
435 SM_INSTANCE_CHECK(stream_h);
437 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
438 return _convert_sound_manager_error_code(__func__, ret);
440 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
442 if (!(stream_h->acquired_focus & focus_mask)) {
443 LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
444 ret = MM_ERROR_SOUND_INVALID_STATE;
448 if (is_focus_cb_thread && ((stream_h->prev_acquired_focus & stream_h->acquired_focus) != focus_mask)) {
449 LOGE("just acquired focus in this callback, it is not allowed to release the focus[0x%x] again. acquired_focus[0x%x], prev[0x%x]",
450 focus_mask, stream_h->acquired_focus, stream_h->prev_acquired_focus);
451 ret = MM_ERROR_SOUND_INVALID_STATE;
455 ret = mm_sound_release_focus_with_option(stream_h->index, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
456 if (ret == MM_ERROR_NONE) {
457 stream_h->acquired_focus &= ~focus_mask;
458 stream_h->prev_acquired_focus &= ~focus_mask;
459 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
462 LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
465 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
467 return _convert_sound_manager_error_code(__func__, ret);
470 int sound_manager_acquire_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
472 int ret = MM_ERROR_NONE;
473 int focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH;
474 bool is_focus_cb_thread = false;
475 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
479 SM_INSTANCE_CHECK(stream_h);
481 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
482 return _convert_sound_manager_error_code(__func__, ret);
484 if (stream_h->is_focus_unavailable) {
485 LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
486 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
489 if (stream_h->user_cb == NULL) {
490 LOGE("focus state changed callback should be set before acquiring focus");
491 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
494 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
496 if (is_focus_cb_thread && (stream_h->prev_acquired_focus > stream_h->acquired_focus)) {
497 LOGE("just lost focus in this callback, it is not allowed to acquire all again. acquired_focus[0x%x], prev[0x%x]",
498 stream_h->acquired_focus, stream_h->prev_acquired_focus);
499 ret = MM_ERROR_POLICY_INTERNAL;
503 focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH & ~(stream_h->acquired_focus);
505 LOGI("PLAYBACK/RECORDING focuses have already been ACQUIRED");
510 ret = mm_sound_acquire_focus_with_option(stream_h->index, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
511 if (ret == MM_ERROR_NONE) {
512 stream_h->acquired_focus |= focus_mask;
513 stream_h->prev_acquired_focus |= focus_mask;
514 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
518 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
520 return _convert_sound_manager_error_code(__func__, ret);
523 int sound_manager_release_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
525 int ret = MM_ERROR_NONE;
526 bool is_focus_cb_thread = false;
527 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
531 SM_INSTANCE_CHECK(stream_h);
533 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
534 return _convert_sound_manager_error_code(__func__, ret);
536 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
538 if (is_focus_cb_thread && (stream_h->prev_acquired_focus < stream_h->acquired_focus)) {
539 LOGE("just acquired focus in this callback, it is not allowed to release all again. acquired_focus[0x%x], prev[0x%x]",
540 stream_h->acquired_focus, stream_h->prev_acquired_focus);
541 ret = MM_ERROR_POLICY_INTERNAL;
545 if (!stream_h->acquired_focus) {
546 LOGI("PLAYBACK/RECORDING focuses have already been RELEASED");
551 ret = mm_sound_release_focus_with_option(stream_h->index, (mm_sound_focus_type_e)stream_h->acquired_focus, sound_behavior, extra_info);
552 if (ret == MM_ERROR_NONE) {
553 stream_h->acquired_focus = 0;
554 stream_h->prev_acquired_focus = 0;
555 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
559 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
561 return _convert_sound_manager_error_code(__func__, ret);
564 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)
566 int ret = MM_ERROR_NONE;
567 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
571 SM_INSTANCE_CHECK(stream_h);
572 if (!state_for_playback && !state_for_recording)
573 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
575 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
577 if (state_for_playback)
578 *state_for_playback = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
579 if (state_for_recording)
580 *state_for_recording = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
582 LOGI("acquired_focus(0x%x)", stream_h->acquired_focus);
584 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
586 return _convert_sound_manager_error_code(__func__, ret);
589 int sound_manager_deliver_focus(sound_stream_info_h source, sound_stream_info_h destination, sound_stream_focus_mask_e focus_mask)
591 int ret = MM_ERROR_NONE;
592 sound_stream_info_s *src_stream_h = (sound_stream_info_s*)source;
593 sound_stream_info_s *dst_stream_h = (sound_stream_info_s*)destination;
594 bool is_focus_cb_thread = false;
598 SM_INSTANCE_CHECK(src_stream_h);
599 SM_INSTANCE_CHECK(dst_stream_h);
601 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
602 return _convert_sound_manager_error_code(__func__, ret);
604 if (is_focus_cb_thread) {
605 LOGE("not allowed calling this function in focus(watch) callback");
606 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
609 if (src_stream_h->index == dst_stream_h->index) {
610 LOGE("not allowed because both handles have same index(%u)", src_stream_h->index);
611 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
614 if (src_stream_h->is_focus_unavailable || dst_stream_h->is_focus_unavailable) {
615 LOGE("focus is unavailable for source(%d)/destination(%d)",
616 src_stream_h->is_focus_unavailable, dst_stream_h->is_focus_unavailable);
617 return SOUND_MANAGER_ERROR_POLICY;
620 if (!(src_stream_h->acquired_focus & focus_mask) || (src_stream_h->acquired_focus < focus_mask)) {
621 LOGE("could not deliver the request focus(0x%x), current acquired focus(0x%x)",
622 focus_mask, src_stream_h->acquired_focus);
623 return SOUND_MANAGER_ERROR_INVALID_STATE;
626 if (dst_stream_h->user_cb == NULL) {
627 LOGE("focus state changed callback should be set to destination handle");
628 return SOUND_MANAGER_ERROR_POLICY;
631 ret = mm_sound_deliver_focus(src_stream_h->index, dst_stream_h->index, (mm_sound_focus_type_e)focus_mask);
632 if (ret == MM_ERROR_NONE) {
633 src_stream_h->acquired_focus &= ~focus_mask;
634 src_stream_h->prev_acquired_focus &= ~focus_mask;
635 dst_stream_h->acquired_focus |= focus_mask;
636 dst_stream_h->prev_acquired_focus |= focus_mask;
639 return _convert_sound_manager_error_code(__func__, ret);
642 int sound_manager_is_stream_on_device(sound_stream_info_h stream_info, sound_device_h device, bool *is_on)
644 int ret = MM_ERROR_NONE;
645 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
649 SM_NULL_ARG_CHECK(stream_h);
650 SM_NULL_ARG_CHECK(device);
651 SM_NULL_ARG_CHECK(is_on);
653 ret = mm_sound_is_stream_on_device(stream_h->index, device, is_on);
655 return _convert_sound_manager_error_code(__func__, ret);
658 int sound_manager_get_current_media_playback_device_type(sound_device_type_e *device_type)
660 int ret = MM_ERROR_NONE;
664 SM_NULL_ARG_CHECK(device_type);
666 ret = _get_current_media_routing_path("out", device_type);
668 return _convert_sound_manager_error_code(__func__, ret);
671 int sound_manager_get_current_playback_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
673 int ret = MM_ERROR_NONE;
674 char *stream_type_str = NULL;
675 char *extra_info_str = NULL;
677 bool is_focus_cb_thread = false;
681 SM_NULL_ARG_CHECK(acquired_by);
682 SM_NULL_ARG_CHECK(flags);
684 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
685 return _convert_sound_manager_error_code(__func__, ret);
687 if (is_focus_cb_thread) {
688 LOGE("this API should not be called in focus callback");
689 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
692 ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_PLAYBACK, &stream_type_str, &option, &extra_info_str);
693 if (ret == MM_ERROR_NONE) {
694 LOGI("current acquired PLAYBACK focus : stream_type[%s]", stream_type_str);
695 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
696 if (ret == MM_ERROR_NONE) {
697 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
700 *extra_info = extra_info_str;
702 SM_SAFE_FREE(extra_info_str);
704 SM_SAFE_FREE(stream_type_str);
707 return _convert_sound_manager_error_code(__func__, ret);
710 int sound_manager_get_current_recording_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
712 int ret = MM_ERROR_NONE;
713 char *stream_type_str = NULL;
714 char *extra_info_str = NULL;
716 bool is_focus_cb_thread = false;
720 SM_NULL_ARG_CHECK(acquired_by);
721 SM_NULL_ARG_CHECK(flags);
723 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
724 return _convert_sound_manager_error_code(__func__, ret);
726 if (is_focus_cb_thread) {
727 LOGE("this API should not be called in focus callback");
728 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
731 ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_RECORDING, &stream_type_str, &option, &extra_info_str);
732 if (ret == MM_ERROR_NONE) {
733 LOGI("current acquired RECORDING focus : stream_type[%s]", stream_type_str);
734 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
735 if (ret == MM_ERROR_NONE) {
736 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
739 *extra_info = extra_info_str;
741 SM_SAFE_FREE(extra_info_str);
743 SM_SAFE_FREE(stream_type_str);
746 return _convert_sound_manager_error_code(__func__, ret);
749 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)
751 int ret = MM_ERROR_NONE;
756 SM_NULL_ARG_CHECK(callback);
757 SM_NULL_ARG_CHECK(id);
758 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
760 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
761 if (focus_watch_info_arr[i].id == 0)
763 if (i == SOUND_STREAM_INFO_ARR_MAX) {
764 LOGE("focus watch info array is full");
765 ret = MM_ERROR_SOUND_INTERNAL;
769 ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, &focus_watch_info_arr[i], id);
770 if (ret == MM_ERROR_NONE) {
771 SM_REF_FOR_STREAM_INFO(g_stream_info_count, ret);
772 focus_watch_info_arr[i].id = *id;
773 focus_watch_info_arr[i].user_data = user_data;
774 focus_watch_info_arr[i].user_cb = callback;
778 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
780 LOGD("cnt(%d), id(%d)", g_stream_info_count, *id);
782 return _convert_sound_manager_error_code(__func__, ret);
785 int sound_manager_remove_focus_state_watch_cb(int id)
787 int ret = MM_ERROR_NONE;
792 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_stream_info_count_mutex, SOUND_MANAGER_ERROR_INTERNAL);
794 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
795 if (focus_watch_info_arr[i].id == id)
797 if (i == SOUND_STREAM_INFO_ARR_MAX) {
798 LOGE("cound not find item in focus watch info array for this id(%d)", id);
799 ret = MM_ERROR_INVALID_ARGUMENT;
803 ret = mm_sound_unset_focus_watch_callback(id);
804 if (ret == MM_ERROR_NONE) {
805 SM_UNREF_FOR_STREAM_INFO(g_stream_info_count);
806 focus_watch_info_arr[i].id = 0;
807 focus_watch_info_arr[i].user_data = NULL;
808 focus_watch_info_arr[i].user_cb = NULL;
812 SM_LEAVE_CRITICAL_SECTION(&g_stream_info_count_mutex);
814 LOGD("cnt(%d)", g_stream_info_count);
816 return _convert_sound_manager_error_code(__func__, ret);
819 int sound_manager_set_session_type(sound_session_type_e type)
821 int ret = MM_ERROR_NONE;
822 int cur_session = -1;
823 int new_session = MM_SESSION_TYPE_MEDIA;
824 bool mic_enable = false;
826 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
827 LOGI(">> enter : type=%d", type);
829 if (type < SOUND_SESSION_TYPE_MEDIA || type > SOUND_SESSION_TYPE_VOIP)
830 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
832 /* If session type is VOIP but MIC is not enabled, return false */
833 if (type == SOUND_SESSION_TYPE_VOIP) {
834 ret = system_info_get_platform_bool(FEATURE_MICROPHONE, &mic_enable);
835 LOGI("system_info_platform [%s]=[%d], ret[%d]", FEATURE_MICROPHONE, mic_enable, ret);
836 if (ret != SYSTEM_INFO_ERROR_NONE || !mic_enable)
837 return _convert_sound_manager_error_code(__func__, MM_ERROR_NOT_SUPPORT_API);
840 /* it is not supported both session and stream feature at the same time */
841 if (g_stream_info_count) {
842 LOGE("Could not set this type(%d) because of being used stream feature", type);
843 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
847 case SOUND_SESSION_TYPE_MEDIA:
848 new_session = MM_SESSION_TYPE_MEDIA;
850 case SOUND_SESSION_TYPE_ALARM:
851 new_session = MM_SESSION_TYPE_ALARM;
853 case SOUND_SESSION_TYPE_NOTIFICATION:
854 new_session = MM_SESSION_TYPE_NOTIFY;
856 case SOUND_SESSION_TYPE_EMERGENCY:
857 new_session = MM_SESSION_TYPE_EMERGENCY;
859 case SOUND_SESSION_TYPE_VOIP:
860 new_session = MM_SESSION_TYPE_VOIP;
864 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_session_mutex, SOUND_MANAGER_ERROR_INTERNAL);
866 /* valid session check */
867 ret = mm_session_get_current_type(&cur_session);
868 if (ret == MM_ERROR_NONE) {
869 if (cur_session == MM_SESSION_TYPE_MEDIA_RECORD) {
870 if (type > SOUND_SESSION_TYPE_MEDIA) {
871 LOGE("Could not set this type(%d) during camera/recorder/audio-io(in)/radio", type);
872 ret = MM_ERROR_POLICY_INTERNAL;
878 if (g_session_interrupt_cb_table.is_registered) {
879 if (new_session == cur_session ||
880 ((new_session == SOUND_SESSION_TYPE_MEDIA) && (cur_session == MM_SESSION_TYPE_MEDIA_RECORD))) {
881 LOGI("already set type=%d, ret=0x%x", type, ret);
885 ret = mm_session_finish();
886 if (ret != MM_ERROR_NONE)
889 g_session_interrupt_cb_table.is_registered = 0;
890 if (cur_session == MM_SESSION_TYPE_VOIP) {
891 /* De-initialize regarding VoIP session */
892 g_cached_session_mode = -1;
893 g_cached_voip_device_id = -1;
894 g_cached_voip_device_id2 = -1;
895 if (g_voip_vstream_h) {
896 _stop_progress_virtual_stream(g_voip_vstream_h);
897 g_voip_vstream_h = NULL;
899 if (g_voip_ringtone_vstream_h) {
900 _stop_progress_virtual_stream(g_voip_ringtone_vstream_h);
901 g_voip_ringtone_vstream_h = NULL;
903 if (g_voip_ringtone_stream_info) {
904 if ((ret = mm_sound_release_focus(g_voip_ringtone_stream_info->index, g_voip_ringtone_stream_info->acquired_focus, EXT_INFO_VOIP_SESSION)))
905 LOGE("failed to release focus for ringtone-voip stream info, ret(0x%x)", ret);
906 } else if (g_voip_stream_info) {
907 if ((ret = mm_sound_release_focus(g_voip_stream_info->index, g_voip_stream_info->acquired_focus, EXT_INFO_VOIP_SESSION)))
908 LOGE("failed to release focus for voip stream info, ret(0x%x)", ret);
910 if (g_voip_stream_info) {
911 ret = _destroy_pa_connection_and_unregister_focus(g_voip_stream_info);
912 SM_SAFE_FREE(g_voip_stream_info);
913 if (ret != MM_ERROR_NONE)
916 if (g_voip_ringtone_stream_info) {
917 ret = _destroy_pa_connection_and_unregister_focus(g_voip_ringtone_stream_info);
918 SM_SAFE_FREE(g_voip_ringtone_stream_info);
919 if (ret != MM_ERROR_NONE)
924 ret = mm_session_init(new_session);
925 if (ret == MM_ERROR_NONE)
926 g_session_interrupt_cb_table.is_registered = 1;
928 LOGI("type=%d", type);
930 SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
932 return _convert_sound_manager_error_code(__func__, ret);
935 int sound_manager_get_session_type(sound_session_type_e *type)
937 int ret = MM_ERROR_NONE;
940 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
942 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
944 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_session_mutex, SOUND_MANAGER_ERROR_INVALID_PARAMETER);
946 ret = mm_session_get_current_type(&cur_session);
947 if (ret != MM_ERROR_NONE) {
948 LOGW("session hasn't been set, setting default session");
949 cur_session = SOUND_SESSION_TYPE_DEFAULT;
950 ret = mm_session_init(cur_session);
951 if (ret == MM_ERROR_NONE)
952 g_session_interrupt_cb_table.is_registered = 1;
954 if ((cur_session > MM_SESSION_TYPE_EMERGENCY) &&
955 (cur_session != MM_SESSION_TYPE_VOIP)) {
956 if (g_cached_session != -1)
957 cur_session = g_cached_session;
958 else /* will be never reached here. just prevent code */
959 cur_session = SOUND_SESSION_TYPE_DEFAULT;
962 switch (cur_session) {
963 case MM_SESSION_TYPE_MEDIA:
964 case MM_SESSION_TYPE_MEDIA_RECORD:
965 *type = SOUND_SESSION_TYPE_MEDIA;
967 case MM_SESSION_TYPE_ALARM:
968 *type = SOUND_SESSION_TYPE_ALARM;
970 case MM_SESSION_TYPE_NOTIFY:
971 *type = SOUND_SESSION_TYPE_NOTIFICATION;
973 case MM_SESSION_TYPE_EMERGENCY:
974 *type = SOUND_SESSION_TYPE_EMERGENCY;
976 case MM_SESSION_TYPE_VOIP:
977 *type = SOUND_SESSION_TYPE_VOIP;
984 LOGI("type=%d", *type);
986 SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
988 return SOUND_MANAGER_ERROR_NONE;
991 int sound_manager_set_media_session_option(sound_session_option_for_starting_e s_option, sound_session_option_for_during_play_e d_option)
993 int ret = MM_ERROR_NONE;
995 int session_option = 0;
998 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
999 LOGI(">> enter : option for starting=%d, for during play=%d", s_option, d_option);
1001 if (s_option < 0 || s_option > SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START)
1002 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1003 if (d_option < 0 || d_option > SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY)
1004 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1006 ret = mm_session_get_current_information(&session, &session_option);
1007 if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
1008 LOGW("session hasn't been set, setting default session");
1009 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
1011 g_session_interrupt_cb_table.is_registered = 1;
1013 } else if (ret == 0 && session > MM_SESSION_TYPE_MEDIA) {
1014 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
1015 if (!g_session_interrupt_cb_table.is_registered) {
1016 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
1017 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
1020 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
1025 case SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START:
1026 if (session_option & MM_SESSION_OPTION_PAUSE_OTHERS) {
1027 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_PAUSE_OTHERS);
1029 return _convert_sound_manager_error_code(__func__, ret);
1034 case SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START:
1035 if (!(session_option & MM_SESSION_OPTION_PAUSE_OTHERS)) {
1036 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_PAUSE_OTHERS);
1038 return _convert_sound_manager_error_code(__func__, ret);
1046 case SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY:
1047 if (session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
1048 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_UNINTERRUPTIBLE);
1050 return _convert_sound_manager_error_code(__func__, ret);
1055 case SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY:
1056 if (!(session_option & MM_SESSION_OPTION_UNINTERRUPTIBLE)) {
1057 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_UNINTERRUPTIBLE);
1059 return _convert_sound_manager_error_code(__func__, ret);
1069 LOGI("already set same option(%x), skip it", session_option);
1071 return _convert_sound_manager_error_code(__func__, ret);
1074 int sound_manager_get_media_session_option(sound_session_option_for_starting_e *s_option, sound_session_option_for_during_play_e *d_option)
1076 int ret = MM_ERROR_NONE;
1078 int session_options = 0;
1080 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1083 if (s_option == NULL || d_option == NULL)
1084 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1086 ret = mm_session_get_current_information(&session, &session_options);
1088 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
1090 g_session_interrupt_cb_table.is_registered = 1;
1092 } else if (session > SOUND_SESSION_TYPE_MEDIA) {
1093 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
1094 if (!g_session_interrupt_cb_table.is_registered) {
1095 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
1096 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
1099 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
1102 if (session_options & MM_SESSION_OPTION_PAUSE_OTHERS)
1103 *s_option = SOUND_SESSION_OPTION_PAUSE_OTHERS_WHEN_START;
1105 *s_option = SOUND_SESSION_OPTION_MIX_WITH_OTHERS_WHEN_START;
1107 if (session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE)
1108 *d_option = SOUND_SESSION_OPTION_UNINTERRUPTIBLE_DURING_PLAY;
1110 *d_option = SOUND_SESSION_OPTION_INTERRUPTIBLE_DURING_PLAY;
1112 LOGI(" option for starting=%d, for during play=%d", *s_option, *d_option);
1114 return SOUND_MANAGER_ERROR_NONE;
1117 int sound_manager_set_media_session_resumption_option(sound_session_option_for_resumption_e option)
1119 int ret = MM_ERROR_NONE;
1121 int session_option = 0;
1124 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1125 LOGI(">> enter : option for resumption=%d (0:by system, 1:by system or media paused)", option);
1127 if (option < SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM || option > SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED)
1128 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1130 ret = mm_session_get_current_information(&session, &session_option);
1131 if (ret != 0 || !g_session_interrupt_cb_table.is_registered) {
1132 LOGW("session hasn't been set, setting default session");
1133 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
1135 g_session_interrupt_cb_table.is_registered = 1;
1137 } else if (ret == 0 && session > MM_SESSION_TYPE_MEDIA) {
1138 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
1139 if (!g_session_interrupt_cb_table.is_registered) {
1140 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
1141 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
1144 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
1149 case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM:
1150 if (session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED) {
1151 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_REMOVE, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
1153 return _convert_sound_manager_error_code(__func__, ret);
1158 case SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED:
1159 if (!(session_option & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)) {
1160 ret = mm_session_update_option(MM_SESSION_UPDATE_TYPE_ADD, MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED);
1162 return _convert_sound_manager_error_code(__func__, ret);
1172 LOGI("already set same option(0x%x), skip it", session_option);
1174 return _convert_sound_manager_error_code(__func__, ret);
1177 int sound_manager_get_media_session_resumption_option(sound_session_option_for_resumption_e *option)
1179 int ret = MM_ERROR_NONE;
1181 int session_options = 0;
1183 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1187 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1189 ret = mm_session_get_current_information(&session, &session_options);
1191 LOGW("session hasn't been set, setting default session");
1192 ret = mm_session_init(MM_SESSION_TYPE_MEDIA);
1194 g_session_interrupt_cb_table.is_registered = 1;
1196 } else if (session > SOUND_SESSION_TYPE_MEDIA) {
1197 if (session == MM_SESSION_TYPE_MEDIA_RECORD) {
1198 if (!g_session_interrupt_cb_table.is_registered) {
1199 LOGE("Already set by camera/recorder/audio-io(in)/radio API, but need to set session to Media first");
1200 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
1203 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
1206 if (session_options & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED)
1207 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM_OR_MEDIA_PAUSED;
1209 *option = SOUND_SESSION_OPTION_RESUMPTION_BY_SYSTEM;
1211 LOGI("option for resumption=%d (0:by system, 1:by system or media paused)", *option);
1213 return SOUND_MANAGER_ERROR_NONE;
1216 int sound_manager_set_voip_session_mode(sound_session_voip_mode_e mode)
1218 int ret = MM_ERROR_NONE;
1220 int session_options = 0;
1222 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1223 LOGI(">> enter : mode=%d", mode);
1225 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_session_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1227 ret = mm_session_get_current_information(&session, &session_options);
1228 if (ret != MM_ERROR_NONE)
1231 if (session != MM_SESSION_TYPE_VOIP) {
1232 ret = MM_ERROR_POLICY_INTERNAL;
1236 if (mode < SOUND_SESSION_VOIP_MODE_RINGTONE || mode > SOUND_SESSION_VOIP_MODE_VOICE_WITH_BLUETOOTH) {
1237 ret = MM_ERROR_INVALID_ARGUMENT;
1241 ret = _set_session_mode((_session_mode_e)mode);
1243 LOGI("session=%d, mode=%d(0:RINGTONE 1:MIC_RCV 2:MIC_SPK 3:EAR 4:BT)", session, mode);
1246 SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
1248 return _convert_sound_manager_error_code(__func__, ret);
1251 int sound_manager_get_voip_session_mode(sound_session_voip_mode_e *mode)
1253 int ret = MM_ERROR_NONE;
1255 int session_options = 0;
1257 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1259 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_session_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1262 LOGE("mode is null");
1263 ret = MM_ERROR_INVALID_ARGUMENT;
1267 ret = mm_session_get_current_information(&session, &session_options);
1268 if (ret != MM_ERROR_NONE) {
1269 LOGI("session = %d, option = %d", session, session_options);
1273 if (session != MM_SESSION_TYPE_VOIP || g_cached_session_mode == -1) {
1274 ret = MM_ERROR_POLICY_INTERNAL;
1278 *mode = (sound_session_voip_mode_e)g_cached_session_mode;
1280 LOGI("session=%d, mode=%d", session, *mode);
1283 SM_LEAVE_CRITICAL_SECTION(&g_session_mutex);
1285 return _convert_sound_manager_error_code(__func__, ret);
1288 int sound_manager_set_session_interrupted_cb(sound_session_interrupted_cb callback, void *user_data)
1290 int ret = MM_ERROR_NONE;
1291 unsigned int subs_id = 0;
1293 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_create_stream_information() instead.", __func__);
1294 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_interrupt_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1296 if (callback == NULL) {
1297 ret = MM_ERROR_INVALID_ARGUMENT;
1301 /* it is not supported both session and stream feature at the same time */
1302 if (g_stream_info_count) {
1303 ret = MM_ERROR_POLICY_INTERNAL;
1307 if (g_session_interrupt_cb_table.user_cb == NULL) {
1308 if ((ret = mm_sound_add_device_connected_callback(SOUND_DEVICE_ALL_MASK, (mm_sound_device_connected_cb)_device_connected_cb, NULL, &subs_id))) {
1309 ret = MM_ERROR_INVALID_ARGUMENT;
1312 if ((ret = mm_sound_focus_set_session_interrupt_callback((mm_sound_focus_session_interrupt_cb)_focus_session_interrupt_cb, NULL))) {
1313 if (mm_sound_remove_device_connected_callback(subs_id) != MM_ERROR_NONE)
1314 LOGW("mm_sound_remove_device_connected_callback failed");
1315 ret = MM_ERROR_INVALID_ARGUMENT;
1318 g_session_interrupt_cb_table.subs_id = subs_id;
1320 g_session_interrupt_cb_table.user_cb = (sound_session_interrupted_cb)callback;
1321 g_session_interrupt_cb_table.user_data = user_data;
1324 SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex);
1326 return _convert_sound_manager_error_code(__func__, ret);
1329 int sound_manager_unset_session_interrupted_cb(void)
1331 int ret = MM_ERROR_NONE;
1333 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1334 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_interrupt_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1336 if (!g_session_interrupt_cb_table.user_cb) {
1337 ret = MM_ERROR_SOUND_INTERNAL;
1341 if ((ret = mm_sound_focus_unset_session_interrupt_callback())) {
1342 if (mm_sound_remove_device_connected_callback(g_session_interrupt_cb_table.subs_id) != MM_ERROR_NONE)
1343 LOGW("mm_sound_remove_device_connected_callback failed");
1344 ret = MM_ERROR_SOUND_INTERNAL;
1348 if ((ret = mm_sound_remove_device_connected_callback(g_session_interrupt_cb_table.subs_id))) {
1349 ret = MM_ERROR_SOUND_INTERNAL;
1353 g_session_interrupt_cb_table.subs_id = 0;
1354 g_session_interrupt_cb_table.user_cb = NULL;
1355 g_session_interrupt_cb_table.user_data = NULL;
1358 SM_LEAVE_CRITICAL_SECTION(&g_interrupt_cb_mutex);
1360 return _convert_sound_manager_error_code(__func__, ret);
1363 int sound_manager_get_current_device_list(sound_device_mask_e device_mask, sound_device_list_h *device_list)
1365 int ret = MM_ERROR_NONE;
1367 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. Use sound_manager_get_device_list() instead.", __func__);
1368 ret = mm_sound_get_current_device_list(device_mask, device_list);
1370 return _convert_sound_manager_error_code(__func__, ret);
1373 int sound_manager_get_device_list(int device_mask, sound_device_list_h *device_list)
1375 int ret = MM_ERROR_NONE;
1377 ret = mm_sound_get_device_list(device_mask, device_list);
1379 return _convert_sound_manager_error_code(__func__, ret);
1382 int sound_manager_free_device_list(sound_device_list_h device_list)
1384 int ret = MM_ERROR_NONE;
1386 ret = mm_sound_free_device_list(device_list);
1388 return _convert_sound_manager_error_code(__func__, ret);
1391 int sound_manager_get_next_device(sound_device_list_h device_list, sound_device_h *device)
1393 int ret = MM_ERROR_NONE;
1395 ret = mm_sound_get_next_device(device_list, device);
1397 return _convert_sound_manager_error_code(__func__, ret);
1400 int sound_manager_get_prev_device(sound_device_list_h device_list, sound_device_h *device)
1402 int ret = MM_ERROR_NONE;
1404 ret = mm_sound_get_prev_device(device_list, device);
1406 return _convert_sound_manager_error_code(__func__, ret);
1409 int sound_manager_get_device_type(sound_device_h device, sound_device_type_e *type)
1411 int ret = MM_ERROR_NONE;
1412 mm_sound_device_type_e mm_sound_device_type;
1414 ret = mm_sound_get_device_type(device, &mm_sound_device_type);
1415 if (ret == MM_ERROR_NONE)
1416 ret = _convert_device_type(mm_sound_device_type, type);
1418 return _convert_sound_manager_error_code(__func__, ret);
1421 int sound_manager_get_device_io_direction(sound_device_h device, sound_device_io_direction_e *io_direction)
1423 int ret = MM_ERROR_NONE;
1424 mm_sound_device_io_direction_e mm_sound_io_direction;
1426 ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction);
1427 if (ret == MM_ERROR_NONE)
1428 ret = _convert_device_io_direction(mm_sound_io_direction, io_direction);
1430 return _convert_sound_manager_error_code(__func__, ret);
1433 int sound_manager_get_device_id(sound_device_h device, int *id)
1435 int ret = MM_ERROR_NONE;
1437 ret = mm_sound_get_device_id(device, id);
1439 return _convert_sound_manager_error_code(__func__, ret);
1442 int sound_manager_get_device_name(sound_device_h device, char **name)
1444 int ret = MM_ERROR_NONE;
1446 ret = mm_sound_get_device_name(device, name);
1448 return _convert_sound_manager_error_code(__func__, ret);
1451 int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *state)
1453 int ret = MM_ERROR_NONE;
1455 ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
1457 return _convert_sound_manager_error_code(__func__, ret);
1460 int sound_manager_set_device_connected_cb(sound_device_mask_e device_mask, sound_device_connected_cb callback, void *user_data)
1462 int ret = MM_ERROR_NONE;
1463 unsigned int subs_id = 0;
1465 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
1466 "Use sound_manager_add_device_connection_changed_cb() instead.", __func__);
1468 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1470 ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data, &subs_id);
1471 if (ret == MM_ERROR_NONE) {
1472 g_device_connected_cb_table.subs_id = subs_id;
1473 g_device_connected_cb_table.user_cb = (sound_device_connected_cb)callback;
1474 g_device_connected_cb_table.user_data = user_data;
1477 SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex);
1479 return _convert_sound_manager_error_code(__func__, ret);
1482 int sound_manager_unset_device_connected_cb(void)
1484 int ret = MM_ERROR_NONE;
1486 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
1487 "Use sound_manager_remove_device_connection_changed_cb() instead.", __func__);
1489 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_conn_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1491 if (g_device_connected_cb_table.subs_id == 0) {
1492 ret = MM_ERROR_SOUND_INTERNAL;
1496 ret = mm_sound_remove_device_connected_callback(g_device_connected_cb_table.subs_id);
1497 if (ret == MM_ERROR_NONE) {
1498 g_device_connected_cb_table.subs_id = 0;
1499 g_device_connected_cb_table.user_cb = NULL;
1500 g_device_connected_cb_table.user_data = NULL;
1504 SM_LEAVE_CRITICAL_SECTION(&g_device_conn_cb_mutex);
1506 return _convert_sound_manager_error_code(__func__, ret);
1509 int sound_manager_add_device_connection_changed_cb(int device_mask, sound_device_connected_cb callback, void *user_data, int *id)
1511 int ret = MM_ERROR_NONE;
1513 if (!callback || !id)
1514 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1516 ret = mm_sound_add_device_connected_callback((mm_sound_device_flags_e)device_mask, (mm_sound_device_connected_cb)callback, user_data, (unsigned int*)id);
1518 return _convert_sound_manager_error_code(__func__, ret);
1521 int sound_manager_remove_device_connection_changed_cb(int id)
1523 int ret = MM_ERROR_NONE;
1526 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1528 ret = mm_sound_remove_device_connected_callback((unsigned int)id);
1530 return _convert_sound_manager_error_code(__func__, ret);
1533 int sound_manager_set_device_information_changed_cb(sound_device_mask_e device_mask, sound_device_information_changed_cb callback, void *user_data)
1535 int ret = MM_ERROR_NONE;
1536 unsigned int subs_id = 0;
1538 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
1539 "Use sound_manager_add_device_state_changed_cb() instead.", __func__);
1540 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1542 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);
1543 if (ret == MM_ERROR_NONE) {
1544 g_device_info_changed_cb_table.subs_id = subs_id;
1545 g_device_info_changed_cb_table.user_cb = (sound_device_information_changed_cb)callback;
1546 g_device_info_changed_cb_table.user_data = user_data;
1549 SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex);
1551 return _convert_sound_manager_error_code(__func__, ret);
1554 int sound_manager_unset_device_information_changed_cb(void)
1556 int ret = MM_ERROR_NONE;
1558 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release. "
1559 "Use sound_manager_remove_device_state_changed_cb() instead.", __func__);
1560 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_device_info_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1562 if (g_device_info_changed_cb_table.subs_id == 0) {
1563 ret = MM_ERROR_SOUND_INTERNAL;
1567 ret = mm_sound_remove_device_information_changed_callback(g_device_info_changed_cb_table.subs_id);
1568 if (ret == MM_ERROR_NONE) {
1569 g_device_info_changed_cb_table.subs_id = 0;
1570 g_device_info_changed_cb_table.user_cb = NULL;
1571 g_device_info_changed_cb_table.user_data = NULL;
1575 SM_LEAVE_CRITICAL_SECTION(&g_device_info_cb_mutex);
1577 return _convert_sound_manager_error_code(__func__, ret);
1580 int sound_manager_add_device_state_changed_cb(int device_mask, sound_device_state_changed_cb callback, void *user_data, int *id)
1582 int ret = MM_ERROR_NONE;
1584 if (!callback || !id)
1585 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1587 ret = mm_sound_add_device_state_changed_callback(device_mask, (mm_sound_device_state_changed_cb)callback, user_data, (unsigned int*)id);
1589 return _convert_sound_manager_error_code(__func__, ret);
1592 int sound_manager_remove_device_state_changed_cb(int id)
1594 int ret = MM_ERROR_NONE;
1597 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1599 ret = mm_sound_remove_device_state_changed_callback((unsigned int)id);
1601 return _convert_sound_manager_error_code(__func__, ret);
1604 __attribute__ ((destructor))
1605 void __sound_manager_finalize(void)
1607 int ret = MM_ERROR_NONE;
1609 if (g_session_interrupt_cb_table.is_registered) {
1611 ret = mm_session_finish();
1612 if (ret != MM_ERROR_NONE)
1613 LOGE("[%s] failed to mm_session_finish(), ret(0x%x)", __func__, ret);
1615 g_session_interrupt_cb_table.is_registered = 0;
1620 __attribute__ ((constructor))
1621 void __sound_manager_initialize(void)