From 4ccac0f25f60bbc7056b24caf0cda7b8707bd5a8 Mon Sep 17 00:00:00 2001 From: DoHyun Pyun Date: Wed, 19 Feb 2020 14:32:46 +0900 Subject: [PATCH 1/1] Implement the event handling logic for AVC Change-Id: I399c0f1e1aba91b95e5cded35c42f7ff5d507a5a Signed-off-by: DoHyun Pyun --- bt-api/bt-event-handler.c | 10 ++ .../services/adapter/bt-service-core-adapter.c | 5 + .../services/audio/a2dp_src/bt-service-a2dp-src.c | 10 ++ .../services/audio/avrcp/bt-service-avrcp-tg.c | 12 +- .../services/audio/bt-service-absolute-volume.c | 182 +++++++++++++++++++-- .../services/include/bt-service-audio-common.h | 6 +- 6 files changed, 197 insertions(+), 28 deletions(-) diff --git a/bt-api/bt-event-handler.c b/bt-api/bt-event-handler.c index c45e644..b8235df 100644 --- a/bt-api/bt-event-handler.c +++ b/bt-api/bt-event-handler.c @@ -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, diff --git a/bt-service-adaptation/services/adapter/bt-service-core-adapter.c b/bt-service-adaptation/services/adapter/bt-service-core-adapter.c index 22c1805..1eb95d4 100644 --- a/bt-service-adaptation/services/adapter/bt-service-core-adapter.c +++ b/bt-service-adaptation/services/adapter/bt-service-core-adapter.c @@ -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); diff --git a/bt-service-adaptation/services/audio/a2dp_src/bt-service-a2dp-src.c b/bt-service-adaptation/services/audio/a2dp_src/bt-service-a2dp-src.c index 8ca051d..8df461a 100644 --- a/bt-service-adaptation/services/audio/a2dp_src/bt-service-a2dp-src.c +++ b/bt-service-adaptation/services/audio/a2dp_src/bt-service-a2dp-src.c @@ -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); diff --git a/bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-tg.c b/bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-tg.c index 656bcbc..d360780 100644 --- a/bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-tg.c +++ b/bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-tg.c @@ -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 } diff --git a/bt-service-adaptation/services/audio/bt-service-absolute-volume.c b/bt-service-adaptation/services/audio/bt-service-absolute-volume.c index 54e2e46..a56d712 100644 --- a/bt-service-adaptation/services/audio/bt-service-absolute-volume.c +++ b/bt-service-adaptation/services/audio/bt-service-absolute-volume.c @@ -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)); +} diff --git a/bt-service-adaptation/services/include/bt-service-audio-common.h b/bt-service-adaptation/services/include/bt-service-audio-common.h index b0f2f69..a6c866d 100644 --- a/bt-service-adaptation/services/include/bt-service-audio-common.h +++ b/bt-service-adaptation/services/include/bt-service-audio-common.h @@ -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); -- 2.7.4