1 /*
2  * Copyright 2021 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
3  * www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <base/functional/bind.h>
19 #include <base/strings/string_number_conversions.h>
20 #include <bluetooth/log.h>
21 #include <com_android_bluetooth_flags.h>
22 #include <stdio.h>
23 
24 #include <algorithm>
25 #include <bitset>
26 #include <chrono>
27 #include <cstddef>
28 #include <cstdint>
29 #include <cstring>
30 #include <deque>
31 #include <functional>
32 #include <list>
33 #include <map>
34 #include <memory>
35 #include <mutex>
36 #include <optional>
37 #include <ostream>
38 #include <sstream>
39 #include <tuple>
40 #include <utility>
41 #include <vector>
42 
43 #include "audio_hal_client/audio_hal_client.h"
44 #include "audio_hal_interface/le_audio_software.h"
45 #include "bt_types.h"
46 #include "bta/csis/csis_types.h"
47 #include "bta_csis_api.h"
48 #include "bta_gatt_api.h"
49 #include "bta_gatt_queue.h"
50 #include "bta_groups.h"
51 #include "bta_le_audio_api.h"
52 #include "bta_le_audio_broadcaster_api.h"
53 #include "btif/include/btif_profile_storage.h"
54 #include "btm_api_types.h"
55 #include "btm_ble_api_types.h"
56 #include "btm_iso_api.h"
57 #include "btm_iso_api_types.h"
58 #include "btm_sec_api_types.h"
59 #include "client_parser.h"
60 #include "codec_interface.h"
61 #include "codec_manager.h"
62 #include "common/strings.h"
63 #include "common/time_util.h"
64 #include "content_control_id_keeper.h"
65 #include "devices.h"
66 #include "gatt/database.h"
67 #include "gatt_api.h"
68 #include "gattdefs.h"
69 #include "gmap_client.h"
70 #include "gmap_server.h"
71 #include "hardware/bt_le_audio.h"
72 #include "hci/controller_interface.h"
73 #include "hci_error_code.h"
74 #include "include/hardware/bt_gmap.h"
75 #include "internal_include/bt_trace.h"
76 #include "internal_include/stack_config.h"
77 #include "le_audio/device_groups.h"
78 #include "le_audio/le_audio_log_history.h"
79 #include "le_audio_health_status.h"
80 #include "le_audio_set_configuration_provider.h"
81 #include "le_audio_types.h"
82 #include "le_audio_utils.h"
83 #include "main/shim/entry.h"
84 #include "metrics_collector.h"
85 #include "osi/include/alarm.h"
86 #include "osi/include/osi.h"
87 #include "osi/include/properties.h"
88 #include "stack/btm/btm_sec.h"
89 #include "stack/include/bt_types.h"
90 #include "stack/include/btm_client_interface.h"
91 #include "stack/include/btm_status.h"
92 #include "stack/include/l2cap_interface.h"
93 #include "stack/include/main_thread.h"
94 #include "state_machine.h"
95 #include "storage_helper.h"
96 #include "types/bluetooth/uuid.h"
97 #include "types/bt_transport.h"
98 #include "types/raw_address.h"
99 
100 #ifdef TARGET_FLOSS
101 #include <audio_hal_interface/audio_linux.h>
102 #else
103 #include <hardware/audio.h>
104 #endif  // TARGET_FLOSS
105 
106 // TODO(b/369381361) Enfore -Wmissing-prototypes
107 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
108 
109 using base::Closure;
110 using bluetooth::Uuid;
111 using bluetooth::common::ToString;
112 using bluetooth::groups::DeviceGroups;
113 using bluetooth::groups::DeviceGroupsCallbacks;
114 using bluetooth::hci::IsoManager;
115 using bluetooth::hci::iso_manager::cig_create_cmpl_evt;
116 using bluetooth::hci::iso_manager::cig_remove_cmpl_evt;
117 using bluetooth::hci::iso_manager::CigCallbacks;
118 using bluetooth::le_audio::CodecManager;
119 using bluetooth::le_audio::ConnectionState;
120 using bluetooth::le_audio::ContentControlIdKeeper;
121 using bluetooth::le_audio::DeviceConnectState;
122 using bluetooth::le_audio::DsaMode;
123 using bluetooth::le_audio::DsaModes;
124 using bluetooth::le_audio::GmapClient;
125 using bluetooth::le_audio::GmapServer;
126 using bluetooth::le_audio::GroupNodeStatus;
127 using bluetooth::le_audio::GroupStatus;
128 using bluetooth::le_audio::GroupStreamStatus;
129 using bluetooth::le_audio::LeAudioCodecConfiguration;
130 using bluetooth::le_audio::LeAudioDevice;
131 using bluetooth::le_audio::LeAudioDeviceGroup;
132 using bluetooth::le_audio::LeAudioDeviceGroups;
133 using bluetooth::le_audio::LeAudioDevices;
134 using bluetooth::le_audio::LeAudioGroupStateMachine;
135 using bluetooth::le_audio::LeAudioHealthBasedAction;
136 using bluetooth::le_audio::LeAudioHealthDeviceStatType;
137 using bluetooth::le_audio::LeAudioHealthGroupStatType;
138 using bluetooth::le_audio::LeAudioHealthStatus;
139 using bluetooth::le_audio::LeAudioRecommendationActionCb;
140 using bluetooth::le_audio::LeAudioSinkAudioHalClient;
141 using bluetooth::le_audio::LeAudioSourceAudioHalClient;
142 using bluetooth::le_audio::UnicastMonitorModeStatus;
143 using bluetooth::le_audio::types::ase;
144 using bluetooth::le_audio::types::AseState;
145 using bluetooth::le_audio::types::AudioContexts;
146 using bluetooth::le_audio::types::AudioLocations;
147 using bluetooth::le_audio::types::BidirectionalPair;
148 using bluetooth::le_audio::types::DataPathState;
149 using bluetooth::le_audio::types::hdl_pair;
150 using bluetooth::le_audio::types::kLeAudioContextAllRemoteSource;
151 using bluetooth::le_audio::types::kLeAudioContextAllTypesArray;
152 using bluetooth::le_audio::types::LeAudioContextType;
153 using bluetooth::le_audio::types::PublishedAudioCapabilities;
154 using bluetooth::le_audio::utils::GetAudioContextsFromSinkMetadata;
155 using bluetooth::le_audio::utils::GetAudioContextsFromSourceMetadata;
156 
157 using namespace bluetooth;
158 
159 /* Enums */
160 enum class AudioReconfigurationResult {
161   RECONFIGURATION_NEEDED = 0x00,
162   RECONFIGURATION_NOT_NEEDED,
163   RECONFIGURATION_NOT_POSSIBLE
164 };
165 
166 enum class AudioState {
167   IDLE = 0x00,
168   READY_TO_START,
169   STARTED,
170   READY_TO_RELEASE,
171   RELEASING,
172 };
173 
operator <<(std::ostream & os,const AudioReconfigurationResult & state)174 std::ostream& operator<<(std::ostream& os, const AudioReconfigurationResult& state) {
175   switch (state) {
176     case AudioReconfigurationResult::RECONFIGURATION_NEEDED:
177       os << "RECONFIGURATION_NEEDED";
178       break;
179     case AudioReconfigurationResult::RECONFIGURATION_NOT_NEEDED:
180       os << "RECONFIGURATION_NOT_NEEDED";
181       break;
182     case AudioReconfigurationResult::RECONFIGURATION_NOT_POSSIBLE:
183       os << "RECONFIGRATION_NOT_POSSIBLE";
184       break;
185     default:
186       os << "UNKNOWN";
187       break;
188   }
189   return os;
190 }
191 
operator <<(std::ostream & os,const AudioState & audio_state)192 std::ostream& operator<<(std::ostream& os, const AudioState& audio_state) {
193   switch (audio_state) {
194     case AudioState::IDLE:
195       os << "IDLE";
196       break;
197     case AudioState::READY_TO_START:
198       os << "READY_TO_START";
199       break;
200     case AudioState::STARTED:
201       os << "STARTED";
202       break;
203     case AudioState::READY_TO_RELEASE:
204       os << "READY_TO_RELEASE";
205       break;
206     case AudioState::RELEASING:
207       os << "RELEASING";
208       break;
209     default:
210       os << "UNKNOWN";
211       break;
212   }
213   return os;
214 }
215 
216 namespace std {
217 template <>
218 struct formatter<AudioState> : ostream_formatter {};
219 }  // namespace std
220 
221 namespace {
222 void le_audio_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data);
223 
224 static void le_audio_health_status_callback(const RawAddress& addr, int group_id,
225                                             LeAudioHealthBasedAction action);
226 
227 class LeAudioClientImpl;
228 LeAudioClientImpl* instance;
229 std::mutex instance_mutex;
230 LeAudioSourceAudioHalClient::Callbacks* audioSinkReceiver;
231 LeAudioSinkAudioHalClient::Callbacks* audioSourceReceiver;
232 CigCallbacks* stateMachineHciCallbacks;
233 LeAudioGroupStateMachine::Callbacks* stateMachineCallbacks;
234 DeviceGroupsCallbacks* device_group_callbacks;
235 LeAudioIsoDataCallback* iso_data_callback;
236 
237 class StreamSpeedTracker {
238 public:
StreamSpeedTracker(void)239   StreamSpeedTracker(void)
240       : is_started_(false),
241         group_id_(bluetooth::groups::kGroupUnknown),
242         num_of_devices_(0),
243         context_type_(LeAudioContextType::UNSPECIFIED),
244         reconfig_start_ts_(0),
245         setup_start_ts_(0),
246         total_time_(0),
247         reconfig_time_(0),
248         stream_setup_time_(0) {}
249 
Init(int group_id,LeAudioContextType context_type,int num_of_devices)250   void Init(int group_id, LeAudioContextType context_type, int num_of_devices) {
251     Reset();
252     group_id_ = group_id;
253     context_type_ = context_type;
254     num_of_devices_ = num_of_devices;
255     log::verbose("StreamSpeedTracker group_id: {}, context: {} #{}", group_id_,
256                  ToString(context_type_), num_of_devices);
257   }
258 
Reset(void)259   void Reset(void) {
260     log::verbose("StreamSpeedTracker group_id: {}", group_id_);
261     is_started_ = false;
262     group_id_ = bluetooth::groups::kGroupUnknown;
263     reconfig_start_ts_ = setup_start_ts_ = total_time_ = reconfig_time_ = stream_setup_time_ =
264             num_of_devices_ = 0;
265     context_type_ = LeAudioContextType::UNSPECIFIED;
266   }
267 
ReconfigStarted(void)268   void ReconfigStarted(void) {
269     log::verbose("StreamSpeedTracker group_id: {}", group_id_);
270     reconfig_time_ = 0;
271     is_started_ = true;
272     reconfig_start_ts_ = bluetooth::common::time_get_os_boottime_us();
273   }
274 
StartStream(void)275   void StartStream(void) {
276     log::verbose("StreamSpeedTracker group_id: {}", group_id_);
277     setup_start_ts_ = bluetooth::common::time_get_os_boottime_us();
278     is_started_ = true;
279   }
280 
ReconfigurationComplete(void)281   void ReconfigurationComplete(void) {
282     reconfig_time_ = (bluetooth::common::time_get_os_boottime_us() - reconfig_start_ts_) / 1000;
283     log::verbose("StreamSpeedTracker group_id: {}, {} reconfig time {} ms", group_id_,
284                  ToString(context_type_), reconfig_time_);
285   }
286 
StreamCreated(void)287   void StreamCreated(void) {
288     stream_setup_time_ = (bluetooth::common::time_get_os_boottime_us() - setup_start_ts_) / 1000;
289     log::verbose("StreamSpeedTracker group_id: {}, {} stream create  time {} ms", group_id_,
290                  ToString(context_type_), stream_setup_time_);
291   }
292 
StopStreamSetup(void)293   void StopStreamSetup(void) {
294     is_started_ = false;
295     uint64_t start_ts = reconfig_time_ != 0 ? reconfig_start_ts_ : setup_start_ts_;
296     total_time_ = (bluetooth::common::time_get_os_boottime_us() - start_ts) / 1000;
297     clock_gettime(CLOCK_REALTIME, &end_ts_);
298     log::verbose("StreamSpeedTracker group_id: {}, {} setup time {} ms", group_id_,
299                  ToString(context_type_), total_time_);
300   }
301 
IsStarted(void)302   bool IsStarted(void) {
303     if (is_started_) {
304       log::verbose("StreamSpeedTracker group_id: {}, {} is_started_: {} ", group_id_,
305                    ToString(context_type_), is_started_);
306     } else {
307       log::verbose("StreamSpeedTracker not started ");
308     }
309     return is_started_;
310   }
311 
Dump(std::stringstream & stream)312   void Dump(std::stringstream& stream) {
313     char ts[20];
314     std::strftime(ts, sizeof(ts), "%T", std::gmtime(&end_ts_.tv_sec));
315 
316     if (total_time_ < 900) {
317       stream << "[ �� ";
318     } else if (total_time_ < 1500) {
319       stream << "[ �� ";
320     } else if (total_time_ < 2500) {
321       stream << "[ �� ";
322     } else {
323       stream << "[ ❗ ";
324     }
325 
326     stream << ts << ": Gid: " << group_id_ << "(#" << num_of_devices_ << "), " << context_type_
327            << ", ";
328     auto hal_idle = total_time_ - stream_setup_time_ - reconfig_time_;
329     if (reconfig_time_ != 0) {
330       stream << "t:" << total_time_ << "ms (r:" << reconfig_time_ << "/s:" << stream_setup_time_
331              << "/hal:" << hal_idle << ")";
332     } else {
333       stream << "t:" << total_time_ << "ms (hal:" << hal_idle << ")";
334     }
335     stream << "]";
336   }
337 
338 private:
339   bool is_started_;
340   int group_id_;
341   int num_of_devices_;
342   LeAudioContextType context_type_;
343   struct timespec end_ts_;
344   uint64_t reconfig_start_ts_;
345   uint64_t setup_start_ts_;
346   uint64_t total_time_;
347   uint64_t reconfig_time_;
348   uint64_t stream_setup_time_;
349 };
350 
351 /*
352  * Coordinatet Set Identification Profile (CSIP) based on CSIP 1.0
353  * and Coordinatet Set Identification Service (CSIS) 1.0
354  *
355  * CSIP allows to organize audio servers into sets e.g. Stereo Set, 5.1 Set
356  * and speed up connecting it.
357  *
358  * Since leaudio has already grouping API it was decided to integrate here CSIS
359  * and allow it to group devices semi-automatically.
360  *
361  * Flow:
362  * If connected device contains CSIS services, and it is included into CAP
363  * service, implementation marks device as a set member and waits for the
364  * bta/csis to learn about groups and notify implementation about assigned
365  * group id.
366  *
367  */
368 /* LeAudioClientImpl class represents main implementation class for le audio
369  * feature in stack. This class implements GATT, le audio and ISO related parts.
370  *
371  * This class is represented in single instance and manages a group of devices,
372  * and devices. All devices calls back static method from it and are dispatched
373  * to target receivers (e.g. ASEs, devices).
374  *
375  * This instance also implements a LeAudioClient which is a upper layer API.
376  * Also LeAudioClientCallbacks are callbacks for upper layer.
377  *
378  * This class may be bonded with Test socket which allows to drive an instance
379  * for test purposes.
380  */
381 class LeAudioClientImpl : public LeAudioClient {
382 public:
~LeAudioClientImpl()383   ~LeAudioClientImpl() {
384     alarm_free(close_vbc_timeout_);
385     alarm_free(disable_timer_);
386     alarm_free(suspend_timeout_);
387     alarm_free(reconfiguration_timeout_);
388   }
389 
LeAudioClientImpl(bluetooth::le_audio::LeAudioClientCallbacks * callbacks,LeAudioGroupStateMachine::Callbacks * state_machine_callbacks,base::Closure initCb)390   LeAudioClientImpl(bluetooth::le_audio::LeAudioClientCallbacks* callbacks,
391                     LeAudioGroupStateMachine::Callbacks* state_machine_callbacks,
392                     base::Closure initCb)
393       : gatt_if_(0),
394         callbacks_(callbacks),
395         active_group_id_(bluetooth::groups::kGroupUnknown),
396         configuration_context_type_(LeAudioContextType::UNINITIALIZED),
397         in_call_metadata_context_types_({.sink = AudioContexts(), .source = AudioContexts()}),
398         local_metadata_context_types_({.sink = AudioContexts(), .source = AudioContexts()}),
399         audio_receiver_state_(AudioState::IDLE),
400         audio_sender_state_(AudioState::IDLE),
401         in_call_(false),
402         in_voip_call_(false),
403         sink_monitor_mode_(false),
404         sink_monitor_notified_status_(std::nullopt),
405         source_monitor_mode_(false),
406         source_monitor_notified_status_(std::nullopt),
407         le_audio_source_hal_client_(nullptr),
408         le_audio_sink_hal_client_(nullptr),
409         close_vbc_timeout_(alarm_new("LeAudioCloseVbcTimeout")),
410         suspend_timeout_(alarm_new("LeAudioSuspendTimeout")),
411         reconfiguration_timeout_(alarm_new("LeAudioReconfigurationTimeout")),
412         disable_timer_(alarm_new("LeAudioDisableTimer")) {
413     LeAudioGroupStateMachine::Initialize(state_machine_callbacks);
414     groupStateMachine_ = LeAudioGroupStateMachine::Get();
415 
416     log::info("Reconnection mode: TARGETED_ANNOUNCEMENTS");
417     reconnection_mode_ = BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS;
418 
419     log::info("Loading health status module");
420     leAudioHealthStatus_ = LeAudioHealthStatus::Get();
421     leAudioHealthStatus_->RegisterCallback(base::BindRepeating(le_audio_health_status_callback));
422 
423     BTA_GATTC_AppRegister(
424             le_audio_gattc_callback,
425             base::Bind(
__anon6840174e0202(base::Closure initCb, uint8_t client_id, uint8_t status) 426                     [](base::Closure initCb, uint8_t client_id, uint8_t status) {
427                       if (status != GATT_SUCCESS) {
428                         log::error("Can't start LeAudio profile - no gatt clients left!");
429                         return;
430                       }
431                       instance->gatt_if_ = client_id;
432                       initCb.Run();
433                     },
434                     initCb),
435             true);
436 
437     DeviceGroups::Get()->Initialize(device_group_callbacks);
438   }
439 
ReconfigureAfterVbcClose()440   void ReconfigureAfterVbcClose() {
441     log::debug("VBC close timeout");
442 
443     if (IsInVoipCall()) {
444       SetInVoipCall(false);
445     }
446 
447     auto group = aseGroups_.FindById(active_group_id_);
448     if (!group) {
449       log::error("Invalid group: {}", active_group_id_);
450       return;
451     }
452 
453     /* Reconfiguration to non requiring source scenario */
454     if (sink_monitor_mode_) {
455       notifyAudioLocalSink(UnicastMonitorModeStatus::STREAMING_SUSPENDED);
456     }
457 
458     /* For sonification events we don't really need to reconfigure to HQ
459      * configuration, but if the previous configuration was for HQ Media,
460      * we might want to go back to that scenario.
461      */
462 
463     if ((configuration_context_type_ != LeAudioContextType::MEDIA) &&
464         (configuration_context_type_ != LeAudioContextType::GAME)) {
465       log::info("Keeping the old configuration as no HQ Media playback is needed right now.");
466       return;
467     }
468 
469     /* Test the existing metadata against the recent availability */
470     local_metadata_context_types_.source &=
471             group->GetAvailableContexts(bluetooth::le_audio::types::kLeAudioDirectionSink);
472     if (local_metadata_context_types_.source.none()) {
473       log::warn("invalid/unknown context metadata, using 'MEDIA' instead");
474       local_metadata_context_types_.source = AudioContexts(LeAudioContextType::MEDIA);
475     }
476 
477     /* Choose the right configuration context */
478     auto new_configuration_context =
479             ChooseConfigurationContextType(local_metadata_context_types_.source);
480 
481     log::debug("new_configuration_context= {}", ToString(new_configuration_context));
482     ReconfigureOrUpdateMetadata(group, new_configuration_context,
483                                 {.sink = local_metadata_context_types_.source,
484                                  .source = local_metadata_context_types_.sink});
485   }
486 
StartVbcCloseTimeout()487   void StartVbcCloseTimeout() {
488     if (alarm_is_scheduled(close_vbc_timeout_)) {
489       StopVbcCloseTimeout();
490     }
491 
492     static const uint64_t timeoutMs = 2000;
493     log::debug("Start VBC close timeout with {} ms", timeoutMs);
494 
495     alarm_set_on_mloop(
496             close_vbc_timeout_, timeoutMs,
497             [](void*) {
498               if (instance) {
499                 log::debug("Reconfigure after VBC close");
500                 instance->ReconfigureAfterVbcClose();
501               }
502             },
503             nullptr);
504   }
505 
StopVbcCloseTimeout()506   void StopVbcCloseTimeout() {
507     if (alarm_is_scheduled(close_vbc_timeout_)) {
508       log::debug("Cancel VBC close timeout");
509       alarm_cancel(close_vbc_timeout_);
510     }
511   }
512 
IsReconfigurationTimeoutRunning(int group_id,uint8_t direction=bluetooth::le_audio::types::kLeAudioDirectionBoth)513   bool IsReconfigurationTimeoutRunning(
514           int group_id, uint8_t direction = bluetooth::le_audio::types::kLeAudioDirectionBoth) {
515     if (alarm_is_scheduled(reconfiguration_timeout_)) {
516       log::debug(" is {} group_id: {}, to check: {}, scheduled: {}",
517                  group_id == reconfiguration_group_ ? "running" : " not running", group_id,
518                  direction, reconfiguration_local_directions_);
519       return group_id == reconfiguration_group_ && (direction & reconfiguration_local_directions_);
520     }
521     return false;
522   }
523 
StartReconfigurationTimeout(int group_id)524   void StartReconfigurationTimeout(int group_id) {
525     log::debug("group_id: {}", group_id);
526 
527     /* This is called when Reconfiguration has been completed. This function starts
528      * timer which is a guard for unwanted reconfiguration which might happen when Audio HAL
529      * is sending to Bluetooth stack multiple metadata updates and suspends/resume commands.
530      * What we want to achieve with this timeout, that BT stack will resume the stream with
531      * configuration picked up when ReconfigurationComplete command was sent out to Audio HAL.
532      */
533 
534     if (alarm_is_scheduled(reconfiguration_timeout_)) {
535       log::info("Is already running for group {}", reconfiguration_group_);
536       return;
537     }
538 
539     auto group = aseGroups_.FindById(group_id);
540     if (group == nullptr) {
541       log::warn("This shall not happen, group_id: {} is not available.", group_id);
542       return;
543     }
544 
545     if (IsDirectionAvailableForCurrentConfiguration(
546                 group, bluetooth::le_audio::types::kLeAudioDirectionSink)) {
547       reconfiguration_local_directions_ |= bluetooth::le_audio::types::kLeAudioDirectionSource;
548     }
549     if (IsDirectionAvailableForCurrentConfiguration(
550                 group, bluetooth::le_audio::types::kLeAudioDirectionSource)) {
551       reconfiguration_local_directions_ |= bluetooth::le_audio::types::kLeAudioDirectionSink;
552     }
553 
554     log::debug("reconfiguration_local_directions_ : {}", reconfiguration_local_directions_);
555 
556     reconfiguration_group_ = group_id;
557     alarm_set_on_mloop(
558             reconfiguration_timeout_, kAudioReconfigurationTimeoutMs,
559             [](void* data) {
560               if (instance) {
561                 instance->StopReconfigurationTimeout(
562                         PTR_TO_INT(data), bluetooth::le_audio::types::kLeAudioDirectionBoth);
563               }
564             },
565             INT_TO_PTR(group_id));
566   }
567 
StopReconfigurationTimeout(int group_id,uint8_t local_direction)568   void StopReconfigurationTimeout(int group_id, uint8_t local_direction) {
569     log::debug("group_id: {}, local_direction {}, reconfiguration directions {}", group_id,
570                local_direction, reconfiguration_local_directions_);
571 
572     reconfiguration_local_directions_ &= ~local_direction;
573 
574     if (reconfiguration_local_directions_ != 0) {
575       log::debug("Wait for remaining directions: {} ", reconfiguration_local_directions_);
576       return;
577     }
578 
579     if (alarm_is_scheduled(reconfiguration_timeout_)) {
580       log::debug("Canceling for group_id {}", reconfiguration_group_);
581       alarm_cancel(reconfiguration_timeout_);
582     }
583     reconfiguration_group_ = bluetooth::groups::kGroupUnknown;
584   }
585 
StartSuspendTimeout(void)586   void StartSuspendTimeout(void) {
587     StopSuspendTimeout();
588 
589     /* Group should tie in time to get requested status */
590     uint64_t timeoutMs = kAudioSuspentKeepIsoAliveTimeoutMs;
591     timeoutMs = osi_property_get_int32(kAudioSuspentKeepIsoAliveTimeoutMsProp, timeoutMs);
592 
593     if (stack_config_get_interface()->get_pts_le_audio_disable_ases_before_stopping()) {
594       timeoutMs += kAudioDisableTimeoutMs;
595     }
596 
597     log::debug("Stream suspend_timeout_ started: {} ms", static_cast<int>(timeoutMs));
598 
599     alarm_set_on_mloop(
600             suspend_timeout_, timeoutMs,
601             [](void* data) {
602               if (instance) {
603                 auto const group_id = PTR_TO_INT(data);
604                 log::debug("No resume request received. Stop the group ID: {}", group_id);
605                 instance->GroupStop(group_id);
606               }
607             },
608             INT_TO_PTR(active_group_id_));
609   }
610 
StopSuspendTimeout(void)611   void StopSuspendTimeout(void) {
612     if (alarm_is_scheduled(suspend_timeout_)) {
613       log::debug("Cancel suspend timeout");
614       alarm_cancel(suspend_timeout_);
615     }
616   }
617 
AseInitialStateReadRequest(LeAudioDevice * leAudioDevice)618   void AseInitialStateReadRequest(LeAudioDevice* leAudioDevice) {
619     int ases_num = leAudioDevice->ases_.size();
620     void* notify_flag_ptr = NULL;
621 
622     tBTA_GATTC_MULTI multi_read{};
623 
624     for (int i = 0; i < ases_num; i++) {
625       /* Last read ase characteristic should issue connected state callback
626        * to upper layer
627        */
628 
629       if (leAudioDevice->notify_connected_after_read_ && (i == (ases_num - 1))) {
630         notify_flag_ptr = INT_TO_PTR(leAudioDevice->notify_connected_after_read_);
631       }
632 
633       if (!com::android::bluetooth::flags::le_ase_read_multiple_variable()) {
634         BtaGattQueue::ReadCharacteristic(leAudioDevice->conn_id_,
635                                          leAudioDevice->ases_[i].hdls.val_hdl, OnGattReadRspStatic,
636                                          notify_flag_ptr);
637         continue;
638       }
639 
640       if (i != 0 && (i % GATT_MAX_READ_MULTI_HANDLES == 0)) {
641         multi_read.num_attr = GATT_MAX_READ_MULTI_HANDLES;
642         BtaGattQueue::ReadMultiCharacteristic(leAudioDevice->conn_id_, multi_read,
643                                               OnGattReadMultiRspStatic, notify_flag_ptr);
644         memset(multi_read.handles, 0, GATT_MAX_READ_MULTI_HANDLES * sizeof(uint16_t));
645       }
646       multi_read.handles[i % GATT_MAX_READ_MULTI_HANDLES] = leAudioDevice->ases_[i].hdls.val_hdl;
647     }
648 
649     if (com::android::bluetooth::flags::le_ase_read_multiple_variable() &&
650         (ases_num % GATT_MAX_READ_MULTI_HANDLES != 0)) {
651       multi_read.num_attr = ases_num % GATT_MAX_READ_MULTI_HANDLES;
652       BtaGattQueue::ReadMultiCharacteristic(leAudioDevice->conn_id_, multi_read,
653                                             OnGattReadMultiRspStatic, notify_flag_ptr);
654     }
655   }
656 
OnGroupAddedCb(const RawAddress & address,const bluetooth::Uuid & uuid,int group_id)657   void OnGroupAddedCb(const RawAddress& address, const bluetooth::Uuid& uuid, int group_id) {
658     log::info("address: {} group uuid {} group_id: {}", address, uuid, group_id);
659 
660     /* We are interested in the groups which are in the context of CAP */
661     if (uuid != bluetooth::le_audio::uuid::kCapServiceUuid) {
662       return;
663     }
664 
665     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
666     if (!leAudioDevice) {
667       return;
668     }
669     if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
670       log::info("group already set: {}", leAudioDevice->group_id_);
671       return;
672     }
673 
674     group_add_node(group_id, address);
675   }
676 
677   /* If device participates in streaming the group, it has to be stopped and
678    * group needs to be reconfigured if needed to new configuration without
679    * considering this removing device.
680    */
SetDeviceAsRemovePendingAndStopGroup(LeAudioDevice * leAudioDevice)681   void SetDeviceAsRemovePendingAndStopGroup(LeAudioDevice* leAudioDevice) {
682     log::info("device {}", leAudioDevice->address_);
683     leAudioDevice->SetConnectionState(DeviceConnectState::REMOVING);
684     leAudioDevice->closing_stream_for_disconnection_ = true;
685     GroupStop(leAudioDevice->group_id_);
686   }
687 
OnGroupMemberAddedCb(const RawAddress & address,int group_id)688   void OnGroupMemberAddedCb(const RawAddress& address, int group_id) {
689     log::info("address: {} group_id: {}", address, group_id);
690 
691     auto group = aseGroups_.FindById(group_id);
692     if (!group) {
693       log::error("Not interested in group id: {}", group_id);
694       return;
695     }
696 
697     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
698     if (!leAudioDevice) {
699       return;
700     }
701     if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
702       log::info("group already set: {}", leAudioDevice->group_id_);
703       return;
704     }
705 
706     if (leAudioHealthStatus_) {
707       leAudioHealthStatus_->AddStatisticForDevice(leAudioDevice,
708                                                   LeAudioHealthDeviceStatType::VALID_CSIS);
709     }
710 
711     group_add_node(group_id, address);
712   }
713 
OnGroupMemberRemovedCb(const RawAddress & address,int group_id)714   void OnGroupMemberRemovedCb(const RawAddress& address, int group_id) {
715     log::info("address: {} group_id: {}", address, group_id);
716 
717     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
718     if (!leAudioDevice) {
719       return;
720     }
721     if (leAudioDevice->group_id_ != group_id) {
722       log::warn("Device: {} not assigned to the group.", leAudioDevice->address_);
723       return;
724     }
725 
726     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
727     if (group == NULL) {
728       log::info("device not in the group: {}, {}", leAudioDevice->address_, group_id);
729       return;
730     }
731 
732     if (leAudioHealthStatus_) {
733       leAudioHealthStatus_->RemoveStatistics(address, group->group_id_);
734     }
735 
736     if (leAudioDevice->HaveActiveAse()) {
737       SetDeviceAsRemovePendingAndStopGroup(leAudioDevice);
738       return;
739     }
740 
741     group_remove_node(group, address);
742   }
743 
744   /* This callback happens if kLeAudioDeviceSetStateTimeoutMs timeout happens
745    * during transition from origin to target state
746    */
OnLeAudioDeviceSetStateTimeout(int group_id)747   void OnLeAudioDeviceSetStateTimeout(int group_id) {
748     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
749 
750     if (!group) {
751       /* Group removed */
752       return;
753     }
754 
755     bool check_if_recovery_needed =
756             group->GetTargetState() == AseState::BTA_LE_AUDIO_ASE_STATE_IDLE;
757 
758     if (leAudioHealthStatus_) {
759       leAudioHealthStatus_->AddStatisticForGroup(
760               group, LeAudioHealthGroupStatType::STREAM_CREATE_SIGNALING_FAILED);
761     }
762 
763     log::error(
764             "State not achieved on time for group: group id {}, current state {}, "
765             "target state: {}, check_if_recovery_needed: {}",
766             group_id, ToString(group->GetState()), ToString(group->GetTargetState()),
767             check_if_recovery_needed);
768     group->PrintDebugState();
769     group->SetTargetState(AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
770     group->ClearAllCises();
771 
772     /* There is an issue with a setting up stream or any other operation which
773      * are gatt operations. It means peer is not responsible. Lets close ACL
774      */
775     CancelStreamingRequest();
776     LeAudioDevice* leAudioDevice = group->GetFirstActiveDevice();
777     if (leAudioDevice == nullptr) {
778       log::error("Shouldn't be called without an active device.");
779       leAudioDevice = group->GetFirstDevice();
780       if (leAudioDevice == nullptr) {
781         log::error("Front device is null. Number of devices: {}", group->Size());
782         return;
783       }
784     }
785 
786     /* If Timeout happens on stream close and stream is closing just for the
787      * purpose of device disconnection, do not bother with recovery mode
788      */
789     bool recovery = true;
790     if (check_if_recovery_needed) {
791       for (auto tmpDevice = leAudioDevice; tmpDevice != nullptr;
792            tmpDevice = group->GetNextActiveDevice(tmpDevice)) {
793         if (tmpDevice->closing_stream_for_disconnection_) {
794           recovery = false;
795           break;
796         }
797       }
798     }
799 
800     do {
801       DisconnectDevice(leAudioDevice, true, recovery);
802       leAudioDevice = group->GetNextActiveDevice(leAudioDevice);
803     } while (leAudioDevice);
804 
805     if (recovery) {
806       /* Both devices will  be disconnected soon. Notify upper layer that group
807        * is inactive */
808       groupSetAndNotifyInactive();
809     }
810   }
811 
UpdateLocationsAndContextsAvailability(LeAudioDeviceGroup * group,bool force=false)812   void UpdateLocationsAndContextsAvailability(LeAudioDeviceGroup* group, bool force = false) {
813     bool group_conf_changed = group->ReloadAudioLocations();
814     group_conf_changed |= group->ReloadAudioDirections();
815     group_conf_changed |= group->UpdateAudioContextAvailability();
816     if (group_conf_changed || force) {
817       /* All the configurations should be recalculated for the new conditions */
818       group->InvalidateCachedConfigurations();
819       group->InvalidateGroupStrategy();
820       callbacks_->OnAudioConf(
821               group->audio_directions_, group->group_id_, group->snk_audio_locations_.to_ulong(),
822               group->src_audio_locations_.to_ulong(), group->GetAvailableContexts().value());
823     }
824   }
825 
SuspendedForReconfiguration()826   void SuspendedForReconfiguration() {
827     if (audio_sender_state_ > AudioState::IDLE) {
828       LeAudioLogHistory::Get()->AddLogHistory(kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
829                                               kLogAfSuspendForReconfig + "LocalSource",
830                                               "r_state: " + ToString(audio_receiver_state_) +
831                                                       "s_state: " + ToString(audio_sender_state_));
832       le_audio_source_hal_client_->SuspendedForReconfiguration();
833     }
834     if (audio_receiver_state_ > AudioState::IDLE) {
835       LeAudioLogHistory::Get()->AddLogHistory(kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
836                                               kLogAfSuspendForReconfig + "LocalSink",
837                                               "r_state: " + ToString(audio_receiver_state_) +
838                                                       "s_state: " + ToString(audio_sender_state_));
839       le_audio_sink_hal_client_->SuspendedForReconfiguration();
840     }
841     StartReconfigurationTimeout(active_group_id_);
842   }
843 
ReconfigurationComplete(uint8_t directions)844   void ReconfigurationComplete(uint8_t directions) {
845     if (directions & bluetooth::le_audio::types::kLeAudioDirectionSink) {
846       LeAudioLogHistory::Get()->AddLogHistory(kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
847                                               kLogAfReconfigComplete + "LocalSource",
848                                               "r_state: " + ToString(audio_receiver_state_) +
849                                                       "s_state: " + ToString(audio_sender_state_));
850 
851       le_audio_source_hal_client_->ReconfigurationComplete();
852     }
853     if (directions & bluetooth::le_audio::types::kLeAudioDirectionSource) {
854       LeAudioLogHistory::Get()->AddLogHistory(kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
855                                               kLogAfReconfigComplete + "LocalSink",
856                                               "r_state: " + ToString(audio_receiver_state_) +
857                                                       "s_state: " + ToString(audio_sender_state_));
858 
859       le_audio_sink_hal_client_->ReconfigurationComplete();
860     }
861   }
862 
CancelLocalAudioSourceStreamingRequest()863   void CancelLocalAudioSourceStreamingRequest() {
864     le_audio_source_hal_client_->CancelStreamingRequest();
865 
866     LeAudioLogHistory::Get()->AddLogHistory(kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
867                                             kLogAfCancel + "LocalSource",
868                                             "s_state: " + ToString(audio_sender_state_));
869 
870     audio_sender_state_ = AudioState::IDLE;
871   }
872 
CancelLocalAudioSinkStreamingRequest()873   void CancelLocalAudioSinkStreamingRequest() {
874     le_audio_sink_hal_client_->CancelStreamingRequest();
875 
876     LeAudioLogHistory::Get()->AddLogHistory(kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
877                                             kLogAfCancel + "LocalSink",
878                                             "s_state: " + ToString(audio_receiver_state_));
879 
880     audio_receiver_state_ = AudioState::IDLE;
881   }
882 
CancelStreamingRequest()883   void CancelStreamingRequest() {
884     if (audio_sender_state_ >= AudioState::READY_TO_START) {
885       CancelLocalAudioSourceStreamingRequest();
886     }
887 
888     if (audio_receiver_state_ >= AudioState::READY_TO_START) {
889       CancelLocalAudioSinkStreamingRequest();
890     }
891   }
892 
group_add_node(const int group_id,const RawAddress & address,bool update_group_module=false)893   void group_add_node(const int group_id, const RawAddress& address,
894                       bool update_group_module = false) {
895     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
896     LeAudioDeviceGroup* new_group;
897     LeAudioDeviceGroup* old_group = nullptr;
898 
899     if (!leAudioDevice) {
900       /* TODO This part possible to remove as this is to handle adding device to
901        * the group which is unknown and not connected.
902        */
903       log::info("leAudioDevice unknown , address: {} group: 0x{:x}", address, group_id);
904 
905       if (group_id == bluetooth::groups::kGroupUnknown) {
906         return;
907       }
908 
909       log::info("Set member adding ...");
910       leAudioDevices_.Add(address, DeviceConnectState::CONNECTING_BY_USER);
911       leAudioDevice = leAudioDevices_.FindByAddress(address);
912     } else {
913       if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
914         old_group = aseGroups_.FindById(leAudioDevice->group_id_);
915       }
916     }
917 
918     auto id = DeviceGroups::Get()->GetGroupId(address, bluetooth::le_audio::uuid::kCapServiceUuid);
919     if (group_id == bluetooth::groups::kGroupUnknown) {
920       if (id == bluetooth::groups::kGroupUnknown) {
921         DeviceGroups::Get()->AddDevice(address, bluetooth::le_audio::uuid::kCapServiceUuid);
922         /* We will get back here when group will be created */
923         return;
924       }
925 
926       new_group = aseGroups_.Add(id);
927       if (!new_group) {
928         log::error("can't create group - group is already there?");
929         return;
930       }
931     } else {
932       log::assert_that(id == group_id, "group id missmatch? leaudio id: {}, groups module {}",
933                        group_id, id);
934       new_group = aseGroups_.FindById(group_id);
935       if (!new_group) {
936         new_group = aseGroups_.Add(group_id);
937       } else {
938         if (new_group->IsDeviceInTheGroup(leAudioDevice)) {
939           return;
940         }
941       }
942     }
943 
944     log::debug("New group {}, id: {}", std::format_ptr(new_group), new_group->group_id_);
945 
946     /* If device was in the group and it was not removed by the application,
947      * lets do it now
948      */
949     if (old_group) {
950       group_remove_node(old_group, address, update_group_module);
951     }
952 
953     new_group->AddNode(leAudioDevices_.GetByAddress(address));
954 
955     callbacks_->OnGroupNodeStatus(address, new_group->group_id_, GroupNodeStatus::ADDED);
956 
957     /* If device is connected and added to the group, lets read ASE states */
958     if (leAudioDevice->conn_id_ != GATT_INVALID_CONN_ID) {
959       AseInitialStateReadRequest(leAudioDevice);
960     }
961 
962     if (leAudioDevice->GetConnectionState() == DeviceConnectState::CONNECTED) {
963       UpdateLocationsAndContextsAvailability(new_group);
964     }
965   }
966 
GroupAddNode(const int group_id,const RawAddress & address)967   void GroupAddNode(const int group_id, const RawAddress& address) override {
968     auto id = DeviceGroups::Get()->GetGroupId(address, bluetooth::le_audio::uuid::kCapServiceUuid);
969     if (id == group_id) {
970       return;
971     }
972 
973     if (id != bluetooth::groups::kGroupUnknown) {
974       DeviceGroups::Get()->RemoveDevice(address, id);
975     }
976 
977     DeviceGroups::Get()->AddDevice(address, bluetooth::le_audio::uuid::kCapServiceUuid, group_id);
978   }
979 
remove_group_if_possible(LeAudioDeviceGroup * group)980   void remove_group_if_possible(LeAudioDeviceGroup* group) {
981     if (!group) {
982       log::debug("group is null");
983       return;
984     }
985     log::debug("Group {}, id: {}, size: {}, is cig_state {}", std::format_ptr(group),
986                group->group_id_, group->Size(), ToString(group->cig.GetState()));
987     if (group->IsEmpty() && (group->cig.GetState() == bluetooth::le_audio::types::CigState::NONE)) {
988       lastNotifiedGroupStreamStatusMap_.erase(group->group_id_);
989       aseGroups_.Remove(group->group_id_);
990     }
991   }
992 
group_remove_node(LeAudioDeviceGroup * group,const RawAddress & address,bool update_group_module=false)993   void group_remove_node(LeAudioDeviceGroup* group, const RawAddress& address,
994                          bool update_group_module = false) {
995     int group_id = group->group_id_;
996     group->RemoveNode(leAudioDevices_.GetByAddress(address));
997 
998     if (update_group_module) {
999       int groups_group_id =
1000               DeviceGroups::Get()->GetGroupId(address, bluetooth::le_audio::uuid::kCapServiceUuid);
1001       if (groups_group_id == group_id) {
1002         DeviceGroups::Get()->RemoveDevice(address, group_id);
1003       }
1004     }
1005 
1006     callbacks_->OnGroupNodeStatus(address, group_id, GroupNodeStatus::REMOVED);
1007 
1008     /* Remove group if this was the last leAudioDevice in this group */
1009     if (group->IsEmpty()) {
1010       remove_group_if_possible(group);
1011       return;
1012     }
1013 
1014     /* Removing node from group requires updating group context availability */
1015     UpdateLocationsAndContextsAvailability(group);
1016   }
1017 
GroupRemoveNode(const int group_id,const RawAddress & address)1018   void GroupRemoveNode(const int group_id, const RawAddress& address) override {
1019     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
1020     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1021 
1022     log::info("group_id: {} address: {}", group_id, address);
1023 
1024     if (!leAudioDevice) {
1025       log::error("Skipping unknown leAudioDevice, address: {}", address);
1026       return;
1027     }
1028 
1029     if (leAudioDevice->group_id_ != group_id) {
1030       log::error("Device is not in group_id: {}, but in group_id: {}", group_id,
1031                  leAudioDevice->group_id_);
1032       return;
1033     }
1034 
1035     if (group == NULL) {
1036       log::error("device not in the group ?!");
1037       return;
1038     }
1039 
1040     if (leAudioDevice->HaveActiveAse()) {
1041       SetDeviceAsRemovePendingAndStopGroup(leAudioDevice);
1042       return;
1043     }
1044 
1045     group_remove_node(group, address, true);
1046   }
1047 
ChooseMetadataContextType(AudioContexts metadata_context_type)1048   AudioContexts ChooseMetadataContextType(AudioContexts metadata_context_type) {
1049     /* This function takes already filtered contexts which we are plannig to use
1050      * in the Enable or UpdateMetadata command.
1051      * Note we are not changing stream configuration here, but just the list of
1052      * the contexts in the Metadata which will be provide to remote side.
1053      * Ideally, we should send all the bits we have, but not all headsets like
1054      * it.
1055      */
1056     if (osi_property_get_bool(kAllowMultipleContextsInMetadata, true)) {
1057       return metadata_context_type;
1058     }
1059 
1060     log::debug("Converting to single context type: {}", metadata_context_type.to_string());
1061 
1062     /* Mini policy */
1063     if (metadata_context_type.any()) {
1064       LeAudioContextType context_priority_list[] = {
1065               /* Highest priority first */
1066               LeAudioContextType::CONVERSATIONAL, LeAudioContextType::RINGTONE,
1067               LeAudioContextType::LIVE,           LeAudioContextType::VOICEASSISTANTS,
1068               LeAudioContextType::GAME,           LeAudioContextType::MEDIA,
1069               LeAudioContextType::EMERGENCYALARM, LeAudioContextType::ALERTS,
1070               LeAudioContextType::INSTRUCTIONAL,  LeAudioContextType::NOTIFICATIONS,
1071               LeAudioContextType::SOUNDEFFECTS,
1072       };
1073       for (auto ct : context_priority_list) {
1074         if (metadata_context_type.test(ct)) {
1075           log::debug("Converted to single context type: {}", ToString(ct));
1076           return AudioContexts(ct);
1077         }
1078       }
1079     }
1080 
1081     /* Fallback to BAP mandated context type */
1082     log::warn("Invalid/unknown context, using 'UNSPECIFIED'");
1083     return AudioContexts(LeAudioContextType::UNSPECIFIED);
1084   }
1085 
1086   /* Return true if stream is started */
GroupStream(int group_id,LeAudioContextType configuration_context_type,BidirectionalPair<AudioContexts> remote_contexts)1087   bool GroupStream(int group_id, LeAudioContextType configuration_context_type,
1088                    BidirectionalPair<AudioContexts> remote_contexts) {
1089     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1090 
1091     log::debug(
1092             "configuration_context_type= {}, remote sink contexts= {}, remote source contexts= {}",
1093             ToString(configuration_context_type), ToString(remote_contexts.sink),
1094             ToString(remote_contexts.source));
1095 
1096     log::debug("");
1097     if (configuration_context_type >= LeAudioContextType::RFU) {
1098       log::error("stream context type is not supported: {}",
1099                  ToHexString(configuration_context_type));
1100       return false;
1101     }
1102 
1103     if (!group) {
1104       log::error("unknown group id: {}", group_id);
1105       return false;
1106     }
1107 
1108     log::debug("group state={}, target_state={}", ToString(group->GetState()),
1109                ToString(group->GetTargetState()));
1110 
1111     if (!group->IsAnyDeviceConnected()) {
1112       log::error("group {} is not connected", group_id);
1113       return false;
1114     }
1115 
1116     /* Check if any group is in the transition state. If so, we don't allow to
1117      * start new group to stream
1118      */
1119     if (group->IsInTransition()) {
1120       /* WARNING: Due to group state machine limitations, we should not
1121        * interrupt any ongoing transition. We will check if another
1122        * reconfiguration is needed once the group reaches streaming state.
1123        */
1124       log::warn(
1125               "Group is already in the transition state. Waiting for the target "
1126               "state to be reached.");
1127       return false;
1128     }
1129 
1130     /* Do not put the TBS CCID when not using Telecom for the VoIP calls. */
1131     auto ccid_contexts = remote_contexts;
1132     if (IsInVoipCall() && !IsInCall()) {
1133       ccid_contexts.sink.unset(LeAudioContextType::CONVERSATIONAL);
1134       ccid_contexts.source.unset(LeAudioContextType::CONVERSATIONAL);
1135     }
1136 
1137     bool group_is_streaming = group->IsStreaming();
1138 
1139     BidirectionalPair<std::vector<uint8_t>> ccids = {
1140             .sink = ContentControlIdKeeper::GetInstance()->GetAllCcids(ccid_contexts.sink),
1141             .source = ContentControlIdKeeper::GetInstance()->GetAllCcids(ccid_contexts.source)};
1142     if (group->IsPendingConfiguration()) {
1143       return groupStateMachine_->ConfigureStream(group, configuration_context_type_,
1144                                                  remote_contexts, ccids);
1145     } else if (!group_is_streaming) {
1146       speed_start_setup(group->group_id_, configuration_context_type, group->NumOfConnected());
1147     }
1148 
1149     /* If assistant have some connected delegators that needs to be informed
1150      * when there would be request to stream unicast.
1151      */
1152     if (!sink_monitor_mode_ && source_monitor_mode_ && !group_is_streaming) {
1153       notifyAudioLocalSource(UnicastMonitorModeStatus::STREAMING_REQUESTED);
1154     }
1155 
1156     bool result = groupStateMachine_->StartStream(group, configuration_context_type,
1157                                                   remote_contexts, ccids);
1158 
1159     if (result && !group_is_streaming) {
1160       /* Notify Java about new configuration when start stream has been accepted and
1161        * it is not metadata update
1162        */
1163       SendAudioGroupCurrentCodecConfigChanged(group);
1164     }
1165 
1166     return result;
1167   }
1168 
GroupStream(const int group_id,uint16_t context_type)1169   void GroupStream(const int group_id, uint16_t context_type) override {
1170     BidirectionalPair<AudioContexts> initial_contexts = {AudioContexts(context_type),
1171                                                          AudioContexts(context_type)};
1172     GroupStream(group_id, LeAudioContextType(context_type), initial_contexts);
1173   }
1174 
GroupSuspend(const int group_id)1175   void GroupSuspend(const int group_id) override {
1176     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1177 
1178     if (!group) {
1179       log::error("unknown group id: {}", group_id);
1180       return;
1181     }
1182 
1183     if (!group->IsAnyDeviceConnected()) {
1184       log::error("group is not connected");
1185       return;
1186     }
1187 
1188     if (group->IsInTransition()) {
1189       log::info(", group is in transition from: {} to: {}", ToString(group->GetState()),
1190                 ToString(group->GetTargetState()));
1191       return;
1192     }
1193 
1194     if (group->GetState() != AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
1195       log::error(", invalid current state of group: {}", ToString(group->GetState()));
1196       return;
1197     }
1198 
1199     groupStateMachine_->SuspendStream(group);
1200   }
1201 
GroupStop(const int group_id)1202   void GroupStop(const int group_id) override {
1203     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1204 
1205     if (!group) {
1206       log::error("unknown group id: {}", group_id);
1207       return;
1208     }
1209 
1210     if (group->IsEmpty()) {
1211       log::error("group is empty");
1212       return;
1213     }
1214 
1215     groupStateMachine_->StopStream(group);
1216   }
1217 
GroupDestroy(const int group_id)1218   void GroupDestroy(const int group_id) override {
1219     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1220 
1221     if (!group) {
1222       log::error("unknown group id: {}", group_id);
1223       return;
1224     }
1225 
1226     // Disconnect and remove each device within the group
1227     auto* dev = group->GetFirstDevice();
1228     while (dev) {
1229       auto* next_dev = group->GetNextDevice(dev);
1230       RemoveDevice(dev->address_);
1231       dev = next_dev;
1232     }
1233   }
1234 
SetCodecConfigPreference(int group_id,bluetooth::le_audio::btle_audio_codec_config_t input_codec_config,bluetooth::le_audio::btle_audio_codec_config_t output_codec_config)1235   void SetCodecConfigPreference(
1236           int group_id, bluetooth::le_audio::btle_audio_codec_config_t input_codec_config,
1237           bluetooth::le_audio::btle_audio_codec_config_t output_codec_config) override {
1238     if (!com::android::bluetooth::flags::leaudio_set_codec_config_preference()) {
1239       log::debug("leaudio_set_codec_config_preference flag is not enabled");
1240       return;
1241     }
1242 
1243     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1244 
1245     if (!group) {
1246       log::error("Unknown group id: %d", group_id);
1247     }
1248 
1249     if (group->SetPreferredAudioSetConfiguration(input_codec_config, output_codec_config)) {
1250       log::info("group id: {}, setting preferred codec is successful.", group_id);
1251     } else {
1252       log::warn("group id: {}, setting preferred codec is failed.", group_id);
1253       return;
1254     }
1255 
1256     if (group_id != active_group_id_) {
1257       log::warn("Selected group is not active.");
1258       return;
1259     }
1260 
1261     if (SetConfigurationAndStopStreamWhenNeeded(group, group->GetConfigurationContextType())) {
1262       log::debug("Group id {} do the reconfiguration based on preferred codec config", group_id);
1263     } else {
1264       log::debug("Group id {} preferred codec config is not changed", group_id);
1265     }
1266   }
1267 
IsUsingPreferredCodecConfig(int group_id,int context_type)1268   bool IsUsingPreferredCodecConfig(int group_id, int context_type) {
1269     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1270     if (!group) {
1271       log::error("Unknown group id: %d", group_id);
1272       return false;
1273     }
1274 
1275     return group->IsUsingPreferredAudioSetConfiguration(
1276             static_cast<LeAudioContextType>(context_type));
1277   }
1278 
SetCcidInformation(int ccid,int context_type)1279   void SetCcidInformation(int ccid, int context_type) override {
1280     log::debug("Ccid: {}, context type {}", ccid, context_type);
1281 
1282     ContentControlIdKeeper::GetInstance()->SetCcid(AudioContexts(context_type), ccid);
1283   }
1284 
initReconfiguration(LeAudioDeviceGroup * group,LeAudioContextType previous_context_type)1285   void initReconfiguration(LeAudioDeviceGroup* group, LeAudioContextType previous_context_type) {
1286     log::debug(" group_id: {}, previous context_type {}", group->group_id_,
1287                ToString(previous_context_type));
1288     pre_configuration_context_type_ = previous_context_type;
1289     group->SetPendingConfiguration();
1290     groupStateMachine_->StopStream(group);
1291     speed_start_setup(group->group_id_, configuration_context_type_, group->NumOfConnected(), true);
1292   }
1293 
SetInCall(bool in_call)1294   void SetInCall(bool in_call) override {
1295     log::debug("in_call: {}", in_call);
1296     if (in_call == in_call_) {
1297       log::verbose("no state change {}", in_call);
1298       return;
1299     }
1300 
1301     in_call_ = in_call;
1302 
1303     if (!com::android::bluetooth::flags::leaudio_speed_up_reconfiguration_between_call()) {
1304       log::debug("leaudio_speed_up_reconfiguration_between_call flag is not enabled");
1305       return;
1306     }
1307 
1308     if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
1309       log::debug("There is no active group");
1310       return;
1311     }
1312 
1313     LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
1314     if (!group || !group->IsStreaming()) {
1315       log::debug("{} is not streaming", active_group_id_);
1316       return;
1317     }
1318 
1319     bool reconfigure = false;
1320 
1321     if (in_call_) {
1322       in_call_metadata_context_types_ = local_metadata_context_types_;
1323 
1324       log::debug("in_call_metadata_context_types_ sink: {}  source: {}",
1325                  in_call_metadata_context_types_.sink.to_string(),
1326                  in_call_metadata_context_types_.source.to_string());
1327 
1328       auto audio_set_conf = group->GetConfiguration(LeAudioContextType::CONVERSATIONAL);
1329       if (audio_set_conf && group->IsGroupConfiguredTo(*audio_set_conf)) {
1330         log::info("Call is coming, but CIG already set for a call");
1331         return;
1332       }
1333       log::info("Call is coming, speed up reconfiguration for a call");
1334       local_metadata_context_types_.sink.clear();
1335       local_metadata_context_types_.source.clear();
1336       reconfigure = true;
1337     } else {
1338       if (configuration_context_type_ == LeAudioContextType::CONVERSATIONAL) {
1339         log::info("Call is ended, speed up reconfiguration for media");
1340         local_metadata_context_types_ = in_call_metadata_context_types_;
1341         log::debug("restored local_metadata_context_types_ sink: {}  source: {}",
1342                    local_metadata_context_types_.sink.to_string(),
1343                    local_metadata_context_types_.source.to_string());
1344         in_call_metadata_context_types_.sink.clear();
1345         in_call_metadata_context_types_.source.clear();
1346         reconfigure = true;
1347       }
1348     }
1349 
1350     if (reconfigure) {
1351       ReconfigureOrUpdateRemote(group, bluetooth::le_audio::types::kLeAudioDirectionSink);
1352     }
1353   }
1354 
IsInCall()1355   bool IsInCall() override { return in_call_; }
1356 
SetInVoipCall(bool in_call)1357   void SetInVoipCall(bool in_call) override {
1358     log::debug("in_voip_call: {}", in_call);
1359     in_voip_call_ = in_call;
1360   }
1361 
IsInVoipCall()1362   bool IsInVoipCall() override { return in_voip_call_; }
1363 
IsInStreaming()1364   bool IsInStreaming() override {
1365     return audio_sender_state_ == AudioState::STARTED ||
1366            audio_receiver_state_ == AudioState::STARTED;
1367   }
1368 
SetUnicastMonitorMode(uint8_t direction,bool enable)1369   void SetUnicastMonitorMode(uint8_t direction, bool enable) override {
1370     if (direction == bluetooth::le_audio::types::kLeAudioDirectionSink) {
1371       /* Cleanup Sink HAL client interface if listening mode is toggled off
1372        * before group activation (active group context would take care of
1373        * Sink HAL client cleanup).
1374        */
1375       if (sink_monitor_mode_ && !enable && le_audio_sink_hal_client_ &&
1376           active_group_id_ == bluetooth::groups::kGroupUnknown) {
1377         local_metadata_context_types_.sink.clear();
1378         le_audio_sink_hal_client_->Stop();
1379         le_audio_sink_hal_client_.reset();
1380       }
1381 
1382       log::debug("enable: {}", enable);
1383       sink_monitor_mode_ = enable;
1384     } else if (direction == bluetooth::le_audio::types::kLeAudioDirectionSource) {
1385       log::debug("enable: {}", enable);
1386       source_monitor_mode_ = enable;
1387 
1388       if (!enable) {
1389         return;
1390       }
1391 
1392       LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
1393       if (!group) {
1394         notifyAudioLocalSource(UnicastMonitorModeStatus::STREAMING_SUSPENDED);
1395 
1396         return;
1397       }
1398 
1399       if (group->IsStreaming()) {
1400         notifyAudioLocalSource(UnicastMonitorModeStatus::STREAMING);
1401       } else {
1402         notifyAudioLocalSource(UnicastMonitorModeStatus::STREAMING_SUSPENDED);
1403       }
1404     } else {
1405       log::error("invalid direction: 0x{:02x} monitor mode set", direction);
1406     }
1407   }
1408 
SendAudioProfilePreferences(const int group_id,bool is_output_preference_le_audio,bool is_duplex_preference_le_audio)1409   void SendAudioProfilePreferences(const int group_id, bool is_output_preference_le_audio,
1410                                    bool is_duplex_preference_le_audio) override {
1411     log::info(
1412             "group_id: {}, is_output_preference_le_audio: {}, "
1413             "is_duplex_preference_le_audio: {}",
1414             group_id, is_output_preference_le_audio, is_duplex_preference_le_audio);
1415     if (group_id == bluetooth::groups::kGroupUnknown) {
1416       log::warn("Unknown group_id");
1417       return;
1418     }
1419     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1420     if (!group) {
1421       log::warn("group_id {} does not exist", group_id);
1422       return;
1423     }
1424 
1425     group->is_output_preference_le_audio = is_output_preference_le_audio;
1426     group->is_duplex_preference_le_audio = is_duplex_preference_le_audio;
1427   }
1428 
SetGroupAllowedContextMask(int group_id,int sink_context_types,int source_context_types)1429   void SetGroupAllowedContextMask(int group_id, int sink_context_types,
1430                                   int source_context_types) override {
1431     log::info("group_id: {}, sink context types: {}, source context types: {}", group_id,
1432               sink_context_types, source_context_types);
1433 
1434     if (group_id == bluetooth::groups::kGroupUnknown) {
1435       log::warn("Unknown group_id");
1436       return;
1437     }
1438     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1439     if (!group) {
1440       log::warn("group_id {} does not exist", group_id);
1441       return;
1442     }
1443 
1444     BidirectionalPair<AudioContexts> allowed_contexts = {
1445             .sink = AudioContexts(sink_context_types),
1446             .source = AudioContexts(source_context_types),
1447     };
1448 
1449     group->SetAllowedContextMask(allowed_contexts);
1450   }
1451 
StartAudioSession(LeAudioDeviceGroup * group)1452   void StartAudioSession(LeAudioDeviceGroup* group) {
1453     /* This function is called when group is not yet set to active.
1454      * This is why we don't have to check if session is started already.
1455      * Just check if it is acquired.
1456      */
1457     log::assert_that(active_group_id_ == bluetooth::groups::kGroupUnknown,
1458                      "Active group is not set.");
1459     log::assert_that(le_audio_source_hal_client_ != nullptr, "Source session not acquired");
1460     log::assert_that(le_audio_sink_hal_client_ != nullptr, "Sink session not acquired");
1461 
1462     DsaModes dsa_modes = {DsaMode::DISABLED};
1463     if (com::android::bluetooth::flags::leaudio_dynamic_spatial_audio()) {
1464       dsa_modes = group->GetAllowedDsaModes();
1465     }
1466 
1467     /* We assume that peer device always use same frame duration */
1468     uint32_t frame_duration_us = 0;
1469     if (!current_encoder_config_.IsInvalid()) {
1470       frame_duration_us = current_encoder_config_.data_interval_us;
1471     } else if (!current_decoder_config_.IsInvalid()) {
1472       frame_duration_us = current_decoder_config_.data_interval_us;
1473     } else {
1474       log::assert_that(true, "Both configs are invalid");
1475     }
1476 
1477     stack::l2cap::get_interface().L2CA_SetEcosystemBaseInterval(frame_duration_us / 1250);
1478 
1479     // Scale by the codec frame blocks per SDU if set
1480     uint8_t codec_frame_blocks_per_sdu =
1481             group->stream_conf.stream_params.source.codec_frames_blocks_per_sdu ?: 1;
1482     audio_framework_source_config.data_interval_us = frame_duration_us * codec_frame_blocks_per_sdu;
1483 
1484     le_audio_source_hal_client_->Start(audio_framework_source_config, audioSinkReceiver, dsa_modes);
1485 
1486     /* We use same frame duration for sink/source */
1487     audio_framework_sink_config.data_interval_us = frame_duration_us * codec_frame_blocks_per_sdu;
1488 
1489     /* If group supports more than 16kHz for the microphone in converstional
1490      * case let's use that also for Audio Framework.
1491      */
1492     auto sink_configuration = group->GetAudioSessionCodecConfigForDirection(
1493             LeAudioContextType::CONVERSATIONAL,
1494             bluetooth::le_audio::types::kLeAudioDirectionSource);
1495     if (!sink_configuration.IsInvalid() &&
1496         sink_configuration.sample_rate > bluetooth::audio::le_audio::kSampleRate16000) {
1497       audio_framework_sink_config.sample_rate = sink_configuration.sample_rate;
1498     }
1499 
1500     le_audio_sink_hal_client_->Start(audio_framework_sink_config, audioSourceReceiver, dsa_modes);
1501   }
1502 
isOutputPreferenceLeAudio(const RawAddress & address)1503   bool isOutputPreferenceLeAudio(const RawAddress& address) {
1504     log::info("address: {}, active_group_id_: {}", address.ToStringForLogging(), active_group_id_);
1505     std::vector<RawAddress> active_leaudio_devices = GetGroupDevices(active_group_id_);
1506     if (std::find(active_leaudio_devices.begin(), active_leaudio_devices.end(), address) ==
1507         active_leaudio_devices.end()) {
1508       log::info("Device {} is not active for LE Audio", address.ToStringForLogging());
1509       return false;
1510     }
1511 
1512     LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
1513     log::info("active_group_id: {}, is_output_preference_le_audio_: {}", group->group_id_,
1514               group->is_output_preference_le_audio);
1515     return group->is_output_preference_le_audio;
1516   }
1517 
isDuplexPreferenceLeAudio(const RawAddress & address)1518   bool isDuplexPreferenceLeAudio(const RawAddress& address) {
1519     log::info("address: {}, active_group_id_: {}", address.ToStringForLogging(), active_group_id_);
1520     std::vector<RawAddress> active_leaudio_devices = GetGroupDevices(active_group_id_);
1521     if (std::find(active_leaudio_devices.begin(), active_leaudio_devices.end(), address) ==
1522         active_leaudio_devices.end()) {
1523       log::info("Device {} is not active for LE Audio", address.ToStringForLogging());
1524       return false;
1525     }
1526 
1527     LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
1528     log::info("active_group_id: {}, is_duplex_preference_le_audio: {}", group->group_id_,
1529               group->is_duplex_preference_le_audio);
1530     return group->is_duplex_preference_le_audio;
1531   }
1532 
groupSetAndNotifyInactive(void)1533   void groupSetAndNotifyInactive(void) {
1534     if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
1535       return;
1536     }
1537     sink_monitor_notified_status_ = std::nullopt;
1538     source_monitor_notified_status_ = std::nullopt;
1539     log::info("Group id: {}", active_group_id_);
1540 
1541     StopSuspendTimeout();
1542 
1543     StopAudio();
1544     ClientAudioInterfaceRelease();
1545 
1546     callbacks_->OnGroupStatus(active_group_id_, GroupStatus::INACTIVE);
1547     active_group_id_ = bluetooth::groups::kGroupUnknown;
1548   }
1549 
PrepareStreamForAConversational(LeAudioDeviceGroup * group)1550   void PrepareStreamForAConversational(LeAudioDeviceGroup* group) {
1551     if (!com::android::bluetooth::flags::leaudio_improve_switch_during_phone_call()) {
1552       log::info("Flag leaudio_improve_switch_during_phone_call is not enabled");
1553       return;
1554     }
1555 
1556     log::debug("group_id: {}", group->group_id_);
1557 
1558     auto remote_direction = bluetooth::le_audio::types::kLeAudioDirectionSink;
1559     ReconfigureOrUpdateRemote(group, remote_direction);
1560 
1561     if (configuration_context_type_ != LeAudioContextType::CONVERSATIONAL) {
1562       log::error("Something went wrong {} != {} ", ToString(configuration_context_type_),
1563                  ToString(LeAudioContextType::CONVERSATIONAL));
1564       return;
1565     }
1566 
1567     BidirectionalPair<std::vector<uint8_t>> ccids = {
1568             .sink = ContentControlIdKeeper::GetInstance()->GetAllCcids(
1569                     local_metadata_context_types_.sink),
1570             .source = ContentControlIdKeeper::GetInstance()->GetAllCcids(
1571                     local_metadata_context_types_.source)};
1572     if (!groupStateMachine_->ConfigureStream(group, configuration_context_type_,
1573                                              local_metadata_context_types_, ccids, true)) {
1574       log::info("Reconfiguration is needed for group {}", group->group_id_);
1575       initReconfiguration(group, LeAudioContextType::UNSPECIFIED);
1576     }
1577   }
1578 
GroupSetActive(const int group_id)1579   void GroupSetActive(const int group_id) override {
1580     log::info("group_id: {}", group_id);
1581 
1582     if (group_id == bluetooth::groups::kGroupUnknown) {
1583       if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
1584         callbacks_->OnGroupStatus(group_id, GroupStatus::INACTIVE);
1585         /* Nothing to do */
1586         return;
1587       }
1588 
1589       log::info("Active group_id changed {} -> {}", active_group_id_, group_id);
1590       auto group_id_to_close = active_group_id_;
1591       groupSetAndNotifyInactive();
1592       GroupStop(group_id_to_close);
1593 
1594       return;
1595     }
1596 
1597     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1598     if (!group) {
1599       log::error("Invalid group: {}", static_cast<int>(group_id));
1600       callbacks_->OnGroupStatus(group_id, GroupStatus::INACTIVE);
1601       return;
1602     }
1603 
1604     if (group->NumOfConnected() == 0) {
1605       log::error("Group: {} is not connected anymore", static_cast<int>(group_id));
1606       callbacks_->OnGroupStatus(group_id, GroupStatus::INACTIVE);
1607       return;
1608     }
1609 
1610     if (active_group_id_ != bluetooth::groups::kGroupUnknown) {
1611       if (active_group_id_ == group_id) {
1612         log::info("Group is already active: {}", static_cast<int>(active_group_id_));
1613         callbacks_->OnGroupStatus(active_group_id_, GroupStatus::ACTIVE);
1614         return;
1615       }
1616       log::info("switching active group to: {}", group_id);
1617 
1618       auto result = CodecManager::GetInstance()->UpdateActiveUnicastAudioHalClient(
1619               le_audio_source_hal_client_.get(), le_audio_sink_hal_client_.get(), false);
1620       log::assert_that(result, "Could not update session to codec manager");
1621     }
1622 
1623     if (!le_audio_source_hal_client_) {
1624       le_audio_source_hal_client_ = LeAudioSourceAudioHalClient::AcquireUnicast();
1625       if (!le_audio_source_hal_client_) {
1626         log::error("could not acquire audio source interface");
1627         callbacks_->OnGroupStatus(group_id, GroupStatus::INACTIVE);
1628         return;
1629       }
1630     }
1631 
1632     if (!le_audio_sink_hal_client_) {
1633       le_audio_sink_hal_client_ = LeAudioSinkAudioHalClient::AcquireUnicast();
1634       if (!le_audio_sink_hal_client_) {
1635         log::error("could not acquire audio sink interface");
1636         callbacks_->OnGroupStatus(group_id, GroupStatus::INACTIVE);
1637         return;
1638       }
1639     }
1640 
1641     auto result = CodecManager::GetInstance()->UpdateActiveUnicastAudioHalClient(
1642             le_audio_source_hal_client_.get(), le_audio_sink_hal_client_.get(), true);
1643     log::assert_that(result, "Could not update session to codec manager");
1644 
1645     /* Mini policy: Try configure audio HAL sessions with most recent context.
1646      * If reconfiguration is not needed it means, context type is not supported.
1647      * If most recent scenario is not supported, try to find first supported.
1648      */
1649     LeAudioContextType default_context_type = configuration_context_type_;
1650     if (!group->IsAudioSetConfigurationAvailable(default_context_type)) {
1651       if (group->IsAudioSetConfigurationAvailable(LeAudioContextType::UNSPECIFIED)) {
1652         default_context_type = LeAudioContextType::UNSPECIFIED;
1653         default_context_type = LeAudioContextType::UNSPECIFIED;
1654       } else {
1655         for (LeAudioContextType context_type : kLeAudioContextAllTypesArray) {
1656           if (group->IsAudioSetConfigurationAvailable(context_type)) {
1657             default_context_type = context_type;
1658             break;
1659           }
1660         }
1661       }
1662     }
1663 
1664     /* Only update the configuration audio context and audio coding session
1665      * parameters if needed.
1666      */
1667     UpdateConfigAndCheckIfReconfigurationIsNeeded(group, default_context_type);
1668 
1669     auto previous_active_group = active_group_id_;
1670     log::info("Active group_id changed {} -> {}", previous_active_group, group_id);
1671 
1672     if (previous_active_group == bluetooth::groups::kGroupUnknown) {
1673       /* Expose audio sessions if there was no previous active group */
1674       StartAudioSession(group);
1675       active_group_id_ = group_id;
1676     } else {
1677       /* In case there was an active group. Stop the stream, but before that, set
1678        * the new group so the group change is correctly handled in OnStateMachineStatusReportCb
1679        */
1680       active_group_id_ = group_id;
1681       SuspendedForReconfiguration();
1682       GroupStop(previous_active_group);
1683       /* Note: On purpose we are not sending INACTIVE status up to Java, because previous active
1684        * group will be provided in ACTIVE status. This is in order to have single call to audio
1685        * framework
1686        */
1687     }
1688 
1689     /* Reset sink and source listener notified status */
1690     sink_monitor_notified_status_ = std::nullopt;
1691     source_monitor_notified_status_ = std::nullopt;
1692     if (com::android::bluetooth::flags::leaudio_codec_config_callback_order_fix()) {
1693       SendAudioGroupSelectableCodecConfigChanged(group);
1694       SendAudioGroupCurrentCodecConfigChanged(group);
1695       callbacks_->OnGroupStatus(active_group_id_, GroupStatus::ACTIVE);
1696     } else {
1697       callbacks_->OnGroupStatus(active_group_id_, GroupStatus::ACTIVE);
1698       SendAudioGroupSelectableCodecConfigChanged(group);
1699     }
1700 
1701     /* If group become active while phone call, let's configure it right away,
1702      * so when audio framework resumes the stream, it will be almost there.
1703      */
1704     if (IsInCall()) {
1705       PrepareStreamForAConversational(group);
1706     }
1707   }
1708 
SetEnableState(const RawAddress & address,bool enabled)1709   void SetEnableState(const RawAddress& address, bool enabled) override {
1710     log::info("{}: {}", address, enabled ? "enabled" : "disabled");
1711     auto leAudioDevice = leAudioDevices_.FindByAddress(address);
1712     if (leAudioDevice == nullptr) {
1713       log::warn("{} is null", address);
1714       return;
1715     }
1716 
1717     auto group_id = leAudioDevice->group_id_;
1718     auto group = aseGroups_.FindById(group_id);
1719     if (group == nullptr) {
1720       log::warn("Group {} is not available", group_id);
1721       return;
1722     }
1723 
1724     if (enabled) {
1725       group->Enable(gatt_if_, reconnection_mode_);
1726     } else {
1727       group->Disable(gatt_if_);
1728     }
1729   }
1730 
RemoveDevice(const RawAddress & address)1731   void RemoveDevice(const RawAddress& address) override {
1732     log::info(": {}", address);
1733     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
1734     if (!leAudioDevice) {
1735       return;
1736     }
1737 
1738     /* Remove device from the background connect if it is there */
1739     BTA_GATTC_CancelOpen(gatt_if_, address, false);
1740     btif_storage_set_leaudio_autoconnect(address, false);
1741 
1742     log::info("{}, state: {}", address,
1743               bluetooth::common::ToString(leAudioDevice->GetConnectionState()));
1744     auto connection_state = leAudioDevice->GetConnectionState();
1745     switch (connection_state) {
1746       case DeviceConnectState::REMOVING:
1747         /* Just return, and let device disconnect */
1748         return;
1749       case DeviceConnectState::CONNECTED:
1750       case DeviceConnectState::CONNECTED_AUTOCONNECT_GETTING_READY:
1751       case DeviceConnectState::CONNECTED_BY_USER_GETTING_READY:
1752         /* ACL exist in this case, disconnect and mark as removing */
1753         Disconnect(address);
1754         [[fallthrough]];
1755       case DeviceConnectState::DISCONNECTING:
1756       case DeviceConnectState::DISCONNECTING_AND_RECOVER:
1757         /* Device is disconnecting, just mark it shall be removed after all. */
1758         leAudioDevice->SetConnectionState(DeviceConnectState::REMOVING);
1759         return;
1760       case DeviceConnectState::CONNECTING_AUTOCONNECT:
1761         /* Fallthrough as for AUTOCONNECT it might be that device is doing direct connect
1762          * in case of previous connection timeout.
1763          */
1764       case DeviceConnectState::CONNECTING_BY_USER:
1765         BTA_GATTC_CancelOpen(gatt_if_, address, true);
1766         leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED);
1767         break;
1768       case DeviceConnectState::DISCONNECTED:
1769         /* Do nothing, just remove device  */
1770         break;
1771     }
1772 
1773     /* Remove the group assignment if not yet removed. It might happen that the
1774      * group module has already called the appropriate callback and we have
1775      * already removed the group assignment.
1776      */
1777     if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
1778       auto group = aseGroups_.FindById(leAudioDevice->group_id_);
1779       group_remove_node(group, address, true);
1780     }
1781 
1782     leAudioDevices_.Remove(address);
1783   }
1784 
Connect(const RawAddress & address)1785   void Connect(const RawAddress& address) override {
1786     log::info(": {}", address);
1787 
1788     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
1789     if (!leAudioDevice) {
1790       if (!BTM_IsLinkKeyKnown(address, BT_TRANSPORT_LE)) {
1791         log::error("Connecting  {} when not bonded", address);
1792         callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, address);
1793         return;
1794       }
1795       leAudioDevices_.Add(address, DeviceConnectState::CONNECTING_BY_USER);
1796     } else {
1797       auto current_connect_state = leAudioDevice->GetConnectionState();
1798       if ((current_connect_state == DeviceConnectState::CONNECTED) ||
1799           (current_connect_state == DeviceConnectState::CONNECTING_BY_USER)) {
1800         log::error("Device {} is in invalid state: {}", leAudioDevice->address_,
1801                    bluetooth::common::ToString(current_connect_state));
1802 
1803         return;
1804       }
1805 
1806       if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
1807         auto group = GetGroupIfEnabled(leAudioDevice->group_id_);
1808         if (!group) {
1809           log::warn("{}, trying to connect to disabled group id {}", address,
1810                     leAudioDevice->group_id_);
1811           callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, address);
1812           return;
1813         }
1814       }
1815 
1816       leAudioDevice->SetConnectionState(DeviceConnectState::CONNECTING_BY_USER);
1817 
1818       bluetooth::le_audio::MetricsCollector::Get()->OnConnectionStateChanged(
1819               leAudioDevice->group_id_, address, ConnectionState::CONNECTING,
1820               bluetooth::le_audio::ConnectionStatus::SUCCESS);
1821     }
1822 
1823     BTA_GATTC_Open(gatt_if_, address, BTM_BLE_DIRECT_CONNECTION, false);
1824   }
1825 
GetGroupDevices(const int group_id)1826   std::vector<RawAddress> GetGroupDevices(const int group_id) override {
1827     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
1828     std::vector<RawAddress> all_group_device_addrs;
1829 
1830     if (group != nullptr) {
1831       LeAudioDevice* leAudioDevice = group->GetFirstDevice();
1832       while (leAudioDevice) {
1833         all_group_device_addrs.push_back(leAudioDevice->address_);
1834         leAudioDevice = group->GetNextDevice(leAudioDevice);
1835       };
1836     }
1837 
1838     return all_group_device_addrs;
1839   }
1840 
1841   /* Restore paired device from storage to recreate groups */
AddFromStorage(const RawAddress & address,bool autoconnect,int sink_audio_location,int source_audio_location,int sink_supported_context_types,int source_supported_context_types,const std::vector<uint8_t> & handles,const std::vector<uint8_t> & sink_pacs,const std::vector<uint8_t> & source_pacs,const std::vector<uint8_t> & ases)1842   void AddFromStorage(const RawAddress& address, bool autoconnect, int sink_audio_location,
1843                       int source_audio_location, int sink_supported_context_types,
1844                       int source_supported_context_types, const std::vector<uint8_t>& handles,
1845                       const std::vector<uint8_t>& sink_pacs,
1846                       const std::vector<uint8_t>& source_pacs, const std::vector<uint8_t>& ases) {
1847     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
1848 
1849     if (leAudioDevice) {
1850       log::error("Device is already loaded. Nothing to do.");
1851       return;
1852     }
1853 
1854     log::info(
1855             "restoring: {}, autoconnect {}, sink_audio_location: {}, "
1856             "source_audio_location: {}, sink_supported_context_types : 0x{:04x}, "
1857             "source_supported_context_types 0x{:04x}",
1858             address, autoconnect, sink_audio_location, source_audio_location,
1859             sink_supported_context_types, source_supported_context_types);
1860 
1861     leAudioDevices_.Add(address, DeviceConnectState::DISCONNECTED);
1862     leAudioDevice = leAudioDevices_.FindByAddress(address);
1863 
1864     int group_id =
1865             DeviceGroups::Get()->GetGroupId(address, bluetooth::le_audio::uuid::kCapServiceUuid);
1866     if (group_id != bluetooth::groups::kGroupUnknown) {
1867       group_add_node(group_id, address);
1868     }
1869 
1870     leAudioDevice->src_audio_locations_ = source_audio_location;
1871     leAudioDevice->snk_audio_locations_ = sink_audio_location;
1872     callbacks_->OnSinkAudioLocationAvailable(leAudioDevice->address_,
1873                                              leAudioDevice->snk_audio_locations_.to_ulong());
1874 
1875     BidirectionalPair<AudioContexts> supported_contexts = {
1876             .sink = AudioContexts(sink_supported_context_types),
1877             .source = AudioContexts(source_supported_context_types),
1878     };
1879 
1880     leAudioDevice->SetSupportedContexts(supported_contexts);
1881 
1882     /* Use same as supported ones for now. */
1883     leAudioDevice->SetAvailableContexts(supported_contexts);
1884 
1885     if (!DeserializeHandles(leAudioDevice, handles)) {
1886       log::warn("Could not load Handles");
1887     }
1888 
1889     /* Presence of PAC characteristic for a direction means support for that direction */
1890     if (leAudioDevice->src_audio_locations_hdls_.val_hdl != 0) {
1891       leAudioDevice->audio_directions_ |= bluetooth::le_audio::types::kLeAudioDirectionSource;
1892     }
1893     if (leAudioDevice->snk_audio_locations_hdls_.val_hdl != 0) {
1894       leAudioDevice->audio_directions_ |= bluetooth::le_audio::types::kLeAudioDirectionSink;
1895     }
1896 
1897     if (!DeserializeSinkPacs(leAudioDevice, sink_pacs)) {
1898       /* If PACs are invalid, just say whole cache is invalid */
1899       leAudioDevice->known_service_handles_ = false;
1900       log::warn("Could not load sink pacs");
1901     }
1902 
1903     if (!DeserializeSourcePacs(leAudioDevice, source_pacs)) {
1904       /* If PACs are invalid, just say whole cache is invalid */
1905       leAudioDevice->known_service_handles_ = false;
1906       log::warn("Could not load source pacs");
1907     }
1908 
1909     if (!DeserializeAses(leAudioDevice, ases)) {
1910       /* If ASEs are invalid, just say whole cache is invalid */
1911       leAudioDevice->known_service_handles_ = false;
1912       log::warn("Could not load ases");
1913     }
1914 
1915     leAudioDevice->autoconnect_flag_ = autoconnect;
1916     /* When adding from storage, make sure that autoconnect is used
1917      * by all the devices in the group.
1918      */
1919     leAudioDevices_.SetInitialGroupAutoconnectState(group_id, gatt_if_, reconnection_mode_,
1920                                                     autoconnect);
1921   }
1922 
GetHandlesForStorage(const RawAddress & addr,std::vector<uint8_t> & out)1923   bool GetHandlesForStorage(const RawAddress& addr, std::vector<uint8_t>& out) {
1924     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(addr);
1925     return SerializeHandles(leAudioDevice, out);
1926   }
1927 
GetSinkPacsForStorage(const RawAddress & addr,std::vector<uint8_t> & out)1928   bool GetSinkPacsForStorage(const RawAddress& addr, std::vector<uint8_t>& out) {
1929     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(addr);
1930     return SerializeSinkPacs(leAudioDevice, out);
1931   }
1932 
GetSourcePacsForStorage(const RawAddress & addr,std::vector<uint8_t> & out)1933   bool GetSourcePacsForStorage(const RawAddress& addr, std::vector<uint8_t>& out) {
1934     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(addr);
1935     return SerializeSourcePacs(leAudioDevice, out);
1936   }
1937 
GetAsesForStorage(const RawAddress & addr,std::vector<uint8_t> & out)1938   bool GetAsesForStorage(const RawAddress& addr, std::vector<uint8_t>& out) {
1939     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(addr);
1940 
1941     return SerializeAses(leAudioDevice, out);
1942   }
1943 
BackgroundConnectIfNeeded(LeAudioDevice * leAudioDevice)1944   void BackgroundConnectIfNeeded(LeAudioDevice* leAudioDevice) {
1945     if (!leAudioDevice->autoconnect_flag_) {
1946       log::debug("Device {} not in the background connect", leAudioDevice->address_);
1947       return;
1948     }
1949     AddToBackgroundConnectCheckGroupConnected(leAudioDevice);
1950   }
1951 
Disconnect(const RawAddress & address)1952   void Disconnect(const RawAddress& address) override {
1953     log::info(": {}", address);
1954     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
1955 
1956     if (!leAudioDevice) {
1957       log::warn("leAudioDevice not connected ( {} )", address);
1958       callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, address);
1959       return;
1960     }
1961 
1962     auto connection_state = leAudioDevice->GetConnectionState();
1963     log::info("{}, state: {}", address, bluetooth::common::ToString(connection_state));
1964 
1965     switch (connection_state) {
1966       case DeviceConnectState::CONNECTING_BY_USER:
1967         /* Timeout happen on the Java layer. Device probably not in the range.
1968          * Cancel just direct connection and keep background if it is there.
1969          */
1970         BTA_GATTC_CancelOpen(gatt_if_, address, true);
1971         /* If this is a device which is a part of the group which is connected,
1972          * lets start backgroup connect
1973          */
1974         BackgroundConnectIfNeeded(leAudioDevice);
1975         return;
1976       case DeviceConnectState::CONNECTED: {
1977         /* User is disconnecting the device, we shall remove the autoconnect
1978          * flag for this device and all others if not TA is used
1979          */
1980         /* If target announcement is used, do not remove autoconnect
1981          */
1982         bool remove_from_autoconnect =
1983                 (reconnection_mode_ != BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS);
1984 
1985         if (leAudioDevice->autoconnect_flag_ && remove_from_autoconnect) {
1986           log::info("Removing autoconnect flag for group_id {}", leAudioDevice->group_id_);
1987 
1988           /* Removes device from background connect */
1989           BTA_GATTC_CancelOpen(gatt_if_, address, false);
1990           btif_storage_set_leaudio_autoconnect(address, false);
1991           leAudioDevice->autoconnect_flag_ = false;
1992         }
1993 
1994         /* Make sure ACL is disconnected to avoid reconnecting immediately
1995          * when autoconnect with TA reconnection mechanism is used.
1996          */
1997         bool force_acl_disconnect = leAudioDevice->autoconnect_flag_;
1998 
1999         auto group = aseGroups_.FindById(leAudioDevice->group_id_);
2000         if (group) {
2001           /* Remove devices from auto connect mode */
2002           for (auto dev = group->GetFirstDevice(); dev; dev = group->GetNextDevice(dev)) {
2003             if (remove_from_autoconnect &&
2004                 (dev->GetConnectionState() == DeviceConnectState::CONNECTING_AUTOCONNECT)) {
2005               btif_storage_set_leaudio_autoconnect(dev->address_, false);
2006               dev->autoconnect_flag_ = false;
2007               BTA_GATTC_CancelOpen(gatt_if_, dev->address_, false);
2008               dev->SetConnectionState(DeviceConnectState::DISCONNECTED);
2009             }
2010           }
2011 
2012           /* If group is Streaming or is in transition for Streaming - lets stop it
2013            * and mark device to disconnect when stream is closed
2014            */
2015           if (group->IsStreaming() || !group->IsReleasingOrIdle()) {
2016             log::debug("group_id {} needs to stop streaming before {} disconnection",
2017                        group->group_id_, leAudioDevice->address_);
2018             leAudioDevice->closing_stream_for_disconnection_ = true;
2019             groupStateMachine_->StopStream(group);
2020             return;
2021           }
2022 
2023           if (group->IsReleasing()) {
2024             log::debug("group_id {} needs to stop streaming before {} disconnection",
2025                        group->group_id_, leAudioDevice->address_);
2026             /* Stream is releasing, wait till it is completed and then disconnect ACL. */
2027             leAudioDevice->closing_stream_for_disconnection_ = true;
2028             return;
2029           }
2030 
2031           force_acl_disconnect &= group->IsEnabled();
2032         }
2033 
2034         DisconnectDevice(leAudioDevice, force_acl_disconnect);
2035       }
2036         return;
2037       case DeviceConnectState::CONNECTED_BY_USER_GETTING_READY:
2038         /* Timeout happen on the Java layer before native got ready with the
2039          * device */
2040         DisconnectDevice(leAudioDevice);
2041         return;
2042       case DeviceConnectState::CONNECTED_AUTOCONNECT_GETTING_READY:
2043         /* Java is not aware about autoconnect actions,
2044          * therefore this should not happen.
2045          */
2046         log::warn("Should not happen - disconnect device");
2047         DisconnectDevice(leAudioDevice);
2048         return;
2049       case DeviceConnectState::DISCONNECTED:
2050       case DeviceConnectState::DISCONNECTING:
2051       case DeviceConnectState::DISCONNECTING_AND_RECOVER:
2052       case DeviceConnectState::CONNECTING_AUTOCONNECT:
2053       case DeviceConnectState::REMOVING:
2054         log::warn("{}, invalid state {}", address, bluetooth::common::ToString(connection_state));
2055         return;
2056     }
2057   }
2058 
DisconnectDevice(LeAudioDevice * leAudioDevice,bool acl_force_disconnect=false,bool recover=false)2059   void DisconnectDevice(LeAudioDevice* leAudioDevice, bool acl_force_disconnect = false,
2060                         bool recover = false) {
2061     if (leAudioDevice->conn_id_ == GATT_INVALID_CONN_ID) {
2062       return;
2063     }
2064 
2065     if (leAudioDevice->GetConnectionState() != DeviceConnectState::REMOVING) {
2066       leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTING);
2067     }
2068 
2069     BtaGattQueue::Clean(leAudioDevice->conn_id_);
2070 
2071     /* Remote in bad state, force ACL Disconnection. */
2072     if (acl_force_disconnect) {
2073       leAudioDevice->DisconnectAcl();
2074       if (recover) {
2075         leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTING_AND_RECOVER);
2076       }
2077     } else {
2078       BTA_GATTC_Close(leAudioDevice->conn_id_);
2079     }
2080   }
2081 
DeregisterNotifications(LeAudioDevice * leAudioDevice)2082   void DeregisterNotifications(LeAudioDevice* leAudioDevice) {
2083     /* GATTC will omit not registered previously handles */
2084     for (auto pac_tuple : leAudioDevice->snk_pacs_) {
2085       BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_,
2086                                            std::get<0>(pac_tuple).val_hdl);
2087     }
2088     for (auto pac_tuple : leAudioDevice->src_pacs_) {
2089       BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_,
2090                                            std::get<0>(pac_tuple).val_hdl);
2091     }
2092 
2093     if (leAudioDevice->snk_audio_locations_hdls_.val_hdl != 0) {
2094       BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_,
2095                                            leAudioDevice->snk_audio_locations_hdls_.val_hdl);
2096     }
2097     if (leAudioDevice->src_audio_locations_hdls_.val_hdl != 0) {
2098       BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_,
2099                                            leAudioDevice->src_audio_locations_hdls_.val_hdl);
2100     }
2101     if (leAudioDevice->audio_avail_hdls_.val_hdl != 0) {
2102       BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_,
2103                                            leAudioDevice->audio_avail_hdls_.val_hdl);
2104     }
2105     if (leAudioDevice->audio_supp_cont_hdls_.val_hdl != 0) {
2106       BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_,
2107                                            leAudioDevice->audio_supp_cont_hdls_.val_hdl);
2108     }
2109     if (leAudioDevice->ctp_hdls_.val_hdl != 0) {
2110       BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_,
2111                                            leAudioDevice->ctp_hdls_.val_hdl);
2112     }
2113 
2114     for (struct ase& ase : leAudioDevice->ases_) {
2115       BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_, ase.hdls.val_hdl);
2116     }
2117   }
2118 
handleInitialCtpCccRead(LeAudioDevice * leAudioDevice,uint16_t len,uint8_t * value)2119   void handleInitialCtpCccRead(LeAudioDevice* leAudioDevice, uint16_t len, uint8_t* value) {
2120     if (len != 2) {
2121       log::error("Could not read CCC for {}, disconnecting", leAudioDevice->address_);
2122       instance->Disconnect(leAudioDevice->address_);
2123       return;
2124     }
2125 
2126     uint16_t val = *(uint16_t*)value;
2127     if (val == 0) {
2128       log::warn("{} forgot CCC values. Re-subscribing", leAudioDevice->address_);
2129       RegisterKnownNotifications(leAudioDevice, false, true);
2130       return;
2131     }
2132 
2133     log::verbose("{}, ASCS ctp ccc: {:#x}", leAudioDevice->address_, val);
2134     connectionReady(leAudioDevice);
2135   }
2136 
2137   /* This is a generic read/notify/indicate handler for gatt. Here messages
2138    * are dispatched to correct elements e.g. ASEs, PACs, audio locations etc.
2139    */
LeAudioCharValueHandle(tCONN_ID conn_id,uint16_t hdl,uint16_t len,uint8_t * value,bool notify=false)2140   void LeAudioCharValueHandle(tCONN_ID conn_id, uint16_t hdl, uint16_t len, uint8_t* value,
2141                               bool notify = false) {
2142     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByConnId(conn_id);
2143     struct ase* ase;
2144 
2145     if (!leAudioDevice) {
2146       log::error("no leAudioDevice assigned to connection id: {}", conn_id);
2147       return;
2148     }
2149 
2150     ase = leAudioDevice->GetAseByValHandle(hdl);
2151     LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
2152     if (ase) {
2153       groupStateMachine_->ProcessGattNotifEvent(value, len, ase, leAudioDevice, group);
2154       return;
2155     }
2156 
2157     /* Initial CCC read to check if remote device properly keeps CCC values */
2158     if (hdl == leAudioDevice->ctp_hdls_.ccc_hdl) {
2159       handleInitialCtpCccRead(leAudioDevice, len, value);
2160       return;
2161     }
2162 
2163     auto snk_pac_ent =
2164             std::find_if(leAudioDevice->snk_pacs_.begin(), leAudioDevice->snk_pacs_.end(),
2165                          [&hdl](auto& pac_ent) { return std::get<0>(pac_ent).val_hdl == hdl; });
2166     if (snk_pac_ent != leAudioDevice->snk_pacs_.end()) {
2167       std::vector<struct bluetooth::le_audio::types::acs_ac_record> pac_recs;
2168 
2169       /* Guard consistency of PAC records structure */
2170       if (!bluetooth::le_audio::client_parser::pacs::ParsePacs(pac_recs, len, value)) {
2171         return;
2172       }
2173 
2174       log::info("Registering sink PACs");
2175       leAudioDevice->RegisterPACs(&std::get<1>(*snk_pac_ent), &pac_recs);
2176 
2177       /* Cached audio set configurations should be considered invalid when
2178        * PACs are updated.
2179        */
2180       if (group) {
2181         /* Changes in PAC record channel counts may change the strategy */
2182         group->InvalidateGroupStrategy();
2183         group->InvalidateCachedConfigurations();
2184       }
2185       if (notify) {
2186         btif_storage_leaudio_update_pacs_bin(leAudioDevice->address_);
2187       }
2188       return;
2189     }
2190 
2191     auto src_pac_ent =
2192             std::find_if(leAudioDevice->src_pacs_.begin(), leAudioDevice->src_pacs_.end(),
2193                          [&hdl](auto& pac_ent) { return std::get<0>(pac_ent).val_hdl == hdl; });
2194     if (src_pac_ent != leAudioDevice->src_pacs_.end()) {
2195       std::vector<struct bluetooth::le_audio::types::acs_ac_record> pac_recs;
2196 
2197       /* Guard consistency of PAC records structure */
2198       if (!bluetooth::le_audio::client_parser::pacs::ParsePacs(pac_recs, len, value)) {
2199         return;
2200       }
2201 
2202       log::info("Registering source PACs");
2203       leAudioDevice->RegisterPACs(&std::get<1>(*src_pac_ent), &pac_recs);
2204 
2205       /* Cached audio set configurations should be considered invalid when
2206        * PACs are updated.
2207        */
2208       if (group) {
2209         /* Changes in PAC record channel counts may change the strategy */
2210         group->InvalidateGroupStrategy();
2211         group->InvalidateCachedConfigurations();
2212       }
2213       if (notify) {
2214         btif_storage_leaudio_update_pacs_bin(leAudioDevice->address_);
2215       }
2216       return;
2217     }
2218 
2219     if (hdl == leAudioDevice->snk_audio_locations_hdls_.val_hdl) {
2220       AudioLocations snk_audio_locations;
2221 
2222       bluetooth::le_audio::client_parser::pacs::ParseAudioLocations(snk_audio_locations, len,
2223                                                                     value);
2224 
2225       /* Value may not change */
2226       if ((leAudioDevice->audio_directions_ & bluetooth::le_audio::types::kLeAudioDirectionSink) &&
2227           (leAudioDevice->snk_audio_locations_ ^ snk_audio_locations).none()) {
2228         return;
2229       }
2230 
2231       /* Presence of PAC characteristic for source means support for source
2232        * audio location. Value of 0x00000000 means mono/unspecified
2233        */
2234       leAudioDevice->audio_directions_ |= bluetooth::le_audio::types::kLeAudioDirectionSink;
2235       leAudioDevice->snk_audio_locations_ = snk_audio_locations;
2236 
2237       callbacks_->OnSinkAudioLocationAvailable(leAudioDevice->address_,
2238                                                snk_audio_locations.to_ulong());
2239 
2240       if (notify) {
2241         btif_storage_set_leaudio_audio_location(leAudioDevice->address_,
2242                                                 leAudioDevice->snk_audio_locations_.to_ulong(),
2243                                                 leAudioDevice->src_audio_locations_.to_ulong());
2244         if (group && group->IsReleasingOrIdle()) {
2245           UpdateLocationsAndContextsAvailability(group);
2246         }
2247       }
2248     } else if (hdl == leAudioDevice->src_audio_locations_hdls_.val_hdl) {
2249       AudioLocations src_audio_locations;
2250 
2251       bluetooth::le_audio::client_parser::pacs::ParseAudioLocations(src_audio_locations, len,
2252                                                                     value);
2253 
2254       /* Value may not change */
2255       if ((leAudioDevice->audio_directions_ &
2256            bluetooth::le_audio::types::kLeAudioDirectionSource) &&
2257           (leAudioDevice->src_audio_locations_ ^ src_audio_locations).none()) {
2258         return;
2259       }
2260 
2261       /* Presence of PAC characteristic for source means support for source
2262        * audio location. Value of 0x00000000 means mono/unspecified
2263        */
2264       leAudioDevice->audio_directions_ |= bluetooth::le_audio::types::kLeAudioDirectionSource;
2265       leAudioDevice->src_audio_locations_ = src_audio_locations;
2266 
2267       if (notify) {
2268         btif_storage_set_leaudio_audio_location(leAudioDevice->address_,
2269                                                 leAudioDevice->snk_audio_locations_.to_ulong(),
2270                                                 leAudioDevice->src_audio_locations_.to_ulong());
2271         if (group && group->IsReleasingOrIdle()) {
2272           UpdateLocationsAndContextsAvailability(group);
2273         }
2274       }
2275     } else if (hdl == leAudioDevice->audio_avail_hdls_.val_hdl) {
2276       BidirectionalPair<AudioContexts> contexts;
2277       if (!bluetooth::le_audio::client_parser::pacs::ParseAvailableAudioContexts(contexts, len,
2278                                                                                  value)) {
2279         return;
2280       }
2281 
2282       leAudioDevice->SetAvailableContexts(contexts);
2283 
2284       if (!group) {
2285         return;
2286       }
2287 
2288       if (group->IsInTransition()) {
2289         /* Group is in transition.
2290          * if group is going to stream, schedule attaching the device to the
2291          * group.
2292          */
2293 
2294         if (group->GetTargetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
2295           AttachToStreamingGroupIfNeeded(leAudioDevice);
2296         }
2297         return;
2298       }
2299 
2300       if (!group->IsStreaming()) {
2301         /* Group is not streaming. Device does not have to be attach to the
2302          * stream, and we can update context availability for the group
2303          */
2304         UpdateLocationsAndContextsAvailability(group);
2305         return;
2306       }
2307 
2308       AttachToStreamingGroupIfNeeded(leAudioDevice);
2309 
2310     } else if (hdl == leAudioDevice->audio_supp_cont_hdls_.val_hdl) {
2311       BidirectionalPair<AudioContexts> supp_audio_contexts;
2312       if (bluetooth::le_audio::client_parser::pacs::ParseSupportedAudioContexts(supp_audio_contexts,
2313                                                                                 len, value)) {
2314         /* Just store if for now */
2315         leAudioDevice->SetSupportedContexts(supp_audio_contexts);
2316 
2317         btif_storage_set_leaudio_supported_context_types(leAudioDevice->address_,
2318                                                          supp_audio_contexts.sink.value(),
2319                                                          supp_audio_contexts.source.value());
2320       }
2321     } else if (hdl == leAudioDevice->ctp_hdls_.val_hdl) {
2322       groupStateMachine_->ProcessGattCtpNotification(group, value, len);
2323     } else if (hdl == leAudioDevice->tmap_role_hdl_) {
2324       bluetooth::le_audio::client_parser::tmap::ParseTmapRole(leAudioDevice->tmap_role_, len,
2325                                                               value);
2326     } else if (leAudioDevice->gmap_client_ != nullptr && GmapClient::IsGmapClientEnabled() &&
2327                hdl == leAudioDevice->gmap_client_->getRoleHandle()) {
2328       leAudioDevice->gmap_client_->parseAndSaveGmapRole(len, value);
2329     } else if (leAudioDevice->gmap_client_ != nullptr && GmapClient::IsGmapClientEnabled() &&
2330                hdl == leAudioDevice->gmap_client_->getUGTFeatureHandle()) {
2331       leAudioDevice->gmap_client_->parseAndSaveUGTFeature(len, value);
2332     } else {
2333       log::error("Unknown attribute read: 0x{:x}", hdl);
2334     }
2335   }
2336 
OnGattReadRsp(tCONN_ID conn_id,tGATT_STATUS,uint16_t hdl,uint16_t len,uint8_t * value,void *)2337   void OnGattReadRsp(tCONN_ID conn_id, tGATT_STATUS /*status*/, uint16_t hdl, uint16_t len,
2338                      uint8_t* value, void* /*data*/) {
2339     LeAudioCharValueHandle(conn_id, hdl, len, value);
2340   }
2341 
GetGroupIfEnabled(int group_id)2342   LeAudioDeviceGroup* GetGroupIfEnabled(int group_id) {
2343     auto group = aseGroups_.FindById(group_id);
2344     if (group == nullptr) {
2345       log::info("Group {} does not exist", group_id);
2346       return nullptr;
2347     }
2348     if (!group->IsEnabled()) {
2349       log::info("Group {} is disabled", group_id);
2350       return nullptr;
2351     }
2352     return group;
2353   }
2354 
AddToBackgroundConnectCheckGroupConnected(LeAudioDevice * leAudioDevice)2355   void AddToBackgroundConnectCheckGroupConnected(LeAudioDevice* leAudioDevice) {
2356     /* If device belongs to streaming group, add it on allow list */
2357     auto address = leAudioDevice->address_;
2358     auto group = GetGroupIfEnabled(leAudioDevice->group_id_);
2359     if (group == nullptr) {
2360       log::info("Group {} is invalid or disabled", leAudioDevice->group_id_);
2361       return;
2362     }
2363 
2364     leAudioDevice->SetConnectionState(DeviceConnectState::CONNECTING_AUTOCONNECT);
2365 
2366     /* Cancel previous bakcground connect */
2367     BTA_GATTC_CancelOpen(gatt_if_, address, false);
2368     if (group->IsAnyDeviceConnected()) {
2369       log::info("Group {} in connected state. Adding {} to allow list", leAudioDevice->group_id_,
2370                 address);
2371       BTA_GATTC_Open(gatt_if_, address, BTM_BLE_BKG_CONNECT_ALLOW_LIST, false);
2372     } else {
2373       log::info("Adding {} to background connect (default reconnection_mode (0x{:02x}))", address,
2374                 reconnection_mode_);
2375       BTA_GATTC_Open(gatt_if_, address, reconnection_mode_, false);
2376     }
2377   }
2378 
OnGattConnected(tGATT_STATUS status,tCONN_ID conn_id,tGATT_IF,RawAddress address,tBT_TRANSPORT transport,uint16_t mtu)2379   void OnGattConnected(tGATT_STATUS status, tCONN_ID conn_id, tGATT_IF /*client_if*/,
2380                        RawAddress address, tBT_TRANSPORT transport, uint16_t mtu) {
2381     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
2382 
2383     log::info("{}, conn_id=0x{:04x}, transport={}, status={} (0x{:02x})", address, conn_id,
2384               bt_transport_text(transport), gatt_status_text(status), status);
2385 
2386     if (transport != BT_TRANSPORT_LE) {
2387       log::warn("Only LE connection is allowed (transport {})", bt_transport_text(transport));
2388       BTA_GATTC_Close(conn_id);
2389       return;
2390     }
2391 
2392     if (!leAudioDevice) {
2393       return;
2394     }
2395 
2396     if (leAudioDevice->conn_id_ != GATT_INVALID_CONN_ID) {
2397       log::debug("Already connected {}, conn_id=0x{:04x}", address, leAudioDevice->conn_id_);
2398       return;
2399     }
2400 
2401     if (status != GATT_SUCCESS) {
2402       /* Clear current connection request and let it be set again if needed */
2403       BTA_GATTC_CancelOpen(gatt_if_, address, false);
2404 
2405       /* autoconnect connection failed, that's ok */
2406       if (status != GATT_ILLEGAL_PARAMETER &&
2407           (leAudioDevice->GetConnectionState() == DeviceConnectState::CONNECTING_AUTOCONNECT ||
2408            leAudioDevice->autoconnect_flag_)) {
2409         log::info("Device not available now, do background connect.");
2410         leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED);
2411         AddToBackgroundConnectCheckGroupConnected(leAudioDevice);
2412         return;
2413       }
2414 
2415       leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED);
2416 
2417       log::error("Failed to connect to LeAudio leAudioDevice, status: 0x{:02x}", status);
2418       callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, address);
2419       bluetooth::le_audio::MetricsCollector::Get()->OnConnectionStateChanged(
2420               leAudioDevice->group_id_, address, ConnectionState::CONNECTED,
2421               bluetooth::le_audio::ConnectionStatus::FAILED);
2422       return;
2423     }
2424 
2425     if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
2426       auto group = GetGroupIfEnabled(leAudioDevice->group_id_);
2427       if (group == nullptr) {
2428         BTA_GATTC_CancelOpen(gatt_if_, address, false);
2429 
2430         log::warn("LeAudio profile is disabled for group_id: {}. {} is not connected",
2431                   leAudioDevice->group_id_, address);
2432         return;
2433       }
2434     }
2435 
2436     leAudioDevice->conn_id_ = conn_id;
2437     leAudioDevice->mtu_ = mtu;
2438     if (com::android::bluetooth::flags::gatt_queue_cleanup_connected()) {
2439       BtaGattQueue::Clean(conn_id);
2440     }
2441 
2442     /* Remove device from the background connect (it might be either Allow list
2443      * or TA) and add it again with reconnection_mode_. In case it is TA, we are
2444      * sure that device will not be in the allow list for other applications
2445      * which are using background connect.
2446      */
2447     BTA_GATTC_CancelOpen(gatt_if_, address, false);
2448     BTA_GATTC_Open(gatt_if_, address, reconnection_mode_, false);
2449 
2450     if (bluetooth::shim::GetController()->SupportsBle2mPhy()) {
2451       log::info("{} set preferred PHY to 2M", address);
2452       get_btm_client_interface().ble.BTM_BleSetPhy(address, PHY_LE_2M, PHY_LE_2M, 0);
2453     }
2454 
2455     get_btm_client_interface().peer.BTM_RequestPeerSCA(leAudioDevice->address_, transport);
2456 
2457     if (leAudioDevice->GetConnectionState() == DeviceConnectState::CONNECTING_AUTOCONNECT) {
2458       leAudioDevice->SetConnectionState(DeviceConnectState::CONNECTED_AUTOCONNECT_GETTING_READY);
2459     } else {
2460       leAudioDevice->SetConnectionState(DeviceConnectState::CONNECTED_BY_USER_GETTING_READY);
2461     }
2462 
2463     /* Check if the device is in allow list and update the flag */
2464     leAudioDevice->UpdateDeviceAllowlistFlag();
2465     if (BTM_SecIsSecurityPending(address)) {
2466       /* if security collision happened, wait for encryption done
2467        * (BTA_GATTC_ENC_CMPL_CB_EVT) */
2468       return;
2469     }
2470 
2471     /* verify bond */
2472     if (BTM_IsEncrypted(address, BT_TRANSPORT_LE)) {
2473       /* if link has been encrypted */
2474       OnEncryptionComplete(address, tBTM_STATUS::BTM_SUCCESS);
2475       return;
2476     }
2477 
2478     tBTM_STATUS result =
2479             BTM_SetEncryption(address, BT_TRANSPORT_LE, nullptr, nullptr, BTM_BLE_SEC_ENCRYPT);
2480 
2481     log::info("Encryption required for {}. Request result: 0x{:02x}", address, result);
2482 
2483     if (result == tBTM_STATUS::BTM_ERR_KEY_MISSING) {
2484       log::error("Link key unknown for {}, disconnect profile", address);
2485       bluetooth::le_audio::MetricsCollector::Get()->OnConnectionStateChanged(
2486               leAudioDevice->group_id_, address, ConnectionState::CONNECTED,
2487               bluetooth::le_audio::ConnectionStatus::FAILED);
2488 
2489       /* If link cannot be enctypted, disconnect profile */
2490       BTA_GATTC_Close(conn_id);
2491     }
2492   }
2493 
RegisterKnownNotifications(LeAudioDevice * leAudioDevice,bool gatt_register,bool write_ccc)2494   void RegisterKnownNotifications(LeAudioDevice* leAudioDevice, bool gatt_register,
2495                                   bool write_ccc) {
2496     log::info("device: {}", leAudioDevice->address_);
2497 
2498     if (leAudioDevice->ctp_hdls_.val_hdl == 0) {
2499       log::error("Control point characteristic is mandatory - disconnecting device {}",
2500                  leAudioDevice->address_);
2501       DisconnectDevice(leAudioDevice);
2502       return;
2503     }
2504 
2505     /* GATTC will omit not registered previously handles */
2506     for (auto pac_tuple : leAudioDevice->snk_pacs_) {
2507       subscribe_for_notification(leAudioDevice->conn_id_, leAudioDevice->address_,
2508                                  std::get<0>(pac_tuple), gatt_register, write_ccc);
2509     }
2510     for (auto pac_tuple : leAudioDevice->src_pacs_) {
2511       subscribe_for_notification(leAudioDevice->conn_id_, leAudioDevice->address_,
2512                                  std::get<0>(pac_tuple), gatt_register, write_ccc);
2513     }
2514 
2515     if (leAudioDevice->snk_audio_locations_hdls_.val_hdl != 0) {
2516       subscribe_for_notification(leAudioDevice->conn_id_, leAudioDevice->address_,
2517                                  leAudioDevice->snk_audio_locations_hdls_, gatt_register,
2518                                  write_ccc);
2519     }
2520     if (leAudioDevice->src_audio_locations_hdls_.val_hdl != 0) {
2521       subscribe_for_notification(leAudioDevice->conn_id_, leAudioDevice->address_,
2522                                  leAudioDevice->src_audio_locations_hdls_, gatt_register,
2523                                  write_ccc);
2524     }
2525 
2526     if (leAudioDevice->audio_avail_hdls_.val_hdl != 0) {
2527       subscribe_for_notification(leAudioDevice->conn_id_, leAudioDevice->address_,
2528                                  leAudioDevice->audio_avail_hdls_, gatt_register, write_ccc);
2529     }
2530 
2531     if (leAudioDevice->audio_supp_cont_hdls_.val_hdl != 0) {
2532       subscribe_for_notification(leAudioDevice->conn_id_, leAudioDevice->address_,
2533                                  leAudioDevice->audio_supp_cont_hdls_, gatt_register, write_ccc);
2534     }
2535 
2536     for (struct ase& ase : leAudioDevice->ases_) {
2537       subscribe_for_notification(leAudioDevice->conn_id_, leAudioDevice->address_, ase.hdls,
2538                                  gatt_register, write_ccc);
2539     }
2540 
2541     subscribe_for_notification(leAudioDevice->conn_id_, leAudioDevice->address_,
2542                                leAudioDevice->ctp_hdls_, gatt_register, write_ccc);
2543   }
2544 
changeMtuIfPossible(LeAudioDevice * leAudioDevice)2545   void changeMtuIfPossible(LeAudioDevice* leAudioDevice) {
2546     if (leAudioDevice->mtu_ == GATT_DEF_BLE_MTU_SIZE) {
2547       log::info("Configure MTU");
2548       /* Use here kBapMinimumAttMtu, because we know that GATT will request
2549        * default ATT MTU anyways. We also know that GATT will use this
2550        * kBapMinimumAttMtu as an input for Data Length Update procedure in the controller.
2551        */
2552       BtaGattQueue::ConfigureMtu(leAudioDevice->conn_id_, kBapMinimumAttMtu);
2553     }
2554   }
2555 
ReadMustHaveAttributesOnReconnect(LeAudioDevice * leAudioDevice)2556   void ReadMustHaveAttributesOnReconnect(LeAudioDevice* leAudioDevice) {
2557     log::verbose("{}", leAudioDevice->address_);
2558     /* Here we read
2559      * 1) ASCS Control Point CCC descriptor in order to validate proper
2560      *    behavior of remote device which should store CCC values for bonded device.
2561      * 2) Available Context Types which normally should be notified by the server,
2562      *    but since it is crucial for proper streaming experiance, and in the same time
2563      *    it can change very often which, as we observed, might lead to not being sent by
2564      *    remote devices
2565      */
2566     if (!com::android::bluetooth::flags::le_ase_read_multiple_variable()) {
2567       BtaGattQueue::ReadCharacteristic(leAudioDevice->conn_id_,
2568                                        leAudioDevice->audio_avail_hdls_.val_hdl,
2569                                        OnGattReadRspStatic, NULL);
2570       BtaGattQueue::ReadCharacteristic(leAudioDevice->conn_id_, leAudioDevice->ctp_hdls_.ccc_hdl,
2571                                        OnGattReadRspStatic, NULL);
2572     } else {
2573       tBTA_GATTC_MULTI multi_read = {.num_attr = 2,
2574                                      .handles = {leAudioDevice->audio_avail_hdls_.val_hdl,
2575                                                  leAudioDevice->ctp_hdls_.ccc_hdl}};
2576 
2577       BtaGattQueue::ReadMultiCharacteristic(leAudioDevice->conn_id_, multi_read,
2578                                             OnGattReadMultiRspStatic, NULL);
2579     }
2580   }
2581 
OnEncryptionComplete(const RawAddress & address,tBTM_STATUS status)2582   void OnEncryptionComplete(const RawAddress& address, tBTM_STATUS status) {
2583     log::info("{} status 0x{:02x}", address, status);
2584     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
2585     if (leAudioDevice == NULL || (leAudioDevice->conn_id_ == GATT_INVALID_CONN_ID)) {
2586       log::warn("Skipping device which is {}",
2587                 leAudioDevice ? " not connected by service." : " null");
2588       return;
2589     }
2590 
2591     if (status != tBTM_STATUS::BTM_SUCCESS) {
2592       log::error("Encryption failed status: {}", btm_status_text(status));
2593       if (leAudioDevice->GetConnectionState() ==
2594           DeviceConnectState::CONNECTED_BY_USER_GETTING_READY) {
2595         callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, address);
2596         bluetooth::le_audio::MetricsCollector::Get()->OnConnectionStateChanged(
2597                 leAudioDevice->group_id_, address, ConnectionState::CONNECTED,
2598                 bluetooth::le_audio::ConnectionStatus::FAILED);
2599       }
2600 
2601       leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTING);
2602 
2603       BTA_GATTC_Close(leAudioDevice->conn_id_);
2604       return;
2605     }
2606 
2607     if (leAudioDevice->encrypted_) {
2608       log::info("link already encrypted, nothing to do");
2609       return;
2610     }
2611 
2612     /* If PHY update did not succeed after ACL connection, which can happen
2613      * when remote feature read was not that quick, lets try to change phy here
2614      * one more time
2615      */
2616     if (!leAudioDevice->acl_phy_update_done_ &&
2617         bluetooth::shim::GetController()->SupportsBle2mPhy()) {
2618       log::info("{} set preferred PHY to 2M", leAudioDevice->address_);
2619       get_btm_client_interface().ble.BTM_BleSetPhy(address, PHY_LE_2M, PHY_LE_2M, 0);
2620     }
2621 
2622     changeMtuIfPossible(leAudioDevice);
2623 
2624     leAudioDevice->encrypted_ = true;
2625 
2626     /* If we know services, register for notifications */
2627     if (leAudioDevice->known_service_handles_) {
2628       /* This registration will do subscribtion in local GATT as we
2629        * assume remote device keeps bonded CCC values.
2630        */
2631       RegisterKnownNotifications(leAudioDevice, true, false);
2632       ReadMustHaveAttributesOnReconnect(leAudioDevice);
2633     }
2634 
2635     /* If we know services and read is not ongoing, this is reconnection and
2636      * just notify connected  */
2637     if (leAudioDevice->known_service_handles_ && !leAudioDevice->notify_connected_after_read_) {
2638       log::info("Wait for CCC registration and MTU change request");
2639       return;
2640     }
2641 
2642     BTA_GATTC_ServiceSearchRequest(leAudioDevice->conn_id_,
2643                                    bluetooth::le_audio::uuid::kPublishedAudioCapabilityServiceUuid);
2644   }
2645 
checkGroupConnectionStateAfterMemberDisconnect(int group_id)2646   void checkGroupConnectionStateAfterMemberDisconnect(int group_id) {
2647     /* This is fired t=kGroupConnectedWatchDelayMs after group member
2648      * got disconnected while either group members were connected.
2649      * We want to check here if there is any group member connected.
2650      * If so we should add other group members to allow list for better
2651      * reconnection experience. If  all group members are disconnected
2652      * i e.g. devices intentionally disconnected for other
2653      * purposes like pairing with other device, then we do nothing here and
2654      * device stay on the default reconnection policy (i.e. targeted
2655      * announcements)
2656      */
2657     auto group = aseGroups_.FindById(group_id);
2658     if (group == nullptr) {
2659       log::info("Group {} is destroyed.", group_id);
2660       return;
2661     }
2662 
2663     if (!group->IsAnyDeviceConnected()) {
2664       log::info("Group {} is not connected", group_id);
2665       /* Make sure all devices are in the default reconnection mode */
2666       group->ApplyReconnectionMode(gatt_if_, reconnection_mode_);
2667       return;
2668     }
2669 
2670     /* if group is still connected, make sure that other not connected
2671      * set members are in the allow list for the quick reconnect.
2672      * E.g. for the earbud case, probably one of the earbud is in the case now.
2673      */
2674     group->AddToAllowListNotConnectedGroupMembers(gatt_if_);
2675   }
2676 
scheduleGroupConnectedCheck(int group_id)2677   void scheduleGroupConnectedCheck(int group_id) {
2678     log::info("Schedule group_id {} connected check.", group_id);
2679     do_in_main_thread_delayed(
2680             base::BindOnce(&LeAudioClientImpl::checkGroupConnectionStateAfterMemberDisconnect,
2681                            weak_factory_.GetWeakPtr(), group_id),
2682             std::chrono::milliseconds(kGroupConnectedWatchDelayMs));
2683   }
2684 
autoConnect(RawAddress address)2685   void autoConnect(RawAddress address) {
2686     auto leAudioDevice = leAudioDevices_.FindByAddress(address);
2687     if (leAudioDevice == nullptr) {
2688       log::warn("Device {} not valid anymore", address);
2689       return;
2690     }
2691 
2692     BackgroundConnectIfNeeded(leAudioDevice);
2693   }
2694 
scheduleAutoConnect(RawAddress & address)2695   void scheduleAutoConnect(RawAddress& address) {
2696     log::info("Schedule auto connect {}", address);
2697     do_in_main_thread_delayed(
2698             base::BindOnce(&LeAudioClientImpl::autoConnect, weak_factory_.GetWeakPtr(), address),
2699             std::chrono::milliseconds(kAutoConnectAfterOwnDisconnectDelayMs));
2700   }
2701 
recoveryReconnect(RawAddress address)2702   void recoveryReconnect(RawAddress address) {
2703     log::info("Reconnecting to {} after timeout on state machine.", address);
2704     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
2705 
2706     if (leAudioDevice == nullptr ||
2707         leAudioDevice->GetConnectionState() != DeviceConnectState::DISCONNECTING_AND_RECOVER) {
2708       log::warn("Device {}, not interested in recovery connect anymore", address);
2709       return;
2710     }
2711 
2712     auto group = GetGroupIfEnabled(leAudioDevice->group_id_);
2713 
2714     if (group != nullptr) {
2715       leAudioDevice->SetConnectionState(DeviceConnectState::CONNECTING_AUTOCONNECT);
2716       BTA_GATTC_Open(gatt_if_, address, BTM_BLE_DIRECT_CONNECTION, false);
2717     } else {
2718       leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED);
2719     }
2720   }
2721 
scheduleRecoveryReconnect(RawAddress & address)2722   void scheduleRecoveryReconnect(RawAddress& address) {
2723     log::info("Schedule reconnecting to {} after timeout on state machine.", address);
2724     do_in_main_thread_delayed(base::BindOnce(&LeAudioClientImpl::recoveryReconnect,
2725                                              weak_factory_.GetWeakPtr(), address),
2726                               std::chrono::milliseconds(kRecoveryReconnectDelayMs));
2727   }
2728 
checkIfGroupMember(RawAddress address)2729   void checkIfGroupMember(RawAddress address) {
2730     log::info("checking being a group member: {}", address);
2731     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
2732 
2733     if (leAudioDevice == nullptr) {
2734       log::warn("Device {}, probably removed", address);
2735       return;
2736     }
2737 
2738     if (leAudioDevice->group_id_ == bluetooth::groups::kGroupUnknown) {
2739       disconnectInvalidDevice(leAudioDevice, ", device not a valid group member",
2740                               LeAudioHealthDeviceStatType::INVALID_CSIS);
2741       return;
2742     }
2743   }
2744 
2745   /* This is called, when CSIS native module is about to add device to the
2746    * group once the CSIS service will be verified on the remote side.
2747    * After some time (kCsisGroupMemberDelayMs)  a checkIfGroupMember will be
2748    * called and will verify if the remote device has a group_id properly set.
2749    * if not, it means there is something wrong with CSIS service on the remote
2750    * side.
2751    */
scheduleGuardForCsisAdd(RawAddress & address)2752   void scheduleGuardForCsisAdd(RawAddress& address) {
2753     log::info("Schedule reconnecting to {} after timeout on state machine.", address);
2754     do_in_main_thread_delayed(base::BindOnce(&LeAudioClientImpl::checkIfGroupMember,
2755                                              weak_factory_.GetWeakPtr(), address),
2756                               std::chrono::milliseconds(kCsisGroupMemberDelayMs));
2757   }
2758 
OnGattDisconnected(tCONN_ID conn_id,tGATT_IF,RawAddress address,tGATT_DISCONN_REASON reason)2759   void OnGattDisconnected(tCONN_ID conn_id, tGATT_IF /*client_if*/, RawAddress address,
2760                           tGATT_DISCONN_REASON reason) {
2761     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByConnId(conn_id);
2762 
2763     if (!leAudioDevice) {
2764       log::error(", skipping unknown leAudioDevice, address: {}", address);
2765       return;
2766     }
2767 
2768     leAudioDevice->acl_asymmetric_ = false;
2769     BtaGattQueue::Clean(leAudioDevice->conn_id_);
2770     LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
2771 
2772     DeregisterNotifications(leAudioDevice);
2773 
2774     callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, address);
2775     leAudioDevice->conn_id_ = GATT_INVALID_CONN_ID;
2776     leAudioDevice->mtu_ = 0;
2777     leAudioDevice->closing_stream_for_disconnection_ = false;
2778     leAudioDevice->encrypted_ = false;
2779     leAudioDevice->acl_phy_update_done_ = false;
2780 
2781     auto connection_state = leAudioDevice->GetConnectionState();
2782 
2783     leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED);
2784 
2785     groupStateMachine_->ProcessHciNotifAclDisconnected(group, leAudioDevice);
2786 
2787     bluetooth::le_audio::MetricsCollector::Get()->OnConnectionStateChanged(
2788             leAudioDevice->group_id_, address, ConnectionState::DISCONNECTED,
2789             bluetooth::le_audio::ConnectionStatus::SUCCESS);
2790 
2791     if (connection_state == DeviceConnectState::REMOVING) {
2792       if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
2793         auto group = aseGroups_.FindById(leAudioDevice->group_id_);
2794         group_remove_node(group, address, true);
2795       }
2796       leAudioDevices_.Remove(address);
2797       return;
2798     }
2799 
2800     log::info("{}, autoconnect {}, reason 0x{:02x}, connection state {}", leAudioDevice->address_,
2801               leAudioDevice->autoconnect_flag_, reason,
2802               bluetooth::common::ToString(connection_state));
2803 
2804     if (connection_state == DeviceConnectState::DISCONNECTING_AND_RECOVER) {
2805       /* We are back after disconnecting device which was in a bad state.
2806        * lets try to reconnected - 30 sec with direct connect and later fallback
2807        * to default background reconnection mode.
2808        * Since GATT notifies us before ACL was dropped, let's wait a bit
2809        * before we do reconnect.
2810        *
2811        * Also, make sure that device has state which allows to do recover
2812        */
2813       leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTING_AND_RECOVER);
2814       scheduleRecoveryReconnect(address);
2815       return;
2816     }
2817 
2818     /* Attempt background re-connect if disconnect was not initiated locally
2819      * or if autoconnect is set and device got disconnected because of some
2820      * issues
2821      */
2822     if (group == nullptr || !group->IsEnabled()) {
2823       log::error("Group id {} ({}) disabled or null", leAudioDevice->group_id_,
2824                  std::format_ptr(group));
2825       return;
2826     }
2827 
2828     if (reason == GATT_CONN_TERMINATE_LOCAL_HOST) {
2829       if (leAudioDevice->autoconnect_flag_) {
2830         /* In this case ACL might not yet been disconnected */
2831         scheduleAutoConnect(address);
2832       }
2833       return;
2834     }
2835 
2836     /* Remote disconnects from us or Timeout happens */
2837     /* In this case ACL is disconnected */
2838     if (reason == GATT_CONN_TIMEOUT) {
2839       leAudioDevice->SetConnectionState(DeviceConnectState::CONNECTING_AUTOCONNECT);
2840 
2841       /* If timeout try to reconnect for 30 sec.*/
2842       BTA_GATTC_Open(gatt_if_, address, BTM_BLE_DIRECT_CONNECTION, false);
2843       return;
2844     }
2845 
2846     /* In other disconnect resons we act based on the autoconnect_flag_ */
2847     if (leAudioDevice->autoconnect_flag_) {
2848       if (group->IsAnyDeviceConnected()) {
2849         /* If all set is disconnecting, let's give it some time.
2850          * If not all get disconnected, and there will be group member
2851          * connected we want to put disconnected devices to allow list
2852          */
2853         scheduleGroupConnectedCheck(leAudioDevice->group_id_);
2854       } else {
2855         group->ApplyReconnectionMode(gatt_if_, reconnection_mode_);
2856       }
2857     }
2858   }
2859 
subscribe_for_notification(tCONN_ID conn_id,const RawAddress & address,struct bluetooth::le_audio::types::hdl_pair handle_pair,bool gatt_register=true,bool write_ccc=true)2860   bool subscribe_for_notification(tCONN_ID conn_id, const RawAddress& address,
2861                                   struct bluetooth::le_audio::types::hdl_pair handle_pair,
2862                                   bool gatt_register = true, bool write_ccc = true) {
2863     std::vector<uint8_t> value(2);
2864     uint8_t* ptr = value.data();
2865     uint16_t handle = handle_pair.val_hdl;
2866     uint16_t ccc_handle = handle_pair.ccc_hdl;
2867 
2868     log::info("conn id {}, gatt_register: {}, write_ccc: {}", conn_id, gatt_register, write_ccc);
2869     if (gatt_register &&
2870         BTA_GATTC_RegisterForNotifications(gatt_if_, address, handle) != GATT_SUCCESS) {
2871       log::error("cannot register for notification: {}", static_cast<int>(handle));
2872       return false;
2873     }
2874 
2875     if (write_ccc == false) {
2876       log::verbose("CCC is not written to {} (0x{:04x}), handle 0x{:04x}", address, conn_id,
2877                    ccc_handle);
2878       return true;
2879     }
2880 
2881     UINT16_TO_STREAM(ptr, GATT_CHAR_CLIENT_CONFIG_NOTIFICATION);
2882 
2883     BtaGattQueue::WriteDescriptor(
2884             conn_id, ccc_handle, std::move(value), GATT_WRITE,
2885             [](tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t /*len*/,
2886                const uint8_t* /*value*/, void* data) {
2887               if (instance) {
2888                 instance->OnGattWriteCcc(conn_id, status, handle, data);
2889               }
2890             },
2891             nullptr);
2892     return true;
2893   }
2894 
2895   /* Find the handle for the client characteristics configuration of a given
2896    * characteristics.
2897    */
find_ccc_handle(const gatt::Characteristic & charac)2898   uint16_t find_ccc_handle(const gatt::Characteristic& charac) {
2899     auto iter = std::find_if(charac.descriptors.begin(), charac.descriptors.end(),
2900                              [](const auto& desc) {
2901                                return desc.uuid == Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG);
2902                              });
2903 
2904     return iter == charac.descriptors.end() ? 0 : (*iter).handle;
2905   }
2906 
ClearDeviceInformationAndStartSearch(LeAudioDevice * leAudioDevice)2907   void ClearDeviceInformationAndStartSearch(LeAudioDevice* leAudioDevice) {
2908     if (!leAudioDevice) {
2909       log::warn("leAudioDevice is null");
2910       return;
2911     }
2912 
2913     log::info("{}", leAudioDevice->address_);
2914 
2915     if (leAudioDevice->known_service_handles_ == false) {
2916       log::debug("Database already invalidated");
2917       return;
2918     }
2919 
2920     leAudioDevice->known_service_handles_ = false;
2921     leAudioDevice->csis_member_ = false;
2922     BtaGattQueue::Clean(leAudioDevice->conn_id_);
2923     DeregisterNotifications(leAudioDevice);
2924 
2925     if (leAudioDevice->GetConnectionState() == DeviceConnectState::CONNECTED) {
2926       leAudioDevice->SetConnectionState(DeviceConnectState::CONNECTED_BY_USER_GETTING_READY);
2927     }
2928 
2929     btif_storage_leaudio_clear_service_data(leAudioDevice->address_);
2930 
2931     BTA_GATTC_ServiceSearchRequest(leAudioDevice->conn_id_,
2932                                    bluetooth::le_audio::uuid::kPublishedAudioCapabilityServiceUuid);
2933   }
2934 
OnServiceChangeEvent(const RawAddress & address)2935   void OnServiceChangeEvent(const RawAddress& address) {
2936     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
2937     if (!leAudioDevice) {
2938       log::warn("Skipping unknown leAudioDevice {} ({})", address, std::format_ptr(leAudioDevice));
2939       return;
2940     }
2941 
2942     if (leAudioDevice->conn_id_ != GATT_INVALID_CONN_ID) {
2943       ClearDeviceInformationAndStartSearch(leAudioDevice);
2944       return;
2945     }
2946 
2947     /* If device is not connected, just clear the handle information and this
2948      * will trigger service search onGattConnected */
2949     leAudioDevice->known_service_handles_ = false;
2950     btif_storage_leaudio_clear_service_data(address);
2951   }
2952 
OnMtuChanged(tCONN_ID conn_id,uint16_t mtu)2953   void OnMtuChanged(tCONN_ID conn_id, uint16_t mtu) {
2954     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByConnId(conn_id);
2955     if (!leAudioDevice) {
2956       log::debug("Unknown connectect id {}", conn_id);
2957       return;
2958     }
2959 
2960     /**
2961      * BAP 1.01. 3.6.1
2962      * ATT and EATT transport requirements
2963      * The Unicast Client shall support a minimum ATT_MTU of 64 octets for one
2964      * Unenhanced ATT bearer, or for at least one Enhanced ATT bearer if the
2965      * Unicast Client supports Enhanced ATT bearers.
2966      *
2967      */
2968     if (mtu < 64) {
2969       log::error("Device {} MTU is too low ({}). Disconnecting from LE Audio",
2970                  leAudioDevice->address_, mtu);
2971       Disconnect(leAudioDevice->address_);
2972       return;
2973     }
2974 
2975     leAudioDevice->mtu_ = mtu;
2976   }
2977 
OnPhyUpdate(tCONN_ID conn_id,uint8_t tx_phy,uint8_t rx_phy,tGATT_STATUS status)2978   void OnPhyUpdate(tCONN_ID conn_id, uint8_t tx_phy, uint8_t rx_phy, tGATT_STATUS status) {
2979     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByConnId(conn_id);
2980     if (leAudioDevice == nullptr) {
2981       log::debug("Unknown conn_id {:#x}", conn_id);
2982       return;
2983     }
2984 
2985     log::info("{}, tx_phy: {:#x}, rx_phy: {:#x} , status: {:#x}", leAudioDevice->address_, tx_phy,
2986               rx_phy, status);
2987 
2988     if (status == 0) {
2989       leAudioDevice->acl_phy_update_done_ = true;
2990     }
2991   }
2992 
OnGattServiceDiscoveryDone(const RawAddress & address)2993   void OnGattServiceDiscoveryDone(const RawAddress& address) {
2994     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(address);
2995     if (!leAudioDevice || (leAudioDevice->conn_id_ == GATT_INVALID_CONN_ID)) {
2996       log::verbose("skipping unknown leAudioDevice, address {} ({})", address,
2997                    std::format_ptr(leAudioDevice));
2998       return;
2999     }
3000 
3001     if (!leAudioDevice->encrypted_) {
3002       log::debug("Wait for device to be encrypted");
3003       return;
3004     }
3005 
3006     if (!leAudioDevice->known_service_handles_) {
3007       BTA_GATTC_ServiceSearchRequest(
3008               leAudioDevice->conn_id_,
3009               bluetooth::le_audio::uuid::kPublishedAudioCapabilityServiceUuid);
3010     }
3011   }
3012 
disconnectInvalidDevice(LeAudioDevice * leAudioDevice,std::string error_string,LeAudioHealthDeviceStatType stat)3013   void disconnectInvalidDevice(LeAudioDevice* leAudioDevice, std::string error_string,
3014                                LeAudioHealthDeviceStatType stat) {
3015     log::error("{}, {}", leAudioDevice->address_, error_string);
3016     if (leAudioHealthStatus_) {
3017       leAudioHealthStatus_->AddStatisticForDevice(leAudioDevice, stat);
3018     }
3019     DisconnectDevice(leAudioDevice);
3020   }
3021 
3022   /* This method is called after connection beginning to identify and initialize
3023    * a le audio device. Any missing mandatory attribute will result in reverting
3024    * and cleaning up device.
3025    */
OnServiceSearchComplete(tCONN_ID conn_id,tGATT_STATUS status)3026   void OnServiceSearchComplete(tCONN_ID conn_id, tGATT_STATUS status) {
3027     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByConnId(conn_id);
3028 
3029     if (!leAudioDevice) {
3030       log::error("skipping unknown leAudioDevice, conn_id: 0x{:x}", conn_id);
3031       return;
3032     }
3033 
3034     log::info("test csis_member {}", leAudioDevice->csis_member_);
3035 
3036     if (status != GATT_SUCCESS) {
3037       /* close connection and report service discovery complete with error */
3038       log::error("Service discovery failed");
3039 
3040       DisconnectDevice(leAudioDevice);
3041       return;
3042     }
3043 
3044     if (!leAudioDevice->encrypted_) {
3045       log::warn("Device not yet bonded - waiting for encryption");
3046       return;
3047     }
3048 
3049     const std::list<gatt::Service>* services = BTA_GATTC_GetServices(conn_id);
3050 
3051     const gatt::Service* pac_svc = nullptr;
3052     const gatt::Service* ase_svc = nullptr;
3053     const gatt::Service* tmas_svc = nullptr;
3054     const gatt::Service* gmap_svc = nullptr;
3055 
3056     std::vector<uint16_t> csis_primary_handles;
3057     uint16_t cas_csis_included_handle = 0;
3058 
3059     for (const gatt::Service& tmp : *services) {
3060       if (tmp.uuid == bluetooth::le_audio::uuid::kPublishedAudioCapabilityServiceUuid) {
3061         log::info("Found Audio Capability service, handle: 0x{:04x}, device: {}", tmp.handle,
3062                   leAudioDevice->address_);
3063         pac_svc = &tmp;
3064       } else if (tmp.uuid == bluetooth::le_audio::uuid::kAudioStreamControlServiceUuid) {
3065         log::info("Found Audio Stream Endpoint service, handle: 0x{:04x}, device: {}", tmp.handle,
3066                   leAudioDevice->address_);
3067         ase_svc = &tmp;
3068       } else if (tmp.uuid == bluetooth::csis::kCsisServiceUuid) {
3069         log::info("Found CSIS service, handle: 0x{:04x}, is primary: {}, device: {}", tmp.handle,
3070                   tmp.is_primary, leAudioDevice->address_);
3071         if (tmp.is_primary) {
3072           csis_primary_handles.push_back(tmp.handle);
3073         }
3074       } else if (tmp.uuid == bluetooth::le_audio::uuid::kCapServiceUuid) {
3075         log::info("Found CAP service, handle: 0x{:04x}, device: {}", tmp.handle,
3076                   leAudioDevice->address_);
3077 
3078         /* Try to find context for CSIS instances */
3079         for (auto& included_srvc : tmp.included_services) {
3080           if (included_srvc.uuid == bluetooth::csis::kCsisServiceUuid) {
3081             log::info("CSIS included into CAS");
3082             if (bluetooth::csis::CsisClient::IsCsisClientRunning()) {
3083               cas_csis_included_handle = included_srvc.start_handle;
3084             }
3085 
3086             break;
3087           }
3088         }
3089       } else if (tmp.uuid == bluetooth::le_audio::uuid::kTelephonyMediaAudioServiceUuid) {
3090         log::info("Found Telephony and Media Audio service, handle: 0x{:04x}, device: {}",
3091                   tmp.handle, leAudioDevice->address_);
3092         tmas_svc = &tmp;
3093       } else if (tmp.uuid == bluetooth::le_audio::uuid::kGamingAudioServiceUuid) {
3094         log::info("Found Gaming Audio service, handle: 0x{:04x}, device: {}", tmp.handle,
3095                   leAudioDevice->address_);
3096         gmap_svc = &tmp;
3097       }
3098     }
3099 
3100     /* Check if CAS includes primary CSIS service */
3101     if (!csis_primary_handles.empty() && cas_csis_included_handle) {
3102       auto iter = std::find(csis_primary_handles.begin(), csis_primary_handles.end(),
3103                             cas_csis_included_handle);
3104       if (iter != csis_primary_handles.end()) {
3105         leAudioDevice->csis_member_ = true;
3106       }
3107     }
3108 
3109     if (!pac_svc || !ase_svc) {
3110       disconnectInvalidDevice(leAudioDevice, "No mandatory le audio services found (pacs or ascs)",
3111                               LeAudioHealthDeviceStatType::INVALID_DB);
3112       return;
3113     }
3114 
3115     /* Refresh PACs handles */
3116     leAudioDevice->ClearPACs();
3117 
3118     for (const gatt::Characteristic& charac : pac_svc->characteristics) {
3119       if (charac.uuid ==
3120           bluetooth::le_audio::uuid::kSinkPublishedAudioCapabilityCharacteristicUuid) {
3121         struct hdl_pair hdl_pair;
3122         hdl_pair.val_hdl = charac.value_handle;
3123         hdl_pair.ccc_hdl = find_ccc_handle(charac);
3124 
3125         if (hdl_pair.ccc_hdl == 0) {
3126           log::info(", Sink PACs ccc not available");
3127         }
3128 
3129         if (hdl_pair.ccc_hdl != 0 &&
3130             !subscribe_for_notification(conn_id, leAudioDevice->address_, hdl_pair)) {
3131           disconnectInvalidDevice(leAudioDevice, ", could not subscribe for snk pac char",
3132                                   LeAudioHealthDeviceStatType::INVALID_DB);
3133           return;
3134         }
3135 
3136         /* Obtain initial state of sink PACs */
3137         BtaGattQueue::ReadCharacteristic(conn_id, hdl_pair.val_hdl, OnGattReadRspStatic, NULL);
3138 
3139         leAudioDevice->snk_pacs_.push_back(std::make_tuple(
3140                 hdl_pair, std::vector<struct bluetooth::le_audio::types::acs_ac_record>()));
3141 
3142         log::info("Found Sink PAC characteristic, handle: 0x{:04x}, ccc handle: 0x{:04x}, addr: {}",
3143                   charac.value_handle, hdl_pair.ccc_hdl, leAudioDevice->address_);
3144       } else if (charac.uuid ==
3145                  bluetooth::le_audio::uuid::kSourcePublishedAudioCapabilityCharacteristicUuid) {
3146         struct hdl_pair hdl_pair;
3147         hdl_pair.val_hdl = charac.value_handle;
3148         hdl_pair.ccc_hdl = find_ccc_handle(charac);
3149 
3150         if (hdl_pair.ccc_hdl == 0) {
3151           log::info(", Source PACs ccc not available");
3152         }
3153 
3154         if (hdl_pair.ccc_hdl != 0 &&
3155             !subscribe_for_notification(conn_id, leAudioDevice->address_, hdl_pair)) {
3156           disconnectInvalidDevice(leAudioDevice, ", could not subscribe for src pac char",
3157                                   LeAudioHealthDeviceStatType::INVALID_DB);
3158           return;
3159         }
3160 
3161         /* Obtain initial state of source PACs */
3162         BtaGattQueue::ReadCharacteristic(conn_id, hdl_pair.val_hdl, OnGattReadRspStatic, NULL);
3163 
3164         leAudioDevice->src_pacs_.push_back(std::make_tuple(
3165                 hdl_pair, std::vector<struct bluetooth::le_audio::types::acs_ac_record>()));
3166 
3167         log::info(
3168                 "Found Source PAC characteristic, handle: 0x{:04x}, ccc handle: 0x{:04x}, addr: {}",
3169                 charac.value_handle, hdl_pair.ccc_hdl, leAudioDevice->address_);
3170       } else if (charac.uuid == bluetooth::le_audio::uuid::kSinkAudioLocationCharacteristicUuid) {
3171         leAudioDevice->snk_audio_locations_hdls_.val_hdl = charac.value_handle;
3172         leAudioDevice->snk_audio_locations_hdls_.ccc_hdl = find_ccc_handle(charac);
3173 
3174         if (leAudioDevice->snk_audio_locations_hdls_.ccc_hdl == 0) {
3175           log::info(", snk audio locations char doesn't have ccc");
3176         }
3177 
3178         if (leAudioDevice->snk_audio_locations_hdls_.ccc_hdl != 0 &&
3179             !subscribe_for_notification(conn_id, leAudioDevice->address_,
3180                                         leAudioDevice->snk_audio_locations_hdls_)) {
3181           disconnectInvalidDevice(leAudioDevice, ", could not subscribe for snk locations char",
3182                                   LeAudioHealthDeviceStatType::INVALID_DB);
3183           return;
3184         }
3185 
3186         /* Obtain initial state of sink audio locations */
3187         BtaGattQueue::ReadCharacteristic(conn_id, leAudioDevice->snk_audio_locations_hdls_.val_hdl,
3188                                          OnGattReadRspStatic, NULL);
3189 
3190         log::info(
3191                 "Found Sink audio locations characteristic, handle: 0x{:04x}, ccc "
3192                 "handle: 0x{:04x}, addr: {}",
3193                 charac.value_handle, leAudioDevice->snk_audio_locations_hdls_.ccc_hdl,
3194                 leAudioDevice->address_);
3195       } else if (charac.uuid == bluetooth::le_audio::uuid::kSourceAudioLocationCharacteristicUuid) {
3196         leAudioDevice->src_audio_locations_hdls_.val_hdl = charac.value_handle;
3197         leAudioDevice->src_audio_locations_hdls_.ccc_hdl = find_ccc_handle(charac);
3198 
3199         if (leAudioDevice->src_audio_locations_hdls_.ccc_hdl == 0) {
3200           log::info(", src audio locations char doesn't have ccc");
3201         }
3202 
3203         if (leAudioDevice->src_audio_locations_hdls_.ccc_hdl != 0 &&
3204             !subscribe_for_notification(conn_id, leAudioDevice->address_,
3205                                         leAudioDevice->src_audio_locations_hdls_)) {
3206           disconnectInvalidDevice(leAudioDevice, ", could not subscribe for src locations char",
3207                                   LeAudioHealthDeviceStatType::INVALID_DB);
3208           return;
3209         }
3210 
3211         /* Obtain initial state of source audio locations */
3212         BtaGattQueue::ReadCharacteristic(conn_id, leAudioDevice->src_audio_locations_hdls_.val_hdl,
3213                                          OnGattReadRspStatic, NULL);
3214 
3215         log::info(
3216                 "Found Source audio locations characteristic, handle: 0x{:04x}, "
3217                 "ccc handle: 0x{:04x}, addr: {}",
3218                 charac.value_handle, leAudioDevice->src_audio_locations_hdls_.ccc_hdl,
3219                 leAudioDevice->address_);
3220       } else if (charac.uuid ==
3221                  bluetooth::le_audio::uuid::kAudioContextAvailabilityCharacteristicUuid) {
3222         leAudioDevice->audio_avail_hdls_.val_hdl = charac.value_handle;
3223         leAudioDevice->audio_avail_hdls_.ccc_hdl = find_ccc_handle(charac);
3224 
3225         if (leAudioDevice->audio_avail_hdls_.ccc_hdl == 0) {
3226           disconnectInvalidDevice(leAudioDevice, ", audio avails char doesn't have ccc",
3227                                   LeAudioHealthDeviceStatType::INVALID_DB);
3228           return;
3229         }
3230 
3231         if (!subscribe_for_notification(conn_id, leAudioDevice->address_,
3232                                         leAudioDevice->audio_avail_hdls_)) {
3233           disconnectInvalidDevice(leAudioDevice, ", could not subscribe for audio avails char",
3234                                   LeAudioHealthDeviceStatType::INVALID_DB);
3235           return;
3236         }
3237 
3238         /* Obtain initial state */
3239         BtaGattQueue::ReadCharacteristic(conn_id, leAudioDevice->audio_avail_hdls_.val_hdl,
3240                                          OnGattReadRspStatic, NULL);
3241 
3242         log::info(
3243                 "Found Audio Availability Context characteristic, handle: "
3244                 "0x{:04x}, ccc handle: 0x{:04x}, addr: {}",
3245                 charac.value_handle, leAudioDevice->audio_avail_hdls_.ccc_hdl,
3246                 leAudioDevice->address_);
3247       } else if (charac.uuid ==
3248                  bluetooth::le_audio::uuid::kAudioSupportedContextCharacteristicUuid) {
3249         leAudioDevice->audio_supp_cont_hdls_.val_hdl = charac.value_handle;
3250         leAudioDevice->audio_supp_cont_hdls_.ccc_hdl = find_ccc_handle(charac);
3251 
3252         if (leAudioDevice->audio_supp_cont_hdls_.ccc_hdl == 0) {
3253           log::info(", audio supported char doesn't have ccc");
3254         }
3255 
3256         if (leAudioDevice->audio_supp_cont_hdls_.ccc_hdl != 0 &&
3257             !subscribe_for_notification(conn_id, leAudioDevice->address_,
3258                                         leAudioDevice->audio_supp_cont_hdls_)) {
3259           disconnectInvalidDevice(leAudioDevice,
3260                                   ", could not subscribe for audio supported ctx char",
3261                                   LeAudioHealthDeviceStatType::INVALID_DB);
3262           return;
3263         }
3264 
3265         /* Obtain initial state */
3266         BtaGattQueue::ReadCharacteristic(conn_id, leAudioDevice->audio_supp_cont_hdls_.val_hdl,
3267                                          OnGattReadRspStatic, NULL);
3268 
3269         log::info(
3270                 "Found Audio Supported Context characteristic, handle: 0x{:04x}, "
3271                 "ccc handle: 0x{:04x}, addr: {}",
3272                 charac.value_handle, leAudioDevice->audio_supp_cont_hdls_.ccc_hdl,
3273                 leAudioDevice->address_);
3274       }
3275     }
3276 
3277     /* Refresh ASE handles */
3278     leAudioDevice->ases_.clear();
3279 
3280     for (const gatt::Characteristic& charac : ase_svc->characteristics) {
3281       log::info("Found characteristic, uuid: {}", charac.uuid.ToString());
3282       if (charac.uuid == bluetooth::le_audio::uuid::kSinkAudioStreamEndpointUuid ||
3283           charac.uuid == bluetooth::le_audio::uuid::kSourceAudioStreamEndpointUuid) {
3284         uint16_t ccc_handle = find_ccc_handle(charac);
3285         if (ccc_handle == 0) {
3286           disconnectInvalidDevice(leAudioDevice, ", ASE char doesn't have ccc",
3287                                   LeAudioHealthDeviceStatType::INVALID_DB);
3288           return;
3289         }
3290         struct bluetooth::le_audio::types::hdl_pair hdls(charac.value_handle, ccc_handle);
3291         if (!subscribe_for_notification(conn_id, leAudioDevice->address_, hdls)) {
3292           disconnectInvalidDevice(leAudioDevice, ", could not subscribe ASE char",
3293                                   LeAudioHealthDeviceStatType::INVALID_DB);
3294           return;
3295         }
3296 
3297         int direction = charac.uuid == bluetooth::le_audio::uuid::kSinkAudioStreamEndpointUuid
3298                                 ? bluetooth::le_audio::types::kLeAudioDirectionSink
3299                                 : bluetooth::le_audio::types::kLeAudioDirectionSource;
3300 
3301         leAudioDevice->ases_.emplace_back(charac.value_handle, ccc_handle, direction);
3302 
3303         log::info(
3304                 "Found ASE characteristic, handle: 0x{:04x}, ccc handle: 0x{:04x}, "
3305                 "direction: {}, addr: {}",
3306                 charac.value_handle, ccc_handle, direction, leAudioDevice->address_);
3307       } else if (charac.uuid ==
3308                  bluetooth::le_audio::uuid::kAudioStreamEndpointControlPointCharacteristicUuid) {
3309         leAudioDevice->ctp_hdls_.val_hdl = charac.value_handle;
3310         leAudioDevice->ctp_hdls_.ccc_hdl = find_ccc_handle(charac);
3311 
3312         if (leAudioDevice->ctp_hdls_.ccc_hdl == 0) {
3313           disconnectInvalidDevice(leAudioDevice, ", ASE ctp doesn't have ccc",
3314                                   LeAudioHealthDeviceStatType::INVALID_DB);
3315           return;
3316         }
3317 
3318         if (!subscribe_for_notification(conn_id, leAudioDevice->address_,
3319                                         leAudioDevice->ctp_hdls_)) {
3320           disconnectInvalidDevice(leAudioDevice, ", could not subscribe ASE char",
3321                                   LeAudioHealthDeviceStatType::INVALID_DB);
3322           return;
3323         }
3324 
3325         log::info(
3326                 "Found ASE Control Point characteristic, handle: 0x{:04x}, ccc "
3327                 "handle: 0x{:04x}, addr: {}",
3328                 charac.value_handle, leAudioDevice->ctp_hdls_.ccc_hdl, leAudioDevice->address_);
3329       }
3330     }
3331 
3332     if (tmas_svc) {
3333       for (const gatt::Characteristic& charac : tmas_svc->characteristics) {
3334         if (charac.uuid ==
3335             bluetooth::le_audio::uuid::kTelephonyMediaAudioProfileRoleCharacteristicUuid) {
3336           leAudioDevice->tmap_role_hdl_ = charac.value_handle;
3337 
3338           /* Obtain initial state of TMAP role */
3339           BtaGattQueue::ReadCharacteristic(conn_id, leAudioDevice->tmap_role_hdl_,
3340                                            OnGattReadRspStatic, NULL);
3341 
3342           log::info(
3343                   "Found Telephony and Media Profile characteristic, handle: 0x{:04x}, device: {}",
3344                   leAudioDevice->tmap_role_hdl_, leAudioDevice->address_);
3345         }
3346       }
3347     }
3348 
3349     if (gmap_svc && GmapClient::IsGmapClientEnabled()) {
3350       leAudioDevice->gmap_client_ = std::make_unique<GmapClient>(leAudioDevice->address_);
3351       for (const gatt::Characteristic& charac : gmap_svc->characteristics) {
3352         if (charac.uuid == bluetooth::le_audio::uuid::kRoleCharacteristicUuid) {
3353           uint16_t handle = charac.value_handle;
3354           leAudioDevice->gmap_client_->setRoleHandle(handle);
3355           BtaGattQueue::ReadCharacteristic(conn_id, handle, OnGattReadRspStatic, NULL);
3356           log::info("Found Gmap Role characteristic, handle: 0x{:04x}, device: {}",
3357                     leAudioDevice->gmap_client_->getRoleHandle(), leAudioDevice->address_);
3358         }
3359         if (charac.uuid == bluetooth::le_audio::uuid::kUnicastGameTerminalCharacteristicUuid) {
3360           uint16_t handle = charac.value_handle;
3361           leAudioDevice->gmap_client_->setUGTFeatureHandle(handle);
3362           BtaGattQueue::ReadCharacteristic(conn_id, handle, OnGattReadRspStatic, NULL);
3363           log::info("Found Gmap UGT Feature characteristic, handle: 0x{:04x}, device: {}",
3364                     leAudioDevice->gmap_client_->getUGTFeatureHandle(), leAudioDevice->address_);
3365         }
3366       }
3367     }
3368 
3369     leAudioDevice->known_service_handles_ = true;
3370     leAudioDevice->notify_connected_after_read_ = true;
3371     if (leAudioHealthStatus_) {
3372       leAudioHealthStatus_->AddStatisticForDevice(leAudioDevice,
3373                                                   LeAudioHealthDeviceStatType::VALID_DB);
3374     }
3375 
3376     /* If already known group id */
3377     if (leAudioDevice->group_id_ != bluetooth::groups::kGroupUnknown) {
3378       AseInitialStateReadRequest(leAudioDevice);
3379       return;
3380     }
3381 
3382     /* If device does not belong to any group yet we either add it to the
3383      * group by our self now or wait for Csis to do it. In both cases, let's
3384      * check if group is already assigned.
3385      */
3386     int group_id = DeviceGroups::Get()->GetGroupId(leAudioDevice->address_,
3387                                                    bluetooth::le_audio::uuid::kCapServiceUuid);
3388     if (group_id != bluetooth::groups::kGroupUnknown) {
3389       instance->group_add_node(group_id, leAudioDevice->address_);
3390       return;
3391     }
3392 
3393     /* CSIS will trigger adding to group */
3394     if (leAudioDevice->csis_member_) {
3395       log::info("{},  waiting for CSIS to create group for device", leAudioDevice->address_);
3396       scheduleGuardForCsisAdd(leAudioDevice->address_);
3397       return;
3398     }
3399 
3400     log::info("{} Not a CSIS member. Create group by our own", leAudioDevice->address_);
3401 
3402     /* If there is no Csis just add device by our own */
3403     DeviceGroups::Get()->AddDevice(leAudioDevice->address_,
3404                                    bluetooth::le_audio::uuid::kCapServiceUuid);
3405   }
3406 
OnGattWriteCcc(tCONN_ID conn_id,tGATT_STATUS status,uint16_t hdl,void *)3407   void OnGattWriteCcc(tCONN_ID conn_id, tGATT_STATUS status, uint16_t hdl, void* /*data*/) {
3408     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByConnId(conn_id);
3409     std::vector<struct ase>::iterator ase_it;
3410 
3411     if (!leAudioDevice) {
3412       log::error("unknown conn_id=0x{:x}", conn_id);
3413       return;
3414     }
3415 
3416     if (status == GATT_DATABASE_OUT_OF_SYNC) {
3417       log::info("Database out of sync for {}, conn_id: 0x{:04x}", leAudioDevice->address_, conn_id);
3418       ClearDeviceInformationAndStartSearch(leAudioDevice);
3419       return;
3420     }
3421 
3422     if (status == GATT_SUCCESS) {
3423       log::info("Successfully registered on ccc: 0x{:04x}, device: {}", hdl,
3424                 leAudioDevice->address_);
3425 
3426       if (leAudioDevice->ctp_hdls_.ccc_hdl == hdl && leAudioDevice->known_service_handles_ &&
3427           !leAudioDevice->notify_connected_after_read_) {
3428         /* Reconnection case. Control point is the last CCC LeAudio is
3429          * registering for on reconnection */
3430         connectionReady(leAudioDevice);
3431       }
3432 
3433       return;
3434     }
3435 
3436     log::error("Failed to register for notifications: 0x{:04x}, device: {}, status: 0x{:02x}", hdl,
3437                leAudioDevice->address_, status);
3438 
3439     ase_it =
3440             std::find_if(leAudioDevice->ases_.begin(), leAudioDevice->ases_.end(),
3441                          [&hdl](const struct ase& ase) -> bool { return ase.hdls.ccc_hdl == hdl; });
3442 
3443     if (ase_it == leAudioDevice->ases_.end()) {
3444       log::error("Unknown ccc handle: 0x{:04x}, device: {}", hdl, leAudioDevice->address_);
3445       return;
3446     }
3447 
3448     BTA_GATTC_DeregisterForNotifications(gatt_if_, leAudioDevice->address_, ase_it->hdls.val_hdl);
3449   }
3450 
AttachToStreamingGroupIfNeeded(LeAudioDevice * leAudioDevice)3451   void AttachToStreamingGroupIfNeeded(LeAudioDevice* leAudioDevice) {
3452     if (leAudioDevice->group_id_ != active_group_id_) {
3453       log::info("group  {} is not streaming. Nothing to do", leAudioDevice->group_id_);
3454       return;
3455     }
3456 
3457     if (leAudioDevice->GetConnectionState() != DeviceConnectState::CONNECTED) {
3458       /* Do nothing, wait until device is connected */
3459       log::debug("{} is not yet connected", leAudioDevice->address_);
3460       return;
3461     }
3462 
3463     if (leAudioDevice->HaveActiveAse()) {
3464       log::debug("{} is already configured, nothing to do", leAudioDevice->address_);
3465       return;
3466     }
3467 
3468     LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
3469 
3470     auto group_metadata_contexts = get_bidirectional(group->GetMetadataContexts());
3471     auto device_available_contexts = leAudioDevice->GetAvailableContexts();
3472     if (!group_metadata_contexts.test_any(device_available_contexts)) {
3473       log::info("{} does is not have required context type", leAudioDevice->address_);
3474       return;
3475     }
3476 
3477     /* Restore configuration */
3478     auto* stream_conf = &group->stream_conf;
3479 
3480     if (audio_sender_state_ == AudioState::IDLE && audio_receiver_state_ == AudioState::IDLE) {
3481       log::debug("Device not streaming but active - nothing to do");
3482       return;
3483     }
3484 
3485     if (!stream_conf->conf) {
3486       log::info("Configuration not yet set. Nothing to do now");
3487       return;
3488     }
3489 
3490     log::info("Attaching {} to group: {}", leAudioDevice->address_, leAudioDevice->group_id_);
3491 
3492     for (auto direction : {bluetooth::le_audio::types::kLeAudioDirectionSink,
3493                            bluetooth::le_audio::types::kLeAudioDirectionSource}) {
3494       log::info("Looking for requirements: {} - {}", stream_conf->conf->name,
3495                 (direction == 1 ? "snk" : "src"));
3496       const auto& pacs = (direction == bluetooth::le_audio::types::kLeAudioDirectionSink)
3497                                  ? leAudioDevice->snk_pacs_
3498                                  : leAudioDevice->src_pacs_;
3499       for (const auto& ent : stream_conf->conf->confs.get(direction)) {
3500         if (!bluetooth::le_audio::utils::GetConfigurationSupportedPac(pacs, ent.codec)) {
3501           log::info("Configuration is not supported by device {}", leAudioDevice->address_);
3502 
3503           /* Reconfigure if newly connected member device cannot support
3504            * current codec configuration */
3505           initReconfiguration(group, configuration_context_type_);
3506           return;
3507         }
3508       }
3509     }
3510 
3511     /* Do not put the TBS CCID when not using Telecom for the VoIP calls. */
3512     auto ccid_contexts = group->GetMetadataContexts();
3513     if (IsInVoipCall() && !IsInCall()) {
3514       ccid_contexts.sink.unset(LeAudioContextType::CONVERSATIONAL);
3515       ccid_contexts.source.unset(LeAudioContextType::CONVERSATIONAL);
3516     }
3517     BidirectionalPair<std::vector<uint8_t>> ccids = {
3518             .sink = ContentControlIdKeeper::GetInstance()->GetAllCcids(ccid_contexts.sink),
3519             .source = ContentControlIdKeeper::GetInstance()->GetAllCcids(ccid_contexts.source)};
3520 
3521     if (!groupStateMachine_->AttachToStream(group, leAudioDevice, std::move(ccids))) {
3522       log::warn("Could not add device {} to the group {} streaming.", leAudioDevice->address_,
3523                 group->group_id_);
3524       scheduleAttachDeviceToTheStream(leAudioDevice->address_);
3525     } else {
3526       speed_start_setup(group->group_id_, configuration_context_type_, 1);
3527     }
3528   }
3529 
restartAttachToTheStream(const RawAddress & addr)3530   void restartAttachToTheStream(const RawAddress& addr) {
3531     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByAddress(addr);
3532     if (leAudioDevice == nullptr || leAudioDevice->conn_id_ == GATT_INVALID_CONN_ID) {
3533       log::info("Device {} not available anymore", addr);
3534       return;
3535     }
3536     AttachToStreamingGroupIfNeeded(leAudioDevice);
3537   }
3538 
scheduleAttachDeviceToTheStream(const RawAddress & addr)3539   void scheduleAttachDeviceToTheStream(const RawAddress& addr) {
3540     log::info("Device {} is scheduled for streaming", addr);
3541     do_in_main_thread_delayed(base::BindOnce(&LeAudioClientImpl::restartAttachToTheStream,
3542                                              weak_factory_.GetWeakPtr(), addr),
3543                               std::chrono::milliseconds(kDeviceAttachDelayMs));
3544   }
3545 
SendAudioGroupSelectableCodecConfigChanged(LeAudioDeviceGroup * group)3546   void SendAudioGroupSelectableCodecConfigChanged(LeAudioDeviceGroup* group) {
3547     auto leAudioDevice = group->GetFirstDevice();
3548     callbacks_->OnAudioGroupSelectableCodecConf(
3549             group->group_id_,
3550             bluetooth::le_audio::utils::GetRemoteBtLeAudioCodecConfigFromPac(
3551                     leAudioDevice->src_pacs_),
3552             bluetooth::le_audio::utils::GetRemoteBtLeAudioCodecConfigFromPac(
3553                     leAudioDevice->snk_pacs_));
3554   }
3555 
SendAudioGroupCurrentCodecConfigChanged(LeAudioDeviceGroup * group)3556   void SendAudioGroupCurrentCodecConfigChanged(LeAudioDeviceGroup* group) {
3557     // This shall be called when configuration changes
3558     log::debug("{}", group->group_id_);
3559 
3560     auto audio_set_conf = group->GetConfiguration(configuration_context_type_);
3561     if (!audio_set_conf) {
3562       log::warn("Stream configuration is not valid for group id {}", group->group_id_);
3563       return;
3564     }
3565 
3566     bluetooth::le_audio::btle_audio_codec_config_t input_config{};
3567     bluetooth::le_audio::utils::fillStreamParamsToBtLeAudioCodecConfig(audio_set_conf->confs.source,
3568                                                                        input_config);
3569 
3570     bluetooth::le_audio::btle_audio_codec_config_t output_config{};
3571     bluetooth::le_audio::utils::fillStreamParamsToBtLeAudioCodecConfig(audio_set_conf->confs.sink,
3572                                                                        output_config);
3573 
3574     callbacks_->OnAudioGroupCurrentCodecConf(group->group_id_, input_config, output_config);
3575   }
3576 
connectionReady(LeAudioDevice * leAudioDevice)3577   void connectionReady(LeAudioDevice* leAudioDevice) {
3578     log::debug("{},  {}", leAudioDevice->address_,
3579                bluetooth::common::ToString(leAudioDevice->GetConnectionState()));
3580 
3581     stack::l2cap::get_interface().L2CA_LockBleConnParamsForProfileConnection(
3582             leAudioDevice->address_, false);
3583 
3584     if (leAudioDevice->GetConnectionState() ==
3585                 DeviceConnectState::CONNECTED_BY_USER_GETTING_READY &&
3586         (leAudioDevice->autoconnect_flag_ == false)) {
3587       btif_storage_set_leaudio_autoconnect(leAudioDevice->address_, true);
3588       leAudioDevice->autoconnect_flag_ = true;
3589     }
3590 
3591     leAudioDevice->SetConnectionState(DeviceConnectState::CONNECTED);
3592     bluetooth::le_audio::MetricsCollector::Get()->OnConnectionStateChanged(
3593             leAudioDevice->group_id_, leAudioDevice->address_, ConnectionState::CONNECTED,
3594             bluetooth::le_audio::ConnectionStatus::SUCCESS);
3595 
3596     if (leAudioDevice->group_id_ == bluetooth::groups::kGroupUnknown) {
3597       log::warn("LeAudio device {} connected with no group", leAudioDevice->address_);
3598       callbacks_->OnConnectionState(ConnectionState::CONNECTED, leAudioDevice->address_);
3599       return;
3600     }
3601 
3602     LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
3603     if (group) {
3604       UpdateLocationsAndContextsAvailability(group, true);
3605     }
3606 
3607     /* Notify connected after contexts are notified */
3608     callbacks_->OnConnectionState(ConnectionState::CONNECTED, leAudioDevice->address_);
3609 
3610     AttachToStreamingGroupIfNeeded(leAudioDevice);
3611 
3612     if (reconnection_mode_ == BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS) {
3613       /* Add other devices to allow list if there are any not yet connected
3614        * from the group
3615        */
3616       group->AddToAllowListNotConnectedGroupMembers(gatt_if_);
3617     }
3618   }
3619 
IsAseAcceptingAudioData(struct ase * ase)3620   bool IsAseAcceptingAudioData(struct ase* ase) {
3621     if (ase == nullptr) {
3622       return false;
3623     }
3624     if (ase->state != AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
3625       return false;
3626     }
3627     if (ase->data_path_state != DataPathState::CONFIGURED) {
3628       return false;
3629     }
3630 
3631     return true;
3632   }
3633 
3634   // mix stero signal into mono
mono_blend(const std::vector<uint8_t> & buf,int bytes_per_sample,size_t frames)3635   std::vector<uint8_t> mono_blend(const std::vector<uint8_t>& buf, int bytes_per_sample,
3636                                   size_t frames) {
3637     std::vector<uint8_t> mono_out;
3638     mono_out.resize(frames * bytes_per_sample);
3639 
3640     if (bytes_per_sample == 2) {
3641       int16_t* out = (int16_t*)mono_out.data();
3642       const int16_t* in = (int16_t*)(buf.data());
3643       for (size_t i = 0; i < frames; ++i) {
3644         int accum = 0;
3645         accum += *in++;
3646         accum += *in++;
3647         accum /= 2;  // round to 0
3648         *out++ = accum;
3649       }
3650     } else if (bytes_per_sample == 4) {
3651       int32_t* out = (int32_t*)mono_out.data();
3652       const int32_t* in = (int32_t*)(buf.data());
3653       for (size_t i = 0; i < frames; ++i) {
3654         int accum = 0;
3655         accum += *in++;
3656         accum += *in++;
3657         accum /= 2;  // round to 0
3658         *out++ = accum;
3659       }
3660     } else {
3661       log::error("Don't know how to mono blend that {}!", bytes_per_sample);
3662     }
3663     return mono_out;
3664   }
3665 
PrepareAndSendToTwoCises(const std::vector<uint8_t> & data,const struct bluetooth::le_audio::stream_parameters & stream_params)3666   void PrepareAndSendToTwoCises(
3667           const std::vector<uint8_t>& data,
3668           const struct bluetooth::le_audio::stream_parameters& stream_params) {
3669     uint16_t left_cis_handle = 0;
3670     uint16_t right_cis_handle = 0;
3671 
3672     uint16_t number_of_required_samples_per_channel = sw_enc_left->GetNumOfSamplesPerChannel();
3673     uint8_t bytes_per_sample = sw_enc_left->GetNumOfBytesPerSample();
3674     if (data.size() <
3675         bytes_per_sample * 2 /* channels */ * number_of_required_samples_per_channel) {
3676       log::error("Missing samples. Data size: {} expected: {}", data.size(),
3677                  bytes_per_sample * 2 * number_of_required_samples_per_channel);
3678       return;
3679     }
3680 
3681     for (auto [cis_handle, audio_location] : stream_params.stream_locations) {
3682       if (audio_location & bluetooth::le_audio::codec_spec_conf::kLeAudioLocationAnyLeft) {
3683         left_cis_handle = cis_handle;
3684       }
3685       if (audio_location & bluetooth::le_audio::codec_spec_conf::kLeAudioLocationAnyRight) {
3686         right_cis_handle = cis_handle;
3687       }
3688     }
3689 
3690     if (stream_params.codec_frames_blocks_per_sdu != 1) {
3691       log::error("Codec Frame Blocks of {} is not supported by the software encoding",
3692                  +stream_params.codec_frames_blocks_per_sdu);
3693     }
3694 
3695     uint16_t byte_count = stream_params.octets_per_codec_frame;
3696     bool mix_to_mono = (left_cis_handle == 0) || (right_cis_handle == 0);
3697     if (mix_to_mono) {
3698       std::vector<uint8_t> mono =
3699               mono_blend(data, bytes_per_sample, number_of_required_samples_per_channel);
3700       if (left_cis_handle) {
3701         sw_enc_left->Encode(mono.data(), 1, byte_count);
3702       }
3703 
3704       if (right_cis_handle) {
3705         sw_enc_left->Encode(mono.data(), 1, byte_count);
3706       }
3707     } else {
3708       sw_enc_left->Encode(data.data(), 2, byte_count);
3709       sw_enc_right->Encode(data.data() + bytes_per_sample, 2, byte_count);
3710     }
3711 
3712     log::debug("left_cis_handle: {} right_cis_handle: {}", left_cis_handle, right_cis_handle);
3713     /* Send data to the controller */
3714     if (left_cis_handle) {
3715       IsoManager::GetInstance()->SendIsoData(
3716               left_cis_handle, (const uint8_t*)sw_enc_left->GetDecodedSamples().data(),
3717               sw_enc_left->GetDecodedSamples().size() * 2);
3718     }
3719 
3720     if (right_cis_handle) {
3721       IsoManager::GetInstance()->SendIsoData(
3722               right_cis_handle, (const uint8_t*)sw_enc_right->GetDecodedSamples().data(),
3723               sw_enc_right->GetDecodedSamples().size() * 2);
3724     }
3725   }
3726 
PrepareAndSendToSingleCis(const std::vector<uint8_t> & data,const struct bluetooth::le_audio::stream_parameters & stream_params)3727   void PrepareAndSendToSingleCis(
3728           const std::vector<uint8_t>& data,
3729           const struct bluetooth::le_audio::stream_parameters& stream_params) {
3730     uint16_t num_channels = stream_params.num_of_channels;
3731     uint16_t cis_handle = stream_params.stream_locations.front().first;
3732 
3733     uint16_t number_of_required_samples_per_channel = sw_enc_left->GetNumOfSamplesPerChannel();
3734     uint8_t bytes_per_sample = sw_enc_left->GetNumOfBytesPerSample();
3735     if ((int)data.size() <
3736         (bytes_per_sample * num_channels * number_of_required_samples_per_channel)) {
3737       log::error("Missing samples");
3738       return;
3739     }
3740 
3741     if (stream_params.codec_frames_blocks_per_sdu != 1) {
3742       log::error("Codec Frame Blocks of {} is not supported by the software encoding",
3743                  +stream_params.codec_frames_blocks_per_sdu);
3744     }
3745 
3746     uint16_t byte_count = stream_params.octets_per_codec_frame;
3747     bool mix_to_mono = (num_channels == 1);
3748     if (mix_to_mono) {
3749       /* Since we always get two channels from framework, lets make it mono here
3750        */
3751       std::vector<uint8_t> mono =
3752               mono_blend(data, bytes_per_sample, number_of_required_samples_per_channel);
3753       sw_enc_left->Encode(mono.data(), 1, byte_count);
3754     } else {
3755       sw_enc_left->Encode((const uint8_t*)data.data(), 2, byte_count);
3756       // Output to the left channel buffer with `byte_count` offset
3757       sw_enc_right->Encode((const uint8_t*)data.data() + 2, 2, byte_count,
3758                            &sw_enc_left->GetDecodedSamples(), byte_count);
3759     }
3760 
3761     IsoManager::GetInstance()->SendIsoData(cis_handle,
3762                                            (const uint8_t*)sw_enc_left->GetDecodedSamples().data(),
3763                                            sw_enc_left->GetDecodedSamples().size() * 2);
3764   }
3765 
GetStreamSinkConfiguration(LeAudioDeviceGroup * group)3766   const struct bluetooth::le_audio::stream_configuration* GetStreamSinkConfiguration(
3767           LeAudioDeviceGroup* group) {
3768     const struct bluetooth::le_audio::stream_configuration* stream_conf = &group->stream_conf;
3769     log::info("group_id: {}", group->group_id_);
3770     if (stream_conf->stream_params.sink.stream_locations.size() == 0) {
3771       return nullptr;
3772     }
3773 
3774     log::info("configuration: {}", stream_conf->conf->name);
3775     return stream_conf;
3776   }
3777 
OnAudioDataReady(const std::vector<uint8_t> & data)3778   void OnAudioDataReady(const std::vector<uint8_t>& data) {
3779     if ((active_group_id_ == bluetooth::groups::kGroupUnknown) ||
3780         (audio_sender_state_ != AudioState::STARTED)) {
3781       return;
3782     }
3783 
3784     LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
3785     if (!group) {
3786       log::error("There is no streaming group available");
3787       return;
3788     }
3789 
3790     auto stream_conf = group->stream_conf;
3791     if ((stream_conf.stream_params.sink.num_of_devices > 2) ||
3792         (stream_conf.stream_params.sink.num_of_devices == 0) ||
3793         stream_conf.stream_params.sink.stream_locations.empty()) {
3794       log::error("Stream configufation is not valid.");
3795       return;
3796     }
3797 
3798     if ((stream_conf.stream_params.sink.num_of_devices == 2) ||
3799         (stream_conf.stream_params.sink.stream_locations.size() == 2)) {
3800       /* Streaming to two devices or one device with 2 CISes */
3801       PrepareAndSendToTwoCises(data, stream_conf.stream_params.sink);
3802     } else {
3803       /* Streaming to one device and 1 CIS */
3804       PrepareAndSendToSingleCis(data, stream_conf.stream_params.sink);
3805     }
3806   }
3807 
CleanCachedMicrophoneData()3808   void CleanCachedMicrophoneData() {
3809     cached_channel_timestamp_ = 0;
3810     cached_channel_ = nullptr;
3811   }
3812 
3813   /* Handles audio data packets coming from the controller */
HandleIncomingCisData(uint8_t * data,uint16_t size,uint16_t cis_conn_hdl,uint32_t timestamp)3814   void HandleIncomingCisData(uint8_t* data, uint16_t size, uint16_t cis_conn_hdl,
3815                              uint32_t timestamp) {
3816     /* Get only one channel for MONO microphone */
3817     /* Gather data for channel */
3818     if ((active_group_id_ == bluetooth::groups::kGroupUnknown) ||
3819         (audio_receiver_state_ != AudioState::STARTED)) {
3820       return;
3821     }
3822 
3823     LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
3824     if (!group) {
3825       log::error("There is no streaming group available");
3826       return;
3827     }
3828 
3829     uint16_t left_cis_handle = 0;
3830     uint16_t right_cis_handle = 0;
3831     for (auto [cis_handle, audio_location] :
3832          group->stream_conf.stream_params.source.stream_locations) {
3833       if (audio_location & bluetooth::le_audio::codec_spec_conf::kLeAudioLocationAnyLeft) {
3834         left_cis_handle = cis_handle;
3835       }
3836       if (audio_location & bluetooth::le_audio::codec_spec_conf::kLeAudioLocationAnyRight) {
3837         right_cis_handle = cis_handle;
3838       }
3839     }
3840 
3841     auto decoder = sw_dec_left.get();
3842     if (cis_conn_hdl == left_cis_handle) {
3843       decoder = sw_dec_left.get();
3844     } else if (cis_conn_hdl == right_cis_handle) {
3845       decoder = sw_dec_right.get();
3846     } else {
3847       log::error("Received data for unknown handle: {:04x}", cis_conn_hdl);
3848       return;
3849     }
3850 
3851     if (!left_cis_handle || !right_cis_handle) {
3852       /* mono or just one device connected */
3853       decoder->Decode(data, size);
3854       SendAudioDataToAF(&decoder->GetDecodedSamples());
3855       return;
3856     }
3857     /* both devices are connected */
3858 
3859     if (cached_channel_ == nullptr || cached_channel_->GetDecodedSamples().empty()) {
3860       /* First packet received, cache it. We need both channel data to send it
3861        * to AF. */
3862       decoder->Decode(data, size);
3863       cached_channel_timestamp_ = timestamp;
3864       cached_channel_ = decoder;
3865       return;
3866     }
3867 
3868     /* We received either data for the other audio channel, or another
3869      * packet for same channel */
3870     if (cached_channel_ != decoder) {
3871       /* It's data for the 2nd channel */
3872       if (timestamp == cached_channel_timestamp_) {
3873         /* Ready to mix data and send out to AF */
3874         decoder->Decode(data, size);
3875         SendAudioDataToAF(&sw_dec_left->GetDecodedSamples(), &sw_dec_right->GetDecodedSamples());
3876 
3877         CleanCachedMicrophoneData();
3878         return;
3879       }
3880 
3881       /* 2nd Channel is in the future compared to the cached data.
3882        Send the cached data to AF, and keep the new channel data in cache.
3883        This should happen only during stream setup */
3884       SendAudioDataToAF(&decoder->GetDecodedSamples());
3885 
3886       decoder->Decode(data, size);
3887       cached_channel_timestamp_ = timestamp;
3888       cached_channel_ = decoder;
3889       return;
3890     }
3891 
3892     /* Data for same channel received. 2nd channel is down/not sending
3893      * data */
3894 
3895     /* Send the cached data out */
3896     SendAudioDataToAF(&decoder->GetDecodedSamples());
3897 
3898     /* Cache the data in case 2nd channel connects */
3899     decoder->Decode(data, size);
3900     cached_channel_timestamp_ = timestamp;
3901     cached_channel_ = decoder;
3902   }
3903 
SendAudioDataToAF(std::vector<int16_t> * left,std::vector<int16_t> * right=nullptr)3904   void SendAudioDataToAF(std::vector<int16_t>* left, std::vector<int16_t>* right = nullptr) {
3905     uint16_t to_write = 0;
3906     uint16_t written = 0;
3907 
3908     bool af_is_stereo = (audio_framework_sink_config.num_channels == 2);
3909     bool bt_got_stereo = (left != nullptr) & (right != nullptr);
3910 
3911     if (!af_is_stereo) {
3912       if (!bt_got_stereo) {
3913         std::vector<int16_t>* mono = left ? left : right;
3914         /* mono audio over bluetooth, audio framework expects mono */
3915         to_write = sizeof(int16_t) * mono->size();
3916         written = le_audio_sink_hal_client_->SendData((uint8_t*)mono->data(), to_write);
3917       } else {
3918         /* stereo audio over bluetooth, audio framework expects mono */
3919         for (size_t i = 0; i < left->size(); i++) {
3920           (*left)[i] = ((*left)[i] + (*right)[i]) / 2;
3921         }
3922         to_write = sizeof(int16_t) * left->size();
3923         written = le_audio_sink_hal_client_->SendData((uint8_t*)left->data(), to_write);
3924       }
3925     } else {
3926       /* mono audio over bluetooth, audio framework expects stereo
3927        * Here we handle stream without checking bt_got_stereo flag.
3928        */
3929       const size_t mono_size = left ? left->size() : right->size();
3930       std::vector<uint16_t> mixed(mono_size * 2);
3931 
3932       for (size_t i = 0; i < mono_size; i++) {
3933         mixed[2 * i] = left ? (*left)[i] : (*right)[i];
3934         mixed[2 * i + 1] = right ? (*right)[i] : (*left)[i];
3935       }
3936       to_write = sizeof(int16_t) * mixed.size();
3937       written = le_audio_sink_hal_client_->SendData((uint8_t*)mixed.data(), to_write);
3938     }
3939 
3940     /* TODO: What to do if not all data sinked ? */
3941     if (written != to_write) {
3942       log::error("not all data sinked");
3943     }
3944   }
3945 
ConfirmLocalAudioSourceStreamingRequest()3946   void ConfirmLocalAudioSourceStreamingRequest() {
3947     le_audio_source_hal_client_->ConfirmStreamingRequest();
3948 
3949     LeAudioLogHistory::Get()->AddLogHistory(
3950             kLogBtCallAf, active_group_id_, RawAddress::kEmpty, kLogAfResumeConfirm + "LocalSource",
3951             "s_state: " + ToString(audio_sender_state_) + "-> STARTED");
3952 
3953     audio_sender_state_ = AudioState::STARTED;
3954   }
3955 
ConfirmLocalAudioSinkStreamingRequest()3956   void ConfirmLocalAudioSinkStreamingRequest() {
3957     le_audio_sink_hal_client_->ConfirmStreamingRequest();
3958 
3959     LeAudioLogHistory::Get()->AddLogHistory(
3960             kLogBtCallAf, active_group_id_, RawAddress::kEmpty, kLogAfResumeConfirm + "LocalSink",
3961             "r_state: " + ToString(audio_receiver_state_) + "-> STARTED");
3962 
3963     audio_receiver_state_ = AudioState::STARTED;
3964   }
3965 
StartSendingAudio(int group_id)3966   void StartSendingAudio(int group_id) {
3967     log::info("");
3968 
3969     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
3970     LeAudioDevice* device = group->GetFirstActiveDevice();
3971     log::assert_that(device, "Shouldn't be called without an active device.");
3972 
3973     /* Assume 2 ases max just for now. */
3974     auto* stream_conf = GetStreamSinkConfiguration(group);
3975     if (stream_conf == nullptr) {
3976       log::error("could not get sink configuration");
3977       groupStateMachine_->StopStream(group);
3978       return;
3979     }
3980 
3981     log::debug("Sink stream config (#{}):\n",
3982                static_cast<int>(stream_conf->stream_params.sink.stream_locations.size()));
3983     for (auto stream : stream_conf->stream_params.sink.stream_locations) {
3984       log::debug("Cis handle: 0x{:02x}, allocation 0x{:04x}\n", stream.first, stream.second);
3985     }
3986     log::debug("Source stream config (#{}):\n",
3987                static_cast<int>(stream_conf->stream_params.source.stream_locations.size()));
3988     for (auto stream : stream_conf->stream_params.source.stream_locations) {
3989       log::debug("Cis handle: 0x{:02x}, allocation 0x{:04x}\n", stream.first, stream.second);
3990     }
3991 
3992     uint16_t remote_delay_ms =
3993             group->GetRemoteDelay(bluetooth::le_audio::types::kLeAudioDirectionSink);
3994     if (CodecManager::GetInstance()->GetCodecLocation() ==
3995         bluetooth::le_audio::types::CodecLocation::HOST) {
3996       if (sw_enc_left || sw_enc_right) {
3997         log::warn("The encoder instance should have been already released.");
3998       }
3999       sw_enc_left = bluetooth::le_audio::CodecInterface::CreateInstance(stream_conf->codec_id);
4000       auto codec_status =
4001               sw_enc_left->InitEncoder(audio_framework_source_config, current_encoder_config_);
4002       if (codec_status != bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
4003         log::error("Left channel codec setup failed with err: {}", codec_status);
4004         groupStateMachine_->StopStream(group);
4005         return;
4006       }
4007 
4008       sw_enc_right = bluetooth::le_audio::CodecInterface::CreateInstance(stream_conf->codec_id);
4009       codec_status =
4010               sw_enc_right->InitEncoder(audio_framework_source_config, current_encoder_config_);
4011       if (codec_status != bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
4012         log::error("Right channel codec setup failed with err: {}", codec_status);
4013         groupStateMachine_->StopStream(group);
4014         return;
4015       }
4016     }
4017 
4018     le_audio_source_hal_client_->UpdateRemoteDelay(remote_delay_ms);
4019     ConfirmLocalAudioSourceStreamingRequest();
4020 
4021     if (!LeAudioHalVerifier::SupportsStreamActiveApi()) {
4022       /* We update the target audio allocation before streamStarted so that the
4023        * CodecManager would know how to configure the encoder. */
4024       BidirectionalPair<uint16_t> delays_pair = {
4025               .sink = group->GetRemoteDelay(bluetooth::le_audio::types::kLeAudioDirectionSink),
4026               .source = group->GetRemoteDelay(bluetooth::le_audio::types::kLeAudioDirectionSource)};
4027       CodecManager::GetInstance()->UpdateActiveAudioConfig(
4028               group->stream_conf.stream_params, delays_pair,
4029               std::bind(&LeAudioClientImpl::UpdateAudioConfigToHal, weak_factory_.GetWeakPtr(),
4030                         std::placeholders::_1, std::placeholders::_2));
4031     }
4032   }
4033 
GetStreamSourceConfiguration(LeAudioDeviceGroup * group)4034   const struct bluetooth::le_audio::stream_configuration* GetStreamSourceConfiguration(
4035           LeAudioDeviceGroup* group) {
4036     const struct bluetooth::le_audio::stream_configuration* stream_conf = &group->stream_conf;
4037     if (stream_conf->stream_params.source.stream_locations.size() == 0) {
4038       return nullptr;
4039     }
4040     log::info("configuration: {}", stream_conf->conf->name);
4041     return stream_conf;
4042   }
4043 
StartReceivingAudio(int group_id)4044   void StartReceivingAudio(int group_id) {
4045     log::info("");
4046 
4047     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
4048 
4049     auto* stream_conf = GetStreamSourceConfiguration(group);
4050     if (!stream_conf) {
4051       log::warn(
4052               "Could not get source configuration for group {} probably microphone not configured",
4053               active_group_id_);
4054       groupStateMachine_->StopStream(group);
4055       return;
4056     }
4057 
4058     uint16_t remote_delay_ms =
4059             group->GetRemoteDelay(bluetooth::le_audio::types::kLeAudioDirectionSource);
4060 
4061     CleanCachedMicrophoneData();
4062 
4063     if (CodecManager::GetInstance()->GetCodecLocation() ==
4064         bluetooth::le_audio::types::CodecLocation::HOST) {
4065       if (sw_dec_left.get() || sw_dec_right.get()) {
4066         log::warn("The decoder instance should have been already released.");
4067       }
4068       sw_dec_left = bluetooth::le_audio::CodecInterface::CreateInstance(stream_conf->codec_id);
4069       auto codec_status =
4070               sw_dec_left->InitDecoder(current_decoder_config_, audio_framework_sink_config);
4071       if (codec_status != bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
4072         log::error("Left channel codec setup failed with err: {}", codec_status);
4073         groupStateMachine_->StopStream(group);
4074         return;
4075       }
4076 
4077       sw_dec_right = bluetooth::le_audio::CodecInterface::CreateInstance(stream_conf->codec_id);
4078       codec_status =
4079               sw_dec_right->InitDecoder(current_decoder_config_, audio_framework_sink_config);
4080       if (codec_status != bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
4081         log::error("Right channel codec setup failed with err: {}", codec_status);
4082         groupStateMachine_->StopStream(group);
4083         return;
4084       }
4085     }
4086     le_audio_sink_hal_client_->UpdateRemoteDelay(remote_delay_ms);
4087     ConfirmLocalAudioSinkStreamingRequest();
4088 
4089     if (!LeAudioHalVerifier::SupportsStreamActiveApi()) {
4090       /* We update the target audio allocation before streamStarted so that the
4091        * CodecManager would know how to configure the encoder. */
4092       BidirectionalPair<uint16_t> delays_pair = {
4093               .sink = group->GetRemoteDelay(bluetooth::le_audio::types::kLeAudioDirectionSink),
4094               .source = group->GetRemoteDelay(bluetooth::le_audio::types::kLeAudioDirectionSource)};
4095       CodecManager::GetInstance()->UpdateActiveAudioConfig(
4096               group->stream_conf.stream_params, delays_pair,
4097               std::bind(&LeAudioClientImpl::UpdateAudioConfigToHal, weak_factory_.GetWeakPtr(),
4098                         std::placeholders::_1, std::placeholders::_2));
4099     }
4100   }
4101 
SuspendAudio(void)4102   void SuspendAudio(void) {
4103     CancelStreamingRequest();
4104 
4105     if (sw_enc_left) {
4106       sw_enc_left.reset();
4107     }
4108     if (sw_enc_right) {
4109       sw_enc_right.reset();
4110     }
4111     if (sw_dec_left) {
4112       sw_dec_left.reset();
4113     }
4114     if (sw_dec_right) {
4115       sw_dec_right.reset();
4116     }
4117     CleanCachedMicrophoneData();
4118   }
4119 
StopAudio(void)4120   void StopAudio(void) {
4121     SuspendAudio();
4122     stack::l2cap::get_interface().L2CA_SetEcosystemBaseInterval(0 /* clear recommendation */);
4123   }
4124 
printCurrentStreamConfiguration(std::stringstream & stream)4125   void printCurrentStreamConfiguration(std::stringstream& stream) {
4126     auto config_printer = [&stream](LeAudioCodecConfiguration& conf) {
4127       stream << "\tsample rate: " << +conf.sample_rate << ", chan: " << +conf.num_channels
4128              << ", bits: " << +conf.bits_per_sample
4129              << ", data_interval_us: " << +conf.data_interval_us << "\n";
4130     };
4131 
4132     stream << "\n";
4133     stream << "  Speaker codec config (audio framework):\n";
4134     stream << "\taudio sender state: " << audio_sender_state_ << "\n";
4135     config_printer(audio_framework_source_config);
4136 
4137     stream << "  Microphone codec config (audio framework):\n";
4138     stream << "\taudio receiver state: " << audio_receiver_state_ << "\n";
4139     config_printer(audio_framework_sink_config);
4140 
4141     stream << "  Speaker codec config (SW encoder):\n";
4142     config_printer(current_encoder_config_);
4143 
4144     stream << "  Microphone codec config (SW decoder):\n";
4145     config_printer(current_decoder_config_);
4146   }
4147 
Dump(int fd)4148   void Dump(int fd) {
4149     std::stringstream stream;
4150 
4151     stream << "  APP ID: " << +gatt_if_ << "\n";
4152     stream << "  TBS state: " << (in_call_ ? " In call" : "No calls") << "\n";
4153     stream << "  Active group: " << +active_group_id_ << "\n";
4154     stream << "  Reconnection mode: "
4155            << (reconnection_mode_ == BTM_BLE_BKG_CONNECT_ALLOW_LIST ? "Allow List"
4156                                                                     : "Targeted Announcements")
4157            << "\n";
4158     stream << "  Configuration: " << bluetooth::common::ToString(configuration_context_type_)
4159            << " (" << loghex(static_cast<uint16_t>(configuration_context_type_)) << ")\n";
4160     stream << "  Local source metadata context type mask: "
4161            << local_metadata_context_types_.source.to_string() << "\n";
4162     stream << "  Local sink metadata context type mask: "
4163            << local_metadata_context_types_.sink.to_string() << "\n";
4164     stream << "  Sink listening mode: " << (sink_monitor_mode_ ? "true" : "false") << "\n";
4165     if (sink_monitor_notified_status_) {
4166       stream << "  Local sink notified state: "
4167              << static_cast<int>(sink_monitor_notified_status_.value()) << "\n";
4168     }
4169     stream << "  Source monitor mode: " << (source_monitor_mode_ ? "true" : "false") << "\n";
4170     if (source_monitor_notified_status_) {
4171       dprintf(fd, "  Local source notified state: %d\n",
4172               static_cast<int>(source_monitor_notified_status_.value()));
4173     }
4174 
4175     auto codec_loc = CodecManager::GetInstance()->GetCodecLocation();
4176     if (codec_loc == bluetooth::le_audio::types::CodecLocation::HOST) {
4177       stream << "  Codec location: HOST\n";
4178     } else if (codec_loc == bluetooth::le_audio::types::CodecLocation::CONTROLLER) {
4179       stream << "  Codec location: CONTROLLER\n";
4180     } else if (codec_loc == bluetooth::le_audio::types::CodecLocation::ADSP) {
4181       stream << "  Codec location: ADSP"
4182              << (CodecManager::GetInstance()->IsUsingCodecExtensibility() ? " (codec extensibility)"
4183                                                                           : "")
4184              << "\n";
4185     } else {
4186       dprintf(fd, "  Codec location: UNKNOWN\n");
4187     }
4188 
4189     stream << "  Stream creation speed: ";
4190     for (auto t : stream_speed_history_) {
4191       t.Dump(stream);
4192       stream << ",";
4193     }
4194     stream << "\n";
4195     printCurrentStreamConfiguration(stream);
4196     stream << "\n";
4197     aseGroups_.Dump(stream, active_group_id_);
4198     stream << "\n ";
4199     stream << "  Not grouped devices:\n";
4200     leAudioDevices_.Dump(stream, bluetooth::groups::kGroupUnknown);
4201 
4202     dprintf(fd, "%s", stream.str().c_str());
4203 
4204     if (leAudioHealthStatus_) {
4205       leAudioHealthStatus_->DebugDump(fd);
4206     }
4207   }
4208 
Cleanup()4209   void Cleanup() {
4210     StopVbcCloseTimeout();
4211     StopSuspendTimeout();
4212 
4213     if (active_group_id_ != bluetooth::groups::kGroupUnknown) {
4214       /* Bluetooth turned off while streaming */
4215       StopAudio();
4216       SetUnicastMonitorMode(bluetooth::le_audio::types::kLeAudioDirectionSink, false);
4217       ClientAudioInterfaceRelease();
4218     } else {
4219       /* There may be not stopped Sink HAL client due to set Listening mode */
4220       if (sink_monitor_mode_) {
4221         SetUnicastMonitorMode(bluetooth::le_audio::types::kLeAudioDirectionSink, false);
4222       }
4223     }
4224     groupStateMachine_->Cleanup();
4225     aseGroups_.Cleanup();
4226     lastNotifiedGroupStreamStatusMap_.clear();
4227     leAudioDevices_.Cleanup(gatt_if_);
4228     if (gatt_if_) {
4229       BTA_GATTC_AppDeregister(gatt_if_);
4230     }
4231 
4232     if (leAudioHealthStatus_) {
4233       leAudioHealthStatus_->Cleanup();
4234     }
4235   }
4236 
UpdateConfigAndCheckIfReconfigurationIsNeeded(LeAudioDeviceGroup * group,LeAudioContextType context_type)4237   AudioReconfigurationResult UpdateConfigAndCheckIfReconfigurationIsNeeded(
4238           LeAudioDeviceGroup* group, LeAudioContextType context_type) {
4239     log::debug("Checking whether to reconfigure from {} to {}",
4240                ToString(configuration_context_type_), ToString(context_type));
4241 
4242     auto audio_set_conf = group->GetConfiguration(context_type);
4243     if (!audio_set_conf) {
4244       return AudioReconfigurationResult::RECONFIGURATION_NOT_POSSIBLE;
4245     }
4246 
4247     if (group->IsGroupConfiguredTo(*audio_set_conf) && !DsaReconfigureNeeded(group, context_type)) {
4248       // Assign the new configuration context as it represennts the current
4249       // use case even when it eventually ends up being the exact same
4250       // codec and qos configuration.
4251       if (configuration_context_type_ != context_type) {
4252         configuration_context_type_ = context_type;
4253         group->SetConfigurationContextType(context_type);
4254       }
4255       return AudioReconfigurationResult::RECONFIGURATION_NOT_NEEDED;
4256     }
4257 
4258     log::info("Session reconfiguration needed group: {} for context type: {}", group->group_id_,
4259               ToHexString(context_type));
4260 
4261     configuration_context_type_ = context_type;
4262 
4263     // Note: The local sink config is based on remote device's source config
4264     //       and vice versa.
4265     current_decoder_config_ = group->GetAudioSessionCodecConfigForDirection(
4266             context_type, bluetooth::le_audio::types::kLeAudioDirectionSource);
4267     current_encoder_config_ = group->GetAudioSessionCodecConfigForDirection(
4268             context_type, bluetooth::le_audio::types::kLeAudioDirectionSink);
4269     return AudioReconfigurationResult::RECONFIGURATION_NEEDED;
4270   }
4271 
4272   /* Returns true if stream is started */
OnAudioResume(LeAudioDeviceGroup * group,int local_direction)4273   bool OnAudioResume(LeAudioDeviceGroup* group, int local_direction) {
4274     auto remote_direction = (local_direction == bluetooth::le_audio::types::kLeAudioDirectionSink
4275                                      ? bluetooth::le_audio::types::kLeAudioDirectionSource
4276                                      : bluetooth::le_audio::types::kLeAudioDirectionSink);
4277 
4278     auto remote_contexts = DirectionalRealignMetadataAudioContexts(group, remote_direction);
4279     ApplyRemoteMetadataAudioContextPolicy(group, remote_contexts, remote_direction);
4280 
4281     if (!remote_contexts.sink.any() && !remote_contexts.source.any()) {
4282       log::warn("Requested context type not available on the remote side");
4283 
4284       if (com::android::bluetooth::flags::leaudio_no_context_validate_streaming_request() &&
4285           source_monitor_mode_) {
4286         notifyAudioLocalSource(UnicastMonitorModeStatus::STREAMING_REQUESTED_NO_CONTEXT_VALIDATE);
4287 
4288         return false;
4289       }
4290 
4291       if (leAudioHealthStatus_) {
4292         leAudioHealthStatus_->AddStatisticForGroup(
4293                 group, LeAudioHealthGroupStatType::STREAM_CONTEXT_NOT_AVAILABLE);
4294       }
4295       return false;
4296     }
4297 
4298     return GroupStream(active_group_id_, configuration_context_type_, remote_contexts);
4299   }
4300 
OnAudioSuspend()4301   void OnAudioSuspend() {
4302     if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
4303       log::warn(", there is no longer active group");
4304       return;
4305     }
4306 
4307     if (stack_config_get_interface()->get_pts_le_audio_disable_ases_before_stopping()) {
4308       log::info("Stream disable_timer_ started");
4309       if (alarm_is_scheduled(disable_timer_)) {
4310         alarm_cancel(disable_timer_);
4311       }
4312 
4313       alarm_set_on_mloop(
4314               disable_timer_, kAudioDisableTimeoutMs,
4315               [](void* data) {
4316                 if (instance) {
4317                   auto const group_id = PTR_TO_INT(data);
4318                   log::debug("No resume request received. Suspend the group ID: {}", group_id);
4319                   instance->GroupSuspend(group_id);
4320                 }
4321               },
4322               INT_TO_PTR(active_group_id_));
4323     }
4324 
4325     StartSuspendTimeout();
4326   }
4327 
OnLocalAudioSourceSuspend()4328   void OnLocalAudioSourceSuspend() {
4329     log::info("active group_id: {}, IN: audio_receiver_state_: {}, audio_sender_state_: {}",
4330               active_group_id_, ToString(audio_receiver_state_), ToString(audio_sender_state_));
4331     LeAudioLogHistory::Get()->AddLogHistory(kLogAfCallBt, active_group_id_, RawAddress::kEmpty,
4332                                             kLogAfSuspend + "LocalSource",
4333                                             "r_state: " + ToString(audio_receiver_state_) +
4334                                                     ", s_state: " + ToString(audio_sender_state_));
4335 
4336     /* Note: This callback is from audio hal driver.
4337      * Bluetooth peer is a Sink for Audio Framework.
4338      * e.g. Peer is a speaker
4339      */
4340     switch (audio_sender_state_) {
4341       case AudioState::READY_TO_START:
4342       case AudioState::STARTED:
4343         audio_sender_state_ = AudioState::READY_TO_RELEASE;
4344         break;
4345       case AudioState::RELEASING:
4346         return;
4347       case AudioState::IDLE:
4348         if (audio_receiver_state_ == AudioState::READY_TO_RELEASE) {
4349           OnAudioSuspend();
4350         }
4351         return;
4352       case AudioState::READY_TO_RELEASE:
4353         break;
4354     }
4355 
4356     /* Last suspends group - triggers group stop */
4357     if ((audio_receiver_state_ == AudioState::IDLE) ||
4358         (audio_receiver_state_ == AudioState::READY_TO_RELEASE)) {
4359       OnAudioSuspend();
4360       bluetooth::le_audio::MetricsCollector::Get()->OnStreamEnded(active_group_id_);
4361     }
4362 
4363     log::info("OUT: audio_receiver_state_: {},  audio_sender_state_: {}",
4364               ToString(audio_receiver_state_), ToString(audio_sender_state_));
4365 
4366     LeAudioLogHistory::Get()->AddLogHistory(kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
4367                                             kLogAfSuspendConfirm + "LocalSource",
4368                                             "r_state: " + ToString(audio_receiver_state_) +
4369                                                     "s_state: " + ToString(audio_sender_state_));
4370   }
4371 
OnLocalAudioSourceResume()4372   void OnLocalAudioSourceResume() {
4373     log::info("active group_id: {}, IN: audio_receiver_state_: {}, audio_sender_state_: {}",
4374               active_group_id_, ToString(audio_receiver_state_), ToString(audio_sender_state_));
4375     LeAudioLogHistory::Get()->AddLogHistory(kLogAfCallBt, active_group_id_, RawAddress::kEmpty,
4376                                             kLogAfResume + "LocalSource",
4377                                             "r_state: " + ToString(audio_receiver_state_) +
4378                                                     ", s_state: " + ToString(audio_sender_state_));
4379 
4380     /* Note: This callback is from audio hal driver.
4381      * Bluetooth peer is a Sink for Audio Framework.
4382      * e.g. Peer is a speaker
4383      */
4384     auto group = aseGroups_.FindById(active_group_id_);
4385     if (!group) {
4386       log::error("Invalid group: {}", static_cast<int>(active_group_id_));
4387       return;
4388     }
4389 
4390     /* Check if the device resume is allowed */
4391     if (!group->HasCodecConfigurationForDirection(
4392                 configuration_context_type_, bluetooth::le_audio::types::kLeAudioDirectionSink)) {
4393       log::error("invalid resume request for context type: {}",
4394                  ToHexString(configuration_context_type_));
4395       CancelLocalAudioSourceStreamingRequest();
4396       return;
4397     }
4398 
4399     if (!group->GetAllowedContextMask(bluetooth::le_audio::types::kLeAudioDirectionSink)
4400                  .test(configuration_context_type_)) {
4401       log::warn("Block source resume request context type: {}",
4402                 ToHexString(configuration_context_type_));
4403       CancelLocalAudioSourceStreamingRequest();
4404       return;
4405     }
4406 
4407     log::debug(
4408             "active_group_id: {}\n audio_receiver_state: {}\n audio_sender_state: "
4409             "{}\n configuration_context_type_: {}\n",
4410             active_group_id_, audio_receiver_state_, audio_sender_state_,
4411             ToHexString(configuration_context_type_));
4412 
4413     switch (audio_sender_state_) {
4414       case AudioState::STARTED:
4415         /* Looks like previous Confirm did not get to the Audio Framework*/
4416         ConfirmLocalAudioSourceStreamingRequest();
4417         break;
4418       case AudioState::IDLE:
4419         switch (audio_receiver_state_) {
4420           case AudioState::IDLE:
4421             /* Stream is not started. Try to do it.*/
4422             if (OnAudioResume(group, bluetooth::le_audio::types::kLeAudioDirectionSource)) {
4423               audio_sender_state_ = AudioState::READY_TO_START;
4424               if (IsReconfigurationTimeoutRunning(active_group_id_)) {
4425                 StopReconfigurationTimeout(active_group_id_,
4426                                            bluetooth::le_audio::types::kLeAudioDirectionSource);
4427               }
4428             } else {
4429               CancelLocalAudioSourceStreamingRequest();
4430             }
4431             break;
4432           case AudioState::READY_TO_START:
4433             audio_sender_state_ = AudioState::READY_TO_START;
4434             if (!IsDirectionAvailableForCurrentConfiguration(
4435                         group, bluetooth::le_audio::types::kLeAudioDirectionSink)) {
4436               log::warn(
4437                       "sink is not configured. \n audio_receiver_state: {} "
4438                       "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4439                       "Reconfiguring to {}",
4440                       ToString(audio_receiver_state_), ToString(audio_sender_state_),
4441                       group->IsPendingConfiguration(), ToString(configuration_context_type_));
4442               group->PrintDebugState();
4443               SetConfigurationAndStopStreamWhenNeeded(group, configuration_context_type_);
4444             }
4445             break;
4446           case AudioState::STARTED:
4447             audio_sender_state_ = AudioState::READY_TO_START;
4448             /* If signalling part is completed trigger start sending audio
4449              * here, otherwise it'll be called on group streaming state callback
4450              */
4451             if (group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
4452               if (IsDirectionAvailableForCurrentConfiguration(
4453                           group, bluetooth::le_audio::types::kLeAudioDirectionSink)) {
4454                 StartSendingAudio(active_group_id_);
4455               } else {
4456                 log::warn(
4457                         "sink is not configured. \n audio_receiver_state: {} "
4458                         "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4459                         "Reconfiguring to {}",
4460                         ToString(audio_receiver_state_), ToString(audio_sender_state_),
4461                         group->IsPendingConfiguration(), ToString(configuration_context_type_));
4462                 group->PrintDebugState();
4463                 SetConfigurationAndStopStreamWhenNeeded(group, configuration_context_type_);
4464               }
4465             } else {
4466               log::error(
4467                       "called in wrong state. \n audio_receiver_state: {} "
4468                       "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4469                       "Reconfiguring to {}",
4470                       ToString(audio_receiver_state_), ToString(audio_sender_state_),
4471                       group->IsPendingConfiguration(), ToString(configuration_context_type_));
4472               group->PrintDebugState();
4473               CancelStreamingRequest();
4474             }
4475             break;
4476           case AudioState::RELEASING:
4477             /* Group is reconfiguring, reassing state and wait for
4478              * the stream to be configured
4479              */
4480             audio_sender_state_ = audio_receiver_state_;
4481             break;
4482           case AudioState::READY_TO_RELEASE:
4483             /* If the other direction is streaming we can start sending audio */
4484             if (group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
4485               if (IsDirectionAvailableForCurrentConfiguration(
4486                           group, bluetooth::le_audio::types::kLeAudioDirectionSink)) {
4487                 StopSuspendTimeout();
4488                 StartSendingAudio(active_group_id_);
4489               } else {
4490                 log::warn(
4491                         "sink is not configured. \n audio_receiver_state: {} "
4492                         "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4493                         "Reconfiguring to {}",
4494                         ToString(audio_receiver_state_), ToString(audio_sender_state_),
4495                         group->IsPendingConfiguration(), ToString(configuration_context_type_));
4496                 group->PrintDebugState();
4497                 SetConfigurationAndStopStreamWhenNeeded(group, configuration_context_type_);
4498               }
4499             } else {
4500               log::error(
4501                       "called in wrong state. \n audio_receiver_state: {} "
4502                       "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4503                       "Reconfiguring to {}",
4504                       ToString(audio_receiver_state_), ToString(audio_sender_state_),
4505                       group->IsPendingConfiguration(), ToString(configuration_context_type_));
4506               group->PrintDebugState();
4507               CancelStreamingRequest();
4508             }
4509             break;
4510         }
4511         break;
4512       case AudioState::READY_TO_START:
4513         log::error(
4514                 "called in wrong state, ignoring double start request. \n "
4515                 "audio_receiver_state: {} \naudio_sender_state: {} \n "
4516                 "isPendingConfiguration: {} \n Reconfiguring to {}",
4517                 ToString(audio_receiver_state_), ToString(audio_sender_state_),
4518                 group->IsPendingConfiguration(), ToString(configuration_context_type_));
4519         group->PrintDebugState();
4520         break;
4521       case AudioState::READY_TO_RELEASE:
4522         switch (audio_receiver_state_) {
4523           case AudioState::STARTED:
4524           case AudioState::READY_TO_START:
4525           case AudioState::IDLE:
4526           case AudioState::READY_TO_RELEASE:
4527             /* Stream is up just restore it */
4528             StopSuspendTimeout();
4529             ConfirmLocalAudioSourceStreamingRequest();
4530             bluetooth::le_audio::MetricsCollector::Get()->OnStreamStarted(
4531                     active_group_id_, configuration_context_type_);
4532             break;
4533           case AudioState::RELEASING:
4534             /* Keep waiting. After release is done, Audio Hal will be notified
4535              */
4536             break;
4537         }
4538         break;
4539       case AudioState::RELEASING:
4540         /* Keep waiting. After release is done, Audio Hal will be notified */
4541         break;
4542     }
4543   }
4544 
OnLocalAudioSinkSuspend()4545   void OnLocalAudioSinkSuspend() {
4546     log::info("active group_id: {}, IN: audio_receiver_state_: {}, audio_sender_state_: {}",
4547               active_group_id_, ToString(audio_receiver_state_), ToString(audio_sender_state_));
4548     LeAudioLogHistory::Get()->AddLogHistory(kLogAfCallBt, active_group_id_, RawAddress::kEmpty,
4549                                             kLogAfSuspend + "LocalSink",
4550                                             "r_state: " + ToString(audio_receiver_state_) +
4551                                                     ", s_state: " + ToString(audio_sender_state_));
4552 
4553     /* If the local sink direction is used, we want to monitor
4554      * if back channel is actually needed.
4555      */
4556     StartVbcCloseTimeout();
4557 
4558     /* Note: This callback is from audio hal driver.
4559      * Bluetooth peer is a Source for Audio Framework.
4560      * e.g. Peer is microphone.
4561      */
4562     switch (audio_receiver_state_) {
4563       case AudioState::READY_TO_START:
4564       case AudioState::STARTED:
4565         audio_receiver_state_ = AudioState::READY_TO_RELEASE;
4566         break;
4567       case AudioState::RELEASING:
4568         return;
4569       case AudioState::IDLE:
4570         if (audio_sender_state_ == AudioState::READY_TO_RELEASE) {
4571           OnAudioSuspend();
4572         }
4573         return;
4574       case AudioState::READY_TO_RELEASE:
4575         break;
4576     }
4577 
4578     /* Last suspends group - triggers group stop */
4579     if ((audio_sender_state_ == AudioState::IDLE) ||
4580         (audio_sender_state_ == AudioState::READY_TO_RELEASE)) {
4581       OnAudioSuspend();
4582     }
4583 
4584     log::info("OUT: audio_receiver_state_: {},  audio_sender_state_: {}",
4585               ToString(audio_receiver_state_), ToString(audio_sender_state_));
4586 
4587     LeAudioLogHistory::Get()->AddLogHistory(kLogBtCallAf, active_group_id_, RawAddress::kEmpty,
4588                                             kLogAfSuspendConfirm + "LocalSink",
4589                                             "r_state: " + ToString(audio_receiver_state_) +
4590                                                     "s_state: " + ToString(audio_sender_state_));
4591   }
4592 
IsDirectionAvailableForCurrentConfiguration(const LeAudioDeviceGroup * group,uint8_t remote_direction) const4593   inline bool IsDirectionAvailableForCurrentConfiguration(const LeAudioDeviceGroup* group,
4594                                                           uint8_t remote_direction) const {
4595     auto current_config =
4596             group->IsUsingPreferredAudioSetConfiguration(configuration_context_type_)
4597                     ? group->GetCachedPreferredConfiguration(configuration_context_type_)
4598                     : group->GetCachedConfiguration(configuration_context_type_);
4599     log::debug("configuration_context_type_ = {}, group_id: {}, remote_direction: {}",
4600                ToString(configuration_context_type_), group->group_id_,
4601                remote_direction == bluetooth::le_audio::types::kLeAudioDirectionSink ? "Sink"
4602                                                                                      : "Source");
4603     if (current_config) {
4604       log::debug("name = {}, size {}", current_config->name,
4605                  current_config->confs.get(remote_direction).size());
4606       return current_config->confs.get(remote_direction).size() != 0;
4607     }
4608     log::debug("no cached configuration");
4609     return false;
4610   }
4611 
notifyAudioLocalSink(UnicastMonitorModeStatus status)4612   void notifyAudioLocalSink(UnicastMonitorModeStatus status) {
4613     if (sink_monitor_notified_status_ != status) {
4614       log::info("Stream monitoring status changed to: {}", static_cast<int>(status));
4615       sink_monitor_notified_status_ = status;
4616       callbacks_->OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSink,
4617                                              status);
4618     }
4619   }
4620 
notifyAudioLocalSource(UnicastMonitorModeStatus status)4621   void notifyAudioLocalSource(UnicastMonitorModeStatus status) {
4622     if (source_monitor_notified_status_ != status) {
4623       log::info("Source stream monitoring status changed to: {}", static_cast<int>(status));
4624       source_monitor_notified_status_ = status;
4625       callbacks_->OnUnicastMonitorModeStatus(bluetooth::le_audio::types::kLeAudioDirectionSource,
4626                                              status);
4627     }
4628   }
4629 
OnLocalAudioSinkResume()4630   void OnLocalAudioSinkResume() {
4631     log::info("active group_id: {} IN: audio_receiver_state_: {}, audio_sender_state_: {}",
4632               active_group_id_, ToString(audio_receiver_state_), ToString(audio_sender_state_));
4633     LeAudioLogHistory::Get()->AddLogHistory(kLogAfCallBt, active_group_id_, RawAddress::kEmpty,
4634                                             kLogAfResume + "LocalSink",
4635                                             "r_state: " + ToString(audio_receiver_state_) +
4636                                                     ", s_state: " + ToString(audio_sender_state_));
4637 
4638     if (sink_monitor_mode_ && active_group_id_ == bluetooth::groups::kGroupUnknown) {
4639       if (sink_monitor_notified_status_ != UnicastMonitorModeStatus::STREAMING_REQUESTED) {
4640         notifyAudioLocalSink(UnicastMonitorModeStatus::STREAMING_REQUESTED);
4641       }
4642       CancelLocalAudioSinkStreamingRequest();
4643       return;
4644     }
4645 
4646     /* Stop the VBC close watchdog if needed */
4647     StopVbcCloseTimeout();
4648 
4649     /* Note: This callback is from audio hal driver.
4650      * Bluetooth peer is a Source for Audio Framework.
4651      * e.g. Peer is microphone.
4652      */
4653     auto group = aseGroups_.FindById(active_group_id_);
4654     if (!group) {
4655       log::error("Invalid group: {}", static_cast<int>(active_group_id_));
4656       return;
4657     }
4658 
4659     if (audio_receiver_state_ == AudioState::IDLE) {
4660       /* We need new configuration_context_type_ to be selected before we go any
4661        * further.
4662        */
4663       ReconfigureOrUpdateRemote(group, bluetooth::le_audio::types::kLeAudioDirectionSource);
4664       log::info("new_configuration_context = {}", ToString(configuration_context_type_));
4665     }
4666 
4667     /* Check if the device resume is allowed */
4668     if (!group->HasCodecConfigurationForDirection(
4669                 configuration_context_type_, bluetooth::le_audio::types::kLeAudioDirectionSource)) {
4670       log::error("invalid resume request for context type: {}",
4671                  ToHexString(configuration_context_type_));
4672       CancelLocalAudioSinkStreamingRequest();
4673       return;
4674     }
4675 
4676     if (!group->GetAllowedContextMask(bluetooth::le_audio::types::kLeAudioDirectionSource)
4677                  .test(configuration_context_type_)) {
4678       log::warn("Block sink resume request context type: {}",
4679                 ToHexString(configuration_context_type_));
4680       CancelLocalAudioSourceStreamingRequest();
4681       return;
4682     }
4683 
4684     log::debug(
4685             "active_group_id: {}\n audio_receiver_state: {}\n audio_sender_state: "
4686             "{}\n configuration_context_type_: {}\n group {}\n",
4687             active_group_id_, audio_receiver_state_, audio_sender_state_,
4688             ToHexString(configuration_context_type_), group ? " exist " : " does not exist ");
4689 
4690     switch (audio_receiver_state_) {
4691       case AudioState::STARTED:
4692         ConfirmLocalAudioSinkStreamingRequest();
4693         break;
4694       case AudioState::IDLE:
4695         switch (audio_sender_state_) {
4696           case AudioState::IDLE:
4697             if (OnAudioResume(group, bluetooth::le_audio::types::kLeAudioDirectionSink)) {
4698               audio_receiver_state_ = AudioState::READY_TO_START;
4699               if (IsReconfigurationTimeoutRunning(active_group_id_)) {
4700                 StopReconfigurationTimeout(active_group_id_,
4701                                            bluetooth::le_audio::types::kLeAudioDirectionSink);
4702               }
4703             } else {
4704               CancelLocalAudioSinkStreamingRequest();
4705             }
4706             break;
4707           case AudioState::READY_TO_START:
4708             audio_receiver_state_ = AudioState::READY_TO_START;
4709             if (!IsDirectionAvailableForCurrentConfiguration(
4710                         group, bluetooth::le_audio::types::kLeAudioDirectionSource)) {
4711               log::warn(
4712                       "source is not configured. \n audio_receiver_state: {} "
4713                       "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4714                       "Reconfiguring to {}",
4715                       ToString(audio_receiver_state_), ToString(audio_sender_state_),
4716                       group->IsPendingConfiguration(), ToString(configuration_context_type_));
4717               group->PrintDebugState();
4718               SetConfigurationAndStopStreamWhenNeeded(group, configuration_context_type_);
4719             }
4720             break;
4721           case AudioState::STARTED:
4722             audio_receiver_state_ = AudioState::READY_TO_START;
4723             /* If signalling part is completed trigger start receiving audio
4724              * here, otherwise it'll be called on group streaming state callback
4725              */
4726             if (group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
4727               if (IsDirectionAvailableForCurrentConfiguration(
4728                           group, bluetooth::le_audio::types::kLeAudioDirectionSource)) {
4729                 StartReceivingAudio(active_group_id_);
4730               } else {
4731                 log::warn(
4732                         "source is not configured. \n audio_receiver_state: {} "
4733                         "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4734                         "Reconfiguring to {}",
4735                         ToString(audio_receiver_state_), ToString(audio_sender_state_),
4736                         group->IsPendingConfiguration(), ToString(configuration_context_type_));
4737                 group->PrintDebugState();
4738                 SetConfigurationAndStopStreamWhenNeeded(group, configuration_context_type_);
4739               }
4740             } else {
4741               log::error(
4742                       "called in wrong state. \n audio_receiver_state: {} "
4743                       "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4744                       "Reconfiguring to {}",
4745                       ToString(audio_receiver_state_), ToString(audio_sender_state_),
4746                       group->IsPendingConfiguration(), ToString(configuration_context_type_));
4747               group->PrintDebugState();
4748               CancelStreamingRequest();
4749             }
4750             break;
4751           case AudioState::RELEASING:
4752             /* Group is reconfiguring, reassing state and wait for
4753              * the stream to be configured
4754              */
4755             audio_receiver_state_ = audio_sender_state_;
4756             break;
4757           case AudioState::READY_TO_RELEASE:
4758             /* If the other direction is streaming we can start receiving audio
4759              */
4760             if (group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
4761               if (IsDirectionAvailableForCurrentConfiguration(
4762                           group, bluetooth::le_audio::types::kLeAudioDirectionSource)) {
4763                 StopSuspendTimeout();
4764                 StartReceivingAudio(active_group_id_);
4765               } else {
4766                 log::warn(
4767                         "source is not configured. \n audio_receiver_state: {} "
4768                         "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4769                         "Reconfiguring to {}",
4770                         ToString(audio_receiver_state_), ToString(audio_sender_state_),
4771                         group->IsPendingConfiguration(), ToString(configuration_context_type_));
4772                 group->PrintDebugState();
4773                 SetConfigurationAndStopStreamWhenNeeded(group, configuration_context_type_);
4774               }
4775             } else {
4776               log::error(
4777                       "called in wrong state. \n audio_receiver_state: {} "
4778                       "\naudio_sender_state: {} \n isPendingConfiguration: {} \n "
4779                       "Reconfiguring to {}",
4780                       ToString(audio_receiver_state_), ToString(audio_sender_state_),
4781                       group->IsPendingConfiguration(), ToString(configuration_context_type_));
4782               group->PrintDebugState();
4783               CancelStreamingRequest();
4784             }
4785             break;
4786         }
4787         break;
4788       case AudioState::READY_TO_START:
4789         log::error(
4790                 "Double resume request, just ignore it.. \n audio_receiver_state: "
4791                 "{} \naudio_sender_state: {} \n isPendingConfiguration: {} \n Reconfiguring to {}",
4792                 ToString(audio_receiver_state_), ToString(audio_sender_state_),
4793                 group->IsPendingConfiguration(), ToString(configuration_context_type_));
4794         group->PrintDebugState();
4795         break;
4796       case AudioState::READY_TO_RELEASE:
4797         switch (audio_sender_state_) {
4798           case AudioState::STARTED:
4799           case AudioState::IDLE:
4800           case AudioState::READY_TO_START:
4801           case AudioState::READY_TO_RELEASE:
4802             /* Stream is up just restore it */
4803             StopSuspendTimeout();
4804             ConfirmLocalAudioSinkStreamingRequest();
4805             break;
4806           case AudioState::RELEASING:
4807             /* Wait until releasing is completed */
4808             break;
4809         }
4810 
4811         break;
4812       case AudioState::RELEASING:
4813         /* Wait until releasing is completed */
4814         break;
4815     }
4816   }
4817 
4818   /* Chooses a single context type to use as a key for selecting a single
4819    * audio set configuration. Contexts used for the metadata can be different
4820    * than this, but it's reasonable to select a configuration context from
4821    * the metadata context types.
4822    */
ChooseConfigurationContextType(AudioContexts available_remote_contexts)4823   LeAudioContextType ChooseConfigurationContextType(AudioContexts available_remote_contexts) {
4824     log::debug("Got contexts={} in config_context={}",
4825                bluetooth::common::ToString(available_remote_contexts),
4826                bluetooth::common::ToString(configuration_context_type_));
4827 
4828     if (IsInCall()) {
4829       log::debug("In Call preference used.");
4830       return LeAudioContextType::CONVERSATIONAL;
4831     }
4832 
4833     /* Mini policy - always prioritize sink+source configurations so that we are
4834      * sure that for a mixed content we enable all the needed directions.
4835      */
4836     if (available_remote_contexts.any()) {
4837       LeAudioContextType context_priority_list[] = {
4838               /* Highest priority first */
4839               LeAudioContextType::CONVERSATIONAL,
4840               LeAudioContextType::RINGTONE,
4841               LeAudioContextType::LIVE,
4842               LeAudioContextType::VOICEASSISTANTS,
4843               LeAudioContextType::GAME,
4844               LeAudioContextType::MEDIA,
4845               LeAudioContextType::EMERGENCYALARM,
4846               LeAudioContextType::ALERTS,
4847               LeAudioContextType::INSTRUCTIONAL,
4848               LeAudioContextType::NOTIFICATIONS,
4849               LeAudioContextType::SOUNDEFFECTS,
4850       };
4851       for (auto ct : context_priority_list) {
4852         if (available_remote_contexts.test(ct)) {
4853           log::debug("Selecting configuration context type: {}", ToString(ct));
4854           return ct;
4855         }
4856       }
4857     }
4858 
4859     /* Use BAP mandated UNSPECIFIED only if we don't have any other valid
4860      * configuration
4861      */
4862     auto fallback_config = LeAudioContextType::UNSPECIFIED;
4863     if (configuration_context_type_ != LeAudioContextType::UNINITIALIZED) {
4864       fallback_config = configuration_context_type_;
4865     }
4866 
4867     log::debug("Selecting configuration context type: {}", ToString(fallback_config));
4868     return fallback_config;
4869   }
4870 
SetConfigurationAndStopStreamWhenNeeded(LeAudioDeviceGroup * group,LeAudioContextType new_context_type)4871   bool SetConfigurationAndStopStreamWhenNeeded(LeAudioDeviceGroup* group,
4872                                                LeAudioContextType new_context_type) {
4873     auto previous_context_type = configuration_context_type_;
4874 
4875     auto reconfig_result = UpdateConfigAndCheckIfReconfigurationIsNeeded(group, new_context_type);
4876     /* Even though the reconfiguration may not be needed, this has
4877      * to be set here as it might be the initial configuration.
4878      */
4879 
4880     configuration_context_type_ = new_context_type;
4881 
4882     log::info("group_id {}, previous_context {} context type {} ({}), {}", group->group_id_,
4883               ToString(previous_context_type), ToString(new_context_type),
4884               ToHexString(new_context_type), ToString(reconfig_result));
4885     if (reconfig_result == AudioReconfigurationResult::RECONFIGURATION_NOT_NEEDED) {
4886       return false;
4887     }
4888 
4889     if (reconfig_result == AudioReconfigurationResult::RECONFIGURATION_NOT_POSSIBLE) {
4890       return false;
4891     }
4892 
4893     if (group->GetState() != AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
4894       log::debug("Group is not streaming");
4895       return false;
4896     }
4897 
4898     StopSuspendTimeout();
4899     /* If group suspend is scheduled, cancel as we are stopping it anyway */
4900 
4901     /* Need to reconfigure stream. At this point pre_configuration_context_type shall be set */
4902 
4903     initReconfiguration(group, previous_context_type);
4904     SendAudioGroupCurrentCodecConfigChanged(group);
4905     return true;
4906   }
4907 
OnLocalAudioSourceMetadataUpdate(const std::vector<struct playback_track_metadata_v7> & source_metadata,DsaMode dsa_mode)4908   void OnLocalAudioSourceMetadataUpdate(
4909           const std::vector<struct playback_track_metadata_v7>& source_metadata, DsaMode dsa_mode) {
4910     if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
4911       log::warn(", cannot start streaming if no active group set");
4912       return;
4913     }
4914 
4915     auto group = aseGroups_.FindById(active_group_id_);
4916     if (!group) {
4917       log::error("Invalid group: {}", static_cast<int>(active_group_id_));
4918       return;
4919     }
4920 
4921     log::info(
4922             "group_id {} state={}, target_state={}, audio_receiver_state_: {}, "
4923             "audio_sender_state_: {}, dsa_mode: {}",
4924             group->group_id_, ToString(group->GetState()), ToString(group->GetTargetState()),
4925             ToString(audio_receiver_state_), ToString(audio_sender_state_),
4926             static_cast<int>(dsa_mode));
4927 
4928     if (IsReconfigurationTimeoutRunning(group->group_id_)) {
4929       log::info("Skip it as group is reconfiguring");
4930       return;
4931     }
4932 
4933     /* Stop the VBC close timeout timer, since we will reconfigure anyway if the
4934      * VBC was suspended.
4935      */
4936     StopVbcCloseTimeout();
4937 
4938     group->dsa_.mode = dsa_mode;
4939 
4940     /* Set the remote sink metadata context from the playback tracks metadata */
4941     local_metadata_context_types_.source = GetAudioContextsFromSourceMetadata(source_metadata);
4942 
4943     local_metadata_context_types_.source =
4944             ChooseMetadataContextType(local_metadata_context_types_.source);
4945 
4946     ReconfigureOrUpdateRemote(group, bluetooth::le_audio::types::kLeAudioDirectionSink);
4947   }
4948 
4949   /* Applies some predefined policy on the audio context metadata, including
4950    * special handling of UNSPECIFIED context, which also involves checking
4951    * context support and availability.
4952    */
ApplyRemoteMetadataAudioContextPolicy(LeAudioDeviceGroup * group,BidirectionalPair<AudioContexts> & contexts_pair,int remote_dir)4953   void ApplyRemoteMetadataAudioContextPolicy(LeAudioDeviceGroup* group,
4954                                              BidirectionalPair<AudioContexts>& contexts_pair,
4955                                              int remote_dir) {
4956     // We expect at least some context when this direction gets enabled
4957     if (contexts_pair.get(remote_dir).none()) {
4958       log::warn("invalid/unknown {} context metadata, using 'UNSPECIFIED' instead",
4959                 (remote_dir == bluetooth::le_audio::types::kLeAudioDirectionSink) ? "sink"
4960                                                                                   : "source");
4961       contexts_pair.get(remote_dir) = AudioContexts(LeAudioContextType::UNSPECIFIED);
4962     }
4963 
4964     std::tuple<int, int, AudioState*> remote_directions[] = {
4965             {bluetooth::le_audio::types::kLeAudioDirectionSink,
4966              bluetooth::le_audio::types::kLeAudioDirectionSource, &audio_sender_state_},
4967             {bluetooth::le_audio::types::kLeAudioDirectionSource,
4968              bluetooth::le_audio::types::kLeAudioDirectionSink, &audio_receiver_state_},
4969     };
4970 
4971     /* Align with the context availability */
4972     for (auto entry : remote_directions) {
4973       int dir, other_dir;
4974       AudioState* local_hal_state;
4975       std::tie(dir, other_dir, local_hal_state) = entry;
4976 
4977       /* When a certain context became unavailable while it was already in
4978        * an active stream, it means that it is unavailable to other clients
4979        * but we can keep using it.
4980        */
4981       auto group_available_contexts = group->GetAvailableContexts(dir);
4982       if ((*local_hal_state == AudioState::STARTED) ||
4983           (*local_hal_state == AudioState::READY_TO_START)) {
4984         group_available_contexts |= group->GetMetadataContexts().get(dir);
4985       }
4986 
4987       log::debug("Checking contexts: {}, against the available contexts: {}",
4988                  ToString(contexts_pair.get(dir)), ToString(group_available_contexts));
4989       auto unavail_contexts = contexts_pair.get(dir) & ~group_available_contexts;
4990       if (unavail_contexts.none()) {
4991         continue;
4992       }
4993 
4994       // Use only available contexts
4995       contexts_pair.get(dir) &= group_available_contexts;
4996 
4997       // Check we we should add UNSPECIFIED as well in case not available context is also not
4998       // supported
4999       auto unavail_but_supported = (unavail_contexts & group->GetSupportedContexts(dir));
5000       if (unavail_but_supported.none() &&
5001           group_available_contexts.test(LeAudioContextType::UNSPECIFIED)) {
5002         contexts_pair.get(dir).set(LeAudioContextType::UNSPECIFIED);
5003 
5004         log::debug("Replaced the unsupported contexts: {} with UNSPECIFIED -> {}",
5005                    ToString(unavail_contexts), ToString(contexts_pair.get(dir)));
5006       } else {
5007         log::debug("Some contexts are supported but currently unavailable: {}!",
5008                    ToString(unavail_but_supported));
5009         /* Some of the streamed contexts are support but not available and they
5010          * were erased from the metadata.
5011          * TODO: Either filter out these contexts from the stream or do not
5012          * stream at all if the unavail_but_supported contexts are the only
5013          * streamed contexts.
5014          */
5015       }
5016     }
5017 
5018     /* Don't mix UNSPECIFIED with any other context
5019      * Note: This has to be in a separate loop - do not merge it with the above.
5020      */
5021     for (auto entry : remote_directions) {
5022       int dir, other_dir;
5023       AudioState* local_hal_state;
5024       std::tie(dir, other_dir, local_hal_state) = entry;
5025 
5026       if (contexts_pair.get(dir).test(LeAudioContextType::UNSPECIFIED)) {
5027         /* If this directions is streaming just UNSPECIFIED and if other direction is streaming some
5028          * meaningfull context type,  try to use the meaningful context type
5029          */
5030         if (contexts_pair.get(dir) == AudioContexts(LeAudioContextType::UNSPECIFIED)) {
5031           auto is_other_direction_streaming = (*local_hal_state == AudioState::STARTED) ||
5032                                               (*local_hal_state == AudioState::READY_TO_START);
5033           if (is_other_direction_streaming) {
5034             auto supported_contexts = group->GetAllSupportedSingleDirectionOnlyContextTypes(dir);
5035             auto common_part = supported_contexts & contexts_pair.get(other_dir);
5036 
5037             log::info(
5038                     "Other direction is streaming. Possible aligning other direction "
5039                     "metadata to match the remote {} direction context: {}. Remote {} supported "
5040                     "contexts: {} ",
5041                     other_dir == bluetooth::le_audio::types::kLeAudioDirectionSink ? " Sink"
5042                                                                                    : " Source",
5043                     ToString(contexts_pair.get(other_dir)),
5044                     dir == bluetooth::le_audio::types::kLeAudioDirectionSink ? " Sink" : " Source",
5045                     ToString(supported_contexts));
5046 
5047             if (common_part.value() != 0) {
5048               contexts_pair.get(dir) = common_part;
5049             }
5050           }
5051         } else {
5052           log::debug("Removing UNSPECIFIED from the remote {} context: {}",
5053                      dir == bluetooth::le_audio::types::kLeAudioDirectionSink ? " Sink" : " Source",
5054                      ToString(contexts_pair.get(other_dir)));
5055           contexts_pair.get(dir).unset(LeAudioContextType::UNSPECIFIED);
5056         }
5057       }
5058     }
5059 
5060     contexts_pair.sink = ChooseMetadataContextType(contexts_pair.sink);
5061     contexts_pair.source = ChooseMetadataContextType(contexts_pair.source);
5062 
5063     log::debug("Aligned remote metadata audio context: sink={}, source={}",
5064                ToString(contexts_pair.sink), ToString(contexts_pair.source));
5065   }
5066 
OnLocalAudioSinkMetadataUpdate(const std::vector<record_track_metadata_v7> & sink_metadata)5067   void OnLocalAudioSinkMetadataUpdate(const std::vector<record_track_metadata_v7>& sink_metadata) {
5068     if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
5069       log::warn(", cannot start streaming if no active group set");
5070       return;
5071     }
5072 
5073     auto group = aseGroups_.FindById(active_group_id_);
5074     if (!group) {
5075       log::error("Invalid group: {}", static_cast<int>(active_group_id_));
5076       return;
5077     }
5078 
5079     log::info(
5080             "group_id {} state={}, target_state={}, audio_receiver_state_: {}, "
5081             "audio_sender_state_: {}",
5082             group->group_id_, ToString(group->GetState()), ToString(group->GetTargetState()),
5083             ToString(audio_receiver_state_), ToString(audio_sender_state_));
5084 
5085     if (IsReconfigurationTimeoutRunning(group->group_id_)) {
5086       log::info("Skip it as group is reconfiguring");
5087       return;
5088     }
5089 
5090     /* Set remote source metadata context from the recording tracks metadata */
5091     local_metadata_context_types_.sink = GetAudioContextsFromSinkMetadata(sink_metadata);
5092 
5093     local_metadata_context_types_.sink =
5094             ChooseMetadataContextType(local_metadata_context_types_.sink);
5095 
5096     /* Reconfigure or update only if the stream is already started
5097      * otherwise wait for the local sink to resume.
5098      */
5099     if (audio_receiver_state_ == AudioState::STARTED) {
5100       ReconfigureOrUpdateRemote(group, bluetooth::le_audio::types::kLeAudioDirectionSource);
5101     }
5102   }
5103 
DirectionalRealignMetadataAudioContexts(LeAudioDeviceGroup * group,int remote_direction)5104   BidirectionalPair<AudioContexts> DirectionalRealignMetadataAudioContexts(
5105           LeAudioDeviceGroup* group, int remote_direction) {
5106     uint8_t remote_other_direction;
5107     std::string remote_direction_str;
5108     std::string remote_other_direction_str;
5109     AudioState other_direction_hal;
5110 
5111     if (remote_direction == bluetooth::le_audio::types::kLeAudioDirectionSink) {
5112       remote_other_direction = bluetooth::le_audio::types::kLeAudioDirectionSource;
5113       remote_direction_str = "Sink";
5114       remote_other_direction_str = "Source";
5115       other_direction_hal = audio_receiver_state_;
5116     } else {
5117       remote_other_direction = bluetooth::le_audio::types::kLeAudioDirectionSink;
5118       remote_direction_str = "Source";
5119       remote_other_direction_str = "Sink";
5120       other_direction_hal = audio_sender_state_;
5121     }
5122 
5123     auto is_streaming_other_direction = (other_direction_hal == AudioState::STARTED) ||
5124                                         (other_direction_hal == AudioState::READY_TO_START);
5125 
5126     auto local_direction = bluetooth::le_audio::types::kLeAudioDirectionBoth & ~remote_direction;
5127     auto local_other_direction =
5128             bluetooth::le_audio::types::kLeAudioDirectionBoth & ~remote_other_direction;
5129 
5130     auto is_releasing_for_reconfiguration =
5131             (((audio_receiver_state_ == AudioState::RELEASING) ||
5132               (audio_sender_state_ == AudioState::RELEASING)) &&
5133              group->IsPendingConfiguration() &&
5134              IsDirectionAvailableForCurrentConfiguration(group, remote_other_direction)) ||
5135             IsReconfigurationTimeoutRunning(active_group_id_, local_direction);
5136 
5137     auto is_releasing_for_reconfiguration_other_direction =
5138             is_releasing_for_reconfiguration &
5139             IsReconfigurationTimeoutRunning(active_group_id_, local_other_direction);
5140 
5141     // Inject conversational when ringtone is played - this is required for all
5142     // the VoIP applications which are not using the telecom API.
5143     constexpr AudioContexts possible_voip_contexts =
5144             LeAudioContextType::RINGTONE | LeAudioContextType::CONVERSATIONAL;
5145     if (local_metadata_context_types_.source.test_any(possible_voip_contexts) &&
5146         ((remote_direction == bluetooth::le_audio::types::kLeAudioDirectionSink) ||
5147          (remote_direction == bluetooth::le_audio::types::kLeAudioDirectionSource &&
5148           is_streaming_other_direction))) {
5149       /* Simulate, we are already in the call. Sending RINGTONE when there is
5150        * no incoming call to accept or reject on TBS could confuse the remote
5151        * device and interrupt the stream establish procedure.
5152        */
5153       if (!IsInCall()) {
5154         SetInVoipCall(true);
5155       }
5156     } else if (IsInVoipCall()) {
5157       SetInVoipCall(false);
5158     }
5159 
5160     BidirectionalPair<AudioContexts> remote_metadata = {
5161             .sink = local_metadata_context_types_.source,
5162             .source = local_metadata_context_types_.sink};
5163 
5164     auto all_bidirectional_contexts = group->GetAllSupportedBidirectionalContextTypes();
5165     log::debug("all_bidirectional_contexts {}", ToString(all_bidirectional_contexts));
5166 
5167     /* Make sure we have CONVERSATIONAL when in a call and it is not mixed
5168      * with any other bidirectional context
5169      */
5170     if (IsInCall() || IsInVoipCall()) {
5171       log::debug("In Call preference used: {}, voip call: {}", IsInCall(), IsInVoipCall());
5172       remote_metadata.sink.unset_all(all_bidirectional_contexts);
5173       remote_metadata.source.unset_all(all_bidirectional_contexts);
5174       remote_metadata.sink.set(LeAudioContextType::CONVERSATIONAL);
5175       remote_metadata.source.set(LeAudioContextType::CONVERSATIONAL);
5176     }
5177 
5178     if (!com::android::bluetooth::flags::leaudio_speed_up_reconfiguration_between_call()) {
5179       local_metadata_context_types_.sink = remote_metadata.source;
5180       local_metadata_context_types_.source = remote_metadata.sink;
5181     }
5182 
5183     if (IsInVoipCall()) {
5184       log::debug("Unsetting RINGTONE from remote sink");
5185       remote_metadata.sink.unset(LeAudioContextType::RINGTONE);
5186     }
5187 
5188     auto is_ongoing_call_on_other_direction =
5189             is_streaming_other_direction && (IsInVoipCall() || IsInCall());
5190 
5191     log::debug("local_metadata_context_types_.source= {}",
5192                ToString(local_metadata_context_types_.source));
5193     log::debug("local_metadata_context_types_.sink= {}",
5194                ToString(local_metadata_context_types_.sink));
5195     log::debug("remote_metadata.source= {}", ToString(remote_metadata.source));
5196     log::debug("remote_metadata.sink= {}", ToString(remote_metadata.sink));
5197     log::debug("remote_direction= {}", remote_direction_str);
5198     log::debug("is_streaming_other_direction= {}", is_streaming_other_direction ? "True" : "False");
5199     log::debug("is_releasing_for_reconfiguration= {}",
5200                is_releasing_for_reconfiguration ? "True" : "False");
5201     log::debug("is_releasing_for_reconfiguration_other_direction= {}",
5202                is_releasing_for_reconfiguration_other_direction ? "True" : "False");
5203     log::debug("is_ongoing_call_on_other_direction={}",
5204                is_ongoing_call_on_other_direction ? "True" : "False");
5205 
5206     if (remote_metadata.get(remote_other_direction).test_any(all_bidirectional_contexts) &&
5207         !(is_streaming_other_direction || is_releasing_for_reconfiguration_other_direction)) {
5208       log::debug("The other direction is not streaming bidirectional, ignore that context.");
5209       remote_metadata.get(remote_other_direction).clear();
5210     }
5211 
5212     auto single_direction_only_context_types =
5213             group->GetAllSupportedSingleDirectionOnlyContextTypes(remote_direction);
5214     auto single_other_direction_only_context_types =
5215             group->GetAllSupportedSingleDirectionOnlyContextTypes(remote_other_direction);
5216     log::debug(
5217             "single direction only contexts : {} for direction {}, single direction contexts {} "
5218             "for {}",
5219             ToString(single_direction_only_context_types), remote_direction_str,
5220             ToString(single_other_direction_only_context_types), remote_other_direction_str);
5221 
5222     /* Mixed contexts in the voiceback channel scenarios can confuse the remote
5223      * on how to configure each channel. We should align the other direction
5224      * metadata for the remote device.
5225      */
5226     if (remote_metadata.get(remote_direction).test_any(all_bidirectional_contexts)) {
5227       log::debug("Aligning the other direction remote metadata to add this direction context");
5228 
5229       if (is_ongoing_call_on_other_direction) {
5230         /* Other direction is streaming and is in call */
5231         remote_metadata.get(remote_direction).unset_all(all_bidirectional_contexts);
5232         remote_metadata.get(remote_direction).set(LeAudioContextType::CONVERSATIONAL);
5233       } else {
5234         if (!(is_streaming_other_direction || is_releasing_for_reconfiguration_other_direction)) {
5235           // Do not take the obsolete metadata
5236           remote_metadata.get(remote_other_direction).clear();
5237         } else {
5238           remote_metadata.get(remote_other_direction).unset_all(all_bidirectional_contexts);
5239           remote_metadata.get(remote_other_direction)
5240                   .unset_all(single_direction_only_context_types);
5241         }
5242 
5243         remote_metadata.get(remote_other_direction)
5244                 .set_all(remote_metadata.get(remote_direction) &
5245                          ~single_other_direction_only_context_types);
5246       }
5247     }
5248     log::debug("remote_metadata.source= {}", ToString(remote_metadata.source));
5249     log::debug("remote_metadata.sink= {}", ToString(remote_metadata.sink));
5250 
5251     if (is_releasing_for_reconfiguration || is_streaming_other_direction) {
5252       log::debug("Other direction is streaming or there is reconfiguration. Taking its contexts {}",
5253                  ToString(remote_metadata.get(remote_other_direction)));
5254       /* If current direction has no valid context or the other direction is
5255        * bidirectional scenario, take the other direction context as well
5256        */
5257       if ((remote_metadata.get(remote_direction).none() &&
5258            remote_metadata.get(remote_other_direction).any()) ||
5259           remote_metadata.get(remote_other_direction).test_any(all_bidirectional_contexts)) {
5260         log::debug("Aligning this direction remote metadata to add the other direction context");
5261         /* Turn off bidirectional contexts on this direction to avoid mixing
5262          * with the other direction bidirectional context
5263          */
5264         remote_metadata.get(remote_direction).unset_all(all_bidirectional_contexts);
5265         remote_metadata.get(remote_direction).set_all(remote_metadata.get(remote_other_direction));
5266       }
5267     }
5268 
5269     /* Make sure that after alignment no sink only context leaks into the other
5270      * direction. */
5271     remote_metadata.source.unset_all(group->GetAllSupportedSingleDirectionOnlyContextTypes(
5272             bluetooth::le_audio::types::kLeAudioDirectionSink));
5273 
5274     log::debug("final remote_metadata.source= {}", ToString(remote_metadata.source));
5275     log::debug("final remote_metadata.sink= {}", ToString(remote_metadata.sink));
5276     return remote_metadata;
5277   }
5278 
ReconfigureOrUpdateRemoteForPTS(LeAudioDeviceGroup * group,int)5279   bool ReconfigureOrUpdateRemoteForPTS(LeAudioDeviceGroup* group, int /*remote_direction*/) {
5280     log::info("{}", group->group_id_);
5281     // Use common audio stream contexts exposed by the PTS
5282     auto override_contexts = AudioContexts(0xFFFF);
5283     for (auto device = group->GetFirstDevice(); device != nullptr;
5284          device = group->GetNextDevice(device)) {
5285       override_contexts &= device->GetAvailableContexts();
5286     }
5287     if (override_contexts.value() == 0xFFFF) {
5288       override_contexts = AudioContexts(LeAudioContextType::UNSPECIFIED);
5289     }
5290     log::warn("Overriding local_metadata_context_types_: {} with: {}",
5291               local_metadata_context_types_.source.to_string(), override_contexts.to_string());
5292 
5293     /* Choose the right configuration context */
5294     auto new_configuration_context = ChooseConfigurationContextType(override_contexts);
5295 
5296     log::info("new_configuration_context= {}.", ToString(new_configuration_context));
5297     BidirectionalPair<AudioContexts> remote_contexts = {.sink = override_contexts,
5298                                                         .source = override_contexts};
5299     return GroupStream(active_group_id_, new_configuration_context, remote_contexts);
5300   }
5301 
5302   /* Return true if stream is started */
ReconfigureOrUpdateRemote(LeAudioDeviceGroup * group,int remote_direction)5303   bool ReconfigureOrUpdateRemote(LeAudioDeviceGroup* group, int remote_direction) {
5304     if (stack_config_get_interface()->get_pts_force_le_audio_multiple_contexts_metadata()) {
5305       return ReconfigureOrUpdateRemoteForPTS(group, remote_direction);
5306     }
5307 
5308     /* When the local sink and source update their metadata, we need to come up
5309      * with a coherent set of contexts for either one or both directions,
5310      * especially when bidirectional scenarios can be triggered be either sink
5311      * or source metadata update event.
5312      */
5313     auto remote_metadata = DirectionalRealignMetadataAudioContexts(group, remote_direction);
5314 
5315     /* Choose the right configuration context */
5316     auto config_context_candids = get_bidirectional(remote_metadata);
5317     auto new_config_context = ChooseConfigurationContextType(config_context_candids);
5318     log::debug("config_context_candids= {}, new_config_context= {}",
5319                ToString(config_context_candids), ToString(new_config_context));
5320 
5321     /* For the following contexts we don't actually need HQ audio:
5322      * LeAudioContextType::NOTIFICATIONS
5323      * LeAudioContextType::SOUNDEFFECTS
5324      * LeAudioContextType::INSTRUCTIONAL
5325      * LeAudioContextType::ALERTS
5326      * LeAudioContextType::EMERGENCYALARM
5327      * LeAudioContextType::UNSPECIFIED
5328      * So do not reconfigure if the remote sink is already available at any
5329      * quality and these are the only contributors to the current audio stream.
5330      */
5331     auto no_reconfigure_contexts =
5332             LeAudioContextType::NOTIFICATIONS | LeAudioContextType::SOUNDEFFECTS |
5333             LeAudioContextType::INSTRUCTIONAL | LeAudioContextType::ALERTS |
5334             LeAudioContextType::EMERGENCYALARM | LeAudioContextType::UNSPECIFIED;
5335     if (group->IsStreaming() && !group->IsReleasingOrIdle() && config_context_candids.any() &&
5336         (config_context_candids & ~no_reconfigure_contexts).none() &&
5337         (configuration_context_type_ != LeAudioContextType::UNINITIALIZED) &&
5338         (configuration_context_type_ != LeAudioContextType::UNSPECIFIED) &&
5339         IsDirectionAvailableForCurrentConfiguration(
5340                 group, bluetooth::le_audio::types::kLeAudioDirectionSink)) {
5341       log::info(
5342               "There is no need to reconfigure for the sonification events, "
5343               "staying with the existing configuration context of {}",
5344               ToString(configuration_context_type_));
5345       new_config_context = configuration_context_type_;
5346     }
5347 
5348     /* Do not configure the Voiceback channel if it is already configured.
5349      * WARNING: This eliminates additional reconfigurations but can
5350      * lead to unsatisfying audio quality when that direction was
5351      * already configured with a lower quality.
5352      */
5353     if (remote_direction == bluetooth::le_audio::types::kLeAudioDirectionSource) {
5354       const auto has_audio_source_configured =
5355               IsDirectionAvailableForCurrentConfiguration(
5356                       group, bluetooth::le_audio::types::kLeAudioDirectionSource) &&
5357               (group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5358       if (has_audio_source_configured) {
5359         log::info(
5360                 "Audio source is already available in the current configuration "
5361                 "context in {}. Not switching to {} right now.",
5362                 ToString(configuration_context_type_), ToString(new_config_context));
5363         new_config_context = configuration_context_type_;
5364       }
5365     }
5366 
5367     /* Note that the remote device metadata was so far unfiltered when it comes
5368      * to group context availability, or multiple contexts support flag, so that
5369      * we could choose the correct configuration for the use case. Now we can
5370      * align it to meet the metadata usage.
5371      */
5372     ApplyRemoteMetadataAudioContextPolicy(group, remote_metadata, remote_direction);
5373     return ReconfigureOrUpdateMetadata(group, new_config_context, remote_metadata);
5374   }
5375 
DsaReconfigureNeeded(LeAudioDeviceGroup * group,LeAudioContextType context)5376   bool DsaReconfigureNeeded(LeAudioDeviceGroup* group, LeAudioContextType context) {
5377     if (!com::android::bluetooth::flags::leaudio_dynamic_spatial_audio()) {
5378       return false;
5379     }
5380 
5381     // Reconfigure if DSA mode changed for media streaming
5382     if (context != bluetooth::le_audio::types::LeAudioContextType::MEDIA) {
5383       return false;
5384     }
5385 
5386     if (group->dsa_.mode != DsaMode::ISO_SW && group->dsa_.mode != DsaMode::ISO_HW) {
5387       return false;
5388     }
5389 
5390     if (group->dsa_.active) {
5391       return false;
5392     }
5393 
5394     log::info("DSA mode {} requested but not active", group->dsa_.mode);
5395     return true;
5396   }
5397 
5398   /* Return true if stream is started */
ReconfigureOrUpdateMetadata(LeAudioDeviceGroup * group,LeAudioContextType new_configuration_context,BidirectionalPair<AudioContexts> remote_contexts)5399   bool ReconfigureOrUpdateMetadata(LeAudioDeviceGroup* group,
5400                                    LeAudioContextType new_configuration_context,
5401                                    BidirectionalPair<AudioContexts> remote_contexts) {
5402     if (new_configuration_context != configuration_context_type_ ||
5403         DsaReconfigureNeeded(group, new_configuration_context)) {
5404       log::info("Checking whether to change configuration context from {} to {}",
5405                 ToString(configuration_context_type_), ToString(new_configuration_context));
5406 
5407       LeAudioLogHistory::Get()->AddLogHistory(
5408               kLogAfCallBt, active_group_id_, RawAddress::kEmpty,
5409               kLogAfMetadataUpdate + "Reconfigure",
5410               ToString(configuration_context_type_) + "->" + ToString(new_configuration_context));
5411       auto is_stopping = SetConfigurationAndStopStreamWhenNeeded(group, new_configuration_context);
5412       if (is_stopping) {
5413         return false;
5414       }
5415     }
5416 
5417     if (group->GetTargetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
5418       log::info("The {} configuration did not change. Updating the metadata to sink={}, source={}",
5419                 ToString(configuration_context_type_), ToString(remote_contexts.sink),
5420                 ToString(remote_contexts.source));
5421 
5422       LeAudioLogHistory::Get()->AddLogHistory(
5423               kLogAfCallBt, active_group_id_, RawAddress::kEmpty,
5424               kLogAfMetadataUpdate + "Updating...",
5425               "Sink: " + ToString(remote_contexts.sink) +
5426                       "Source: " + ToString(remote_contexts.source));
5427 
5428       return GroupStream(group->group_id_, configuration_context_type_, remote_contexts);
5429     }
5430     return false;
5431   }
5432 
OnGattReadRspStatic(tCONN_ID conn_id,tGATT_STATUS status,uint16_t hdl,uint16_t len,uint8_t * value,void * data)5433   static void OnGattReadRspStatic(tCONN_ID conn_id, tGATT_STATUS status, uint16_t hdl, uint16_t len,
5434                                   uint8_t* value, void* data) {
5435     if (!instance) {
5436       return;
5437     }
5438 
5439     LeAudioDevice* leAudioDevice = instance->leAudioDevices_.FindByConnId(conn_id);
5440 
5441     if (status == GATT_SUCCESS) {
5442       instance->LeAudioCharValueHandle(conn_id, hdl, len, value);
5443     } else if (status == GATT_DATABASE_OUT_OF_SYNC) {
5444       instance->ClearDeviceInformationAndStartSearch(leAudioDevice);
5445       return;
5446     } else {
5447       log::error("Failed to read attribute, hdl: 0x{:04x}, status: 0x{:02x}", hdl,
5448                  static_cast<int>(status));
5449       return;
5450     }
5451 
5452     /* We use data to keep notify connected flag. */
5453     if (data && !!PTR_TO_INT(data)) {
5454       leAudioDevice->notify_connected_after_read_ = false;
5455 
5456       /* Update handles, PACs and ASEs when all is read.*/
5457       btif_storage_leaudio_update_handles_bin(leAudioDevice->address_);
5458       btif_storage_leaudio_update_pacs_bin(leAudioDevice->address_);
5459       btif_storage_leaudio_update_ase_bin(leAudioDevice->address_);
5460 
5461       btif_storage_set_leaudio_audio_location(leAudioDevice->address_,
5462                                               leAudioDevice->snk_audio_locations_.to_ulong(),
5463                                               leAudioDevice->src_audio_locations_.to_ulong());
5464 
5465       instance->connectionReady(leAudioDevice);
5466     }
5467   }
5468 
OnGattReadMultiRspStatic(tCONN_ID conn_id,tGATT_STATUS status,tBTA_GATTC_MULTI & handles,uint16_t total_len,uint8_t * value,void * data)5469   static void OnGattReadMultiRspStatic(tCONN_ID conn_id, tGATT_STATUS status,
5470                                        tBTA_GATTC_MULTI& handles, uint16_t total_len,
5471                                        uint8_t* value, void* data) {
5472     if (!instance) {
5473       return;
5474     }
5475 
5476     if (status == GATT_DATABASE_OUT_OF_SYNC) {
5477       LeAudioDevice* leAudioDevice = instance->leAudioDevices_.FindByConnId(conn_id);
5478       instance->ClearDeviceInformationAndStartSearch(leAudioDevice);
5479       return;
5480     }
5481     if (status != GATT_SUCCESS) {
5482       log::error("Failed to read multiple attributes, conn_id: 0x{:04x}, status: 0x{:02x}", conn_id,
5483                  +status);
5484       return;
5485     }
5486 
5487     size_t position = 0;
5488     int index = 0;
5489     while (position != total_len) {
5490       uint8_t* ptr = value + position;
5491       uint16_t len;
5492       STREAM_TO_UINT16(len, ptr);
5493       uint16_t hdl = handles.handles[index];
5494 
5495       if (position + len >= total_len) {
5496         log::warn("Multi read was too long, value truncated conn_id: 0x{:04x} handle: 0x{:04x}",
5497                   conn_id, hdl);
5498         break;
5499       }
5500 
5501       OnGattReadRspStatic(conn_id, status, hdl, len, ptr,
5502                           ((index == (handles.num_attr - 1)) ? data : nullptr));
5503 
5504       position += len + 2; /* skip the length of data */
5505       index++;
5506     }
5507 
5508     if (handles.num_attr - 1 != index) {
5509       log::warn("Attempted to read {} handles, but received just {} values", +handles.num_attr,
5510                 index + 1);
5511     }
5512   }
5513 
LeAudioHealthSendRecommendation(const RawAddress & address,int group_id,LeAudioHealthBasedAction action)5514   void LeAudioHealthSendRecommendation(const RawAddress& address, int group_id,
5515                                        LeAudioHealthBasedAction action) {
5516     log::debug("{}, {}, {}", address, group_id, ToString(action));
5517 
5518     if (address != RawAddress::kEmpty && leAudioDevices_.FindByAddress(address)) {
5519       callbacks_->OnHealthBasedRecommendationAction(address, action);
5520     }
5521 
5522     if (group_id != bluetooth::groups::kGroupUnknown && aseGroups_.FindById(group_id)) {
5523       callbacks_->OnHealthBasedGroupRecommendationAction(group_id, action);
5524     }
5525   }
5526 
IsoCigEventsCb(uint16_t event_type,void * data)5527   void IsoCigEventsCb(uint16_t event_type, void* data) {
5528     switch (event_type) {
5529       case bluetooth::hci::iso_manager::kIsoEventCigOnCreateCmpl: {
5530         auto* evt = static_cast<cig_create_cmpl_evt*>(data);
5531         LeAudioDeviceGroup* group = aseGroups_.FindById(evt->cig_id);
5532         log::assert_that(group, "Group id: {} is null", evt->cig_id);
5533         groupStateMachine_->ProcessHciNotifOnCigCreate(group, evt->status, evt->cig_id,
5534                                                        evt->conn_handles);
5535       } break;
5536       case bluetooth::hci::iso_manager::kIsoEventCigOnRemoveCmpl: {
5537         auto* evt = static_cast<cig_remove_cmpl_evt*>(data);
5538         LeAudioDeviceGroup* group = aseGroups_.FindById(evt->cig_id);
5539         log::assert_that(group, "Group id: {} is null", evt->cig_id);
5540         groupStateMachine_->ProcessHciNotifOnCigRemove(evt->status, group);
5541         remove_group_if_possible(group);
5542       } break;
5543       default:
5544         log::error("Invalid event {}", event_type);
5545     }
5546   }
5547 
IsoCisEventsCb(uint16_t event_type,void * data)5548   void IsoCisEventsCb(uint16_t event_type, void* data) {
5549     switch (event_type) {
5550       case bluetooth::hci::iso_manager::kIsoEventCisDataAvailable: {
5551         auto* event = static_cast<bluetooth::hci::iso_manager::cis_data_evt*>(data);
5552 
5553         if (DsaDataConsume(event)) {
5554           return;
5555         }
5556 
5557         if (audio_receiver_state_ != AudioState::STARTED) {
5558           log::error("receiver state not ready, current state={}", ToString(audio_receiver_state_));
5559           break;
5560         }
5561 
5562         HandleIncomingCisData(event->p_msg->data + event->p_msg->offset,
5563                               event->p_msg->len - event->p_msg->offset, event->cis_conn_hdl,
5564                               event->ts);
5565       } break;
5566       case bluetooth::hci::iso_manager::kIsoEventCisEstablishCmpl: {
5567         auto* event = static_cast<bluetooth::hci::iso_manager::cis_establish_cmpl_evt*>(data);
5568 
5569         LeAudioDevice* leAudioDevice =
5570                 leAudioDevices_.FindByCisConnHdl(event->cig_id, event->cis_conn_hdl);
5571         if (!leAudioDevice) {
5572           log::error("no bonded Le Audio Device with CIS: {}", event->cis_conn_hdl);
5573           break;
5574         }
5575         LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
5576 
5577         if (event->max_pdu_mtos > 0) {
5578           group->SetTransportLatency(bluetooth::le_audio::types::kLeAudioDirectionSink,
5579                                      event->trans_lat_mtos);
5580         }
5581         if (event->max_pdu_stom > 0) {
5582           group->SetTransportLatency(bluetooth::le_audio::types::kLeAudioDirectionSource,
5583                                      event->trans_lat_stom);
5584         }
5585 
5586         if (leAudioHealthStatus_ && (event->status != HCI_SUCCESS)) {
5587           leAudioHealthStatus_->AddStatisticForGroup(
5588                   group, LeAudioHealthGroupStatType::STREAM_CREATE_CIS_FAILED);
5589         }
5590 
5591         groupStateMachine_->ProcessHciNotifCisEstablished(group, leAudioDevice, event);
5592       } break;
5593       case bluetooth::hci::iso_manager::kIsoEventCisDisconnected: {
5594         auto* event = static_cast<bluetooth::hci::iso_manager::cis_disconnected_evt*>(data);
5595 
5596         LeAudioDevice* leAudioDevice =
5597                 leAudioDevices_.FindByCisConnHdl(event->cig_id, event->cis_conn_hdl);
5598         if (!leAudioDevice) {
5599           log::error("no bonded Le Audio Device with CIS: {}", event->cis_conn_hdl);
5600           break;
5601         }
5602         LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
5603 
5604         groupStateMachine_->ProcessHciNotifCisDisconnected(group, leAudioDevice, event);
5605       } break;
5606       default:
5607         log::info(", Not handled ISO event");
5608         break;
5609     }
5610   }
5611 
IsoSetupIsoDataPathCb(uint8_t status,uint16_t conn_handle,uint8_t cig_id)5612   void IsoSetupIsoDataPathCb(uint8_t status, uint16_t conn_handle, uint8_t cig_id) {
5613     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByCisConnHdl(cig_id, conn_handle);
5614     /* In case device has been disconnected before data path was setup */
5615     if (!leAudioDevice) {
5616       log::warn("Device for CIG {} and using cis_handle 0x{:04x} is disconnected.", cig_id,
5617                 conn_handle);
5618       return;
5619     }
5620     LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
5621 
5622     instance->groupStateMachine_->ProcessHciNotifSetupIsoDataPath(group, leAudioDevice, status,
5623                                                                   conn_handle);
5624   }
5625 
IsoRemoveIsoDataPathCb(uint8_t status,uint16_t conn_handle,uint8_t cig_id)5626   void IsoRemoveIsoDataPathCb(uint8_t status, uint16_t conn_handle, uint8_t cig_id) {
5627     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByCisConnHdl(cig_id, conn_handle);
5628 
5629     /* If CIS has been disconnected just before ACL being disconnected by the
5630      * remote device, leAudioDevice might be already cleared i.e. has no
5631      * information about conn_handle, when the data path remove compete arrives.
5632      */
5633     if (!leAudioDevice) {
5634       log::warn("Device for CIG {} and using cis_handle 0x{:04x} is disconnected.", cig_id,
5635                 conn_handle);
5636       return;
5637     }
5638 
5639     LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
5640 
5641     instance->groupStateMachine_->ProcessHciNotifRemoveIsoDataPath(group, leAudioDevice, status,
5642                                                                    conn_handle);
5643   }
5644 
IsoLinkQualityReadCb(uint8_t conn_handle,uint8_t cig_id,uint32_t txUnackedPackets,uint32_t txFlushedPackets,uint32_t txLastSubeventPackets,uint32_t retransmittedPackets,uint32_t crcErrorPackets,uint32_t rxUnreceivedPackets,uint32_t duplicatePackets)5645   void IsoLinkQualityReadCb(uint8_t conn_handle, uint8_t cig_id, uint32_t txUnackedPackets,
5646                             uint32_t txFlushedPackets, uint32_t txLastSubeventPackets,
5647                             uint32_t retransmittedPackets, uint32_t crcErrorPackets,
5648                             uint32_t rxUnreceivedPackets, uint32_t duplicatePackets) {
5649     LeAudioDevice* leAudioDevice = leAudioDevices_.FindByCisConnHdl(cig_id, conn_handle);
5650     if (!leAudioDevice) {
5651       log::warn("device under connection handle: 0x{:x}, has been disconnecected in meantime",
5652                 conn_handle);
5653       return;
5654     }
5655     LeAudioDeviceGroup* group = aseGroups_.FindById(leAudioDevice->group_id_);
5656 
5657     instance->groupStateMachine_->ProcessHciNotifIsoLinkQualityRead(
5658             group, leAudioDevice, conn_handle, txUnackedPackets, txFlushedPackets,
5659             txLastSubeventPackets, retransmittedPackets, crcErrorPackets, rxUnreceivedPackets,
5660             duplicatePackets);
5661   }
5662 
HandlePendingDeviceRemove(LeAudioDeviceGroup * group)5663   void HandlePendingDeviceRemove(LeAudioDeviceGroup* group) {
5664     for (auto device = group->GetFirstDevice(); device != nullptr;
5665          device = group->GetNextDevice(device)) {
5666       if (device->GetConnectionState() == DeviceConnectState::REMOVING) {
5667         if (device->closing_stream_for_disconnection_) {
5668           device->closing_stream_for_disconnection_ = false;
5669           log::info("Disconnecting group id: {}, address: {}", group->group_id_, device->address_);
5670           bool force_acl_disconnect = device->autoconnect_flag_ && group->IsEnabled();
5671           DisconnectDevice(device, force_acl_disconnect);
5672         }
5673         group_remove_node(group, device->address_, true);
5674       }
5675     }
5676   }
5677 
HandlePendingDeviceDisconnection(LeAudioDeviceGroup * group)5678   void HandlePendingDeviceDisconnection(LeAudioDeviceGroup* group) {
5679     log::debug("");
5680 
5681     auto leAudioDevice = group->GetFirstDevice();
5682     while (leAudioDevice) {
5683       if (leAudioDevice->closing_stream_for_disconnection_) {
5684         leAudioDevice->closing_stream_for_disconnection_ = false;
5685         log::debug("Disconnecting group id: {}, address: {}", group->group_id_,
5686                    leAudioDevice->address_);
5687         bool force_acl_disconnect = leAudioDevice->autoconnect_flag_ && group->IsEnabled();
5688         DisconnectDevice(leAudioDevice, force_acl_disconnect);
5689       }
5690       leAudioDevice = group->GetNextDevice(leAudioDevice);
5691     }
5692   }
5693 
UpdateAudioConfigToHal(const::bluetooth::le_audio::offload_config & config,uint8_t remote_direction)5694   void UpdateAudioConfigToHal(const ::bluetooth::le_audio::offload_config& config,
5695                               uint8_t remote_direction) {
5696     if ((remote_direction & bluetooth::le_audio::types::kLeAudioDirectionSink) &&
5697         le_audio_source_hal_client_) {
5698       le_audio_source_hal_client_->UpdateAudioConfigToHal(config);
5699     }
5700     if ((remote_direction & bluetooth::le_audio::types::kLeAudioDirectionSource) &&
5701         le_audio_sink_hal_client_) {
5702       le_audio_sink_hal_client_->UpdateAudioConfigToHal(config);
5703     }
5704   }
5705 
NotifyUpperLayerGroupTurnedIdleDuringCall(int group_id)5706   void NotifyUpperLayerGroupTurnedIdleDuringCall(int group_id) {
5707     if (!osi_property_get_bool(kNotifyUpperLayerAboutGroupBeingInIdleDuringCall, false)) {
5708       return;
5709     }
5710 
5711     /* If group is inactive, phone is in call and Group is not having CIS
5712      * connected, notify upper layer about it, so it can decide to create SCO if
5713      * it is in the handover case
5714      */
5715     if ((IsInCall() || IsInVoipCall()) && active_group_id_ == bluetooth::groups::kGroupUnknown) {
5716       callbacks_->OnGroupStatus(group_id, GroupStatus::TURNED_IDLE_DURING_CALL);
5717     }
5718   }
5719 
speed_start_setup(int group_id,LeAudioContextType context_type,int num_of_connected,bool is_reconfig=false)5720   void speed_start_setup(int group_id, LeAudioContextType context_type, int num_of_connected,
5721                          bool is_reconfig = false) {
5722     log::verbose("is_started {} is_reconfig {} num_of_connected {}", speed_tracker_.IsStarted(),
5723                  is_reconfig, num_of_connected);
5724     if (!speed_tracker_.IsStarted()) {
5725       speed_tracker_.Init(group_id, context_type, num_of_connected);
5726     }
5727     if (is_reconfig) {
5728       speed_tracker_.ReconfigStarted();
5729     } else {
5730       speed_tracker_.StartStream();
5731     }
5732   }
5733 
speed_stop_reconfig(void)5734   void speed_stop_reconfig(void) {
5735     log::verbose("");
5736     if (!speed_tracker_.IsStarted()) {
5737       return;
5738     }
5739     speed_tracker_.ReconfigurationComplete();
5740   }
5741 
speed_stream_created()5742   void speed_stream_created() {
5743     log::verbose("");
5744     if (!speed_tracker_.IsStarted()) {
5745       return;
5746     }
5747 
5748     speed_tracker_.StreamCreated();
5749   }
5750 
speed_stop_setup()5751   void speed_stop_setup() {
5752     log::verbose("");
5753     if (!speed_tracker_.IsStarted()) {
5754       return;
5755     }
5756 
5757     if (stream_speed_history_.size() == 10) {
5758       stream_speed_history_.pop_back();
5759     }
5760 
5761     speed_tracker_.StopStreamSetup();
5762     stream_speed_history_.emplace_front(speed_tracker_);
5763     speed_tracker_.Reset();
5764   }
5765 
notifyGroupStreamStatus(int group_id,GroupStreamStatus groupStreamStatus)5766   void notifyGroupStreamStatus(int group_id, GroupStreamStatus groupStreamStatus) {
5767     GroupStreamStatus newGroupStreamStatus = GroupStreamStatus::IDLE;
5768     if (groupStreamStatus == GroupStreamStatus::STREAMING) {
5769       newGroupStreamStatus = GroupStreamStatus::STREAMING;
5770     }
5771 
5772     auto it = lastNotifiedGroupStreamStatusMap_.find(group_id);
5773 
5774     if (it != lastNotifiedGroupStreamStatusMap_.end()) {
5775       if (it->second != newGroupStreamStatus) {
5776         callbacks_->OnGroupStreamStatus(group_id, newGroupStreamStatus);
5777         it->second = newGroupStreamStatus;
5778       }
5779     } else {
5780       callbacks_->OnGroupStreamStatus(group_id, newGroupStreamStatus);
5781       lastNotifiedGroupStreamStatusMap_.emplace(group_id, newGroupStreamStatus);
5782     }
5783   }
5784 
handleAsymmetricPhyForUnicast(LeAudioDeviceGroup * group)5785   void handleAsymmetricPhyForUnicast(LeAudioDeviceGroup* group) {
5786     if (!group->asymmetric_phy_for_unidirectional_cis_supported) {
5787       return;
5788     }
5789 
5790     auto it = lastNotifiedGroupStreamStatusMap_.find(group->group_id_);
5791 
5792     if (it != lastNotifiedGroupStreamStatusMap_.end() &&
5793         it->second == GroupStreamStatus::STREAMING &&
5794         group->GetSduInterval(bluetooth::le_audio::types::kLeAudioDirectionSource) == 0) {
5795       SetAsymmetricBlePhy(group, true);
5796       return;
5797     }
5798 
5799     SetAsymmetricBlePhy(group, false);
5800   }
5801 
reconfigurationComplete(void)5802   void reconfigurationComplete(void) {
5803     // Check which directions were suspended
5804     uint8_t previously_active_directions = 0;
5805     if (audio_sender_state_ >= AudioState::READY_TO_START) {
5806       previously_active_directions |= bluetooth::le_audio::types::kLeAudioDirectionSink;
5807     }
5808     if (audio_receiver_state_ >= AudioState::READY_TO_START) {
5809       previously_active_directions |= bluetooth::le_audio::types::kLeAudioDirectionSource;
5810     }
5811 
5812     /* We are done with reconfiguration.
5813      * Clean state and if Audio HAL is waiting, cancel the request
5814      * so Audio HAL can Resume again.
5815      */
5816     CancelStreamingRequest();
5817     ReconfigurationComplete(previously_active_directions);
5818     speed_stop_reconfig();
5819   }
5820 
OnStateMachineStatusReportCb(int group_id,GroupStreamStatus status)5821   void OnStateMachineStatusReportCb(int group_id, GroupStreamStatus status) {
5822     log::info("status: {},  group_id: {}, audio_sender_state {}, audio_receiver_state {}",
5823               static_cast<int>(status), group_id, bluetooth::common::ToString(audio_sender_state_),
5824               bluetooth::common::ToString(audio_receiver_state_));
5825     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
5826 
5827     notifyGroupStreamStatus(group_id, status);
5828 
5829     switch (status) {
5830       case GroupStreamStatus::STREAMING: {
5831         if (group_id != active_group_id_) {
5832           log::error("Streaming group {} is no longer active. Stop the group.", group_id);
5833           GroupStop(group_id);
5834           return;
5835         }
5836 
5837         speed_stream_created();
5838         bluetooth::le_audio::MetricsCollector::Get()->OnStreamStarted(active_group_id_,
5839                                                                       configuration_context_type_);
5840 
5841         if (leAudioHealthStatus_) {
5842           leAudioHealthStatus_->AddStatisticForGroup(
5843                   group, LeAudioHealthGroupStatType::STREAM_CREATE_SUCCESS);
5844         }
5845 
5846         if (!group) {
5847           log::error("Group {} does not exist anymore. This shall not happen", group_id);
5848           return;
5849         }
5850 
5851         handleAsymmetricPhyForUnicast(group);
5852 
5853         if ((audio_sender_state_ == AudioState::IDLE) &&
5854             (audio_receiver_state_ == AudioState::IDLE)) {
5855           /* Audio Framework is not interested in the stream anymore.
5856            * Just stop streaming
5857            */
5858           log::warn("Stopping stream for group {} as AF not interested.", group_id);
5859           speed_stop_setup();
5860           groupStateMachine_->StopStream(group);
5861           return;
5862         }
5863 
5864         /* It might happen that the configuration has already changed, while
5865          * the group was in the ongoing reconfiguration. We should stop the
5866          * stream and reconfigure once again.
5867          */
5868         if (group->GetConfigurationContextType() != configuration_context_type_) {
5869           log::debug(
5870                   "The configuration {} is no longer valid. Stopping the stream to "
5871                   "reconfigure to {}",
5872                   ToString(group->GetConfigurationContextType()),
5873                   ToString(configuration_context_type_));
5874           speed_stop_setup();
5875           initReconfiguration(group, group->GetConfigurationContextType());
5876           return;
5877         }
5878 
5879         BidirectionalPair<uint16_t> delays_pair = {
5880                 .sink = group->GetRemoteDelay(bluetooth::le_audio::types::kLeAudioDirectionSink),
5881                 .source =
5882                         group->GetRemoteDelay(bluetooth::le_audio::types::kLeAudioDirectionSource)};
5883         CodecManager::GetInstance()->UpdateActiveAudioConfig(
5884                 group->stream_conf.stream_params, delays_pair,
5885                 std::bind(&LeAudioClientImpl::UpdateAudioConfigToHal, weak_factory_.GetWeakPtr(),
5886                           std::placeholders::_1, std::placeholders::_2));
5887 
5888         if (audio_sender_state_ == AudioState::READY_TO_START) {
5889           StartSendingAudio(group_id);
5890         }
5891 
5892         if (audio_receiver_state_ == AudioState::READY_TO_START) {
5893           StartReceivingAudio(group_id);
5894         }
5895 
5896         speed_stop_setup();
5897         break;
5898       }
5899       case GroupStreamStatus::SUSPENDED:
5900         speed_tracker_.Reset();
5901         /** Stop Audio but don't release all the Audio resources */
5902         SuspendAudio();
5903         break;
5904       case GroupStreamStatus::CONFIGURED_BY_USER:
5905         reconfigurationComplete();
5906         break;
5907       case GroupStreamStatus::CONFIGURED_AUTONOMOUS:
5908         /* This state is notified only when
5909          * groups stays into CONFIGURED state after
5910          * STREAMING. Peer device uses cache. For the moment
5911          * it is handled same as IDLE
5912          */
5913       case GroupStreamStatus::IDLE: {
5914         if (sw_enc_left) {
5915           sw_enc_left.reset();
5916         }
5917         if (sw_enc_right) {
5918           sw_enc_right.reset();
5919         }
5920         if (sw_dec_left) {
5921           sw_dec_left.reset();
5922         }
5923         if (sw_dec_right) {
5924           sw_dec_right.reset();
5925         }
5926         CleanCachedMicrophoneData();
5927 
5928         if (group) {
5929           handleAsymmetricPhyForUnicast(group);
5930           UpdateLocationsAndContextsAvailability(group);
5931           if (group->IsPendingConfiguration()) {
5932             log::debug(
5933                     "Pending configuration for group_id: {} pre_configuration_context_type_ : {} "
5934                     "-> "
5935                     "configuration_context_type_ {}",
5936                     group->group_id_, ToString(pre_configuration_context_type_),
5937                     ToString(configuration_context_type_));
5938             auto remote_direction = kLeAudioContextAllRemoteSource.test(configuration_context_type_)
5939                                             ? bluetooth::le_audio::types::kLeAudioDirectionSource
5940                                             : bluetooth::le_audio::types::kLeAudioDirectionSink;
5941 
5942             /* Reconfiguration to non requiring source scenario */
5943             if (sink_monitor_mode_ &&
5944                 (remote_direction == bluetooth::le_audio::types::kLeAudioDirectionSink)) {
5945               notifyAudioLocalSink(UnicastMonitorModeStatus::STREAMING_SUSPENDED);
5946             }
5947 
5948             auto remote_contexts = DirectionalRealignMetadataAudioContexts(group, remote_direction);
5949             ApplyRemoteMetadataAudioContextPolicy(group, remote_contexts, remote_direction);
5950             log::verbose(
5951                     "Pending configuration 2 pre_configuration_context_type_ : {} -> "
5952                     "configuration_context_type_ {}",
5953                     ToString(pre_configuration_context_type_),
5954                     ToString(configuration_context_type_));
5955             if ((configuration_context_type_ != pre_configuration_context_type_) &&
5956                 GroupStream(group->group_id_, configuration_context_type_, remote_contexts)) {
5957               /* If configuration succeed wait for new status. */
5958               return;
5959             }
5960             log::info("Clear pending configuration flag for group {}", group->group_id_);
5961             group->ClearPendingConfiguration();
5962             reconfigurationComplete();
5963           } else {
5964             if (sink_monitor_mode_) {
5965               notifyAudioLocalSink(UnicastMonitorModeStatus::STREAMING_SUSPENDED);
5966             }
5967 
5968             if (source_monitor_mode_) {
5969               notifyAudioLocalSource(UnicastMonitorModeStatus::STREAMING_SUSPENDED);
5970             }
5971           }
5972         }
5973 
5974         speed_tracker_.Reset();
5975         CancelStreamingRequest();
5976 
5977         if (group) {
5978           NotifyUpperLayerGroupTurnedIdleDuringCall(group->group_id_);
5979           HandlePendingDeviceRemove(group);
5980           HandlePendingDeviceDisconnection(group);
5981         }
5982         break;
5983       }
5984       case GroupStreamStatus::RELEASING:
5985       case GroupStreamStatus::SUSPENDING:
5986         if (active_group_id_ != bluetooth::groups::kGroupUnknown &&
5987             (active_group_id_ == group->group_id_) && !group->IsPendingConfiguration() &&
5988             (audio_sender_state_ == AudioState::STARTED ||
5989              audio_receiver_state_ == AudioState::STARTED) &&
5990             group->GetTargetState() != AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) {
5991           /* If releasing state is happening but it was not initiated either by
5992            * reconfiguration or Audio Framework actions either by the Active group change,
5993            * it means that it is some internal state machine error. This is very unlikely and
5994            * for now just Inactivate the group.
5995            */
5996           log::error("Internal state machine error");
5997           group->PrintDebugState();
5998           groupSetAndNotifyInactive();
5999         }
6000 
6001         if (audio_sender_state_ != AudioState::IDLE) {
6002           audio_sender_state_ = AudioState::RELEASING;
6003         }
6004 
6005         if (audio_receiver_state_ != AudioState::IDLE) {
6006           audio_receiver_state_ = AudioState::RELEASING;
6007         }
6008 
6009         if (group && group->IsPendingConfiguration()) {
6010           log::info("Releasing for reconfiguration, don't send anything on CISes");
6011           SuspendedForReconfiguration();
6012         }
6013         break;
6014       default:
6015         break;
6016     }
6017   }
6018 
OnUpdatedCisConfiguration(int group_id,uint8_t direction)6019   void OnUpdatedCisConfiguration(int group_id, uint8_t direction) {
6020     LeAudioDeviceGroup* group = aseGroups_.FindById(group_id);
6021     if (!group) {
6022       log::error("Invalid group_id: {}", group_id);
6023       return;
6024     }
6025     group->UpdateCisConfiguration(direction);
6026   }
6027 
6028 private:
6029   tGATT_IF gatt_if_;
6030   bluetooth::le_audio::LeAudioClientCallbacks* callbacks_;
6031   LeAudioDevices leAudioDevices_;
6032   LeAudioDeviceGroups aseGroups_;
6033   LeAudioGroupStateMachine* groupStateMachine_;
6034   int active_group_id_;
6035   LeAudioContextType pre_configuration_context_type_;
6036   LeAudioContextType configuration_context_type_;
6037   static constexpr char kAllowMultipleContextsInMetadata[] =
6038           "persist.bluetooth.leaudio.allow.multiple.contexts";
6039   BidirectionalPair<AudioContexts> in_call_metadata_context_types_;
6040   BidirectionalPair<AudioContexts> local_metadata_context_types_;
6041   StreamSpeedTracker speed_tracker_;
6042   std::deque<StreamSpeedTracker> stream_speed_history_;
6043 
6044   /* Microphone (s) */
6045   AudioState audio_receiver_state_;
6046   /* Speaker(s) */
6047   AudioState audio_sender_state_;
6048   /* Keep in call state. */
6049   bool in_call_;
6050   bool in_voip_call_;
6051   /* Listen for streaming status on Sink stream */
6052   bool sink_monitor_mode_;
6053   /* Sink stream status which has been notified to Service */
6054   std::optional<UnicastMonitorModeStatus> sink_monitor_notified_status_;
6055   /* Listen for streaming status on Source stream */
6056   bool source_monitor_mode_;
6057   /* Source stream status which has been notified to Service */
6058   std::optional<UnicastMonitorModeStatus> source_monitor_notified_status_;
6059 
6060   /* Reconnection mode */
6061   tBTM_BLE_CONN_TYPE reconnection_mode_;
6062   static constexpr uint64_t kGroupConnectedWatchDelayMs = 3000;
6063   static constexpr uint64_t kRecoveryReconnectDelayMs = 2000;
6064   static constexpr uint64_t kAutoConnectAfterOwnDisconnectDelayMs = 1000;
6065   static constexpr uint64_t kCsisGroupMemberDelayMs = 5000;
6066 
6067   /* LeAudioHealthStatus */
6068   LeAudioHealthStatus* leAudioHealthStatus_ = nullptr;
6069 
6070   static constexpr char kNotifyUpperLayerAboutGroupBeingInIdleDuringCall[] =
6071           "persist.bluetooth.leaudio.notify.idle.during.call";
6072 
6073   static constexpr uint16_t kBapMinimumAttMtu = 64;
6074 
6075   /* Current stream configuration - used to set up the software codecs */
6076   LeAudioCodecConfiguration current_encoder_config_;
6077   LeAudioCodecConfiguration current_decoder_config_;
6078 
6079   /* Static Audio Framework session configuration.
6080    *  Resampling will be done inside the bt stack
6081    */
6082   LeAudioCodecConfiguration audio_framework_source_config = {
6083           .num_channels = 2,
6084           .sample_rate = bluetooth::audio::le_audio::kSampleRate48000,
6085           .bits_per_sample = bluetooth::audio::le_audio::kBitsPerSample16,
6086           .data_interval_us = LeAudioCodecConfiguration::kInterval10000Us,
6087   };
6088 
6089   LeAudioCodecConfiguration audio_framework_sink_config = {
6090           .num_channels = 2,
6091           .sample_rate = bluetooth::audio::le_audio::kSampleRate16000,
6092           .bits_per_sample = bluetooth::audio::le_audio::kBitsPerSample16,
6093           .data_interval_us = LeAudioCodecConfiguration::kInterval10000Us,
6094   };
6095 
6096   std::unique_ptr<bluetooth::le_audio::CodecInterface> sw_enc_left;
6097   std::unique_ptr<bluetooth::le_audio::CodecInterface> sw_enc_right;
6098 
6099   std::unique_ptr<bluetooth::le_audio::CodecInterface> sw_dec_left;
6100   std::unique_ptr<bluetooth::le_audio::CodecInterface> sw_dec_right;
6101 
6102   std::vector<uint8_t> encoded_data;
6103   std::unique_ptr<LeAudioSourceAudioHalClient> le_audio_source_hal_client_;
6104   std::unique_ptr<LeAudioSinkAudioHalClient> le_audio_sink_hal_client_;
6105   static constexpr uint64_t kAudioSuspentKeepIsoAliveTimeoutMs = 500;
6106   static constexpr uint64_t kAudioDisableTimeoutMs = 3000;
6107   static constexpr char kAudioSuspentKeepIsoAliveTimeoutMsProp[] =
6108           "persist.bluetooth.leaudio.audio.suspend.timeoutms";
6109   static constexpr uint64_t kAudioReconfigurationTimeoutMs = 1500;
6110   alarm_t* close_vbc_timeout_;
6111   alarm_t* suspend_timeout_;
6112 
6113   /* Reconfiguration guard to make sure reconfigration is not broken by unexpected Metadata change.
6114    * When Reconfiguration is scheduled then
6115    * 1. BT stack remembers local directions which should be resumed after reconfiguration
6116    * 2. Blocks another reconfiguration until:
6117    *      a) all the reconfigured directions has been resumed
6118    *      b) reconfiguration timeout fires
6119    */
6120   alarm_t* reconfiguration_timeout_;
6121   int reconfiguration_group_ = bluetooth::groups::kGroupUnknown;
6122   uint8_t reconfiguration_local_directions_ = 0;
6123 
6124   alarm_t* disable_timer_;
6125   static constexpr uint64_t kDeviceAttachDelayMs = 500;
6126 
6127   uint32_t cached_channel_timestamp_ = 0;
6128   bluetooth::le_audio::CodecInterface* cached_channel_ = nullptr;
6129 
6130   base::WeakPtrFactory<LeAudioClientImpl> weak_factory_{this};
6131 
6132   std::map<int, GroupStreamStatus> lastNotifiedGroupStreamStatusMap_;
6133 
ClientAudioInterfaceRelease()6134   void ClientAudioInterfaceRelease() {
6135     auto group = aseGroups_.FindById(active_group_id_);
6136     if (!group) {
6137       log::error("Invalid group: {}", static_cast<int>(active_group_id_));
6138     } else {
6139       handleAsymmetricPhyForUnicast(group);
6140       log::info("ClientAudioInterfaceRelease - cleanup");
6141     }
6142 
6143     auto result = CodecManager::GetInstance()->UpdateActiveUnicastAudioHalClient(
6144             le_audio_source_hal_client_.get(), le_audio_sink_hal_client_.get(), false);
6145     log::assert_that(result, "Could not update session to codec manager");
6146 
6147     if (le_audio_source_hal_client_) {
6148       le_audio_source_hal_client_->Stop();
6149       le_audio_source_hal_client_.reset();
6150     }
6151 
6152     if (le_audio_sink_hal_client_) {
6153       /* Keep session set up to monitor streaming request. This is required if
6154        * there is another LE Audio device streaming (e.g. Broadcast) and via
6155        * the session callbacks special action from this Module would be
6156        * required e.g. to Unicast handover.
6157        */
6158       if (!sink_monitor_mode_) {
6159         local_metadata_context_types_.sink.clear();
6160         le_audio_sink_hal_client_->Stop();
6161         le_audio_sink_hal_client_.reset();
6162       }
6163     }
6164     local_metadata_context_types_.source.clear();
6165     configuration_context_type_ = LeAudioContextType::UNINITIALIZED;
6166 
6167     bluetooth::le_audio::MetricsCollector::Get()->OnStreamEnded(active_group_id_);
6168   }
6169 
DsaDataConsume(bluetooth::hci::iso_manager::cis_data_evt * event)6170   bool DsaDataConsume(bluetooth::hci::iso_manager::cis_data_evt* event) {
6171     if (!com::android::bluetooth::flags::leaudio_dynamic_spatial_audio()) {
6172       return false;
6173     }
6174 
6175     if (active_group_id_ == bluetooth::groups::kGroupUnknown) {
6176       return false;
6177     }
6178     LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_);
6179     if (!group || !group->dsa_.active) {
6180       return false;
6181     }
6182 
6183     if (group->dsa_.mode != DsaMode::ISO_SW) {
6184       log::warn("ISO packets received over HCI in DSA mode: {}", group->dsa_.mode);
6185       return false;
6186     }
6187 
6188     if (iso_data_callback == nullptr) {
6189       log::warn("Dsa data consumer not registered");
6190       return false;
6191     }
6192 
6193     uint16_t cis_conn_hdl = event->cis_conn_hdl;
6194     uint8_t* data = event->p_msg->data + event->p_msg->offset;
6195     uint16_t size = event->p_msg->len - event->p_msg->offset;
6196     uint32_t timestamp = event->ts;
6197 
6198     // Find LE Audio device
6199     LeAudioDevice* leAudioDevice = group->GetFirstDevice();
6200     while (leAudioDevice != nullptr) {
6201       if (leAudioDevice->GetDsaCisHandle() == cis_conn_hdl &&
6202           leAudioDevice->GetDsaDataPathState() == DataPathState::CONFIGURED) {
6203         break;
6204       }
6205       leAudioDevice = group->GetNextDevice(leAudioDevice);
6206     }
6207     if (leAudioDevice == nullptr) {
6208       log::warn("No LE Audio device found for CIS handle: {}", cis_conn_hdl);
6209       return false;
6210     }
6211 
6212     bool consumed = iso_data_callback(leAudioDevice->address_, cis_conn_hdl, data, size, timestamp);
6213     if (consumed) {
6214       return true;
6215     } else {
6216       log::verbose("ISO data consumer not ready to accept data");
6217       return false;
6218     }
6219   }
6220 
SetAsymmetricBlePhy(LeAudioDeviceGroup * group,bool asymmetric)6221   void SetAsymmetricBlePhy(LeAudioDeviceGroup* group, bool asymmetric) {
6222     LeAudioDevice* leAudioDevice = group->GetFirstDevice();
6223     if (leAudioDevice == nullptr) {
6224       log::error("Shouldn't be called without a device.");
6225       return;
6226     }
6227 
6228     for (auto tmpDevice = leAudioDevice; tmpDevice != nullptr;
6229          tmpDevice = group->GetNextDevice(tmpDevice)) {
6230       log::info("tmpDevice->acl_asymmetric_: {}, asymmetric: {}, address: {}, acl_connected: {}",
6231                 tmpDevice->acl_asymmetric_ == asymmetric, asymmetric, tmpDevice->address_,
6232                 get_btm_client_interface().peer.BTM_IsAclConnectionUp(tmpDevice->address_,
6233                                                                       BT_TRANSPORT_LE));
6234       if (tmpDevice->acl_asymmetric_ == asymmetric ||
6235           !get_btm_client_interface().peer.BTM_IsAclConnectionUp(tmpDevice->address_,
6236                                                                  BT_TRANSPORT_LE)) {
6237         continue;
6238       }
6239 
6240       log::info("SetAsymmetricBlePhy: {} for {}", asymmetric, tmpDevice->address_);
6241       get_btm_client_interface().ble.BTM_BleSetPhy(tmpDevice->address_, PHY_LE_2M,
6242                                                    asymmetric ? PHY_LE_1M : PHY_LE_2M, 0);
6243       tmpDevice->acl_asymmetric_ = asymmetric;
6244     }
6245   }
6246 };
6247 
le_audio_health_status_callback(const RawAddress & addr,int group_id,LeAudioHealthBasedAction action)6248 static void le_audio_health_status_callback(const RawAddress& addr, int group_id,
6249                                             LeAudioHealthBasedAction action) {
6250   if (instance) {
6251     instance->LeAudioHealthSendRecommendation(addr, group_id, action);
6252   }
6253 }
6254 
6255 /* This is a generic callback method for gatt client which handles every client
6256  * application events.
6257  */
le_audio_gattc_callback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)6258 void le_audio_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
6259   if (!p_data || !instance) {
6260     return;
6261   }
6262 
6263   log::info("event = {}", static_cast<int>(event));
6264 
6265   switch (event) {
6266     case BTA_GATTC_DEREG_EVT:
6267       break;
6268 
6269     case BTA_GATTC_NOTIF_EVT:
6270       instance->LeAudioCharValueHandle(p_data->notify.conn_id, p_data->notify.handle,
6271                                        p_data->notify.len,
6272                                        static_cast<uint8_t*>(p_data->notify.value), true);
6273 
6274       if (!p_data->notify.is_notify) {
6275         BTA_GATTC_SendIndConfirm(p_data->notify.conn_id, p_data->notify.handle);
6276       }
6277 
6278       break;
6279 
6280     case BTA_GATTC_OPEN_EVT:
6281       instance->OnGattConnected(p_data->open.status, p_data->open.conn_id, p_data->open.client_if,
6282                                 p_data->open.remote_bda, p_data->open.transport, p_data->open.mtu);
6283       break;
6284 
6285     case BTA_GATTC_ENC_CMPL_CB_EVT: {
6286       tBTM_STATUS encryption_status;
6287       if (BTM_IsEncrypted(p_data->enc_cmpl.remote_bda, BT_TRANSPORT_LE)) {
6288         encryption_status = tBTM_STATUS::BTM_SUCCESS;
6289       } else {
6290         encryption_status = tBTM_STATUS::BTM_FAILED_ON_SECURITY;
6291       }
6292       instance->OnEncryptionComplete(p_data->enc_cmpl.remote_bda, encryption_status);
6293     } break;
6294 
6295     case BTA_GATTC_CLOSE_EVT:
6296       instance->OnGattDisconnected(p_data->close.conn_id, p_data->close.client_if,
6297                                    p_data->close.remote_bda, p_data->close.reason);
6298       break;
6299 
6300     case BTA_GATTC_SEARCH_CMPL_EVT:
6301       instance->OnServiceSearchComplete(p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
6302       break;
6303 
6304     case BTA_GATTC_SRVC_DISC_DONE_EVT:
6305       instance->OnGattServiceDiscoveryDone(p_data->service_discovery_done.remote_bda);
6306       break;
6307 
6308     case BTA_GATTC_SRVC_CHG_EVT:
6309       instance->OnServiceChangeEvent(p_data->service_changed.remote_bda);
6310       break;
6311     case BTA_GATTC_CFG_MTU_EVT:
6312       instance->OnMtuChanged(p_data->cfg_mtu.conn_id, p_data->cfg_mtu.mtu);
6313       break;
6314     case BTA_GATTC_PHY_UPDATE_EVT:
6315       instance->OnPhyUpdate(p_data->phy_update.conn_id, p_data->phy_update.tx_phy,
6316                             p_data->phy_update.rx_phy, p_data->phy_update.status);
6317       break;
6318     default:
6319       break;
6320   }
6321 }
6322 
6323 class LeAudioStateMachineHciCallbacksImpl : public CigCallbacks {
6324 public:
OnCigEvent(uint8_t event,void * data)6325   void OnCigEvent(uint8_t event, void* data) override {
6326     if (instance) {
6327       instance->IsoCigEventsCb(event, data);
6328     }
6329   }
6330 
OnCisEvent(uint8_t event,void * data)6331   void OnCisEvent(uint8_t event, void* data) override {
6332     if (instance) {
6333       instance->IsoCisEventsCb(event, data);
6334     }
6335   }
6336 
OnSetupIsoDataPath(uint8_t status,uint16_t conn_handle,uint8_t cig_id)6337   void OnSetupIsoDataPath(uint8_t status, uint16_t conn_handle, uint8_t cig_id) override {
6338     if (instance) {
6339       instance->IsoSetupIsoDataPathCb(status, conn_handle, cig_id);
6340     }
6341   }
6342 
OnRemoveIsoDataPath(uint8_t status,uint16_t conn_handle,uint8_t cig_id)6343   void OnRemoveIsoDataPath(uint8_t status, uint16_t conn_handle, uint8_t cig_id) override {
6344     if (instance) {
6345       instance->IsoRemoveIsoDataPathCb(status, conn_handle, cig_id);
6346     }
6347   }
6348 
OnIsoLinkQualityRead(uint8_t conn_handle,uint8_t cig_id,uint32_t txUnackedPackets,uint32_t txFlushedPackets,uint32_t txLastSubeventPackets,uint32_t retransmittedPackets,uint32_t crcErrorPackets,uint32_t rxUnreceivedPackets,uint32_t duplicatePackets)6349   void OnIsoLinkQualityRead(uint8_t conn_handle, uint8_t cig_id, uint32_t txUnackedPackets,
6350                             uint32_t txFlushedPackets, uint32_t txLastSubeventPackets,
6351                             uint32_t retransmittedPackets, uint32_t crcErrorPackets,
6352                             uint32_t rxUnreceivedPackets, uint32_t duplicatePackets) {
6353     if (instance) {
6354       instance->IsoLinkQualityReadCb(conn_handle, cig_id, txUnackedPackets, txFlushedPackets,
6355                                      txLastSubeventPackets, retransmittedPackets, crcErrorPackets,
6356                                      rxUnreceivedPackets, duplicatePackets);
6357     }
6358   }
6359 };
6360 
6361 LeAudioStateMachineHciCallbacksImpl stateMachineHciCallbacksImpl;
6362 
6363 class CallbacksImpl : public LeAudioGroupStateMachine::Callbacks {
6364 public:
StatusReportCb(int group_id,GroupStreamStatus status)6365   void StatusReportCb(int group_id, GroupStreamStatus status) override {
6366     if (instance) {
6367       instance->OnStateMachineStatusReportCb(group_id, status);
6368     }
6369   }
6370 
OnStateTransitionTimeout(int group_id)6371   void OnStateTransitionTimeout(int group_id) override {
6372     if (instance) {
6373       instance->OnLeAudioDeviceSetStateTimeout(group_id);
6374     }
6375   }
6376 
OnUpdatedCisConfiguration(int group_id,uint8_t direction)6377   void OnUpdatedCisConfiguration(int group_id, uint8_t direction) {
6378     if (instance) {
6379       instance->OnUpdatedCisConfiguration(group_id, direction);
6380     }
6381   }
6382 };
6383 
6384 CallbacksImpl stateMachineCallbacksImpl;
6385 
6386 class SourceCallbacksImpl : public LeAudioSourceAudioHalClient::Callbacks {
6387 public:
OnAudioDataReady(const std::vector<uint8_t> & data)6388   void OnAudioDataReady(const std::vector<uint8_t>& data) override {
6389     if (instance) {
6390       instance->OnAudioDataReady(data);
6391     }
6392   }
OnAudioSuspend(void)6393   void OnAudioSuspend(void) override {
6394     if (instance) {
6395       instance->OnLocalAudioSourceSuspend();
6396     }
6397   }
6398 
OnAudioResume(void)6399   void OnAudioResume(void) override {
6400     if (instance) {
6401       instance->OnLocalAudioSourceResume();
6402     }
6403   }
6404 
OnAudioMetadataUpdate(std::vector<struct playback_track_metadata_v7> source_metadata,DsaMode dsa_mode)6405   void OnAudioMetadataUpdate(std::vector<struct playback_track_metadata_v7> source_metadata,
6406                              DsaMode dsa_mode) override {
6407     if (instance) {
6408       instance->OnLocalAudioSourceMetadataUpdate(source_metadata, dsa_mode);
6409     }
6410   }
6411 };
6412 
6413 class SinkCallbacksImpl : public LeAudioSinkAudioHalClient::Callbacks {
6414 public:
OnAudioSuspend(void)6415   void OnAudioSuspend(void) override {
6416     if (instance) {
6417       instance->OnLocalAudioSinkSuspend();
6418     }
6419   }
OnAudioResume(void)6420   void OnAudioResume(void) override {
6421     if (instance) {
6422       instance->OnLocalAudioSinkResume();
6423     }
6424   }
6425 
OnAudioMetadataUpdate(std::vector<record_track_metadata_v7> sink_metadata)6426   void OnAudioMetadataUpdate(std::vector<record_track_metadata_v7> sink_metadata) override {
6427     if (instance) {
6428       instance->OnLocalAudioSinkMetadataUpdate(sink_metadata);
6429     }
6430   }
6431 };
6432 
6433 SourceCallbacksImpl audioSinkReceiverImpl;
6434 SinkCallbacksImpl audioSourceReceiverImpl;
6435 
6436 class DeviceGroupsCallbacksImpl : public DeviceGroupsCallbacks {
6437 public:
OnGroupAdded(const RawAddress & address,const bluetooth::Uuid & uuid,int group_id)6438   void OnGroupAdded(const RawAddress& address, const bluetooth::Uuid& uuid, int group_id) override {
6439     if (instance) {
6440       instance->OnGroupAddedCb(address, uuid, group_id);
6441     }
6442   }
OnGroupMemberAdded(const RawAddress & address,int group_id)6443   void OnGroupMemberAdded(const RawAddress& address, int group_id) override {
6444     if (instance) {
6445       instance->OnGroupMemberAddedCb(address, group_id);
6446     }
6447   }
OnGroupMemberRemoved(const RawAddress & address,int group_id)6448   void OnGroupMemberRemoved(const RawAddress& address, int group_id) override {
6449     if (instance) {
6450       instance->OnGroupMemberRemovedCb(address, group_id);
6451     }
6452   }
OnGroupRemoved(const bluetooth::Uuid &,int)6453   void OnGroupRemoved(const bluetooth::Uuid& /*uuid*/,
6454                       int /*group_id*/) { /* to implement if needed */ }
OnGroupAddFromStorage(const RawAddress &,const bluetooth::Uuid &,int)6455   void OnGroupAddFromStorage(const RawAddress& /*address*/, const bluetooth::Uuid& /*uuid*/,
6456                              int /*group_id*/) {
6457     /* to implement if needed */
6458   }
6459 };
6460 
6461 class DeviceGroupsCallbacksImpl;
6462 DeviceGroupsCallbacksImpl deviceGroupsCallbacksImpl;
6463 
6464 }  // namespace
6465 
AddFromStorage(const RawAddress & addr,bool autoconnect,int sink_audio_location,int source_audio_location,int sink_supported_context_types,int source_supported_context_types,const std::vector<uint8_t> & handles,const std::vector<uint8_t> & sink_pacs,const std::vector<uint8_t> & source_pacs,const std::vector<uint8_t> & ases)6466 void LeAudioClient::AddFromStorage(const RawAddress& addr, bool autoconnect,
6467                                    int sink_audio_location, int source_audio_location,
6468                                    int sink_supported_context_types,
6469                                    int source_supported_context_types,
6470                                    const std::vector<uint8_t>& handles,
6471                                    const std::vector<uint8_t>& sink_pacs,
6472                                    const std::vector<uint8_t>& source_pacs,
6473                                    const std::vector<uint8_t>& ases) {
6474   if (!instance) {
6475     log::error("Not initialized yet");
6476     return;
6477   }
6478 
6479   instance->AddFromStorage(addr, autoconnect, sink_audio_location, source_audio_location,
6480                            sink_supported_context_types, source_supported_context_types, handles,
6481                            sink_pacs, source_pacs, ases);
6482 }
6483 
GetHandlesForStorage(const RawAddress & addr,std::vector<uint8_t> & out)6484 bool LeAudioClient::GetHandlesForStorage(const RawAddress& addr, std::vector<uint8_t>& out) {
6485   if (!instance) {
6486     log::error("Not initialized yet");
6487     return false;
6488   }
6489 
6490   return instance->GetHandlesForStorage(addr, out);
6491 }
6492 
GetSinkPacsForStorage(const RawAddress & addr,std::vector<uint8_t> & out)6493 bool LeAudioClient::GetSinkPacsForStorage(const RawAddress& addr, std::vector<uint8_t>& out) {
6494   if (!instance) {
6495     log::error("Not initialized yet");
6496     return false;
6497   }
6498 
6499   return instance->GetSinkPacsForStorage(addr, out);
6500 }
6501 
GetSourcePacsForStorage(const RawAddress & addr,std::vector<uint8_t> & out)6502 bool LeAudioClient::GetSourcePacsForStorage(const RawAddress& addr, std::vector<uint8_t>& out) {
6503   if (!instance) {
6504     log::error("Not initialized yet");
6505     return false;
6506   }
6507 
6508   return instance->GetSourcePacsForStorage(addr, out);
6509 }
6510 
GetAsesForStorage(const RawAddress & addr,std::vector<uint8_t> & out)6511 bool LeAudioClient::GetAsesForStorage(const RawAddress& addr, std::vector<uint8_t>& out) {
6512   if (!instance) {
6513     log::error("Not initialized yet");
6514     return false;
6515   }
6516 
6517   return instance->GetAsesForStorage(addr, out);
6518 }
6519 
IsLeAudioClientRunning(void)6520 bool LeAudioClient::IsLeAudioClientRunning(void) { return instance != nullptr; }
6521 
IsLeAudioClientInStreaming(void)6522 bool LeAudioClient::IsLeAudioClientInStreaming(void) {
6523   if (!instance) {
6524     return false;
6525   }
6526   return instance->IsInStreaming();
6527 }
6528 
Get()6529 LeAudioClient* LeAudioClient::Get() {
6530   log::assert_that(instance != nullptr, "assert failed: instance != nullptr");
6531   return instance;
6532 }
6533 
6534 /* Initializer of main le audio implementation class and its instance */
Initialize(bluetooth::le_audio::LeAudioClientCallbacks * callbacks_,base::Closure initCb,base::Callback<bool ()> hal_2_1_verifier,const std::vector<bluetooth::le_audio::btle_audio_codec_config_t> & offloading_preference)6535 void LeAudioClient::Initialize(
6536         bluetooth::le_audio::LeAudioClientCallbacks* callbacks_, base::Closure initCb,
6537         base::Callback<bool()> hal_2_1_verifier,
6538         const std::vector<bluetooth::le_audio::btle_audio_codec_config_t>& offloading_preference) {
6539   std::scoped_lock<std::mutex> lock(instance_mutex);
6540   if (instance) {
6541     log::error("Already initialized");
6542     return;
6543   }
6544 
6545   if (!bluetooth::shim::GetController()->SupportsBleConnectedIsochronousStreamCentral() &&
6546       !bluetooth::shim::GetController()->SupportsBleConnectedIsochronousStreamPeripheral()) {
6547     log::error("Controller reports no ISO support. LeAudioClient Init aborted.");
6548     return;
6549   }
6550 
6551   log::assert_that(std::move(hal_2_1_verifier).Run(),
6552                    "LE Audio Client requires Bluetooth Audio HAL V2.1 at least. Either "
6553                    "disable LE Audio Profile, or update your HAL");
6554 
6555   IsoManager::GetInstance()->Start();
6556 
6557   audioSinkReceiver = &audioSinkReceiverImpl;
6558   audioSourceReceiver = &audioSourceReceiverImpl;
6559   stateMachineHciCallbacks = &stateMachineHciCallbacksImpl;
6560   stateMachineCallbacks = &stateMachineCallbacksImpl;
6561   device_group_callbacks = &deviceGroupsCallbacksImpl;
6562   instance = new LeAudioClientImpl(callbacks_, stateMachineCallbacks, initCb);
6563 
6564   IsoManager::GetInstance()->RegisterCigCallbacks(stateMachineHciCallbacks);
6565   CodecManager::GetInstance()->Start(offloading_preference);
6566   ContentControlIdKeeper::GetInstance()->Start();
6567 
6568   callbacks_->OnInitialized();
6569 
6570   auto cm = CodecManager::GetInstance();
6571   callbacks_->OnAudioLocalCodecCapabilities(cm->GetLocalAudioInputCodecCapa(),
6572                                             cm->GetLocalAudioOutputCodecCapa());
6573 
6574   if (GmapServer::IsGmapServerEnabled()) {
6575     auto capabilities = cm->GetLocalAudioOutputCodecCapa();
6576     std::bitset<8> UGG_feature = GmapServer::GetUGGFeature();
6577     for (auto& capa : capabilities) {
6578       if (capa.sample_rate == bluetooth::le_audio::LE_AUDIO_SAMPLE_RATE_INDEX_48000HZ) {
6579         UGG_feature |= static_cast<uint8_t>(
6580                 bluetooth::gmap::UGGFeatureBitMask::NinetySixKbpsSourceFeatureSupport);
6581         break;
6582       }
6583     }
6584     GmapServer::Initialize(UGG_feature);
6585   }
6586 }
6587 
DebugDump(int fd)6588 void LeAudioClient::DebugDump(int fd) {
6589   std::scoped_lock<std::mutex> lock(instance_mutex);
6590   DeviceGroups::DebugDump(fd);
6591 
6592   dprintf(fd, "LeAudio Manager: \n");
6593   if (instance) {
6594     instance->Dump(fd);
6595   } else {
6596     dprintf(fd, "  Not initialized \n");
6597   }
6598 
6599   LeAudioSinkAudioHalClient::DebugDump(fd);
6600   LeAudioSourceAudioHalClient::DebugDump(fd);
6601   bluetooth::le_audio::AudioSetConfigurationProvider::DebugDump(fd);
6602   IsoManager::GetInstance()->Dump(fd);
6603   LeAudioLogHistory::DebugDump(fd);
6604   dprintf(fd, "\n");
6605 }
6606 
Cleanup(void)6607 void LeAudioClient::Cleanup(void) {
6608   std::scoped_lock<std::mutex> lock(instance_mutex);
6609   if (!instance) {
6610     log::error("Not initialized");
6611     return;
6612   }
6613 
6614   LeAudioClientImpl* ptr = instance;
6615   instance = nullptr;
6616   ptr->Cleanup();
6617   delete ptr;
6618   ptr = nullptr;
6619 
6620   CodecManager::GetInstance()->Stop();
6621   ContentControlIdKeeper::GetInstance()->Stop();
6622   LeAudioGroupStateMachine::Cleanup();
6623 
6624   if (!LeAudioBroadcaster::IsLeAudioBroadcasterRunning()) {
6625     IsoManager::GetInstance()->Stop();
6626   }
6627 
6628   bluetooth::le_audio::MetricsCollector::Get()->Flush();
6629 }
6630 
RegisterIsoDataConsumer(LeAudioIsoDataCallback callback)6631 bool LeAudioClient::RegisterIsoDataConsumer(LeAudioIsoDataCallback callback) {
6632   if (!com::android::bluetooth::flags::leaudio_dynamic_spatial_audio()) {
6633     return false;
6634   }
6635 
6636   log::info("ISO data consumer changed");
6637   iso_data_callback = callback;
6638   return true;
6639 }
6640