xref: /aosp_15_r20/hardware/interfaces/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
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 if(session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH) {
143       if (audio_config.getTag() != AudioConfiguration::hfpConfig) {
144         LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
145                   << toString(session_type_);
146         return;
147       }
148     } else if (session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
149                session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH) {
150       if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
151         LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
152                    << toString(session_type_);
153         return;
154       }
155     } else {
156       LOG(ERROR) << __func__ << " invalid SessionType ="
157                  << toString(session_type_);
158       return;
159     }
160   } else {
161     if (session_type_ ==
162             SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
163         session_type_ ==
164             SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
165       if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
166         LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
167                    << toString(session_type_);
168         return;
169       }
170     } else if(session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH) {
171       if (audio_config.getTag() != AudioConfiguration::hfpConfig) {
172         LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
173                   << toString(session_type_);
174         return;
175       }
176     } else if (session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
177                session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH) {
178       if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
179         LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
180                    << toString(session_type_);
181         return;
182       }
183     } else {
184       LOG(ERROR) << __func__
185                  << " invalid SessionType =" << toString(session_type_);
186       return;
187     }
188   }
189 
190   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
191 
192   if (observers_.empty()) {
193     LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
194                  << " has NO port state observer";
195     return;
196   }
197   for (auto& observer : observers_) {
198     uint16_t cookie = observer.first;
199     std::shared_ptr<struct PortStatusCallbacks> cb = observer.second;
200     LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_)
201               << ", bluetooth_audio=0x"
202               << ::android::base::StringPrintf("%04x", cookie);
203     if (cb->audio_configuration_changed_cb_ != nullptr) {
204       cb->audio_configuration_changed_cb_(cookie);
205     }
206   }
207 }
208 
IsSessionReady()209 bool BluetoothAudioSession::IsSessionReady() {
210   std::lock_guard<std::recursive_mutex> guard(mutex_);
211 
212   bool is_mq_valid =
213       (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
214        session_type_ ==
215            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
216        session_type_ ==
217            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
218        session_type_ ==
219            SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
220        session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
221        session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
222        (data_mq_ != nullptr && data_mq_->isValid()));
223   return stack_iface_ != nullptr && is_mq_valid && audio_config_ != nullptr;
224 }
225 
226 /***
227  *
228  * Status callback methods
229  *
230  ***/
231 
RegisterStatusCback(const PortStatusCallbacks & callbacks)232 uint16_t BluetoothAudioSession::RegisterStatusCback(
233     const PortStatusCallbacks& callbacks) {
234   std::lock_guard<std::recursive_mutex> guard(mutex_);
235   uint16_t cookie = ObserversCookieGetInitValue(session_type_);
236   uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_);
237 
238   while (cookie < cookie_upper_bound) {
239     if (observers_.find(cookie) == observers_.end()) {
240       break;
241     }
242     ++cookie;
243   }
244   if (cookie >= cookie_upper_bound) {
245     LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
246                << " has " << observers_.size()
247                << " observers already (No Resource)";
248     return kObserversCookieUndefined;
249   }
250   std::shared_ptr<PortStatusCallbacks> cb =
251       std::make_shared<PortStatusCallbacks>();
252   *cb = callbacks;
253   observers_[cookie] = cb;
254   return cookie;
255 }
256 
UnregisterStatusCback(uint16_t cookie)257 void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) {
258   std::lock_guard<std::recursive_mutex> guard(mutex_);
259   if (observers_.erase(cookie) != 1) {
260     LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
261                  << " no such provider=0x"
262                  << ::android::base::StringPrintf("%04x", cookie);
263   }
264 }
265 
266 /***
267  *
268  * Stream methods
269  *
270  ***/
271 
StartStream(bool is_low_latency)272 bool BluetoothAudioSession::StartStream(bool is_low_latency) {
273   std::lock_guard<std::recursive_mutex> guard(mutex_);
274   if (!IsSessionReady()) {
275     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
276                << " has NO session";
277     return false;
278   }
279   auto hal_retval = stack_iface_->startStream(is_low_latency);
280   if (!hal_retval.isOk()) {
281     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
282                  << toString(session_type_) << " failed";
283     return false;
284   }
285   return true;
286 }
287 
SuspendStream()288 bool BluetoothAudioSession::SuspendStream() {
289   std::lock_guard<std::recursive_mutex> guard(mutex_);
290   if (!IsSessionReady()) {
291     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
292                << " has NO session";
293     return false;
294   }
295   auto hal_retval = stack_iface_->suspendStream();
296   if (!hal_retval.isOk()) {
297     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
298                  << toString(session_type_) << " failed";
299     return false;
300   }
301   return true;
302 }
303 
StopStream()304 void BluetoothAudioSession::StopStream() {
305   std::lock_guard<std::recursive_mutex> guard(mutex_);
306   if (!IsSessionReady()) {
307     return;
308   }
309   auto hal_retval = stack_iface_->stopStream();
310   if (!hal_retval.isOk()) {
311     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
312                  << toString(session_type_) << " failed";
313   }
314 }
315 
316 /***
317  *
318  * Private methods
319  *
320  ***/
321 
UpdateDataPath(const DataMQDesc * mq_desc)322 bool BluetoothAudioSession::UpdateDataPath(const DataMQDesc* mq_desc) {
323   if (mq_desc == nullptr) {
324     // usecase of reset by nullptr
325     data_mq_ = nullptr;
326     return true;
327   }
328   std::unique_ptr<DataMQ> temp_mq;
329   temp_mq.reset(new DataMQ(*mq_desc));
330   if (!temp_mq || !temp_mq->isValid()) {
331     data_mq_ = nullptr;
332     return false;
333   }
334   data_mq_ = std::move(temp_mq);
335   return true;
336 }
337 
UpdateAudioConfig(const AudioConfiguration & audio_config)338 bool BluetoothAudioSession::UpdateAudioConfig(
339     const AudioConfiguration& audio_config) {
340   bool is_software_session =
341       (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
342        session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
343        session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
344        session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
345        session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
346        session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
347        session_type_ ==
348            SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH ||
349        session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
350   bool is_offload_a2dp_session =
351       (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
352        session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
353   bool is_offload_hfp_session =
354       session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH;
355   bool is_offload_le_audio_unicast_session =
356       (session_type_ ==
357            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
358        session_type_ ==
359            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
360   bool is_offload_le_audio_broadcast_session =
361       (session_type_ ==
362        SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
363   auto audio_config_tag = audio_config.getTag();
364   bool is_software_audio_config =
365       (is_software_session &&
366        audio_config_tag == AudioConfiguration::pcmConfig);
367   bool is_a2dp_offload_audio_config =
368       (is_offload_a2dp_session &&
369        (audio_config_tag == AudioConfiguration::a2dp ||
370         audio_config_tag == AudioConfiguration::a2dpConfig));
371   bool is_hfp_offload_audio_config =
372       (is_offload_hfp_session &&
373        audio_config_tag == AudioConfiguration::hfpConfig);
374   bool is_le_audio_offload_unicast_audio_config =
375       (is_offload_le_audio_unicast_session &&
376        audio_config_tag == AudioConfiguration::leAudioConfig);
377   bool is_le_audio_offload_broadcast_audio_config =
378       (is_offload_le_audio_broadcast_session &&
379        audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
380   if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
381       !is_hfp_offload_audio_config &&
382       !is_le_audio_offload_unicast_audio_config &&
383       !is_le_audio_offload_broadcast_audio_config) {
384     return false;
385   }
386   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
387   return true;
388 }
389 
ReportSessionStatus()390 void BluetoothAudioSession::ReportSessionStatus() {
391   // This is locked already by OnSessionStarted / OnSessionEnded
392   if (observers_.empty()) {
393     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
394               << " has NO port state observer";
395     return;
396   }
397   for (auto& observer : observers_) {
398     uint16_t cookie = observer.first;
399     std::shared_ptr<PortStatusCallbacks> callback = observer.second;
400     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
401               << " notify to bluetooth_audio=0x"
402               << ::android::base::StringPrintf("%04x", cookie);
403     callback->session_changed_cb_(cookie);
404   }
405 }
406 
407 /***
408  *
409  * PCM methods
410  *
411  ***/
412 
OutWritePcmData(const void * buffer,size_t bytes)413 size_t BluetoothAudioSession::OutWritePcmData(const void* buffer,
414                                               size_t bytes) {
415   if (buffer == nullptr || bytes <= 0) {
416     return 0;
417   }
418   size_t total_written = 0;
419   int timeout_ms = kFmqSendTimeoutMs;
420   do {
421     std::unique_lock<std::recursive_mutex> lock(mutex_);
422     if (!IsSessionReady()) {
423       break;
424     }
425     size_t num_bytes_to_write = data_mq_->availableToWrite();
426     if (num_bytes_to_write) {
427       if (num_bytes_to_write > (bytes - total_written)) {
428         num_bytes_to_write = bytes - total_written;
429       }
430 
431       if (!data_mq_->write(
432               static_cast<const MQDataType*>(buffer) + total_written,
433               num_bytes_to_write)) {
434         LOG(ERROR) << "FMQ datapath writing " << total_written << "/" << bytes
435                    << " failed";
436         return total_written;
437       }
438       total_written += num_bytes_to_write;
439     } else if (timeout_ms >= kWritePollMs) {
440       lock.unlock();
441       usleep(kWritePollMs * 1000);
442       timeout_ms -= kWritePollMs;
443     } else {
444       LOG(DEBUG) << "Data " << total_written << "/" << bytes << " overflow "
445                  << (kFmqSendTimeoutMs - timeout_ms) << " ms";
446       return total_written;
447     }
448   } while (total_written < bytes);
449   return total_written;
450 }
451 
InReadPcmData(void * buffer,size_t bytes)452 size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) {
453   if (buffer == nullptr || bytes <= 0) {
454     return 0;
455   }
456   size_t total_read = 0;
457   int timeout_ms = kFmqReceiveTimeoutMs;
458   do {
459     std::unique_lock<std::recursive_mutex> lock(mutex_);
460     if (!IsSessionReady()) {
461       break;
462     }
463     size_t num_bytes_to_read = data_mq_->availableToRead();
464     if (num_bytes_to_read) {
465       if (num_bytes_to_read > (bytes - total_read)) {
466         num_bytes_to_read = bytes - total_read;
467       }
468       if (!data_mq_->read(static_cast<MQDataType*>(buffer) + total_read,
469                           num_bytes_to_read)) {
470         LOG(ERROR) << "FMQ datapath reading " << total_read << "/" << bytes
471                    << " failed";
472         return total_read;
473       }
474       total_read += num_bytes_to_read;
475     } else if (timeout_ms >= kReadPollMs) {
476       lock.unlock();
477       usleep(kReadPollMs * 1000);
478       timeout_ms -= kReadPollMs;
479       continue;
480     } else {
481       LOG(DEBUG) << "Data " << total_read << "/" << bytes << " overflow "
482                  << (kFmqReceiveTimeoutMs - timeout_ms) << " ms";
483       return total_read;
484     }
485   } while (total_read < bytes);
486   return total_read;
487 }
488 
489 /***
490  *
491  * Other methods
492  *
493  ***/
494 
ReportControlStatus(bool start_resp,BluetoothAudioStatus status)495 void BluetoothAudioSession::ReportControlStatus(bool start_resp,
496                                                 BluetoothAudioStatus status) {
497   std::lock_guard<std::recursive_mutex> guard(mutex_);
498   if (observers_.empty()) {
499     LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
500                  << " has NO port state observer";
501     return;
502   }
503   for (auto& observer : observers_) {
504     uint16_t cookie = observer.first;
505     std::shared_ptr<PortStatusCallbacks> callback = observer.second;
506     LOG(INFO) << __func__ << " - status=" << toString(status)
507               << " for SessionType=" << toString(session_type_)
508               << ", bluetooth_audio=0x"
509               << ::android::base::StringPrintf("%04x", cookie)
510               << (start_resp ? " started" : " suspended");
511     callback->control_result_cb_(cookie, start_resp, status);
512   }
513 }
514 
ReportLowLatencyModeAllowedChanged(bool allowed)515 void BluetoothAudioSession::ReportLowLatencyModeAllowedChanged(bool allowed) {
516   if (session_type_ != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
517     return;
518   }
519   std::lock_guard<std::recursive_mutex> guard(mutex_);
520   low_latency_allowed_ = allowed;
521   // TODO(b/294498919): Remove this after there is API to update latency mode
522   // after audio session started. If low_latency_allowed_ is true, the session
523   // can support LOW_LATENCY and FREE LatencyMode.
524   if (low_latency_allowed_) {
525     if (std::find(latency_modes_.begin(), latency_modes_.end(),
526                   LatencyMode::LOW_LATENCY) == latency_modes_.end()) {
527       LOG(INFO) << __func__ << " - insert LOW_LATENCY LatencyMode";
528       latency_modes_.push_back(LatencyMode::LOW_LATENCY);
529     }
530   }
531   if (observers_.empty()) {
532     LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
533                  << " has NO port state observer";
534     return;
535   }
536   for (auto& observer : observers_) {
537     uint16_t cookie = observer.first;
538     std::shared_ptr<PortStatusCallbacks> callback = observer.second;
539     LOG(INFO) << __func__
540               << " - allowed=" << (allowed ? " allowed" : " disallowed");
541     if (callback->low_latency_mode_allowed_cb_ != nullptr) {
542       callback->low_latency_mode_allowed_cb_(cookie, allowed);
543     }
544   }
545 }
546 
GetPresentationPosition(PresentationPosition & presentation_position)547 bool BluetoothAudioSession::GetPresentationPosition(
548     PresentationPosition& presentation_position) {
549   std::lock_guard<std::recursive_mutex> guard(mutex_);
550   if (!IsSessionReady()) {
551     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
552                << " has NO session";
553     return false;
554   }
555   if (!stack_iface_->getPresentationPosition(&presentation_position).isOk()) {
556     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
557                  << toString(session_type_) << " failed";
558     return false;
559   }
560   return true;
561 }
562 
UpdateSourceMetadata(const struct source_metadata & source_metadata)563 void BluetoothAudioSession::UpdateSourceMetadata(
564     const struct source_metadata& source_metadata) {
565   ssize_t track_count = source_metadata.track_count;
566   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
567             << track_count << " track(s)";
568   SourceMetadata hal_source_metadata;
569   hal_source_metadata.tracks.resize(track_count);
570   for (int i = 0; i < track_count; i++) {
571     hal_source_metadata.tracks[i].usage =
572         static_cast<media::audio::common::AudioUsage>(
573             source_metadata.tracks[i].usage);
574     hal_source_metadata.tracks[i].contentType =
575         static_cast<media::audio::common::AudioContentType>(
576             source_metadata.tracks[i].content_type);
577     hal_source_metadata.tracks[i].gain = source_metadata.tracks[i].gain;
578     LOG(VERBOSE) << __func__ << " - SessionType=" << toString(session_type_)
579                  << ", usage=" << toString(hal_source_metadata.tracks[i].usage)
580                  << ", content="
581                  << toString(hal_source_metadata.tracks[i].contentType)
582                  << ", gain=" << hal_source_metadata.tracks[i].gain;
583   }
584   UpdateSourceMetadata(hal_source_metadata);
585 }
586 
UpdateSinkMetadata(const struct sink_metadata & sink_metadata)587 void BluetoothAudioSession::UpdateSinkMetadata(
588     const struct sink_metadata& sink_metadata) {
589   ssize_t track_count = sink_metadata.track_count;
590   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
591             << track_count << " track(s)";
592   SinkMetadata hal_sink_metadata;
593   hal_sink_metadata.tracks.resize(track_count);
594   for (int i = 0; i < track_count; i++) {
595     hal_sink_metadata.tracks[i].source =
596         static_cast<media::audio::common::AudioSource>(
597             sink_metadata.tracks[i].source);
598     hal_sink_metadata.tracks[i].gain = sink_metadata.tracks[i].gain;
599     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
600               << ", source=" << sink_metadata.tracks[i].source
601               << ", dest_device=" << sink_metadata.tracks[i].dest_device
602               << ", gain=" << sink_metadata.tracks[i].gain
603               << ", dest_device_address="
604               << sink_metadata.tracks[i].dest_device_address;
605   }
606   UpdateSinkMetadata(hal_sink_metadata);
607 }
608 
UpdateSourceMetadata(const SourceMetadata & hal_source_metadata)609 bool BluetoothAudioSession::UpdateSourceMetadata(
610     const SourceMetadata& hal_source_metadata) {
611   std::lock_guard<std::recursive_mutex> guard(mutex_);
612   if (!IsSessionReady()) {
613     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
614                << " has NO session";
615     return false;
616   }
617 
618   if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
619       session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
620       session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
621       session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
622       session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
623       session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH) {
624     return false;
625   }
626 
627   auto hal_retval = stack_iface_->updateSourceMetadata(hal_source_metadata);
628   if (!hal_retval.isOk()) {
629     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
630                  << toString(session_type_) << " failed";
631     return false;
632   }
633   return true;
634 }
635 
UpdateSinkMetadata(const SinkMetadata & hal_sink_metadata)636 bool BluetoothAudioSession::UpdateSinkMetadata(
637     const SinkMetadata& hal_sink_metadata) {
638   std::lock_guard<std::recursive_mutex> guard(mutex_);
639   if (!IsSessionReady()) {
640     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
641                << " has NO session";
642     return false;
643   }
644 
645   if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
646       session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
647       session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
648       session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
649       session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
650       session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH) {
651     return false;
652   }
653 
654   auto hal_retval = stack_iface_->updateSinkMetadata(hal_sink_metadata);
655   if (!hal_retval.isOk()) {
656     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
657                  << toString(session_type_) << " failed";
658     return false;
659   }
660   return true;
661 }
662 
GetSupportedLatencyModes()663 std::vector<LatencyMode> BluetoothAudioSession::GetSupportedLatencyModes() {
664   std::lock_guard<std::recursive_mutex> guard(mutex_);
665   if (!IsSessionReady()) {
666     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
667                << " has NO session";
668     return std::vector<LatencyMode>();
669   }
670 
671   if (com::android::btaudio::hal::flags::dsa_lea()) {
672     std::vector<LatencyMode> supported_latency_modes;
673     if (session_type_ ==
674         SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
675       for (LatencyMode mode : latency_modes_) {
676         if (mode == LatencyMode::LOW_LATENCY) {
677           // LOW_LATENCY is not supported for LE_HARDWARE_OFFLOAD_ENC sessions
678           continue;
679         }
680         supported_latency_modes.push_back(mode);
681       }
682     } else {
683       for (LatencyMode mode : latency_modes_) {
684         if (!low_latency_allowed_ && mode == LatencyMode::LOW_LATENCY) {
685           // ignore LOW_LATENCY mode if Bluetooth stack doesn't allow
686           continue;
687         }
688         if (mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_SOFTWARE ||
689             mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_HARDWARE) {
690           // DSA_SW and DSA_HW only supported for LE_HARDWARE_OFFLOAD_ENC
691           // sessions
692           continue;
693         }
694         supported_latency_modes.push_back(mode);
695       }
696     }
697     LOG(DEBUG) << __func__ << " - Supported LatencyMode="
698                << toString(supported_latency_modes);
699     return supported_latency_modes;
700   }
701 
702   if (low_latency_allowed_) return latency_modes_;
703   std::vector<LatencyMode> modes;
704   for (LatencyMode mode : latency_modes_) {
705     if (mode == LatencyMode::LOW_LATENCY)
706       // ignore those low latency mode if Bluetooth stack doesn't allow
707       continue;
708     modes.push_back(mode);
709   }
710   return modes;
711 }
712 
SetLatencyMode(const LatencyMode & latency_mode)713 void BluetoothAudioSession::SetLatencyMode(const LatencyMode& latency_mode) {
714   std::lock_guard<std::recursive_mutex> guard(mutex_);
715   if (!IsSessionReady()) {
716     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
717                << " has NO session";
718     return;
719   }
720 
721   auto hal_retval = stack_iface_->setLatencyMode(latency_mode);
722   if (!hal_retval.isOk()) {
723     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
724                  << toString(session_type_) << " failed";
725   }
726 }
727 
IsAidlAvailable()728 bool BluetoothAudioSession::IsAidlAvailable() {
729   if (is_aidl_checked) return is_aidl_available;
730   is_aidl_available =
731       (AServiceManager_checkService(
732            kDefaultAudioProviderFactoryInterface.c_str()) != nullptr);
733   is_aidl_checked = true;
734   return is_aidl_available;
735 }
736 
737 /***
738  *
739  * BluetoothAudioSessionInstance
740  *
741  ***/
742 std::mutex BluetoothAudioSessionInstance::mutex_;
743 std::unordered_map<SessionType, std::shared_ptr<BluetoothAudioSession>>
744     BluetoothAudioSessionInstance::sessions_map_;
745 
746 std::shared_ptr<BluetoothAudioSession>
GetSessionInstance(const SessionType & session_type)747 BluetoothAudioSessionInstance::GetSessionInstance(
748     const SessionType& session_type) {
749   std::lock_guard<std::mutex> guard(mutex_);
750 
751   if (!sessions_map_.empty()) {
752     auto entry = sessions_map_.find(session_type);
753     if (entry != sessions_map_.end()) {
754       return entry->second;
755     }
756   }
757   std::shared_ptr<BluetoothAudioSession> session_ptr =
758       std::make_shared<BluetoothAudioSession>(session_type);
759   sessions_map_[session_type] = session_ptr;
760   return session_ptr;
761 }
762 
763 }  // namespace audio
764 }  // namespace bluetooth
765 }  // namespace hardware
766 }  // namespace android
767 }  // namespace aidl
768