Move the volume changed event path from AVRCP to HEADSET
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / audio / bt-service-absolute-volume.c
index 54e2e46..631f3b1 100644 (file)
@@ -31,6 +31,9 @@
 #include "bt-service-event.h"
 #include "bt-service-avrcp-tg.h"
 
+/* We will remove this flag after stabilizing the functionality */
+#define AVC_DEBUG 1
+
 /* Avoid the build error related to vconf.h's dependency */
 #ifndef VCONFKEY_BT_AVC_MODE
 #define VCONFKEY_BT_AVC_MODE "db/bluetooth/avc_mode"
@@ -62,7 +65,9 @@ static void __bt_audio_covert_system_to_bt_volume(unsigned int sys_vol, unsigned
        if (*bt_vol > 0 && *bt_vol < 127)
                *bt_vol = *bt_vol + 1;
 
+#ifdef AVC_DEBUG
        BT_DBG("System volume [%d], BT volume [%d]", sys_vol, *bt_vol);
+#endif
 }
 
 static void __bt_audio_covert_bt_to_system_volume(unsigned int bt_vol, unsigned int *sys_vol)
@@ -80,7 +85,9 @@ static void __bt_audio_covert_bt_to_system_volume(unsigned int bt_vol, unsigned
        if (*sys_vol > 0 && *sys_vol < 150)
                *sys_vol = *sys_vol + 1;
 
+#ifdef AVC_DEBUG
        BT_DBG("System volume [%d], BT volume [%d]", *sys_vol, bt_vol);
+#endif
 }
 
 static int __bt_audio_get_active_headset_volume(void)
@@ -91,6 +98,10 @@ static int __bt_audio_get_active_headset_volume(void)
        gboolean connected = FALSE;
        unsigned int volume = BT_VOLUME_MAX + 1;
 
+#ifdef AVC_DEBUG
+       BT_DBG("+");
+#endif
+
        /* 1. Get active A2DP headset path */
 
        /* We should modify this function to get the active headset in later */
@@ -118,51 +129,95 @@ static int __bt_audio_get_active_headset_volume(void)
        return volume;
 }
 
+/* Emit AVC mode changed signal (AVC_OFF/AVC_NULL/AVC_MAX) to application (Pulseaudio) */
 static void __bt_audio_notify_avc_mode_changed(unsigned int avc_mode)
 {
        GVariant *param = g_variant_new("(u)", avc_mode);
 
+       /* AVC Event */
        _bt_send_event(BT_AUDIO_AVC_EVENT,
                        BLUETOOTH_EVENT_AUDIO_AVC_MODE_CHANGED,
                        param);
 }
 
+/* Emit On / off state changed signal to application (Setting) */
+static void __bt_audio_notify_avc_onoff_changed(bool status)
+{
+       GVariant *param = g_variant_new("(b)", status);
+
+       /* HEADSET Event */
+       _bt_send_event(BT_HEADSET_EVENT,
+                       BLUETOOTH_EVENT_AUDIO_AVC_MODE_CHANGED,
+                       param);
+}
+
 static void __bt_audio_set_avc_mode(unsigned int mode)
 {
        unsigned int prev_mode = avc_mode;
+       bool onoff_state = false;
 
        if (prev_mode == mode) {
                BT_DBG("No avc mode change");
                return;
        }
 
-       BT_ERR("Previous mode [%d], New mode [%d]", prev_mode, mode);
+       BT_DBG("Previous mode [%d], New mode [%d]", prev_mode, mode);
 
+       /*  Emit AVC mode changed signal (AVC_OFF/AVC_NULL/AVC_MAX) to Pulseaudio  */
        __bt_audio_notify_avc_mode_changed(mode);
 
        avc_mode = mode;
+
+       switch (mode) {
+       case BT_AVC_OFF:
+               onoff_state = false;
+               break;
+       case BT_AVC_NULL:
+       case BT_AVC_MAX:
+               if (prev_mode != BT_AVC_OFF) {
+                       BT_DBG("Don't need to send onff state changed");
+                       return;
+               }
+
+               onoff_state = true;
+               break;
+       default:
+               BT_ERR("Abnormal state!");
+               return;
+               break;
+       }
+
+       /* Emit On / off state changed signal to application (Setting) */
+       __bt_audio_notify_avc_onoff_changed(onoff_state);
 }
 
 static void __bt_audio_sync_absolute_volume(unsigned int bt_vol)
 {
-       if (absolute_volume > ABSOLUTE_VOLUME_MAX || bt_volume > BT_VOLUME_MAX) {
-               unsigned int sys_vol = 0;
+       unsigned int sys_vol = 0;
 
-               BT_DBG("synchronize the system and bt volume");
+       BT_DBG("synchronize the system and bt volume");
 
-               __bt_audio_covert_bt_to_system_volume(bt_vol, &sys_vol);
+       __bt_audio_covert_bt_to_system_volume(bt_vol, &sys_vol);
 
-               bt_volume = bt_vol;
-               absolute_volume = sys_vol;
-       }
+       bt_volume = bt_vol;
+       absolute_volume = sys_vol;
 }
 
 static void __bt_audio_set_user_avc_value(bool mode)
 {
        int volume = 0;
 
+       BT_DBG("mode: %d", mode);
+
        if (mode == false) {
                __bt_audio_set_avc_mode(BT_AVC_OFF);
+               absolute_volume = ABSOLUTE_VOLUME_MAX + 1;
+               bt_volume = BT_VOLUME_MAX + 1;
+               return;
+       }
+
+       if (avc_mode != BT_AVC_OFF) {
+               BT_DBG("Already activate AVC mode");
                return;
        }
 
@@ -203,6 +258,10 @@ static void __bt_audio_user_avc_mode_cb(keynode_t *node, void *data)
 
 int _bt_audio_init_absolute_volume_control(void)
 {
+#ifdef AVC_DEBUG
+       BT_DBG("+");
+#endif
+
        absolute_volume = ABSOLUTE_VOLUME_MAX + 1;
        bt_volume = BT_VOLUME_MAX + 1;
        avc_mode = BT_AVC_OFF;
@@ -218,6 +277,10 @@ int _bt_audio_init_absolute_volume_control(void)
 
 void _bt_audio_deinit_absolute_volume_control(void)
 {
+#ifdef AVC_DEBUG
+       BT_DBG("+");
+#endif
+
        absolute_volume = ABSOLUTE_VOLUME_MAX + 1;
        bt_volume = BT_VOLUME_MAX + 1;
        avc_mode = BT_AVC_OFF;
@@ -234,6 +297,8 @@ int _bt_audio_set_absolute_volume(unsigned int volume)
        bluetooth_device_address_t device_address;
        gboolean connected = FALSE;
 
+       BT_DBG("volume: %d", volume);
+
        if (volume > 150) {
                BT_ERR("The volume exceeded 150");
                return BLUETOOTH_ERROR_INVALID_PARAM;
@@ -279,16 +344,23 @@ int _bt_audio_set_absolute_volume(unsigned int volume)
 /* Just return the absolute_volume value */
 int _bt_audio_get_absolute_volume(unsigned int *volume)
 {
-       int result = BLUETOOTH_ERROR_NONE;
-
        if (avc_mode == BT_AVC_OFF) {
                BT_ERR("AVC mode is off");
                return BLUETOOTH_ERROR_INTERNAL;
        }
 
+       if (absolute_volume > ABSOLUTE_VOLUME_MAX) {
+               BT_ERR("Absolute Volume level is not set");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
        *volume = absolute_volume;
 
-       return result;
+#ifdef AVC_DEBUG
+       BT_DBG("volume: %d", *volume);
+#endif
+
+       return BLUETOOTH_ERROR_NONE;
 }
 
 int _bt_audio_is_avc_activated(bool *activated)
@@ -300,6 +372,10 @@ int _bt_audio_is_avc_activated(bool *activated)
 
        *activated = (mode == BT_AVC_OFF) ? false : true;
 
+#ifdef AVC_DEBUG
+       BT_DBG("avc_mode: %d", avc_mode);
+#endif
+
        return BLUETOOTH_ERROR_NONE;
 }
 
@@ -308,6 +384,10 @@ int _bt_audio_get_avc_mode(unsigned int *mode)
        int state = 0;
        int volume = 0;
 
+#ifdef AVC_DEBUG
+       BT_DBG("+");
+#endif
+
        /* 1. Get AVC mode in the vconf value */
        if (vconf_get_bool(VCONFKEY_BT_AVC_MODE, &state) != 0) {
                BT_ERR("vconf_get_bool failed");
@@ -341,9 +421,84 @@ int _bt_audio_get_avc_mode(unsigned int *mode)
        return BLUETOOTH_ERROR_NONE;
 }
 
-/* 1. When a2dp headset is connected, we should set 'AVC' mode internaly */
-/* 2. If the avc mode is changed, we should inform 'AVC' mode to pulseaudio */
-/* 3. If BT is off, we should send 'AVC' off mode event for application */
-/* 4. If BT A2DP is disconnected, we should send 'AVC' off mode event for application */
-/* 5. When we recieve the volume changed, we shuld sync up the volume */
+void _bt_audio_handle_adapter_disabled(void)
+{
+       BT_DBG("Reset AVC mode, and volume");
+
+       absolute_volume = ABSOLUTE_VOLUME_MAX + 1;
+       bt_volume = BT_VOLUME_MAX + 1;
+       __bt_audio_set_avc_mode(BT_AVC_OFF);
+       return;
+}
+
+void _bt_audio_handle_a2dp_state_changed(const char *address, bool connected)
+{
+       unsigned int mode = 0;
+
+#ifdef AVC_DEBUG
+       BT_DBG("+");
+#endif
+
+       /* In later, we can check the event for the active headset or not in here */
+
+       if (connected == false) {
+               BT_DBG("Reset AVC mode, and volume");
+
+               absolute_volume = ABSOLUTE_VOLUME_MAX + 1;
+               bt_volume = BT_VOLUME_MAX + 1;
+               __bt_audio_set_avc_mode(BT_AVC_OFF);
+               return;
+       }
+
+       if (_bt_audio_get_avc_mode(&mode) != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("Fail to get the avc mode");
+               return;
+       }
+
+       if (mode != BT_AVC_OFF) {
+               __bt_audio_set_avc_mode(mode);
+
+               /* Send the initial volume to application */
+               _bt_send_event(BT_HEADSET_EVENT,
+                       BLUETOOTH_EVENT_AVRCP_VOLUME_CHANGED,
+                       g_variant_new("(u)", absolute_volume));
+       }
+}
+
+void _bt_audio_handle_transport_volume_changed(unsigned int bt_vol)
+{
+       unsigned int sys_vol = 0;
+       int mode = BT_AVC_OFF;
+       unsigned int prev_vol = absolute_volume;
+
+#ifdef AVC_DEBUG
+       BT_DBG("+");
+#endif
+
+       if (bt_vol > BT_VOLUME_MAX) {
+               /* BT AVC mode off, because bluez transport initiate the volue as MAX */
+               absolute_volume = ABSOLUTE_VOLUME_MAX + 1;
+               bt_volume = BT_VOLUME_MAX + 1;
+               __bt_audio_set_avc_mode(BT_AVC_OFF);
+               return;
+       }
+
+       __bt_audio_covert_bt_to_system_volume(bt_vol, &sys_vol);
+
+       bt_volume = bt_vol;
+       absolute_volume = sys_vol;
+
+       mode = (absolute_volume == 0) ? BT_AVC_NULL : BT_AVC_MAX;
+
+       __bt_audio_set_avc_mode(mode);
+
+       if (prev_vol == absolute_volume) {
+               BT_DBG("Same volume level");
+               return;
+       }
+
+       _bt_send_event(BT_HEADSET_EVENT,
+               BLUETOOTH_EVENT_AVRCP_VOLUME_CHANGED,
+               g_variant_new("(u)", absolute_volume));
+}