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 "audio_hal_interface/a2dp_encoding.h"
26 #include "bt_common.h"
27 #include "bta_av_api.h"
28 #include "btif_a2dp.h"
29 #include "btif_a2dp_audio_interface.h"
30 #include "btif_a2dp_control.h"
31 #include "btif_a2dp_sink.h"
32 #include "btif_a2dp_source.h"
33 #include "btif_av.h"
34 #include "btif_av_co.h"
35 #include "btif_hf.h"
36 #include "btif_util.h"
37 #include "osi/include/log.h"
38
btif_a2dp_on_idle(void)39 void btif_a2dp_on_idle(void) {
40 LOG_INFO("%s: ## ON A2DP IDLE ## peer_sep = %d", __func__,
41 btif_av_get_peer_sep());
42 if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) {
43 btif_a2dp_source_on_idle();
44 } else if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
45 btif_a2dp_sink_on_idle();
46 }
47 }
48
btif_a2dp_on_started(const RawAddress & peer_addr,tBTA_AV_START * p_av_start)49 bool btif_a2dp_on_started(const RawAddress& peer_addr, tBTA_AV_START* p_av_start) {
50 LOG(INFO) << __func__ << ": ## ON A2DP STARTED ## peer " << peer_addr << " p_av_start:" << p_av_start;
51
52 if (p_av_start == NULL) {
53 tA2DP_CTRL_ACK status = A2DP_CTRL_ACK_SUCCESS;
54 if (!bluetooth::headset::IsCallIdle()) {
55 LOG(ERROR) << __func__ << ": peer " << peer_addr << " call in progress, do not start A2DP stream";
56 status = A2DP_CTRL_ACK_INCALL_FAILURE;
57 }
58 /* just ack back a local start request, do not start the media encoder since
59 * this is not for BTA_AV_START_EVT. */
60 if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
61 bluetooth::audio::a2dp::ack_stream_started(status);
62 } else if (btif_av_is_a2dp_offload_enabled()) {
63 // TODO: BluetoothA2dp@1.0 is deprecated
64 btif_a2dp_audio_on_started(status);
65 } else {
66 btif_a2dp_command_ack(status);
67 }
68 return true;
69 }
70
71 LOG(INFO) << __func__ << ": peer " << peer_addr << " status:" << +p_av_start->status
72 << " suspending:" << logbool(p_av_start->suspending) << " initiator:" << logbool(p_av_start->initiator);
73
74 if (p_av_start->status == BTA_AV_SUCCESS) {
75 if (p_av_start->suspending) {
76 LOG(WARNING) << __func__ << ": peer " << peer_addr << " A2DP is suspending and ignores the started event";
77 return false;
78 }
79 if (btif_av_is_a2dp_offload_running()) {
80 btif_av_stream_start_offload();
81 } else if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
82 if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) {
83 /* Start the media encoder to do the SW audio stream */
84 btif_a2dp_source_start_audio_req();
85 }
86 if (p_av_start->initiator) {
87 bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_SUCCESS);
88 return true;
89 }
90 } else {
91 if (p_av_start->initiator) {
92 btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
93 return true;
94 }
95 /* media task is auto-started upon UIPC connection of a2dp audiopath */
96 }
97 } else if (p_av_start->initiator) {
98 LOG(ERROR) << __func__ << ": peer " << peer_addr << " A2DP start request failed: status = " << +p_av_start->status;
99 if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
100 bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_FAILURE);
101 } else if (btif_av_is_a2dp_offload_enabled()) {
102 // TODO: BluetoothA2dp@1.0 is deprecated
103 btif_a2dp_audio_on_started(p_av_start->status);
104 } else {
105 btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
106 }
107 return true;
108 }
109 return false;
110 }
111
btif_a2dp_on_stopped(tBTA_AV_SUSPEND * p_av_suspend)112 void btif_a2dp_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) {
113 LOG_INFO("%s: ## ON A2DP STOPPED ## p_av_suspend=%p", __func__, p_av_suspend);
114
115 if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
116 btif_a2dp_sink_on_stopped(p_av_suspend);
117 return;
118 }
119 if (bluetooth::audio::a2dp::is_hal_2_0_enabled() ||
120 !btif_av_is_a2dp_offload_running()) {
121 btif_a2dp_source_on_stopped(p_av_suspend);
122 } else if (p_av_suspend != NULL) {
123 // TODO: BluetoothA2dp@1.0 is deprecated
124 btif_a2dp_audio_on_stopped(p_av_suspend->status);
125 }
126 }
127
btif_a2dp_on_suspended(tBTA_AV_SUSPEND * p_av_suspend)128 void btif_a2dp_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) {
129 LOG_INFO("%s: ## ON A2DP SUSPENDED ## p_av_suspend=%p", __func__,
130 p_av_suspend);
131 if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
132 btif_a2dp_sink_on_suspended(p_av_suspend);
133 return;
134 }
135 if (bluetooth::audio::a2dp::is_hal_2_0_enabled() ||
136 !btif_av_is_a2dp_offload_running()) {
137 btif_a2dp_source_on_suspended(p_av_suspend);
138 } else if (p_av_suspend != NULL) {
139 // TODO: BluetoothA2dp@1.0 is deprecated
140 btif_a2dp_audio_on_suspended(p_av_suspend->status);
141 }
142 }
143
btif_a2dp_on_offload_started(const RawAddress & peer_addr,tBTA_AV_STATUS status)144 void btif_a2dp_on_offload_started(const RawAddress& peer_addr,
145 tBTA_AV_STATUS status) {
146 tA2DP_CTRL_ACK ack;
147 LOG_INFO("%s: peer %s status %d", __func__, peer_addr.ToString().c_str(),
148 status);
149
150 switch (status) {
151 case BTA_AV_SUCCESS:
152 ack = A2DP_CTRL_ACK_SUCCESS;
153 break;
154 case BTA_AV_FAIL_RESOURCES:
155 LOG_ERROR("%s: peer %s FAILED UNSUPPORTED", __func__,
156 peer_addr.ToString().c_str());
157 ack = A2DP_CTRL_ACK_UNSUPPORTED;
158 break;
159 default:
160 LOG_ERROR("%s: peer %s FAILED: status = %d", __func__,
161 peer_addr.ToString().c_str(), status);
162 ack = A2DP_CTRL_ACK_FAILURE;
163 break;
164 }
165 if (btif_av_is_a2dp_offload_running()) {
166 if (ack != BTA_AV_SUCCESS && btif_av_stream_started_ready()) {
167 // Offload request will return with failure from btif_av sm if
168 // suspend is triggered for remote start. Disconnect only if SoC
169 // returned failure for offload VSC
170 LOG_ERROR("%s: peer %s offload start failed", __func__,
171 peer_addr.ToString().c_str());
172 btif_av_src_disconnect_sink(peer_addr);
173 }
174 }
175 if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
176 bluetooth::audio::a2dp::ack_stream_started(ack);
177 } else {
178 btif_a2dp_command_ack(ack);
179 // TODO: BluetoothA2dp@1.0 is deprecated
180 btif_a2dp_audio_on_started(status);
181 }
182 }
183
btif_debug_a2dp_dump(int fd)184 void btif_debug_a2dp_dump(int fd) {
185 btif_a2dp_source_debug_dump(fd);
186 btif_a2dp_sink_debug_dump(fd);
187 btif_a2dp_codec_debug_dump(fd);
188 }
189