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"
20 static int ducking_arr_count;
21 static unsigned int ducking_cb_subs_id;
22 static pthread_mutex_t ducking_mutex;
23 static sound_stream_ducking_s *ducking_arr[SOUND_DUCKING_ARR_MAX];
25 _focus_watch_info_s focus_watch_info_arr[SOUND_STREAM_INFO_ARR_MAX];
27 static void _ducking_state_changed_cb(int pa_index, bool is_ducked, void *user_data)
31 SM_ENTER_CRITICAL_SECTION(&ducking_mutex);
33 for (i = 0 ; i < SOUND_DUCKING_ARR_MAX ; i++) {
34 if (ducking_arr[i] && ducking_arr[i]->pa_info.index == pa_index) {
35 LOGI("ducking state changed [i:%d,ducked:%u]", pa_index, is_ducked);
36 if (ducking_arr[i]->user_cb)
37 ducking_arr[i]->user_cb((sound_stream_ducking_h)ducking_arr[i], is_ducked, ducking_arr[i]->user_data);
39 LOGW("no user callback for pa_index %d", pa_index);
44 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
49 int sound_manager_get_max_volume(sound_type_e type, int *max)
51 const char *volume_type = NULL;
52 unsigned int max_level = 0;
53 int ret = SOUND_MANAGER_ERROR_NONE;
56 SM_ARG_CHECK(type < SOUND_TYPE_NUM);
58 LOGI("type[%d]", type);
60 ret = _convert_sound_type(type, &volume_type);
61 if (ret == SOUND_MANAGER_ERROR_NONE) {
62 ret = _get_volume_max_level(DIRECTION_OUT_STR, volume_type, &max_level);
63 if (ret == SOUND_MANAGER_ERROR_NONE) {
64 *max = (int)max_level -1; /* actual volume step can be max step - 1 */
65 LOGI("volume_type[%s] max_volume[%d]", volume_type, *max);
69 LOGI("ret[0x%x]", ret);
74 int sound_manager_set_volume(sound_type_e type, int volume)
76 int ret = MM_ERROR_NONE;
78 SM_ARG_CHECK(type < SOUND_TYPE_NUM);
79 SM_ARG_CHECK(volume >= 0);
81 LOGI("type[%d] volume[%d]", type, volume);
83 ret = mm_sound_volume_set_value(type, volume);
85 return _convert_sound_manager_error_code(__func__, ret);
88 int sound_manager_get_volume(sound_type_e type, int *volume)
90 int ret = MM_ERROR_NONE;
93 SM_ARG_CHECK(type < SOUND_TYPE_NUM);
96 LOGI("type[%d]", type);
98 ret = mm_sound_volume_get_value(type, &uvolume);
99 if (ret == MM_ERROR_NONE) {
101 LOGI("volume[%d]", *volume);
104 return _convert_sound_manager_error_code(__func__, ret);
107 int sound_manager_get_current_sound_type(sound_type_e *type)
109 int ret = SOUND_MANAGER_ERROR_NONE;
110 char *volume_type = NULL;
114 /* get the volume type of the current playing stream */
115 ret = _get_current_volume_type(DIRECTION_OUT_STR, &volume_type);
116 if (ret == SOUND_MANAGER_ERROR_NONE) {
117 ret = _convert_sound_type_to_enum((const char*)volume_type, type);
118 if (ret == SOUND_MANAGER_ERROR_NONE)
119 LOGI("type[%d]", *type);
122 LOGI("ret[0x%x]", ret);
127 int sound_manager_add_volume_changed_cb(sound_manager_volume_changed_cb callback, void *user_data, int *id)
129 int ret = MM_ERROR_NONE;
131 SM_ARG_CHECK(callback);
134 LOGI("callback[%p] user_data[%p]", callback, user_data);
136 ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data, (unsigned int*)id);
140 return _convert_sound_manager_error_code(__func__, ret);
143 int sound_manager_remove_volume_changed_cb(int id)
145 int ret = MM_ERROR_NONE;
147 SM_ARG_CHECK(id >= 0);
151 ret = mm_sound_remove_volume_changed_callback(id);
153 return _convert_sound_manager_error_code(__func__, ret);
156 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)
158 int ret = SOUND_MANAGER_ERROR_NONE;
160 SM_ARG_CHECK(stream_info);
162 LOGI("stream_type[%d] callback[%p] user_data[%p]", stream_type, callback, user_data);
164 sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s));
166 ret = SOUND_MANAGER_ERROR_INTERNAL;
170 memset(stream_h, 0, sizeof(sound_stream_info_s));
171 ret = _convert_stream_type(stream_type, &stream_h->stream_type);
172 if (ret == SOUND_MANAGER_ERROR_NONE) {
173 ret = _make_pa_connection_and_register_focus(stream_h, callback, user_data);
174 if (ret == SOUND_MANAGER_ERROR_NONE) {
175 *stream_info = (sound_stream_info_h)stream_h;
176 LOGI("stream_info[%p, type:%s] pa_index[%u] focus_id[%d]",
177 stream_info, stream_h->stream_type, stream_h->pa_info.index, stream_h->focus_id);
182 if (ret != SOUND_MANAGER_ERROR_NONE)
183 SM_SAFE_FREE(stream_h);
185 LOGI("ret[0x%x]", ret);
190 int sound_manager_destroy_stream_information(sound_stream_info_h stream_info)
192 int ret = SOUND_MANAGER_ERROR_NONE;
193 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
195 SM_ARG_CHECK(stream_h);
197 LOGI("stream_info[%p, type:%s]", stream_info, stream_h->stream_type);
199 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->vstream_mutex, SOUND_MANAGER_ERROR_INTERNAL);
200 if (stream_h->vstream) {
201 LOGE("virtual stream is still alive");
202 SM_LEAVE_CRITICAL_SECTION(&stream_h->vstream_mutex);
203 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
205 SM_LEAVE_CRITICAL_SECTION(&stream_h->vstream_mutex);
207 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
208 ret = _destroy_pa_connection_and_unregister_focus(stream_h);
209 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
210 if (ret == SOUND_MANAGER_ERROR_NONE)
211 SM_SAFE_FREE(stream_h);
213 LOGI("ret[0x%x]", ret);
218 int sound_manager_get_sound_type(sound_stream_info_h stream_info, sound_type_e *sound_type)
220 int ret = SOUND_MANAGER_ERROR_NONE;
221 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
223 SM_ARG_CHECK(stream_h);
224 SM_ARG_CHECK(sound_type);
226 LOGI("stream_info[%p, type:%s]", stream_info, stream_h->stream_type);
228 if (stream_h->stream_conf_info.volume_type == NULL) {
229 ret = SOUND_MANAGER_ERROR_NO_DATA;
230 LOGW("There's no sound type for this stream_info(%p)", stream_info);
234 ret = _convert_sound_type_to_enum(stream_h->stream_conf_info.volume_type, sound_type);
235 LOGI("sound type(%d)", *sound_type);
238 LOGI("ret[0x%x]", ret);
243 int sound_manager_add_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
245 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
247 SM_ARG_CHECK(stream_h);
248 SM_ARG_CHECK(device);
250 LOGI("stream_info[%p, type:%s] device[%p]", stream_info, stream_h->stream_type, device);
252 return _add_device_for_stream_routing(stream_h, device);
255 int sound_manager_remove_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
257 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
259 SM_ARG_CHECK(stream_h);
260 SM_ARG_CHECK(device);
262 LOGI("stream_info[%p, type:%s] device[%p]", stream_info, stream_h->stream_type, device);
264 return _remove_device_for_stream_routing(stream_h, device);
267 int sound_manager_remove_all_devices_for_stream_routing(sound_stream_info_h stream_info)
269 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
271 SM_ARG_CHECK(stream_h);
273 LOGI("stream_info[%p, type:%s]", stream_info, stream_h->stream_type);
275 return _remove_all_devices_for_stream_routing(stream_h);
278 int sound_manager_apply_stream_routing(sound_stream_info_h stream_info)
280 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
282 SM_ARG_CHECK(stream_h);
284 LOGI("stream_info[%p, type:%s]", stream_info, stream_h->stream_type);
286 return _apply_stream_routing(stream_h);
289 int sound_manager_set_stream_preferred_device(sound_stream_info_h stream_info, sound_device_io_direction_e io_direction, sound_device_h device)
291 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
293 SM_ARG_CHECK(stream_h);
295 LOGI("stream_info[%p, type:%s] io_direction[%d] device[%p]", stream_info, stream_h->stream_type, io_direction, device);
297 return _set_preferred_device(stream_h, io_direction, device);
300 int sound_manager_get_stream_preferred_device(sound_stream_info_h stream_info, int *in_device_id, int *out_device_id)
302 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
304 SM_ARG_CHECK(stream_h);
305 SM_ARG_CHECK(in_device_id || out_device_id);
307 LOGI("stream_info[%p, type:%s]", stream_info, stream_h->stream_type);
309 return _get_preferred_device(stream_h, in_device_id, out_device_id);
312 int sound_manager_set_focus_reacquisition(sound_stream_info_h stream_info, bool enable)
314 int ret = MM_ERROR_NONE;
315 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
317 SM_ARG_CHECK(stream_h);
319 LOGI("stream_info[%p, type:%s, focus_id:%d] enable[%d]", stream_info, stream_h->stream_type, stream_h->focus_id, enable);
321 ret = mm_sound_set_focus_reacquisition(stream_h->focus_id, enable);
323 return _convert_sound_manager_error_code(__func__, ret);
326 int sound_manager_get_focus_reacquisition(sound_stream_info_h stream_info, bool *enabled)
328 int ret = MM_ERROR_NONE;
329 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
331 SM_ARG_CHECK(stream_h);
332 SM_ARG_CHECK(enabled);
334 LOGI("stream_info[%p, type:%s, focus_id:%d]", stream_info, stream_h->stream_type, stream_h->focus_id);
336 ret = mm_sound_get_focus_reacquisition(stream_h->focus_id, enabled);
338 LOGI("enabled(%d)", *enabled);
340 return _convert_sound_manager_error_code(__func__, ret);
343 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)
345 int ret = MM_ERROR_NONE;
346 bool is_focus_cb_thread = false;
347 bool is_focus_watch_cb_thread = false;
348 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
350 SM_ARG_CHECK(stream_h);
352 LOGI("stream_info[%p, type:%s, focus_id:%d] focus_mask[0x%x] sound_behavior[0x%x] extra_info[%s]",
353 stream_info, stream_h->stream_type, stream_h->focus_id, focus_mask, sound_behavior, extra_info);
355 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)) != MM_ERROR_NONE)
356 return _convert_sound_manager_error_code(__func__, ret);
358 if (stream_h->is_focus_unavailable) {
359 LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
360 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
363 if (stream_h->user_cb == NULL) {
364 LOGE("focus state changed callback should be set before acquiring focus");
365 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
368 if (!is_focus_cb_thread) {
369 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
370 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
372 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
373 * the focus state mutex could be still locked. Therefore, it returns error here. */
374 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
375 LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
376 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
378 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
381 if (stream_h->acquired_focus & focus_mask) {
382 LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
383 ret = MM_ERROR_SOUND_INVALID_STATE;
387 if (is_focus_cb_thread && ((stream_h->prev_acquired_focus & ~stream_h->acquired_focus) & focus_mask)) {
388 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]",
389 focus_mask, stream_h->acquired_focus, stream_h->prev_acquired_focus);
390 ret = MM_ERROR_POLICY_INTERNAL;
394 stream_h->is_requesting = true;
396 ret = mm_sound_acquire_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
397 if (ret == MM_ERROR_NONE) {
398 stream_h->acquired_focus |= focus_mask;
399 stream_h->prev_acquired_focus |= focus_mask;
400 _update_focus_status(stream_h->pa_info.index, (unsigned int)stream_h->acquired_focus);
403 LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
406 stream_h->is_requesting = false;
407 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
408 if (!is_focus_cb_thread)
409 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
411 return _convert_sound_manager_error_code(__func__, ret);
414 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)
416 int ret = MM_ERROR_NONE;
417 bool is_focus_cb_thread = false;
418 bool is_focus_watch_cb_thread = false;
419 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
421 SM_ARG_CHECK(stream_h);
423 LOGI("stream_info[%p, type:%s, focus_id:%d] focus_mask[0x%x] sound_behavior[0x%x] extra_info[%s]",
424 stream_info, stream_h->stream_type, stream_h->focus_id, focus_mask, sound_behavior, extra_info);
426 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)) != MM_ERROR_NONE)
427 return _convert_sound_manager_error_code(__func__, ret);
429 if (!is_focus_cb_thread) {
430 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
431 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
433 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
434 * the focus state mutex could be still locked. Therefore, it returns error here. */
435 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
436 LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
437 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
439 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_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 stream_h->is_requesting = true;
457 ret = mm_sound_release_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
458 if (ret == MM_ERROR_NONE) {
459 stream_h->acquired_focus &= ~focus_mask;
460 stream_h->prev_acquired_focus &= ~focus_mask;
461 _update_focus_status(stream_h->pa_info.index, (unsigned int)stream_h->acquired_focus);
464 LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
467 stream_h->is_requesting = false;
468 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
469 if (!is_focus_cb_thread)
470 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
472 return _convert_sound_manager_error_code(__func__, ret);
475 int sound_manager_acquire_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
477 int ret = MM_ERROR_NONE;
478 int focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH;
479 bool is_focus_cb_thread = false;
480 bool is_focus_watch_cb_thread = false;
481 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
483 SM_ARG_CHECK(stream_h);
485 LOGI("stream_info[%p, type:%s, focus_id:%d] sound_behavior[0x%x] extra_info[%s]",
486 stream_info, stream_h->stream_type, stream_h->focus_id, sound_behavior, extra_info);
488 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)) != MM_ERROR_NONE)
489 return _convert_sound_manager_error_code(__func__, ret);
491 if (stream_h->is_focus_unavailable) {
492 LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
493 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
496 if (stream_h->user_cb == NULL) {
497 LOGE("focus state changed callback should be set before acquiring focus");
498 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
501 if (!is_focus_cb_thread) {
502 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
503 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
505 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
506 * the focus state mutex could be still locked. Therefore, it returns error here. */
507 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
508 LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
509 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
511 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
514 if (is_focus_cb_thread && (stream_h->prev_acquired_focus > stream_h->acquired_focus)) {
515 LOGE("just lost focus in this callback, it is not allowed to acquire all again. acquired_focus[0x%x], prev[0x%x]",
516 stream_h->acquired_focus, stream_h->prev_acquired_focus);
517 ret = MM_ERROR_POLICY_INTERNAL;
521 focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH & ~(stream_h->acquired_focus);
523 LOGI("PLAYBACK/RECORDING focuses have already been ACQUIRED");
528 stream_h->is_requesting = true;
530 ret = mm_sound_acquire_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
531 if (ret == MM_ERROR_NONE) {
532 stream_h->acquired_focus |= focus_mask;
533 stream_h->prev_acquired_focus |= focus_mask;
534 _update_focus_status(stream_h->pa_info.index, (unsigned int)stream_h->acquired_focus);
538 stream_h->is_requesting = false;
539 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
540 if (!is_focus_cb_thread)
541 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
543 return _convert_sound_manager_error_code(__func__, ret);
546 int sound_manager_release_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
548 int ret = MM_ERROR_NONE;
549 bool is_focus_cb_thread = false;
550 bool is_focus_watch_cb_thread = false;
551 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
553 SM_ARG_CHECK(stream_h);
555 LOGI("stream_info[%p, type:%s, focus_id:%d] sound_behavior[0x%x] extra_info[%s]",
556 stream_info, stream_h->stream_type, stream_h->focus_id, sound_behavior, extra_info);
558 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)) != MM_ERROR_NONE)
559 return _convert_sound_manager_error_code(__func__, ret);
561 if (!is_focus_cb_thread) {
562 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
563 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, SOUND_MANAGER_ERROR_INTERNAL);
565 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
566 * the focus state mutex could be still locked. Therefore, it returns error here. */
567 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
568 LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
569 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
571 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
574 if (is_focus_cb_thread && (stream_h->prev_acquired_focus < stream_h->acquired_focus)) {
575 LOGE("just acquired focus in this callback, it is not allowed to release all again. acquired_focus[0x%x], prev[0x%x]",
576 stream_h->acquired_focus, stream_h->prev_acquired_focus);
577 ret = MM_ERROR_POLICY_INTERNAL;
581 if (!stream_h->acquired_focus) {
582 LOGI("PLAYBACK/RECORDING focuses have already been RELEASED");
587 stream_h->is_requesting = true;
589 ret = mm_sound_release_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)stream_h->acquired_focus, sound_behavior, extra_info);
590 if (ret == MM_ERROR_NONE) {
591 stream_h->acquired_focus = 0;
592 stream_h->prev_acquired_focus = 0;
593 _update_focus_status(stream_h->pa_info.index, (unsigned int)stream_h->acquired_focus);
597 stream_h->is_requesting = false;
598 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
599 if (!is_focus_cb_thread)
600 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
602 return _convert_sound_manager_error_code(__func__, ret);
605 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)
607 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
609 SM_ARG_CHECK(stream_h);
610 SM_ARG_CHECK(state_for_playback || state_for_recording);
612 LOGI("stream_info[%p, type:%s, focus_id:%d]", stream_info, stream_h->stream_type, stream_h->focus_id);
614 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
616 if (state_for_playback)
617 *state_for_playback = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
618 if (state_for_recording)
619 *state_for_recording = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
621 LOGI("acquired_focus(0x%x)", stream_h->acquired_focus);
623 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
625 return SOUND_MANAGER_ERROR_NONE;
628 int sound_manager_deliver_focus(sound_stream_info_h source, sound_stream_info_h destination, sound_stream_focus_mask_e focus_mask)
630 int ret = MM_ERROR_NONE;
631 sound_stream_info_s *src_stream_h = (sound_stream_info_s*)source;
632 sound_stream_info_s *dst_stream_h = (sound_stream_info_s*)destination;
633 bool is_focus_cb_thread = false;
635 SM_ARG_CHECK(src_stream_h);
636 SM_ARG_CHECK(dst_stream_h);
638 LOGI("SRC stream_info[%p, type:%s, focus_id:%d]", source, src_stream_h->stream_type, src_stream_h->focus_id);
639 LOGI("DST stream_info[%p, type:%s, focus_id:%d]", destination, dst_stream_h->stream_type, dst_stream_h->focus_id);
640 LOGI("focus_mask[0x%x]", focus_mask);
642 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)) != MM_ERROR_NONE)
643 return _convert_sound_manager_error_code(__func__, ret);
645 if (is_focus_cb_thread) {
646 LOGE("not allowed calling this function in focus(watch) callback");
647 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
650 if (src_stream_h->focus_id == dst_stream_h->focus_id) {
651 LOGE("not allowed because both handles have same id(%u)", src_stream_h->focus_id);
652 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
655 if (src_stream_h->is_focus_unavailable || dst_stream_h->is_focus_unavailable) {
656 LOGE("focus is unavailable for source(%d)/destination(%d)",
657 src_stream_h->is_focus_unavailable, dst_stream_h->is_focus_unavailable);
658 return SOUND_MANAGER_ERROR_POLICY;
661 if (!(src_stream_h->acquired_focus & focus_mask) || (src_stream_h->acquired_focus < focus_mask)) {
662 LOGE("could not deliver the request focus(0x%x), current acquired focus(0x%x)",
663 focus_mask, src_stream_h->acquired_focus);
664 return SOUND_MANAGER_ERROR_INVALID_STATE;
667 if (dst_stream_h->user_cb == NULL) {
668 LOGE("focus state changed callback should be set to destination handle");
669 return SOUND_MANAGER_ERROR_POLICY;
672 ret = mm_sound_deliver_focus(src_stream_h->focus_id, dst_stream_h->focus_id, (mm_sound_focus_type_e)focus_mask);
673 if (ret == MM_ERROR_NONE) {
674 src_stream_h->acquired_focus &= ~focus_mask;
675 src_stream_h->prev_acquired_focus &= ~focus_mask;
676 dst_stream_h->acquired_focus |= focus_mask;
677 dst_stream_h->prev_acquired_focus |= focus_mask;
680 return _convert_sound_manager_error_code(__func__, ret);
683 int sound_manager_is_stream_on_device(sound_stream_info_h stream_info, sound_device_h device, bool *is_on)
685 int ret = MM_ERROR_NONE;
686 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
688 SM_ARG_CHECK(stream_h);
689 SM_ARG_CHECK(device);
692 LOGI("stream_info[%p, type:%s] device[%p]", stream_info, stream_h->stream_type, device);
694 ret = mm_sound_is_stream_on_device(stream_h->pa_info.index, device, is_on);
696 LOGI("is_on[%d]", *is_on);
698 return _convert_sound_manager_error_code(__func__, ret);
701 int sound_manager_get_current_media_playback_device_type(sound_device_type_e *device_type)
703 SM_ARG_CHECK(device_type);
705 return _get_current_media_routing_path("out", device_type);
708 int sound_manager_get_current_playback_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
710 int ret = SOUND_MANAGER_ERROR_NONE;
711 int mm_ret = MM_ERROR_NONE;
712 char *stream_type_str = NULL;
713 char *extra_info_str = NULL;
715 bool is_focus_cb_thread = false;
717 SM_ARG_CHECK(acquired_by);
720 if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)) != MM_ERROR_NONE)
721 return _convert_sound_manager_error_code(__func__, mm_ret);
723 if (is_focus_cb_thread) {
724 LOGE("this API should not be called in focus callback");
725 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
728 mm_ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_PLAYBACK, &stream_type_str, &option, &extra_info_str);
729 if (mm_ret != MM_ERROR_NONE)
730 return _convert_sound_manager_error_code(__func__, mm_ret);
732 LOGI("current acquired PLAYBACK focus : stream_type[%s]", stream_type_str);
733 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
734 if (ret == SOUND_MANAGER_ERROR_NONE) {
735 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
738 *extra_info = strdup(extra_info_str);
740 SM_SAFE_FREE(stream_type_str);
741 SM_SAFE_FREE(extra_info_str);
746 int sound_manager_get_current_recording_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
748 int ret = SOUND_MANAGER_ERROR_NONE;
749 int mm_ret = MM_ERROR_NONE;
750 char *stream_type_str = NULL;
751 char *extra_info_str = NULL;
753 bool is_focus_cb_thread = false;
755 SM_ARG_CHECK(acquired_by);
758 if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)) != MM_ERROR_NONE)
759 return _convert_sound_manager_error_code(__func__, mm_ret);
761 if (is_focus_cb_thread) {
762 LOGE("this API should not be called in focus callback");
763 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
766 mm_ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_RECORDING, &stream_type_str, &option, &extra_info_str);
767 if (mm_ret != MM_ERROR_NONE)
768 return _convert_sound_manager_error_code(__func__, mm_ret);
770 LOGI("current acquired RECORDING focus : stream_type[%s]", stream_type_str);
771 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
772 if (ret == SOUND_MANAGER_ERROR_NONE) {
773 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
776 *extra_info = strdup(extra_info_str);
778 SM_SAFE_FREE(stream_type_str);
779 SM_SAFE_FREE(extra_info_str);
784 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)
786 int ret = MM_ERROR_NONE;
789 SM_ARG_CHECK(callback);
792 LOGI("focus_mask[0x%x] callback[%p] user_data[%p]", focus_mask, callback, user_data);
794 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
795 if (focus_watch_info_arr[i].id == 0)
797 if (i == SOUND_STREAM_INFO_ARR_MAX) {
799 LOGE("focus watch info array is full");
800 ret = MM_ERROR_SOUND_INTERNAL;
805 ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, &focus_watch_info_arr[i], id);
806 if (ret == MM_ERROR_NONE) {
807 focus_watch_info_arr[i].id = *id;
808 focus_watch_info_arr[i].user_data = user_data;
809 focus_watch_info_arr[i].user_cb = callback;
815 return _convert_sound_manager_error_code(__func__, ret);
818 int sound_manager_remove_focus_state_watch_cb(int id)
820 int ret = MM_ERROR_NONE;
825 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
826 if (focus_watch_info_arr[i].id == id)
828 if (i == SOUND_STREAM_INFO_ARR_MAX) {
829 LOGE("could not find item in focus watch info array for this id(%d)", id);
830 ret = MM_ERROR_INVALID_ARGUMENT;
834 ret = mm_sound_unset_focus_watch_callback(id);
835 if (ret == MM_ERROR_NONE) {
836 focus_watch_info_arr[i].id = 0;
837 focus_watch_info_arr[i].user_data = NULL;
838 focus_watch_info_arr[i].user_cb = NULL;
842 return _convert_sound_manager_error_code(__func__, ret);
845 int sound_manager_get_device_list(int device_mask, sound_device_list_h *device_list)
847 int ret = MM_ERROR_NONE;
849 SM_ARG_CHECK(device_list);
851 LOGI("device_mask[0x%x]", device_mask);
853 ret = mm_sound_get_device_list(device_mask, device_list);
855 LOGI("device_list[%p]", *device_list);
857 return _convert_sound_manager_error_code(__func__, ret);
860 int sound_manager_free_device_list(sound_device_list_h device_list)
862 int ret = MM_ERROR_NONE;
864 SM_ARG_CHECK(device_list);
866 LOGI("device_list[%p]", device_list);
868 ret = mm_sound_free_device_list(device_list);
870 return _convert_sound_manager_error_code(__func__, ret);
873 int sound_manager_get_next_device(sound_device_list_h device_list, sound_device_h *device)
875 int ret = MM_ERROR_NONE;
877 SM_ARG_CHECK(device_list);
878 SM_ARG_CHECK(device);
880 LOGI("device_list[%p]", device_list);
882 ret = mm_sound_get_next_device(device_list, device);
884 LOGI("device[%p]", *device);
886 return _convert_sound_manager_error_code(__func__, ret);
889 int sound_manager_get_prev_device(sound_device_list_h device_list, sound_device_h *device)
891 int ret = MM_ERROR_NONE;
893 SM_ARG_CHECK(device_list);
894 SM_ARG_CHECK(device);
896 LOGI("device_list[%p]", device_list);
898 ret = mm_sound_get_prev_device(device_list, device);
900 LOGI("device[%p]", *device);
902 return _convert_sound_manager_error_code(__func__, ret);
905 int sound_manager_get_device_type(sound_device_h device, sound_device_type_e *type)
907 int ret = MM_ERROR_NONE;
908 mm_sound_device_type_e mm_sound_device_type;
910 SM_ARG_CHECK(device);
913 LOGI("device[%p]", device);
915 if ((ret = mm_sound_get_device_type(device, &mm_sound_device_type)) != MM_ERROR_NONE)
916 return _convert_sound_manager_error_code(__func__, ret);
918 return _convert_device_type(mm_sound_device_type, type);
921 int sound_manager_get_device_io_direction(sound_device_h device, sound_device_io_direction_e *io_direction)
923 int ret = MM_ERROR_NONE;
924 mm_sound_device_io_direction_e mm_sound_io_direction;
926 SM_ARG_CHECK(device);
927 SM_ARG_CHECK(io_direction);
929 LOGI("device[%p]", device);
931 if ((ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction)) != MM_ERROR_NONE)
932 return _convert_sound_manager_error_code(__func__, ret);
934 return _convert_device_io_direction(mm_sound_io_direction, io_direction);
937 int sound_manager_get_device_id(sound_device_h device, int *id)
939 int ret = MM_ERROR_NONE;
941 SM_ARG_CHECK(device);
944 LOGI("device[%p]", device);
946 ret = mm_sound_get_device_id(device, id);
950 return _convert_sound_manager_error_code(__func__, ret);
953 int sound_manager_get_device_name(sound_device_h device, char **name)
955 int ret = MM_ERROR_NONE;
957 SM_ARG_CHECK(device);
960 LOGI("device[%p]", device);
962 ret = mm_sound_get_device_name(device, name);
964 LOGI("name[%s]", *name);
966 return _convert_sound_manager_error_code(__func__, ret);
969 int sound_manager_is_device_running(sound_device_h device, bool *is_running)
971 int ret = MM_ERROR_NONE;
973 SM_ARG_CHECK(device);
974 SM_ARG_CHECK(is_running);
976 LOGI("device[%p]", device);
978 ret = mm_sound_is_device_running(device, is_running);
980 LOGI("is_running[%d]", *is_running);
982 return _convert_sound_manager_error_code(__func__, ret);
985 int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *state)
987 int ret = MM_ERROR_NONE;
989 SM_ARG_CHECK(device);
992 LOGI("device[%p]", device);
994 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
995 ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
997 LOGI("state[%d]", *state);
999 return _convert_sound_manager_error_code(__func__, ret);
1002 int sound_manager_get_supported_sample_formats(sound_device_h device, sound_sample_format_e **formats, unsigned int *num_of_elems)
1004 int ret = SOUND_MANAGER_ERROR_NONE;
1005 int mm_ret = MM_ERROR_NONE;
1008 SM_ARG_CHECK(device);
1009 SM_ARG_CHECK(formats);
1010 SM_ARG_CHECK(num_of_elems);
1012 LOGI("device[%p]", device);
1014 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1017 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1018 return _convert_sound_manager_error_code(__func__, mm_ret);
1020 return _get_supported_sample_formats(device_id, formats, num_of_elems);
1023 int sound_manager_set_sample_format(sound_device_h device, sound_sample_format_e format)
1025 int ret = SOUND_MANAGER_ERROR_NONE;
1026 int mm_ret = MM_ERROR_NONE;
1029 SM_ARG_CHECK(device);
1031 LOGI("device[%p] format[%d]", device, format);
1033 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1036 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1037 return _convert_sound_manager_error_code(__func__, mm_ret);
1039 return _set_sample_format(device_id, format);
1042 int sound_manager_get_sample_format(sound_device_h device, sound_sample_format_e *format)
1044 int ret = SOUND_MANAGER_ERROR_NONE;
1045 int mm_ret = MM_ERROR_NONE;
1048 SM_ARG_CHECK(device);
1049 SM_ARG_CHECK(format);
1051 LOGI("device[%p]", device);
1053 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1056 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1057 return _convert_sound_manager_error_code(__func__, mm_ret);
1059 return _get_sample_format(device_id, format);
1062 int sound_manager_get_supported_sample_rates(sound_device_h device, sound_sample_rate_e **rates, unsigned int *num_of_elems)
1064 int ret = SOUND_MANAGER_ERROR_NONE;
1065 int mm_ret = MM_ERROR_NONE;
1068 SM_ARG_CHECK(device);
1069 SM_ARG_CHECK(rates);
1070 SM_ARG_CHECK(num_of_elems);
1072 LOGI("device[%p]", device);
1074 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1077 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1078 return _convert_sound_manager_error_code(__func__, mm_ret);
1080 return _get_supported_sample_rates(device_id, rates, num_of_elems);
1083 int sound_manager_set_sample_rate(sound_device_h device, sound_sample_rate_e rate)
1085 int ret = SOUND_MANAGER_ERROR_NONE;
1086 int mm_ret = MM_ERROR_NONE;
1089 SM_ARG_CHECK(device);
1091 LOGI("device[%p] rate[%d]", device, rate);
1093 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1096 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1097 return _convert_sound_manager_error_code(__func__, mm_ret);
1099 return _set_sample_rate(device_id, rate);
1102 int sound_manager_get_sample_rate(sound_device_h device, sound_sample_rate_e *rate)
1104 int ret = SOUND_MANAGER_ERROR_NONE;
1105 int mm_ret = MM_ERROR_NONE;
1108 SM_ARG_CHECK(device);
1111 LOGI("device[%p]", device);
1113 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1116 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1117 return _convert_sound_manager_error_code(__func__, mm_ret);
1119 return _get_sample_rate(device_id, rate);
1122 int sound_manager_set_avoid_resampling(sound_device_h device, bool enable)
1124 int ret = SOUND_MANAGER_ERROR_NONE;
1125 int mm_ret = MM_ERROR_NONE;
1128 SM_ARG_CHECK(device);
1130 LOGI("device[%p] enable[%d]", device, enable);
1132 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1135 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1136 return _convert_sound_manager_error_code(__func__, mm_ret);
1138 return _set_avoid_resampling(device_id, enable);
1141 int sound_manager_get_avoid_resampling(sound_device_h device, bool *enabled)
1143 int ret = SOUND_MANAGER_ERROR_NONE;
1144 int mm_ret = MM_ERROR_NONE;
1147 SM_ARG_CHECK(device);
1148 SM_ARG_CHECK(enabled);
1150 LOGI("device[%p]", device);
1152 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1155 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1156 return _convert_sound_manager_error_code(__func__, mm_ret);
1158 return _get_avoid_resampling(device_id, enabled);
1161 int sound_manager_set_media_stream_only(sound_device_h device, bool enable)
1163 int ret = SOUND_MANAGER_ERROR_NONE;
1164 int mm_ret = MM_ERROR_NONE;
1167 SM_ARG_CHECK(device);
1169 LOGI("device[%p] enable[%d]", device, enable);
1171 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1174 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1175 return _convert_sound_manager_error_code(__func__, mm_ret);
1177 return _set_media_stream_only(device_id, enable);
1180 int sound_manager_get_media_stream_only(sound_device_h device, bool *enabled)
1182 int ret = SOUND_MANAGER_ERROR_NONE;
1183 int mm_ret = MM_ERROR_NONE;
1186 SM_ARG_CHECK(device);
1187 SM_ARG_CHECK(enabled);
1189 LOGI("device[%p]", device);
1191 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1194 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1195 return _convert_sound_manager_error_code(__func__, mm_ret);
1197 return _get_media_stream_only(device_id, enabled);
1200 int sound_manager_add_device_connection_changed_cb(int device_mask, sound_device_connection_changed_cb callback, void *user_data, int *id)
1202 int ret = MM_ERROR_NONE;
1204 SM_ARG_CHECK(callback);
1207 LOGI("device_mask[0x%x] callback[%p] user_data[%p]", device_mask, callback, user_data);
1209 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);
1211 LOGI("id[%d]", *id);
1213 return _convert_sound_manager_error_code(__func__, ret);
1216 int sound_manager_remove_device_connection_changed_cb(int id)
1218 int ret = MM_ERROR_NONE;
1220 SM_ARG_CHECK(id >= 0);
1224 ret = mm_sound_remove_device_connected_callback((unsigned int)id);
1226 return _convert_sound_manager_error_code(__func__, ret);
1229 int sound_manager_add_device_running_changed_cb(int device_mask, sound_device_running_changed_cb callback, void *user_data, int *id)
1231 int ret = MM_ERROR_NONE;
1233 SM_ARG_CHECK(callback);
1236 LOGI("device_mask[0x%x] callback[%p] user_data[%p]", device_mask, callback, user_data);
1238 ret = mm_sound_add_device_running_changed_callback(device_mask, (mm_sound_device_running_changed_cb)callback, user_data, (unsigned int*)id);
1240 LOGI("id[%d]", *id);
1242 return _convert_sound_manager_error_code(__func__, ret);
1245 int sound_manager_remove_device_running_changed_cb(int id)
1247 int ret = MM_ERROR_NONE;
1249 SM_ARG_CHECK(id >= 0);
1253 ret = mm_sound_remove_device_running_changed_callback((unsigned int)id);
1255 return _convert_sound_manager_error_code(__func__, ret);
1258 int sound_manager_add_device_state_changed_cb(int device_mask, sound_device_state_changed_cb callback, void *user_data, int *id)
1260 int ret = MM_ERROR_NONE;
1262 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1263 SM_ARG_CHECK(callback);
1266 LOGI("device_mask[0x%x] callback[%p] user_data[%p]", device_mask, callback, user_data);
1268 ret = mm_sound_add_device_state_changed_callback(device_mask, (mm_sound_device_state_changed_cb)callback, user_data, (unsigned int*)id);
1270 LOGI("id[%d]", *id);
1272 return _convert_sound_manager_error_code(__func__, ret);
1275 int sound_manager_remove_device_state_changed_cb(int id)
1277 int ret = MM_ERROR_NONE;
1279 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1280 SM_ARG_CHECK(id >= 0);
1284 ret = mm_sound_remove_device_state_changed_callback((unsigned int)id);
1286 return _convert_sound_manager_error_code(__func__, ret);
1289 int sound_manager_create_stream_ducking(sound_stream_type_e target_stream, sound_stream_ducking_state_changed_cb callback, void *user_data, sound_stream_ducking_h *stream_ducking)
1292 int ret = SOUND_MANAGER_ERROR_NONE;
1293 int mm_ret = MM_ERROR_NONE;
1294 sound_stream_ducking_s *new_ducking = NULL;
1296 SM_ARG_CHECK(stream_ducking);
1298 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1300 for (i = 0 ; i < SOUND_DUCKING_ARR_MAX ; i++)
1301 if (ducking_arr[i] == NULL)
1304 if (i == SOUND_DUCKING_ARR_MAX) {
1305 LOGE("ducking array is full");
1306 ret = SOUND_MANAGER_ERROR_INTERNAL;
1310 LOGI("target_stream[%d] callback[%p] user_data[%p]", target_stream, callback, user_data);
1312 new_ducking = (sound_stream_ducking_s *)calloc(1, sizeof(sound_stream_ducking_s));
1314 ret = SOUND_MANAGER_ERROR_INTERNAL;
1318 ret = _convert_stream_type(target_stream, &new_ducking->target_stream);
1319 if (ret != SOUND_MANAGER_ERROR_NONE)
1322 ret = _make_pa_connection(&new_ducking->pa_info, "SOUND_MANAGER_STREAM_DUCKING");
1323 if (ret != SOUND_MANAGER_ERROR_NONE)
1326 if (++ducking_arr_count == 1) {
1327 /* subscribe ducking finished signal */
1328 mm_ret = mm_sound_add_ducking_state_changed_callback((mm_sound_ducking_state_changed_cb)_ducking_state_changed_cb,
1329 NULL, &ducking_cb_subs_id);
1330 if (mm_ret != MM_ERROR_NONE) {
1331 ducking_arr_count = 0;
1332 ret = _convert_sound_manager_error_code(__func__, mm_ret);
1336 LOGI("ducking state changed cb subs id %d", ducking_cb_subs_id);
1339 new_ducking->user_cb = callback;
1340 new_ducking->user_data = user_data;
1342 ducking_arr[i] = new_ducking;
1343 *stream_ducking = (sound_stream_ducking_h)new_ducking;
1345 LOGI("new stream_ducking[%p] target_stream[%s] pa_index[%u]",
1346 new_ducking, new_ducking->target_stream, new_ducking->pa_info.index);
1349 if (ret != SOUND_MANAGER_ERROR_NONE) {
1351 _destroy_pa_connection(&new_ducking->pa_info);
1356 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1358 LOGI("ret[0x%x]", ret);
1363 int sound_manager_destroy_stream_ducking(sound_stream_ducking_h stream_ducking)
1366 int ret = SOUND_MANAGER_ERROR_NONE;
1367 bool is_ducked = false;
1368 sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1370 SM_ARG_CHECK(ducking);
1372 LOGI("stream_ducking[%p]", ducking);
1374 ret = _get_ducking_state(&ducking->pa_info, &is_ducked);
1375 if (ret != SOUND_MANAGER_ERROR_NONE && !ducking->pa_info.is_disconnected)
1379 LOGE("ducked now, it should be deactivated first.");
1380 return SOUND_MANAGER_ERROR_INVALID_STATE;
1383 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1385 _destroy_pa_connection(&ducking->pa_info);
1387 for (i = 0 ; i < SOUND_DUCKING_ARR_MAX ; i++)
1388 if (ducking_arr[i] == ducking)
1389 ducking_arr[i] = NULL;
1391 if (--ducking_arr_count == 0) {
1392 /* unsubscribe ducking finished signal */
1393 if (mm_sound_remove_ducking_state_changed_callback(ducking_cb_subs_id) != MM_ERROR_NONE)
1394 LOGW("mm_sound_remove_ducking_state_changed_callback(id:%u) failed", ducking_cb_subs_id);
1396 ducking_cb_subs_id = 0;
1401 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1403 return SOUND_MANAGER_ERROR_NONE;
1406 int sound_manager_is_ducked(sound_stream_ducking_h stream_ducking, bool *is_ducked)
1408 sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1410 SM_ARG_CHECK(ducking);
1411 SM_ARG_CHECK(is_ducked);
1413 LOGI("stream_ducking[%p]", ducking);
1415 return _get_ducking_state(&ducking->pa_info, is_ducked);
1418 int sound_manager_activate_ducking(sound_stream_ducking_h stream_ducking, unsigned int duration, double ratio)
1420 int ret = SOUND_MANAGER_ERROR_NONE;
1421 bool is_ducked = false;
1422 sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1424 SM_ARG_CHECK(ducking);
1425 SM_ARG_CHECK(duration <= 3000);
1426 SM_ARG_CHECK(ratio < 1.0);
1427 SM_ARG_CHECK(ratio >= 0.0);
1429 LOGI("stream_ducking[%p] duration[%u] ratio[%lf]", ducking, duration, ratio);
1431 ret = _get_ducking_state(&ducking->pa_info, &is_ducked);
1432 if (ret != SOUND_MANAGER_ERROR_NONE)
1436 LOGE("already ducked");
1437 return SOUND_MANAGER_ERROR_INVALID_STATE;
1440 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1442 ret = _activate_ducking(ducking->pa_info.index,
1443 true, ducking->target_stream, (uint32_t)duration, ratio);
1444 if (ret == SOUND_MANAGER_ERROR_NONE) {
1445 ducking->duration = duration;
1446 ducking->ratio = ratio;
1449 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1451 LOGI("ret[0x%x]", ret);
1456 int sound_manager_deactivate_ducking(sound_stream_ducking_h stream_ducking)
1458 int ret = SOUND_MANAGER_ERROR_NONE;
1459 bool is_ducked = false;
1460 sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1462 SM_ARG_CHECK(ducking);
1464 LOGI("stream_ducking[%p]", ducking);
1466 ret = _get_ducking_state(&ducking->pa_info, &is_ducked);
1467 if (ret != SOUND_MANAGER_ERROR_NONE)
1472 return SOUND_MANAGER_ERROR_INVALID_STATE;
1475 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1477 ret = _activate_ducking(ducking->pa_info.index,
1478 false, ducking->target_stream, (uint32_t)ducking->duration, ducking->ratio);
1480 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1482 LOGI("ret[0x%x]", ret);