Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2017 Google, Inc.
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 #define LOG_TAG "btif_a2dp_audio_interface"
     20 
     21 #include "btif_a2dp_audio_interface.h"
     22 #include <a2dp_vendor.h>
     23 #include <a2dp_vendor_ldac_constants.h>
     24 #include <android/hardware/bluetooth/a2dp/1.0/IBluetoothAudioHost.h>
     25 #include <android/hardware/bluetooth/a2dp/1.0/IBluetoothAudioOffload.h>
     26 #include <android/hardware/bluetooth/a2dp/1.0/types.h>
     27 #include <base/logging.h>
     28 #include <hwbinder/ProcessState.h>
     29 #include <utils/RefBase.h>
     30 #include "a2dp_sbc.h"
     31 #include "bt_common.h"
     32 #include "bta/av/bta_av_int.h"
     33 #include "btif_a2dp.h"
     34 #include "btif_a2dp_control.h"
     35 #include "btif_a2dp_sink.h"
     36 #include "btif_a2dp_source.h"
     37 #include "btif_av.h"
     38 #include "btif_av_co.h"
     39 #include "btif_hf.h"
     40 #include "osi/include/osi.h"
     41 
     42 using android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioOffload;
     43 using android::hardware::bluetooth::a2dp::V1_0::IBluetoothAudioHost;
     44 using android::hardware::bluetooth::a2dp::V1_0::Status;
     45 using android::hardware::bluetooth::a2dp::V1_0::CodecConfiguration;
     46 using android::hardware::bluetooth::a2dp::V1_0::CodecType;
     47 using android::hardware::bluetooth::a2dp::V1_0::SampleRate;
     48 using android::hardware::bluetooth::a2dp::V1_0::BitsPerSample;
     49 using android::hardware::bluetooth::a2dp::V1_0::ChannelMode;
     50 using android::hardware::ProcessState;
     51 using ::android::hardware::Return;
     52 using ::android::hardware::Void;
     53 using ::android::hardware::hidl_vec;
     54 using ::android::sp;
     55 android::sp<IBluetoothAudioOffload> btAudio;
     56 
     57 #define CASE_RETURN_STR(const) \
     58   case const:                  \
     59     return #const;
     60 static uint8_t a2dp_cmd_pending = A2DP_CTRL_CMD_NONE;
     61 static Status mapToStatus(uint8_t resp);
     62 uint8_t btif_a2dp_audio_process_request(uint8_t cmd);
     63 
     64 static void btif_a2dp_audio_send_start_req();
     65 static void btif_a2dp_audio_send_suspend_req();
     66 static void btif_a2dp_audio_interface_init();
     67 static void btif_a2dp_audio_interface_deinit();
     68 // Delay reporting
     69 // static void btif_a2dp_audio_send_sink_latency();
     70 
     71 class BluetoothAudioHost : public IBluetoothAudioHost {
     72  public:
     73   Return<void> startStream() {
     74     btif_a2dp_audio_send_start_req();
     75     return Void();
     76   }
     77   Return<void> suspendStream() {
     78     btif_a2dp_audio_send_suspend_req();
     79     return Void();
     80   }
     81   Return<void> stopStream() {
     82     btif_a2dp_audio_process_request(A2DP_CTRL_CMD_STOP);
     83     return Void();
     84   }
     85 
     86   // TODO : Delay reporting
     87   /*    Return<void> a2dp_get_sink_latency() {
     88           LOG_INFO(LOG_TAG,"%s:start ", __func__);
     89           btif_a2dp_audio_send_sink_latency();
     90           return Void();
     91       }*/
     92 };
     93 
     94 static Status mapToStatus(uint8_t resp) {
     95   switch (resp) {
     96     case A2DP_CTRL_ACK_SUCCESS:
     97       return Status::SUCCESS;
     98       break;
     99     case A2DP_CTRL_ACK_PENDING:
    100       return Status::PENDING;
    101       break;
    102     case A2DP_CTRL_ACK_FAILURE:
    103     case A2DP_CTRL_ACK_INCALL_FAILURE:
    104     case A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS:
    105       return Status::FAILURE;
    106     default:
    107       APPL_TRACE_WARNING("%s: unknown status recevied :%d", __func__, resp);
    108       return Status::FAILURE;
    109       break;
    110   }
    111 }
    112 
    113 static void btif_a2dp_get_codec_configuration(
    114     CodecConfiguration* p_codec_info) {
    115   LOG_INFO(LOG_TAG, "%s", __func__);
    116   tBT_A2DP_OFFLOAD a2dp_offload;
    117   A2dpCodecConfig* a2dpCodecConfig = bta_av_get_a2dp_current_codec();
    118   a2dpCodecConfig->getCodecSpecificConfig(&a2dp_offload);
    119   btav_a2dp_codec_config_t codec_config;
    120   codec_config = a2dpCodecConfig->getCodecConfig();
    121   switch (codec_config.codec_type) {
    122     case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
    123       p_codec_info->codecType =
    124           (::android::hardware::bluetooth::a2dp::V1_0::CodecType)
    125               BTA_AV_CODEC_TYPE_SBC;
    126       p_codec_info->codecSpecific.sbcData.codecParameters =
    127           a2dp_offload.codec_info[0];
    128       LOG_INFO(LOG_TAG, " %s: codec parameters =%d", __func__,
    129                a2dp_offload.codec_info[0]);
    130       p_codec_info->codecSpecific.sbcData.minBitpool =
    131           a2dp_offload.codec_info[1];
    132       p_codec_info->codecSpecific.sbcData.maxBitpool =
    133           a2dp_offload.codec_info[2];
    134       break;
    135     case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
    136       p_codec_info->codecType =
    137           (::android::hardware::bluetooth::a2dp::V1_0::CodecType)
    138               BTA_AV_CODEC_TYPE_AAC;
    139       break;
    140     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
    141       p_codec_info->codecType =
    142           (::android::hardware::bluetooth::a2dp::V1_0::CodecType)
    143               BTA_AV_CODEC_TYPE_APTX;
    144       break;
    145     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
    146       p_codec_info->codecType =
    147           (::android::hardware::bluetooth::a2dp::V1_0::CodecType)
    148               BTA_AV_CODEC_TYPE_APTXHD;
    149       break;
    150     case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
    151       p_codec_info->codecType =
    152           (::android::hardware::bluetooth::a2dp::V1_0::CodecType)
    153               BTA_AV_CODEC_TYPE_LDAC;
    154       p_codec_info->codecSpecific.ldacData.bitrateIndex =
    155           a2dp_offload.codec_info[6];
    156       break;
    157     default:
    158       APPL_TRACE_ERROR("%s: Unknown Codec type :%d ", __func__,
    159                        codec_config.codec_type);
    160   }
    161 
    162   // Obtain the MTU
    163   RawAddress peer_addr = btif_av_source_active_peer();
    164   tA2DP_ENCODER_INIT_PEER_PARAMS peer_param;
    165   bta_av_co_get_peer_params(peer_addr, &peer_param);
    166   int effectiveMtu = a2dpCodecConfig->getEffectiveMtu();
    167   if (effectiveMtu > 0 && effectiveMtu < peer_param.peer_mtu) {
    168     p_codec_info->peerMtu = effectiveMtu;
    169   } else {
    170     p_codec_info->peerMtu = peer_param.peer_mtu;
    171   }
    172   LOG_INFO(LOG_TAG, "%s: peer MTU: %d effective MTU: %d result MTU: %d",
    173            __func__, peer_param.peer_mtu, effectiveMtu, p_codec_info->peerMtu);
    174 
    175   p_codec_info->sampleRate =
    176       (::android::hardware::bluetooth::a2dp::V1_0::SampleRate)
    177           codec_config.sample_rate;
    178   p_codec_info->bitsPerSample =
    179       (::android::hardware::bluetooth::a2dp::V1_0::BitsPerSample)
    180           codec_config.bits_per_sample;
    181   p_codec_info->channelMode =
    182       (::android::hardware::bluetooth::a2dp::V1_0::ChannelMode)
    183           codec_config.channel_mode;
    184   p_codec_info->encodedAudioBitrate = a2dpCodecConfig->getTrackBitRate();
    185 }
    186 
    187 static void btif_a2dp_audio_interface_init() {
    188   LOG_INFO(LOG_TAG, "%s", __func__);
    189 
    190   btAudio = IBluetoothAudioOffload::getService();
    191   CHECK(btAudio != nullptr);
    192 
    193   LOG_DEBUG(
    194       LOG_TAG, "%s: IBluetoothAudioOffload::getService() returned %p (%s)",
    195       __func__, btAudio.get(), (btAudio->isRemote() ? "remote" : "local"));
    196 
    197   LOG_INFO(LOG_TAG, "%s:Init returned", __func__);
    198 }
    199 
    200 static void btif_a2dp_audio_interface_deinit() {
    201   LOG_INFO(LOG_TAG, "%s: start", __func__);
    202   btAudio = nullptr;
    203 }
    204 
    205 void btif_a2dp_audio_interface_start_session() {
    206   LOG_INFO(LOG_TAG, "%s", __func__);
    207   btif_a2dp_audio_interface_init();
    208   CHECK(btAudio != nullptr);
    209   CodecConfiguration codec_info;
    210   btif_a2dp_get_codec_configuration(&codec_info);
    211   android::sp<IBluetoothAudioHost> host_if = new BluetoothAudioHost();
    212   btAudio->startSession(host_if, codec_info);
    213 }
    214 
    215 void btif_a2dp_audio_interface_end_session() {
    216   LOG_INFO(LOG_TAG, "%s", __func__);
    217   if (btAudio == nullptr) return;
    218   auto ret = btAudio->endSession();
    219   if (!ret.isOk()) {
    220     LOG_ERROR(LOG_TAG, "HAL server is dead");
    221   }
    222   btif_a2dp_audio_interface_deinit();
    223 }
    224 
    225 void btif_a2dp_audio_on_started(tBTA_AV_STATUS status) {
    226   LOG_INFO(LOG_TAG, "%s: status = %d", __func__, status);
    227   if (btAudio != nullptr) {
    228     if (a2dp_cmd_pending == A2DP_CTRL_CMD_START) {
    229       LOG_INFO(LOG_TAG, "%s: calling method onStarted", __func__);
    230       btAudio->streamStarted(mapToStatus(status));
    231     }
    232   }
    233 }
    234 
    235 void btif_a2dp_audio_on_suspended(tBTA_AV_STATUS status) {
    236   LOG_INFO(LOG_TAG, "%s: status = %d", __func__, status);
    237   if (btAudio != nullptr) {
    238     if (a2dp_cmd_pending == A2DP_CTRL_CMD_SUSPEND) {
    239       LOG_INFO(LOG_TAG, "calling method onSuspended");
    240       btAudio->streamSuspended(mapToStatus(status));
    241     }
    242   }
    243 }
    244 
    245 void btif_a2dp_audio_on_stopped(tBTA_AV_STATUS status) {
    246   LOG_INFO(LOG_TAG, "%s: status = %d", __func__, status);
    247   if (btAudio != nullptr && a2dp_cmd_pending == A2DP_CTRL_CMD_START) {
    248     LOG_INFO(LOG_TAG, "%s: Remote disconnected when start under progress",
    249              __func__);
    250     btAudio->streamStarted(mapToStatus(A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS));
    251   }
    252 }
    253 void btif_a2dp_audio_send_start_req() {
    254   LOG_INFO(LOG_TAG, "%s", __func__);
    255   uint8_t resp;
    256   resp = btif_a2dp_audio_process_request(A2DP_CTRL_CMD_START);
    257   if (btAudio != nullptr) {
    258     auto ret = btAudio->streamStarted(mapToStatus(resp));
    259     if (!ret.isOk()) LOG_ERROR(LOG_TAG, "HAL server died");
    260   }
    261 }
    262 void btif_a2dp_audio_send_suspend_req() {
    263   LOG_INFO(LOG_TAG, "%s", __func__);
    264   uint8_t resp;
    265   resp = btif_a2dp_audio_process_request(A2DP_CTRL_CMD_SUSPEND);
    266   if (btAudio != nullptr) {
    267     auto ret = btAudio->streamSuspended(mapToStatus(resp));
    268     if (!ret.isOk()) LOG_ERROR(LOG_TAG, "HAL server died");
    269   }
    270 }
    271 /*void btif_a2dp_audio_send_sink_latency()
    272 {
    273   LOG_INFO(LOG_TAG, "%s", __func__);
    274   uint16_t sink_latency = btif_av_get_sink_latency();
    275   if (btAudio != nullptr) {
    276     auto ret = btAudio->a2dp_on_get_sink_latency(sink_latency);
    277     if (!ret.isOk()) LOG_ERROR(LOG_TAG, "server died");
    278   }
    279 }*/
    280 
    281 uint8_t btif_a2dp_audio_process_request(uint8_t cmd) {
    282   LOG_INFO(LOG_TAG, "%s: cmd: %s", __func__,
    283            audio_a2dp_hw_dump_ctrl_event((tA2DP_CTRL_CMD)cmd));
    284   a2dp_cmd_pending = cmd;
    285   uint8_t status;
    286   switch (cmd) {
    287     case A2DP_CTRL_CMD_START:
    288       /*
    289        * Don't send START request to stack while we are in a call.
    290        * Some headsets such as "Sony MW600", don't allow AVDTP START
    291        * while in a call, and respond with BAD_STATE.
    292        */
    293       if (!bluetooth::headset::IsCallIdle()) {
    294         APPL_TRACE_WARNING("%s: A2DP command %s failed as call state is busy",
    295                            __func__,
    296                            audio_a2dp_hw_dump_ctrl_event((tA2DP_CTRL_CMD)cmd));
    297         status = A2DP_CTRL_ACK_INCALL_FAILURE;
    298         break;
    299       }
    300       if (btif_av_stream_started_ready()) {
    301         /*
    302          * Already started, setup audio data channel listener and ACK
    303          * back immediately.
    304          */
    305         status = A2DP_CTRL_ACK_SUCCESS;
    306         break;
    307       }
    308       if (btif_av_stream_ready()) {
    309         /*
    310          * Post start event and wait for audio path to open.
    311          * If we are the source, the ACK will be sent after the start
    312          * procedure is completed, othewise send it now.
    313          */
    314         btif_av_stream_start();
    315         if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
    316           status = A2DP_CTRL_ACK_SUCCESS;
    317           break;
    318         }
    319         /*Return pending and ack when start stream cfm received from remote*/
    320         status = A2DP_CTRL_ACK_PENDING;
    321         break;
    322       }
    323 
    324       APPL_TRACE_WARNING("%s: A2DP command %s while AV stream is not ready",
    325                          __func__,
    326                          audio_a2dp_hw_dump_ctrl_event((tA2DP_CTRL_CMD)cmd));
    327       return A2DP_CTRL_ACK_FAILURE;
    328       break;
    329 
    330     case A2DP_CTRL_CMD_STOP:
    331       if (btif_av_get_peer_sep() == AVDT_TSEP_SNK &&
    332           !btif_a2dp_source_is_streaming()) {
    333         /* We are already stopped, just ack back */
    334         status = A2DP_CTRL_ACK_SUCCESS;
    335         break;
    336       }
    337       btif_av_stream_stop(RawAddress::kEmpty);
    338       return A2DP_CTRL_ACK_SUCCESS;
    339       break;
    340 
    341     case A2DP_CTRL_CMD_SUSPEND:
    342       /* Local suspend */
    343       if (btif_av_stream_started_ready()) {
    344         btif_av_stream_suspend();
    345         status = A2DP_CTRL_ACK_PENDING;
    346         break;
    347       }
    348       /* If we are not in started state, just ack back ok and let
    349        * audioflinger close the channel. This can happen if we are
    350        * remotely suspended, clear REMOTE SUSPEND flag.
    351        */
    352       btif_av_clear_remote_suspend_flag();
    353       status = A2DP_CTRL_ACK_SUCCESS;
    354       break;
    355 
    356     case A2DP_CTRL_CMD_OFFLOAD_START:
    357       btif_av_stream_start_offload();
    358       status = A2DP_CTRL_ACK_PENDING;
    359       break;
    360 
    361     default:
    362       APPL_TRACE_ERROR("UNSUPPORTED CMD (%d)", cmd);
    363       status = A2DP_CTRL_ACK_FAILURE;
    364       break;
    365   }
    366   LOG_INFO(LOG_TAG, "a2dp-ctrl-cmd : %s DONE returning status %d",
    367            audio_a2dp_hw_dump_ctrl_event((tA2DP_CTRL_CMD)cmd), status);
    368   return status;
    369 }
    370