• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "btif_a2dp.h"
23 
24 #include <stdbool.h>
25 
26 #include "audio_a2dp_hw/include/audio_a2dp_hw.h"
27 #include "audio_hal_interface/a2dp_encoding.h"
28 #include "bta_av_api.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 #include "types/raw_address.h"
38 
39 #include <base/logging.h>
40 
btif_a2dp_on_idle(void)41 void btif_a2dp_on_idle(void) {
42   LOG_VERBOSE("Peer stream endpoint type:%s",
43               peer_stream_endpoint_text(btif_av_get_peer_sep()).c_str());
44   if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) {
45     btif_a2dp_source_on_idle();
46   } else if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
47     btif_a2dp_sink_on_idle();
48   }
49 }
50 
btif_a2dp_on_started(const RawAddress & peer_addr,tBTA_AV_START * p_av_start)51 bool btif_a2dp_on_started(const RawAddress& peer_addr, tBTA_AV_START* p_av_start) {
52   LOG(INFO) << __func__ << ": ## ON A2DP STARTED ## peer "
53             << ADDRESS_TO_LOGGABLE_STR(peer_addr) << " p_av_start:"
54             << p_av_start;
55 
56   if (p_av_start == NULL) {
57     tA2DP_CTRL_ACK status = A2DP_CTRL_ACK_SUCCESS;
58     if (!bluetooth::headset::IsCallIdle()) {
59       LOG(ERROR) << __func__ << ": peer " << ADDRESS_TO_LOGGABLE_STR(peer_addr)
60                  << " call in progress, do not start A2DP stream";
61       status = A2DP_CTRL_ACK_INCALL_FAILURE;
62     }
63     /* just ack back a local start request, do not start the media encoder since
64      * this is not for BTA_AV_START_EVT. */
65     if (bluetooth::audio::a2dp::is_hal_enabled()) {
66       bluetooth::audio::a2dp::ack_stream_started(status);
67     } else {
68       btif_a2dp_command_ack(status);
69     }
70     return true;
71   }
72 
73   LOG(INFO) << __func__ << ": peer " << ADDRESS_TO_LOGGABLE_STR(peer_addr)
74             << " status:" << +p_av_start->status
75             << " suspending:" << logbool(p_av_start->suspending) << " initiator:" << logbool(p_av_start->initiator);
76 
77   if (p_av_start->status == BTA_AV_SUCCESS) {
78     if (p_av_start->suspending) {
79       LOG(WARNING) << __func__ << ": peer "
80                    << ADDRESS_TO_LOGGABLE_STR(peer_addr)
81                    << " A2DP is suspending and ignores the started event";
82       return false;
83     }
84     if (btif_av_is_a2dp_offload_running()) {
85       btif_av_stream_start_offload();
86     } else if (bluetooth::audio::a2dp::is_hal_enabled()) {
87       if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) {
88         /* Start the media encoder to do the SW audio stream */
89         btif_a2dp_source_start_audio_req();
90       }
91       if (p_av_start->initiator) {
92         bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_SUCCESS);
93         return true;
94       }
95     } else {
96       if (p_av_start->initiator) {
97         btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
98         return true;
99       }
100       /* media task is auto-started upon UIPC connection of a2dp audiopath */
101     }
102   } else if (p_av_start->initiator) {
103     LOG(ERROR) << __func__ << ": peer " << ADDRESS_TO_LOGGABLE_STR(peer_addr)
104                << " A2DP start request failed: status = " << +p_av_start->status;
105     if (bluetooth::audio::a2dp::is_hal_enabled()) {
106       bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_FAILURE);
107     } else {
108       btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
109     }
110     return true;
111   }
112   return false;
113 }
114 
btif_a2dp_on_stopped(tBTA_AV_SUSPEND * p_av_suspend)115 void btif_a2dp_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) {
116   LOG_INFO("%s: ## ON A2DP STOPPED ## p_av_suspend=%p", __func__, p_av_suspend);
117 
118   if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
119     btif_a2dp_sink_on_stopped(p_av_suspend);
120     return;
121   }
122   if (bluetooth::audio::a2dp::is_hal_enabled() ||
123       !btif_av_is_a2dp_offload_running()) {
124     btif_a2dp_source_on_stopped(p_av_suspend);
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_enabled() ||
136       !btif_av_is_a2dp_offload_running()) {
137     btif_a2dp_source_on_suspended(p_av_suspend);
138   }
139 }
140 
btif_a2dp_on_offload_started(const RawAddress & peer_addr,tBTA_AV_STATUS status)141 void btif_a2dp_on_offload_started(const RawAddress& peer_addr,
142                                   tBTA_AV_STATUS status) {
143   tA2DP_CTRL_ACK ack;
144   LOG_INFO("%s: peer %s status %d", __func__,
145            ADDRESS_TO_LOGGABLE_CSTR(peer_addr), status);
146 
147   switch (status) {
148     case BTA_AV_SUCCESS:
149       ack = A2DP_CTRL_ACK_SUCCESS;
150       break;
151     case BTA_AV_FAIL_RESOURCES:
152       LOG_ERROR("%s: peer %s FAILED UNSUPPORTED", __func__,
153                 ADDRESS_TO_LOGGABLE_CSTR(peer_addr));
154       ack = A2DP_CTRL_ACK_UNSUPPORTED;
155       break;
156     default:
157       LOG_ERROR("%s: peer %s FAILED: status = %d", __func__,
158                 ADDRESS_TO_LOGGABLE_CSTR(peer_addr), status);
159       ack = A2DP_CTRL_ACK_FAILURE;
160       break;
161   }
162   if (btif_av_is_a2dp_offload_running()) {
163     if (ack != BTA_AV_SUCCESS && btif_av_stream_started_ready()) {
164       // Offload request will return with failure from btif_av sm if
165       // suspend is triggered for remote start. Disconnect only if SoC
166       // returned failure for offload VSC
167       LOG_ERROR("%s: peer %s offload start failed", __func__,
168                 ADDRESS_TO_LOGGABLE_CSTR(peer_addr));
169       btif_av_src_disconnect_sink(peer_addr);
170     }
171   }
172   if (bluetooth::audio::a2dp::is_hal_enabled()) {
173     bluetooth::audio::a2dp::ack_stream_started(ack);
174   } else {
175     btif_a2dp_command_ack(ack);
176   }
177 }
178 
btif_debug_a2dp_dump(int fd)179 void btif_debug_a2dp_dump(int fd) {
180   btif_a2dp_source_debug_dump(fd);
181   btif_a2dp_sink_debug_dump(fd);
182   btif_a2dp_codec_debug_dump(fd);
183 }
184