Implement User AVC mode handling logic 55/225155/2
authorDoHyun Pyun <dh79.pyun@samsung.com>
Tue, 18 Feb 2020 01:07:16 +0000 (10:07 +0900)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Tue, 18 Feb 2020 01:08:42 +0000 (10:08 +0900)
Change-Id: I9375d17a6309ea30dcef6effd9ae0a64e7ae269d
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
bt-service-adaptation/services/audio/bt-service-absolute-volume.c
bt-service-adaptation/services/bt-service-main.c
bt-service-adaptation/services/include/bt-service-audio-common.h

index 29447fb..14a5a4f 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <vconf.h>
+#include <vconf-internal-keys.h>
 
 #include <oal-event.h>
 #include <oal-hardware.h>
 #include "bt-service-audio-common.h"
 #include "bt-service-event.h"
 
-static unsigned int absolute_volume = 0;
-static unsigned int bt_volume = 0;
+/* Avoid the build error related to vconf.h's dependency */
+#ifndef VCONFKEY_BT_AVC_MODE
+#define VCONFKEY_BT_AVC_MODE "db/bluetooth/avc_mode"
+#endif
+
+#ifndef VCONFKEY_BT_AVC_OFF
+#define VCONFKEY_BT_AVC_OFF false
+#endif
+
+#define ABSOLUTE_VOLUME_MAX 150
+#define BT_VOLUME_MAX 127
+
+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 int __bt_audio_get_active_headset_volume(void)
+{
+       char connected_address[BT_ADDRESS_STRING_SIZE + 1];
+       gboolean connected = FALSE;
+       int volume = -1;
+
+       /* 1. Get active A2DP headset path */
+
+       /* We should modify this function to get the active headset in later */
+       connected = _bt_is_headset_type_connected(BT_AUDIO_A2DP, connected_address);
+
+       if (connected == FALSE) {
+               BT_DBG("There is no active A2DP headset");
+               return -1;
+       }
+
+       /* 2. Get volume info for active transport for the path */
+
+       /*
+               _bt_avrcp_transport_get_property(VOLUME, &volume)
+       */
+
+       return volume;
+}
+
+static void __bt_audio_notify_avc_mode_changed(unsigned int avc_mode)
+{
+       GVariant *param = g_variant_new("(u)", avc_mode);
+
+       _bt_send_event(BT_AUDIO_AVC_EVENT,
+                       BLUETOOTH_EVENT_AUDIO_AVC_MODE_CHANGED,
+                       param);
+}
+
+static void __bt_audio_set_avc_mode(unsigned int mode)
+{
+       unsigned int prev_mode = avc_mode;
+
+       if (prev_mode == mode) {
+               BT_DBG("No avc mode change");
+               return;
+       }
+
+       BT_ERR("Previous mode [%d], New mode [%d]", prev_mode, mode);
+
+       __bt_audio_notify_avc_mode_changed(mode);
+
+       avc_mode = mode;
+}
+
+static void __bt_audio_set_user_avc_value(bool mode)
+{
+       int volume = 0;
+
+       if (mode == false) {
+               __bt_audio_set_avc_mode(BT_AVC_OFF);
+               return;
+       }
+
+       volume = __bt_audio_get_active_headset_volume();
+
+       if (volume == -1) {
+               __bt_audio_set_avc_mode(BT_AVC_OFF);
+               return;
+       }
+
+       BT_INFO("The current transport supports AVC : volume [%d]", volume);
+
+       if (volume == 0) {
+               __bt_audio_set_avc_mode(BT_AVC_NULL);
+       } else {
+               BT_DBG("BT volume: %d", volume);
+               __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 */
+       }
+}
+
+static void __bt_audio_user_avc_mode_cb(keynode_t *node, void *data)
+{
+       int type;
+       bool mode = VCONFKEY_BT_AVC_OFF;
+
+       DBG_SECURE("key=%s", vconf_keynode_get_name(node));
+       type = vconf_keynode_get_type(node);
+
+       if (type == VCONF_TYPE_BOOL) {
+               mode = vconf_keynode_get_bool(node);
+               __bt_audio_set_user_avc_value(mode);
+       } else {
+               BT_ERR("Invaild vconf key type : %d", type);
+       }
+}
+
+int _bt_audio_init_absolute_volume_control(void)
+{
+       absolute_volume = ABSOLUTE_VOLUME_MAX + 1;
+       bt_volume = BT_VOLUME_MAX + 1;
+       avc_mode = BT_AVC_OFF;
+
+       if (vconf_notify_key_changed(VCONFKEY_BT_AVC_MODE,
+               (vconf_callback_fn)__bt_audio_user_avc_mode_cb, NULL) < 0) {
+                       BT_ERR("Unable to register key handler");
+                       return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_audio_deinit_absolute_volume_control(void)
+{
+       absolute_volume = ABSOLUTE_VOLUME_MAX + 1;
+       bt_volume = BT_VOLUME_MAX + 1;
+       avc_mode = BT_AVC_OFF;
+
+       vconf_ignore_key_changed(VCONFKEY_BT_AVC_MODE,
+                       (vconf_callback_fn)__bt_audio_user_avc_mode_cb);
+}
+
 int _bt_audio_set_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;
+       }
+
        /* 1. Translate the absolute volume to bt volume */
 
        /* Convert system gain to BT
@@ -54,7 +195,17 @@ int _bt_audio_set_absolute_volume(unsigned int volume)
 
        /* 2. Notify the bt_volume to transport (BT Headset) */
 
+       /*
+               _bt_avrcp_transport_set_property(VOLUME, bt_volume)
+       */
+
        /* 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_audio_set_avc_mode(BT_AVC_MAX);
+       }
 
        return result;
 }
@@ -64,6 +215,11 @@ 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;
+       }
+
        *volume = absolute_volume;
 
        return result;
@@ -71,36 +227,59 @@ int _bt_audio_get_absolute_volume(unsigned int *volume)
 
 int _bt_audio_is_avc_activated(bool *activated)
 {
-       *activated = (avc_mode == BT_AVC_OFF) ? false : true;
+       unsigned int mode = BT_AVC_OFF;
+
+       if (_bt_audio_get_avc_mode(&mode) != BLUETOOTH_ERROR_NONE)
+               BT_ERR("Fail to get the avc mode");
+
+       *activated = (mode == BT_AVC_OFF) ? false : true;
 
        return BLUETOOTH_ERROR_NONE;
 }
 
 int _bt_audio_get_avc_mode(unsigned int *mode)
 {
-       /* 1. AVC mode in the vconf value */
+       int state = 0;
+       int volume = 0;
 
-       /* 2. Get active A2DP headset path */
+       /* 1. Get AVC mode in the vconf value */
+       if (vconf_get_bool(VCONFKEY_BT_AVC_MODE, &state) != 0) {
+               BT_ERR("vconf_get_bool failed");
+               *mode = BT_AVC_OFF;
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
 
-       /* 3. Get volume info for activae transport for the path */
+       if (state == VCONFKEY_BT_AVC_OFF) {
+               *mode = BT_AVC_OFF;
+               return BLUETOOTH_ERROR_NONE;
+       }
 
-       *mode = avc_mode;
+       volume = __bt_audio_get_active_headset_volume();
 
-       return BLUETOOTH_ERROR_NONE;
-}
+       if (volume == -1) {
+               *mode = BT_AVC_OFF;
+               return BLUETOOTH_ERROR_NONE;
+       }
 
-int _bt_audio_notify_avc_mode_changed(unsigned int avc_mode)
-{
-       GVariant *param = g_variant_new("(u)", avc_mode);
+       BT_INFO("The current transport supports AVC : volume [%d]", volume);
 
-       _bt_send_event(BT_AUDIO_AVC_EVENT,
-                       BLUETOOTH_EVENT_AUDIO_AVC_MODE_CHANGED,
-                       param);
+       if (volume == 0) {
+               *mode = BT_AVC_NULL;
+       } else {
+               BT_DBG("BT volume: %d", volume);
+               *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 */
+       }
 
        return BLUETOOTH_ERROR_NONE;
 }
 
-/* 1. When a2dp headset is connected, we should set 'AVC' mode into pulseaudio */
+/* 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 */
index 2ad0871..184e778 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "bt-internal-types.h"
 #include "bt-service-common.h"
+#include "bt-service-audio-common.h"
 #include "bt-request-handler.h"
 #include "bt-service-obex-event.h"
 #ifdef TIZEN_FEATURE_BT_PAN_NAP
@@ -57,6 +58,10 @@ static void __on_log_glib(const gchar *log_domain, GLogLevelFlags log_level,
 
 static void __bt_release_service(void)
 {
+#ifdef TIZEN_FEATURE_BT_AVC_TARGET
+       _bt_audio_deinit_absolute_volume_control();
+#endif
+
        _bt_service_le_deinit();
        _bt_deinit_hf_local_term_event_sender();
        _bt_deinit_service_event_sender();
@@ -320,6 +325,12 @@ int _bt_service_initialize(void)
 
        _bt_init_request_list();
 
+#ifdef TIZEN_FEATURE_BT_AVC_TARGET
+       ret = _bt_audio_init_absolute_volume_control();
+       if (ret != BLUETOOTH_ERROR_NONE)
+               BT_ERR("Fail to init AVC");
+#endif
+
        is_initialized = TRUE;
 
        return BLUETOOTH_ERROR_NONE;
index 085a451..b0f2f69 100644 (file)
@@ -137,6 +137,10 @@ typedef enum {
        BT_AVC_MAX
 } bt_avc_mode_t;
 
+int _bt_audio_init_absolute_volume_control(void);
+
+void _bt_audio_deinit_absolute_volume_control(void);
+
 int _bt_audio_set_absolute_volume(unsigned int volume);
 
 int _bt_audio_get_absolute_volume(unsigned int *volume);