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), index(%u), user_cb(%p), ret(0x%x)", stream_h, stream_h->index, stream_h->user_cb, ret);
144 SM_SAFE_FREE(stream_h);
146 return _convert_sound_manager_error_code(__func__, ret);
149 int sound_manager_destroy_stream_information(sound_stream_info_h stream_info)
151 int ret = MM_ERROR_NONE;
152 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
156 SM_INSTANCE_CHECK(stream_h);
158 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
159 ret = _destroy_pa_connection_and_unregister_focus(stream_h);
160 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
161 if (ret == MM_ERROR_NONE) {
162 SM_SAFE_FREE(stream_h);
165 return _convert_sound_manager_error_code(__func__, ret);
168 int sound_manager_get_sound_type(sound_stream_info_h stream_info, sound_type_e *sound_type)
170 int ret = MM_ERROR_NONE;
171 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
175 SM_INSTANCE_CHECK(stream_h);
176 SM_NULL_ARG_CHECK(sound_type);
178 if (stream_h->stream_conf_info.volume_type == NULL) {
179 ret = MM_ERROR_SOUND_NO_DATA;
183 ret = _convert_sound_type_to_enum(stream_h->stream_conf_info.volume_type, sound_type);
184 LOGI("sound type(%d)", *sound_type);
187 return _convert_sound_manager_error_code(__func__, ret);
190 int sound_manager_add_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
192 int ret = MM_ERROR_NONE;
193 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
197 ret = _add_device_for_stream_routing(stream_h, device);
199 return _convert_sound_manager_error_code(__func__, ret);
202 int sound_manager_remove_device_for_stream_routing(sound_stream_info_h stream_info, sound_device_h device)
204 int ret = MM_ERROR_NONE;
205 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
209 ret = _remove_device_for_stream_routing(stream_h, device);
211 return _convert_sound_manager_error_code(__func__, ret);
214 int sound_manager_remove_all_devices_for_stream_routing(sound_stream_info_h stream_info)
216 int ret = MM_ERROR_NONE;
217 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
221 ret = _remove_all_devices_for_stream_routing(stream_h);
223 return _convert_sound_manager_error_code(__func__, ret);
226 int sound_manager_apply_stream_routing(sound_stream_info_h stream_info)
228 int ret = MM_ERROR_NONE;
229 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
233 ret = _apply_stream_routing(stream_h);
235 return _convert_sound_manager_error_code(__func__, ret);
238 int sound_manager_set_focus_reacquisition(sound_stream_info_h stream_info, bool enable)
240 int ret = MM_ERROR_NONE;
241 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
245 SM_INSTANCE_CHECK(stream_h);
247 ret = mm_sound_set_focus_reacquisition(stream_h->index, enable);
249 LOGI("enable(%d)", enable);
251 return _convert_sound_manager_error_code(__func__, ret);
254 int sound_manager_get_focus_reacquisition(sound_stream_info_h stream_info, bool *enabled)
256 int ret = MM_ERROR_NONE;
257 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
261 SM_INSTANCE_CHECK(stream_h);
262 SM_NULL_ARG_CHECK(enabled);
264 ret = mm_sound_get_focus_reacquisition(stream_h->index, enabled);
266 LOGI("enabled(%d)", *enabled);
268 return _convert_sound_manager_error_code(__func__, ret);
271 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)
273 int ret = MM_ERROR_NONE;
274 bool is_focus_cb_thread = false;
275 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
279 SM_INSTANCE_CHECK(stream_h);
281 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
282 return _convert_sound_manager_error_code(__func__, ret);
284 if (stream_h->is_focus_unavailable) {
285 LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
286 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
289 if (stream_h->user_cb == NULL) {
290 LOGE("focus state changed callback should be set before acquiring focus");
291 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
294 if (!is_focus_cb_thread) {
295 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
296 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
298 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
301 if (stream_h->acquired_focus & focus_mask) {
302 LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
303 ret = MM_ERROR_SOUND_INVALID_STATE;
307 if (is_focus_cb_thread && ((stream_h->prev_acquired_focus & ~stream_h->acquired_focus) & focus_mask)) {
308 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]",
309 focus_mask, stream_h->acquired_focus, stream_h->prev_acquired_focus);
310 ret = MM_ERROR_POLICY_INTERNAL;
314 ret = mm_sound_acquire_focus_with_option(stream_h->index, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
315 if (ret == MM_ERROR_NONE) {
316 stream_h->acquired_focus |= focus_mask;
317 stream_h->prev_acquired_focus |= focus_mask;
318 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
321 LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
324 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
325 if (!is_focus_cb_thread)
326 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
328 return _convert_sound_manager_error_code(__func__, ret);
331 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)
333 int ret = MM_ERROR_NONE;
334 bool is_focus_cb_thread = false;
335 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
339 SM_INSTANCE_CHECK(stream_h);
341 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
342 return _convert_sound_manager_error_code(__func__, ret);
344 if (!is_focus_cb_thread) {
345 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
346 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
348 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
351 if (!(stream_h->acquired_focus & focus_mask)) {
352 LOGE("invalid state: focus_mask[0x%x], acquired_focus[0x%x]", focus_mask, stream_h->acquired_focus);
353 ret = MM_ERROR_SOUND_INVALID_STATE;
357 if (is_focus_cb_thread && ((stream_h->prev_acquired_focus & stream_h->acquired_focus) != focus_mask)) {
358 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]",
359 focus_mask, stream_h->acquired_focus, stream_h->prev_acquired_focus);
360 ret = MM_ERROR_SOUND_INVALID_STATE;
364 ret = mm_sound_release_focus_with_option(stream_h->index, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
365 if (ret == MM_ERROR_NONE) {
366 stream_h->acquired_focus &= ~focus_mask;
367 stream_h->prev_acquired_focus &= ~focus_mask;
368 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
371 LOGI("acquired_focus[0x%x], prev[0x%x]", stream_h->acquired_focus, stream_h->prev_acquired_focus);
374 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
375 if (!is_focus_cb_thread)
376 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
378 return _convert_sound_manager_error_code(__func__, ret);
381 int sound_manager_acquire_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
383 int ret = MM_ERROR_NONE;
384 int focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH;
385 bool is_focus_cb_thread = false;
386 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
390 SM_INSTANCE_CHECK(stream_h);
392 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
393 return _convert_sound_manager_error_code(__func__, ret);
395 if (stream_h->is_focus_unavailable) {
396 LOGE("acquiring focus is not allowed for this stream type(%s)", stream_h->stream_type);
397 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
400 if (stream_h->user_cb == NULL) {
401 LOGE("focus state changed callback should be set before acquiring focus");
402 return _convert_sound_manager_error_code(__func__, MM_ERROR_POLICY_INTERNAL);
405 if (!is_focus_cb_thread) {
406 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
407 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
409 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
412 if (is_focus_cb_thread && (stream_h->prev_acquired_focus > stream_h->acquired_focus)) {
413 LOGE("just lost focus in this callback, it is not allowed to acquire all again. acquired_focus[0x%x], prev[0x%x]",
414 stream_h->acquired_focus, stream_h->prev_acquired_focus);
415 ret = MM_ERROR_POLICY_INTERNAL;
419 focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH & ~(stream_h->acquired_focus);
421 LOGI("PLAYBACK/RECORDING focuses have already been ACQUIRED");
426 ret = mm_sound_acquire_focus_with_option(stream_h->index, (mm_sound_focus_type_e)focus_mask, sound_behavior, extra_info);
427 if (ret == MM_ERROR_NONE) {
428 stream_h->acquired_focus |= focus_mask;
429 stream_h->prev_acquired_focus |= focus_mask;
430 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
434 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
435 if (!is_focus_cb_thread)
436 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
438 return _convert_sound_manager_error_code(__func__, ret);
441 int sound_manager_release_focus_all(sound_stream_info_h stream_info, int sound_behavior, const char *extra_info)
443 int ret = MM_ERROR_NONE;
444 bool is_focus_cb_thread = false;
445 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
449 SM_INSTANCE_CHECK(stream_h);
451 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
452 return _convert_sound_manager_error_code(__func__, ret);
454 if (!is_focus_cb_thread) {
455 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
456 SM_ENTER_CRITICAL_SECTION_WITH_UNLOCK_AND_RETURN(&stream_h->focus_state_mutex, &stream_h->focus_cb_mutex, MM_ERROR_SOUND_INTERNAL);
458 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
461 if (is_focus_cb_thread && (stream_h->prev_acquired_focus < stream_h->acquired_focus)) {
462 LOGE("just acquired focus in this callback, it is not allowed to release all again. acquired_focus[0x%x], prev[0x%x]",
463 stream_h->acquired_focus, stream_h->prev_acquired_focus);
464 ret = MM_ERROR_POLICY_INTERNAL;
468 if (!stream_h->acquired_focus) {
469 LOGI("PLAYBACK/RECORDING focuses have already been RELEASED");
474 ret = mm_sound_release_focus_with_option(stream_h->index, (mm_sound_focus_type_e)stream_h->acquired_focus, sound_behavior, extra_info);
475 if (ret == MM_ERROR_NONE) {
476 stream_h->acquired_focus = 0;
477 stream_h->prev_acquired_focus = 0;
478 _update_focus_status(stream_h->index, (unsigned int)stream_h->acquired_focus);
482 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
483 if (!is_focus_cb_thread)
484 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_cb_mutex);
486 return _convert_sound_manager_error_code(__func__, ret);
489 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)
491 int ret = MM_ERROR_NONE;
492 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
496 SM_INSTANCE_CHECK(stream_h);
497 if (!state_for_playback && !state_for_recording)
498 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
500 SM_ENTER_CRITICAL_SECTION_WITH_RETURN(&stream_h->focus_state_mutex, MM_ERROR_SOUND_INTERNAL);
502 if (state_for_playback)
503 *state_for_playback = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_PLAYBACK) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
504 if (state_for_recording)
505 *state_for_recording = ((stream_h->acquired_focus & SOUND_STREAM_FOCUS_FOR_RECORDING) ? (SOUND_STREAM_FOCUS_STATE_ACQUIRED) : (SOUND_STREAM_FOCUS_STATE_RELEASED));
507 LOGI("acquired_focus(0x%x)", stream_h->acquired_focus);
509 SM_LEAVE_CRITICAL_SECTION(&stream_h->focus_state_mutex);
511 return _convert_sound_manager_error_code(__func__, ret);
514 int sound_manager_deliver_focus(sound_stream_info_h source, sound_stream_info_h destination, sound_stream_focus_mask_e focus_mask)
516 int ret = MM_ERROR_NONE;
517 sound_stream_info_s *src_stream_h = (sound_stream_info_s*)source;
518 sound_stream_info_s *dst_stream_h = (sound_stream_info_s*)destination;
519 bool is_focus_cb_thread = false;
523 SM_INSTANCE_CHECK(src_stream_h);
524 SM_INSTANCE_CHECK(dst_stream_h);
526 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
527 return _convert_sound_manager_error_code(__func__, ret);
529 if (is_focus_cb_thread) {
530 LOGE("not allowed calling this function in focus(watch) callback");
531 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
534 if (src_stream_h->index == dst_stream_h->index) {
535 LOGE("not allowed because both handles have same index(%u)", src_stream_h->index);
536 return SOUND_MANAGER_ERROR_INVALID_PARAMETER;
539 if (src_stream_h->is_focus_unavailable || dst_stream_h->is_focus_unavailable) {
540 LOGE("focus is unavailable for source(%d)/destination(%d)",
541 src_stream_h->is_focus_unavailable, dst_stream_h->is_focus_unavailable);
542 return SOUND_MANAGER_ERROR_POLICY;
545 if (!(src_stream_h->acquired_focus & focus_mask) || (src_stream_h->acquired_focus < focus_mask)) {
546 LOGE("could not deliver the request focus(0x%x), current acquired focus(0x%x)",
547 focus_mask, src_stream_h->acquired_focus);
548 return SOUND_MANAGER_ERROR_INVALID_STATE;
551 if (dst_stream_h->user_cb == NULL) {
552 LOGE("focus state changed callback should be set to destination handle");
553 return SOUND_MANAGER_ERROR_POLICY;
556 ret = mm_sound_deliver_focus(src_stream_h->index, dst_stream_h->index, (mm_sound_focus_type_e)focus_mask);
557 if (ret == MM_ERROR_NONE) {
558 src_stream_h->acquired_focus &= ~focus_mask;
559 src_stream_h->prev_acquired_focus &= ~focus_mask;
560 dst_stream_h->acquired_focus |= focus_mask;
561 dst_stream_h->prev_acquired_focus |= focus_mask;
564 return _convert_sound_manager_error_code(__func__, ret);
567 int sound_manager_is_stream_on_device(sound_stream_info_h stream_info, sound_device_h device, bool *is_on)
569 int ret = MM_ERROR_NONE;
570 sound_stream_info_s *stream_h = (sound_stream_info_s*)stream_info;
574 SM_NULL_ARG_CHECK(stream_h);
575 SM_NULL_ARG_CHECK(device);
576 SM_NULL_ARG_CHECK(is_on);
578 ret = mm_sound_is_stream_on_device(stream_h->index, device, is_on);
580 return _convert_sound_manager_error_code(__func__, ret);
583 int sound_manager_get_current_media_playback_device_type(sound_device_type_e *device_type)
585 int ret = MM_ERROR_NONE;
589 SM_NULL_ARG_CHECK(device_type);
591 ret = _get_current_media_routing_path("out", device_type);
593 return _convert_sound_manager_error_code(__func__, ret);
596 int sound_manager_get_current_playback_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
598 int ret = MM_ERROR_NONE;
599 char *stream_type_str = NULL;
600 char *extra_info_str = NULL;
602 bool is_focus_cb_thread = false;
606 SM_NULL_ARG_CHECK(acquired_by);
607 SM_NULL_ARG_CHECK(flags);
609 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
610 return _convert_sound_manager_error_code(__func__, ret);
612 if (is_focus_cb_thread) {
613 LOGE("this API should not be called in focus callback");
614 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
617 ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_PLAYBACK, &stream_type_str, &option, &extra_info_str);
618 if (ret == MM_ERROR_NONE) {
619 LOGI("current acquired PLAYBACK focus : stream_type[%s]", stream_type_str);
620 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
621 if (ret == MM_ERROR_NONE) {
622 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
625 *extra_info = extra_info_str;
627 SM_SAFE_FREE(extra_info_str);
629 SM_SAFE_FREE(stream_type_str);
632 return _convert_sound_manager_error_code(__func__, ret);
635 int sound_manager_get_current_recording_focus(sound_stream_focus_change_reason_e *acquired_by, int *flags, char **extra_info)
637 int ret = MM_ERROR_NONE;
638 char *stream_type_str = NULL;
639 char *extra_info_str = NULL;
641 bool is_focus_cb_thread = false;
645 SM_NULL_ARG_CHECK(acquired_by);
646 SM_NULL_ARG_CHECK(flags);
648 if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
649 return _convert_sound_manager_error_code(__func__, ret);
651 if (is_focus_cb_thread) {
652 LOGE("this API should not be called in focus callback");
653 return SOUND_MANAGER_ERROR_INVALID_OPERATION;
656 ret = mm_sound_get_stream_type_of_acquired_focus((int)SOUND_STREAM_FOCUS_FOR_RECORDING, &stream_type_str, &option, &extra_info_str);
657 if (ret == MM_ERROR_NONE) {
658 LOGI("current acquired RECORDING focus : stream_type[%s]", stream_type_str);
659 ret = _convert_stream_type_to_change_reason(stream_type_str, acquired_by);
660 if (ret == MM_ERROR_NONE) {
661 LOGI(" : reason[%d], flags[0x%x], extra_info[%s]", *acquired_by, option, extra_info_str);
664 *extra_info = extra_info_str;
666 SM_SAFE_FREE(extra_info_str);
668 SM_SAFE_FREE(stream_type_str);
671 return _convert_sound_manager_error_code(__func__, ret);
674 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)
676 int ret = MM_ERROR_NONE;
681 SM_NULL_ARG_CHECK(callback);
682 SM_NULL_ARG_CHECK(id);
684 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
685 if (focus_watch_info_arr[i].id == 0)
687 if (i == SOUND_STREAM_INFO_ARR_MAX) {
689 LOGE("focus watch info array is full");
690 ret = MM_ERROR_SOUND_INTERNAL;
695 ret = mm_sound_set_focus_watch_callback((mm_sound_focus_type_e)focus_mask, _focus_watch_callback, &focus_watch_info_arr[i], id);
696 if (ret == MM_ERROR_NONE) {
697 focus_watch_info_arr[i].id = *id;
698 focus_watch_info_arr[i].user_data = user_data;
699 focus_watch_info_arr[i].user_cb = callback;
705 return _convert_sound_manager_error_code(__func__, ret);
708 int sound_manager_remove_focus_state_watch_cb(int id)
710 int ret = MM_ERROR_NONE;
715 for (i = 0; i < SOUND_STREAM_INFO_ARR_MAX; i++)
716 if (focus_watch_info_arr[i].id == id)
718 if (i == SOUND_STREAM_INFO_ARR_MAX) {
719 LOGE("cound not find item in focus watch info array for this id(%d)", id);
720 ret = MM_ERROR_INVALID_ARGUMENT;
724 ret = mm_sound_unset_focus_watch_callback(id);
725 if (ret == MM_ERROR_NONE) {
726 focus_watch_info_arr[i].id = 0;
727 focus_watch_info_arr[i].user_data = NULL;
728 focus_watch_info_arr[i].user_cb = NULL;
732 return _convert_sound_manager_error_code(__func__, ret);
735 int sound_manager_get_device_list(int device_mask, sound_device_list_h *device_list)
737 int ret = MM_ERROR_NONE;
739 ret = mm_sound_get_device_list(device_mask, device_list);
741 return _convert_sound_manager_error_code(__func__, ret);
744 int sound_manager_free_device_list(sound_device_list_h device_list)
746 int ret = MM_ERROR_NONE;
748 ret = mm_sound_free_device_list(device_list);
750 return _convert_sound_manager_error_code(__func__, ret);
753 int sound_manager_get_next_device(sound_device_list_h device_list, sound_device_h *device)
755 int ret = MM_ERROR_NONE;
757 ret = mm_sound_get_next_device(device_list, device);
759 return _convert_sound_manager_error_code(__func__, ret);
762 int sound_manager_get_prev_device(sound_device_list_h device_list, sound_device_h *device)
764 int ret = MM_ERROR_NONE;
766 ret = mm_sound_get_prev_device(device_list, device);
768 return _convert_sound_manager_error_code(__func__, ret);
771 int sound_manager_get_device_type(sound_device_h device, sound_device_type_e *type)
773 int ret = MM_ERROR_NONE;
774 mm_sound_device_type_e mm_sound_device_type;
776 ret = mm_sound_get_device_type(device, &mm_sound_device_type);
777 if (ret == MM_ERROR_NONE)
778 ret = _convert_device_type(mm_sound_device_type, type);
780 return _convert_sound_manager_error_code(__func__, ret);
783 int sound_manager_get_device_io_direction(sound_device_h device, sound_device_io_direction_e *io_direction)
785 int ret = MM_ERROR_NONE;
786 mm_sound_device_io_direction_e mm_sound_io_direction;
788 ret = mm_sound_get_device_io_direction(device, &mm_sound_io_direction);
789 if (ret == MM_ERROR_NONE)
790 ret = _convert_device_io_direction(mm_sound_io_direction, io_direction);
792 return _convert_sound_manager_error_code(__func__, ret);
795 int sound_manager_get_device_id(sound_device_h device, int *id)
797 int ret = MM_ERROR_NONE;
799 ret = mm_sound_get_device_id(device, id);
801 return _convert_sound_manager_error_code(__func__, ret);
804 int sound_manager_get_device_name(sound_device_h device, char **name)
806 int ret = MM_ERROR_NONE;
808 ret = mm_sound_get_device_name(device, name);
810 return _convert_sound_manager_error_code(__func__, ret);
813 int sound_manager_is_device_running(sound_device_h device, bool *is_running)
815 int ret = MM_ERROR_NONE;
819 SM_INSTANCE_CHECK(device);
820 SM_NULL_ARG_CHECK(is_running);
822 ret = mm_sound_is_device_running(device, is_running);
824 return _convert_sound_manager_error_code(__func__, ret);
827 int sound_manager_get_device_state(sound_device_h device, sound_device_state_e *state)
829 int ret = MM_ERROR_NONE;
831 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
832 ret = mm_sound_get_device_state(device, (mm_sound_device_state_e*)state);
834 return _convert_sound_manager_error_code(__func__, ret);
837 int sound_manager_add_device_connection_changed_cb(int device_mask, sound_device_connection_changed_cb callback, void *user_data, int *id)
839 int ret = MM_ERROR_NONE;
841 SM_NULL_ARG_CHECK(callback);
842 SM_NULL_ARG_CHECK(id);
844 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);
846 return _convert_sound_manager_error_code(__func__, ret);
849 int sound_manager_remove_device_connection_changed_cb(int id)
851 int ret = MM_ERROR_NONE;
854 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
856 ret = mm_sound_remove_device_connected_callback((unsigned int)id);
858 return _convert_sound_manager_error_code(__func__, ret);
861 int sound_manager_add_device_running_changed_cb(int device_mask, sound_device_running_changed_cb callback, void *user_data, int *id)
863 int ret = MM_ERROR_NONE;
865 SM_NULL_ARG_CHECK(callback);
866 SM_NULL_ARG_CHECK(id);
868 ret = mm_sound_add_device_running_changed_callback(device_mask, (mm_sound_device_running_changed_cb)callback, user_data, (unsigned int*)id);
870 return _convert_sound_manager_error_code(__func__, ret);
873 int sound_manager_remove_device_running_changed_cb(int id)
875 int ret = MM_ERROR_NONE;
878 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
880 ret = mm_sound_remove_device_running_changed_callback((unsigned int)id);
882 return _convert_sound_manager_error_code(__func__, ret);
885 int sound_manager_add_device_state_changed_cb(int device_mask, sound_device_state_changed_cb callback, void *user_data, int *id)
887 int ret = MM_ERROR_NONE;
889 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
890 SM_NULL_ARG_CHECK(callback);
891 SM_NULL_ARG_CHECK(id);
893 ret = mm_sound_add_device_state_changed_callback(device_mask, (mm_sound_device_state_changed_cb)callback, user_data, (unsigned int*)id);
895 return _convert_sound_manager_error_code(__func__, ret);
898 int sound_manager_remove_device_state_changed_cb(int id)
900 int ret = MM_ERROR_NONE;
902 LOGW("DEPRECATION WARNING: %s() is deprecated and will be removed from next release.", __func__);
904 return _convert_sound_manager_error_code(__func__, MM_ERROR_INVALID_ARGUMENT);
906 ret = mm_sound_remove_device_state_changed_callback((unsigned int)id);
908 return _convert_sound_manager_error_code(__func__, ret);
911 __attribute__ ((destructor))
912 void __sound_manager_finalize(void)
917 __attribute__ ((constructor))
918 void __sound_manager_initialize(void)