Implement set / get volume logic from transport
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / audio / bt-service-absolute-volume.c
index 14a5a4f..54e2e46 100644 (file)
@@ -29,6 +29,7 @@
 #include "bt-service-common.h"
 #include "bt-service-audio-common.h"
 #include "bt-service-event.h"
+#include "bt-service-avrcp-tg.h"
 
 /* Avoid the build error related to vconf.h's dependency */
 #ifndef VCONFKEY_BT_AVC_MODE
@@ -46,11 +47,49 @@ static unsigned int absolute_volume = ABSOLUTE_VOLUME_MAX + 1;
 static unsigned int bt_volume = BT_VOLUME_MAX + 1;
 static unsigned int avc_mode = BT_AVC_OFF;
 
+static void __bt_audio_covert_system_to_bt_volume(unsigned int sys_vol, unsigned int *bt_vol)
+{
+       /* Convert system gain to BT
+               BT volume range : 0 ~ 127
+               system volume range : 0 ~ 150 */
+
+       *bt_vol = 127 * ((float)sys_vol / 150);
+
+       /* volume table
+               system volume : 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150
+               avrcp  volume : 0  9 17 26 34 43 51 60 68 77  85  94 102 111 119 127 */
+
+       if (*bt_vol > 0 && *bt_vol < 127)
+               *bt_vol = *bt_vol + 1;
+
+       BT_DBG("System volume [%d], BT volume [%d]", sys_vol, *bt_vol);
+}
+
+static void __bt_audio_covert_bt_to_system_volume(unsigned int bt_vol, unsigned int *sys_vol)
+{
+       /* Convert BT gain to system
+               BT volume range : 0 ~ 127
+               system volume range : 0 ~ 150 */
+
+       *sys_vol = 150 * ((float)bt_vol / 127);
+
+       /* volume table
+               system volume : 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150
+               avrcp  volume : 0  9 17 26 34 43 51 60 68 77  85  94 102 111 119 127 */
+
+       if (*sys_vol > 0 && *sys_vol < 150)
+               *sys_vol = *sys_vol + 1;
+
+       BT_DBG("System volume [%d], BT volume [%d]", *sys_vol, bt_vol);
+}
+
 static int __bt_audio_get_active_headset_volume(void)
 {
+       int result = BLUETOOTH_ERROR_NONE;
        char connected_address[BT_ADDRESS_STRING_SIZE + 1];
+       bluetooth_device_address_t device_address;
        gboolean connected = FALSE;
-       int volume = -1;
+       unsigned int volume = BT_VOLUME_MAX + 1;
 
        /* 1. Get active A2DP headset path */
 
@@ -62,11 +101,19 @@ static int __bt_audio_get_active_headset_volume(void)
                return -1;
        }
 
+       _bt_convert_addr_string_to_type(device_address.addr, connected_address);
+
        /* 2. Get volume info for active transport for the path */
+       result = _bt_avrcp_target_get_volume(&device_address, &volume);
+       if (result != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("Fail to notify BT volume to headset");
+               return -1;
+       }
 
-       /*
-               _bt_avrcp_transport_get_property(VOLUME, &volume)
-       */
+       if (volume > BT_VOLUME_MAX) {
+               BT_DBG("Absolute Volume is not set in transport");
+               return -1;
+       }
 
        return volume;
 }
@@ -96,6 +143,20 @@ static void __bt_audio_set_avc_mode(unsigned int mode)
        avc_mode = mode;
 }
 
+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;
+
+               BT_DBG("synchronize the system and bt volume");
+
+               __bt_audio_covert_bt_to_system_volume(bt_vol, &sys_vol);
+
+               bt_volume = bt_vol;
+               absolute_volume = sys_vol;
+       }
+}
+
 static void __bt_audio_set_user_avc_value(bool mode)
 {
        int volume = 0;
@@ -121,11 +182,7 @@ static void __bt_audio_set_user_avc_value(bool mode)
                __bt_audio_set_avc_mode(BT_AVC_MAX);
        }
 
-       if (absolute_volume > ABSOLUTE_VOLUME_MAX || bt_volume > BT_VOLUME_MAX) {
-               BT_DBG("synchronize the system and bt volume");
-
-               /* Add Sync volumes */
-       }
+       __bt_audio_sync_absolute_volume(volume);
 }
 
 static void __bt_audio_user_avc_mode_cb(keynode_t *node, void *data)
@@ -172,38 +229,47 @@ void _bt_audio_deinit_absolute_volume_control(void)
 int _bt_audio_set_absolute_volume(unsigned int volume)
 {
        int result = BLUETOOTH_ERROR_NONE;
+       unsigned int bt_vol = 0;
+       char connected_address[BT_ADDRESS_STRING_SIZE + 1];
+       bluetooth_device_address_t device_address;
+       gboolean connected = FALSE;
+
+       if (volume > 150) {
+               BT_ERR("The volume exceeded 150");
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+       }
 
        if (avc_mode == BT_AVC_OFF) {
                BT_ERR("AVC mode is off");
                return BLUETOOTH_ERROR_INTERNAL;
        }
 
-       /* 1. Translate the absolute volume to bt volume */
+       /* We should modify this function to get the active headset in later */
+       connected = _bt_is_headset_type_connected(BT_AUDIO_A2DP, connected_address);
 
-       /* Convert system gain to BT
-               BT volume range : 0 ~ 127
-               system volume range : 0 ~ 150 */
+       if (connected == FALSE) {
+               BT_DBG("There is no active A2DP headset");
+               return BLUETOOTH_ERROR_NOT_CONNECTED;
+       }
 
-       bt_volume = 127 * volume / 150;
+       _bt_convert_addr_string_to_type(device_address.addr, connected_address);
 
-       /* volume table
-               system volume : 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150
-               avrcp_ volume : 0  9 17 26 34 43 51 60 68 77  85  94 102 111 119 127 */
+       /* 1. Translate the absolute volume to bt volume */
+       __bt_audio_covert_system_to_bt_volume(volume, &bt_vol);
 
-       if (bt_volume > 0 && bt_volume < 127)
-               bt_volume++;
+       bt_volume = bt_vol;
+       absolute_volume = volume;
 
        /* 2. Notify the bt_volume to transport (BT Headset) */
-
-       /*
-               _bt_avrcp_transport_set_property(VOLUME, bt_volume)
-       */
+       result = _bt_avrcp_target_notify_volume(&device_address, bt_volume);
+       if (result != BLUETOOTH_ERROR_NONE)
+               BT_ERR("Fail to notify BT volume to headset");
 
        /* 3. Notify the avc mode to the pulseaudio if it is needed */
        if (volume == 0) {
                __bt_audio_set_avc_mode(BT_AVC_NULL);
        } else {
-               BT_DBG("BT volume: %d", volume);
+               BT_DBG("System volume: %d", volume);
                __bt_audio_set_avc_mode(BT_AVC_MAX);
        }
 
@@ -270,11 +336,7 @@ int _bt_audio_get_avc_mode(unsigned int *mode)
                *mode = BT_AVC_MAX;
        }
 
-       if (absolute_volume > ABSOLUTE_VOLUME_MAX || bt_volume > BT_VOLUME_MAX) {
-               BT_DBG("synchronize the system and bt volume");
-
-               /* Add Sync volumes */
-       }
+       __bt_audio_sync_absolute_volume(volume);
 
        return BLUETOOTH_ERROR_NONE;
 }
@@ -283,4 +345,5 @@ int _bt_audio_get_avc_mode(unsigned int *mode)
 /* 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 */