4 * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Sangchul Lee <sc11.lee@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include "include/mm_sound.h"
28 #include "include/mm_sound_client.h"
30 #define RETURN_ERROR_IF_FOCUS_CB_THREAD(x_thread) \
32 int ret = MM_ERROR_NONE; \
33 bool result = false; \
34 ret = mm_sound_client_is_focus_cb_thread(x_thread, &result); \
38 debug_error("it might be called in the thread of focus callback, it is not allowed\n"); \
39 return MM_ERROR_SOUND_INVALID_OPERATION; \
44 int mm_sound_focus_set_session_interrupt_callback(mm_sound_focus_session_interrupt_cb callback, void *user_data)
46 int ret = MM_ERROR_NONE;
49 RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
52 return MM_ERROR_INVALID_ARGUMENT;
54 ret = mm_sound_client_set_session_interrupt_callback (callback, user_data);
62 int mm_sound_focus_unset_session_interrupt_callback(void)
64 int ret = MM_ERROR_NONE;
67 RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
69 ret = mm_sound_client_unset_session_interrupt_callback ();
71 debug_error("Failed to mm_sound_client_unset_session_interrupt_callback(), ret[0x%x]\n", ret);
80 int mm_sound_focus_get_id(int *id)
82 int ret = MM_ERROR_NONE;
86 RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
88 ret = mm_sound_client_get_unique_id(id);
90 debug_error("Failed to mm_sound_client_get_unique_id(), ret[0x%x]\n", ret);
99 int mm_sound_focus_is_cb_thread(bool *result)
101 int ret = MM_ERROR_NONE;
105 ret = mm_sound_client_is_focus_cb_thread(g_thread_self(), result);
108 debug_msg("it might be called in the thread of focus callback\n");
117 int mm_sound_register_focus(int id, const char *stream_type, mm_sound_focus_changed_cb callback, void *user_data)
119 int ret = MM_ERROR_NONE;
123 RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
125 if (id < 0 || callback == NULL) {
126 debug_error("argument is not valid\n");
127 return MM_ERROR_INVALID_ARGUMENT;
130 ret = mm_sound_client_register_focus(id, getpid(), stream_type, callback, false, user_data);
132 debug_error("Could not register focus, ret[0x%x]\n", ret);
141 int mm_sound_register_focus_for_session(int id, int pid, const char *stream_type, mm_sound_focus_changed_cb callback, void *user_data)
143 int ret = MM_ERROR_NONE;
147 RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
149 if (id < 0 || callback == NULL) {
150 debug_error("argument is not valid\n");
151 return MM_ERROR_INVALID_ARGUMENT;
154 ret = mm_sound_client_register_focus(id, pid, stream_type, callback, true, user_data);
156 debug_error("Could not register focus for session, ret[0x%x]\n", ret);
165 int mm_sound_unregister_focus(int id)
167 int ret = MM_ERROR_NONE;
173 debug_error("argument is not valid\n");
174 return MM_ERROR_INVALID_ARGUMENT;
177 mm_sound_client_is_focus_cb_thread(g_thread_self(), &result);
179 if ((ret = mm_sound_client_unregister_focus(id)))
180 debug_error("Could not unregister focus, ret = %x\n", ret);
182 ret = mm_sound_client_execute_focus_func_in_main_context(IDLE_EVENT_TYPE_UNREGISTER_FOCUS, id);
191 int mm_sound_set_focus_reacquisition(int id, bool reacquisition)
193 int ret = MM_ERROR_NONE;
198 debug_error("argument is not valid\n");
199 return MM_ERROR_INVALID_ARGUMENT;
202 if ((ret = mm_sound_client_set_focus_reacquisition(id, reacquisition, false)))
203 debug_error("Could not set focus reacquisition, ret[0x%x]\n", ret);
211 int mm_sound_set_focus_reacquisition_for_session(int id, bool reacquisition)
213 int ret = MM_ERROR_NONE;
218 debug_error("argument is not valid\n");
219 return MM_ERROR_INVALID_ARGUMENT;
222 if ((ret = mm_sound_client_set_focus_reacquisition(id, reacquisition, true)))
223 debug_error("Could not set focus reacquisition, ret[0x%x]\n", ret);
231 int mm_sound_get_focus_reacquisition(int id, bool *reacquisition)
233 int ret = MM_ERROR_NONE;
237 if (id < 0 || !reacquisition) {
238 debug_error("argument is not valid\n");
239 return MM_ERROR_INVALID_ARGUMENT;
242 ret = mm_sound_client_get_focus_reacquisition(id, reacquisition);
244 debug_error("Could not get focus reacquisition, ret[0x%x]\n", ret);
253 int mm_sound_get_stream_type_of_acquired_focus(int focus_type, char **stream_type, int *option, char **ext_info)
255 int ret = MM_ERROR_NONE;
259 if (stream_type == NULL) {
260 debug_error("argument is not valid\n");
261 return MM_ERROR_INVALID_ARGUMENT;
264 ret = mm_sound_client_get_acquired_focus_stream_type(focus_type, stream_type, option, ext_info);
266 debug_error("Could not get acquired focus stream type, ret[0x%x]\n", ret);
275 int mm_sound_acquire_focus(int id, mm_sound_focus_type_e focus_type, const char *ext_info)
277 int ret = MM_ERROR_NONE;
281 RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
284 debug_error("argument is not valid\n");
285 return MM_ERROR_INVALID_ARGUMENT;
287 if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
288 debug_error("argument is not valid\n");
289 return MM_ERROR_INVALID_ARGUMENT;
292 ret = mm_sound_client_acquire_focus(id, focus_type, 0, ext_info);
294 debug_error("Could not acquire focus, ret[0x%x]\n", ret);
303 int mm_sound_release_focus(int id, mm_sound_focus_type_e focus_type, const char *ext_info)
305 int ret = MM_ERROR_NONE;
309 RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
312 debug_error("argument is not valid\n");
313 return MM_ERROR_INVALID_ARGUMENT;
315 if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
316 debug_error("argument is not valid\n");
317 return MM_ERROR_INVALID_ARGUMENT;
320 ret = mm_sound_client_release_focus(id, focus_type, 0, ext_info);
322 debug_error("Could not release focus, ret[0x%x]\n", ret);
331 int mm_sound_acquire_focus_with_option(int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info)
333 int ret = MM_ERROR_NONE;
337 RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
340 debug_error("id is not valid\n");
341 return MM_ERROR_INVALID_ARGUMENT;
345 debug_error("option is not valid\n");
346 return MM_ERROR_INVALID_ARGUMENT;
349 if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
350 debug_error("focus type is not valid\n");
351 return MM_ERROR_INVALID_ARGUMENT;
354 ret = mm_sound_client_acquire_focus(id, focus_type, option, ext_info);
356 debug_error("Could not acquire focus, ret[0x%x]\n", ret);
365 int mm_sound_release_focus_with_option(int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info)
367 int ret = MM_ERROR_NONE;
371 RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
374 debug_error("id is not valid\n");
375 return MM_ERROR_INVALID_ARGUMENT;
379 debug_error("option is not valid\n");
380 return MM_ERROR_INVALID_ARGUMENT;
383 if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
384 debug_error("focus type is not valid\n");
385 return MM_ERROR_INVALID_ARGUMENT;
388 ret = mm_sound_client_release_focus(id, focus_type, option, ext_info);
390 debug_error("Could not release focus, ret[0x%x]\n", ret);
399 int mm_sound_update_focus_status(int id, unsigned int status)
401 int ret = MM_ERROR_NONE;
403 if ((ret = mm_sound_client_update_stream_focus_status(id, status)))
404 debug_error("failed to mm_sound_client_update_stream_focus_status(), id(%d), status(%d, ret[0x%x]\n",
411 int mm_sound_set_focus_watch_callback(mm_sound_focus_type_e focus_type, mm_sound_focus_changed_watch_cb callback, void *user_data, int *id)
413 int ret = MM_ERROR_NONE;
417 RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
419 if (callback == NULL || id == NULL) {
420 debug_error("argument is not valid\n");
421 return MM_ERROR_INVALID_ARGUMENT;
423 ret = mm_sound_client_set_focus_watch_callback(getpid(), focus_type, callback, false, user_data, id);
425 debug_error("Could not set focus watch callback, ret[0x%x]\n", ret);
434 int mm_sound_set_focus_watch_callback_for_session(int pid, mm_sound_focus_type_e focus_type, mm_sound_focus_changed_watch_cb callback, void *user_data, int *id)
436 int ret = MM_ERROR_NONE;
440 RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
442 if (callback == NULL || id == NULL) {
443 debug_error("argument is not valid\n");
444 return MM_ERROR_INVALID_ARGUMENT;
446 ret = mm_sound_client_set_focus_watch_callback(pid, focus_type, callback, true, user_data, id);
448 debug_error("Could not set focus watch callback, ret[0x%x]\n", ret);
457 int mm_sound_unset_focus_watch_callback(int id)
459 int ret = MM_ERROR_NONE;
465 debug_error("argument is not valid\n");
466 return MM_ERROR_INVALID_ARGUMENT;
469 mm_sound_client_is_focus_cb_thread(g_thread_self(), &result);
471 if ((ret = mm_sound_client_unset_focus_watch_callback(id)))
472 debug_error("Could not unset focus watch callback, id(%d), ret[0x%x]\n", id, ret);
474 ret = mm_sound_client_execute_focus_func_in_main_context(IDLE_EVENT_TYPE_UNSET_FOCUS_WATCH_CB, id);