Add interfaces for BT AVC feature (AVRCP Target) 22/224922/4
authorDoHyun Pyun <dh79.pyun@samsung.com>
Fri, 14 Feb 2020 06:10:13 +0000 (15:10 +0900)
committerPyun DoHyun <dh79.pyun@samsung.com>
Mon, 17 Feb 2020 00:58:43 +0000 (00:58 +0000)
Change-Id: I648968c4642b6ce4edf06aab4cb6a40150d10570
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
include/bluetooth_internal.h
include/bluetooth_private.h
include/bluetooth_type_internal.h
src/bluetooth-audio.c
src/bluetooth-common.c
test/bt_unit_test.c
test/bt_unit_test.h

index 2c19911..2a7539d 100644 (file)
@@ -199,6 +199,131 @@ int bt_adapter_recover(void);
  * @see bt_audio_initialize()
  */
 int bt_audio_select_role(bt_audio_role_e role);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_MODULE
+ * @brief  Absolute Volume of the remote headset is set using this API
+ * @since_tizen 6.0
+ * @param[in] The absolute volume of the remote headset (0 ~ 150)
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #BT_ERROR_NONE Successful
+ * @retval #BT_ERROR_NOT_INITIALIZED Not initialized
+ * @retval #BT_ERROR_NOT_SUPPORTED Not supported
+ * @retval #BT_ERROR_NOT_ENABLED  Not enabled
+ * @retval #BT_ERROR_OPERATION_FAILED Internal Error
+ * @pre The Bluetooth service must be initialized with bt_initialize().
+ * @pre The Bluetooth audio service must be initialized with bt_audio_initialize().
+ * @see bt_initialize()
+ * @see bt_audio_initialize()
+ */
+int bt_audio_set_absolute_volume(unsigned int volume);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_MODULE
+ * @brief  Get Absolute Volume of the remote headset using this API
+ * @since_tizen 6.0
+ * @param[out] The absolute volume of the remote headset (0 ~ 150)
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #BT_ERROR_NONE Successful
+ * @retval #BT_ERROR_NOT_INITIALIZED Not initialized
+ * @retval #BT_ERROR_NOT_SUPPORTED Not supported
+ * @retval #BT_ERROR_NOT_ENABLED  Not enabled
+ * @retval #BT_ERROR_OPERATION_FAILED Internal Error
+ * @pre The Bluetooth service must be initialized with bt_initialize().
+ * @pre The Bluetooth audio service must be initialized with bt_audio_initialize().
+ * @see bt_initialize()
+ * @see bt_audio_initialize()
+ */
+int bt_audio_get_absolute_volume(unsigned int *volume);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE
+ * @brief  Registers a callback function that will be invoked when the volume is changed.
+ * @since_tizen 6.0
+ * @param[in] callback The callback function to register
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return   0 on success, otherwise a negative error value.
+ * @retval #BT_ERROR_NONE  Successful
+ * @retval #BT_ERROR_NOT_INITIALIZED  Not initialized
+ * @retval #BT_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval #BT_ERROR_NOT_SUPPORTED  Not supported
+ * @pre The Bluetooth service must be initialized with bt_initialize().
+ * @pre The Bluetooth audio service must be initialized with bt_audio_initialize().
+ * @see bt_initialize()
+ * @see bt_audio_initialize()
+ */
+int bt_audio_set_absolute_volume_changed_cb(bt_audio_absolute_volume_changed_cb callback, void *user_data);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE
+ * @brief  Unregisters a callback function that will be invoked when the volume is changed.
+ * @since_tizen 6.0
+ * @return   0 on success, otherwise a negative error value.
+ * @retval #BT_ERROR_NONE  Successful
+ * @retval #BT_ERROR_NOT_INITIALIZED  Not initialized
+ * @retval #BT_ERROR_NOT_SUPPORTED  Not supported
+ *
+ * @pre The AVRCP service must be initialized with bt_avrcp_target_initialize() or bt_avrcp_control_initialize().
+ * @pre The Bluetooth service must be initialized with bt_initialize().
+ * @pre The Bluetooth audio service must be initialized with bt_audio_initialize().
+ * @see bt_initialize()
+ * @see bt_audio_initialize()
+ */
+int bt_audio_unset_absolute_volume_changed_cb(void);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_MODULE
+ * @brief  Get Absolute Volume Control status using this API
+ * @since_tizen 6.0
+ * @param[out] Activated infomation
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #BT_ERROR_NONE Successful
+ * @retval #BT_ERROR_NOT_INITIALIZED Not initialized
+ * @retval #BT_ERROR_NOT_SUPPORTED Not supported
+ * @retval #BT_ERROR_OPERATION_FAILED Internal Error
+ * @pre The Bluetooth service must be initialized with bt_initialize().
+ * @pre The Bluetooth audio service must be initialized with bt_audio_initialize().
+ * @see bt_initialize()
+ * @see bt_audio_initialize()
+ */
+int bt_audio_is_avc_activated(bool *activated);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE
+ * @brief  Registers a callback function that will be invoked when the absolute volume control status is changed.
+ * @since_tizen 6.0
+ * @param[in] callback The callback function to register
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return   0 on success, otherwise a negative error value.
+ * @retval #BT_ERROR_NONE  Successful
+ * @retval #BT_ERROR_NOT_INITIALIZED  Not initialized
+ * @retval #BT_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval #BT_ERROR_NOT_SUPPORTED  Not supported
+ * @pre The Bluetooth service must be initialized with bt_initialize().
+ * @pre The Bluetooth audio service must be initialized with bt_audio_initialize().
+ * @see bt_initialize()
+ * @see bt_audio_initialize()
+ */
+int bt_audio_set_avc_status_changed_cb(bt_audio_avc_status_changed_cb callback, void *user_data);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE
+ * @brief  Unregisters a callback function that will be invoked when the absolute volume control status is changed.
+ * @since_tizen 6.0
+ * @return   0 on success, otherwise a negative error value.
+ * @retval #BT_ERROR_NONE  Successful
+ * @retval #BT_ERROR_NOT_INITIALIZED  Not initialized
+ * @retval #BT_ERROR_NOT_SUPPORTED  Not supported
+ * @pre The Bluetooth service must be initialized with bt_initialize().
+ * @pre The Bluetooth audio service must be initialized with bt_audio_initialize().
+ * @see bt_initialize()
+ * @see bt_audio_initialize()
+ */
+int bt_audio_unset_avc_status_changed_cb(void);
+
 /**
  * @internal
  * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE
index d48f417..4f7e392 100644 (file)
@@ -105,6 +105,8 @@ typedef enum {
        BT_EVENT_AG_MICROPHONE_GAIN_CHANGE, /**< Audio Microphone change callback */
        BT_EVENT_AG_SPEAKER_GAIN_CHANGE, /**< Audio Speaker gain change callback */
        BT_EVENT_AG_VENDOR_CMD, /**< Audio - XSAT Vendor cmd */
+       BT_EVENT_AUDIO_ABSOLUTE_VOLUME_CHANGED, /**< Audio absolute volume change callback */
+       BT_EVENT_AUDIO_AVC_STATUS_CHANGED, /**< Absolute Volume Control status change callback */
        BT_EVENT_AVRCP_CONNECTION_STATUS, /**< AVRCP connection change callback */
        BT_EVENT_AVRCP_EQUALIZER_STATE_CHANGED, /**< AVRCP equalizer state change callback */
        BT_EVENT_AVRCP_REPEAT_MODE_CHANGED, /**< AVRCP repeat mode change callback */
index 82feedb..259609e 100644 (file)
@@ -136,6 +136,28 @@ typedef void (*bt_adapter_le_state_changed_cb)(int result, bt_adapter_le_state_e
 typedef void (*bt_avrcp_delay_changed_cb) (unsigned int delay, void *user_data);
 
 /**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE
+ * @brief  Called when the volume is changed by the remote device.
+ * @since_tizen 6.0
+ * @param[in] volume Volume in system value. (0 ~ 150)
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see bt_avrcp_set_volume_changed_cb()
+ * @see bt_avrcp_unset_volume_changed_cb()
+ */
+typedef void (*bt_audio_absolute_volume_changed_cb) (unsigned int volume, void *user_data);
+
+/**
+ * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_MODULE
+ * @brief  Called when the absolute volume control status is changed.
+ * @since_tizen 6.0
+ * @param[in] activated
+ * @param[in] user_data The user data passed from the callback registration function
+ * @see bt_avrcp_set_volume_changed_cb()
+ * @see bt_avrcp_unset_volume_changed_cb()
+ */
+typedef void (*bt_audio_avc_status_changed_cb) (bool activated, void *user_data);
+
+/**
  * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE
  * @brief  Enumerations for the call state
  * @since_tizen @if WEARABLE 2.3.1 @else 2.3 @endif
index 9c305d2..da5d103 100644 (file)
@@ -318,6 +318,98 @@ int bt_audio_disconnect(const char *remote_address, bt_audio_profile_type_e type
        return error;
 }
 
+/* LCOV_EXCL_START */
+int bt_audio_set_absolute_volume(unsigned int volume)
+{
+       BT_CHECK_AUDIO_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_AUDIO_INIT_STATUS();
+       int ret;
+
+       ret = bluetooth_audio_set_absolute_volume(volume);
+       ret = _bt_get_error_code(ret);
+
+       if (ret != BT_ERROR_NONE)
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+
+       return ret;
+}
+
+int bt_audio_get_absolute_volume(unsigned int *volume)
+{
+       int ret;
+
+       BT_CHECK_AUDIO_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_AUDIO_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(volume);
+
+       ret = bluetooth_audio_get_absolute_volume((unsigned int *)volume);
+       ret = _bt_get_error_code(ret);
+
+       if (BT_ERROR_NONE != ret)
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+
+       return ret;
+}
+
+int bt_audio_set_absolute_volume_changed_cb(bt_audio_absolute_volume_changed_cb callback, void *user_data)
+{
+       BT_CHECK_AUDIO_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_AUDIO_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(callback);
+       _bt_set_cb(BT_EVENT_AUDIO_ABSOLUTE_VOLUME_CHANGED, callback, user_data);
+       return BT_ERROR_NONE;
+}
+
+int bt_audio_unset_absolute_volume_changed_cb(void)
+{
+       BT_CHECK_AUDIO_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_AUDIO_INIT_STATUS();
+       _bt_unset_cb(BT_EVENT_AUDIO_ABSOLUTE_VOLUME_CHANGED);
+       return BT_ERROR_NONE;
+}
+
+int bt_audio_is_avc_activated(bool *activated)
+{
+       int ret;
+
+       BT_CHECK_AUDIO_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_AUDIO_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(activated);
+
+       ret = bluetooth_audio_get_absolute_volume((unsigned int *)activated);
+       ret = _bt_get_error_code(ret);
+
+       if (BT_ERROR_NONE != ret)
+               BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+
+       return ret;
+}
+
+int bt_audio_set_avc_status_changed_cb(bt_audio_avc_status_changed_cb callback, void *user_data)
+{
+       BT_CHECK_AUDIO_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_AUDIO_INIT_STATUS();
+       BT_CHECK_INPUT_PARAMETER(callback);
+       _bt_set_cb(BT_EVENT_AUDIO_AVC_STATUS_CHANGED, callback, user_data);
+       return BT_ERROR_NONE;
+}
+
+int bt_audio_unset_avc_status_changed_cb(void)
+{
+       BT_CHECK_AUDIO_SUPPORT();
+       BT_CHECK_INIT_STATUS();
+       BT_CHECK_AUDIO_INIT_STATUS();
+       _bt_unset_cb(BT_EVENT_AUDIO_AVC_STATUS_CHANGED);
+       return BT_ERROR_NONE;
+}
+/* LCOV_EXCL_STOP */
+
 int bt_audio_select_role(bt_audio_role_e role)
 {
        BT_CHECK_AUDIO_SUPPORT();
index 9327d9b..9b22f14 100644 (file)
@@ -220,6 +220,8 @@ static bt_event2index_table_t event2index[] = {
        { BLUETOOTH_EVENT_AVRCP_PLAY_STATUS_CHANGED, BT_EVENT_AVRCP_PLAY_STATUS_CHANGED },
        { BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED, BT_EVENT_AVRCP_TRACK_INFO_CHANGED },
        { BLUETOOTH_EVENT_AVRCP_DELAY_CHANGED, BT_EVENT_AVRCP_DELAY_CHANGED },
+       { BLUETOOTH_EVENT_AVRCP_VOLUME_CHANGED, BT_EVENT_AUDIO_ABSOLUTE_VOLUME_CHANGED },
+       { BLUETOOTH_EVENT_AUDIO_AVC_STATUS, BT_EVENT_AUDIO_AVC_STATUS_CHANGED},
        { BLUETOOTH_HID_CONNECTED, BT_EVENT_HID_CONNECTION_STATUS },
        { BLUETOOTH_HID_DISCONNECTED, BT_EVENT_HID_CONNECTION_STATUS },
        { BLUETOOTH_HID_DEVICE_CONNECTED, BT_EVENT_HID_DEVICE_CONNECTION_STATUS },
@@ -2165,6 +2167,12 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                (_bt_get_error_code(param->result), FALSE, device_addr, BT_AUDIO_PROFILE_TYPE_A2DP_SINK,
                bt_event_slot_container[event_index].user_data);
                break;
+       case BLUETOOTH_EVENT_AUDIO_AVC_STATUS:
+               BT_INFO("BLUETOOTH_EVENT_AUDIO_AVC_STATUS ");
+               bool *avc_activated = (bool *)(param->param_data);
+               ((bt_audio_avc_status_changed_cb)bt_event_slot_container[event_index].callback)
+               (*avc_activated, bt_event_slot_container[event_index].user_data);
+               break;
        case BLUETOOTH_EVENT_AVRCP_CONNECTED:
                BT_INFO("BLUETOOTH_EVENT_AVRCP_CONNECTED ");
                device_addr = (char *)(param->param_data);
@@ -2255,6 +2263,14 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                ((bt_avrcp_delay_changed_cb)bt_event_slot_container[event_index].callback)
                (*delay, bt_event_slot_container[event_index].user_data);
                break;
+       case BLUETOOTH_EVENT_AVRCP_VOLUME_CHANGED:
+               BT_INFO("BLUETOOTH_EVENT_AVRCP_VOLUME_CHANGED ");
+               unsigned int *volume = (unsigned int *)(param->param_data);
+               ((bt_audio_absolute_volume_changed_cb)bt_event_slot_container[event_index].callback)
+               (*volume, bt_event_slot_container[event_index].user_data);
+
+               /* We should handle for avrcp control role in later */
+               break;
        case BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED:
                BT_INFO("BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED ");
                bt_avrcp_metadata_attributes_info_s meta_info = {0, };
index 8268f3b..bf07f8a 100644 (file)
@@ -89,6 +89,8 @@ static int bt_onoff_cnt_fail = 0;
 static int total_time = 0;
 static struct timeval check_time = {0,};
 
+static int absolute_volume = 0;
+
 int service_index;
 int char_service_index;
 
@@ -562,6 +564,20 @@ tc_table_t tc_audio[] = {
                , BT_UNIT_TEST_FUNCTION_A2DP_SOURCE_ROLE},
        {"bt_audio_select_role(sink)"
                , BT_UNIT_TEST_FUNCTION_A2DP_SINK_ROLE},
+       {"bt_audio_set_absolute_volume"
+               , BT_UNIT_TEST_FUNCTION_AUDIO_SET_ABSOLUTE_VOLUME},
+       {"bt_audio_get_absolute_volume"
+               , BT_UNIT_TEST_FUNCTION_AUDIO_GET_ABSOLUTE_VOLUME},
+       {"bt_audio_is_avc_activated"
+               , BT_UNIT_TEST_FUNCTION_AUDIO_IS_AVC_ACTIVATED},
+       {"bt_audio_set_absolute_volume_changed_cb"
+               , BT_UNIT_TEST_FUNCTION_AUDIO_SET_ABSOLUTE_VOLUME_CHANGED_CB},
+       {"bt_audio_unset_absolute_volume_changed_cb"
+               , BT_UNIT_TEST_FUNCTION_AUDIO_UNSET_ABSOLUTE_VOLUME_CHANGED_CB},
+       {"bt_audio_set_avc_status_changed_cb"
+               , BT_UNIT_TEST_FUNCTION_AUDIO_SET_AVC_STATUE_CHANGED_CB},
+       {"bt_audio_unset_avc_status_changed_cb"
+               , BT_UNIT_TEST_FUNCTION_AUDIO_UNSET_AVC_STATUE_CHANGED_CB},
        /* A2DP SCMS-T functions */
        {"Select this menu to set parameters and then select the function again."
                , BT_UNIT_TEST_FUNCTION_ACTIVATE_FLAG_TO_SET_PARAMETERS},
@@ -2130,6 +2146,16 @@ void __bt_audio_connection_state_changed_cb(int result,
        TC_PRT("type [%d]", type);
 }
 
+void __bt_audio_absolute_volume_changed_cb(unsigned int volume, void *user_data)
+{
+       TC_PRT("volume [%d]", volume);
+}
+
+void __bt_audio_avc_status_changed_cb(bool activated, void *user_data)
+{
+       TC_PRT("activated [%d]", activated);
+}
+
 void __bt_ag_sco_state_changed_cb(int result,
                bool opened, void *user_data)
 {
@@ -6179,6 +6205,53 @@ int test_input_callback(void *data)
                        TC_PRT("Asdp Sink set change ret = %d", ret);
                        break;
                }
+               case BT_UNIT_TEST_FUNCTION_AUDIO_SET_ABSOLUTE_VOLUME: {
+                       if (absolute_volume > 150)
+                               absolute_volume = 0;
+
+                       ret = bt_audio_set_absolute_volume(absolute_volume);
+                       TC_PRT("ret = %d", ret);
+
+                       if (ret != BT_ERROR_NONE)
+                               absolute_volume = absolute_volume + 10;
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_AUDIO_GET_ABSOLUTE_VOLUME: {
+                       unsigned int volume = 0;
+                       ret = bt_audio_get_absolute_volume(&volume);
+                       TC_PRT("ret = %d, volume: %d", ret, volume);
+
+                       if (ret != BT_ERROR_NONE)
+                               absolute_volume = volume;
+
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_AUDIO_IS_AVC_ACTIVATED: {
+                       bool activated = false;
+                       ret = bt_audio_is_avc_activated(&activated);
+                       TC_PRT("ret = %d, activated = %d", ret, activated);
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_AUDIO_SET_ABSOLUTE_VOLUME_CHANGED_CB: {
+                       ret = bt_audio_set_absolute_volume_changed_cb(__bt_audio_absolute_volume_changed_cb, NULL);
+                       TC_PRT("ret = %d", ret);
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_AUDIO_UNSET_ABSOLUTE_VOLUME_CHANGED_CB: {
+                       ret = bt_audio_unset_absolute_volume_changed_cb();
+                       TC_PRT("ret = %d", ret);
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_AUDIO_SET_AVC_STATUE_CHANGED_CB: {
+                       ret = bt_audio_set_avc_status_changed_cb(__bt_audio_avc_status_changed_cb, NULL);
+                       TC_PRT("ret = %d", ret);
+                       break;
+               }
+               case BT_UNIT_TEST_FUNCTION_AUDIO_UNSET_AVC_STATUE_CHANGED_CB: {
+                       ret = bt_audio_unset_avc_status_changed_cb();
+                       TC_PRT("ret = %d", ret);
+                       break;
+               }
                default:
                        break;
                }
index e932fbf..76d9ad7 100644 (file)
@@ -211,6 +211,13 @@ typedef enum {
        BT_UNIT_TEST_FUNCTION_AUDIO_DISCONNECT,
        BT_UNIT_TEST_FUNCTION_AUDIO_SINK_CONNECT,
        BT_UNIT_TEST_FUNCTION_AUDIO_SINK_DISCONNECT,
+       BT_UNIT_TEST_FUNCTION_AUDIO_SET_ABSOLUTE_VOLUME,
+       BT_UNIT_TEST_FUNCTION_AUDIO_GET_ABSOLUTE_VOLUME,
+       BT_UNIT_TEST_FUNCTION_AUDIO_IS_AVC_ACTIVATED,
+       BT_UNIT_TEST_FUNCTION_AUDIO_SET_ABSOLUTE_VOLUME_CHANGED_CB,
+       BT_UNIT_TEST_FUNCTION_AUDIO_UNSET_ABSOLUTE_VOLUME_CHANGED_CB,
+       BT_UNIT_TEST_FUNCTION_AUDIO_SET_AVC_STATUE_CHANGED_CB,
+       BT_UNIT_TEST_FUNCTION_AUDIO_UNSET_AVC_STATUE_CHANGED_CB,
        BT_UNIT_TEST_FUNCTION_AUDIO_SET_CONNECTION_STATE_CHANGED_CB,
        BT_UNIT_TEST_FUNCTION_AUDIO_UNSET_CONNECTION_STATE_CHANGED_CB,
        BT_UNIT_TEST_FUNCTION_AG_OPEN_SCO,