Implement set / get volume logic from transport 39/225239/5
authorDoHyun Pyun <dh79.pyun@samsung.com>
Tue, 18 Feb 2020 09:21:04 +0000 (18:21 +0900)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Wed, 19 Feb 2020 02:25:19 +0000 (11:25 +0900)
Change-Id: I7b801240e57f715186737fe7aea89f1be4ce5029
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
13 files changed:
bt-oal/bluez_hal/CMakeLists.txt
bt-oal/bluez_hal/src/bt-hal-avrcp-ctrl-dbus-handler.c
bt-oal/bluez_hal/src/bt-hal-avrcp-ctrl-dbus-handler.h
bt-oal/bluez_hal/src/bt-hal-avrcp-ctrl.c
bt-oal/bluez_hal/src/bt-hal-avrcp-tg.c
bt-oal/bluez_hal/src/bt-hal-avrcp-transport-dbus-handler.c [new file with mode: 0644]
bt-oal/bluez_hal/src/bt-hal-avrcp-transport-dbus-handler.h [new file with mode: 0644]
bt-oal/hardware/bt_rc.h
bt-oal/include/oal-avrcp-tg.h
bt-oal/oal-avrcp-tg.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-avrcp-tg.h

index 07cbebb..b08dba3 100644 (file)
@@ -22,6 +22,7 @@ SET(SRCS
 ./src/bt-hal-avrcp-tg-dbus-handler.c
 ./src/bt-hal-avrcp-ctrl.c
 ./src/bt-hal-avrcp-ctrl-dbus-handler.c
+./src/bt-hal-avrcp-transport-dbus-handler.c
 ./src/bt-hal-hf.c
 ./src/bt-hal-hf-dbus-handler.c
 ./src/bt-hal-hid-dbus-handler.c
index 4c09266..32cff46 100644 (file)
@@ -347,22 +347,6 @@ static const char *__bt_media_type_to_str(int type)
        return NULL;
 }
 
-#if 0
-static const char *__bt_transport_type_to_str(int type)
-{
-       switch (type) {
-       case BTRC_TRANSPORT_ATTR_DELAY:
-               return "Delay";
-       case BTRC_TRANSPORT_ATTR_VOLUME:
-               return "Volume";
-       default:
-               return NULL;
-       }
-
-       return NULL;
-}
-#endif
-
 bt_status_t _bt_hal_dbus_handler_avrcp_ctrl_set_property(bt_bdaddr_t *bd_addr, uint8_t type, uint8_t value)
 {
        GVariant *reply, *param = NULL;
@@ -422,54 +406,3 @@ bt_status_t _bt_hal_dbus_handler_avrcp_ctrl_set_property(bt_bdaddr_t *bd_addr, u
        return BT_STATUS_SUCCESS;
 }
 
-bt_status_t _bt_hal_dbus_handler_avrcp_transport_set_property(bt_bdaddr_t *bd_addr, int type, unsigned int value)
-{
-       GVariant *reply, *param = NULL;
-       GError *err = NULL;
-       GDBusProxy *proxy = NULL;
-       uint16_t property_level = (uint16_t)value;
-
-       DBG("+");
-       switch (type) {
-       case BTRC_TRANSPORT_ATTR_DELAY:
-               param = g_variant_new("q", property_level);
-               INFO("delay level %d", property_level);
-               break;
-       case BTRC_TRANSPORT_ATTR_VOLUME:
-               param = g_variant_new("q", property_level);
-               INFO("volume level %d", property_level);
-               break;
-       default:
-               ERR("Invalid property type: %d", type);
-               return BT_STATUS_FAIL;
-       }
-
-       proxy = _bt_hal_get_avrcp_transport_properties_proxy(bd_addr);
-       if (proxy == NULL) {
-               ERR("Unable to allocate new proxy \n");
-               if (err) {
-                       ERR("%s", err->message);
-                       g_clear_error(&err);
-               }
-               return BT_STATUS_FAIL;
-       }
-
-       reply = g_dbus_proxy_call_sync(proxy,
-                       "Set", g_variant_new("(ssv)",
-                               BT_HAL_MEDIATRANSPORT_INTERFACE,
-                               __bt_media_type_to_str(type), param),
-                       G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
-       g_object_unref(proxy);
-       if (!reply) {
-               ERR("Can't get managed objects");
-               if (err) {
-                       ERR("SetProperty Fail: %s", err->message);
-                       g_clear_error(&err);
-                       return BT_STATUS_FAIL;
-               }
-       }
-
-       g_variant_unref(reply);
-       DBG("-");
-       return BT_STATUS_SUCCESS;
-}
index d52eba5..6a2f408 100644 (file)
@@ -103,8 +103,6 @@ bt_status_t _bt_hal_dbus_handler_avrcp_ctrl_cmd(bt_bdaddr_t *bd_addr, uint8_t ke
 
 bt_status_t _bt_hal_dbus_handler_avrcp_ctrl_set_property(bt_bdaddr_t *bd_addr, uint8_t type, uint8_t value);
 
-bt_status_t _bt_hal_dbus_handler_avrcp_transport_set_property(bt_bdaddr_t *bd_addr, int type, unsigned int value);
-
 int _bt_media_attr_to_type(const char *str);
 
 int _bt_media_attrval_to_val(int type, const char *value);
index 8bef230..c654ca1 100644 (file)
@@ -31,6 +31,7 @@
 #include "bt-hal-msg.h"
 #include "bt-hal-utils.h"
 #include "bt-hal-avrcp-ctrl-dbus-handler.h"
+#include "bt-hal-avrcp-transport-dbus-handler.h"
 
 #define AVRC_MAX_NUM_MEDIA_ATTR_ID               7
 
index ce19459..ce46fb4 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "bt-hal-event-receiver.h"
 #include "bt-hal-avrcp-tg-dbus-handler.h"
+#include "bt-hal-avrcp-transport-dbus-handler.h"
 
 static const btrc_callbacks_t *bt_hal_avrcp_tg_cbacks;
 
@@ -133,9 +134,22 @@ bt_status_t register_notification_rsp(btrc_event_id_t event_id,
        return BT_STATUS_SUCCESS;
 }
 
-bt_status_t set_volume(uint8_t volume)
+bt_status_t set_volume(bt_bdaddr_t *bd_addr, uint32_t volume)
 {
-       return BT_STATUS_UNSUPPORTED;
+       int ret = BT_STATUS_SUCCESS;
+
+       ret = _bt_hal_dbus_handler_avrcp_transport_set_property(bd_addr, BTRC_TRANSPORT_ATTR_VOLUME, volume);
+
+       return ret;
+}
+
+bt_status_t get_volume(bt_bdaddr_t *bd_addr, uint32_t *volume)
+{
+       int ret = BT_STATUS_SUCCESS;
+
+       ret = _bt_hal_dbus_handler_avrcp_transport_get_property(bd_addr, BTRC_TRANSPORT_ATTR_VOLUME, volume);
+
+       return ret;
 }
 
 bt_status_t set_addressed_player_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status)
@@ -368,6 +382,7 @@ static btrc_interface_t avrcp_tg_if = {
        .set_player_app_value_rsp = set_player_app_value_rsp,
        .register_notification_rsp = register_notification_rsp,
        .set_volume = set_volume,
+       .get_volume = get_volume,
        .set_addressed_player_rsp = set_addressed_player_rsp,
        .set_browsed_player_rsp = set_browsed_player_rsp,
        .get_folder_items_list_rsp = get_folder_items_list_rsp,
diff --git a/bt-oal/bluez_hal/src/bt-hal-avrcp-transport-dbus-handler.c b/bt-oal/bluez_hal/src/bt-hal-avrcp-transport-dbus-handler.c
new file mode 100644 (file)
index 0000000..09f0e20
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ *
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Nilesh Trimbake <t.shripati@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <dlog.h>
+#include <vconf.h>
+
+#include "bt-hal-avrcp-transport-dbus-handler.h"
+#include "bt-hal-dbus-common-utils.h"
+#include "bt-hal-internal.h"
+
+static const char *__bt_transport_type_to_str(int type)
+{
+       switch (type) {
+       case BTRC_TRANSPORT_ATTR_DELAY:
+               return "Delay";
+       case BTRC_TRANSPORT_ATTR_VOLUME:
+               return "Volume";
+       default:
+               return NULL;
+       }
+
+       return NULL;
+}
+
+bt_status_t _bt_hal_dbus_handler_avrcp_transport_get_property(bt_bdaddr_t *bd_addr, int type, unsigned int *value)
+{
+       GDBusProxy *proxy = NULL;
+       GError *err = NULL;
+       GVariant *reply = NULL;
+       GVariant *temp = NULL;
+
+       proxy = _bt_hal_get_avrcp_transport_properties_proxy(bd_addr);
+       if (proxy == NULL) {
+               ERR("Unable to get proxy \n");
+               return BT_STATUS_FAIL;
+       }
+
+       reply = g_dbus_proxy_call_sync(proxy,
+                                       "Get", g_variant_new("(ss)", BT_HAL_MEDIATRANSPORT_INTERFACE,
+                                       __bt_transport_type_to_str(type)),
+                                       G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
+
+       g_object_unref(proxy);
+
+       if (!reply) {
+               ERR("Can't get managed objects");
+               if (err) {
+                       ERR("%s", err->message);
+                       g_clear_error(&err);
+               }
+               return BT_STATUS_FAIL;
+       }
+
+       g_variant_get(reply, "(v)", &temp);
+       *value = g_variant_get_uint16(temp);
+       g_variant_unref(temp);
+
+       DBG("Type[%s] and Value[%d]", __bt_transport_type_to_str(type), *value);
+
+       g_variant_unref(reply);
+       return BT_STATUS_SUCCESS;
+}
+
+
+bt_status_t _bt_hal_dbus_handler_avrcp_transport_set_property(bt_bdaddr_t *bd_addr, int type, unsigned int value)
+{
+       GVariant *reply, *param = NULL;
+       GError *err = NULL;
+       GDBusProxy *proxy = NULL;
+       uint16_t property_level = (uint16_t)value;
+
+       switch (type) {
+       case BTRC_TRANSPORT_ATTR_DELAY:
+               param = g_variant_new("q", property_level);
+               INFO("delay level %d", property_level);
+               break;
+       case BTRC_TRANSPORT_ATTR_VOLUME:
+               param = g_variant_new("q", property_level);
+               INFO("volume level %d", property_level);
+               break;
+       default:
+               ERR("Invalid property type: %d", type);
+               return BT_STATUS_FAIL;
+       }
+
+       proxy = _bt_hal_get_avrcp_transport_properties_proxy(bd_addr);
+       if (proxy == NULL) {
+               ERR("Unable to get proxy \n");
+               return BT_STATUS_FAIL;
+       }
+
+       reply = g_dbus_proxy_call_sync(proxy,
+                       "Set", g_variant_new("(ssv)",
+                               BT_HAL_MEDIATRANSPORT_INTERFACE,
+                               __bt_transport_type_to_str(type), param),
+                       G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
+       g_object_unref(proxy);
+       if (!reply) {
+               ERR("Can't get managed objects");
+               if (err) {
+                       ERR("SetProperty Fail: %s", err->message);
+                       g_clear_error(&err);
+                       return BT_STATUS_FAIL;
+               }
+       }
+
+       g_variant_unref(reply);
+
+       return BT_STATUS_SUCCESS;
+}
diff --git a/bt-oal/bluez_hal/src/bt-hal-avrcp-transport-dbus-handler.h b/bt-oal/bluez_hal/src/bt-hal-avrcp-transport-dbus-handler.h
new file mode 100644 (file)
index 0000000..4a64817
--- /dev/null
@@ -0,0 +1,45 @@
+/* Bluetooth-frwk
+ *
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Nilesh Trimbake <t.shripati@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef _BT_HAL_AVRCP_TRANSPORT_DBUS_HANDLER_H_
+#define _BT_HAL_AVRCP_TRANSPORT_DBUS_HANDLER_H_
+
+#include <glib.h>
+#include <sys/types.h>
+
+#include "bt-hal.h"
+#include "bt-hal-log.h"
+#include "bt-hal-msg.h"
+
+#include "bt-hal-event-receiver.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bt_status_t _bt_hal_dbus_handler_avrcp_transport_get_property(bt_bdaddr_t *bd_addr, int type, unsigned int *value);
+
+bt_status_t _bt_hal_dbus_handler_avrcp_transport_set_property(bt_bdaddr_t *bd_addr, int type, unsigned int value);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _BT_HAL_AVRCP_TRANSPORT_DBUS_HANDLER_H_*/
index 6c38d02..006aa91 100644 (file)
@@ -501,7 +501,9 @@ typedef struct {
         ** With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN opposed to absolute volume level
         ** volume: Should be in the range 0-127. bit7 is reseved and cannot be set
         */
-       bt_status_t (*set_volume)(uint8_t volume);
+       bt_status_t (*set_volume)(bt_bdaddr_t *bd_addr, uint32_t volume);
+
+       bt_status_t (*get_volume)(bt_bdaddr_t *bd_addr, uint32_t *volume);
 
        /* Set addressed player response from TG to CT */
        bt_status_t (*set_addressed_player_rsp)(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status);
index 6b78cd8..b9621a9 100644 (file)
@@ -227,6 +227,31 @@ oal_status_t avrcp_set_property(int type, unsigned int value);
  */
 oal_status_t avrcp_set_track_info(oal_media_metadata_attributes_t *meta_data);
 
+/**
+ * @brief Set the transport volue of remote device
+ *
+ * @return OAL_STATUS_SUCCESS on success, otherwise a non-zero error value.
+ * @retval #OAL_STATUS_SUCCESS Successful
+ *
+ * @pre AVRCP should be enabled with avrcp_enable().
+ *
+ * @see  avrcp_enable()
+ */
+oal_status_t avrcp_tg_set_volume(bt_address_t *rem_addr, unsigned int volume);
+
+/**
+ * @brief Get the transport volue of remote device
+ *
+ * @return OAL_STATUS_SUCCESS on success, otherwise a non-zero error value.
+ * @retval #OAL_STATUS_SUCCESS Successful
+ *
+ * @pre AVRCP should be enabled with avrcp_enable().
+ *
+ * @see  avrcp_enable()
+ */
+oal_status_t avrcp_tg_get_volume(bt_address_t *rem_addr, unsigned int *volume);
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index c7ac558..f9c3875 100644 (file)
@@ -506,6 +506,61 @@ oal_status_t avrcp_set_property(int type, unsigned int value)
        return OAL_STATUS_SUCCESS;
 }
 
+oal_status_t avrcp_tg_set_volume(bt_address_t *rem_addr, unsigned int volume)
+{
+       int result = OAL_STATUS_SUCCESS;
+       bt_status_t status;
+       bdstr_t bdstr;
+
+       API_TRACE();
+
+       CHECK_OAL_AVRCP_ENABLED();
+       OAL_CHECK_PARAMETER(rem_addr, return);
+
+       BT_INFO("BT Audio Address: %s", bdt_bd2str(rem_addr, &bdstr));
+
+#ifdef TIZEN_BT_HAL
+       status = avrcp_api->set_volume((bt_bdaddr_t *)rem_addr, volume);
+       if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
+               BT_ERR("set volume failed, err: %s", status2string(status));;
+               result = convert_to_oal_status(status);
+       }
+#else
+       BT_INFO("Not Supported");
+       result = OAL_STATUS_NOT_SUPPORT;
+#endif
+
+       return result;
+}
+
+oal_status_t avrcp_tg_get_volume(bt_address_t *rem_addr, unsigned int *volume)
+{
+       int result = OAL_STATUS_SUCCESS;
+       bt_status_t status;
+       bdstr_t bdstr;
+
+       API_TRACE();
+
+       CHECK_OAL_AVRCP_ENABLED();
+       OAL_CHECK_PARAMETER(rem_addr, return);
+
+       BT_INFO("BT Audio Address: %s", bdt_bd2str(rem_addr, &bdstr));
+
+#ifdef TIZEN_BT_HAL
+       status = avrcp_api->get_volume((bt_bdaddr_t *)rem_addr, volume);
+       if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
+               BT_ERR("set volume failed, err: %s", status2string(status));;
+               result = convert_to_oal_status(status);
+       }
+#else
+       BT_INFO("Not Supported");
+       result = OAL_STATUS_NOT_SUPPORT;
+#endif
+
+       return result;
+}
+
+
 #ifdef TIZEN_BT_HAL
 static void cb_connection_state(bt_bdaddr_t* bd_addr, btrc_connection_state_t state)
 {
index 5e2c064..656bcbc 100644 (file)
@@ -304,6 +304,38 @@ int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data)
        return BLUETOOTH_ERROR_NONE;
 }
 
+int _bt_avrcp_target_notify_volume(bluetooth_device_address_t *address, unsigned int volume)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_address_t bdaddr;
+
+       memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
+
+       result = avrcp_tg_set_volume(&bdaddr, volume);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("hid_connect error: [%d]", result);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_avrcp_target_get_volume(bluetooth_device_address_t *address, unsigned int *volume)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_address_t bdaddr;
+
+       memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
+
+       result = avrcp_tg_get_volume(&bdaddr, volume);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("hid_connect error: [%d]", result);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
 int _bt_avrcp_set_properties(media_player_settings_t *properties)
 {
        int ret;
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 */
 
index e5e1ad6..9ad8239 100755 (executable)
@@ -58,6 +58,10 @@ int _bt_avrcp_disconnect_remote_ctrl(bluetooth_device_address_t *address);
 
 int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data);
 
+int _bt_avrcp_target_notify_volume(bluetooth_device_address_t *address, unsigned int volume);
+
+int _bt_avrcp_target_get_volume(bluetooth_device_address_t *address, unsigned int *volume);
+
 int _bt_avrcp_set_properties(media_player_settings_t *properties);
 
 int _bt_avrcp_set_property(int type, unsigned int value);