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