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_VERBOSE("Peer stream endpoint type:%s",
41               peer_stream_endpoint_text(btif_av_get_peer_sep()).c_str());
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(
65           (status == A2DP_CTRL_ACK_SUCCESS) ? BTA_AV_SUCCESS : BTA_AV_FAIL_SDP);
66     } else {
67       btif_a2dp_command_ack(status);
68     }
69     return true;
70   }
71 
72   LOG(INFO) << __func__ << ": peer " << peer_addr << " status:" << +p_av_start->status
73             << " suspending:" << logbool(p_av_start->suspending) << " initiator:" << logbool(p_av_start->initiator);
74 
75   if (p_av_start->status == BTA_AV_SUCCESS) {
76     if (p_av_start->suspending) {
77       LOG(WARNING) << __func__ << ": peer " << peer_addr << " A2DP is suspending and ignores the started event";
78       return false;
79     }
80     if (btif_av_is_a2dp_offload_running()) {
81       btif_av_stream_start_offload();
82     } else if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
83       if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) {
84         /* Start the media encoder to do the SW audio stream */
85         btif_a2dp_source_start_audio_req();
86       }
87       if (p_av_start->initiator) {
88         bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_SUCCESS);
89         return true;
90       }
91     } else {
92       if (p_av_start->initiator) {
93         btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
94         return true;
95       }
96       /* media task is auto-started upon UIPC connection of a2dp audiopath */
97     }
98   } else if (p_av_start->initiator) {
99     LOG(ERROR) << __func__ << ": peer " << peer_addr << " A2DP start request failed: status = " << +p_av_start->status;
100     if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
101       bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_FAILURE);
102     } else if (btif_av_is_a2dp_offload_enabled()) {
103       // TODO: BluetoothA2dp@1.0 is deprecated
104       btif_a2dp_audio_on_started(p_av_start->status);
105     } else {
106       btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
107     }
108     return true;
109   }
110   return false;
111 }
112 
btif_a2dp_on_stopped(tBTA_AV_SUSPEND * p_av_suspend)113 void btif_a2dp_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) {
114   LOG_INFO("%s: ## ON A2DP STOPPED ## p_av_suspend=%p", __func__, p_av_suspend);
115 
116   if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
117     btif_a2dp_sink_on_stopped(p_av_suspend);
118     return;
119   }
120   if (bluetooth::audio::a2dp::is_hal_2_0_enabled() ||
121       !btif_av_is_a2dp_offload_running()) {
122     btif_a2dp_source_on_stopped(p_av_suspend);
123   } else if (p_av_suspend != NULL) {
124     // TODO: BluetoothA2dp@1.0 is deprecated
125     btif_a2dp_audio_on_stopped(p_av_suspend->status);
126   }
127 }
128 
btif_a2dp_on_suspended(tBTA_AV_SUSPEND * p_av_suspend)129 void btif_a2dp_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) {
130   LOG_INFO("%s: ## ON A2DP SUSPENDED ## p_av_suspend=%p", __func__,
131            p_av_suspend);
132   if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
133     btif_a2dp_sink_on_suspended(p_av_suspend);
134     return;
135   }
136   if (bluetooth::audio::a2dp::is_hal_2_0_enabled() ||
137       !btif_av_is_a2dp_offload_running()) {
138     btif_a2dp_source_on_suspended(p_av_suspend);
139   } else if (p_av_suspend != NULL) {
140     // TODO: BluetoothA2dp@1.0 is deprecated
141     btif_a2dp_audio_on_suspended(p_av_suspend->status);
142   }
143 }
144 
btif_a2dp_on_offload_started(const RawAddress & peer_addr,tBTA_AV_STATUS status)145 void btif_a2dp_on_offload_started(const RawAddress& peer_addr,
146                                   tBTA_AV_STATUS status) {
147   tA2DP_CTRL_ACK ack;
148   LOG_INFO("%s: peer %s status %d", __func__, peer_addr.ToString().c_str(),
149            status);
150 
151   switch (status) {
152     case BTA_AV_SUCCESS:
153       ack = A2DP_CTRL_ACK_SUCCESS;
154       break;
155     case BTA_AV_FAIL_RESOURCES:
156       LOG_ERROR("%s: peer %s FAILED UNSUPPORTED", __func__,
157                 peer_addr.ToString().c_str());
158       ack = A2DP_CTRL_ACK_UNSUPPORTED;
159       break;
160     default:
161       LOG_ERROR("%s: peer %s FAILED: status = %d", __func__,
162                 peer_addr.ToString().c_str(), status);
163       ack = A2DP_CTRL_ACK_FAILURE;
164       break;
165   }
166   if (btif_av_is_a2dp_offload_running()) {
167     if (ack != BTA_AV_SUCCESS && btif_av_stream_started_ready()) {
168       // Offload request will return with failure from btif_av sm if
169       // suspend is triggered for remote start. Disconnect only if SoC
170       // returned failure for offload VSC
171       LOG_ERROR("%s: peer %s offload start failed", __func__,
172                 peer_addr.ToString().c_str());
173       btif_av_src_disconnect_sink(peer_addr);
174     }
175   }
176   if (bluetooth::audio::a2dp::is_hal_2_0_enabled()) {
177     bluetooth::audio::a2dp::ack_stream_started(ack);
178   } else {
179     btif_a2dp_command_ack(ack);
180     // TODO: BluetoothA2dp@1.0 is deprecated
181     btif_a2dp_audio_on_started(status);
182   }
183 }
184 
btif_debug_a2dp_dump(int fd)185 void btif_debug_a2dp_dump(int fd) {
186   btif_a2dp_source_debug_dump(fd);
187   btif_a2dp_sink_debug_dump(fd);
188   btif_a2dp_codec_debug_dump(fd);
189 }
190