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