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;
608 bool is_focus_cb_thread = false;
609 int mm_ret = MM_ERROR_NONE;
611 SM_ARG_CHECK(stream_h);
612 SM_ARG_CHECK(state_for_playback || state_for_recording);
614 LOGI("stream_info[%p, type:%s, focus_id:%d]", stream_info, stream_h->stream_type, stream_h->focus_id);
616 if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)) != MM_ERROR_NONE)
617 return _convert_sound_manager_error_code(__func__, mm_ret);
619 if (!is_focus_cb_thread)
620 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, SOUND_MANAGER_ERROR_INTERNAL);
622 if (state_for_playback)
623 *state_for_playback = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
624 if (state_for_recording)
625 *state_for_recording = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
627 LOGI("acquired_focus(0x%x)", stream_h->acquired_focus);
629 if (!is_focus_cb_thread)
630 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
632 return SOUND_MANAGER_ERROR_NONE;
635 int sound_manager_deliver_focus(sound_stream_info_h source, sound_stream_info_h destination, sound_stream_focus_mask_e focus_mask)
637 int ret = MM_ERROR_NONE;
638 sound_stream_info_s *src_stream_h = (sound_stream_info_s*)source;
639 sound_stream_info_s *dst_stream_h = (sound_stream_info_s*)destination;
640 bool is_focus_cb_thread = false;
642 SM_ARG_CHECK(src_stream_h);
643 SM_ARG_CHECK(dst_stream_h);
645 LOGI("SRC stream_info[%p, type:%s, focus_id:%d]", source, src_stream_h->stream_type, src_stream_h->focus_id);
646 LOGI("DST stream_info[%p, type:%s, focus_id:%d]", destination, dst_stream_h->stream_type, dst_stream_h->focus_id);
647 LOGI("focus_mask[0x%x]", focus_mask);
649 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)) != MM_ERROR_NONE)
650 return _convert_sound_manager_error_code(__func__, ret);
652 if (is_focus_cb_thread) {
653 LOGE("not allowed calling this function in focus(watch) callback");
654 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
657 if (src_stream_h->focus_id == dst_stream_h->focus_id) {
658 LOGE("not allowed because both handles have same id(%u)", src_stream_h->focus_id);
659 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
662 if (src_stream_h->is_focus_unavailable || dst_stream_h->is_focus_unavailable) {
663 LOGE("focus is unavailable for source(%d)/destination(%d)",
664 src_stream_h->is_focus_unavailable, dst_stream_h->is_focus_unavailable);
665 return SOUND_MANAGER_ERROR_POLICY;
668 if (!(src_stream_h->acquired_focus & focus_mask) || (src_stream_h->acquired_focus < focus_mask)) {
669 LOGE("could not deliver the request focus(0x%x), current acquired focus(0x%x)",
670 focus_mask, src_stream_h->acquired_focus);
671 return SOUND_MANAGER_ERROR_INVALID_STATE;
674 if (dst_stream_h->user_cb == NULL) {
675 LOGE("focus state changed callback should be set to destination handle");
676 return SOUND_MANAGER_ERROR_POLICY;
679 ret = mm_sound_deliver_focus(src_stream_h->focus_id, dst_stream_h->focus_id, (mm_sound_focus_type_e)focus_mask);
680 if (ret == MM_ERROR_NONE) {
681 src_stream_h->acquired_focus &= ~focus_mask;
682 src_stream_h->prev_acquired_focus &= ~focus_mask;
683 dst_stream_h->acquired_focus |= focus_mask;
684 dst_stream_h->prev_acquired_focus |= focus_mask;
687 return _convert_sound_manager_error_code(__func__, ret);
690 int sound_manager_is_stream_on_device(sound_stream_info_h stream_info, sound_device_h device, bool *is_on)
692 int ret = MM_ERROR_NONE;
693 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
695 SM_ARG_CHECK(stream_h);
696 SM_ARG_CHECK(device);
699 LOGI("stream_info[%p, type:%s] device[%p]", stream_info, stream_h->stream_type, device);
701 ret = mm_sound_is_stream_on_device(stream_h->pa_info.index, device, is_on);
703 LOGI("is_on[%d]", *is_on);
705 return _convert_sound_manager_error_code(__func__, ret);
708 int sound_manager_get_current_media_playback_device_type(sound_device_type_e *device_type)
710 SM_ARG_CHECK(device_type);
712 return _get_current_media_routing_path("out", device_type);
715 int sound_manager_get_current_playback_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
717 int ret = SOUND_MANAGER_ERROR_NONE;
718 int mm_ret = MM_ERROR_NONE;
719 char *stream_type_str = NULL;
720 char *extra_info_str = NULL;
722 bool is_focus_cb_thread = false;
724 SM_ARG_CHECK(acquired_by);
727 if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)) != MM_ERROR_NONE)
728 return _convert_sound_manager_error_code(__func__, mm_ret);
730 if (is_focus_cb_thread) {
731 LOGE("this API should not be called in focus callback");
732 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
735 mm_ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_PLAYBACK, &stream_type_str, &option, &extra_info_str);
736 if (mm_ret != MM_ERROR_NONE)
737 return _convert_sound_manager_error_code(__func__, mm_ret);
739 LOGI("current acquired PLAYBACK focus : stream_type[%s]", stream_type_str);
740 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
741 if (ret == SOUND_MANAGER_ERROR_NONE) {
742 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
745 *extra_info = strdup(extra_info_str);
747 SM_SAFE_FREE(stream_type_str);
748 SM_SAFE_FREE(extra_info_str);
753 int sound_manager_get_current_recording_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
755 int ret = SOUND_MANAGER_ERROR_NONE;
756 int mm_ret = MM_ERROR_NONE;
757 char *stream_type_str = NULL;
758 char *extra_info_str = NULL;
760 bool is_focus_cb_thread = false;
762 SM_ARG_CHECK(acquired_by);
765 if ((mm_ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)) != MM_ERROR_NONE)
766 return _convert_sound_manager_error_code(__func__, mm_ret);
768 if (is_focus_cb_thread) {
769 LOGE("this API should not be called in focus callback");
770 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
773 mm_ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_RECORDING, &stream_type_str, &option, &extra_info_str);
774 if (mm_ret != MM_ERROR_NONE)
775 return _convert_sound_manager_error_code(__func__, mm_ret);
777 LOGI("current acquired RECORDING focus : stream_type[%s]", stream_type_str);
778 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
779 if (ret == SOUND_MANAGER_ERROR_NONE) {
780 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
783 *extra_info = strdup(extra_info_str);
785 SM_SAFE_FREE(stream_type_str);
786 SM_SAFE_FREE(extra_info_str);
791 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)
793 int ret = MM_ERROR_NONE;
796 SM_ARG_CHECK(callback);
799 LOGI("focus_mask[0x%x] callback[%p] user_data[%p]", focus_mask, callback, user_data);
801 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
802 if (focus_watch_info_arr[i].id == 0)
804 if (i == SOUND_STREAM_INFO_ARR_MAX) {
806 LOGE("focus watch info array is full");
807 ret = MM_ERROR_SOUND_INTERNAL;
812 ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, &focus_watch_info_arr[i], id);
813 if (ret == MM_ERROR_NONE) {
814 focus_watch_info_arr[i].id = *id;
815 focus_watch_info_arr[i].user_data = user_data;
816 focus_watch_info_arr[i].user_cb = callback;
822 return _convert_sound_manager_error_code(__func__, ret);
825 int sound_manager_remove_focus_state_watch_cb(int id)
827 int ret = MM_ERROR_NONE;
832 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
833 if (focus_watch_info_arr[i].id == id)
835 if (i == SOUND_STREAM_INFO_ARR_MAX) {
836 LOGE("could not find item in focus watch info array for this id(%d)", id);
837 ret = MM_ERROR_INVALID_ARGUMENT;
841 ret = mm_sound_unset_focus_watch_callback(id);
842 if (ret == MM_ERROR_NONE) {
843 focus_watch_info_arr[i].id = 0;
844 focus_watch_info_arr[i].user_data = NULL;
845 focus_watch_info_arr[i].user_cb = NULL;
849 return _convert_sound_manager_error_code(__func__, ret);
852 int sound_manager_get_device_list(int device_mask, sound_device_list_h *device_list)
854 int ret = MM_ERROR_NONE;
856 SM_ARG_CHECK(device_list);
858 LOGI("device_mask[0x%x]", device_mask);
860 ret = mm_sound_get_device_list(device_mask, device_list);
862 LOGI("device_list[%p]", *device_list);
864 return _convert_sound_manager_error_code(__func__, ret);
867 int sound_manager_free_device_list(sound_device_list_h device_list)
869 int ret = MM_ERROR_NONE;
871 SM_ARG_CHECK(device_list);
873 LOGI("device_list[%p]", device_list);
875 ret = mm_sound_free_device_list(device_list);
877 return _convert_sound_manager_error_code(__func__, ret);
880 int sound_manager_get_next_device(sound_device_list_h device_list, sound_device_h *device)
882 int ret = MM_ERROR_NONE;
884 SM_ARG_CHECK(device_list);
885 SM_ARG_CHECK(device);
887 LOGI("device_list[%p]", device_list);
889 ret = mm_sound_get_next_device(device_list, device);
891 LOGI("device[%p]", *device);
893 return _convert_sound_manager_error_code(__func__, ret);
896 int sound_manager_get_prev_device(sound_device_list_h device_list, sound_device_h *device)
898 int ret = MM_ERROR_NONE;
900 SM_ARG_CHECK(device_list);
901 SM_ARG_CHECK(device);
903 LOGI("device_list[%p]", device_list);
905 ret = mm_sound_get_prev_device(device_list, device);
907 LOGI("device[%p]", *device);
909 return _convert_sound_manager_error_code(__func__, ret);
912 int sound_manager_get_device_type(sound_device_h device, sound_device_type_e *type)
914 int ret = MM_ERROR_NONE;
915 mm_sound_device_type_e mm_sound_device_type;
917 SM_ARG_CHECK(device);
920 LOGI("device[%p]", device);
922 if ((ret = mm_sound_get_device_type(device, &mm_sound_device_type)) != MM_ERROR_NONE)
923 return _convert_sound_manager_error_code(__func__, ret);
925 return _convert_device_type(mm_sound_device_type, type);
928 int sound_manager_get_device_io_direction(sound_device_h device, sound_device_io_direction_e *io_direction)
930 int ret = MM_ERROR_NONE;
931 mm_sound_device_io_direction_e mm_sound_io_direction;
933 SM_ARG_CHECK(device);
934 SM_ARG_CHECK(io_direction);
936 LOGI("device[%p]", device);
938 if ((ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction)) != MM_ERROR_NONE)
939 return _convert_sound_manager_error_code(__func__, ret);
941 return _convert_device_io_direction(mm_sound_io_direction, io_direction);
944 int sound_manager_get_device_id(sound_device_h device, int *id)
946 int ret = MM_ERROR_NONE;
948 SM_ARG_CHECK(device);
951 LOGI("device[%p]", device);
953 ret = mm_sound_get_device_id(device, id);
957 return _convert_sound_manager_error_code(__func__, ret);
960 int sound_manager_get_device_name(sound_device_h device, char **name)
962 int ret = MM_ERROR_NONE;
964 SM_ARG_CHECK(device);
967 LOGI("device[%p]", device);
969 ret = mm_sound_get_device_name(device, name);
971 LOGI("name[%s]", *name);
973 return _convert_sound_manager_error_code(__func__, ret);
976 int sound_manager_is_device_running(sound_device_h device, bool *is_running)
978 int ret = MM_ERROR_NONE;
980 SM_ARG_CHECK(device);
981 SM_ARG_CHECK(is_running);
983 LOGI("device[%p]", device);
985 ret = mm_sound_is_device_running(device, is_running);
987 LOGI("is_running[%d]", *is_running);
989 return _convert_sound_manager_error_code(__func__, ret);
992 int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *state)
994 SM_ARG_CHECK(device);
997 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
998 *state = SOUND_DEVICE_STATE_DEACTIVATED;
1000 return SOUND_MANAGER_ERROR_NONE;
1003 int sound_manager_get_supported_sample_formats(sound_device_h device, sound_sample_format_e **formats, unsigned int *num_of_elems)
1005 int ret = SOUND_MANAGER_ERROR_NONE;
1006 int mm_ret = MM_ERROR_NONE;
1009 SM_ARG_CHECK(device);
1010 SM_ARG_CHECK(formats);
1011 SM_ARG_CHECK(num_of_elems);
1013 LOGI("device[%p]", device);
1015 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1018 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1019 return _convert_sound_manager_error_code(__func__, mm_ret);
1021 return _get_supported_sample_formats(device_id, formats, num_of_elems);
1024 int sound_manager_set_sample_format(sound_device_h device, sound_sample_format_e format)
1026 int ret = SOUND_MANAGER_ERROR_NONE;
1027 int mm_ret = MM_ERROR_NONE;
1030 SM_ARG_CHECK(device);
1032 LOGI("device[%p] format[%d]", device, format);
1034 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1037 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1038 return _convert_sound_manager_error_code(__func__, mm_ret);
1040 return _set_sample_format(device_id, format);
1043 int sound_manager_get_sample_format(sound_device_h device, sound_sample_format_e *format)
1045 int ret = SOUND_MANAGER_ERROR_NONE;
1046 int mm_ret = MM_ERROR_NONE;
1049 SM_ARG_CHECK(device);
1050 SM_ARG_CHECK(format);
1052 LOGI("device[%p]", device);
1054 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1057 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1058 return _convert_sound_manager_error_code(__func__, mm_ret);
1060 return _get_sample_format(device_id, format);
1063 int sound_manager_get_supported_sample_rates(sound_device_h device, sound_sample_rate_e **rates, unsigned int *num_of_elems)
1065 int ret = SOUND_MANAGER_ERROR_NONE;
1066 int mm_ret = MM_ERROR_NONE;
1069 SM_ARG_CHECK(device);
1070 SM_ARG_CHECK(rates);
1071 SM_ARG_CHECK(num_of_elems);
1073 LOGI("device[%p]", device);
1075 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1078 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1079 return _convert_sound_manager_error_code(__func__, mm_ret);
1081 return _get_supported_sample_rates(device_id, rates, num_of_elems);
1084 int sound_manager_set_sample_rate(sound_device_h device, sound_sample_rate_e rate)
1086 int ret = SOUND_MANAGER_ERROR_NONE;
1087 int mm_ret = MM_ERROR_NONE;
1090 SM_ARG_CHECK(device);
1092 LOGI("device[%p] rate[%d]", device, rate);
1094 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1097 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1098 return _convert_sound_manager_error_code(__func__, mm_ret);
1100 return _set_sample_rate(device_id, rate);
1103 int sound_manager_get_sample_rate(sound_device_h device, sound_sample_rate_e *rate)
1105 int ret = SOUND_MANAGER_ERROR_NONE;
1106 int mm_ret = MM_ERROR_NONE;
1109 SM_ARG_CHECK(device);
1112 LOGI("device[%p]", device);
1114 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1117 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1118 return _convert_sound_manager_error_code(__func__, mm_ret);
1120 return _get_sample_rate(device_id, rate);
1123 int sound_manager_set_avoid_resampling(sound_device_h device, bool enable)
1125 int ret = SOUND_MANAGER_ERROR_NONE;
1126 int mm_ret = MM_ERROR_NONE;
1129 SM_ARG_CHECK(device);
1131 LOGI("device[%p] enable[%d]", device, enable);
1133 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1136 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1137 return _convert_sound_manager_error_code(__func__, mm_ret);
1139 return _set_avoid_resampling(device_id, enable);
1142 int sound_manager_get_avoid_resampling(sound_device_h device, bool *enabled)
1144 int ret = SOUND_MANAGER_ERROR_NONE;
1145 int mm_ret = MM_ERROR_NONE;
1148 SM_ARG_CHECK(device);
1149 SM_ARG_CHECK(enabled);
1151 LOGI("device[%p]", device);
1153 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1156 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1157 return _convert_sound_manager_error_code(__func__, mm_ret);
1159 return _get_avoid_resampling(device_id, enabled);
1162 int sound_manager_set_media_stream_only(sound_device_h device, bool enable)
1164 int ret = SOUND_MANAGER_ERROR_NONE;
1165 int mm_ret = MM_ERROR_NONE;
1168 SM_ARG_CHECK(device);
1170 LOGI("device[%p] enable[%d]", device, enable);
1172 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1175 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1176 return _convert_sound_manager_error_code(__func__, mm_ret);
1178 return _set_media_stream_only(device_id, enable);
1181 int sound_manager_get_media_stream_only(sound_device_h device, bool *enabled)
1183 int ret = SOUND_MANAGER_ERROR_NONE;
1184 int mm_ret = MM_ERROR_NONE;
1187 SM_ARG_CHECK(device);
1188 SM_ARG_CHECK(enabled);
1190 LOGI("device[%p]", device);
1192 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)) != SOUND_MANAGER_ERROR_NONE)
1195 if ((mm_ret = mm_sound_get_device_id(device, &device_id)) != MM_ERROR_NONE)
1196 return _convert_sound_manager_error_code(__func__, mm_ret);
1198 return _get_media_stream_only(device_id, enabled);
1201 int sound_manager_add_device_connection_changed_cb(int device_mask, sound_device_connection_changed_cb callback, void *user_data, int *id)
1203 int ret = MM_ERROR_NONE;
1205 SM_ARG_CHECK(callback);
1208 LOGI("device_mask[0x%x] callback[%p] user_data[%p]", device_mask, callback, user_data);
1210 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);
1212 LOGI("id[%d]", *id);
1214 return _convert_sound_manager_error_code(__func__, ret);
1217 int sound_manager_remove_device_connection_changed_cb(int id)
1219 int ret = MM_ERROR_NONE;
1221 SM_ARG_CHECK(id >= 0);
1225 ret = mm_sound_remove_device_connected_callback((unsigned int)id);
1227 return _convert_sound_manager_error_code(__func__, ret);
1230 int sound_manager_add_device_running_changed_cb(int device_mask, sound_device_running_changed_cb callback, void *user_data, int *id)
1232 int ret = MM_ERROR_NONE;
1234 SM_ARG_CHECK(callback);
1237 LOGI("device_mask[0x%x] callback[%p] user_data[%p]", device_mask, callback, user_data);
1239 ret = mm_sound_add_device_running_changed_callback(device_mask, (mm_sound_device_running_changed_cb)callback, user_data, (unsigned int*)id);
1241 LOGI("id[%d]", *id);
1243 return _convert_sound_manager_error_code(__func__, ret);
1246 int sound_manager_remove_device_running_changed_cb(int id)
1248 int ret = MM_ERROR_NONE;
1250 SM_ARG_CHECK(id >= 0);
1254 ret = mm_sound_remove_device_running_changed_callback((unsigned int)id);
1256 return _convert_sound_manager_error_code(__func__, ret);
1259 int sound_manager_add_device_state_changed_cb(int device_mask, sound_device_state_changed_cb callback, void *user_data, int *id)
1261 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1262 SM_ARG_CHECK(callback);
1267 return SOUND_MANAGER_ERROR_NONE;
1270 int sound_manager_remove_device_state_changed_cb(int id)
1272 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1274 return SOUND_MANAGER_ERROR_NONE;
1277 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)
1280 int ret = SOUND_MANAGER_ERROR_NONE;
1281 int mm_ret = MM_ERROR_NONE;
1282 sound_stream_ducking_s *new_ducking = NULL;
1284 SM_ARG_CHECK(stream_ducking);
1286 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1288 for (i = 0 ; i < SOUND_DUCKING_ARR_MAX ; i++)
1289 if (ducking_arr[i] == NULL)
1292 if (i == SOUND_DUCKING_ARR_MAX) {
1293 LOGE("ducking array is full");
1294 ret = SOUND_MANAGER_ERROR_INTERNAL;
1298 LOGI("target_stream[%d] callback[%p] user_data[%p]", target_stream, callback, user_data);
1300 new_ducking = (sound_stream_ducking_s *)calloc(1, sizeof(sound_stream_ducking_s));
1302 ret = SOUND_MANAGER_ERROR_INTERNAL;
1306 ret = _convert_stream_type(target_stream, &new_ducking->target_stream);
1307 if (ret != SOUND_MANAGER_ERROR_NONE)
1310 ret = _make_pa_connection(&new_ducking->pa_info, "SOUND_MANAGER_STREAM_DUCKING");
1311 if (ret != SOUND_MANAGER_ERROR_NONE)
1314 if (++ducking_arr_count == 1) {
1315 /* subscribe ducking finished signal */
1316 mm_ret = mm_sound_add_ducking_state_changed_callback((mm_sound_ducking_state_changed_cb)_ducking_state_changed_cb,
1317 NULL, &ducking_cb_subs_id);
1318 if (mm_ret != MM_ERROR_NONE) {
1319 ducking_arr_count = 0;
1320 ret = _convert_sound_manager_error_code(__func__, mm_ret);
1324 LOGI("ducking state changed cb subs id %d", ducking_cb_subs_id);
1327 new_ducking->user_cb = callback;
1328 new_ducking->user_data = user_data;
1330 ducking_arr[i] = new_ducking;
1331 *stream_ducking = (sound_stream_ducking_h)new_ducking;
1333 LOGI("new stream_ducking[%p] target_stream[%s] pa_index[%u]",
1334 new_ducking, new_ducking->target_stream, new_ducking->pa_info.index);
1337 if (ret != SOUND_MANAGER_ERROR_NONE) {
1339 _destroy_pa_connection(&new_ducking->pa_info);
1344 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1346 LOGI("ret[0x%x]", ret);
1351 int sound_manager_destroy_stream_ducking(sound_stream_ducking_h stream_ducking)
1354 int ret = SOUND_MANAGER_ERROR_NONE;
1355 bool is_ducked = false;
1356 sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1358 SM_ARG_CHECK(ducking);
1360 LOGI("stream_ducking[%p]", ducking);
1362 ret = _get_ducking_state(&ducking->pa_info, &is_ducked);
1363 if (ret != SOUND_MANAGER_ERROR_NONE && !ducking->pa_info.is_disconnected)
1367 LOGE("ducked now, it should be deactivated first.");
1368 return SOUND_MANAGER_ERROR_INVALID_STATE;
1371 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1373 _destroy_pa_connection(&ducking->pa_info);
1375 for (i = 0 ; i < SOUND_DUCKING_ARR_MAX ; i++)
1376 if (ducking_arr[i] == ducking)
1377 ducking_arr[i] = NULL;
1379 if (--ducking_arr_count == 0) {
1380 /* unsubscribe ducking finished signal */
1381 if (mm_sound_remove_ducking_state_changed_callback(ducking_cb_subs_id) != MM_ERROR_NONE)
1382 LOGW("mm_sound_remove_ducking_state_changed_callback(id:%u) failed", ducking_cb_subs_id);
1384 ducking_cb_subs_id = 0;
1389 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1391 return SOUND_MANAGER_ERROR_NONE;
1394 int sound_manager_is_ducked(sound_stream_ducking_h stream_ducking, bool *is_ducked)
1396 sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1398 SM_ARG_CHECK(ducking);
1399 SM_ARG_CHECK(is_ducked);
1401 LOGI("stream_ducking[%p]", ducking);
1403 return _get_ducking_state(&ducking->pa_info, is_ducked);
1406 int sound_manager_activate_ducking(sound_stream_ducking_h stream_ducking, unsigned int duration, double ratio)
1408 int ret = SOUND_MANAGER_ERROR_NONE;
1409 bool is_ducked = false;
1410 sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1412 SM_ARG_CHECK(ducking);
1413 SM_ARG_CHECK(duration <= 3000);
1414 SM_ARG_CHECK(ratio < 1.0);
1415 SM_ARG_CHECK(ratio >= 0.0);
1417 LOGI("stream_ducking[%p] duration[%u] ratio[%lf]", ducking, duration, ratio);
1419 ret = _get_ducking_state(&ducking->pa_info, &is_ducked);
1420 if (ret != SOUND_MANAGER_ERROR_NONE)
1424 LOGE("already ducked");
1425 return SOUND_MANAGER_ERROR_INVALID_STATE;
1428 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1430 ret = _activate_ducking(ducking->pa_info.index,
1431 true, ducking->target_stream, (uint32_t)duration, ratio);
1432 if (ret == SOUND_MANAGER_ERROR_NONE) {
1433 ducking->duration = duration;
1434 ducking->ratio = ratio;
1437 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1439 LOGI("ret[0x%x]", ret);
1444 int sound_manager_deactivate_ducking(sound_stream_ducking_h stream_ducking)
1446 int ret = SOUND_MANAGER_ERROR_NONE;
1447 bool is_ducked = false;
1448 sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1450 SM_ARG_CHECK(ducking);
1452 LOGI("stream_ducking[%p]", ducking);
1454 ret = _get_ducking_state(&ducking->pa_info, &is_ducked);
1455 if (ret != SOUND_MANAGER_ERROR_NONE)
1460 return SOUND_MANAGER_ERROR_INVALID_STATE;
1463 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1465 ret = _activate_ducking(ducking->pa_info.index,
1466 false, ducking->target_stream, (uint32_t)ducking->duration, ducking->ratio);
1468 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1470 LOGI("ret[0x%x]", ret);