Android蓝牙绝对音量问题

问题Android连接蓝牙设备调节音量会出现乱变的问题

原因是由于上层判断出支持绝对音量设置,会调用绝对音量的设置,有些蓝牙设备设置绝对音量出问题导致的异常。
解决办法设置黑名单让一些设备不支持绝对音量的设置。
external/bluetooth/bluedroid/btif/src/btif_rc.c

/***************************************************************************
**
** Function         set_volume
**
** Description      Send current volume setting to remote side.
**                  Support limited to SetAbsoluteVolume
**                  This can be enhanced to support Relative Volume (AVRCP 1.0).
**                  With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN
**                  as opposed to absolute volume level
** volume: Should be in the range 0-127. bit7 is reseved and cannot be set
**
** Returns          bt_status_t
**
***************************************************************************/
static bt_status_t set_volume(uint8_t volume)
{
    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
    CHECK_RC_CONNECTED
    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
    rc_transaction_t *p_transaction=NULL;
    if(btif_rc_cb.rc_volume==volume)
    {
        status=BT_STATUS_DONE;
        BTIF_TRACE_ERROR2("%s: volume value already set earlier: 0x%02x",__FUNCTION__, volume);
        return status;
    }

    if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) &&
        (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL))
    {
        tAVRC_COMMAND avrc_cmd = {0};
        BT_HDR *p_msg = NULL;

        BTIF_TRACE_ERROR2("%s: Peer supports absolute volume. newVolume=%d", __FUNCTION__, volume);

黑名单设置

static const UINT8 rc_black_addr_prefix[][3] = {
    {0x0, 0x18, 0x6B}, // LG HBS-730
    {0x0, 0x26, 0x7E}  // VW Passat
};

static const UINT8 rc_white_addr_prefix[][3] = {
    {0x94, 0xCE, 0x2C}, // Sony SBH50
    {0x30, 0x17, 0xC8}  // Sony wm600
};

static BOOLEAN dev_blacklisted_for_absolute_volume(BD_ADDR peer_dev)
{
    int i;
    int whitelist_size = sizeof(rc_white_addr_prefix)/sizeof(rc_white_addr_prefix[0]);
    for (i = 0; i < whitelist_size; i++) {
        if (rc_white_addr_prefix[i][0] == peer_dev[0] &&
            rc_white_addr_prefix[i][1] == peer_dev[1] &&
            rc_white_addr_prefix[i][2] == peer_dev[2]) {
            BTIF_TRACE_DEBUG3("whitelist absolute volume for %02x:%02x:%02x",
                                peer_dev[0], peer_dev[1], peer_dev[2]);
            return FALSE;
        }
    }
    BTIF_TRACE_WARNING3("blacklist absolute volume for %02x:%02x:%02x",
                        peer_dev[0], peer_dev[1], peer_dev[2]);
    return TRUE;
} 
void handle_rc_features()
{
    btrc_remote_features_t rc_features = BTRC_FEAT_NONE;
    bt_bdaddr_t rc_addr;
    bdcpy(rc_addr.address, btif_rc_cb.rc_addr);

    if (dev_blacklisted_for_absolute_volume(btif_rc_cb.rc_addr))
    {
    	//不支持绝对音量设置
        btif_rc_cb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
    }

    if (btif_rc_cb.rc_features & BTA_AV_FEAT_BROWSE)
    {
        rc_features |= BTRC_FEAT_BROWSE;
    }
    if ( (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL) &&
         (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG))
    { 
        rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
    }
    if (btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA)
    { 
        rc_features |= BTRC_FEAT_METADATA;
    }
...
}

frameworks/base/media/java/android/media/AudioSerivce.java

        public void applyDeviceVolume(int device) {
            int index;
            if (isMuted()) {
                index = 0;
            } else if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&
                       mAvrcpAbsVolSupported) {   //mAvrcpAbsVolSupported 是底层返回是否支持绝对音量设置
                index = (mIndexMax + 5)/10;
            } else {
                index = (getIndex(device) + 5)/10;
            }
            AudioSystem.setStreamVolumeIndex(mStreamType, index, device);
        }

你可能感兴趣的:(HAL)