Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright 2016 The Android Open Source Project
      4  *  Copyright 2009-2012 Broadcom Corporation
      5  *
      6  *  Licensed under the Apache License, Version 2.0 (the "License");
      7  *  you may not use this file except in compliance with the License.
      8  *  You may obtain a copy of the License at:
      9  *
     10  *  http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  *  Unless required by applicable law or agreed to in writing, software
     13  *  distributed under the License is distributed on an "AS IS" BASIS,
     14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  *  See the License for the specific language governing permissions and
     16  *  limitations under the License.
     17  *
     18  ******************************************************************************/
     19 
     20 #define LOG_TAG "bt_btif_a2dp"
     21 
     22 #include <stdbool.h>
     23 
     24 #include "audio_a2dp_hw/include/audio_a2dp_hw.h"
     25 #include "bt_common.h"
     26 #include "bta_av_api.h"
     27 #include "btif_a2dp.h"
     28 #include "btif_a2dp_audio_interface.h"
     29 #include "btif_a2dp_control.h"
     30 #include "btif_a2dp_sink.h"
     31 #include "btif_a2dp_source.h"
     32 #include "btif_av.h"
     33 #include "btif_av_co.h"
     34 #include "btif_hf.h"
     35 #include "btif_util.h"
     36 #include "osi/include/log.h"
     37 
     38 void btif_a2dp_on_idle(void) {
     39   LOG_INFO(LOG_TAG, "%s: ## ON A2DP IDLE ## peer_sep = %d", __func__,
     40            btif_av_get_peer_sep());
     41   if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) {
     42     btif_a2dp_source_on_idle();
     43   } else if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
     44     btif_a2dp_sink_on_idle();
     45   }
     46 }
     47 
     48 bool btif_a2dp_on_started(const RawAddress& peer_addr,
     49                           tBTA_AV_START* p_av_start, bool pending_start) {
     50   bool ack = false;
     51 
     52   LOG_INFO(LOG_TAG,
     53            "%s: ## ON A2DP STARTED ## peer %s pending_start:%s p_av_start:%p",
     54            __func__, peer_addr.ToString().c_str(),
     55            logbool(pending_start).c_str(), p_av_start);
     56 
     57   if (p_av_start == NULL) {
     58     /* ack back a local start request */
     59 
     60     if (!btif_av_is_a2dp_offload_enabled()) {
     61       btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
     62       return true;
     63     } else if (bluetooth::headset::IsCallIdle()) {
     64       btif_av_stream_start_offload();
     65     } else {
     66       LOG_ERROR(LOG_TAG, "%s: peer %s call in progress, do not start offload",
     67                 __func__, peer_addr.ToString().c_str());
     68       btif_a2dp_audio_on_started(A2DP_CTRL_ACK_INCALL_FAILURE);
     69     }
     70     return true;
     71   }
     72 
     73   LOG_INFO(LOG_TAG,
     74            "%s: peer %s pending_start:%s status:%d suspending:%s initiator:%s",
     75            __func__, peer_addr.ToString().c_str(),
     76            logbool(pending_start).c_str(), p_av_start->status,
     77            logbool(p_av_start->suspending).c_str(),
     78            logbool(p_av_start->initiator).c_str());
     79 
     80   if (p_av_start->status == BTA_AV_SUCCESS) {
     81     if (!p_av_start->suspending) {
     82       if (p_av_start->initiator) {
     83         if (pending_start) {
     84           if (btif_av_is_a2dp_offload_enabled()) {
     85             btif_av_stream_start_offload();
     86           } else {
     87             btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
     88           }
     89           ack = true;
     90         }
     91       }
     92 
     93       /* media task is autostarted upon a2dp audiopath connection */
     94     }
     95   } else if (pending_start) {
     96     LOG_ERROR(LOG_TAG, "%s: peer %s A2DP start request failed: status = %d",
     97               __func__, peer_addr.ToString().c_str(), p_av_start->status);
     98     btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
     99     ack = true;
    100   }
    101   return ack;
    102 }
    103 
    104 void btif_a2dp_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) {
    105   LOG_INFO(LOG_TAG, "%s: ## ON A2DP STOPPED ## p_av_suspend=%p", __func__,
    106            p_av_suspend);
    107 
    108   if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
    109     btif_a2dp_sink_on_stopped(p_av_suspend);
    110     return;
    111   }
    112   if (!btif_av_is_a2dp_offload_enabled()) {
    113     btif_a2dp_source_on_stopped(p_av_suspend);
    114   } else if (p_av_suspend != NULL) {
    115     btif_a2dp_audio_on_stopped(p_av_suspend->status);
    116   }
    117 }
    118 
    119 void btif_a2dp_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) {
    120   LOG_INFO(LOG_TAG, "%s: ## ON A2DP SUSPENDED ## p_av_suspend=%p", __func__,
    121            p_av_suspend);
    122   if (!btif_av_is_a2dp_offload_enabled()) {
    123     if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
    124       btif_a2dp_sink_on_suspended(p_av_suspend);
    125     } else {
    126       btif_a2dp_source_on_suspended(p_av_suspend);
    127     }
    128   } else {
    129     btif_a2dp_audio_on_suspended(p_av_suspend->status);
    130   }
    131 }
    132 
    133 void btif_a2dp_on_offload_started(const RawAddress& peer_addr,
    134                                   tBTA_AV_STATUS status) {
    135   tA2DP_CTRL_ACK ack;
    136   LOG_INFO(LOG_TAG, "%s: peer %s status %d", __func__,
    137            peer_addr.ToString().c_str(), status);
    138 
    139   switch (status) {
    140     case BTA_AV_SUCCESS:
    141       ack = A2DP_CTRL_ACK_SUCCESS;
    142       break;
    143     case BTA_AV_FAIL_RESOURCES:
    144       LOG_ERROR(LOG_TAG, "%s: peer %s FAILED UNSUPPORTED", __func__,
    145                 peer_addr.ToString().c_str());
    146       ack = A2DP_CTRL_ACK_UNSUPPORTED;
    147       break;
    148     default:
    149       LOG_ERROR(LOG_TAG, "%s: peer %s FAILED: status = %d", __func__,
    150                 peer_addr.ToString().c_str(), status);
    151       ack = A2DP_CTRL_ACK_FAILURE;
    152       break;
    153   }
    154   if (btif_av_is_a2dp_offload_enabled()) {
    155     btif_a2dp_audio_on_started(status);
    156     if (ack != BTA_AV_SUCCESS && btif_av_stream_started_ready()) {
    157       // Offload request will return with failure from btif_av sm if
    158       // suspend is triggered for remote start. Disconnect only if SoC
    159       // returned failure for offload VSC
    160       LOG_ERROR(LOG_TAG, "%s: peer %s offload start failed", __func__,
    161                 peer_addr.ToString().c_str());
    162       btif_av_src_disconnect_sink(peer_addr);
    163     }
    164   } else {
    165     btif_a2dp_command_ack(ack);
    166   }
    167 }
    168 
    169 void btif_debug_a2dp_dump(int fd) {
    170   btif_a2dp_source_debug_dump(fd);
    171   btif_a2dp_sink_debug_dump(fd);
    172   btif_a2dp_codec_debug_dump(fd);
    173 }
    174