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 "bluetooth-a2dp"
21 
22 #include "btif_a2dp.h"
23 
24 #include <bluetooth/log.h>
25 #include <com_android_bluetooth_flags.h>
26 #include <stdbool.h>
27 
28 #include "audio_a2dp_hw/include/audio_a2dp_hw.h"
29 #include "audio_hal_interface/a2dp_encoding.h"
30 #include "bta_av_api.h"
31 #include "btif_a2dp_control.h"
32 #include "btif_a2dp_sink.h"
33 #include "btif_a2dp_source.h"
34 #include "btif_av.h"
35 #include "btif_av_co.h"
36 #include "btif_hf.h"
37 #include "btif_util.h"
38 #include "internal_include/bt_trace.h"
39 #include "os/log.h"
40 #include "types/raw_address.h"
41 
42 using namespace bluetooth;
43 
44 using namespace bluetooth;
45 
btif_a2dp_on_idle(const RawAddress & peer_addr,const A2dpType local_a2dp_type)46 void btif_a2dp_on_idle(const RawAddress& peer_addr,
47                        const A2dpType local_a2dp_type) {
48   log::verbose(
49       "Peer stream endpoint type:{}",
50       peer_stream_endpoint_text(btif_av_get_peer_sep(local_a2dp_type)));
51   if (!com::android::bluetooth::flags::a2dp_concurrent_source_sink() &&
52       btif_av_src_sink_coexist_enabled()) {
53     bool is_sink = btif_av_peer_is_sink(peer_addr);
54     bool is_source = btif_av_peer_is_source(peer_addr);
55     log::info("## ON A2DP IDLE ## is_sink:{} is_source:{}", is_sink, is_source);
56     if (is_sink) {
57       btif_a2dp_source_on_idle();
58     } else if (is_source) {
59       btif_a2dp_sink_on_idle();
60     }
61     return;
62   }
63   if (btif_av_get_peer_sep(local_a2dp_type) == AVDT_TSEP_SNK) {
64     btif_a2dp_source_on_idle();
65   } else if (btif_av_get_peer_sep(local_a2dp_type) == AVDT_TSEP_SRC) {
66     btif_a2dp_sink_on_idle();
67   }
68 }
69 
btif_a2dp_on_started(const RawAddress & peer_addr,tBTA_AV_START * p_av_start,const A2dpType local_a2dp_type)70 bool btif_a2dp_on_started(const RawAddress& peer_addr,
71                           tBTA_AV_START* p_av_start,
72                           const A2dpType local_a2dp_type) {
73   log::info("## ON A2DP STARTED ## peer {} p_av_start:{}", peer_addr,
74             fmt::ptr(p_av_start));
75 
76   if (p_av_start == NULL) {
77     tA2DP_CTRL_ACK status = A2DP_CTRL_ACK_SUCCESS;
78     if (!bluetooth::headset::IsCallIdle()) {
79       log::error("peer {} call in progress, do not start A2DP stream",
80                  peer_addr);
81       status = A2DP_CTRL_ACK_INCALL_FAILURE;
82     }
83     /* just ack back a local start request, do not start the media encoder since
84      * this is not for BTA_AV_START_EVT. */
85     if (bluetooth::audio::a2dp::is_hal_enabled()) {
86       bluetooth::audio::a2dp::ack_stream_started(status);
87     } else {
88       btif_a2dp_command_ack(status);
89     }
90     return true;
91   }
92 
93   log::info("peer {} status:{} suspending:{} initiator:{}", peer_addr,
94             p_av_start->status, p_av_start->suspending, p_av_start->initiator);
95 
96   if (p_av_start->status == BTA_AV_SUCCESS) {
97     if (p_av_start->suspending) {
98       log::warn("peer {} A2DP is suspending and ignores the started event",
99                 peer_addr);
100       return false;
101     }
102     if (btif_av_is_a2dp_offload_running()) {
103       btif_av_stream_start_offload();
104     } else if (bluetooth::audio::a2dp::is_hal_enabled()) {
105       if (btif_av_get_peer_sep(local_a2dp_type) == AVDT_TSEP_SNK) {
106         /* Start the media encoder to do the SW audio stream */
107         btif_a2dp_source_start_audio_req();
108       }
109       if (p_av_start->initiator) {
110         bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_SUCCESS);
111         return true;
112       }
113     } else {
114       if (p_av_start->initiator) {
115         btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
116         return true;
117       }
118       /* media task is auto-started upon UIPC connection of a2dp audiopath */
119     }
120   } else if (p_av_start->initiator) {
121     log::error("peer {} A2DP start request failed: status = {}", peer_addr,
122                p_av_start->status);
123     if (bluetooth::audio::a2dp::is_hal_enabled()) {
124       bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_FAILURE);
125     } else {
126       btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
127     }
128     return true;
129   }
130   return false;
131 }
132 
btif_a2dp_on_stopped(tBTA_AV_SUSPEND * p_av_suspend,const A2dpType local_a2dp_type)133 void btif_a2dp_on_stopped(tBTA_AV_SUSPEND* p_av_suspend,
134                           const A2dpType local_a2dp_type) {
135   log::info("## ON A2DP STOPPED ## p_av_suspend={}", fmt::ptr(p_av_suspend));
136 
137   const uint8_t peer_type_sep = btif_av_get_peer_sep(local_a2dp_type);
138   if (peer_type_sep == AVDT_TSEP_SRC) {
139     btif_a2dp_sink_on_stopped(p_av_suspend);
140     return;
141   }
142   if (!com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
143     if (bluetooth::audio::a2dp::is_hal_enabled() ||
144         !btif_av_is_a2dp_offload_running()) {
145       btif_a2dp_source_on_stopped(p_av_suspend);
146       return;
147     }
148   } else if (peer_type_sep == AVDT_TSEP_SNK) {
149     if (bluetooth::audio::a2dp::is_hal_enabled() ||
150         !btif_av_is_a2dp_offload_running()) {
151       btif_a2dp_source_on_stopped(p_av_suspend);
152       return;
153     }
154   }
155 }
156 
btif_a2dp_on_suspended(tBTA_AV_SUSPEND * p_av_suspend,const A2dpType local_a2dp_type)157 void btif_a2dp_on_suspended(tBTA_AV_SUSPEND* p_av_suspend,
158                             const A2dpType local_a2dp_type) {
159   log::info("## ON A2DP SUSPENDED ## p_av_suspend={}", fmt::ptr(p_av_suspend));
160   const uint8_t peer_type_sep = btif_av_get_peer_sep(local_a2dp_type);
161   if (peer_type_sep == AVDT_TSEP_SRC) {
162     btif_a2dp_sink_on_suspended(p_av_suspend);
163     return;
164   }
165   if (!com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
166     if (bluetooth::audio::a2dp::is_hal_enabled() ||
167         !btif_av_is_a2dp_offload_running()) {
168       btif_a2dp_source_on_suspended(p_av_suspend);
169       return;
170     }
171   } else if (peer_type_sep == AVDT_TSEP_SNK) {
172     if (bluetooth::audio::a2dp::is_hal_enabled() ||
173         !btif_av_is_a2dp_offload_running()) {
174       btif_a2dp_source_on_suspended(p_av_suspend);
175       return;
176     }
177   }
178 }
179 
btif_a2dp_on_offload_started(const RawAddress & peer_addr,tBTA_AV_STATUS status)180 void btif_a2dp_on_offload_started(const RawAddress& peer_addr,
181                                   tBTA_AV_STATUS status) {
182   tA2DP_CTRL_ACK ack;
183   log::info("peer {} status {}", peer_addr, status);
184 
185   switch (status) {
186     case BTA_AV_SUCCESS:
187       ack = A2DP_CTRL_ACK_SUCCESS;
188       break;
189     case BTA_AV_FAIL_RESOURCES:
190       log::error("peer {} FAILED UNSUPPORTED", peer_addr);
191       ack = A2DP_CTRL_ACK_UNSUPPORTED;
192       break;
193     default:
194       log::error("peer {} FAILED: status = {}", peer_addr, status);
195       ack = A2DP_CTRL_ACK_FAILURE;
196       break;
197   }
198   if (btif_av_is_a2dp_offload_running()) {
199     if (ack != BTA_AV_SUCCESS &&
200         btif_av_stream_started_ready(A2dpType::kSource)) {
201       // Offload request will return with failure from btif_av sm if
202       // suspend is triggered for remote start. Disconnect only if SoC
203       // returned failure for offload VSC
204       log::error("peer {} offload start failed", peer_addr);
205       btif_av_src_disconnect_sink(peer_addr);
206     }
207   }
208   if (bluetooth::audio::a2dp::is_hal_enabled()) {
209     bluetooth::audio::a2dp::ack_stream_started(ack);
210   } else {
211     btif_a2dp_command_ack(ack);
212   }
213 }
214 
btif_debug_a2dp_dump(int fd)215 void btif_debug_a2dp_dump(int fd) {
216   btif_a2dp_source_debug_dump(fd);
217   btif_a2dp_sink_debug_dump(fd);
218   btif_a2dp_codec_debug_dump(fd);
219 }
220