Implement the event handling logic for AVC 18/225318/2 submit/tizen/20200220.012925
authorDoHyun Pyun <dh79.pyun@samsung.com>
Wed, 19 Feb 2020 05:32:46 +0000 (14:32 +0900)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Wed, 19 Feb 2020 06:18:31 +0000 (15:18 +0900)
Change-Id: I399c0f1e1aba91b95e5cded35c42f7ff5d507a5a
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
bt-api/bt-event-handler.c
bt-service-adaptation/services/adapter/bt-service-core-adapter.c
bt-service-adaptation/services/audio/a2dp_src/bt-service-a2dp-src.c
bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-tg.c
bt-service-adaptation/services/audio/bt-service-absolute-volume.c
bt-service-adaptation/services/include/bt-service-audio-common.h

index c45e644..b8235df 100644 (file)
@@ -1386,7 +1386,17 @@ void __bt_headset_event_filter(GDBusConnection *connection,
                _bt_headset_event_cb(BLUETOOTH_EVENT_AG_MIC_GAIN,
                                result, &gain,
                                event_info->cb, event_info->user_data);
+#ifdef TIZEN_FEATURE_BT_AVC_TARGET
+       } else if (strcasecmp(signal_name, BT_AUDIO_AVC_MODE_CHANGED) == 0) {
+               bool mode;
+
+               g_variant_get(parameters, "(b)", &mode);
+
+               _bt_headset_event_cb(BLUETOOTH_EVENT_AUDIO_AVC_STATUS,
+                               result, &mode,
+                               event_info->cb, event_info->user_data);
        }
+#endif
 }
 
 void __bt_hid_device_event_filter(GDBusConnection *connection,
index 22c1805..1eb95d4 100644 (file)
@@ -1604,6 +1604,11 @@ static void __bt_adapter_update_bt_disabled(void)
 
        _bt_device_handle_adapter_state(FALSE);
 
+#ifdef TIZEN_FEATURE_BT_AVC_TARGET
+       /* Send the information to Absolute Volume Controller */
+       _bt_audio_handle_adapter_disabled();
+#endif
+
        /* Update the vconf BT status in normal Deactivation case only */
        ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
        BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
index 8ca051d..8df461a 100644 (file)
@@ -103,6 +103,11 @@ static void __bt_handle_av_connected_state(bluetooth_device_address_t *address)
        /* Add data from the connected list */
        _bt_add_headset_to_list(BT_AUDIO_A2DP, BT_STATE_CONNECTED, addr);
 
+#ifdef TIZEN_FEATURE_BT_AVC_TARGET
+       /* Send the information to Absolute Volume Controller */
+       _bt_audio_handle_a2dp_state_changed(addr, true);
+#endif
+
        /* Delete waiting device data if present */
        wait_device = _bt_get_audio_wait_data();
        if (wait_device != NULL &&
@@ -182,6 +187,11 @@ static void __bt_handle_av_disconnected_state(bluetooth_device_address_t *addres
        /* Remove data from the connected list */
        _bt_remove_headset_from_list(BT_AUDIO_A2DP, addr);
 
+#ifdef TIZEN_FEATURE_BT_AVC_TARGET
+       /* Send the information to Absolute Volume Controller */
+       _bt_audio_handle_a2dp_state_changed(addr, false);
+#endif
+
        req_info = _bt_get_request_info_data(BT_AV_DISCONNECT, addr);
        BT_INFO("Address  of disconnected device[%s]", addr);
 
index 656bcbc..d360780 100644 (file)
@@ -532,17 +532,7 @@ static void __handle_transport_property_delay(unsigned int *value)
 static void __handle_transport_property_volume(unsigned int avrcp_volume)
 {
 #ifdef TIZEN_FEATURE_BT_AVC_TARGET
-       unsigned int system_volume = 0;
-
-       BT_DBG("+");
-
-       /* Need to add the logic for platform */
-
-       _bt_send_event(BT_AVRCP_EVENT,
-                       BLUETOOTH_EVENT_AVRCP_VOLUME_CHANGED,
-                       g_variant_new("(u)", system_volume));
-
-       BT_DBG("-");
+       _bt_audio_handle_transport_volume_changed(avrcp_volume);
 #endif
 }
 
index 54e2e46..a56d712 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,90 @@ 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;
        }
 
@@ -203,6 +253,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 +272,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 +292,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 +339,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 +367,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 +379,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 +416,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_AVRCP_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_AVRCP_EVENT,
+               BLUETOOTH_EVENT_AVRCP_VOLUME_CHANGED,
+               g_variant_new("(u)", absolute_volume));
+}
 
index b0f2f69..a6c866d 100644 (file)
@@ -149,7 +149,11 @@ int _bt_audio_is_avc_activated(bool *activated);
 
 int _bt_audio_get_avc_mode(unsigned int *avc_mode);
 
-int _bt_audio_notify_avc_mode_changed(unsigned int avc_mode);
+void _bt_audio_handle_adapter_disabled(void);
+
+void _bt_audio_handle_a2dp_state_changed(const char *address, bool connected);
+
+void _bt_audio_handle_transport_volume_changed(unsigned int bt_vol);
 #endif
 
 int _bt_hf_connect(bluetooth_device_address_t *device_address);