#include "backends/base.h"
#include <pulse/pulseaudio.h>
-#ifdef __TIZEN__
-#include <unistd.h>
-#include <mm_session.h>
-#include <mm_sound.h>
-#include <mm_sound_focus.h>
-#include <mm_session_private.h>
-int g_focus_handle_id = 0;
-int g_session_options;
-int g_focus_watch_id = 0;
-ALCboolean g_mute = ALC_FALSE;
-#endif
#if PA_API_VERSION == 12
#ifdef HAVE_DYNLOAD
return stream;
}
-#ifdef __TIZEN__
-static void stream_success_cb(pa_stream *stream, int success, void *userdata)
-{
- ALCpulsePlayback *self = userdata;
- if(!self)
- {
- return;
- }
- TRACE("context_success_cb(stream:%p, success:%d)\n", stream, success);
- ppa_threaded_mainloop_signal(self->loop, 0);
-}
-#endif
static int ALCpulsePlayback_mixerProc(void *ptr)
{
ALCpulsePlayback *self = ptr;
continue;
}
len -= len%update_size;
-#ifdef __TIZEN__
- while(len > 0 && !g_mute)
-#else
while(len > 0)
-#endif
{
size_t newlen = len;
void *buf;
pa_stream_write(self->stream, buf, newlen, free_func, 0, PA_SEEK_RELATIVE);
len -= newlen;
}
-#ifdef __TIZEN__
- {
- pa_operation *o = NULL;
- if(!g_mute && ppa_stream_is_corked(self->stream))
- {
- if(!(o = ppa_stream_cork(self->stream, 0, stream_success_cb, self)))
- TRACE("failed to pa_stream_cork(0), error(%s)\n", ppa_strerror(ppa_context_errno(self->context)));
- }
- else if(g_mute && !ppa_stream_is_corked(self->stream))
- {
- if(!(o = ppa_stream_cork(self->stream, 1, stream_success_cb, self)))
- TRACE("failed to pa_stream_cork(1),error(%s)\n", ppa_strerror(ppa_context_errno(self->context)));
- }
- if(o)
- {
- while(ppa_operation_get_state(o) != PA_OPERATION_DONE)
- ppa_threaded_mainloop_wait(self->loop);
- ppa_operation_unref(o);
- }
- }
-#endif
} while(!self->killNow && device->Connected);
pa_threaded_mainloop_unlock(self->loop);
return 0;
}
-#ifdef __TIZEN__
-static int g_acquired_focus_type;
-static void focus_cb(int index, mm_sound_focus_type_e type, mm_sound_focus_state_e state, const char *reason_for_change, int option, const char *ext_info, void *user_data)
-{
- TRACE("focus_cb is called, index(%d), type(%d), state(%d), reason_for_change(%s), option(%d), ext_info(%s), user_data(%p)\n",
- index, type, state, reason_for_change, option, ext_info, user_data);
- if(g_session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE)
- {
- TRACE("Session uninterruptible\n");
- }
- else
- {
- TRACE("Session interruptible\n");
- if (state == FOCUS_IS_RELEASED)
- {
- g_acquired_focus_type &= ~type;
- if (g_acquired_focus_type != FOCUS_FOR_BOTH)
- g_mute = ALC_TRUE;
- TRACE("focus state is released, g_acquired_focus_type(%d), g_mute(%d)\n", g_acquired_focus_type, g_mute);
- }
- else
- {
- g_acquired_focus_type |= type;
- if (g_acquired_focus_type == FOCUS_FOR_BOTH)
- g_mute = ALC_FALSE;
- TRACE("focus state is acquired, g_acquired_focus_type(%d), g_mute(%d)\n", g_acquired_focus_type, g_mute);
- }
- }
-}
-
-static void focus_watch_cb(int index, mm_sound_focus_type_e type, mm_sound_focus_state_e state, const char *reason_for_change, const char *ext_info, void *user_data)
-{
- TRACE("focus_watch_cb is called, index(%d), type(%d), state(%d), reason_for_change(%s), ext_info(%s), user_data(%p)\n",
- index, type, state, reason_for_change, ext_info, user_data);
- if(g_session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE)
- {
- TRACE("Session uninterruptible\n");
- }
- else
- {
- TRACE("Session interruptible\n");
- if (state == FOCUS_IS_RELEASED)
- {
- g_acquired_focus_type &= ~type;
- if (g_acquired_focus_type == FOCUS_NONE)
- g_mute = ALC_FALSE;
- TRACE("focus state is released, g_acquired_focus_type(%d), g_mute(%d)\n", g_acquired_focus_type, g_mute);
- }
- else
- {
- g_acquired_focus_type |= type;
- if (g_acquired_focus_type != FOCUS_NONE)
- g_mute = ALC_TRUE;
- TRACE("focus state is acquired, g_acquired_focus_type(%d), g_mute(%d)\n", g_acquired_focus_type, g_mute);
- }
- }
-}
-
-static int focus_register(void)
-{
- int ret = MM_ERROR_NONE;
- int session_type = 0;
-
- /* read session information */
- ret = _mm_session_util_read_information(-1, &session_type, &g_session_options);
-
- if(ret == (int)MM_ERROR_INVALID_HANDLE)
- {
- TRACE(" No session presnt, Registering focus_watch_cb() function \n");
- /* case 1. if there is no session */
- ret = mm_sound_set_focus_watch_callback_for_session(getpid(), FOCUS_FOR_BOTH, focus_watch_cb, NULL, &g_focus_watch_id);
- if(ret!= MM_ERROR_NONE)
- {
- ERR("failed to mm_sound_set_focus_watch_callback(), ret[0x%x]\n", ret);
- return -1;
- }
- }
- else if(ret == MM_ERROR_NONE)
- {
- /* case 2. if session exists */
- if(session_type == MM_SESSION_TYPE_REPLACED_BY_STREAM)
- {
- /* in this case, this process is using stream info created by using sound-manager,
- * we're going to skip working on backward compatibility of session. */
- TRACE(" this process is using stream info created by using sound-manager \n");
- }
- else
- {
- if((session_type == MM_SESSION_TYPE_MEDIA) || (session_type == MM_SESSION_TYPE_MEDIA_RECORD))
- {
- if(g_session_options == 0)
- {
- ret = mm_sound_set_focus_watch_callback_for_session(getpid(), FOCUS_FOR_BOTH, focus_watch_cb, NULL, &g_focus_watch_id);
- TRACE(" mm_sound_set_focus_watch_callback_for_session ret value is %x \n", ret);
- if(ret!= MM_ERROR_NONE)
- {
- ERR("failed to mm_sound_set_focus_watch_callback(), ret[0x%x]\n", ret);
- return -1;
- }
- }
- else if(g_session_options & MM_SESSION_OPTION_PAUSE_OTHERS)
- {
- /* get unique id */
- ret = mm_sound_focus_get_id(&g_focus_handle_id);
- if(ret != MM_ERROR_NONE)
- {
- ERR("failed to get unique focus id\n");
- return -1;
- }
- /* register sound focus callback */
- ret = mm_sound_register_focus_for_session(g_focus_handle_id, getpid(), "media", focus_cb, NULL);
- if(ret != MM_ERROR_NONE)
- {
- ERR("mm_sound_register_focus is failed\n");
- return -1;
- }
- }
- else if(g_session_options & MM_SESSION_OPTION_UNINTERRUPTIBLE)
- {
- /* do nothing */
- TRACE("session option is UNINTERRUPTIBLE, nothing to do with focus \n");
- }
- else
- {
- ERR("Unexpected Session Type %d \n", g_session_options);
- return -1;
- }
- }
- }
- }
- else
- {
- ERR("failed at _mm_session_util_read_information(k(), ret[0x%x]\n", ret);
- return -1;
- }
- return 0;
-}
-
-static void focus_unregister(void)
-{
- int ret = MM_ERROR_NONE;
- g_acquired_focus_type = FOCUS_NONE;
- if(g_focus_handle_id > 0)
- {
- ret = mm_sound_unregister_focus(g_focus_handle_id);
- if(ret != MM_ERROR_NONE)
- {
- ERR("failed to mm_sound_unregister_focus() %d\n", g_focus_handle_id);
- g_focus_handle_id = 0;
- }
- }
-
- if(g_focus_watch_id > 0)
- {
- ret = mm_sound_unset_focus_watch_callback(g_focus_watch_id);
- if(ret != MM_ERROR_NONE)
- {
- ERR("failed to mm_sound_unset_focus_watch_callback() %d \n", g_focus_watch_id);
- g_focus_watch_id = 0;
- }
- }
-}
-static ALboolean check_need_block(const char *focus_acquired_by)
-{
- if (!focus_acquired_by)
- return AL_FALSE;
-
- if (!strcmp(focus_acquired_by, "alarm") ||
- !strcmp(focus_acquired_by, "ringtone-voip") ||
- !strcmp(focus_acquired_by, "ringtone-call") ||
- !strcmp(focus_acquired_by, "voip") ||
- !strcmp(focus_acquired_by, "call-voice") ||
- !strcmp(focus_acquired_by, "call-video"))
- {
- TRACE("Blocked by session policy, focus_acquired_by[%s]", focus_acquired_by);
- return AL_TRUE;
- }
-
- return AL_FALSE;
-}
-#endif
static ALCenum ALCpulsePlayback_open(ALCpulsePlayback *self, const ALCchar *name)
{
const_al_string dev_name = AL_STRING_INIT_STATIC();
const char *pulse_name = NULL;
pa_stream_flags_t flags;
pa_sample_spec spec;
-#ifdef __TIZEN__
- int ret = 0;
-#endif
if(name)
{
const DevMap *iter;
if(!pulse_open(&self->loop, &self->context, ALCpulsePlayback_contextStateCallback, self))
return ALC_INVALID_VALUE;
-
-#ifdef __TIZEN__
- ret = focus_register();
- if(ret < 0 )
- {
- ERR("focus_register is failed(), ret value is %d \n", ret);
- return ALC_FALSE;
- }
-#endif
pa_threaded_mainloop_lock(self->loop);
flags = PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE |
spec.format = PA_SAMPLE_S16NE;
spec.rate = 44100;
spec.channels = 2;
-#ifdef __TIZEN__
- if(g_focus_handle_id > 0)
- {
- TRACE("calling mm_sound_acquire_focus \n");
- ret = mm_sound_acquire_focus(g_focus_handle_id, FOCUS_FOR_BOTH, "openAL");
- if(ret)
- {
- ERR("failed to mm_sound_acquire_focus(), ret[0x%x]\n", ret);
- focus_unregister();
- pa_threaded_mainloop_unlock(self->loop);
- return ALC_FALSE;
- }
- g_acquired_focus_type = FOCUS_FOR_BOTH;
- }
- if (g_focus_watch_id > 0)
- {
- char *stream_type = NULL;
- char *ext_info = NULL;
- int option = 0;
-
- ret = mm_sound_get_stream_type_of_acquired_focus(FOCUS_FOR_BOTH, &stream_type, &option, &ext_info);
- if (ret == MM_ERROR_NONE)
- {
- TRACE("Focus is acquired by stream_type[%s], option[%d], ext_info[%s]", stream_type, option, ext_info);
- if (check_need_block((const char*)stream_type))
- {
- TRACE("Blocked by an acquired focus[%s]", stream_type);
- free(ext_info);
- free(stream_type);
- pa_threaded_mainloop_unlock(self->loop);
- return ALC_FALSE;
- }
- free(stream_type);
- free(ext_info);
- }
- }
-#endif
TRACE("Connecting to \"%s\"\n", pulse_name ? pulse_name : "(default)");
#ifdef __TIZEN__
ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
static void ALCpulsePlayback_close(ALCpulsePlayback *self)
{
-#ifdef __TIZEN__
- if(g_focus_handle_id > 0)
- {
- TRACE("calling release \n");
- mm_sound_release_focus(g_focus_handle_id, FOCUS_FOR_BOTH, "openAL");
- }
- focus_unregister();
- g_mute = ALC_FALSE;
-#endif
pulse_close(self->loop, self->context, self->stream);
self->loop = NULL;
self->context = NULL;