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)
38 if (i < SOUND_DUCKING_ARR_MAX) {
39 LOGI("ducking state changed [i:%d,ducked:%u]", pa_index, is_ducked);
41 if (ducking_arr[i]->user_cb)
42 ducking_arr[i]->user_cb((sound_stream_ducking_h)ducking_arr[i], is_ducked, ducking_arr[i]->user_data);
44 LOGW("no user callback for pa_index %d", pa_index);
46 LOGE("could not found for pa_index %d", pa_index);
49 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
54 int sound_manager_get_max_volume(sound_type_e type, int *max)
56 const char *volume_type = NULL;
57 unsigned int max_level = 0;
58 int ret = MM_ERROR_NONE;
60 SM_NULL_ARG_CHECK(max);
61 if (type >= SOUND_TYPE_NUM)
62 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
64 ret = _convert_sound_type(type, &volume_type);
65 if (ret == MM_ERROR_NONE) {
66 ret = _get_volume_max_level(DIRECTION_OUT_STR, volume_type, &max_level);
67 if (ret == MM_ERROR_NONE)
68 *max = (int)max_level -1; /* actual volume step can be max step - 1 */
71 return _convert_sound_manager_error_code(__func__, ret);
74 int sound_manager_set_volume(sound_type_e type, int volume)
76 int ret = MM_ERROR_NONE;
78 if (type >= SOUND_TYPE_NUM)
79 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
81 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
83 ret = mm_sound_volume_set_value(type, volume);
84 LOGI("type=%d, volume=%d", type, volume);
86 return _convert_sound_manager_error_code(__func__, ret);
89 int sound_manager_get_volume(sound_type_e type, int *volume)
91 int ret = MM_ERROR_NONE;
94 if (type >= SOUND_TYPE_NUM)
95 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
97 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
99 ret = mm_sound_volume_get_value(type, &uvolume);
100 if (ret == MM_ERROR_NONE)
103 LOGI("type=%d, volume=%d", type, *volume);
105 return _convert_sound_manager_error_code(__func__, ret);
108 int sound_manager_get_current_sound_type(sound_type_e *type)
110 int ret = MM_ERROR_NONE;
111 char *volume_type = NULL;
114 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
116 /* get the volume type of the current playing stream */
117 ret = _get_current_volume_type(DIRECTION_OUT_STR, &volume_type);
118 if (ret == MM_ERROR_NONE) {
119 ret = _convert_sound_type_to_enum((const char*)volume_type, type);
120 if (ret == MM_ERROR_NONE)
121 LOGI("type=%d", *type);
124 return _convert_sound_manager_error_code(__func__, 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 if (!callback || !id)
132 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
134 ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data, (unsigned int*)id);
136 return _convert_sound_manager_error_code(__func__, ret);
139 int sound_manager_remove_volume_changed_cb(int id)
141 int ret = MM_ERROR_NONE;
144 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
146 ret = mm_sound_remove_volume_changed_callback(id);
148 return _convert_sound_manager_error_code(__func__, ret);
151 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)
153 int ret = MM_ERROR_NONE;
157 SM_NULL_ARG_CHECK(stream_info);
159 sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s));
161 ret = MM_ERROR_OUT_OF_MEMORY;
165 memset(stream_h, 0, sizeof(sound_stream_info_s));
166 ret = _convert_stream_type(stream_type, &stream_h->stream_type);
167 if (ret == MM_ERROR_NONE) {
168 ret = _make_pa_connection_and_register_focus(stream_h, callback, user_data);
169 if (ret == MM_ERROR_NONE) {
170 *stream_info = (sound_stream_info_h)stream_h;
171 LOGI("stream_h(%p), pa_index(%u), focus_id(%d), user_cb(%p), ret(0x%x)",
172 stream_h, stream_h->pa_info.index, stream_h->focus_id, stream_h->user_cb, ret);
178 SM_SAFE_FREE(stream_h);
180 return _convert_sound_manager_error_code(__func__, ret);
183 int sound_manager_destroy_stream_information(sound_stream_info_h stream_info)
185 int ret = MM_ERROR_NONE;
186 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
190 SM_INSTANCE_CHECK(stream_h);
192 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->vstream_mutex, SOUND_MANAGER_ERROR_INTERNAL);
193 if (stream_h->vstream) {
194 LOGE("virtual stream is still alive");
195 SM_LEAVE_CRITICAL_SECTION(&stream_h->vstream_mutex);
196 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
198 SM_LEAVE_CRITICAL_SECTION(&stream_h->vstream_mutex);
200 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
201 ret = _destroy_pa_connection_and_unregister_focus(stream_h);
202 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
203 if (ret == MM_ERROR_NONE)
204 SM_SAFE_FREE(stream_h);
206 return _convert_sound_manager_error_code(__func__, ret);
209 int sound_manager_get_sound_type(sound_stream_info_h stream_info, sound_type_e *sound_type)
211 int ret = MM_ERROR_NONE;
212 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
216 SM_INSTANCE_CHECK(stream_h);
217 SM_NULL_ARG_CHECK(sound_type);
219 if (stream_h->stream_conf_info.volume_type == NULL) {
220 ret = MM_ERROR_SOUND_NO_DATA;
224 ret = _convert_sound_type_to_enum(stream_h->stream_conf_info.volume_type, sound_type);
225 LOGI("sound type(%d)", *sound_type);
228 return _convert_sound_manager_error_code(__func__, ret);
231 int sound_manager_add_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
233 int ret = MM_ERROR_NONE;
234 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
238 ret = _add_device_for_stream_routing(stream_h, device);
240 return _convert_sound_manager_error_code(__func__, ret);
243 int sound_manager_remove_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
245 int ret = MM_ERROR_NONE;
246 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
250 ret = _remove_device_for_stream_routing(stream_h, device);
252 return _convert_sound_manager_error_code(__func__, ret);
255 int sound_manager_remove_all_devices_for_stream_routing(sound_stream_info_h stream_info)
257 int ret = MM_ERROR_NONE;
258 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
262 ret = _remove_all_devices_for_stream_routing(stream_h);
264 return _convert_sound_manager_error_code(__func__, ret);
267 int sound_manager_apply_stream_routing(sound_stream_info_h stream_info)
269 int ret = MM_ERROR_NONE;
270 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
274 ret = _apply_stream_routing(stream_h);
276 return _convert_sound_manager_error_code(__func__, ret);
279 int sound_manager_set_stream_preferred_device(sound_stream_info_h stream_info, sound_device_io_direction_e io_direction, sound_device_h device)
281 int ret = MM_ERROR_NONE;
282 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
284 SM_NULL_ARG_CHECK(stream_h);
286 ret = _set_preferred_device(stream_h, io_direction, device);
288 return _convert_sound_manager_error_code(__func__, ret);
291 int sound_manager_get_stream_preferred_device(sound_stream_info_h stream_info, int *in_device_id, int *out_device_id)
293 int ret = MM_ERROR_NONE;
294 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
296 SM_NULL_ARG_CHECK(stream_h);
297 SM_NULL_ARG_CHECK(in_device_id || out_device_id);
299 ret = _get_preferred_device(stream_h, in_device_id, out_device_id);
301 return _convert_sound_manager_error_code(__func__, ret);
304 int sound_manager_set_focus_reacquisition(sound_stream_info_h stream_info, bool enable)
306 int ret = MM_ERROR_NONE;
307 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
311 SM_INSTANCE_CHECK(stream_h);
313 ret = mm_sound_set_focus_reacquisition(stream_h->focus_id, enable);
315 LOGI("enable(%d)", enable);
317 return _convert_sound_manager_error_code(__func__, ret);
320 int sound_manager_get_focus_reacquisition(sound_stream_info_h stream_info, bool *enabled)
322 int ret = MM_ERROR_NONE;
323 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
327 SM_INSTANCE_CHECK(stream_h);
328 SM_NULL_ARG_CHECK(enabled);
330 ret = mm_sound_get_focus_reacquisition(stream_h->focus_id, enabled);
332 LOGI("enabled(%d)", *enabled);
334 return _convert_sound_manager_error_code(__func__, ret);
337 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)
339 int ret = MM_ERROR_NONE;
340 bool is_focus_cb_thread = false;
341 bool is_focus_watch_cb_thread = false;
342 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
346 SM_INSTANCE_CHECK(stream_h);
348 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
349 return _convert_sound_manager_error_code(__func__, ret);
351 if (stream_h->is_focus_unavailable) {
352 LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
353 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
356 if (stream_h->user_cb == NULL) {
357 LOGE("focus state changed callback should be set before acquiring focus");
358 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
361 if (!is_focus_cb_thread) {
362 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
363 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
365 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
366 * the focus state mutex could be still locked. Therefore, it returns error here. */
367 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
368 LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
369 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
371 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
374 if (stream_h->acquired_focus & focus_mask) {
375 LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
376 ret = MM_ERROR_SOUND_INVALID_STATE;
380 if (is_focus_cb_thread && ((stream_h->prev_acquired_focus & ~stream_h->acquired_focus) & focus_mask)) {
381 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]",
382 focus_mask, stream_h->acquired_focus, stream_h->prev_acquired_focus);
383 ret = MM_ERROR_POLICY_INTERNAL;
387 stream_h->is_requesting = true;
389 ret = mm_sound_acquire_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
390 if (ret == MM_ERROR_NONE) {
391 stream_h->acquired_focus |= focus_mask;
392 stream_h->prev_acquired_focus |= focus_mask;
393 _update_focus_status(stream_h->pa_info.index, (unsigned int)stream_h->acquired_focus);
396 LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
399 stream_h->is_requesting = false;
400 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
401 if (!is_focus_cb_thread)
402 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
404 return _convert_sound_manager_error_code(__func__, ret);
407 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)
409 int ret = MM_ERROR_NONE;
410 bool is_focus_cb_thread = false;
411 bool is_focus_watch_cb_thread = false;
412 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
416 SM_INSTANCE_CHECK(stream_h);
418 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
419 return _convert_sound_manager_error_code(__func__, ret);
421 if (!is_focus_cb_thread) {
422 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
423 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
425 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
426 * the focus state mutex could be still locked. Therefore, it returns error here. */
427 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
428 LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
429 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
431 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
434 if (!(stream_h->acquired_focus & focus_mask)) {
435 LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
436 ret = MM_ERROR_SOUND_INVALID_STATE;
440 if (is_focus_cb_thread && ((stream_h->prev_acquired_focus & stream_h->acquired_focus) != focus_mask)) {
441 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]",
442 focus_mask, stream_h->acquired_focus, stream_h->prev_acquired_focus);
443 ret = MM_ERROR_SOUND_INVALID_STATE;
447 stream_h->is_requesting = true;
449 ret = mm_sound_release_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
450 if (ret == MM_ERROR_NONE) {
451 stream_h->acquired_focus &= ~focus_mask;
452 stream_h->prev_acquired_focus &= ~focus_mask;
453 _update_focus_status(stream_h->pa_info.index, (unsigned int)stream_h->acquired_focus);
456 LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
459 stream_h->is_requesting = false;
460 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
461 if (!is_focus_cb_thread)
462 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
464 return _convert_sound_manager_error_code(__func__, ret);
467 int sound_manager_acquire_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
469 int ret = MM_ERROR_NONE;
470 int focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH;
471 bool is_focus_cb_thread = false;
472 bool is_focus_watch_cb_thread = false;
473 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
477 SM_INSTANCE_CHECK(stream_h);
479 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
480 return _convert_sound_manager_error_code(__func__, ret);
482 if (stream_h->is_focus_unavailable) {
483 LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
484 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
487 if (stream_h->user_cb == NULL) {
488 LOGE("focus state changed callback should be set before acquiring focus");
489 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
492 if (!is_focus_cb_thread) {
493 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
494 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
496 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
497 * the focus state mutex could be still locked. Therefore, it returns error here. */
498 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
499 LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
500 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
502 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
505 if (is_focus_cb_thread && (stream_h->prev_acquired_focus > stream_h->acquired_focus)) {
506 LOGE("just lost focus in this callback, it is not allowed to acquire all again. acquired_focus[0x%x], prev[0x%x]",
507 stream_h->acquired_focus, stream_h->prev_acquired_focus);
508 ret = MM_ERROR_POLICY_INTERNAL;
512 focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH & ~(stream_h->acquired_focus);
514 LOGI("PLAYBACK/RECORDING focuses have already been ACQUIRED");
519 stream_h->is_requesting = true;
521 ret = mm_sound_acquire_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
522 if (ret == MM_ERROR_NONE) {
523 stream_h->acquired_focus |= focus_mask;
524 stream_h->prev_acquired_focus |= focus_mask;
525 _update_focus_status(stream_h->pa_info.index, (unsigned int)stream_h->acquired_focus);
529 stream_h->is_requesting = false;
530 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
531 if (!is_focus_cb_thread)
532 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
534 return _convert_sound_manager_error_code(__func__, ret);
537 int sound_manager_release_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
539 int ret = MM_ERROR_NONE;
540 bool is_focus_cb_thread = false;
541 bool is_focus_watch_cb_thread = false;
542 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
546 SM_INSTANCE_CHECK(stream_h);
548 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
549 return _convert_sound_manager_error_code(__func__, ret);
551 if (!is_focus_cb_thread) {
552 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
553 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
555 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
556 * the focus state mutex could be still locked. Therefore, it returns error here. */
557 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
558 LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
559 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
561 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
564 if (is_focus_cb_thread && (stream_h->prev_acquired_focus < stream_h->acquired_focus)) {
565 LOGE("just acquired focus in this callback, it is not allowed to release all again. acquired_focus[0x%x], prev[0x%x]",
566 stream_h->acquired_focus, stream_h->prev_acquired_focus);
567 ret = MM_ERROR_POLICY_INTERNAL;
571 if (!stream_h->acquired_focus) {
572 LOGI("PLAYBACK/RECORDING focuses have already been RELEASED");
577 stream_h->is_requesting = true;
579 ret = mm_sound_release_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)stream_h->acquired_focus, sound_behavior, extra_info);
580 if (ret == MM_ERROR_NONE) {
581 stream_h->acquired_focus = 0;
582 stream_h->prev_acquired_focus = 0;
583 _update_focus_status(stream_h->pa_info.index, (unsigned int)stream_h->acquired_focus);
587 stream_h->is_requesting = false;
588 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
589 if (!is_focus_cb_thread)
590 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
592 return _convert_sound_manager_error_code(__func__, ret);
595 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)
597 int ret = MM_ERROR_NONE;
598 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
602 SM_INSTANCE_CHECK(stream_h);
603 if (!state_for_playback && !state_for_recording)
604 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
606 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
608 if (state_for_playback)
609 *state_for_playback = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
610 if (state_for_recording)
611 *state_for_recording = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
613 LOGI("acquired_focus(0x%x)", stream_h->acquired_focus);
615 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
617 return _convert_sound_manager_error_code(__func__, ret);
620 int sound_manager_deliver_focus(sound_stream_info_h source, sound_stream_info_h destination, sound_stream_focus_mask_e focus_mask)
622 int ret = MM_ERROR_NONE;
623 sound_stream_info_s *src_stream_h = (sound_stream_info_s*)source;
624 sound_stream_info_s *dst_stream_h = (sound_stream_info_s*)destination;
625 bool is_focus_cb_thread = false;
629 SM_INSTANCE_CHECK(src_stream_h);
630 SM_INSTANCE_CHECK(dst_stream_h);
632 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
633 return _convert_sound_manager_error_code(__func__, ret);
635 if (is_focus_cb_thread) {
636 LOGE("not allowed calling this function in focus(watch) callback");
637 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
640 if (src_stream_h->focus_id == dst_stream_h->focus_id) {
641 LOGE("not allowed because both handles have same id(%u)", src_stream_h->focus_id);
642 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
645 if (src_stream_h->is_focus_unavailable || dst_stream_h->is_focus_unavailable) {
646 LOGE("focus is unavailable for source(%d)/destination(%d)",
647 src_stream_h->is_focus_unavailable, dst_stream_h->is_focus_unavailable);
648 return SOUND_MANAGER_ERROR_POLICY;
651 if (!(src_stream_h->acquired_focus & focus_mask) || (src_stream_h->acquired_focus < focus_mask)) {
652 LOGE("could not deliver the request focus(0x%x), current acquired focus(0x%x)",
653 focus_mask, src_stream_h->acquired_focus);
654 return SOUND_MANAGER_ERROR_INVALID_STATE;
657 if (dst_stream_h->user_cb == NULL) {
658 LOGE("focus state changed callback should be set to destination handle");
659 return SOUND_MANAGER_ERROR_POLICY;
662 ret = mm_sound_deliver_focus(src_stream_h->focus_id, dst_stream_h->focus_id, (mm_sound_focus_type_e)focus_mask);
663 if (ret == MM_ERROR_NONE) {
664 src_stream_h->acquired_focus &= ~focus_mask;
665 src_stream_h->prev_acquired_focus &= ~focus_mask;
666 dst_stream_h->acquired_focus |= focus_mask;
667 dst_stream_h->prev_acquired_focus |= focus_mask;
670 return _convert_sound_manager_error_code(__func__, ret);
673 int sound_manager_is_stream_on_device(sound_stream_info_h stream_info, sound_device_h device, bool *is_on)
675 int ret = MM_ERROR_NONE;
676 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
680 SM_NULL_ARG_CHECK(stream_h);
681 SM_NULL_ARG_CHECK(device);
682 SM_NULL_ARG_CHECK(is_on);
684 ret = mm_sound_is_stream_on_device(stream_h->pa_info.index, device, is_on);
686 return _convert_sound_manager_error_code(__func__, ret);
689 int sound_manager_get_current_media_playback_device_type(sound_device_type_e *device_type)
691 int ret = MM_ERROR_NONE;
695 SM_NULL_ARG_CHECK(device_type);
697 ret = _get_current_media_routing_path("out", device_type);
699 return _convert_sound_manager_error_code(__func__, ret);
702 int sound_manager_get_current_playback_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
704 int ret = MM_ERROR_NONE;
705 char *stream_type_str = NULL;
706 char *extra_info_str = NULL;
708 bool is_focus_cb_thread = false;
712 SM_NULL_ARG_CHECK(acquired_by);
713 SM_NULL_ARG_CHECK(flags);
715 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
716 return _convert_sound_manager_error_code(__func__, ret);
718 if (is_focus_cb_thread) {
719 LOGE("this API should not be called in focus callback");
720 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
723 ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_PLAYBACK, &stream_type_str, &option, &extra_info_str);
724 if (ret == MM_ERROR_NONE) {
725 LOGI("current acquired PLAYBACK focus : stream_type[%s]", stream_type_str);
726 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
727 if (ret == MM_ERROR_NONE) {
728 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
731 *extra_info = strdup(extra_info_str);
733 SM_SAFE_FREE(stream_type_str);
734 SM_SAFE_FREE(extra_info_str);
737 return _convert_sound_manager_error_code(__func__, ret);
740 int sound_manager_get_current_recording_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
742 int ret = MM_ERROR_NONE;
743 char *stream_type_str = NULL;
744 char *extra_info_str = NULL;
746 bool is_focus_cb_thread = false;
750 SM_NULL_ARG_CHECK(acquired_by);
751 SM_NULL_ARG_CHECK(flags);
753 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
754 return _convert_sound_manager_error_code(__func__, ret);
756 if (is_focus_cb_thread) {
757 LOGE("this API should not be called in focus callback");
758 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
761 ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_RECORDING, &stream_type_str, &option, &extra_info_str);
762 if (ret == MM_ERROR_NONE) {
763 LOGI("current acquired RECORDING focus : stream_type[%s]", stream_type_str);
764 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
765 if (ret == MM_ERROR_NONE) {
766 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
769 *extra_info = strdup(extra_info_str);
771 SM_SAFE_FREE(stream_type_str);
772 SM_SAFE_FREE(extra_info_str);
775 return _convert_sound_manager_error_code(__func__, ret);
778 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)
780 int ret = MM_ERROR_NONE;
785 SM_NULL_ARG_CHECK(callback);
786 SM_NULL_ARG_CHECK(id);
788 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
789 if (focus_watch_info_arr[i].id == 0)
791 if (i == SOUND_STREAM_INFO_ARR_MAX) {
793 LOGE("focus watch info array is full");
794 ret = MM_ERROR_SOUND_INTERNAL;
799 ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, &focus_watch_info_arr[i], id);
800 if (ret == MM_ERROR_NONE) {
801 focus_watch_info_arr[i].id = *id;
802 focus_watch_info_arr[i].user_data = user_data;
803 focus_watch_info_arr[i].user_cb = callback;
809 return _convert_sound_manager_error_code(__func__, ret);
812 int sound_manager_remove_focus_state_watch_cb(int id)
814 int ret = MM_ERROR_NONE;
819 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
820 if (focus_watch_info_arr[i].id == id)
822 if (i == SOUND_STREAM_INFO_ARR_MAX) {
823 LOGE("cound not find item in focus watch info array for this id(%d)", id);
824 ret = MM_ERROR_INVALID_ARGUMENT;
828 ret = mm_sound_unset_focus_watch_callback(id);
829 if (ret == MM_ERROR_NONE) {
830 focus_watch_info_arr[i].id = 0;
831 focus_watch_info_arr[i].user_data = NULL;
832 focus_watch_info_arr[i].user_cb = NULL;
836 return _convert_sound_manager_error_code(__func__, ret);
839 int sound_manager_get_device_list(int device_mask, sound_device_list_h *device_list)
841 int ret = MM_ERROR_NONE;
843 ret = mm_sound_get_device_list(device_mask, device_list);
845 return _convert_sound_manager_error_code(__func__, ret);
848 int sound_manager_free_device_list(sound_device_list_h device_list)
850 int ret = MM_ERROR_NONE;
852 ret = mm_sound_free_device_list(device_list);
854 return _convert_sound_manager_error_code(__func__, ret);
857 int sound_manager_get_next_device(sound_device_list_h device_list, sound_device_h *device)
859 int ret = MM_ERROR_NONE;
861 ret = mm_sound_get_next_device(device_list, device);
863 return _convert_sound_manager_error_code(__func__, ret);
866 int sound_manager_get_prev_device(sound_device_list_h device_list, sound_device_h *device)
868 int ret = MM_ERROR_NONE;
870 ret = mm_sound_get_prev_device(device_list, device);
872 return _convert_sound_manager_error_code(__func__, ret);
875 int sound_manager_get_device_type(sound_device_h device, sound_device_type_e *type)
877 int ret = MM_ERROR_NONE;
878 mm_sound_device_type_e mm_sound_device_type;
880 ret = mm_sound_get_device_type(device, &mm_sound_device_type);
881 if (ret == MM_ERROR_NONE)
882 ret = _convert_device_type(mm_sound_device_type, type);
884 return _convert_sound_manager_error_code(__func__, ret);
887 int sound_manager_get_device_io_direction(sound_device_h device, sound_device_io_direction_e *io_direction)
889 int ret = MM_ERROR_NONE;
890 mm_sound_device_io_direction_e mm_sound_io_direction;
892 ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction);
893 if (ret == MM_ERROR_NONE)
894 ret = _convert_device_io_direction(mm_sound_io_direction, io_direction);
896 return _convert_sound_manager_error_code(__func__, ret);
899 int sound_manager_get_device_id(sound_device_h device, int *id)
901 int ret = MM_ERROR_NONE;
903 ret = mm_sound_get_device_id(device, id);
905 return _convert_sound_manager_error_code(__func__, ret);
908 int sound_manager_get_device_name(sound_device_h device, char **name)
910 int ret = MM_ERROR_NONE;
912 ret = mm_sound_get_device_name(device, name);
914 return _convert_sound_manager_error_code(__func__, ret);
917 int sound_manager_is_device_running(sound_device_h device, bool *is_running)
919 int ret = MM_ERROR_NONE;
923 SM_INSTANCE_CHECK(device);
924 SM_NULL_ARG_CHECK(is_running);
926 ret = mm_sound_is_device_running(device, is_running);
928 return _convert_sound_manager_error_code(__func__, ret);
931 int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *state)
933 int ret = MM_ERROR_NONE;
935 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
936 ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
938 return _convert_sound_manager_error_code(__func__, ret);
941 int sound_manager_get_supported_sample_formats(sound_device_h device, sound_sample_format_e **formats, unsigned int *num_of_elems)
943 int ret = MM_ERROR_NONE;
946 SM_INSTANCE_CHECK(device);
947 SM_NULL_ARG_CHECK(formats);
948 SM_NULL_ARG_CHECK(num_of_elems);
950 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
953 if (!(ret = mm_sound_get_device_id(device, &device_id)))
954 ret = _get_supported_sample_formats(device_id, formats, num_of_elems);
956 return _convert_sound_manager_error_code(__func__, ret);
959 int sound_manager_set_sample_format(sound_device_h device, sound_sample_format_e format)
961 int ret = MM_ERROR_NONE;
964 SM_INSTANCE_CHECK(device);
966 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
969 if (!(ret = mm_sound_get_device_id(device, &device_id)))
970 ret = _set_sample_format(device_id, format);
972 return _convert_sound_manager_error_code(__func__, ret);
975 int sound_manager_get_sample_format(sound_device_h device, sound_sample_format_e *format)
977 int ret = MM_ERROR_NONE;
980 SM_INSTANCE_CHECK(device);
981 SM_NULL_ARG_CHECK(format);
983 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
986 if (!(ret = mm_sound_get_device_id(device, &device_id)))
987 ret = _get_sample_format(device_id, format);
989 return _convert_sound_manager_error_code(__func__, ret);
992 int sound_manager_get_supported_sample_rates(sound_device_h device, sound_sample_rate_e **rates, unsigned int *num_of_elems)
994 int ret = MM_ERROR_NONE;
997 SM_INSTANCE_CHECK(device);
998 SM_NULL_ARG_CHECK(rates);
999 SM_NULL_ARG_CHECK(num_of_elems);
1001 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
1004 if (!(ret = mm_sound_get_device_id(device, &device_id)))
1005 ret = _get_supported_sample_rates(device_id, rates, num_of_elems);
1007 return _convert_sound_manager_error_code(__func__, ret);
1010 int sound_manager_set_sample_rate(sound_device_h device, sound_sample_rate_e rate)
1012 int ret = MM_ERROR_NONE;
1015 SM_INSTANCE_CHECK(device);
1017 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
1020 if (!(ret = mm_sound_get_device_id(device, &device_id)))
1021 ret = _set_sample_rate(device_id, rate);
1023 return _convert_sound_manager_error_code(__func__, ret);
1026 int sound_manager_get_sample_rate(sound_device_h device, sound_sample_rate_e *rate)
1028 int ret = MM_ERROR_NONE;
1031 SM_INSTANCE_CHECK(device);
1032 SM_NULL_ARG_CHECK(rate);
1034 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
1037 if (!(ret = mm_sound_get_device_id(device, &device_id)))
1038 ret = _get_sample_rate(device_id, rate);
1040 return _convert_sound_manager_error_code(__func__, ret);
1043 int sound_manager_set_avoid_resampling(sound_device_h device, bool enable)
1045 int ret = MM_ERROR_NONE;
1048 SM_INSTANCE_CHECK(device);
1050 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
1053 if (!(ret = mm_sound_get_device_id(device, &device_id)))
1054 ret = _set_avoid_resampling(device_id, enable);
1056 return _convert_sound_manager_error_code(__func__, ret);
1059 int sound_manager_get_avoid_resampling(sound_device_h device, bool *enabled)
1061 int ret = MM_ERROR_NONE;
1064 SM_INSTANCE_CHECK(device);
1065 SM_NULL_ARG_CHECK(enabled);
1067 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
1070 if (!(ret = mm_sound_get_device_id(device, &device_id)))
1071 ret = _get_avoid_resampling(device_id, enabled);
1073 return _convert_sound_manager_error_code(__func__, ret);
1076 int sound_manager_set_media_stream_only(sound_device_h device, bool enable)
1078 int ret = MM_ERROR_NONE;
1081 SM_INSTANCE_CHECK(device);
1083 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
1086 if (!(ret = mm_sound_get_device_id(device, &device_id)))
1087 ret = _set_media_stream_only(device_id, enable);
1089 return _convert_sound_manager_error_code(__func__, ret);
1092 int sound_manager_get_media_stream_only(sound_device_h device, bool *enabled)
1094 int ret = MM_ERROR_NONE;
1097 SM_INSTANCE_CHECK(device);
1098 SM_NULL_ARG_CHECK(enabled);
1100 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
1103 if (!(ret = mm_sound_get_device_id(device, &device_id)))
1104 ret = _get_media_stream_only(device_id, enabled);
1106 return _convert_sound_manager_error_code(__func__, ret);
1109 int sound_manager_add_device_connection_changed_cb(int device_mask, sound_device_connection_changed_cb callback, void *user_data, int *id)
1111 int ret = MM_ERROR_NONE;
1113 SM_NULL_ARG_CHECK(callback);
1114 SM_NULL_ARG_CHECK(id);
1116 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);
1118 return _convert_sound_manager_error_code(__func__, ret);
1121 int sound_manager_remove_device_connection_changed_cb(int id)
1123 int ret = MM_ERROR_NONE;
1126 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1128 ret = mm_sound_remove_device_connected_callback((unsigned int)id);
1130 return _convert_sound_manager_error_code(__func__, ret);
1133 int sound_manager_add_device_running_changed_cb(int device_mask, sound_device_running_changed_cb callback, void *user_data, int *id)
1135 int ret = MM_ERROR_NONE;
1137 SM_NULL_ARG_CHECK(callback);
1138 SM_NULL_ARG_CHECK(id);
1140 ret = mm_sound_add_device_running_changed_callback(device_mask, (mm_sound_device_running_changed_cb)callback, user_data, (unsigned int*)id);
1142 return _convert_sound_manager_error_code(__func__, ret);
1145 int sound_manager_remove_device_running_changed_cb(int id)
1147 int ret = MM_ERROR_NONE;
1150 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1152 ret = mm_sound_remove_device_running_changed_callback((unsigned int)id);
1154 return _convert_sound_manager_error_code(__func__, ret);
1157 int sound_manager_add_device_state_changed_cb(int device_mask, sound_device_state_changed_cb callback, void *user_data, int *id)
1159 int ret = MM_ERROR_NONE;
1161 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1162 SM_NULL_ARG_CHECK(callback);
1163 SM_NULL_ARG_CHECK(id);
1165 ret = mm_sound_add_device_state_changed_callback(device_mask, (mm_sound_device_state_changed_cb)callback, user_data, (unsigned int*)id);
1167 return _convert_sound_manager_error_code(__func__, ret);
1170 int sound_manager_remove_device_state_changed_cb(int id)
1172 int ret = MM_ERROR_NONE;
1174 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1176 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1178 ret = mm_sound_remove_device_state_changed_callback((unsigned int)id);
1180 return _convert_sound_manager_error_code(__func__, ret);
1183 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)
1186 int ret = MM_ERROR_NONE;
1187 sound_stream_ducking_s *new_ducking = NULL;
1189 SM_NULL_ARG_CHECK(stream_ducking);
1191 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1193 for (i = 0 ; i < SOUND_DUCKING_ARR_MAX ; i++)
1194 if (ducking_arr[i] == NULL)
1197 if (i == SOUND_DUCKING_ARR_MAX) {
1198 LOGE("ducking array is full");
1199 ret = MM_ERROR_SOUND_INTERNAL;
1203 new_ducking = (sound_stream_ducking_s *)calloc(1, sizeof(sound_stream_ducking_s));
1205 ret = MM_ERROR_OUT_OF_MEMORY;
1209 ret = _convert_stream_type(target_stream, &new_ducking->target_stream);
1210 if (ret != MM_ERROR_NONE)
1213 ret = _make_pa_connection(&new_ducking->pa_info, "SOUND_MANAGER_STREAM_DUCKING");
1216 if (ret == MM_ERROR_NONE) {
1217 if (++ducking_arr_count == 1) {
1218 /* subscribe ducking finished signal */
1219 ret = mm_sound_add_ducking_state_changed_callback((mm_sound_ducking_state_changed_cb)_ducking_state_changed_cb,
1220 NULL, &ducking_cb_subs_id);
1221 if (ret != MM_ERROR_NONE) {
1222 ducking_arr_count = 0;
1226 LOGI("ducking state changed cb subs id %d", ducking_cb_subs_id);
1229 new_ducking->user_cb = callback;
1230 new_ducking->user_data = user_data;
1232 ducking_arr[i] = new_ducking;
1233 *stream_ducking = (sound_stream_ducking_h)new_ducking;
1235 LOGI("new stream_ducking(%p), target_stream(%s), pa_index(%u), user_cb(%p)",
1236 new_ducking, new_ducking->target_stream, new_ducking->pa_info.index, new_ducking->user_cb);
1239 _destroy_pa_connection(&new_ducking->pa_info);
1244 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1246 return _convert_sound_manager_error_code(__func__, ret);
1249 int sound_manager_destroy_stream_ducking(sound_stream_ducking_h stream_ducking)
1252 int ret = MM_ERROR_NONE;
1253 bool is_ducked = false;
1254 sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1256 LOGI(">> enter %p", ducking);
1258 SM_INSTANCE_CHECK(ducking);
1260 ret = _get_ducking_state(&ducking->pa_info, &is_ducked);
1261 if (ret != MM_ERROR_NONE && ret != MM_ERROR_SOUND_SERVER_DISCONNECTED)
1262 return _convert_sound_manager_error_code(__func__, ret);
1265 LOGE("ducked now, it should be deactivated first.");
1266 return SOUND_MANAGER_ERROR_INVALID_STATE;
1269 LOGI("destroy stream ducking(%p)", ducking);
1271 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1273 _destroy_pa_connection(&ducking->pa_info);
1275 for (i = 0 ; i < SOUND_DUCKING_ARR_MAX ; i++)
1276 if (ducking_arr[i] == ducking)
1277 ducking_arr[i] = NULL;
1279 if (--ducking_arr_count == 0) {
1280 /* unsubscribe ducking finished signal */
1281 if (mm_sound_remove_ducking_state_changed_callback(ducking_cb_subs_id) != MM_ERROR_NONE)
1282 LOGW("mm_sound_remove_ducking_state_changed_callback(id:%u) failed", ducking_cb_subs_id);
1284 ducking_cb_subs_id = 0;
1289 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1291 return _convert_sound_manager_error_code(__func__, MM_ERROR_NONE);
1294 int sound_manager_is_ducked(sound_stream_ducking_h stream_ducking, bool *is_ducked)
1296 int ret = MM_ERROR_NONE;
1297 sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1299 LOGI(">> enter %p", ducking);
1301 SM_INSTANCE_CHECK(ducking);
1302 SM_NULL_ARG_CHECK(is_ducked);
1304 ret = _get_ducking_state(&ducking->pa_info, is_ducked);
1306 return _convert_sound_manager_error_code(__func__, ret);
1309 int sound_manager_activate_ducking(sound_stream_ducking_h stream_ducking, unsigned int duration, double ratio)
1311 int ret = MM_ERROR_NONE;
1312 bool is_ducked = false;
1313 sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1315 if (duration > 3000 || ratio >= 1.0 || ratio < 0.0) {
1316 LOGE("Invalid params : duration(%u) or ratio(%lf)", duration, ratio);
1317 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
1320 LOGI(">> enter %p - duration(%u), ratio(%lf)", ducking, duration, ratio);
1322 SM_INSTANCE_CHECK(ducking);
1324 ret = _get_ducking_state(&ducking->pa_info, &is_ducked);
1325 if (ret != MM_ERROR_NONE)
1326 return _convert_sound_manager_error_code(__func__, ret);
1329 LOGE("already ducked");
1330 return SOUND_MANAGER_ERROR_INVALID_STATE;
1333 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1335 ret = _activate_ducking(ducking->pa_info.index,
1336 true, ducking->target_stream, (uint32_t)duration, ratio);
1338 if (ret == MM_ERROR_NONE) {
1339 ducking->duration = duration;
1340 ducking->ratio = ratio;
1343 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1345 return _convert_sound_manager_error_code(__func__, ret);
1348 int sound_manager_deactivate_ducking(sound_stream_ducking_h stream_ducking)
1350 int ret = MM_ERROR_NONE;
1351 bool is_ducked = false;
1352 sound_stream_ducking_s *ducking = (sound_stream_ducking_s*)stream_ducking;
1354 LOGI(">> enter %p", ducking);
1356 SM_INSTANCE_CHECK(ducking);
1358 ret = _get_ducking_state(&ducking->pa_info, &is_ducked);
1359 if (ret != MM_ERROR_NONE)
1360 return _convert_sound_manager_error_code(__func__, ret);
1364 return SOUND_MANAGER_ERROR_INVALID_STATE;
1367 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&ducking_mutex, SOUND_MANAGER_ERROR_INTERNAL);
1369 ret = _activate_ducking(ducking->pa_info.index,
1370 false, ducking->target_stream, (uint32_t)ducking->duration, ducking->ratio);
1372 SM_LEAVE_CRITICAL_SECTION(&ducking_mutex);
1374 return _convert_sound_manager_error_code(__func__, ret);