summaryrefslogtreecommitdiff
path: root/server/mm_sound_mgr_pulse.c
diff options
context:
space:
mode:
authorSeungbae Shin <seungbae.shin@samsung.com>2012-08-21 17:59:19 +0900
committerSeungbae Shin <seungbae.shin@samsung.com>2012-08-21 20:51:34 +0900
commit4b557013c69aba50fe1197bf556d4c24dc9f96e3 (patch)
tree296377f274d9c20213753ec0710116a18f5745d4 /server/mm_sound_mgr_pulse.c
parent13c42beed719f9c7911c2d82c5c3b6b531a06e55 (diff)
downloadlibmm-sound-4b557013c69aba50fe1197bf556d4c24dc9f96e3.tar.gz
libmm-sound-4b557013c69aba50fe1197bf556d4c24dc9f96e3.tar.bz2
libmm-sound-4b557013c69aba50fe1197bf556d4c24dc9f96e3.zip
2.0 init
Change-Id: I1fccce4dee3e9a772dc8b9b3580296eaad513a77
Diffstat (limited to 'server/mm_sound_mgr_pulse.c')
-rw-r--r--server/mm_sound_mgr_pulse.c689
1 files changed, 244 insertions, 445 deletions
diff --git a/server/mm_sound_mgr_pulse.c b/server/mm_sound_mgr_pulse.c
index d92655a..1fe93c2 100644
--- a/server/mm_sound_mgr_pulse.c
+++ b/server/mm_sound_mgr_pulse.c
@@ -33,178 +33,138 @@
#include <errno.h>
#include "include/mm_sound_mgr_common.h"
-#include "../include/mm_sound_msg.h"
#include "../include/mm_sound_common.h"
#include <mm_error.h>
#include <mm_debug.h>
-#include <audio-session-manager.h>
-#include <avsys-audio.h>
+//#include <audio-session-manager.h>
+//#include <avsys-audio.h>
+#include <pulse/pulseaudio.h>
#include <pulse/ext-policy.h>
#define SUPPORT_MONO_AUDIO
-//#define BT_DISCONNECT_PAUSE
-#include "include/mm_sound_mgr_pulse.h"
+#define SUPPORT_BT_SCO_DETECT
-#define SOUND_MSG_SET(sound_msg, x_msgtype, x_handle, x_code, x_msgid) \
-do { \
- sound_msg.msgtype = x_msgtype; \
- sound_msg.handle = x_handle; \
- sound_msg.code = x_code; \
- sound_msg.msgid = x_msgid; \
-} while(0)
+#include "include/mm_sound_mgr_pulse.h"
+#include "include/mm_sound_mgr_session.h"
-pa_threaded_mainloop *g_m;
-pa_context *g_context;
+#include "include/mm_sound_msg.h"
+#include "include/mm_sound_mgr_ipc.h"
-pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
+#include <vconf.h>
+#include <vconf-keys.h>
-#ifdef BT_DISCONNECT_PAUSE
-int g_asm_handle = -1;
+#define MAX_STRING 64
-bool _asm_register_for_bt ()
+typedef struct _pulse_info
{
- int asm_error = 0;
- if(!ASM_register_sound(-1, &g_asm_handle, ASM_EVENT_EARJACK_UNPLUG, ASM_STATE_NONE, NULL, NULL, ASM_RESOURCE_NONE, &asm_error))
- {
- debug_warning("earjack event register failed with 0x%x\n", asm_error);
- return false;
- }
- return true;
-}
+ pa_threaded_mainloop *m;
+ pa_context *context;
+ char sink_to_find[MAX_STRING];
+ bool init_bt_status;
+}pulse_info_t;
+pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
-int set_audio_route_to_default()
-{
- int ret = MM_ERROR_NONE;
- int codec_option = AVSYS_AUDIO_PATH_OPTION_JACK_AUTO;
+pulse_info_t* pulse_info = NULL;
- debug_msg("Set audio route to default by sound_server pulse mgr\n");
+/* -------------------------------- PULSEAUDIO --------------------------------------------*/
- if(MM_ERROR_NONE != __mm_sound_lock()) {
- debug_error("Lock failed\n");
- return MM_ERROR_SOUND_INTERNAL;
- }
+static void server_info_cb(pa_context *c, const pa_server_info *i, void *userdata)
+{
+ int ret = 0;
- ret = avsys_audio_set_path_ex(AVSYS_AUDIO_GAIN_EX_KEYTONE, AVSYS_AUDIO_PATH_EX_SPK, AVSYS_AUDIO_PATH_EX_NONE, codec_option);
- if(AVSYS_FAIL(ret)) {
- debug_error("Can not set playback sound path 0x%x\n", ret);
- if(MM_ERROR_NONE != __mm_sound_unlock()) {
- debug_error("Unlock failed\n");
- return MM_ERROR_SOUND_INTERNAL;
- }
- return ret;
- }
- ret = avsys_audio_set_path_ex(AVSYS_AUDIO_GAIN_EX_VOICEREC, AVSYS_AUDIO_PATH_EX_NONE, AVSYS_AUDIO_PATH_EX_MIC, codec_option);
- if(AVSYS_FAIL(ret)) {
- debug_error("Can not set capture sound path 0x%x\n", ret);
- if(MM_ERROR_NONE != __mm_sound_unlock()) {
- debug_error("Unlock failed\n");
- return MM_ERROR_SOUND_INTERNAL;
- }
- return ret;
- }
+ if (!i) {
+ debug_error("error in server info callback\n");
- ret = avsys_audio_set_route_policy(AVSYS_AUDIO_ROUTE_POLICY_DEFAULT);
- if(AVSYS_FAIL(ret)) {
- debug_error("Can not set route policy to avsystem 0x%x\n", ret);
- if(MM_ERROR_NONE != __mm_sound_unlock()) {
- debug_error("Unlock failed\n");
- return MM_ERROR_SOUND_INTERNAL;
- }
- return ret;
- }
+ } else {
+ debug_msg ("We got default sink = [%s]\n", i->default_sink_name);
- ret = vconf_set_int(ROUTE_VCONF_KEY, (int)AVSYS_AUDIO_ROUTE_POLICY_DEFAULT);
- if(ret < 0) {
- debug_error("Can not set route policy to vconf %s\n", ROUTE_VCONF_KEY);
- if(MM_ERROR_NONE != __mm_sound_unlock()) {
- debug_error("Unlock failed\n");
- return MM_ERROR_SOUND_INTERNAL;
+ /* ToDo: Update server info */
+ ret = MMSoundMgrSessionSetDefaultSink (i->default_sink_name);
+ if (ret != MM_ERROR_NONE) {
+ /* TODO : Error Handling */
+ debug_error ("MMSoundMgrSessionSetDefaultSink failed....ret = [%x]\n", ret);
}
- return MM_ERROR_SOUND_INTERNAL;
- }
+ }
+}
- if(MM_ERROR_NONE != __mm_sound_unlock()) {
- debug_error("Unlock failed\n");
- return MM_ERROR_SOUND_INTERNAL;
+static void init_card_info_cb (pa_context *c, const pa_card_info *i, int eol, void *userdata)
+{
+ pulse_info_t *pinfo = (pulse_info_t *)userdata;
+ if (eol || i == NULL) {
+ debug_msg ("signaling--------------\n");
+ pa_threaded_mainloop_signal (pinfo->m, 0);
+ return;
}
- return MM_ERROR_NONE;
+ if (strstr (i->name, "bluez")) {
+ pinfo->init_bt_status = true;
+ }
}
-int process_asm_pause ()
+static void card_info_cb (pa_context *c, const pa_card_info *i, int eol, void *userdata)
{
- int asm_error = 0;
-
- // mute is not affecting now
- //if(AVSYS_FAIL(avsys_audio_set_global_mute(AVSYS_AUDIO_MUTE)))
- //debug_error("Set unmute failed\n");
-
- if (g_asm_handle == -1) {
- debug_msg ("ASM handle is not valid, try to register once more\n");
- /* This register should be success */
- if (_asm_register_for_bt ()) {
- debug_msg("_asm_register_for_bt() success\n");
- } else {
- debug_error("_asm_register_for_bt() failed\n");
- }
- }
+ int ret = 0;
+ char* desc = NULL;
- if(!ASM_set_sound_state(g_asm_handle, ASM_EVENT_EARJACK_UNPLUG, ASM_STATE_PLAYING, ASM_RESOURCE_NONE, &asm_error ))
- debug_error("earjack event set sound state to playing failed with 0x%x\n", asm_error);
+ if (eol || i == NULL) {
+ return;
+ }
- if(!ASM_set_sound_state(g_asm_handle, ASM_EVENT_EARJACK_UNPLUG, ASM_STATE_STOP, ASM_RESOURCE_NONE, &asm_error ))
- debug_error("earjack event set sound state to stop failed with 0x%x\n", asm_error);
+ /* Get device name : eg. SBH-600 */
+ desc = pa_proplist_gets(i->proplist, PA_PROP_DEVICE_DESCRIPTION);
+ debug_msg ("[%s][%d] card name is [%s], card.property.device.description = [%s]\n", __func__, __LINE__, i->name, desc);
- //if(AVSYS_FAIL(avsys_audio_set_global_mute(AVSYS_AUDIO_UNMUTE)))
- //debug_error("Set unmute failed\n");
+ /* ToDo: Update Device */
+ ret = MMSoundMgrSessionSetDeviceAvailable (DEVICE_BT_A2DP, AVAILABLE, 0, (desc)? desc : "NONAME");
+ if (ret != MM_ERROR_NONE) {
+ /* TODO : Error Handling */
+ debug_error ("MMSoundMgrSessionSetDeviceAvailable failed....ret = [%x]\n", ret);
+ }
}
-static void
-context_subscribe_cb (pa_context * c,
- pa_subscription_event_type_t t, uint32_t idx, void *userdata)
+static void context_subscribe_cb (pa_context * c, pa_subscription_event_type_t t, uint32_t idx, void *userdata)
{
- debug_msg (">>>>>>>>> [%s][%d] type=(%d) idx=(%u)\n", __func__, __LINE__, t, idx);
-
- /* if event is "sink" index is not 0 (alsa) then bluetooth sink device is load/unloaded */
- /* FIXME : what if alsa index is not 0???? we have check more strictly*/
- if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK && idx != 0) {
- if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { /* unloaded */
- /* Check current policy */
- avsys_audio_route_policy_t cur_policy;
- if (avsys_audio_get_route_policy(&cur_policy) == AVSYS_STATE_SUCCESS) {
- /* We Do pause if policy is default, if not, do nothing */
- if (cur_policy == AVSYS_AUDIO_ROUTE_POLICY_DEFAULT) {
- /* Do pause here */
- debug_msg("Do pause here");
- process_asm_pause();
- } else {
- debug_msg("Policy is not default, Do nothing");
- }
- } else {
- debug_error ("avsys_audio_get_route_policy() failed");
- }
- } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { /* loaded */
- /* Restore audio route policy to default */
- if(MM_ERROR_NONE != set_audio_route_to_default()) {
- debug_error("set_audio_route_to_default() failed\n");
- } else {
- debug_msg("set_audio_route_to_default() done.\n");
+ debug_msg (">>>>>>>>> [%s][%d] type=(0x%x) idx=(%u)\n", __func__, __LINE__, t, idx);
+
+ if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_CARD) {
+ /* FIXME: We assumed that card is bt, card new/remove = bt new/remove */
+
+ if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { /* BT is removed */
+ /* ToDo: Update Device */
+ //MMSoundMgrSessionSetDeviceBT (STATUS_NONE, NULL);
+ MMSoundMgrSessionSetDeviceAvailable (DEVICE_BT_A2DP, NOT_AVAILABLE, 0, NULL);
+
+ } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { /* BT is loaded */
+ /* Get Card info for BT name. Update device after that */
+ pa_operation *o;
+ if (!(o = pa_context_get_card_info_by_index (c, idx, card_info_cb, NULL))) {
+ return;
}
+ pa_operation_unref(o);
+
}
- }
+
+ } else if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SERVER) {
+
+ pa_operation_unref(pa_context_get_server_info(c, server_info_cb, NULL));
+
+
+ } else {
+ debug_msg ("[%s][%d] type=(0x%x) idx=(%u) is not card or server event, skip...\n", __func__, __LINE__, t, idx);
+ return;
+ }
}
-#endif
-void context_state_cb (pa_context *c, void *userdata)
+static void context_state_cb (pa_context *c, void *userdata)
{
- //g_print (">>>>>>>>> [%s][%d]\n", __func__, __LINE__);
+ pulse_info_t *pinfo = (pulse_info_t *)userdata;
switch (pa_context_get_state(c)) {
case PA_CONTEXT_UNCONNECTED:
@@ -217,76 +177,60 @@ void context_state_cb (pa_context *c, void *userdata)
case PA_CONTEXT_READY:
{
- //g_print ("PA_CONTEXT_READY\n");
-
- if (g_context == c) {
-
-#ifdef BT_DISCONNECT_PAUSE
- /* Do SINK Subscribe */
- pa_context_set_subscribe_callback(c, context_subscribe_cb, NULL);
+ if (pinfo->context == c) {
+ /* Do CARD and SERVER Subscribe */
+ pa_context_set_subscribe_callback(c, context_subscribe_cb, pinfo);
pa_operation *o;
- if (!(o = pa_context_subscribe(c, (pa_subscription_mask_t)PA_SUBSCRIPTION_MASK_SINK, NULL, NULL))) {
- //g_print ("pa_context_subscribe() failed\n");
+ if (!(o = pa_context_subscribe(c, (pa_subscription_mask_t)PA_SUBSCRIPTION_MASK_CARD | PA_SUBSCRIPTION_MASK_SERVER, NULL, NULL))) {
return;
}
pa_operation_unref(o);
-#else
- //pa_context_set_subscribe_callback(c, NULL, NULL);
-#endif
- /* Signal */
- debug_msg ("signaling--------------\n");
- pa_threaded_mainloop_signal (g_m, 0);
+ pa_operation_unref(pa_context_get_card_info_list (pinfo->context, init_card_info_cb, pinfo));
+
+ /* signaling will be done after get card info in card info callback */
}
break;
}
}
-
- return;
}
-int pulse_init ()
+static int pulse_init (pulse_info_t * pinfo)
{
int res;
debug_msg (">>>>>>>>> [%s][%d]\n", __func__, __LINE__);
-#ifdef BT_DISCONNECT_PAUSE
- /* Set audio route policy to default when sound server startup */
- if(MM_ERROR_NONE != set_audio_route_to_default())
- {
- debug_error("Set audio route policy to default failed\n");
- }
-#endif
+
/* Create new mainloop */
- g_m = pa_threaded_mainloop_new();
+ pinfo->m = pa_threaded_mainloop_new();
//g_assert(g_m);
- res = pa_threaded_mainloop_start (g_m);
+ res = pa_threaded_mainloop_start (pinfo->m);
//g_assert (res == 0);
/* LOCK thread */
- pa_threaded_mainloop_lock (g_m);
+ pa_threaded_mainloop_lock (pinfo->m);
/* Get mainloop API */
- pa_mainloop_api *api = pa_threaded_mainloop_get_api(g_m);
+ pa_mainloop_api *api = pa_threaded_mainloop_get_api(pinfo->m);
/* Create new Context */
- g_context = pa_context_new(api, "SOUND_SERVER_ROUTE_MANAGER");
+ pinfo->context = pa_context_new(api, "SOUND_SERVER_ROUTE_MANAGER");
/* Set Callback */
- pa_context_set_state_callback (g_context, context_state_cb, NULL);
+ pa_context_set_state_callback (pinfo->context, context_state_cb, pinfo);
/* Connect */
- if (pa_context_connect (g_context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL) < 0) {
+ if (pa_context_connect (pinfo->context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL) < 0) {
debug_error ("connection error\n");
}
for (;;) {
pa_context_state_t state;
- state = pa_context_get_state (g_context);
+ state = pa_context_get_state (pinfo->context);
debug_msg ("context state is now %d\n", state);
@@ -300,371 +244,226 @@ int pulse_init ()
/* Wait until the context is ready */
debug_msg ("waiting..................\n");
- pa_threaded_mainloop_wait (g_m);
+ pa_threaded_mainloop_wait (pinfo->m);
}
/* UNLOCK thread */
- pa_threaded_mainloop_unlock (g_m);
+ pa_threaded_mainloop_unlock (pinfo->m);
debug_msg ("<<<<<<<<<< [%s][%d]\n", __func__, __LINE__);
- return 0;
+ return res;
}
-int pulse_deinit ()
-{
- pa_threaded_mainloop_lock (g_m);
-
- if (g_context) {
- pa_context_disconnect (g_context);
- /* Make sure we don't get any further callbacks */
- pa_context_set_state_callback (g_context, NULL, NULL);
-
- pa_context_unref (g_context);
- g_context = NULL;
- }
- pa_threaded_mainloop_unlock (g_m);
-
- pa_threaded_mainloop_stop (g_m);
- pa_threaded_mainloop_free (g_m);
-
- debug_msg ("<<<<<<<<<< [%s][%d]\n", __func__, __LINE__);
-
- return 0;
-
-}
+static void sink_info_cb (pa_context *c, const pa_sink_info *i, int is_last, void *userdata)
+{
+ pulse_info_t * pinfo = (pulse_info_t *)userdata;
-void get_server_info_callback(pa_context *c, const pa_server_info *i, void *userdata) {
- int ret;
- mm_ipc_msg_t respmsg = {0,};
- server_struct *ss = (server_struct *)userdata;
- if (ss == NULL) {
- debug_error ("Input userdata is NULL\n");
+ if (is_last || i == NULL || pinfo == NULL) {
+ if (is_last < 0) {
+ debug_error("Failed to get sink information: %s\n", pa_strerror(pa_context_errno(c)));
+ }
return;
}
- if (!i) {
- debug_error("Error to MM_SOUND_MSG_REQ_GET_AUDIO_ROUTE.\n");
- SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, 0, ss->msg->sound_msg.msgid);
- } else {
- debug_msg ("We got default sink = [%s]\n", i->default_sink_name);
- SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_GET_AUDIO_ROUTE, ss->msg->sound_msg.handle, 0, ss->msg->sound_msg.msgid);
- if (strstr (i->default_sink_name, "alsa"))
- respmsg.sound_msg.code = 0;
- else if (strstr (i->default_sink_name, "bluez"))
- respmsg.sound_msg.code = 1;
- else
- respmsg.sound_msg.code = 2;
- }
+ if (i->name && i->proplist) {
+ const char *api_string = pa_proplist_gets (i->proplist, "device.api");
+ if (api_string) {
+ debug_log ("sink name = [%s], api = [%s]\n", i->name, api_string);
+ if (strcmp (api_string, pinfo->sink_to_find) == 0) {
+ debug_log ("FOUND!!! set default sink to [%s]\n", i->name);
+ pa_operation_unref(pa_context_set_default_sink(pinfo->context, i->name, NULL, NULL));
- if (ss->func) {
- ret = ss->func (&respmsg);
- if (ret != MM_ERROR_NONE) {
- debug_error ("Fail to send message [%x]\n", ret);
- } else {
- debug_msg("Sent msg to client msgid [%d] [codechandle %d][message type %d] (code 0x%08X)\n",
- ss->msg->sound_msg.msgid, respmsg.sound_msg.handle, respmsg.sound_msg.msgtype, respmsg.sound_msg.code);
+ } else {
+ debug_warning ("No string [%s] match!!!!\n", pinfo->sink_to_find);
+ }
}
- } else {
- debug_error ("No send function\n");
}
+}
- debug_msg("Ready to next msg\n");
- if (ss->msg) {
- debug_msg ("free [%p]\n", ss->msg);
- free (ss->msg);
- ss->msg = NULL;
- }
- if (ss) {
- free (ss);
- ss = NULL;
- }
- pthread_mutex_unlock(&g_mutex);
+static void pulse_set_default_sink (pulse_info_t * pinfo, char *default_sink_name)
+{
+ strcpy (pinfo->sink_to_find, default_sink_name);
+ pa_operation_unref(pa_context_get_sink_info_list(pinfo->context, sink_info_cb, pinfo));
}
-void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_last, void *userdata)
+static int pulse_deinit (pulse_info_t * pinfo)
{
- int ret;
- mm_ipc_msg_t respmsg = {0,};
- sink_struct *ss = (sink_struct *)userdata;
- if (ss == NULL) {
- debug_error ("Input userdata is NULL\n");
- return;
- }
+ pa_threaded_mainloop_lock (pinfo->m);
+ if (pinfo->context) {
+ pa_context_disconnect (pinfo->context);
- if (is_last) {
- if (is_last < 0) { /* ERROR */
- /* Compose Error Response */
- debug_error("Failed to get sink information: %s\n", pa_strerror(pa_context_errno(c)));
- debug_error("Error to MM_SOUND_MSG_REQ_SET_AUDIO_ROUTE.\n");
- SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, 0, ss->msg->sound_msg.msgid);
- } else { /* FINISHED WELL */
- /* Compose Response */
- SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_SET_AUDIO_ROUTE, ss->msg->sound_msg.handle, ss->route_to, ss->msg->sound_msg.msgid);
-
- /* Do further action related with route request */
- /* ToDo : is this sync operation??? */
- if (ss->route_to == 0 && ss->is_speaker_on ) {
- /* route to speaker and speaker is on */
- debug_msg ("Trying to set default sink to [%s] \n", ss->speaker_name);
- pa_operation_unref(pa_context_set_default_sink(g_context, ss->speaker_name, NULL, NULL));
- } else if (ss->route_to == 1 && ss->is_bt_on) {
- /* route to bt and bt is on */
- debug_msg ("Trying to set default sink to [%s] \n", ss->bt_name);
- pa_operation_unref(pa_context_set_default_sink(g_context, ss->bt_name, NULL, NULL));
- } else {
- /* Nothing to do.... */
- debug_warning ("No match for [%d] \n", ss->route_to);
- respmsg.sound_msg.code = -1; // this means no exists
- }
- }
-
- if (ss) {
- /* Send Response */
- if (ss->func) {
- ret = ss->func (&respmsg);
- if (ret != MM_ERROR_NONE) {
- debug_error ("Fail to send message \n");
- }
- debug_msg("Sent msg to client msgid [%d] [codechandle %d][message type %d] (code 0x%08X)\n",
- ss->msg->sound_msg.msgid, respmsg.sound_msg.handle, respmsg.sound_msg.msgtype, respmsg.sound_msg.code);
- } else {
- debug_error ("No send function\n");
- }
-
- /* Cleanup */
- if (ss->msg) {
- debug_msg ("free [%p]\n", ss->msg);
- free (ss->msg);
- ss->msg = NULL;
- }
- free (ss);
- ss = NULL;
- }
- debug_msg("Ready to next msg\n");
- pthread_mutex_unlock(&g_mutex);
-
- return;
- }
-
- //pa_assert(i);
-
- if (i->name) {
- debug_msg("sink name = [%s]\n", i->name);
-
- if (strstr (i->name, "alsa_")) {
- ss->is_speaker_on = 1;
- strncpy (ss->speaker_name, i->name, sizeof(ss->speaker_name)-1);
- } else if (strstr (i->name, "bluez")) {
- ss->is_bt_on = 1;
- strncpy (ss->bt_name, i->name, sizeof(ss->bt_name)-1);
- } else
- debug_warning("Unknown sink name!!!\n");
- }
-
-}
+ /* Make sure we don't get any further callbacks */
+ pa_context_set_state_callback (pinfo->context, NULL, NULL);
-void check_bt_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_last, void *userdata)
-{
- int ret;
- mm_ipc_msg_t respmsg = {0,};
- bt_struct *bs = (bt_struct *)userdata;
- if (bs == NULL) {
- debug_error ("Input userdata is NULL\n");
- return;
+ pa_context_unref (pinfo->context);
+ pinfo->context = NULL;
}
+ pa_threaded_mainloop_unlock (pinfo->m);
- if (is_last) {
- if (is_last < 0) { /* ERROR */
- /* Compose Error Response */
- debug_error("Failed to get sink information: %s\n", pa_strerror(pa_context_errno(c)));
- debug_error("Error to MM_SOUND_MSG_RES_IS_BT_A2DP_ON.\n");
- SOUND_MSG_SET(respmsg.sound_msg, MM_SOUND_MSG_RES_ERROR, -1, 0, bs->msg->sound_msg.msgid);
- } else { /* FINISHED WELL */
- /* Compose Response */
- SOUND_MSG_SET(respmsg.sound_msg,
- MM_SOUND_MSG_RES_IS_BT_A2DP_ON, bs->msg->sound_msg.handle, (bs->bt_found)? 1:0, bs->msg->sound_msg.msgid);
- strncpy (respmsg.sound_msg.filename, bs->bt_name, sizeof (respmsg.sound_msg.filename)-1);
- }
-
- /* Send resone & clean up */
- if (bs) {
- /* Send Response */
- if (bs->func) {
- ret = bs->func (&respmsg);
- if (ret != MM_ERROR_NONE) {
- debug_error ("Fail to send message \n");
- } else {
- debug_msg("Sent msg to client msgid [%d] [codechandle %d][message type %d] (code 0x%08X)\n",
- bs->msg->sound_msg.msgid, respmsg.sound_msg.handle, respmsg.sound_msg.msgtype, respmsg.sound_msg.code);
- }
- } else {
- debug_error ("No sendfunc!!!!\n");
- }
+ pa_threaded_mainloop_stop (pinfo->m);
+ pa_threaded_mainloop_free (pinfo->m);
- /* clean up */
- if (bs->msg) {
- debug_msg ("free [%p]\n", bs->msg);
- free (bs->msg);
- bs->msg = NULL;
- }
- free (bs);
- bs = NULL;
- }
+ debug_msg ("<<<<<<<<<< [%s][%d]\n", __func__, __LINE__);
- debug_msg("Ready to next msg\n");
- pthread_mutex_unlock(&g_mutex);
- return;
- }
+ return 0;
- //pa_assert(i);
-
- if (i->name) {
- debug_msg("sink name = [%s]\n", i->name);
-
- if (strstr (i->name, "bluez")) {
- char* desc = pa_proplist_gets(i->proplist, PA_PROP_DEVICE_DESCRIPTION);
- if (desc && strlen(desc)>0) {
- debug_msg ("sink device description = [%s]\n", desc);
- bs->bt_found = 1;
- strncpy (bs->bt_name, desc, strlen(desc));
- } else {
- debug_warning ("No Description!!!!\n");
- }
- }
- }
-
}
-int MMSoundMgrPulseHandleGetAudioRouteReq (mm_ipc_msg_t *msg, int (*sendfunc)(mm_ipc_msg_t*))
-{
- debug_enter("msg = %p , sendfunc = %p\n", msg, sendfunc);
+/* -------------------------------- MONO AUDIO --------------------------------------------*/
+#ifdef SUPPORT_MONO_AUDIO
+#define MONO_KEY VCONFKEY_SETAPPL_ACCESSIBILITY_MONO_AUDIO
- pthread_mutex_lock(&g_mutex);
+static void success_cb (pa_context *c, int success, void *userdata)
+{
+ debug_msg ("success = %d\n", success);
+}
- server_struct *ss = malloc (sizeof (server_struct));
- memset (ss, 0, sizeof (server_struct));
+static void mono_changed_cb(keynode_t* node, void* data)
+{
+ int key_value;
+ pulse_info_t* pinfo = (pulse_info_t*)data;
- /* common setting */
- ss->msg = msg;
- ss->func = sendfunc;
+ debug_msg ("%s changed callback called\n",vconf_keynode_get_name(node));
- /* Do async pulse operation */
- pa_operation_unref(pa_context_get_server_info(g_context, get_server_info_callback, ss));
+ vconf_get_bool(MONO_KEY, &key_value);
+ debug_msg ("key value = %d\n", key_value);
- debug_leave("\n");
+ pa_operation_unref (pa_ext_policy_set_mono (pinfo->context, key_value, success_cb, NULL));
}
-int MMSoundMgrPulseHandleSetAudioRouteReq (mm_ipc_msg_t *msg, int (*sendfunc)(mm_ipc_msg_t*))
+int MMSoundMgrPulseHandleRegisterMonoAudio (void* pinfo)
{
- debug_enter("\n");
+ int ret = vconf_notify_key_changed(MONO_KEY, mono_changed_cb, pinfo);
+ debug_msg ("vconf [%s] set ret = %d\n", MONO_KEY, ret);
+ return ret;
+}
+#endif /* SUPPORT_MONO_AUDIO */
- pthread_mutex_lock(&g_mutex);
- sink_struct *ss = malloc (sizeof (sink_struct));
- memset (ss, 0, sizeof(sink_struct));
+/* -------------------------------- BT SCO --------------------------------------------*/
+#ifdef SUPPORT_BT_SCO_DETECT
- /* common setting */
- ss->msg = msg;
- ss->func = sendfunc;
+static void bt_changed_cb(keynode_t* node, void* data)
+{
+ int bt_status = VCONFKEY_BT_DEVICE_NONE;
+ int available = 0;
+ pulse_info_t* pinfo = (pulse_info_t*)data;
- /* specific setting */
- ss->is_speaker_on = ss->is_bt_on = 0;
- ss->route_to = msg->sound_msg.handle;
+ debug_msg ("[%s] changed callback called\n", vconf_keynode_get_name(node));
- /* Do async pulse operation */
- pa_operation_unref(pa_context_get_sink_info_list(g_context, get_sink_info_callback, ss));
+ /* Get actual vconf value */
+ vconf_get_int(VCONFKEY_BT_DEVICE, &bt_status);
+ debug_msg ("key value = 0x%x\n", bt_status);
- debug_leave("\n");
+ /* Set device available based on vconf key value */
+ available = (bt_status & VCONFKEY_BT_DEVICE_HEADSET_CONNECTED)? AVAILABLE : NOT_AVAILABLE;
+ MMSoundMgrSessionSetDeviceAvailable (DEVICE_BT_SCO, available, 0, NULL);
+}
+
+int MMSoundMgrPulseHandleRegisterBluetoothStatus (void* pinfo)
+{
+ /* set callback for vconf key change */
+ int ret = vconf_notify_key_changed(VCONFKEY_BT_DEVICE , bt_changed_cb, pinfo);
+ debug_msg ("vconf [%s] set ret = %d\n", VCONFKEY_BT_DEVICE, ret);
+ return ret;
}
+#endif /* SUPPORT_BT_SCO_DETECT */
+
+/* -------------------------------- MGR MAIN --------------------------------------------*/
int MMSoundMgrPulseHandleIsBtA2DPOnReq (mm_ipc_msg_t *msg, int (*sendfunc)(mm_ipc_msg_t*))
{
+ int ret = 0;
+ mm_ipc_msg_t respmsg = {0,};
+ char* bt_name;
+ bool is_bt_on = false;
+ pthread_mutex_lock(&g_mutex);
+
debug_enter("msg = %p, sendfunc = %p\n", msg, sendfunc);
- pthread_mutex_lock(&g_mutex);
+ bt_name = MMSoundMgrSessionGetBtA2DPName();
+ if (bt_name && strlen(bt_name) > 0) {
+ is_bt_on = true;
+ }
- bt_struct *bs = malloc (sizeof(bt_struct));
- memset (bs, 0, sizeof (bt_struct));
+ debug_log ("is_bt_on = [%d], name = [%s]\n", is_bt_on, bt_name);
- /* common setting */
- bs->msg = msg;
- bs->func = sendfunc;
+ SOUND_MSG_SET(respmsg.sound_msg,
+ MM_SOUND_MSG_RES_IS_BT_A2DP_ON, msg->sound_msg.handle, is_bt_on, msg->sound_msg.msgid);
+ strncpy (respmsg.sound_msg.filename, bt_name, sizeof (respmsg.sound_msg.filename)-1);
- /* specific setting */
- bs->bt_found = 0;
+ /* Send Response */
+ ret = sendfunc (&respmsg);
+ if (ret != MM_ERROR_NONE) {
+ /* TODO : Error Handling */
+ debug_error ("sendfunc failed....ret = [%x]\n", ret);
+ }
- /* Do async pulse operation */
- pa_operation_unref(pa_context_get_sink_info_list(g_context, check_bt_sink_info_callback, bs));
+ pthread_mutex_unlock(&g_mutex);
debug_leave("\n");
-}
-#ifdef SUPPORT_MONO_AUDIO
-#define MONO_KEY "db/setting/accessibility/mono_audio"
+ return ret;
+}
-void success_cb (pa_context *c, int success, void *userdata)
+void MMSoundMgrPulseSetDefaultSink (char* default_sink_name)
{
- debug_msg ("success = %d\n", success);
+ debug_enter("\n");
+
+ pulse_set_default_sink(pulse_info, default_sink_name);
+
+ debug_leave("\n");
}
-void mono_changed_cb(keynode_t* node, void* data)
+void MMSoundMgrPulseGetInitialBTStatus (bool *a2dp, bool *sco)
{
- debug_msg ("%s changed callback called\n",vconf_keynode_get_name(node));
+ int bt_status = VCONFKEY_BT_DEVICE_NONE;
- int key_value;
- vconf_get_bool(MONO_KEY, &key_value);
+ if (a2dp == NULL || sco == NULL) {
+ debug_error ("Invalide arguments!!!\n");
+ return;
+ }
- debug_msg ("key value = %d\n", key_value);
+ /* Get saved bt status */
+ *a2dp = pulse_info->init_bt_status;
- pa_operation_unref (pa_ext_policy_set_mono (g_context, key_value, success_cb, NULL));
-}
+ /* Get actual vconf value */
+ vconf_get_int(VCONFKEY_BT_DEVICE, &bt_status);
+ debug_msg ("key value = 0x%x\n", bt_status);
+ *sco = (bt_status & VCONFKEY_BT_DEVICE_HEADSET_CONNECTED)? true : false;
-int MMSoundMgrPulseHandleRegisterMonoAudio ()
-{
- int ret = vconf_notify_key_changed(MONO_KEY, mono_changed_cb, NULL);
- debug_enter ("vconf set ret = %d\n", ret);
- return ret;
+ debug_msg ("returning a2dp=[%d], sco=[%d]\n", *a2dp, *sco);
}
-#endif
-
-int MMSoundMgrPulseInit(void)
+void* MMSoundMgrPulseInit(void)
{
+ pulse_info = (pulse_info_t*) malloc (sizeof(pulse_info_t));
+ memset (pulse_info, 0, sizeof(pulse_info_t));
+
debug_enter("\n");
- pulse_init();
+ pulse_init(pulse_info);
#ifdef SUPPORT_MONO_AUDIO
- MMSoundMgrPulseHandleRegisterMonoAudio();
+ MMSoundMgrPulseHandleRegisterMonoAudio(pulse_info);
#endif
-#ifdef BT_DISCONNECT_PAUSE
- /* This registeration can be failed when hibernation capture, because of security server */
- _asm_register_for_bt ();
-
+#ifdef SUPPORT_BT_SCO_DETECT
+ MMSoundMgrPulseHandleRegisterBluetoothStatus(pulse_info);
#endif
+
debug_leave("\n");
- return MM_ERROR_NONE;
+ return pulse_info;
}
-int MMSoundMgrPulseFini(void)
+int MMSoundMgrPulseFini(void* handle)
{
debug_enter("\n");
- pulse_deinit();
-
-#ifdef BT_DISCONNECT_PAUSE
- {
- int asm_error = 0;
- if(!ASM_unregister_sound(g_asm_handle, ASM_EVENT_EARJACK_UNPLUG, &asm_error))
- {
- debug_error("earjack event unregister failed with 0x%x\n", asm_error);
- }
- }
-#endif
+ pulse_deinit((pulse_info_t *)handle);
debug_leave("\n");
return MM_ERROR_NONE;