1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <sys/types.h>
18 #define LOG_TAG "BTAudioSessionAidl"
19 
20 #include <android-base/logging.h>
21 #include <android-base/stringprintf.h>
22 #include <android/binder_manager.h>
23 #include <com_android_btaudio_hal_flags.h>
24 #include <hardware/audio.h>
25 
26 #include "BluetoothAudioSession.h"
27 
28 namespace aidl {
29 namespace android {
30 namespace hardware {
31 namespace bluetooth {
32 namespace audio {
33 
34 static constexpr int kFmqSendTimeoutMs = 1000;  // 1000 ms timeout for sending
35 static constexpr int kFmqReceiveTimeoutMs =
36     1000;                               // 1000 ms timeout for receiving
37 static constexpr int kWritePollMs = 1;  // polled non-blocking interval
38 static constexpr int kReadPollMs = 1;   // polled non-blocking interval
39 
toString(const std::vector<LatencyMode> & latencies)40 static std::string toString(const std::vector<LatencyMode>& latencies) {
41   std::stringstream latencyModesStr;
42   for (LatencyMode mode : latencies) {
43     latencyModesStr << " " << toString(mode);
44   }
45   return latencyModesStr.str();
46 }
47 
BluetoothAudioSession(const SessionType & session_type)48 BluetoothAudioSession::BluetoothAudioSession(const SessionType& session_type)
49     : session_type_(session_type), stack_iface_(nullptr), data_mq_(nullptr) {}
50 
51 /***
52  *
53  * Callback methods
54  *
55  ***/
56 
OnSessionStarted(const std::shared_ptr<IBluetoothAudioPort> stack_iface,const DataMQDesc * mq_desc,const AudioConfiguration & audio_config,const std::vector<LatencyMode> & latency_modes)57 void BluetoothAudioSession::OnSessionStarted(
58     const std::shared_ptr<IBluetoothAudioPort> stack_iface,
59     const DataMQDesc* mq_desc, const AudioConfiguration& audio_config,
60     const std::vector<LatencyMode>& latency_modes) {
61   std::lock_guard<std::recursive_mutex> guard(mutex_);
62   if (stack_iface == nullptr) {
63     LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
64                << ", IBluetoothAudioPort Invalid";
65   } else if (!UpdateAudioConfig(audio_config)) {
66     LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
67                << ", AudioConfiguration=" << audio_config.toString()
68                << " Invalid";
69   } else if (!UpdateDataPath(mq_desc)) {
70     LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
71                << " MqDescriptor Invalid";
72     audio_config_ = nullptr;
73   } else {
74     stack_iface_ = stack_iface;
75     latency_modes_ = latency_modes;
76     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
77               << " - All LatencyModes=" << toString(latency_modes)
78               << ", AudioConfiguration=" << audio_config.toString();
79     ReportSessionStatus();
80   }
81 }
82 
OnSessionEnded()83 void BluetoothAudioSession::OnSessionEnded() {
84   std::lock_guard<std::recursive_mutex> guard(mutex_);
85   bool toggled = IsSessionReady();
86   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
87   audio_config_ = nullptr;
88   stack_iface_ = nullptr;
89   UpdateDataPath(nullptr);
90   if (toggled) {
91     ReportSessionStatus();
92   }
93 }
94 
95 /***
96  *
97  * Util methods
98  *
99  ***/
100 
GetAudioConfig()101 const AudioConfiguration BluetoothAudioSession::GetAudioConfig() {
102   std::lock_guard<std::recursive_mutex> guard(mutex_);
103   if (!IsSessionReady()) {
104     switch (session_type_) {
105       case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
106       case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
107         return AudioConfiguration(CodecConfiguration{});
108       case SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH:
109         return AudioConfiguration(HfpConfiguration{});
110       case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
111       case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
112         return AudioConfiguration(LeAudioConfiguration{});
113       case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
114         return AudioConfiguration(LeAudioBroadcastConfiguration{});
115       default:
116         return AudioConfiguration(PcmConfiguration{});
117     }
118   }
119   return *audio_config_;
120 }
121 
ReportAudioConfigChanged(const AudioConfiguration & audio_config)122 void BluetoothAudioSession::ReportAudioConfigChanged(
123     const AudioConfiguration& audio_config) {
124   std::lock_guard<std::recursive_mutex> guard(mutex_);
125   if (com::android::btaudio::hal::flags::leaudio_report_broadcast_ac_to_hal()) {
126     if (session_type_ ==
127             SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
128         session_type_ ==
129             SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
130       if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
131         LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
132                   << toString(session_type_);
133         return;
134       }
135     } else if (session_type_ ==
136             SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
137       if (audio_config.getTag() != AudioConfiguration::leAudioBroadcastConfig) {
138         LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
139                   << toString(session_type_);
140         return;
141       }
142     } else {
143       LOG(ERROR) << __func__ << " invalid SessionType ="
144                  << toString(session_type_);
145       return;
146     }
147   } else {
148     if (session_type_ !=
149             SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
150         session_type_ !=
151             SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
152       return;
153     }
154     if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
155       LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
156                  << toString(session_type_);
157       return;
158     }
159   }
160 
161   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
162 
163   if (observers_.empty()) {
164     LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
165                  << " has NO port state observer";
166     return;
167   }
168   for (auto& observer : observers_) {
169     uint16_t cookie = observer.first;
170     std::shared_ptr<struct PortStatusCallbacks> cb = observer.second;
171     LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_)
172               << ", bluetooth_audio=0x"
173               << ::android::base::StringPrintf("%04x", cookie);
174     if (cb->audio_configuration_changed_cb_ != nullptr) {
175       cb->audio_configuration_changed_cb_(cookie);
176     }
177   }
178 }
179 
IsSessionReady()180 bool BluetoothAudioSession::IsSessionReady() {
181   std::lock_guard<std::recursive_mutex> guard(mutex_);
182 
183   bool is_mq_valid =
184       (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
185        session_type_ ==
186            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
187        session_type_ ==
188            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
189        session_type_ ==
190            SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
191        session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
192        session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
193        (data_mq_ != nullptr && data_mq_->isValid()));
194   return stack_iface_ != nullptr && is_mq_valid && audio_config_ != nullptr;
195 }
196 
197 /***
198  *
199  * Status callback methods
200  *
201  ***/
202 
RegisterStatusCback(const PortStatusCallbacks & callbacks)203 uint16_t BluetoothAudioSession::RegisterStatusCback(
204     const PortStatusCallbacks& callbacks) {
205   std::lock_guard<std::recursive_mutex> guard(mutex_);
206   uint16_t cookie = ObserversCookieGetInitValue(session_type_);
207   uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_);
208 
209   while (cookie < cookie_upper_bound) {
210     if (observers_.find(cookie) == observers_.end()) {
211       break;
212     }
213     ++cookie;
214   }
215   if (cookie >= cookie_upper_bound) {
216     LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
217                << " has " << observers_.size()
218                << " observers already (No Resource)";
219     return kObserversCookieUndefined;
220   }
221   std::shared_ptr<PortStatusCallbacks> cb =
222       std::make_shared<PortStatusCallbacks>();
223   *cb = callbacks;
224   observers_[cookie] = cb;
225   return cookie;
226 }
227 
UnregisterStatusCback(uint16_t cookie)228 void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) {
229   std::lock_guard<std::recursive_mutex> guard(mutex_);
230   if (observers_.erase(cookie) != 1) {
231     LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
232                  << " no such provider=0x"
233                  << ::android::base::StringPrintf("%04x", cookie);
234   }
235 }
236 
237 /***
238  *
239  * Stream methods
240  *
241  ***/
242 
StartStream(bool is_low_latency)243 bool BluetoothAudioSession::StartStream(bool is_low_latency) {
244   std::lock_guard<std::recursive_mutex> guard(mutex_);
245   if (!IsSessionReady()) {
246     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
247                << " has NO session";
248     return false;
249   }
250   auto hal_retval = stack_iface_->startStream(is_low_latency);
251   if (!hal_retval.isOk()) {
252     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
253                  << toString(session_type_) << " failed";
254     return false;
255   }
256   return true;
257 }
258 
SuspendStream()259 bool BluetoothAudioSession::SuspendStream() {
260   std::lock_guard<std::recursive_mutex> guard(mutex_);
261   if (!IsSessionReady()) {
262     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
263                << " has NO session";
264     return false;
265   }
266   auto hal_retval = stack_iface_->suspendStream();
267   if (!hal_retval.isOk()) {
268     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
269                  << toString(session_type_) << " failed";
270     return false;
271   }
272   return true;
273 }
274 
StopStream()275 void BluetoothAudioSession::StopStream() {
276   std::lock_guard<std::recursive_mutex> guard(mutex_);
277   if (!IsSessionReady()) {
278     return;
279   }
280   auto hal_retval = stack_iface_->stopStream();
281   if (!hal_retval.isOk()) {
282     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
283                  << toString(session_type_) << " failed";
284   }
285 }
286 
287 /***
288  *
289  * Private methods
290  *
291  ***/
292 
UpdateDataPath(const DataMQDesc * mq_desc)293 bool BluetoothAudioSession::UpdateDataPath(const DataMQDesc* mq_desc) {
294   if (mq_desc == nullptr) {
295     // usecase of reset by nullptr
296     data_mq_ = nullptr;
297     return true;
298   }
299   std::unique_ptr<DataMQ> temp_mq;
300   temp_mq.reset(new DataMQ(*mq_desc));
301   if (!temp_mq || !temp_mq->isValid()) {
302     data_mq_ = nullptr;
303     return false;
304   }
305   data_mq_ = std::move(temp_mq);
306   return true;
307 }
308 
UpdateAudioConfig(const AudioConfiguration & audio_config)309 bool BluetoothAudioSession::UpdateAudioConfig(
310     const AudioConfiguration& audio_config) {
311   bool is_software_session =
312       (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
313        session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
314        session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
315        session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
316        session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
317        session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
318        session_type_ ==
319            SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH ||
320        session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
321   bool is_offload_a2dp_session =
322       (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
323        session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
324   bool is_offload_hfp_session =
325       session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH;
326   bool is_offload_le_audio_unicast_session =
327       (session_type_ ==
328            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
329        session_type_ ==
330            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
331   bool is_offload_le_audio_broadcast_session =
332       (session_type_ ==
333        SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
334   auto audio_config_tag = audio_config.getTag();
335   bool is_software_audio_config =
336       (is_software_session &&
337        audio_config_tag == AudioConfiguration::pcmConfig);
338   bool is_a2dp_offload_audio_config =
339       (is_offload_a2dp_session &&
340        (audio_config_tag == AudioConfiguration::a2dp ||
341         audio_config_tag == AudioConfiguration::a2dpConfig));
342   bool is_hfp_offload_audio_config =
343       (is_offload_hfp_session &&
344        audio_config_tag == AudioConfiguration::hfpConfig);
345   bool is_le_audio_offload_unicast_audio_config =
346       (is_offload_le_audio_unicast_session &&
347        audio_config_tag == AudioConfiguration::leAudioConfig);
348   bool is_le_audio_offload_broadcast_audio_config =
349       (is_offload_le_audio_broadcast_session &&
350        audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
351   if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
352       !is_hfp_offload_audio_config &&
353       !is_le_audio_offload_unicast_audio_config &&
354       !is_le_audio_offload_broadcast_audio_config) {
355     return false;
356   }
357   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
358   return true;
359 }
360 
ReportSessionStatus()361 void BluetoothAudioSession::ReportSessionStatus() {
362   // This is locked already by OnSessionStarted / OnSessionEnded
363   if (observers_.empty()) {
364     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
365               << " has NO port state observer";
366     return;
367   }
368   for (auto& observer : observers_) {
369     uint16_t cookie = observer.first;
370     std::shared_ptr<PortStatusCallbacks> callback = observer.second;
371     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
372               << " notify to bluetooth_audio=0x"
373               << ::android::base::StringPrintf("%04x", cookie);
374     callback->session_changed_cb_(cookie);
375   }
376 }
377 
378 /***
379  *
380  * PCM methods
381  *
382  ***/
383 
OutWritePcmData(const void * buffer,size_t bytes)384 size_t BluetoothAudioSession::OutWritePcmData(const void* buffer,
385                                               size_t bytes) {
386   if (buffer == nullptr || bytes <= 0) {
387     return 0;
388   }
389   size_t total_written = 0;
390   int timeout_ms = kFmqSendTimeoutMs;
391   do {
392     std::unique_lock<std::recursive_mutex> lock(mutex_);
393     if (!IsSessionReady()) {
394       break;
395     }
396     size_t num_bytes_to_write = data_mq_->availableToWrite();
397     if (num_bytes_to_write) {
398       if (num_bytes_to_write > (bytes - total_written)) {
399         num_bytes_to_write = bytes - total_written;
400       }
401 
402       if (!data_mq_->write(
403               static_cast<const MQDataType*>(buffer) + total_written,
404               num_bytes_to_write)) {
405         LOG(ERROR) << "FMQ datapath writing " << total_written << "/" << bytes
406                    << " failed";
407         return total_written;
408       }
409       total_written += num_bytes_to_write;
410     } else if (timeout_ms >= kWritePollMs) {
411       lock.unlock();
412       usleep(kWritePollMs * 1000);
413       timeout_ms -= kWritePollMs;
414     } else {
415       LOG(DEBUG) << "Data " << total_written << "/" << bytes << " overflow "
416                  << (kFmqSendTimeoutMs - timeout_ms) << " ms";
417       return total_written;
418     }
419   } while (total_written < bytes);
420   return total_written;
421 }
422 
InReadPcmData(void * buffer,size_t bytes)423 size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) {
424   if (buffer == nullptr || bytes <= 0) {
425     return 0;
426   }
427   size_t total_read = 0;
428   int timeout_ms = kFmqReceiveTimeoutMs;
429   do {
430     std::unique_lock<std::recursive_mutex> lock(mutex_);
431     if (!IsSessionReady()) {
432       break;
433     }
434     size_t num_bytes_to_read = data_mq_->availableToRead();
435     if (num_bytes_to_read) {
436       if (num_bytes_to_read > (bytes - total_read)) {
437         num_bytes_to_read = bytes - total_read;
438       }
439       if (!data_mq_->read(static_cast<MQDataType*>(buffer) + total_read,
440                           num_bytes_to_read)) {
441         LOG(ERROR) << "FMQ datapath reading " << total_read << "/" << bytes
442                    << " failed";
443         return total_read;
444       }
445       total_read += num_bytes_to_read;
446     } else if (timeout_ms >= kReadPollMs) {
447       lock.unlock();
448       usleep(kReadPollMs * 1000);
449       timeout_ms -= kReadPollMs;
450       continue;
451     } else {
452       LOG(DEBUG) << "Data " << total_read << "/" << bytes << " overflow "
453                  << (kFmqReceiveTimeoutMs - timeout_ms) << " ms";
454       return total_read;
455     }
456   } while (total_read < bytes);
457   return total_read;
458 }
459 
460 /***
461  *
462  * Other methods
463  *
464  ***/
465 
ReportControlStatus(bool start_resp,BluetoothAudioStatus status)466 void BluetoothAudioSession::ReportControlStatus(bool start_resp,
467                                                 BluetoothAudioStatus status) {
468   std::lock_guard<std::recursive_mutex> guard(mutex_);
469   if (observers_.empty()) {
470     LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
471                  << " has NO port state observer";
472     return;
473   }
474   for (auto& observer : observers_) {
475     uint16_t cookie = observer.first;
476     std::shared_ptr<PortStatusCallbacks> callback = observer.second;
477     LOG(INFO) << __func__ << " - status=" << toString(status)
478               << " for SessionType=" << toString(session_type_)
479               << ", bluetooth_audio=0x"
480               << ::android::base::StringPrintf("%04x", cookie)
481               << (start_resp ? " started" : " suspended");
482     callback->control_result_cb_(cookie, start_resp, status);
483   }
484 }
485 
ReportLowLatencyModeAllowedChanged(bool allowed)486 void BluetoothAudioSession::ReportLowLatencyModeAllowedChanged(bool allowed) {
487   if (session_type_ != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
488     return;
489   }
490   std::lock_guard<std::recursive_mutex> guard(mutex_);
491   low_latency_allowed_ = allowed;
492   // TODO(b/294498919): Remove this after there is API to update latency mode
493   // after audio session started. If low_latency_allowed_ is true, the session
494   // can support LOW_LATENCY and FREE LatencyMode.
495   if (low_latency_allowed_) {
496     if (std::find(latency_modes_.begin(), latency_modes_.end(),
497                   LatencyMode::LOW_LATENCY) == latency_modes_.end()) {
498       LOG(INFO) << __func__ << " - insert LOW_LATENCY LatencyMode";
499       latency_modes_.push_back(LatencyMode::LOW_LATENCY);
500     }
501   }
502   if (observers_.empty()) {
503     LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
504                  << " has NO port state observer";
505     return;
506   }
507   for (auto& observer : observers_) {
508     uint16_t cookie = observer.first;
509     std::shared_ptr<PortStatusCallbacks> callback = observer.second;
510     LOG(INFO) << __func__
511               << " - allowed=" << (allowed ? " allowed" : " disallowed");
512     if (callback->low_latency_mode_allowed_cb_ != nullptr) {
513       callback->low_latency_mode_allowed_cb_(cookie, allowed);
514     }
515   }
516 }
517 
GetPresentationPosition(PresentationPosition & presentation_position)518 bool BluetoothAudioSession::GetPresentationPosition(
519     PresentationPosition& presentation_position) {
520   std::lock_guard<std::recursive_mutex> guard(mutex_);
521   if (!IsSessionReady()) {
522     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
523                << " has NO session";
524     return false;
525   }
526   if (!stack_iface_->getPresentationPosition(&presentation_position).isOk()) {
527     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
528                  << toString(session_type_) << " failed";
529     return false;
530   }
531   return true;
532 }
533 
UpdateSourceMetadata(const struct source_metadata & source_metadata)534 void BluetoothAudioSession::UpdateSourceMetadata(
535     const struct source_metadata& source_metadata) {
536   ssize_t track_count = source_metadata.track_count;
537   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
538             << track_count << " track(s)";
539   SourceMetadata hal_source_metadata;
540   hal_source_metadata.tracks.resize(track_count);
541   for (int i = 0; i < track_count; i++) {
542     hal_source_metadata.tracks[i].usage =
543         static_cast<media::audio::common::AudioUsage>(
544             source_metadata.tracks[i].usage);
545     hal_source_metadata.tracks[i].contentType =
546         static_cast<media::audio::common::AudioContentType>(
547             source_metadata.tracks[i].content_type);
548     hal_source_metadata.tracks[i].gain = source_metadata.tracks[i].gain;
549     LOG(VERBOSE) << __func__ << " - SessionType=" << toString(session_type_)
550                  << ", usage=" << toString(hal_source_metadata.tracks[i].usage)
551                  << ", content="
552                  << toString(hal_source_metadata.tracks[i].contentType)
553                  << ", gain=" << hal_source_metadata.tracks[i].gain;
554   }
555   UpdateSourceMetadata(hal_source_metadata);
556 }
557 
UpdateSinkMetadata(const struct sink_metadata & sink_metadata)558 void BluetoothAudioSession::UpdateSinkMetadata(
559     const struct sink_metadata& sink_metadata) {
560   ssize_t track_count = sink_metadata.track_count;
561   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
562             << track_count << " track(s)";
563   SinkMetadata hal_sink_metadata;
564   hal_sink_metadata.tracks.resize(track_count);
565   for (int i = 0; i < track_count; i++) {
566     hal_sink_metadata.tracks[i].source =
567         static_cast<media::audio::common::AudioSource>(
568             sink_metadata.tracks[i].source);
569     hal_sink_metadata.tracks[i].gain = sink_metadata.tracks[i].gain;
570     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
571               << ", source=" << sink_metadata.tracks[i].source
572               << ", dest_device=" << sink_metadata.tracks[i].dest_device
573               << ", gain=" << sink_metadata.tracks[i].gain
574               << ", dest_device_address="
575               << sink_metadata.tracks[i].dest_device_address;
576   }
577   UpdateSinkMetadata(hal_sink_metadata);
578 }
579 
UpdateSourceMetadata(const SourceMetadata & hal_source_metadata)580 bool BluetoothAudioSession::UpdateSourceMetadata(
581     const SourceMetadata& hal_source_metadata) {
582   std::lock_guard<std::recursive_mutex> guard(mutex_);
583   if (!IsSessionReady()) {
584     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
585                << " has NO session";
586     return false;
587   }
588 
589   if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
590       session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
591       session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
592       session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
593     return false;
594   }
595 
596   auto hal_retval = stack_iface_->updateSourceMetadata(hal_source_metadata);
597   if (!hal_retval.isOk()) {
598     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
599                  << toString(session_type_) << " failed";
600     return false;
601   }
602   return true;
603 }
604 
UpdateSinkMetadata(const SinkMetadata & hal_sink_metadata)605 bool BluetoothAudioSession::UpdateSinkMetadata(
606     const SinkMetadata& hal_sink_metadata) {
607   std::lock_guard<std::recursive_mutex> guard(mutex_);
608   if (!IsSessionReady()) {
609     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
610                << " has NO session";
611     return false;
612   }
613 
614   if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
615       session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
616       session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
617       session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
618     return false;
619   }
620 
621   auto hal_retval = stack_iface_->updateSinkMetadata(hal_sink_metadata);
622   if (!hal_retval.isOk()) {
623     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
624                  << toString(session_type_) << " failed";
625     return false;
626   }
627   return true;
628 }
629 
GetSupportedLatencyModes()630 std::vector<LatencyMode> BluetoothAudioSession::GetSupportedLatencyModes() {
631   std::lock_guard<std::recursive_mutex> guard(mutex_);
632   if (!IsSessionReady()) {
633     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
634                << " has NO session";
635     return std::vector<LatencyMode>();
636   }
637 
638   if (com::android::btaudio::hal::flags::dsa_lea()) {
639     std::vector<LatencyMode> supported_latency_modes;
640     if (session_type_ ==
641         SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
642       for (LatencyMode mode : latency_modes_) {
643         if (mode == LatencyMode::LOW_LATENCY) {
644           // LOW_LATENCY is not supported for LE_HARDWARE_OFFLOAD_ENC sessions
645           continue;
646         }
647         supported_latency_modes.push_back(mode);
648       }
649     } else {
650       for (LatencyMode mode : latency_modes_) {
651         if (!low_latency_allowed_ && mode == LatencyMode::LOW_LATENCY) {
652           // ignore LOW_LATENCY mode if Bluetooth stack doesn't allow
653           continue;
654         }
655         if (mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_SOFTWARE ||
656             mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_HARDWARE) {
657           // DSA_SW and DSA_HW only supported for LE_HARDWARE_OFFLOAD_ENC
658           // sessions
659           continue;
660         }
661         supported_latency_modes.push_back(mode);
662       }
663     }
664     LOG(DEBUG) << __func__ << " - Supported LatencyMode="
665                << toString(supported_latency_modes);
666     return supported_latency_modes;
667   }
668 
669   if (low_latency_allowed_) return latency_modes_;
670   std::vector<LatencyMode> modes;
671   for (LatencyMode mode : latency_modes_) {
672     if (mode == LatencyMode::LOW_LATENCY)
673       // ignore those low latency mode if Bluetooth stack doesn't allow
674       continue;
675     modes.push_back(mode);
676   }
677   return modes;
678 }
679 
SetLatencyMode(const LatencyMode & latency_mode)680 void BluetoothAudioSession::SetLatencyMode(const LatencyMode& latency_mode) {
681   std::lock_guard<std::recursive_mutex> guard(mutex_);
682   if (!IsSessionReady()) {
683     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
684                << " has NO session";
685     return;
686   }
687 
688   auto hal_retval = stack_iface_->setLatencyMode(latency_mode);
689   if (!hal_retval.isOk()) {
690     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
691                  << toString(session_type_) << " failed";
692   }
693 }
694 
IsAidlAvailable()695 bool BluetoothAudioSession::IsAidlAvailable() {
696   if (is_aidl_checked) return is_aidl_available;
697   is_aidl_available =
698       (AServiceManager_checkService(
699            kDefaultAudioProviderFactoryInterface.c_str()) != nullptr);
700   is_aidl_checked = true;
701   return is_aidl_available;
702 }
703 
704 /***
705  *
706  * BluetoothAudioSessionInstance
707  *
708  ***/
709 std::mutex BluetoothAudioSessionInstance::mutex_;
710 std::unordered_map<SessionType, std::shared_ptr<BluetoothAudioSession>>
711     BluetoothAudioSessionInstance::sessions_map_;
712 
713 std::shared_ptr<BluetoothAudioSession>
GetSessionInstance(const SessionType & session_type)714 BluetoothAudioSessionInstance::GetSessionInstance(
715     const SessionType& session_type) {
716   std::lock_guard<std::mutex> guard(mutex_);
717 
718   if (!sessions_map_.empty()) {
719     auto entry = sessions_map_.find(session_type);
720     if (entry != sessions_map_.end()) {
721       return entry->second;
722     }
723   }
724   std::shared_ptr<BluetoothAudioSession> session_ptr =
725       std::make_shared<BluetoothAudioSession>(session_type);
726   sessions_map_[session_type] = session_ptr;
727   return session_ptr;
728 }
729 
730 }  // namespace audio
731 }  // namespace bluetooth
732 }  // namespace hardware
733 }  // namespace android
734 }  // namespace aidl
735