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 _focus_watch_info_s focus_watch_info_arr[SOUND_STREAM_INFO_ARR_MAX];
22 int sound_manager_get_max_volume(sound_type_e type, int *max)
24 const char *volume_type = NULL;
25 unsigned int max_level = 0;
26 int ret = MM_ERROR_NONE;
28 SM_NULL_ARG_CHECK(max);
29 if (type >= SOUND_TYPE_NUM)
30 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
32 ret = _convert_sound_type(type, &volume_type);
33 if (ret == MM_ERROR_NONE) {
34 ret = _get_volume_max_level(DIRECTION_OUT_STR, volume_type, &max_level);
35 if (ret == MM_ERROR_NONE)
36 *max = (int)max_level -1; /* actual volume step can be max step - 1 */
39 return _convert_sound_manager_error_code(__func__, ret);
42 int sound_manager_set_volume(sound_type_e type, int volume)
44 int ret = MM_ERROR_NONE;
46 if (type >= SOUND_TYPE_NUM)
47 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
49 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
51 ret = mm_sound_volume_set_value(type, volume);
52 LOGI("type=%d, volume=%d", type, volume);
54 return _convert_sound_manager_error_code(__func__, ret);
57 int sound_manager_get_volume(sound_type_e type, int *volume)
59 int ret = MM_ERROR_NONE;
62 if (type >= SOUND_TYPE_NUM)
63 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
65 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
67 ret = mm_sound_volume_get_value(type, &uvolume);
68 if (ret == MM_ERROR_NONE)
71 LOGI("type=%d, volume=%d", type, *volume);
73 return _convert_sound_manager_error_code(__func__, ret);
76 int sound_manager_get_current_sound_type(sound_type_e *type)
78 int ret = MM_ERROR_NONE;
79 char *volume_type = NULL;
82 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
84 /* get the volume type of the current playing stream */
85 ret = _get_current_volume_type(DIRECTION_OUT_STR, &volume_type);
86 if (ret == MM_ERROR_NONE) {
87 ret = _convert_sound_type_to_enum((const char*)volume_type, type);
88 LOGI("type=%d", *type);
91 return _convert_sound_manager_error_code(__func__, ret);
94 int sound_manager_add_volume_changed_cb(sound_manager_volume_changed_cb callback, void *user_data, int *id)
96 int ret = MM_ERROR_NONE;
99 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
101 ret = mm_sound_add_volume_changed_callback((mm_sound_volume_changed_cb)callback, user_data, (unsigned int*)id);
103 return _convert_sound_manager_error_code(__func__, ret);
106 int sound_manager_remove_volume_changed_cb(int id)
108 int ret = MM_ERROR_NONE;
111 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
113 ret = mm_sound_remove_volume_changed_callback(id);
115 return _convert_sound_manager_error_code(__func__, ret);
118 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)
120 int ret = MM_ERROR_NONE;
124 SM_NULL_ARG_CHECK(stream_info);
126 sound_stream_info_s *stream_h = malloc(sizeof(sound_stream_info_s));
128 ret = MM_ERROR_OUT_OF_MEMORY;
132 memset(stream_h, 0, sizeof(sound_stream_info_s));
133 ret = _convert_stream_type(stream_type, &stream_h->stream_type);
134 if (ret == MM_ERROR_NONE) {
135 ret = _make_pa_connection_and_register_focus(stream_h, callback, user_data);
136 if (ret == MM_ERROR_NONE) {
137 *stream_info = (sound_stream_info_h)stream_h;
138 LOGI("stream_h(%p), pa_index(%u), focus_id(%d), user_cb(%p), ret(0x%x)",
139 stream_h, stream_h->pa_index, stream_h->focus_id, stream_h->user_cb, ret);
145 SM_SAFE_FREE(stream_h);
147 return _convert_sound_manager_error_code(__func__, ret);
150 int sound_manager_destroy_stream_information(sound_stream_info_h stream_info)
152 int ret = MM_ERROR_NONE;
153 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
157 SM_INSTANCE_CHECK(stream_h);
159 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
160 ret = _destroy_pa_connection_and_unregister_focus(stream_h);
161 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
162 if (ret == MM_ERROR_NONE) {
163 SM_SAFE_FREE(stream_h);
166 return _convert_sound_manager_error_code(__func__, ret);
169 int sound_manager_get_sound_type(sound_stream_info_h stream_info, sound_type_e *sound_type)
171 int ret = MM_ERROR_NONE;
172 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
176 SM_INSTANCE_CHECK(stream_h);
177 SM_NULL_ARG_CHECK(sound_type);
179 if (stream_h->stream_conf_info.volume_type == NULL) {
180 ret = MM_ERROR_SOUND_NO_DATA;
184 ret = _convert_sound_type_to_enum(stream_h->stream_conf_info.volume_type, sound_type);
185 LOGI("sound type(%d)", *sound_type);
188 return _convert_sound_manager_error_code(__func__, ret);
191 int sound_manager_add_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
193 int ret = MM_ERROR_NONE;
194 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
198 ret = _add_device_for_stream_routing(stream_h, device);
200 return _convert_sound_manager_error_code(__func__, ret);
203 int sound_manager_remove_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
205 int ret = MM_ERROR_NONE;
206 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
210 ret = _remove_device_for_stream_routing(stream_h, device);
212 return _convert_sound_manager_error_code(__func__, ret);
215 int sound_manager_remove_all_devices_for_stream_routing(sound_stream_info_h stream_info)
217 int ret = MM_ERROR_NONE;
218 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
222 ret = _remove_all_devices_for_stream_routing(stream_h);
224 return _convert_sound_manager_error_code(__func__, ret);
227 int sound_manager_apply_stream_routing(sound_stream_info_h stream_info)
229 int ret = MM_ERROR_NONE;
230 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
234 ret = _apply_stream_routing(stream_h);
236 return _convert_sound_manager_error_code(__func__, ret);
239 int sound_manager_set_focus_reacquisition(sound_stream_info_h stream_info, bool enable)
241 int ret = MM_ERROR_NONE;
242 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
246 SM_INSTANCE_CHECK(stream_h);
248 ret = mm_sound_set_focus_reacquisition(stream_h->focus_id, enable);
250 LOGI("enable(%d)", enable);
252 return _convert_sound_manager_error_code(__func__, ret);
255 int sound_manager_get_focus_reacquisition(sound_stream_info_h stream_info, bool *enabled)
257 int ret = MM_ERROR_NONE;
258 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
262 SM_INSTANCE_CHECK(stream_h);
263 SM_NULL_ARG_CHECK(enabled);
265 ret = mm_sound_get_focus_reacquisition(stream_h->focus_id, enabled);
267 LOGI("enabled(%d)", *enabled);
269 return _convert_sound_manager_error_code(__func__, ret);
272 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)
274 int ret = MM_ERROR_NONE;
275 bool is_focus_cb_thread = false;
276 bool is_focus_watch_cb_thread = false;
277 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
281 SM_INSTANCE_CHECK(stream_h);
283 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
284 return _convert_sound_manager_error_code(__func__, ret);
286 if (stream_h->is_focus_unavailable) {
287 LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
288 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
291 if (stream_h->user_cb == NULL) {
292 LOGE("focus state changed callback should be set before acquiring focus");
293 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
296 if (!is_focus_cb_thread) {
297 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
298 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
300 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
301 * the focus state mutex could be still locked. Therefore, it returns error here. */
302 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
303 LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
304 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
306 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
309 if (stream_h->acquired_focus & focus_mask) {
310 LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
311 ret = MM_ERROR_SOUND_INVALID_STATE;
315 if (is_focus_cb_thread && ((stream_h->prev_acquired_focus & ~stream_h->acquired_focus) & focus_mask)) {
316 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]",
317 focus_mask, stream_h->acquired_focus, stream_h->prev_acquired_focus);
318 ret = MM_ERROR_POLICY_INTERNAL;
322 stream_h->is_requesting = true;
324 ret = mm_sound_acquire_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
325 if (ret == MM_ERROR_NONE) {
326 stream_h->acquired_focus |= focus_mask;
327 stream_h->prev_acquired_focus |= focus_mask;
328 _update_focus_status(stream_h->pa_index, (unsigned int)stream_h->acquired_focus);
331 LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
334 stream_h->is_requesting = false;
335 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
336 if (!is_focus_cb_thread)
337 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
339 return _convert_sound_manager_error_code(__func__, ret);
342 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)
344 int ret = MM_ERROR_NONE;
345 bool is_focus_cb_thread = false;
346 bool is_focus_watch_cb_thread = false;
347 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
351 SM_INSTANCE_CHECK(stream_h);
353 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
354 return _convert_sound_manager_error_code(__func__, ret);
356 if (!is_focus_cb_thread) {
357 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
358 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
360 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
361 * the focus state mutex could be still locked. Therefore, it returns error here. */
362 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
363 LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
364 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
366 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
369 if (!(stream_h->acquired_focus & focus_mask)) {
370 LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
371 ret = MM_ERROR_SOUND_INVALID_STATE;
375 if (is_focus_cb_thread && ((stream_h->prev_acquired_focus & stream_h->acquired_focus) != focus_mask)) {
376 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]",
377 focus_mask, stream_h->acquired_focus, stream_h->prev_acquired_focus);
378 ret = MM_ERROR_SOUND_INVALID_STATE;
382 stream_h->is_requesting = true;
384 ret = mm_sound_release_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
385 if (ret == MM_ERROR_NONE) {
386 stream_h->acquired_focus &= ~focus_mask;
387 stream_h->prev_acquired_focus &= ~focus_mask;
388 _update_focus_status(stream_h->pa_index, (unsigned int)stream_h->acquired_focus);
391 LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
394 stream_h->is_requesting = false;
395 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
396 if (!is_focus_cb_thread)
397 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
399 return _convert_sound_manager_error_code(__func__, ret);
402 int sound_manager_acquire_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
404 int ret = MM_ERROR_NONE;
405 int focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH;
406 bool is_focus_cb_thread = false;
407 bool is_focus_watch_cb_thread = false;
408 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
412 SM_INSTANCE_CHECK(stream_h);
414 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
415 return _convert_sound_manager_error_code(__func__, ret);
417 if (stream_h->is_focus_unavailable) {
418 LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
419 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
422 if (stream_h->user_cb == NULL) {
423 LOGE("focus state changed callback should be set before acquiring focus");
424 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
427 if (!is_focus_cb_thread) {
428 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
429 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
431 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
432 * the focus state mutex could be still locked. Therefore, it returns error here. */
433 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
434 LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
435 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
437 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
440 if (is_focus_cb_thread && (stream_h->prev_acquired_focus > stream_h->acquired_focus)) {
441 LOGE("just lost focus in this callback, it is not allowed to acquire all again. acquired_focus[0x%x], prev[0x%x]",
442 stream_h->acquired_focus, stream_h->prev_acquired_focus);
443 ret = MM_ERROR_POLICY_INTERNAL;
447 focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH & ~(stream_h->acquired_focus);
449 LOGI("PLAYBACK/RECORDING focuses have already been ACQUIRED");
454 stream_h->is_requesting = true;
456 ret = mm_sound_acquire_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
457 if (ret == MM_ERROR_NONE) {
458 stream_h->acquired_focus |= focus_mask;
459 stream_h->prev_acquired_focus |= focus_mask;
460 _update_focus_status(stream_h->pa_index, (unsigned int)stream_h->acquired_focus);
464 stream_h->is_requesting = false;
465 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
466 if (!is_focus_cb_thread)
467 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
469 return _convert_sound_manager_error_code(__func__, ret);
472 int sound_manager_release_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
474 int ret = MM_ERROR_NONE;
475 bool is_focus_cb_thread = false;
476 bool is_focus_watch_cb_thread = false;
477 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
481 SM_INSTANCE_CHECK(stream_h);
483 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, &is_focus_watch_cb_thread)))
484 return _convert_sound_manager_error_code(__func__, ret);
486 if (!is_focus_cb_thread) {
487 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
488 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
490 /* If it is inside of the watch cb and if the previous request of this process has not been finished yet,
491 * the focus state mutex could be still locked. Therefore, it returns error here. */
492 if (is_focus_watch_cb_thread && stream_h->is_requesting) {
493 LOGE("It is not allowed in watch cb thread during the previous request has not been finished yet");
494 return _convert_sound_manager_error_code(__func__, MM_ERROR_SOUND_INVALID_OPERATION);
496 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
499 if (is_focus_cb_thread && (stream_h->prev_acquired_focus < stream_h->acquired_focus)) {
500 LOGE("just acquired focus in this callback, it is not allowed to release all again. acquired_focus[0x%x], prev[0x%x]",
501 stream_h->acquired_focus, stream_h->prev_acquired_focus);
502 ret = MM_ERROR_POLICY_INTERNAL;
506 if (!stream_h->acquired_focus) {
507 LOGI("PLAYBACK/RECORDING focuses have already been RELEASED");
512 stream_h->is_requesting = true;
514 ret = mm_sound_release_focus_with_option(stream_h->focus_id, (mm_sound_focus_type_e)stream_h->acquired_focus, sound_behavior, extra_info);
515 if (ret == MM_ERROR_NONE) {
516 stream_h->acquired_focus = 0;
517 stream_h->prev_acquired_focus = 0;
518 _update_focus_status(stream_h->pa_index, (unsigned int)stream_h->acquired_focus);
522 stream_h->is_requesting = false;
523 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
524 if (!is_focus_cb_thread)
525 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
527 return _convert_sound_manager_error_code(__func__, ret);
530 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)
532 int ret = MM_ERROR_NONE;
533 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
537 SM_INSTANCE_CHECK(stream_h);
538 if (!state_for_playback && !state_for_recording)
539 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
541 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
543 if (state_for_playback)
544 *state_for_playback = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
545 if (state_for_recording)
546 *state_for_recording = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
548 LOGI("acquired_focus(0x%x)", stream_h->acquired_focus);
550 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
552 return _convert_sound_manager_error_code(__func__, ret);
555 int sound_manager_deliver_focus(sound_stream_info_h source, sound_stream_info_h destination, sound_stream_focus_mask_e focus_mask)
557 int ret = MM_ERROR_NONE;
558 sound_stream_info_s *src_stream_h = (sound_stream_info_s*)source;
559 sound_stream_info_s *dst_stream_h = (sound_stream_info_s*)destination;
560 bool is_focus_cb_thread = false;
564 SM_INSTANCE_CHECK(src_stream_h);
565 SM_INSTANCE_CHECK(dst_stream_h);
567 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
568 return _convert_sound_manager_error_code(__func__, ret);
570 if (is_focus_cb_thread) {
571 LOGE("not allowed calling this function in focus(watch) callback");
572 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
575 if (src_stream_h->focus_id == dst_stream_h->focus_id) {
576 LOGE("not allowed because both handles have same id(%u)", src_stream_h->focus_id);
577 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
580 if (src_stream_h->is_focus_unavailable || dst_stream_h->is_focus_unavailable) {
581 LOGE("focus is unavailable for source(%d)/destination(%d)",
582 src_stream_h->is_focus_unavailable, dst_stream_h->is_focus_unavailable);
583 return SOUND_MANAGER_ERROR_POLICY;
586 if (!(src_stream_h->acquired_focus & focus_mask) || (src_stream_h->acquired_focus < focus_mask)) {
587 LOGE("could not deliver the request focus(0x%x), current acquired focus(0x%x)",
588 focus_mask, src_stream_h->acquired_focus);
589 return SOUND_MANAGER_ERROR_INVALID_STATE;
592 if (dst_stream_h->user_cb == NULL) {
593 LOGE("focus state changed callback should be set to destination handle");
594 return SOUND_MANAGER_ERROR_POLICY;
597 ret = mm_sound_deliver_focus(src_stream_h->focus_id, dst_stream_h->focus_id, (mm_sound_focus_type_e)focus_mask);
598 if (ret == MM_ERROR_NONE) {
599 src_stream_h->acquired_focus &= ~focus_mask;
600 src_stream_h->prev_acquired_focus &= ~focus_mask;
601 dst_stream_h->acquired_focus |= focus_mask;
602 dst_stream_h->prev_acquired_focus |= focus_mask;
605 return _convert_sound_manager_error_code(__func__, ret);
608 int sound_manager_is_stream_on_device(sound_stream_info_h stream_info, sound_device_h device, bool *is_on)
610 int ret = MM_ERROR_NONE;
611 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
615 SM_NULL_ARG_CHECK(stream_h);
616 SM_NULL_ARG_CHECK(device);
617 SM_NULL_ARG_CHECK(is_on);
619 ret = mm_sound_is_stream_on_device(stream_h->pa_index, device, is_on);
621 return _convert_sound_manager_error_code(__func__, ret);
624 int sound_manager_get_current_media_playback_device_type(sound_device_type_e *device_type)
626 int ret = MM_ERROR_NONE;
630 SM_NULL_ARG_CHECK(device_type);
632 ret = _get_current_media_routing_path("out", device_type);
634 return _convert_sound_manager_error_code(__func__, ret);
637 int sound_manager_get_current_playback_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
639 int ret = MM_ERROR_NONE;
640 char *stream_type_str = NULL;
641 char *extra_info_str = NULL;
643 bool is_focus_cb_thread = false;
647 SM_NULL_ARG_CHECK(acquired_by);
648 SM_NULL_ARG_CHECK(flags);
650 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
651 return _convert_sound_manager_error_code(__func__, ret);
653 if (is_focus_cb_thread) {
654 LOGE("this API should not be called in focus callback");
655 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
658 ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_PLAYBACK, &stream_type_str, &option, &extra_info_str);
659 if (ret == MM_ERROR_NONE) {
660 LOGI("current acquired PLAYBACK focus : stream_type[%s]", stream_type_str);
661 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
662 if (ret == MM_ERROR_NONE) {
663 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
666 *extra_info = strdup(extra_info_str);
668 SM_SAFE_FREE(stream_type_str);
669 SM_SAFE_FREE(extra_info_str);
672 return _convert_sound_manager_error_code(__func__, ret);
675 int sound_manager_get_current_recording_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
677 int ret = MM_ERROR_NONE;
678 char *stream_type_str = NULL;
679 char *extra_info_str = NULL;
681 bool is_focus_cb_thread = false;
685 SM_NULL_ARG_CHECK(acquired_by);
686 SM_NULL_ARG_CHECK(flags);
688 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread, NULL)))
689 return _convert_sound_manager_error_code(__func__, ret);
691 if (is_focus_cb_thread) {
692 LOGE("this API should not be called in focus callback");
693 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
696 ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_RECORDING, &stream_type_str, &option, &extra_info_str);
697 if (ret == MM_ERROR_NONE) {
698 LOGI("current acquired RECORDING focus : stream_type[%s]", stream_type_str);
699 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
700 if (ret == MM_ERROR_NONE) {
701 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
704 *extra_info = strdup(extra_info_str);
706 SM_SAFE_FREE(stream_type_str);
707 SM_SAFE_FREE(extra_info_str);
710 return _convert_sound_manager_error_code(__func__, ret);
713 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)
715 int ret = MM_ERROR_NONE;
720 SM_NULL_ARG_CHECK(callback);
721 SM_NULL_ARG_CHECK(id);
723 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
724 if (focus_watch_info_arr[i].id == 0)
726 if (i == SOUND_STREAM_INFO_ARR_MAX) {
728 LOGE("focus watch info array is full");
729 ret = MM_ERROR_SOUND_INTERNAL;
734 ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, &focus_watch_info_arr[i], id);
735 if (ret == MM_ERROR_NONE) {
736 focus_watch_info_arr[i].id = *id;
737 focus_watch_info_arr[i].user_data = user_data;
738 focus_watch_info_arr[i].user_cb = callback;
744 return _convert_sound_manager_error_code(__func__, ret);
747 int sound_manager_remove_focus_state_watch_cb(int id)
749 int ret = MM_ERROR_NONE;
754 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
755 if (focus_watch_info_arr[i].id == id)
757 if (i == SOUND_STREAM_INFO_ARR_MAX) {
758 LOGE("cound not find item in focus watch info array for this id(%d)", id);
759 ret = MM_ERROR_INVALID_ARGUMENT;
763 ret = mm_sound_unset_focus_watch_callback(id);
764 if (ret == MM_ERROR_NONE) {
765 focus_watch_info_arr[i].id = 0;
766 focus_watch_info_arr[i].user_data = NULL;
767 focus_watch_info_arr[i].user_cb = NULL;
771 return _convert_sound_manager_error_code(__func__, ret);
774 int sound_manager_get_device_list(int device_mask, sound_device_list_h *device_list)
776 int ret = MM_ERROR_NONE;
778 ret = mm_sound_get_device_list(device_mask, device_list);
780 return _convert_sound_manager_error_code(__func__, ret);
783 int sound_manager_free_device_list(sound_device_list_h device_list)
785 int ret = MM_ERROR_NONE;
787 ret = mm_sound_free_device_list(device_list);
789 return _convert_sound_manager_error_code(__func__, ret);
792 int sound_manager_get_next_device(sound_device_list_h device_list, sound_device_h *device)
794 int ret = MM_ERROR_NONE;
796 ret = mm_sound_get_next_device(device_list, device);
798 return _convert_sound_manager_error_code(__func__, ret);
801 int sound_manager_get_prev_device(sound_device_list_h device_list, sound_device_h *device)
803 int ret = MM_ERROR_NONE;
805 ret = mm_sound_get_prev_device(device_list, device);
807 return _convert_sound_manager_error_code(__func__, ret);
810 int sound_manager_get_device_type(sound_device_h device, sound_device_type_e *type)
812 int ret = MM_ERROR_NONE;
813 mm_sound_device_type_e mm_sound_device_type;
815 ret = mm_sound_get_device_type(device, &mm_sound_device_type);
816 if (ret == MM_ERROR_NONE)
817 ret = _convert_device_type(mm_sound_device_type, type);
819 return _convert_sound_manager_error_code(__func__, ret);
822 int sound_manager_get_device_io_direction(sound_device_h device, sound_device_io_direction_e *io_direction)
824 int ret = MM_ERROR_NONE;
825 mm_sound_device_io_direction_e mm_sound_io_direction;
827 ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction);
828 if (ret == MM_ERROR_NONE)
829 ret = _convert_device_io_direction(mm_sound_io_direction, io_direction);
831 return _convert_sound_manager_error_code(__func__, ret);
834 int sound_manager_get_device_id(sound_device_h device, int *id)
836 int ret = MM_ERROR_NONE;
838 ret = mm_sound_get_device_id(device, id);
840 return _convert_sound_manager_error_code(__func__, ret);
843 int sound_manager_get_device_name(sound_device_h device, char **name)
845 int ret = MM_ERROR_NONE;
847 ret = mm_sound_get_device_name(device, name);
849 return _convert_sound_manager_error_code(__func__, ret);
852 int sound_manager_is_device_running(sound_device_h device, bool *is_running)
854 int ret = MM_ERROR_NONE;
858 SM_INSTANCE_CHECK(device);
859 SM_NULL_ARG_CHECK(is_running);
861 ret = mm_sound_is_device_running(device, is_running);
863 return _convert_sound_manager_error_code(__func__, ret);
866 int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *state)
868 int ret = MM_ERROR_NONE;
870 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
871 ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
873 return _convert_sound_manager_error_code(__func__, ret);
876 int sound_manager_get_supported_sample_formats(sound_device_h device, sound_sample_format_e **formats, unsigned int *num_of_elems)
878 int ret = MM_ERROR_NONE;
881 SM_INSTANCE_CHECK(device);
882 SM_NULL_ARG_CHECK(formats);
883 SM_NULL_ARG_CHECK(num_of_elems);
885 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
888 if (!(ret = mm_sound_get_device_id(device, &device_id)))
889 ret = _get_supported_sample_formats(device_id, formats, num_of_elems);
891 return _convert_sound_manager_error_code(__func__, ret);
894 int sound_manager_set_sample_format(sound_device_h device, sound_sample_format_e format)
896 int ret = MM_ERROR_NONE;
899 SM_INSTANCE_CHECK(device);
901 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
904 if (!(ret = mm_sound_get_device_id(device, &device_id)))
905 ret = _set_sample_format(device_id, format);
907 return _convert_sound_manager_error_code(__func__, ret);
910 int sound_manager_get_sample_format(sound_device_h device, sound_sample_format_e *format)
912 int ret = MM_ERROR_NONE;
915 SM_INSTANCE_CHECK(device);
916 SM_NULL_ARG_CHECK(format);
918 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
921 if (!(ret = mm_sound_get_device_id(device, &device_id)))
922 ret = _get_sample_format(device_id, format);
924 return _convert_sound_manager_error_code(__func__, ret);
927 int sound_manager_get_supported_sample_rates(sound_device_h device, sound_sample_rate_e **rates, unsigned int *num_of_elems)
929 int ret = MM_ERROR_NONE;
932 SM_INSTANCE_CHECK(device);
933 SM_NULL_ARG_CHECK(rates);
934 SM_NULL_ARG_CHECK(num_of_elems);
936 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
939 if (!(ret = mm_sound_get_device_id(device, &device_id)))
940 ret = _get_supported_sample_rates(device_id, rates, num_of_elems);
942 return _convert_sound_manager_error_code(__func__, ret);
945 int sound_manager_set_sample_rate(sound_device_h device, sound_sample_rate_e rate)
947 int ret = MM_ERROR_NONE;
950 SM_INSTANCE_CHECK(device);
952 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
955 if (!(ret = mm_sound_get_device_id(device, &device_id)))
956 ret = _set_sample_rate(device_id, rate);
958 return _convert_sound_manager_error_code(__func__, ret);
961 int sound_manager_get_sample_rate(sound_device_h device, sound_sample_rate_e *rate)
963 int ret = MM_ERROR_NONE;
966 SM_INSTANCE_CHECK(device);
967 SM_NULL_ARG_CHECK(rate);
969 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
972 if (!(ret = mm_sound_get_device_id(device, &device_id)))
973 ret = _get_sample_rate(device_id, rate);
975 return _convert_sound_manager_error_code(__func__, ret);
978 int sound_manager_set_avoid_resampling(sound_device_h device, bool enable)
980 int ret = MM_ERROR_NONE;
983 SM_INSTANCE_CHECK(device);
985 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
988 if (!(ret = mm_sound_get_device_id(device, &device_id)))
989 ret = _set_avoid_resampling(device_id, enable);
991 return _convert_sound_manager_error_code(__func__, ret);
994 int sound_manager_get_avoid_resampling(sound_device_h device, bool *enabled)
996 int ret = MM_ERROR_NONE;
999 SM_INSTANCE_CHECK(device);
1000 SM_NULL_ARG_CHECK(enabled);
1002 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
1005 if (!(ret = mm_sound_get_device_id(device, &device_id)))
1006 ret = _get_avoid_resampling(device_id, enabled);
1008 return _convert_sound_manager_error_code(__func__, ret);
1011 int sound_manager_set_media_stream_only(sound_device_h device, bool enable)
1013 int ret = MM_ERROR_NONE;
1016 SM_INSTANCE_CHECK(device);
1018 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
1021 if (!(ret = mm_sound_get_device_id(device, &device_id)))
1022 ret = _set_media_stream_only(device_id, enable);
1024 return _convert_sound_manager_error_code(__func__, ret);
1027 int sound_manager_get_media_stream_only(sound_device_h device, bool *enabled)
1029 int ret = MM_ERROR_NONE;
1032 SM_INSTANCE_CHECK(device);
1033 SM_NULL_ARG_CHECK(enabled);
1035 if ((ret = _return_val_if_not_usb_device(device, SOUND_MANAGER_ERROR_INVALID_OPERATION)))
1038 if (!(ret = mm_sound_get_device_id(device, &device_id)))
1039 ret = _get_media_stream_only(device_id, enabled);
1041 return _convert_sound_manager_error_code(__func__, ret);
1044 int sound_manager_add_device_connection_changed_cb(int device_mask, sound_device_connection_changed_cb callback, void *user_data, int *id)
1046 int ret = MM_ERROR_NONE;
1048 SM_NULL_ARG_CHECK(callback);
1049 SM_NULL_ARG_CHECK(id);
1051 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);
1053 return _convert_sound_manager_error_code(__func__, ret);
1056 int sound_manager_remove_device_connection_changed_cb(int id)
1058 int ret = MM_ERROR_NONE;
1061 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1063 ret = mm_sound_remove_device_connected_callback((unsigned int)id);
1065 return _convert_sound_manager_error_code(__func__, ret);
1068 int sound_manager_add_device_running_changed_cb(int device_mask, sound_device_running_changed_cb callback, void *user_data, int *id)
1070 int ret = MM_ERROR_NONE;
1072 SM_NULL_ARG_CHECK(callback);
1073 SM_NULL_ARG_CHECK(id);
1075 ret = mm_sound_add_device_running_changed_callback(device_mask, (mm_sound_device_running_changed_cb)callback, user_data, (unsigned int*)id);
1077 return _convert_sound_manager_error_code(__func__, ret);
1080 int sound_manager_remove_device_running_changed_cb(int id)
1082 int ret = MM_ERROR_NONE;
1085 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1087 ret = mm_sound_remove_device_running_changed_callback((unsigned int)id);
1089 return _convert_sound_manager_error_code(__func__, ret);
1092 int sound_manager_add_device_state_changed_cb(int device_mask, sound_device_state_changed_cb callback, void *user_data, int *id)
1094 int ret = MM_ERROR_NONE;
1096 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1097 SM_NULL_ARG_CHECK(callback);
1098 SM_NULL_ARG_CHECK(id);
1100 ret = mm_sound_add_device_state_changed_callback(device_mask, (mm_sound_device_state_changed_cb)callback, user_data, (unsigned int*)id);
1102 return _convert_sound_manager_error_code(__func__, ret);
1105 int sound_manager_remove_device_state_changed_cb(int id)
1107 int ret = MM_ERROR_NONE;
1109 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
1111 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
1113 ret = mm_sound_remove_device_state_changed_callback((unsigned int)id);
1115 return _convert_sound_manager_error_code(__func__, ret);