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 "state_machine.h"
19 
20 #include <bluetooth/log.h>
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 #include <log/log.h>
24 
25 #include <functional>
26 
27 #include "bta/le_audio/content_control_id_keeper.h"
28 #include "bta_gatt_api_mock.h"
29 #include "bta_gatt_queue_mock.h"
30 #include "btm_api_mock.h"
31 #include "client_parser.h"
32 #include "common/init_flags.h"
33 #include "fake_osi.h"
34 #include "hci/controller_interface_mock.h"
35 #include "internal_include/stack_config.h"
36 #include "le_audio/le_audio_types.h"
37 #include "le_audio_set_configuration_provider.h"
38 #include "mock_codec_manager.h"
39 #include "mock_csis_client.h"
40 #include "stack/include/bt_types.h"
41 #include "test/common/mock_functions.h"
42 #include "test/mock/mock_main_shim_entry.h"
43 #include "test/mock/mock_stack_btm_iso.h"
44 #include "types/bt_transport.h"
45 
46 using ::bluetooth::le_audio::DeviceConnectState;
47 using ::bluetooth::le_audio::codec_spec_caps::
48     kLeAudioCodecChannelCountSingleChannel;
49 using ::bluetooth::le_audio::codec_spec_caps::
50     kLeAudioCodecChannelCountTwoChannel;
51 using ::bluetooth::le_audio::types::LeAudioContextType;
52 using ::testing::_;
53 using ::testing::AnyNumber;
54 using ::testing::AtLeast;
55 using ::testing::DoAll;
56 using ::testing::Invoke;
57 using ::testing::NiceMock;
58 using ::testing::Return;
59 using ::testing::SaveArg;
60 using ::testing::Test;
61 
62 extern struct fake_osi_alarm_set_on_mloop fake_osi_alarm_set_on_mloop_;
63 
64 void osi_property_set_bool(const char* key, bool value);
65 
66 constexpr uint8_t media_ccid = 0xC0;
67 constexpr auto media_context = LeAudioContextType::MEDIA;
68 
69 constexpr uint8_t call_ccid = 0xD0;
70 constexpr auto call_context = LeAudioContextType::CONVERSATIONAL;
71 
72 const std::string kSmpOptions("mock smp options");
get_pts_avrcp_test(void)73 bool get_pts_avrcp_test(void) { return false; }
get_pts_secure_only_mode(void)74 bool get_pts_secure_only_mode(void) { return false; }
get_pts_conn_updates_disabled(void)75 bool get_pts_conn_updates_disabled(void) { return false; }
get_pts_crosskey_sdp_disable(void)76 bool get_pts_crosskey_sdp_disable(void) { return false; }
get_pts_smp_options(void)77 const std::string* get_pts_smp_options(void) { return &kSmpOptions; }
get_pts_smp_failure_case(void)78 int get_pts_smp_failure_case(void) { return 123; }
get_pts_force_eatt_for_notifications(void)79 bool get_pts_force_eatt_for_notifications(void) { return false; }
get_pts_connect_eatt_unconditionally(void)80 bool get_pts_connect_eatt_unconditionally(void) { return false; }
get_pts_connect_eatt_before_encryption(void)81 bool get_pts_connect_eatt_before_encryption(void) { return false; }
get_pts_unencrypt_broadcast(void)82 bool get_pts_unencrypt_broadcast(void) { return false; }
get_pts_eatt_peripheral_collision_support(void)83 bool get_pts_eatt_peripheral_collision_support(void) { return false; }
get_pts_force_le_audio_multiple_contexts_metadata(void)84 bool get_pts_force_le_audio_multiple_contexts_metadata(void) { return false; }
get_pts_le_audio_disable_ases_before_stopping(void)85 bool get_pts_le_audio_disable_ases_before_stopping(void) { return false; }
get_all(void)86 config_t* get_all(void) { return nullptr; }
87 
88 stack_config_t mock_stack_config{
89     .get_pts_avrcp_test = get_pts_avrcp_test,
90     .get_pts_secure_only_mode = get_pts_secure_only_mode,
91     .get_pts_conn_updates_disabled = get_pts_conn_updates_disabled,
92     .get_pts_crosskey_sdp_disable = get_pts_crosskey_sdp_disable,
93     .get_pts_smp_options = get_pts_smp_options,
94     .get_pts_smp_failure_case = get_pts_smp_failure_case,
95     .get_pts_force_eatt_for_notifications =
96         get_pts_force_eatt_for_notifications,
97     .get_pts_connect_eatt_unconditionally =
98         get_pts_connect_eatt_unconditionally,
99     .get_pts_connect_eatt_before_encryption =
100         get_pts_connect_eatt_before_encryption,
101     .get_pts_unencrypt_broadcast = get_pts_unencrypt_broadcast,
102     .get_pts_eatt_peripheral_collision_support =
103         get_pts_eatt_peripheral_collision_support,
104     .get_pts_force_le_audio_multiple_contexts_metadata =
105         get_pts_force_le_audio_multiple_contexts_metadata,
106     .get_pts_le_audio_disable_ases_before_stopping =
107         get_pts_le_audio_disable_ases_before_stopping,
108     .get_all = get_all,
109 };
stack_config_get_interface(void)110 const stack_config_t* stack_config_get_interface(void) {
111   return &mock_stack_config;
112 }
113 
114 namespace bluetooth::le_audio {
115 namespace internal {
116 
117 // Just some arbitrary initial handles - it has no real meaning
118 #define ATTR_HANDLE_ASCS_POOL_START (0x0000 | 32)
119 #define ATTR_HANDLE_PACS_POOL_START (0xFF00 | 64)
120 
121 constexpr LeAudioContextType kContextTypeUnspecified =
122     static_cast<LeAudioContextType>(0x0001);
123 constexpr LeAudioContextType kContextTypeConversational =
124     static_cast<LeAudioContextType>(0x0002);
125 constexpr LeAudioContextType kContextTypeMedia =
126     static_cast<LeAudioContextType>(0x0004);
127 constexpr LeAudioContextType kContextTypeLive =
128     static_cast<LeAudioContextType>(0x0040);
129 constexpr LeAudioContextType kContextTypeSoundEffects =
130     static_cast<LeAudioContextType>(0x0080);
131 constexpr LeAudioContextType kContextTypeRingtone =
132     static_cast<LeAudioContextType>(0x0200);
133 
134 namespace codec_specific {
135 
136 constexpr uint8_t kLc3CodingFormat = 0x06;
137 
138 // Reference Codec Capabilities values to test against
139 constexpr uint8_t kCapTypeSupportedSamplingFrequencies = 0x01;
140 constexpr uint8_t kCapTypeSupportedFrameDurations = 0x02;
141 constexpr uint8_t kCapTypeAudioChannelCount = 0x03;
142 constexpr uint8_t kCapTypeSupportedOctetsPerCodecFrame = 0x04;
143 // constexpr uint8_t kCapTypeSupportedLc3CodecFramesPerSdu = 0x05;
144 
145 // constexpr uint8_t kCapSamplingFrequency8000Hz = 0x0001;
146 // constexpr uint8_t kCapSamplingFrequency11025Hz = 0x0002;
147 constexpr uint8_t kCapSamplingFrequency16000Hz = 0x0004;
148 // constexpr uint8_t kCapSamplingFrequency22050Hz = 0x0008;
149 // constexpr uint8_t kCapSamplingFrequency24000Hz = 0x0010;
150 constexpr uint8_t kCapSamplingFrequency32000Hz = 0x0020;
151 // constexpr uint8_t kCapSamplingFrequency44100Hz = 0x0040;
152 constexpr uint8_t kCapSamplingFrequency48000Hz = 0x0080;
153 // constexpr uint8_t kCapSamplingFrequency88200Hz = 0x0100;
154 // constexpr uint8_t kCapSamplingFrequency96000Hz = 0x0200;
155 // constexpr uint8_t kCapSamplingFrequency176400Hz = 0x0400;
156 // constexpr uint8_t kCapSamplingFrequency192000Hz = 0x0800;
157 // constexpr uint8_t kCapSamplingFrequency384000Hz = 0x1000;
158 
159 constexpr uint8_t kCapFrameDuration7p5ms = 0x01;
160 constexpr uint8_t kCapFrameDuration10ms = 0x02;
161 // constexpr uint8_t kCapFrameDuration7p5msPreferred = 0x10;
162 constexpr uint8_t kCapFrameDuration10msPreferred = 0x20;
163 }  // namespace codec_specific
164 
165 namespace ascs {
166 constexpr uint8_t kAseStateIdle = 0x00;
167 constexpr uint8_t kAseStateCodecConfigured = 0x01;
168 constexpr uint8_t kAseStateQoSConfigured = 0x02;
169 constexpr uint8_t kAseStateEnabling = 0x03;
170 constexpr uint8_t kAseStateStreaming = 0x04;
171 constexpr uint8_t kAseStateDisabling = 0x05;
172 constexpr uint8_t kAseStateReleasing = 0x06;
173 
174 // constexpr uint8_t kAseParamDirectionServerIsAudioSink = 0x01;
175 // constexpr uint8_t kAseParamDirectionServerIsAudioSource = 0x02;
176 
177 constexpr uint8_t kAseParamFramingUnframedSupported = 0x00;
178 // constexpr uint8_t kAseParamFramingUnframedNotSupported = 0x01;
179 
180 // constexpr uint8_t kAseParamPreferredPhy1M = 0x01;
181 // constexpr uint8_t kAseParamPreferredPhy2M = 0x02;
182 // constexpr uint8_t kAseParamPreferredPhyCoded = 0x04;
183 
184 constexpr uint8_t kAseCtpOpcodeMaxVal = client_parser::ascs::kCtpOpcodeRelease;
185 
186 }  // namespace ascs
187 
GetTestAddress(uint8_t index)188 static RawAddress GetTestAddress(uint8_t index) {
189   return {{0xC0, 0xDE, 0xC0, 0xDE, 0x00, index}};
190 }
191 
192 class MockLeAudioGroupStateMachineCallbacks
193     : public LeAudioGroupStateMachine::Callbacks {
194  public:
195   MockLeAudioGroupStateMachineCallbacks() = default;
196   MockLeAudioGroupStateMachineCallbacks(
197       const MockLeAudioGroupStateMachineCallbacks&) = delete;
198   MockLeAudioGroupStateMachineCallbacks& operator=(
199       const MockLeAudioGroupStateMachineCallbacks&) = delete;
200 
201   ~MockLeAudioGroupStateMachineCallbacks() override = default;
202   MOCK_METHOD((void), StatusReportCb,
203               (int group_id, bluetooth::le_audio::GroupStreamStatus status),
204               (override));
205   MOCK_METHOD((void), OnStateTransitionTimeout, (int group_id), (override));
206   MOCK_METHOD((void), OnUpdatedCisConfiguration,
207               (int group_id, uint8_t direction), (override));
208   MOCK_METHOD((void), OnDeviceAutonomousStateTransitionTimeout,
209               (LeAudioDevice * leAudioDevice), (override));
210 };
211 
212 class MockAseRemoteStateMachine {
213  public:
214   MockAseRemoteStateMachine() = default;
215   MockAseRemoteStateMachine& operator=(const MockAseRemoteStateMachine&) =
216       delete;
217   ~MockAseRemoteStateMachine() = default;
218   MOCK_METHOD((void), AseCtpConfigureCodecHandler,
219               (LeAudioDevice * device, std::vector<uint8_t> value,
220                GATT_WRITE_OP_CB cb, void* cb_data));
221   MOCK_METHOD((void), AseCtpConfigureQosHandler,
222               (LeAudioDevice * device, std::vector<uint8_t> value,
223                GATT_WRITE_OP_CB cb, void* cb_data));
224   MOCK_METHOD((void), AseCtpEnableHandler,
225               (LeAudioDevice * device, std::vector<uint8_t> value,
226                GATT_WRITE_OP_CB cb, void* cb_data));
227   MOCK_METHOD((void), AseCtpReceiverStartReadyHandler,
228               (LeAudioDevice * device, std::vector<uint8_t> value,
229                GATT_WRITE_OP_CB cb, void* cb_data));
230   MOCK_METHOD((void), AseCtpDisableHandler,
231               (LeAudioDevice * device, std::vector<uint8_t> value,
232                GATT_WRITE_OP_CB cb, void* cb_data));
233   MOCK_METHOD((void), AseCtpReceiverStopReadyHandler,
234               (LeAudioDevice * device, std::vector<uint8_t> value,
235                GATT_WRITE_OP_CB cb, void* cb_data));
236   MOCK_METHOD((void), AseCtpUpdateMetadataHandler,
237               (LeAudioDevice * device, std::vector<uint8_t> value,
238                GATT_WRITE_OP_CB cb, void* cb_data));
239   MOCK_METHOD((void), AseCtpReleaseHandler,
240               (LeAudioDevice * device, std::vector<uint8_t> value,
241                GATT_WRITE_OP_CB cb, void* cb_data));
242 };
243 
244 class StateMachineTestBase : public Test {
245  protected:
246   uint8_t ase_id_last_assigned = types::ase::kAseIdInvalid;
247   uint8_t additional_snk_ases = 0;
248   uint8_t additional_src_ases = 0;
249   uint8_t channel_count_ = kLeAudioCodecChannelCountSingleChannel;
250   uint16_t sample_freq_ = codec_specific::kCapSamplingFrequency16000Hz |
251                           codec_specific::kCapSamplingFrequency32000Hz;
252   uint8_t channel_allocations_sink_ =
253       ::bluetooth::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft |
254       ::bluetooth::le_audio::codec_spec_conf::kLeAudioLocationFrontRight;
255   uint8_t channel_allocations_source_ =
256       ::bluetooth::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft |
257       ::bluetooth::le_audio::codec_spec_conf::kLeAudioLocationFrontRight;
258 
259   /* Use to simulated error status on Cis creation */
260   bool overwrite_cis_status_;
261   bool use_cis_retry_cnt_;
262   int retry_cis_established_cnt_;
263   bool do_not_send_cis_establish_event_;
264   uint8_t overwrite_cis_status_idx_;
265   std::vector<uint8_t> cis_status_;
266 
267   /* Keep ASE in releasing state */
268   bool stay_in_releasing_state_;
269 
270   /* Use for single test to simulate late ASE notifications */
271   bool stop_inject_configured_ase_after_first_ase_configured_;
272 
SetUp()273   virtual void SetUp() override {
274     __android_log_set_minimum_priority(ANDROID_LOG_DEBUG);
275     reset_mock_function_count_map();
276     bluetooth::manager::SetMockBtmInterface(&btm_interface);
277     gatt::SetMockBtaGattInterface(&gatt_interface);
278     gatt::SetMockBtaGattQueue(&gatt_queue);
279     bluetooth::hci::testing::mock_controller_ = &controller_;
280 
281     overwrite_cis_status_idx_ = 0;
282     use_cis_retry_cnt_ = false;
283     retry_cis_established_cnt_ = 0;
284     overwrite_cis_status_ = false;
285     do_not_send_cis_establish_event_ = false;
286     stay_in_releasing_state_ = false;
287     stop_inject_configured_ase_after_first_ase_configured_ = false;
288     cis_status_.clear();
289 
290     LeAudioGroupStateMachine::Initialize(&mock_callbacks_);
291 
292     ContentControlIdKeeper::GetInstance()->Start();
293 
294     ON_CALL(mock_callbacks_, StatusReportCb(_, _))
295         .WillByDefault(Invoke(
296             [](int group_id, bluetooth::le_audio::GroupStreamStatus status) {
297               log::debug("[Testing] StatusReportCb: group id: {}, status: {}",
298                          group_id, status);
299             }));
300 
301     MockCsisClient::SetMockInstanceForTesting(&mock_csis_client_module_);
302     ON_CALL(mock_csis_client_module_, Get())
303         .WillByDefault(Return(&mock_csis_client_module_));
304     ON_CALL(mock_csis_client_module_, IsCsisClientRunning())
305         .WillByDefault(Return(true));
306     ON_CALL(mock_csis_client_module_, GetDeviceList(_))
307         .WillByDefault(Invoke([this](int group_id) { return addresses_; }));
308     ON_CALL(mock_csis_client_module_, GetDesiredSize(_))
309         .WillByDefault(
310             Invoke([this](int group_id) { return (int)(addresses_.size()); }));
311 
312     // Support 2M Phy
313     ON_CALL(btm_interface, IsPhy2mSupported(_, _)).WillByDefault(Return(true));
314     ON_CALL(btm_interface, GetHCIConnHandle(_, _))
315         .WillByDefault(
316             Invoke([](RawAddress const& remote_bda, tBT_TRANSPORT transport) {
317               return remote_bda.IsEmpty()
318                          ? HCI_INVALID_HANDLE
319                          : ((uint16_t)(remote_bda.address[0] ^
320                                        remote_bda.address[1] ^
321                                        remote_bda.address[2]))
322                                    << 8 |
323                                (remote_bda.address[3] ^ remote_bda.address[4] ^
324                                 remote_bda.address[5]);
325             }));
326 
327     ON_CALL(gatt_queue, WriteCharacteristic(_, _, _, GATT_WRITE_NO_RSP, _, _))
328         .WillByDefault(Invoke([this](uint16_t conn_id, uint16_t handle,
329                                      std::vector<uint8_t> value,
330                                      tGATT_WRITE_TYPE write_type,
331                                      GATT_WRITE_OP_CB cb, void* cb_data) {
332           for (auto& dev : le_audio_devices_) {
333             if (dev->conn_id_ == conn_id) {
334               // Control point write handler
335               if (dev->ctp_hdls_.val_hdl == handle) {
336                 HandleCtpOperation(dev.get(), value, cb, cb_data);
337               }
338               break;
339             }
340           }
341         }));
342 
343     ConfigureIsoManagerMock();
344   }
345 
HandleCtpOperation(LeAudioDevice * device,std::vector<uint8_t> value,GATT_WRITE_OP_CB cb,void * cb_data)346   void HandleCtpOperation(LeAudioDevice* device, std::vector<uint8_t> value,
347                           GATT_WRITE_OP_CB cb, void* cb_data) {
348     auto opcode = value[0];
349 
350     // Verify against valid opcode range
351     ASSERT_LT(opcode, ascs::kAseCtpOpcodeMaxVal + 1);
352     ASSERT_NE(opcode, 0);
353 
354     switch (opcode) {
355       case client_parser::ascs::kCtpOpcodeCodecConfiguration:
356         ase_ctp_handler.AseCtpConfigureCodecHandler(device, std::move(value),
357                                                     cb, cb_data);
358         break;
359       case client_parser::ascs::kCtpOpcodeQosConfiguration:
360         ase_ctp_handler.AseCtpConfigureQosHandler(device, std::move(value), cb,
361                                                   cb_data);
362         break;
363       case client_parser::ascs::kCtpOpcodeEnable:
364         ase_ctp_handler.AseCtpEnableHandler(device, std::move(value), cb,
365                                             cb_data);
366         break;
367       case client_parser::ascs::kCtpOpcodeReceiverStartReady:
368         ase_ctp_handler.AseCtpReceiverStartReadyHandler(
369             device, std::move(value), cb, cb_data);
370         break;
371       case client_parser::ascs::kCtpOpcodeDisable:
372         ase_ctp_handler.AseCtpDisableHandler(device, std::move(value), cb,
373                                              cb_data);
374         break;
375       case client_parser::ascs::kCtpOpcodeReceiverStopReady:
376         ase_ctp_handler.AseCtpReceiverStopReadyHandler(device, std::move(value),
377                                                        cb, cb_data);
378         break;
379       case client_parser::ascs::kCtpOpcodeUpdateMetadata:
380         ase_ctp_handler.AseCtpUpdateMetadataHandler(device, std::move(value),
381                                                     cb, cb_data);
382         break;
383       case client_parser::ascs::kCtpOpcodeRelease:
384         ase_ctp_handler.AseCtpReleaseHandler(device, std::move(value), cb,
385                                              cb_data);
386         break;
387       default:
388         break;
389     };
390   }
391 
392 /* Helper function to make a deterministic (and unique on the entire device)
393  * connection handle for a given cis.
394  */
395 #define UNIQUE_CIS_CONN_HANDLE(cig_id, cis_index) (cig_id << 8 | cis_index)
396 
ConfigureIsoManagerMock()397   void ConfigureIsoManagerMock() {
398     iso_manager_ = bluetooth::hci::IsoManager::GetInstance();
399     ASSERT_NE(iso_manager_, nullptr);
400     iso_manager_->Start();
401 
402     mock_iso_manager_ = MockIsoManager::GetInstance();
403     ASSERT_NE(mock_iso_manager_, nullptr);
404 
405     ON_CALL(*mock_iso_manager_, CreateCig)
406         .WillByDefault(
407             [this](uint8_t cig_id,
408                    bluetooth::hci::iso_manager::cig_create_params p) {
409               log::debug("CreateCig");
410 
411               auto& group = le_audio_device_groups_[cig_id];
412               if (group) {
413                 std::vector<uint16_t> conn_handles;
414                 // Fake connection ID for each cis in a request
415                 for (auto i = 0u; i < p.cis_cfgs.size(); ++i) {
416                   conn_handles.push_back(UNIQUE_CIS_CONN_HANDLE(cig_id, i));
417                 }
418                 auto status = HCI_SUCCESS;
419                 if (group_create_command_disallowed_) {
420                   group_create_command_disallowed_ = false;
421                   status = HCI_ERR_COMMAND_DISALLOWED;
422                 }
423 
424                 LeAudioGroupStateMachine::Get()->ProcessHciNotifOnCigCreate(
425                     group.get(), status, cig_id, conn_handles);
426               }
427             });
428 
429     ON_CALL(*mock_iso_manager_, RemoveCig)
430         .WillByDefault([this](uint8_t cig_id, bool force) {
431           log::debug("CreateRemove");
432 
433           auto& group = le_audio_device_groups_[cig_id];
434           if (group) {
435             // Fake connection ID for each cis in a request
436             LeAudioGroupStateMachine::Get()->ProcessHciNotifOnCigRemove(
437                 0, group.get());
438           }
439         });
440 
441     ON_CALL(*mock_iso_manager_, SetupIsoDataPath)
442         .WillByDefault([this](uint16_t conn_handle,
443                               bluetooth::hci::iso_manager::iso_data_path_params
444                                   p) {
445           log::debug("SetupIsoDataPath");
446 
447           auto dev_it =
448               std::find_if(le_audio_devices_.begin(), le_audio_devices_.end(),
449                            [&conn_handle](auto& dev) {
450                              auto ases = dev->GetAsesByCisConnHdl(conn_handle);
451                              return (ases.sink || ases.source);
452                            });
453           if (dev_it == le_audio_devices_.end()) {
454             log::error("Device not found");
455             return;
456           }
457 
458           for (auto& kv_pair : le_audio_device_groups_) {
459             auto& group = kv_pair.second;
460             if (group->IsDeviceInTheGroup(dev_it->get())) {
461               LeAudioGroupStateMachine::Get()->ProcessHciNotifSetupIsoDataPath(
462                   group.get(), dev_it->get(), 0, conn_handle);
463               return;
464             }
465           }
466         });
467 
468     ON_CALL(*mock_iso_manager_, RemoveIsoDataPath)
469         .WillByDefault([this](uint16_t conn_handle, uint8_t iso_direction) {
470           log::debug("RemoveIsoDataPath");
471 
472           auto dev_it =
473               std::find_if(le_audio_devices_.begin(), le_audio_devices_.end(),
474                            [&conn_handle](auto& dev) {
475                              auto ases = dev->GetAsesByCisConnHdl(conn_handle);
476                              return (ases.sink || ases.source);
477                            });
478           if (dev_it == le_audio_devices_.end()) {
479             log::error("Device not found");
480             return;
481           }
482 
483           for (auto& kv_pair : le_audio_device_groups_) {
484             auto& group = kv_pair.second;
485             if (group->IsDeviceInTheGroup(dev_it->get())) {
486               LeAudioGroupStateMachine::Get()->ProcessHciNotifRemoveIsoDataPath(
487                   group.get(), dev_it->get(), 0, conn_handle);
488               return;
489             }
490           }
491         });
492 
493     ON_CALL(*mock_iso_manager_, EstablishCis)
494         .WillByDefault([this](bluetooth::hci::iso_manager::cis_establish_params
495                                   conn_params) {
496           log::debug("EstablishCis");
497 
498           if (do_not_send_cis_establish_event_) {
499             log::debug("Don't send cis establish event");
500             return;
501           }
502 
503           for (auto& pair : conn_params.conn_pairs) {
504             auto dev_it = std::find_if(
505                 le_audio_devices_.begin(), le_audio_devices_.end(),
506                 [&pair](auto& dev) {
507                   auto ases = dev->GetAsesByCisConnHdl(pair.cis_conn_handle);
508                   return (ases.sink || ases.source);
509                 });
510             if (dev_it == le_audio_devices_.end()) {
511               log::error("Device not found");
512               return;
513             }
514 
515             for (auto& kv_pair : le_audio_device_groups_) {
516               auto& group = kv_pair.second;
517               if (group->IsDeviceInTheGroup(dev_it->get())) {
518                 bluetooth::hci::iso_manager::cis_establish_cmpl_evt evt;
519 
520                 // Fill proper values if needed
521                 if (use_cis_retry_cnt_) {
522                   if (retry_cis_established_cnt_ > 0) {
523                     evt.status = HCI_ERR_CONN_FAILED_ESTABLISHMENT;
524                     retry_cis_established_cnt_--;
525                   } else {
526                     evt.status = 0;
527                   }
528                 } else if (overwrite_cis_status_) {
529                   evt.status = cis_status_[overwrite_cis_status_idx_++];
530                   /* Reset the index */
531                   if (cis_status_.size() == overwrite_cis_status_idx_) {
532                     overwrite_cis_status_idx_ = 0;
533                   }
534                 } else {
535                   evt.status = 0;
536                 }
537 
538                 evt.cig_id = group->group_id_;
539                 evt.cis_conn_hdl = pair.cis_conn_handle;
540                 evt.cig_sync_delay = 0;
541                 evt.cis_sync_delay = 0;
542                 evt.trans_lat_mtos = 0;
543                 evt.trans_lat_stom = 0;
544                 evt.phy_mtos = 0;
545                 evt.phy_stom = 0;
546                 evt.nse = 0;
547                 evt.bn_mtos = 0;
548                 evt.bn_stom = 0;
549                 evt.ft_mtos = 0;
550                 evt.ft_stom = 0;
551                 evt.max_pdu_mtos = 0;
552                 evt.max_pdu_stom = 0;
553                 evt.iso_itv = 0;
554 
555                 LeAudioGroupStateMachine::Get()->ProcessHciNotifCisEstablished(
556                     group.get(), dev_it->get(), &evt);
557                 break;
558               }
559             }
560           }
561         });
562 
563     ON_CALL(*mock_iso_manager_, DisconnectCis)
564         .WillByDefault([this](uint16_t cis_handle, uint8_t reason) {
565           log::debug("DisconnectCis");
566 
567           auto dev_it =
568               std::find_if(le_audio_devices_.begin(), le_audio_devices_.end(),
569                            [&cis_handle](auto& dev) {
570                              auto ases = dev->GetAsesByCisConnHdl(cis_handle);
571                              return (ases.sink || ases.source);
572                            });
573           if (dev_it == le_audio_devices_.end()) {
574             log::error("Device not found");
575             return;
576           }
577 
578           // When we disconnect the remote with HCI_ERR_PEER_USER, we
579           // should be getting HCI_ERR_CONN_CAUSE_LOCAL_HOST from HCI.
580           if (reason == HCI_ERR_PEER_USER) {
581             reason = HCI_ERR_CONN_CAUSE_LOCAL_HOST;
582           }
583 
584           for (auto& kv_pair : le_audio_device_groups_) {
585             auto& group = kv_pair.second;
586             if (group->IsDeviceInTheGroup(dev_it->get())) {
587               bluetooth::hci::iso_manager::cis_disconnected_evt evt{
588                   .reason = reason,
589                   .cig_id = static_cast<uint8_t>(group->group_id_),
590                   .cis_conn_hdl = cis_handle,
591               };
592               LeAudioGroupStateMachine::Get()->ProcessHciNotifCisDisconnected(
593                   group.get(), dev_it->get(), &evt);
594               return;
595             }
596           }
597         });
598   }
599 
ConfigCodecManagerMock(types::CodecLocation location)600   void ConfigCodecManagerMock(types::CodecLocation location) {
601     codec_manager_ = bluetooth::le_audio::CodecManager::GetInstance();
602     ASSERT_NE(codec_manager_, nullptr);
603     std::vector<bluetooth::le_audio::btle_audio_codec_config_t>
604         mock_offloading_preference(0);
605     codec_manager_->Start(mock_offloading_preference);
606     mock_codec_manager_ = MockCodecManager::GetInstance();
607     ASSERT_NE(mock_codec_manager_, nullptr);
608     ON_CALL(*mock_codec_manager_, GetCodecLocation())
609         .WillByDefault(Return(location));
610     // Regardless of the codec location, return all the possible configurations
611     ON_CALL(*mock_codec_manager_, IsDualBiDirSwbSupported)
612         .WillByDefault(Return(true));
613     ON_CALL(*mock_codec_manager_, CheckCodecConfigIsBiDirSwb)
614         .WillByDefault(
615             Invoke([](const set_configurations::AudioSetConfiguration& config)
616                        -> bool {
617               return AudioSetConfigurationProvider::Get()
618                   ->CheckConfigurationIsBiDirSwb(config);
619             }));
620     ON_CALL(*mock_codec_manager_, GetCodecConfig)
621         .WillByDefault(Invoke([](const bluetooth::le_audio::CodecManager::
622                                      UnicastConfigurationRequirements&
623                                          requirements,
624                                  bluetooth::le_audio::CodecManager::
625                                      UnicastConfigurationVerifier verifier) {
626           auto configs =
627               *bluetooth::le_audio::AudioSetConfigurationProvider::Get()
628                    ->GetConfigurations(requirements.audio_context_type);
629           // Note: This dual bidir SWB exclusion logic has to match the
630           // CodecManager::GetCodecConfig() implementation.
631           if (!CodecManager::GetInstance()->IsDualBiDirSwbSupported()) {
632             configs.erase(
633                 std::remove_if(configs.begin(), configs.end(),
634                                [](auto const& el) {
635                                  if (el->confs.source.empty()) return false;
636                                  return AudioSetConfigurationProvider::Get()
637                                      ->CheckConfigurationIsDualBiDirSwb(*el);
638                                }),
639                 configs.end());
640           }
641 
642           auto cfg = verifier(requirements, &configs);
643           if (cfg == nullptr) {
644             return std::unique_ptr<
645                 bluetooth::le_audio::set_configurations::AudioSetConfiguration>(
646                 nullptr);
647           }
648           return std::make_unique<
649               bluetooth::le_audio::set_configurations::AudioSetConfiguration>(
650               *cfg);
651         }));
652   }
653 
TearDown()654   void TearDown() override {
655     /* Clear the alarm on tear down in case test case ends when the
656      * alarm is scheduled
657      */
658     alarm_cancel(nullptr);
659 
660     iso_manager_->Stop();
661     mock_iso_manager_ = nullptr;
662     codec_manager_->Stop();
663     mock_codec_manager_ = nullptr;
664 
665     gatt::SetMockBtaGattQueue(nullptr);
666     gatt::SetMockBtaGattInterface(nullptr);
667     bluetooth::manager::SetMockBtmInterface(nullptr);
668 
669     le_audio_devices_.clear();
670     addresses_.clear();
671     cached_codec_configuration_map_.clear();
672     cached_qos_configuration_map_.clear();
673     cached_ase_to_cis_id_map_.clear();
674     cached_remote_qos_configuration_for_ase_.clear();
675     LeAudioGroupStateMachine::Cleanup();
676     ::bluetooth::le_audio::AudioSetConfigurationProvider::Cleanup();
677     bluetooth::hci::testing::mock_controller_ = nullptr;
678   }
679 
PrepareConnectedDevice(uint8_t id,DeviceConnectState initial_connect_state,uint8_t num_ase_snk,uint8_t num_ase_src)680   std::shared_ptr<LeAudioDevice> PrepareConnectedDevice(
681       uint8_t id, DeviceConnectState initial_connect_state, uint8_t num_ase_snk,
682       uint8_t num_ase_src) {
683     auto leAudioDevice = std::make_shared<LeAudioDevice>(GetTestAddress(id),
684                                                          initial_connect_state);
685     leAudioDevice->conn_id_ = id;
686     leAudioDevice->SetConnectionState(DeviceConnectState::CONNECTED);
687 
688     uint16_t attr_handle = ATTR_HANDLE_ASCS_POOL_START;
689     leAudioDevice->snk_audio_locations_hdls_.val_hdl = attr_handle++;
690     leAudioDevice->snk_audio_locations_hdls_.ccc_hdl = attr_handle++;
691     leAudioDevice->src_audio_locations_hdls_.val_hdl = attr_handle++;
692     leAudioDevice->src_audio_locations_hdls_.ccc_hdl = attr_handle++;
693     leAudioDevice->audio_avail_hdls_.val_hdl = attr_handle++;
694     leAudioDevice->audio_avail_hdls_.ccc_hdl = attr_handle++;
695     leAudioDevice->audio_supp_cont_hdls_.val_hdl = attr_handle++;
696     leAudioDevice->audio_supp_cont_hdls_.ccc_hdl = attr_handle++;
697     leAudioDevice->ctp_hdls_.val_hdl = attr_handle++;
698     leAudioDevice->ctp_hdls_.ccc_hdl = attr_handle++;
699 
700     // Add some Sink ASEs
701     while (num_ase_snk) {
702       types::ase ase(0, 0, 0x01);
703       ase.hdls.val_hdl = attr_handle++;
704       ase.hdls.ccc_hdl = attr_handle++;
705 
706       leAudioDevice->ases_.push_back(std::move(ase));
707       num_ase_snk--;
708     }
709 
710     // Add some Source ASEs
711     while (num_ase_src) {
712       types::ase ase(0, 0, 0x02);
713       ase.hdls.val_hdl = attr_handle++;
714       ase.hdls.ccc_hdl = attr_handle++;
715 
716       leAudioDevice->ases_.push_back(std::move(ase));
717       num_ase_src--;
718     }
719 
720     le_audio_devices_.push_back(leAudioDevice);
721     addresses_.push_back(leAudioDevice->address_);
722 
723     return std::move(leAudioDevice);
724   }
725 
GroupTheDevice(int group_id,const std::shared_ptr<LeAudioDevice> & leAudioDevice)726   LeAudioDeviceGroup* GroupTheDevice(
727       int group_id, const std::shared_ptr<LeAudioDevice>& leAudioDevice) {
728     if (le_audio_device_groups_.count(group_id) == 0) {
729       le_audio_device_groups_[group_id] =
730           std::make_unique<LeAudioDeviceGroup>(group_id);
731     }
732 
733     auto& group = le_audio_device_groups_[group_id];
734 
735     group->AddNode(leAudioDevice);
736     if (group->IsEmpty()) return nullptr;
737 
738     return &(*group);
739   }
740 
InjectAclDisconnected(LeAudioDeviceGroup * group,LeAudioDevice * leAudioDevice)741   void InjectAclDisconnected(LeAudioDeviceGroup* group,
742                              LeAudioDevice* leAudioDevice) {
743     // Do what the client.cc does when handling the disconnection event
744     leAudioDevice->conn_id_ = GATT_INVALID_CONN_ID;
745     leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED);
746     LeAudioGroupStateMachine::Get()->ProcessHciNotifAclDisconnected(
747         group, leAudioDevice);
748   }
749 
InjectReleasingAndIdleState(LeAudioDeviceGroup * group,LeAudioDevice * device)750   void InjectReleasingAndIdleState(LeAudioDeviceGroup* group,
751                                    LeAudioDevice* device) {
752     for (auto& ase : device->ases_) {
753       if (ase.id == bluetooth::le_audio::types::ase::kAseIdInvalid) {
754         continue;
755       }
756       // Simulate autonomus RELEASE and moving to IDLE state
757       InjectAseStateNotification(&ase, device, group, ascs::kAseStateReleasing,
758                                  nullptr);
759       InjectAseStateNotification(&ase, device, group, ascs::kAseStateIdle,
760                                  nullptr);
761     }
762   }
763 
InjectCachedConfiguratuibForActiveAses(LeAudioDeviceGroup * group,LeAudioDevice * device)764   void InjectCachedConfiguratuibForActiveAses(LeAudioDeviceGroup* group,
765                                               LeAudioDevice* device) {
766     for (auto& ase : device->ases_) {
767       if (!ase.active) {
768         continue;
769       }
770       log::info("ID : {},  status {}", ase.id,
771                 bluetooth::common::ToString(ase.state));
772 
773       InjectAseStateNotification(&ase, device, group,
774                                  ascs::kAseStateCodecConfigured,
775                                  &cached_codec_configuration_map_[ase.id]);
776     }
777   }
778 
InjectAseStateNotification(types::ase * ase,LeAudioDevice * device,LeAudioDeviceGroup * group,uint8_t new_state,void * new_state_params)779   void InjectAseStateNotification(types::ase* ase, LeAudioDevice* device,
780                                   LeAudioDeviceGroup* group, uint8_t new_state,
781                                   void* new_state_params) {
782     // Prepare additional params
783     switch (new_state) {
784       case ascs::kAseStateCodecConfigured: {
785         client_parser::ascs::ase_codec_configured_state_params* conf =
786             static_cast<
787                 client_parser::ascs::ase_codec_configured_state_params*>(
788                 new_state_params);
789         std::vector<uint8_t> notif_value(25 + conf->codec_spec_conf.size());
790         auto* p = notif_value.data();
791 
792         UINT8_TO_STREAM(p, ase->id == types::ase::kAseIdInvalid
793                                ? ++ase_id_last_assigned
794                                : ase->id);
795         UINT8_TO_STREAM(p, new_state);
796 
797         UINT8_TO_STREAM(p, conf->framing);
798         UINT8_TO_STREAM(p, conf->preferred_phy);
799         UINT8_TO_STREAM(p, conf->preferred_retrans_nb);
800         UINT16_TO_STREAM(p, conf->max_transport_latency);
801         UINT24_TO_STREAM(p, conf->pres_delay_min);
802         UINT24_TO_STREAM(p, conf->pres_delay_max);
803         UINT24_TO_STREAM(p, conf->preferred_pres_delay_min);
804         UINT24_TO_STREAM(p, conf->preferred_pres_delay_max);
805 
806         // CodecID:
807         UINT8_TO_STREAM(p, conf->codec_id.coding_format);
808         UINT16_TO_STREAM(p, conf->codec_id.vendor_company_id);
809         UINT16_TO_STREAM(p, conf->codec_id.vendor_codec_id);
810 
811         // Codec Spec. Conf. Length and Data
812         UINT8_TO_STREAM(p, conf->codec_spec_conf.size());
813         memcpy(p, conf->codec_spec_conf.data(), conf->codec_spec_conf.size());
814 
815         LeAudioGroupStateMachine::Get()->ProcessGattNotifEvent(
816             notif_value.data(), notif_value.size(), ase, device, group);
817       } break;
818 
819       case ascs::kAseStateQoSConfigured: {
820         client_parser::ascs::ase_qos_configured_state_params* conf =
821             static_cast<client_parser::ascs::ase_qos_configured_state_params*>(
822                 new_state_params);
823         std::vector<uint8_t> notif_value(17);
824         auto* p = notif_value.data();
825 
826         // Prepare header
827         UINT8_TO_STREAM(p, ase->id == types::ase::kAseIdInvalid
828                                ? ++ase_id_last_assigned
829                                : ase->id);
830         UINT8_TO_STREAM(p, new_state);
831 
832         UINT8_TO_STREAM(p, conf->cig_id);
833         UINT8_TO_STREAM(p, conf->cis_id);
834         UINT24_TO_STREAM(p, conf->sdu_interval);
835         UINT8_TO_STREAM(p, conf->framing);
836         UINT8_TO_STREAM(p, conf->phy);
837         UINT16_TO_STREAM(p, conf->max_sdu);
838         UINT8_TO_STREAM(p, conf->retrans_nb);
839         UINT16_TO_STREAM(p, conf->max_transport_latency);
840         UINT24_TO_STREAM(p, conf->pres_delay);
841 
842         cached_remote_qos_configuration_for_ase_[ase] = notif_value;
843 
844         LeAudioGroupStateMachine::Get()->ProcessGattNotifEvent(
845             notif_value.data(), notif_value.size(), ase, device, group);
846       } break;
847 
848       case ascs::kAseStateEnabling:
849         // fall-through
850       case ascs::kAseStateStreaming:
851         // fall-through
852       case ascs::kAseStateDisabling: {
853         client_parser::ascs::ase_transient_state_params* params =
854             static_cast<client_parser::ascs::ase_transient_state_params*>(
855                 new_state_params);
856         std::vector<uint8_t> notif_value(5 + params->metadata.size());
857         auto* p = notif_value.data();
858 
859         // Prepare header
860         UINT8_TO_STREAM(p, ase->id == types::ase::kAseIdInvalid
861                                ? ++ase_id_last_assigned
862                                : ase->id);
863 
864         UINT8_TO_STREAM(p, new_state);
865 
866         UINT8_TO_STREAM(p, group->group_id_);
867         UINT8_TO_STREAM(p, ase->cis_id);
868         UINT8_TO_STREAM(p, params->metadata.size());
869         memcpy(p, params->metadata.data(), params->metadata.size());
870 
871         LeAudioGroupStateMachine::Get()->ProcessGattNotifEvent(
872             notif_value.data(), notif_value.size(), ase, device, group);
873       } break;
874 
875       case ascs::kAseStateReleasing:
876         // fall-through
877       case ascs::kAseStateIdle: {
878         std::vector<uint8_t> notif_value(2);
879         auto* p = notif_value.data();
880 
881         // Prepare header
882         UINT8_TO_STREAM(p, ase->id == types::ase::kAseIdInvalid
883                                ? ++ase_id_last_assigned
884                                : ase->id);
885         UINT8_TO_STREAM(p, new_state);
886 
887         LeAudioGroupStateMachine::Get()->ProcessGattNotifEvent(
888             notif_value.data(), notif_value.size(), ase, device, group);
889       } break;
890 
891       default:
892         break;
893     };
894   }
895 
InsertPacRecord(std::vector<types::acs_ac_record> & recs,uint16_t sampling_frequencies_bitfield,uint8_t supported_frame_durations_bitfield,uint8_t audio_channel_count_bitfield,uint16_t supported_octets_per_codec_frame_min,uint16_t supported_octets_per_codec_frame_max,uint8_t coding_format=codec_specific::kLc3CodingFormat,uint16_t vendor_company_id=0x0000,uint16_t vendor_codec_id=0x0000,std::vector<uint8_t> metadata={})896   static void InsertPacRecord(
897       std::vector<types::acs_ac_record>& recs,
898       uint16_t sampling_frequencies_bitfield,
899       uint8_t supported_frame_durations_bitfield,
900       uint8_t audio_channel_count_bitfield,
901       uint16_t supported_octets_per_codec_frame_min,
902       uint16_t supported_octets_per_codec_frame_max,
903       uint8_t coding_format = codec_specific::kLc3CodingFormat,
904       uint16_t vendor_company_id = 0x0000, uint16_t vendor_codec_id = 0x0000,
905       std::vector<uint8_t> metadata = {}) {
906     auto ltv_map = types::LeAudioLtvMap({
907         {codec_specific::kCapTypeSupportedSamplingFrequencies,
908          {(uint8_t)(sampling_frequencies_bitfield),
909           (uint8_t)(sampling_frequencies_bitfield >> 8)}},
910         {codec_specific::kCapTypeSupportedFrameDurations,
911          {supported_frame_durations_bitfield}},
912         {codec_specific::kCapTypeAudioChannelCount,
913          {audio_channel_count_bitfield}},
914         {codec_specific::kCapTypeSupportedOctetsPerCodecFrame,
915          {
916              // Min
917              (uint8_t)(supported_octets_per_codec_frame_min),
918              (uint8_t)(supported_octets_per_codec_frame_min >> 8),
919              // Max
920              (uint8_t)(supported_octets_per_codec_frame_max),
921              (uint8_t)(supported_octets_per_codec_frame_max >> 8),
922          }},
923     });
924     recs.push_back({
925         .codec_id =
926             {
927                 .coding_format = coding_format,
928                 .vendor_company_id = vendor_company_id,
929                 .vendor_codec_id = vendor_codec_id,
930             },
931         .codec_spec_caps = ltv_map,
932         .codec_spec_caps_raw = ltv_map.RawPacket(),
933         .metadata = std::move(metadata),
934     });
935   }
936 
InjectInitialIdleNotification(LeAudioDeviceGroup * group)937   void InjectInitialIdleNotification(LeAudioDeviceGroup* group) {
938     for (auto* device = group->GetFirstDevice(); device != nullptr;
939          device = group->GetNextDevice(device)) {
940       for (auto& ase : device->ases_) {
941         InjectAseStateNotification(&ase, device, group, ascs::kAseStateIdle,
942                                    nullptr);
943       }
944     }
945   }
946 
InjectInitialConfiguredNotification(LeAudioDeviceGroup * group)947   void InjectInitialConfiguredNotification(LeAudioDeviceGroup* group) {
948     for (auto* device = group->GetFirstDevice(); device != nullptr;
949          device = group->GetNextDevice(device)) {
950       for (auto& ase : device->ases_) {
951         client_parser::ascs::ase_codec_configured_state_params
952             codec_configured_state_params;
953         InjectAseStateNotification(&ase, device, group,
954                                    ascs::kAseStateCodecConfigured,
955                                    &codec_configured_state_params);
956       }
957     }
958   }
959 
InjectInitialIdleAndConfiguredNotification(LeAudioDeviceGroup * group)960   void InjectInitialIdleAndConfiguredNotification(LeAudioDeviceGroup* group) {
961     for (auto* device = group->GetFirstDevice(); device != nullptr;
962          device = group->GetNextDevice(device)) {
963       int i = 0;
964       for (auto& ase : device->ases_) {
965         if (i % 2 == 1) {
966           InjectAseStateNotification(&ase, device, group, ascs::kAseStateIdle,
967                                      nullptr);
968         } else {
969           client_parser::ascs::ase_codec_configured_state_params
970               codec_configured_state_params;
971           InjectAseStateNotification(&ase, device, group,
972                                      ascs::kAseStateCodecConfigured,
973                                      &codec_configured_state_params);
974         }
975         i++;
976       }
977     }
978   }
979 
InjectInitialInvalidNotification(LeAudioDeviceGroup * group)980   void InjectInitialInvalidNotification(LeAudioDeviceGroup* group) {
981     for (auto* device = group->GetFirstDevice(); device != nullptr;
982          device = group->GetNextDevice(device)) {
983       int i = 0;
984       for (auto& ase : device->ases_) {
985         if (i % 2 == 1) {
986           client_parser::ascs::ase_qos_configured_state_params
987               qos_configured_state_params;
988           InjectAseStateNotification(&ase, device, group,
989                                      ascs::kAseStateQoSConfigured,
990                                      &qos_configured_state_params);
991         } else {
992           client_parser::ascs::ase_transient_state_params enable_params;
993           InjectAseStateNotification(&ase, device, group,
994                                      ascs::kAseStateEnabling, &enable_params);
995         }
996         i++;
997       }
998     }
999   }
1000 
MultipleTestDevicePrepare(int leaudio_group_id,LeAudioContextType context_type,uint16_t device_cnt,types::AudioContexts update_contexts,bool insert_default_pac_records=true,bool second_device_0_ases=false)1001   void MultipleTestDevicePrepare(int leaudio_group_id,
1002                                  LeAudioContextType context_type,
1003                                  uint16_t device_cnt,
1004                                  types::AudioContexts update_contexts,
1005                                  bool insert_default_pac_records = true,
1006                                  bool second_device_0_ases = false) {
1007     // Prepare fake connected device group
1008     DeviceConnectState initial_connect_state =
1009         DeviceConnectState::CONNECTING_BY_USER;
1010     int total_devices = device_cnt;
1011     bluetooth::le_audio::LeAudioDeviceGroup* group = nullptr;
1012 
1013     uint8_t num_ase_snk;
1014     uint8_t num_ase_src;
1015     switch (context_type) {
1016       case kContextTypeRingtone:
1017         num_ase_snk = 1 + additional_snk_ases;
1018         num_ase_src = 0 + additional_src_ases;
1019         break;
1020 
1021       case kContextTypeMedia:
1022         num_ase_snk = 2 + additional_snk_ases;
1023         num_ase_src = 0 + additional_src_ases;
1024         break;
1025 
1026       case kContextTypeConversational:
1027         num_ase_snk = 1 + additional_snk_ases;
1028         num_ase_src = 1 + additional_src_ases;
1029         break;
1030 
1031       case kContextTypeLive:
1032         num_ase_snk = 1 + additional_snk_ases;
1033         num_ase_src = 1 + additional_src_ases;
1034         break;
1035 
1036       default:
1037         ASSERT_TRUE(false);
1038     }
1039 
1040     while (device_cnt) {
1041       std::shared_ptr<LeAudioDevice> leAudioDevice;
1042 
1043       if (device_cnt == 2 && second_device_0_ases == true) {
1044         leAudioDevice =
1045             PrepareConnectedDevice(device_cnt--, initial_connect_state, 0, 0);
1046       } else {
1047         leAudioDevice = PrepareConnectedDevice(
1048             device_cnt--, initial_connect_state, num_ase_snk, num_ase_src);
1049       }
1050 
1051       if (insert_default_pac_records) {
1052         uint16_t attr_handle = ATTR_HANDLE_PACS_POOL_START;
1053 
1054         /* As per spec, unspecified shall be supported */
1055         auto snk_context_type = kContextTypeUnspecified | update_contexts;
1056         auto src_context_type = kContextTypeUnspecified | update_contexts;
1057 
1058         // Prepare Sink Published Audio Capability records
1059         if ((kContextTypeRingtone | kContextTypeMedia |
1060              kContextTypeConversational | kContextTypeLive)
1061                 .test(context_type)) {
1062           // Set target ASE configurations
1063           std::vector<types::acs_ac_record> pac_recs;
1064 
1065           InsertPacRecord(pac_recs, sample_freq_,
1066                           codec_specific::kCapFrameDuration10ms |
1067                               codec_specific::kCapFrameDuration7p5ms |
1068                               codec_specific::kCapFrameDuration10msPreferred,
1069                           channel_count_, 30, 120);
1070 
1071           types::hdl_pair handle_pair;
1072           handle_pair.val_hdl = attr_handle++;
1073           handle_pair.ccc_hdl = attr_handle++;
1074 
1075           leAudioDevice->snk_pacs_.emplace_back(
1076               std::make_tuple(std::move(handle_pair), pac_recs));
1077 
1078           snk_context_type.set(context_type);
1079           leAudioDevice->snk_audio_locations_ = channel_allocations_sink_;
1080         }
1081 
1082         // Prepare Source Published Audio Capability records
1083         if ((context_type == kContextTypeConversational) ||
1084             (context_type == kContextTypeLive)) {
1085           // Set target ASE configurations
1086           std::vector<types::acs_ac_record> pac_recs;
1087 
1088           InsertPacRecord(pac_recs,
1089                           codec_specific::kCapSamplingFrequency16000Hz |
1090                               codec_specific::kCapSamplingFrequency32000Hz,
1091                           codec_specific::kCapFrameDuration10ms |
1092                               codec_specific::kCapFrameDuration7p5ms |
1093                               codec_specific::kCapFrameDuration10msPreferred,
1094                           0b00000001, 30, 120);
1095 
1096           types::hdl_pair handle_pair;
1097           handle_pair.val_hdl = attr_handle++;
1098           handle_pair.ccc_hdl = attr_handle++;
1099 
1100           leAudioDevice->src_pacs_.emplace_back(
1101               std::make_tuple(std::move(handle_pair), pac_recs));
1102           src_context_type.set(context_type);
1103 
1104           leAudioDevice->src_audio_locations_ = channel_allocations_source_;
1105         }
1106 
1107         leAudioDevice->SetSupportedContexts(
1108             {.sink = snk_context_type, .source = src_context_type});
1109         leAudioDevice->SetAvailableContexts(
1110             {.sink = snk_context_type, .source = src_context_type});
1111       }
1112 
1113       group = GroupTheDevice(leaudio_group_id, std::move(leAudioDevice));
1114       /* Set the location and direction to the group (done in client.cc)*/
1115       group->ReloadAudioLocations();
1116       group->ReloadAudioDirections();
1117     }
1118 
1119     /* Stimulate update of available context map and configuration cache */
1120     group->UpdateAudioContextAvailability();
1121     group->UpdateAudioSetConfigurationCache(context_type);
1122 
1123     ASSERT_NE(group, nullptr);
1124     ASSERT_EQ(group->Size(), total_devices);
1125   }
1126 
PrepareSingleTestDeviceGroup(int leaudio_group_id,LeAudioContextType context_type,uint16_t device_cnt=1,types::AudioContexts update_contexts=types::AudioContexts (),bool second_device_0_ases=false)1127   LeAudioDeviceGroup* PrepareSingleTestDeviceGroup(
1128       int leaudio_group_id, LeAudioContextType context_type,
1129       uint16_t device_cnt = 1,
1130       types::AudioContexts update_contexts = types::AudioContexts(),
1131       bool second_device_0_ases = false) {
1132     MultipleTestDevicePrepare(leaudio_group_id, context_type, device_cnt,
1133                               update_contexts, true, second_device_0_ases);
1134     return le_audio_device_groups_.count(leaudio_group_id)
1135                ? le_audio_device_groups_[leaudio_group_id].get()
1136                : nullptr;
1137   }
1138 
PrepareConfigureCodecHandler(LeAudioDeviceGroup * group,int verify_ase_count=0,bool caching=false,bool inject_configured=true)1139   void PrepareConfigureCodecHandler(LeAudioDeviceGroup* group,
1140                                     int verify_ase_count = 0,
1141                                     bool caching = false,
1142                                     bool inject_configured = true) {
1143     ON_CALL(ase_ctp_handler, AseCtpConfigureCodecHandler)
1144         .WillByDefault(Invoke([group, verify_ase_count, caching,
1145                                inject_configured,
1146                                this](LeAudioDevice* device,
1147                                      std::vector<uint8_t> value,
1148                                      GATT_WRITE_OP_CB cb, void* cb_data) {
1149           auto num_ase = value[1];
1150 
1151           // Verify ase count if needed
1152           if (verify_ase_count) ASSERT_EQ(verify_ase_count, num_ase);
1153 
1154           // Inject Configured ASE state notification for each requested ASE
1155           auto* ase_p = &value[2];
1156           for (auto i = 0u; i < num_ase; ++i) {
1157             client_parser::ascs::ase_codec_configured_state_params
1158                 codec_configured_state_params;
1159 
1160             /* Check if this is a valid ASE ID  */
1161             auto ase_id = *ase_p++;
1162             auto it = std::find_if(
1163                 device->ases_.begin(), device->ases_.end(),
1164                 [ase_id](auto& ase) { return (ase.id == ase_id); });
1165             ASSERT_NE(it, device->ases_.end());
1166             const auto ase = &(*it);
1167 
1168             // Skip target latency param
1169             ase_p++;
1170 
1171             codec_configured_state_params.preferred_phy = *ase_p++;
1172             codec_configured_state_params.codec_id.coding_format = ase_p[0];
1173             codec_configured_state_params.codec_id.vendor_company_id =
1174                 (uint16_t)(ase_p[1] << 8 | ase_p[2]),
1175             codec_configured_state_params.codec_id.vendor_codec_id =
1176                 (uint16_t)(ase_p[3] << 8 | ase_p[4]),
1177             ase_p += 5;
1178 
1179             auto codec_spec_param_len = *ase_p++;
1180             auto num_handled_bytes = ase_p - value.data();
1181             codec_configured_state_params.codec_spec_conf =
1182                 std::vector<uint8_t>(
1183                     value.begin() + num_handled_bytes,
1184                     value.begin() + num_handled_bytes + codec_spec_param_len);
1185             ase_p += codec_spec_param_len;
1186 
1187             // Some initial QoS settings
1188             codec_configured_state_params.framing =
1189                 ascs::kAseParamFramingUnframedSupported;
1190             codec_configured_state_params.preferred_retrans_nb = 0x04;
1191             codec_configured_state_params.max_transport_latency = 0x0010;
1192             codec_configured_state_params.pres_delay_min = 0xABABAB;
1193             codec_configured_state_params.pres_delay_max = 0xCDCDCD;
1194             codec_configured_state_params.preferred_pres_delay_min =
1195                 types::kPresDelayNoPreference;
1196             codec_configured_state_params.preferred_pres_delay_max =
1197                 types::kPresDelayNoPreference;
1198 
1199             if (caching) {
1200               cached_codec_configuration_map_[ase_id] =
1201                   codec_configured_state_params;
1202             }
1203 
1204             if (inject_configured) {
1205               InjectAseStateNotification(ase, device, group,
1206                                          ascs::kAseStateCodecConfigured,
1207                                          &codec_configured_state_params);
1208             }
1209 
1210             if (stop_inject_configured_ase_after_first_ase_configured_) {
1211               return;
1212             }
1213           }
1214         }));
1215   }
1216 
PrepareConfigureQosHandler(LeAudioDeviceGroup * group,int verify_ase_count=0,bool caching=false)1217   void PrepareConfigureQosHandler(LeAudioDeviceGroup* group,
1218                                   int verify_ase_count = 0,
1219                                   bool caching = false) {
1220     ON_CALL(ase_ctp_handler, AseCtpConfigureQosHandler)
1221         .WillByDefault(Invoke([group, verify_ase_count, caching, this](
1222                                   LeAudioDevice* device,
1223                                   std::vector<uint8_t> value,
1224                                   GATT_WRITE_OP_CB cb, void* cb_data) {
1225           auto num_ase = value[1];
1226 
1227           // Verify ase count if needed
1228           if (verify_ase_count) ASSERT_EQ(verify_ase_count, num_ase);
1229 
1230           // Inject Configured QoS state notification for each requested ASE
1231           auto* ase_p = &value[2];
1232           for (auto i = 0u; i < num_ase; ++i) {
1233             client_parser::ascs::ase_qos_configured_state_params
1234                 qos_configured_state_params;
1235 
1236             /* Check if this is a valid ASE ID  */
1237             auto ase_id = *ase_p++;
1238             auto it = std::find_if(
1239                 device->ases_.begin(), device->ases_.end(),
1240                 [ase_id](auto& ase) { return (ase.id == ase_id); });
1241             ASSERT_NE(it, device->ases_.end());
1242             const auto ase = &(*it);
1243 
1244             qos_configured_state_params.cig_id = *ase_p++;
1245             qos_configured_state_params.cis_id = *ase_p++;
1246 
1247             qos_configured_state_params.sdu_interval =
1248                 (uint32_t)((ase_p[0] << 16) | (ase_p[1] << 8) | ase_p[2]);
1249             ase_p += 3;
1250 
1251             qos_configured_state_params.framing = *ase_p++;
1252             qos_configured_state_params.phy = *ase_p++;
1253             qos_configured_state_params.max_sdu =
1254                 (uint16_t)((ase_p[0] << 8) | ase_p[1]);
1255             ase_p += 2;
1256 
1257             qos_configured_state_params.retrans_nb = *ase_p++;
1258             qos_configured_state_params.max_transport_latency =
1259                 (uint16_t)((ase_p[0] << 8) | ase_p[1]);
1260             ase_p += 2;
1261 
1262             qos_configured_state_params.pres_delay =
1263                 (uint16_t)((ase_p[0] << 16) | (ase_p[1] << 8) | ase_p[2]);
1264             ase_p += 3;
1265 
1266             if (caching) {
1267               log::info("Device: {}", device->address_);
1268               if (cached_ase_to_cis_id_map_.count(device->address_) > 0) {
1269                 auto ase_list = cached_ase_to_cis_id_map_.at(device->address_);
1270                 if (ase_list.count(ase_id) > 0) {
1271                   auto cis_id = ase_list.at(ase_id);
1272                   ASSERT_EQ(cis_id, qos_configured_state_params.cis_id);
1273                 } else {
1274                   ase_list[ase_id] = qos_configured_state_params.cis_id;
1275                 }
1276               } else {
1277                 std::map<int, int> ase_map;
1278                 ase_map[ase_id] = qos_configured_state_params.cis_id;
1279 
1280                 cached_ase_to_cis_id_map_[device->address_] = ase_map;
1281               }
1282               cached_qos_configuration_map_[ase_id] =
1283                   qos_configured_state_params;
1284             }
1285 
1286             InjectAseStateNotification(ase, device, group,
1287                                        ascs::kAseStateQoSConfigured,
1288                                        &qos_configured_state_params);
1289           }
1290         }));
1291   }
1292 
PrepareCtpNotificationError(LeAudioDeviceGroup * group,uint8_t opcode,uint8_t response_code,uint8_t reason)1293   void PrepareCtpNotificationError(LeAudioDeviceGroup* group, uint8_t opcode,
1294                                    uint8_t response_code, uint8_t reason) {
1295     auto foo = [group, opcode, response_code, reason](
1296                    LeAudioDevice* device, std::vector<uint8_t> value,
1297                    GATT_WRITE_OP_CB cb, void* cb_data) {
1298       auto num_ase = value[1];
1299       std::vector<uint8_t> notif_value(
1300           2 + num_ase * sizeof(struct client_parser::ascs::ctp_ase_entry));
1301       auto* p = notif_value.data();
1302 
1303       UINT8_TO_STREAM(p, opcode);
1304       UINT8_TO_STREAM(p, num_ase);
1305 
1306       auto* ase_p = &value[2];
1307       for (auto i = 0u; i < num_ase; ++i) {
1308         /* Check if this is a valid ASE ID  */
1309         auto ase_id = *ase_p++;
1310         auto it =
1311             std::find_if(device->ases_.begin(), device->ases_.end(),
1312                          [ase_id](auto& ase) { return (ase.id == ase_id); });
1313         ASSERT_NE(it, device->ases_.end());
1314 
1315         auto meta_len = *ase_p++;
1316         auto num_handled_bytes = ase_p - value.data();
1317         ase_p += meta_len;
1318 
1319         client_parser::ascs::ase_transient_state_params enable_params = {
1320             .metadata = std::vector<uint8_t>(
1321                 value.begin() + num_handled_bytes,
1322                 value.begin() + num_handled_bytes + meta_len)};
1323 
1324         // Inject error response
1325         UINT8_TO_STREAM(p, ase_id);
1326         UINT8_TO_STREAM(p, response_code);
1327         UINT8_TO_STREAM(p, reason);
1328       }
1329 
1330       LeAudioGroupStateMachine::Get()->ProcessGattCtpNotification(
1331           group, notif_value.data(), notif_value.size());
1332     };
1333 
1334     switch (opcode) {
1335       case client_parser::ascs::kCtpOpcodeCodecConfiguration:
1336         ON_CALL(ase_ctp_handler, AseCtpConfigureCodecHandler)
1337             .WillByDefault(Invoke(foo));
1338         break;
1339       case client_parser::ascs::kCtpOpcodeQosConfiguration:
1340         ON_CALL(ase_ctp_handler, AseCtpConfigureQosHandler)
1341             .WillByDefault(Invoke(foo));
1342         break;
1343       case client_parser::ascs::kCtpOpcodeEnable:
1344         ON_CALL(ase_ctp_handler, AseCtpEnableHandler)
1345             .WillByDefault(Invoke(foo));
1346         break;
1347       case client_parser::ascs::kCtpOpcodeReceiverStartReady:
1348         ON_CALL(ase_ctp_handler, AseCtpReceiverStartReadyHandler)
1349             .WillByDefault(Invoke(foo));
1350         break;
1351       case client_parser::ascs::kCtpOpcodeDisable:
1352         ON_CALL(ase_ctp_handler, AseCtpDisableHandler)
1353             .WillByDefault(Invoke(foo));
1354         break;
1355       case client_parser::ascs::kCtpOpcodeReceiverStopReady:
1356         ON_CALL(ase_ctp_handler, AseCtpReceiverStopReadyHandler)
1357             .WillByDefault(Invoke(foo));
1358         break;
1359       case client_parser::ascs::kCtpOpcodeUpdateMetadata:
1360         ON_CALL(ase_ctp_handler, AseCtpUpdateMetadataHandler)
1361             .WillByDefault(Invoke(foo));
1362         break;
1363       case client_parser::ascs::kCtpOpcodeRelease:
1364         ON_CALL(ase_ctp_handler, AseCtpReleaseHandler)
1365             .WillByDefault(Invoke(foo));
1366         break;
1367       default:
1368         break;
1369     };
1370   }
1371 
PrepareEnableHandler(LeAudioDeviceGroup * group,int verify_ase_count=0,bool inject_enabling=true,bool incject_streaming=true)1372   void PrepareEnableHandler(LeAudioDeviceGroup* group, int verify_ase_count = 0,
1373                             bool inject_enabling = true,
1374                             bool incject_streaming = true) {
1375     ON_CALL(ase_ctp_handler, AseCtpEnableHandler)
1376         .WillByDefault(Invoke([group, verify_ase_count, inject_enabling,
1377                                incject_streaming,
1378                                this](LeAudioDevice* device,
1379                                      std::vector<uint8_t> value,
1380                                      GATT_WRITE_OP_CB cb, void* cb_data) {
1381           auto num_ase = value[1];
1382 
1383           // Verify ase count if needed
1384           if (verify_ase_count) ASSERT_EQ(verify_ase_count, num_ase);
1385 
1386           // Inject Streaming ASE state notification for each requested ASE
1387           auto* ase_p = &value[2];
1388           for (auto i = 0u; i < num_ase; ++i) {
1389             /* Check if this is a valid ASE ID  */
1390             auto ase_id = *ase_p++;
1391             auto it = std::find_if(
1392                 device->ases_.begin(), device->ases_.end(),
1393                 [ase_id](auto& ase) { return (ase.id == ase_id); });
1394             ASSERT_NE(it, device->ases_.end());
1395             const auto ase = &(*it);
1396 
1397             auto meta_len = *ase_p++;
1398             auto num_handled_bytes = ase_p - value.data();
1399             ase_p += meta_len;
1400 
1401             client_parser::ascs::ase_transient_state_params enable_params = {
1402                 .metadata = std::vector<uint8_t>(
1403                     value.begin() + num_handled_bytes,
1404                     value.begin() + num_handled_bytes + meta_len)};
1405 
1406             // Server does the 'ReceiverStartReady' on its own - goes to
1407             // Streaming, when in Sink role
1408             if (ase->direction &
1409                 bluetooth::le_audio::types::kLeAudioDirectionSink) {
1410               if (inject_enabling)
1411                 InjectAseStateNotification(ase, device, group,
1412                                            ascs::kAseStateEnabling,
1413                                            &enable_params);
1414               if (incject_streaming) {
1415                 InjectAseStateNotification(ase, device, group,
1416                                            ascs::kAseStateStreaming,
1417                                            &enable_params);
1418               }
1419             } else {
1420               InjectAseStateNotification(
1421                   ase, device, group, ascs::kAseStateEnabling, &enable_params);
1422             }
1423           }
1424         }));
1425   }
1426 
PrepareDisableHandler(LeAudioDeviceGroup * group,int verify_ase_count=0)1427   void PrepareDisableHandler(LeAudioDeviceGroup* group,
1428                              int verify_ase_count = 0) {
1429     ON_CALL(ase_ctp_handler, AseCtpDisableHandler)
1430         .WillByDefault(Invoke([group, verify_ase_count, this](
1431                                   LeAudioDevice* device,
1432                                   std::vector<uint8_t> value,
1433                                   GATT_WRITE_OP_CB cb, void* cb_data) {
1434           auto num_ase = value[1];
1435 
1436           // Verify ase count if needed
1437           if (verify_ase_count) ASSERT_EQ(verify_ase_count, num_ase);
1438           ASSERT_EQ(value.size(), 2ul + num_ase);
1439 
1440           // Inject Disabling & QoS Conf. ASE state notification for each ASE
1441           auto* ase_p = &value[2];
1442           for (auto i = 0u; i < num_ase; ++i) {
1443             /* Check if this is a valid ASE ID  */
1444             auto ase_id = *ase_p++;
1445             auto it = std::find_if(
1446                 device->ases_.begin(), device->ases_.end(),
1447                 [ase_id](auto& ase) { return (ase.id == ase_id); });
1448             ASSERT_NE(it, device->ases_.end());
1449             const auto ase = &(*it);
1450 
1451             // The Disabling state is present for Source ASE
1452             if (ase->direction &
1453                 bluetooth::le_audio::types::kLeAudioDirectionSource) {
1454               client_parser::ascs::ase_transient_state_params disabling_params =
1455                   {.metadata = {}};
1456               InjectAseStateNotification(ase, device, group,
1457                                          ascs::kAseStateDisabling,
1458                                          &disabling_params);
1459             }
1460 
1461             // Server does the 'ReceiverStopReady' on its own - goes to
1462             // Streaming, when in Sink role
1463             if (ase->direction &
1464                 bluetooth::le_audio::types::kLeAudioDirectionSink) {
1465               // FIXME: For now our fake peer does not remember qos params
1466               client_parser::ascs::ase_qos_configured_state_params
1467                   qos_configured_state_params;
1468               InjectAseStateNotification(ase, device, group,
1469                                          ascs::kAseStateQoSConfigured,
1470                                          &qos_configured_state_params);
1471             }
1472           }
1473         }));
1474   }
1475 
PrepareReceiverStartReadyHandler(LeAudioDeviceGroup * group,int verify_ase_count=0)1476   void PrepareReceiverStartReadyHandler(LeAudioDeviceGroup* group,
1477                                         int verify_ase_count = 0) {
1478     ON_CALL(ase_ctp_handler, AseCtpReceiverStartReadyHandler)
1479         .WillByDefault(Invoke([group, verify_ase_count, this](
1480                                   LeAudioDevice* device,
1481                                   std::vector<uint8_t> value,
1482                                   GATT_WRITE_OP_CB cb, void* cb_data) {
1483           auto num_ase = value[1];
1484 
1485           // Verify ase count if needed
1486           if (verify_ase_count) ASSERT_EQ(verify_ase_count, num_ase);
1487 
1488           // Inject Streaming ASE state notification for each Source ASE
1489           auto* ase_p = &value[2];
1490           for (auto i = 0u; i < num_ase; ++i) {
1491             /* Check if this is a valid ASE ID  */
1492             auto ase_id = *ase_p++;
1493             auto it = std::find_if(
1494                 device->ases_.begin(), device->ases_.end(),
1495                 [ase_id](auto& ase) { return (ase.id == ase_id); });
1496             ASSERT_NE(it, device->ases_.end());
1497 
1498             // Once we did the 'ReceiverStartReady' the server goes to
1499             // Streaming, when in Source role
1500             const auto& ase = &(*it);
1501             client_parser::ascs::ase_transient_state_params streaming_params = {
1502                 .metadata = ase->metadata};
1503             InjectAseStateNotification(ase, device, group,
1504                                        ascs::kAseStateStreaming,
1505                                        &streaming_params);
1506           }
1507         }));
1508   }
1509 
PrepareReceiverStopReady(LeAudioDeviceGroup * group,int verify_ase_count=0)1510   void PrepareReceiverStopReady(LeAudioDeviceGroup* group,
1511                                 int verify_ase_count = 0) {
1512     ON_CALL(ase_ctp_handler, AseCtpReceiverStopReadyHandler)
1513         .WillByDefault(
1514             Invoke([group, verify_ase_count, this](
1515                        LeAudioDevice* device, std::vector<uint8_t> value,
1516                        GATT_WRITE_OP_CB cb, void* cb_data) {
1517               auto num_ase = value[1];
1518 
1519               // Verify ase count if needed
1520               if (verify_ase_count) ASSERT_EQ(verify_ase_count, num_ase);
1521 
1522               // Inject QoS configured ASE state notification for each Source
1523               // ASE
1524               auto* ase_p = &value[2];
1525               for (auto i = 0u; i < num_ase; ++i) {
1526                 /* Check if this is a valid ASE ID  */
1527                 auto ase_id = *ase_p++;
1528                 auto it = std::find_if(
1529                     device->ases_.begin(), device->ases_.end(),
1530                     [ase_id](auto& ase) { return (ase.id == ase_id); });
1531                 ASSERT_NE(it, device->ases_.end());
1532 
1533                 const auto& ase = &(*it);
1534 
1535                 // FIXME: For now our fake peer does not remember qos params
1536                 client_parser::ascs::ase_qos_configured_state_params
1537                     qos_configured_state_params;
1538                 InjectAseStateNotification(ase, device, group,
1539                                            ascs::kAseStateQoSConfigured,
1540                                            &qos_configured_state_params);
1541               }
1542             }));
1543   }
1544 
PrepareReleaseHandler(LeAudioDeviceGroup * group,int verify_ase_count=0,bool inject_disconnect_device=false,LeAudioDevice * dev=nullptr)1545   void PrepareReleaseHandler(LeAudioDeviceGroup* group,
1546                              int verify_ase_count = 0,
1547                              bool inject_disconnect_device = false,
1548                              LeAudioDevice* dev = nullptr) {
1549     ON_CALL(ase_ctp_handler, AseCtpReleaseHandler)
1550         .WillByDefault(
1551             Invoke([group, verify_ase_count, inject_disconnect_device, dev,
1552                     this](LeAudioDevice* device, std::vector<uint8_t> value,
1553                           GATT_WRITE_OP_CB cb, void* cb_data) {
1554               if (dev != nullptr && device != dev) {
1555                 log::info("Do nothing for {}", dev->address_);
1556                 return;
1557               }
1558 
1559               auto num_ase = value[1];
1560 
1561               // Verify ase count if needed
1562               if (verify_ase_count) ASSERT_EQ(verify_ase_count, num_ase);
1563               ASSERT_EQ(value.size(), 2ul + num_ase);
1564 
1565               if (inject_disconnect_device) {
1566                 InjectAclDisconnected(group, device);
1567                 return;
1568               }
1569 
1570               // Inject Releasing & Idle ASE state notification for each ASE
1571               auto* ase_p = &value[2];
1572               for (auto i = 0u; i < num_ase; ++i) {
1573                 /* Check if this is a valid ASE ID  */
1574                 auto ase_id = *ase_p++;
1575                 auto it = std::find_if(
1576                     device->ases_.begin(), device->ases_.end(),
1577                     [ase_id](auto& ase) { return (ase.id == ase_id); });
1578                 ASSERT_NE(it, device->ases_.end());
1579                 const auto ase = &(*it);
1580 
1581                 InjectAseStateNotification(ase, device, group,
1582                                            ascs::kAseStateReleasing, nullptr);
1583 
1584                 if (stay_in_releasing_state_) {
1585                   continue;
1586                 }
1587 
1588                 /* Check if codec configuration is cached */
1589                 if (cached_codec_configuration_map_.count(ase_id) > 0) {
1590                   InjectAseStateNotification(
1591                       ase, device, group, ascs::kAseStateCodecConfigured,
1592                       &cached_codec_configuration_map_[ase_id]);
1593                 } else {
1594                   // Release - no caching
1595                   InjectAseStateNotification(ase, device, group,
1596                                              ascs::kAseStateIdle, nullptr);
1597                 }
1598               }
1599             }));
1600   }
1601 
1602   MockCsisClient mock_csis_client_module_;
1603   NiceMock<bluetooth::manager::MockBtmInterface> btm_interface;
1604   gatt::MockBtaGattInterface gatt_interface;
1605   gatt::MockBtaGattQueue gatt_queue;
1606 
1607   bluetooth::hci::IsoManager* iso_manager_;
1608   MockIsoManager* mock_iso_manager_;
1609   bluetooth::le_audio::CodecManager* codec_manager_;
1610   MockCodecManager* mock_codec_manager_;
1611 
1612   MockAseRemoteStateMachine ase_ctp_handler;
1613   std::map<int, client_parser::ascs::ase_codec_configured_state_params>
1614       cached_codec_configuration_map_;
1615   std::map<int, client_parser::ascs::ase_qos_configured_state_params>
1616       cached_qos_configuration_map_;
1617 
1618   std::map<RawAddress, std::map<int, int>> cached_ase_to_cis_id_map_;
1619   std::map<types::ase*, std::vector<uint8_t>>
1620       cached_remote_qos_configuration_for_ase_;
1621 
1622   MockLeAudioGroupStateMachineCallbacks mock_callbacks_;
1623   std::vector<std::shared_ptr<LeAudioDevice>> le_audio_devices_;
1624   std::vector<RawAddress> addresses_;
1625   std::map<uint8_t, std::unique_ptr<LeAudioDeviceGroup>>
1626       le_audio_device_groups_;
1627   bool group_create_command_disallowed_ = false;
1628   bluetooth::hci::testing::MockControllerInterface controller_;
1629 };
1630 
1631 class StateMachineTest : public StateMachineTestBase {
SetUp()1632   void SetUp() override {
1633     ConfigCodecManagerMock(types::CodecLocation::HOST);
1634     ::bluetooth::le_audio::AudioSetConfigurationProvider::Initialize(
1635         ::bluetooth::le_audio::types::CodecLocation::HOST);
1636     StateMachineTestBase::SetUp();
1637   }
1638 };
1639 
1640 class StateMachineTestNoSwb : public StateMachineTestBase {
SetUp()1641   void SetUp() override {
1642     ConfigCodecManagerMock(types::CodecLocation::HOST);
1643     ::bluetooth::le_audio::AudioSetConfigurationProvider::Initialize(
1644         ::bluetooth::le_audio::types::CodecLocation::HOST);
1645     ON_CALL(*mock_codec_manager_, IsDualBiDirSwbSupported)
1646         .WillByDefault(Return(false));
1647     StateMachineTestBase::SetUp();
1648   }
1649 };
1650 
1651 class StateMachineTestAdsp : public StateMachineTestBase {
SetUp()1652   void SetUp() override {
1653     ConfigCodecManagerMock(types::CodecLocation::ADSP);
1654     ::bluetooth::le_audio::AudioSetConfigurationProvider::Initialize(
1655         ::bluetooth::le_audio::types::CodecLocation::ADSP);
1656     StateMachineTestBase::SetUp();
1657   }
1658 };
1659 
TEST_F(StateMachineTest,testInit)1660 TEST_F(StateMachineTest, testInit) {
1661   ASSERT_NE(LeAudioGroupStateMachine::Get(), nullptr);
1662 }
1663 
TEST_F(StateMachineTest,testCleanup)1664 TEST_F(StateMachineTest, testCleanup) {
1665   ASSERT_NE(LeAudioGroupStateMachine::Get(), nullptr);
1666   LeAudioGroupStateMachine::Cleanup();
1667   EXPECT_DEATH(LeAudioGroupStateMachine::Get(), "");
1668 }
1669 
TEST_F(StateMachineTest,testConfigureCodecSingle)1670 TEST_F(StateMachineTest, testConfigureCodecSingle) {
1671   /* Device is banded headphones with 1x snk + 0x src ase
1672    * (1xunidirectional CIS) with channel count 2 (for stereo
1673    */
1674   const auto context_type = kContextTypeRingtone;
1675   const int leaudio_group_id = 2;
1676   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
1677                    kLeAudioCodecChannelCountTwoChannel;
1678 
1679   // Prepare fake connected device group
1680   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
1681 
1682   /* Since we prepared device with Ringtone context in mind, only one ASE
1683    * should have been configured.
1684    */
1685   auto* leAudioDevice = group->GetFirstDevice();
1686   PrepareConfigureCodecHandler(group, 1);
1687 
1688   /* Start the configuration and stream Media content.
1689    * Expect 1 time for the Codec Config call only. */
1690   EXPECT_CALL(gatt_queue,
1691               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
1692                                   GATT_WRITE_NO_RSP, _, _))
1693       .Times(1);
1694 
1695   /* Do nothing on the CigCreate, so the state machine stays in the configure
1696    * state */
1697   ON_CALL(*mock_iso_manager_, CreateCig).WillByDefault(Return());
1698   EXPECT_CALL(*mock_iso_manager_, CreateCig).Times(1);
1699 
1700   InjectInitialIdleNotification(group);
1701 
1702   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
1703       group, context_type,
1704       {.sink = types::AudioContexts(context_type),
1705        .source = types::AudioContexts(context_type)}));
1706 
1707   // Check if group has transitioned to a proper state
1708   ASSERT_EQ(group->GetState(),
1709             types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
1710 
1711   /* Cancel is called when group goes to streaming. */
1712   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
1713 }
1714 
TEST_F(StateMachineTest,testConfigureCodecMulti)1715 TEST_F(StateMachineTest, testConfigureCodecMulti) {
1716   const auto context_type = kContextTypeMedia;
1717   const auto leaudio_group_id = 2;
1718   const auto num_devices = 2;
1719 
1720   // Prepare multiple fake connected devices in a group
1721   auto* group =
1722       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
1723   ASSERT_EQ(group->Size(), num_devices);
1724 
1725   PrepareConfigureCodecHandler(group);
1726 
1727   auto expected_devices_written = 0;
1728   auto* leAudioDevice = group->GetFirstDevice();
1729   while (leAudioDevice) {
1730     EXPECT_CALL(gatt_queue,
1731                 WriteCharacteristic(leAudioDevice->conn_id_,
1732                                     leAudioDevice->ctp_hdls_.val_hdl, _,
1733                                     GATT_WRITE_NO_RSP, _, _))
1734         .Times(AtLeast(1));
1735     expected_devices_written++;
1736     leAudioDevice = group->GetNextDevice(leAudioDevice);
1737   }
1738   ASSERT_EQ(expected_devices_written, num_devices);
1739 
1740   InjectInitialIdleNotification(group);
1741 
1742   /* Do nothing on the CigCreate, so the state machine stays in the configure
1743    * state */
1744   ON_CALL(*mock_iso_manager_, CreateCig).WillByDefault(Return());
1745   EXPECT_CALL(*mock_iso_manager_, CreateCig).Times(1);
1746 
1747   // Start the configuration and stream the content
1748   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
1749       group, context_type,
1750       {.sink = types::AudioContexts(context_type),
1751        .source = types::AudioContexts(context_type)}));
1752 
1753   // Check if group has transitioned to a proper state
1754   ASSERT_EQ(group->GetState(),
1755             types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
1756 
1757   /* Cancel is called when group goes to streaming. */
1758   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
1759 }
1760 
TEST_F(StateMachineTest,testConfigureQosSingle)1761 TEST_F(StateMachineTest, testConfigureQosSingle) {
1762   /* Device is banded headphones with 2x snk + 1x src ase
1763    * (1x bidirectional + 1xunidirectional CIS)
1764    */
1765   additional_snk_ases = 1;
1766   additional_src_ases = 1;
1767   const auto context_type = kContextTypeRingtone;
1768   const int leaudio_group_id = 3;
1769 
1770   // Prepare fake connected device group
1771   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
1772 
1773   /* Since we prepared device with Ringtone context in mind, only one ASE
1774    * should have been configured.
1775    */
1776   auto* leAudioDevice = group->GetFirstDevice();
1777   PrepareConfigureCodecHandler(group, 2);
1778   PrepareConfigureQosHandler(group, 2);
1779 
1780   // Start the configuration and stream Media content
1781   EXPECT_CALL(gatt_queue,
1782               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
1783                                   GATT_WRITE_NO_RSP, _, _))
1784       .Times(3);
1785 
1786   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
1787   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
1788   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
1789   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
1790   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
1791   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
1792 
1793   InjectInitialIdleNotification(group);
1794 
1795   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
1796       group, context_type,
1797       {.sink = types::AudioContexts(context_type),
1798        .source = types::AudioContexts(context_type)}));
1799 
1800   // Check if group has transitioned to a proper state
1801   ASSERT_EQ(group->GetState(),
1802             types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED);
1803 
1804   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
1805 }
1806 
TEST_F(StateMachineTest,testConfigureQosSingleRecoverCig)1807 TEST_F(StateMachineTest, testConfigureQosSingleRecoverCig) {
1808   /* Device is banded headphones with 2x snk + 1x src ase
1809    * (1x bidirectional + 1xunidirectional CIS)
1810    */
1811   additional_snk_ases = 1;
1812   additional_src_ases = 1;
1813   const auto context_type = kContextTypeRingtone;
1814   const int leaudio_group_id = 3;
1815 
1816   /* Assume that on previous BT OFF CIG was not removed */
1817   group_create_command_disallowed_ = true;
1818 
1819   // Prepare fake connected device group
1820   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
1821 
1822   /* Since we prepared device with Ringtone context in mind, only one ASE
1823    * should have been configured.
1824    */
1825   auto* leAudioDevice = group->GetFirstDevice();
1826   PrepareConfigureCodecHandler(group, 2);
1827   PrepareConfigureQosHandler(group, 2);
1828 
1829   // Start the configuration and stream Media content
1830   EXPECT_CALL(gatt_queue,
1831               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
1832                                   GATT_WRITE_NO_RSP, _, _))
1833       .Times(3);
1834 
1835   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(2);
1836   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
1837   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
1838   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
1839   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
1840   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
1841 
1842   InjectInitialIdleNotification(group);
1843 
1844   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
1845       group, context_type,
1846       {.sink = types::AudioContexts(context_type),
1847        .source = types::AudioContexts(context_type)}));
1848 
1849   // Check if group has transitioned to a proper state
1850   ASSERT_EQ(group->GetState(),
1851             types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED);
1852   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
1853 }
1854 
TEST_F(StateMachineTest,testConfigureQosMultiple)1855 TEST_F(StateMachineTest, testConfigureQosMultiple) {
1856   const auto context_type = kContextTypeMedia;
1857   const auto leaudio_group_id = 3;
1858   const auto num_devices = 2;
1859 
1860   // Prepare multiple fake connected devices in a group
1861   auto* group =
1862       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
1863   ASSERT_EQ(group->Size(), num_devices);
1864 
1865   PrepareConfigureCodecHandler(group);
1866   PrepareConfigureQosHandler(group);
1867 
1868   auto* leAudioDevice = group->GetFirstDevice();
1869   auto expected_devices_written = 0;
1870   while (leAudioDevice) {
1871     EXPECT_CALL(gatt_queue,
1872                 WriteCharacteristic(leAudioDevice->conn_id_,
1873                                     leAudioDevice->ctp_hdls_.val_hdl, _,
1874                                     GATT_WRITE_NO_RSP, _, _))
1875         .Times(AtLeast(2));
1876     expected_devices_written++;
1877     leAudioDevice = group->GetNextDevice(leAudioDevice);
1878   }
1879   ASSERT_EQ(expected_devices_written, num_devices);
1880 
1881   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
1882   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
1883   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
1884   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
1885   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
1886   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
1887 
1888   InjectInitialIdleNotification(group);
1889 
1890   // Start the configuration and stream Media content
1891   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
1892       group, context_type,
1893       {.sink = types::AudioContexts(context_type),
1894        .source = types::AudioContexts(context_type)}));
1895 
1896   // Check if group has transitioned to a proper state
1897   ASSERT_EQ(group->GetState(),
1898             types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED);
1899   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
1900 }
1901 
TEST_F(StateMachineTest,testConfigureQosFailed)1902 TEST_F(StateMachineTest, testConfigureQosFailed) {
1903   const auto context_type = kContextTypeMedia;
1904   const auto leaudio_group_id = 3;
1905   const auto num_devices = 2;
1906 
1907   // Check if CIG is properly cleared when QoS failed
1908 
1909   // Prepare multiple fake connected devices in a group
1910   auto* group =
1911       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
1912   ASSERT_EQ(group->Size(), num_devices);
1913 
1914   PrepareConfigureCodecHandler(group);
1915   PrepareCtpNotificationError(
1916       group, client_parser::ascs::kCtpOpcodeQosConfiguration,
1917       client_parser::ascs::kCtpResponseCodeInvalidConfigurationParameterValue,
1918       client_parser::ascs::kCtpResponsePhy);
1919   PrepareReleaseHandler(group);
1920 
1921   auto* leAudioDevice = group->GetFirstDevice();
1922   auto expected_devices_written = 0;
1923   while (leAudioDevice) {
1924     EXPECT_CALL(gatt_queue,
1925                 WriteCharacteristic(leAudioDevice->conn_id_,
1926                                     leAudioDevice->ctp_hdls_.val_hdl, _,
1927                                     GATT_WRITE_NO_RSP, _, _))
1928         .Times(AtLeast(2));
1929     expected_devices_written++;
1930     leAudioDevice = group->GetNextDevice(leAudioDevice);
1931   }
1932   ASSERT_EQ(expected_devices_written, num_devices);
1933 
1934   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
1935   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
1936   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
1937   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
1938   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
1939   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
1940 
1941   InjectInitialIdleNotification(group);
1942 
1943   // Start the configuration and stream Media content
1944   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
1945       group, context_type,
1946       {.sink = types::AudioContexts(context_type),
1947        .source = types::AudioContexts(context_type)}));
1948 
1949   // Check if group has transitioned to a proper state
1950   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
1951   ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
1952 
1953   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
1954 }
1955 
TEST_F(StateMachineTest,testDeviceDisconnectedWhileCigCreated)1956 TEST_F(StateMachineTest, testDeviceDisconnectedWhileCigCreated) {
1957   const auto context_type = kContextTypeMedia;
1958   const auto leaudio_group_id = 3;
1959   const auto num_devices = 1;
1960 
1961   // verify proper cleaning when group is disconnected while CIG is creating.
1962 
1963   // Prepare fake connected device in a group
1964   auto* group =
1965       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
1966   ASSERT_EQ(group->Size(), num_devices);
1967 
1968   PrepareConfigureCodecHandler(group);
1969 
1970   ON_CALL(*mock_iso_manager_, CreateCig).WillByDefault(Return());
1971 
1972   auto* leAudioDevice = group->GetFirstDevice();
1973   EXPECT_CALL(gatt_queue, WriteCharacteristic(leAudioDevice->conn_id_,
1974                                               leAudioDevice->ctp_hdls_.val_hdl,
1975                                               _, GATT_WRITE_NO_RSP, _, _))
1976       .Times(1);
1977 
1978   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
1979   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
1980   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
1981   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
1982   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
1983 
1984   InjectInitialIdleNotification(group);
1985 
1986   // Start the configuration and stream Media content
1987   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
1988       group, context_type,
1989       {.sink = types::AudioContexts(context_type),
1990        .source = types::AudioContexts(context_type)}));
1991 
1992   // Check if group has transitioned to a proper state
1993   ASSERT_EQ(group->GetState(),
1994             types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
1995 
1996   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
1997 
1998   InjectAclDisconnected(group, leAudioDevice);
1999   std::vector<uint16_t> conn_handles = {0x0001, 0x0002};
2000   int cig_id = 1;
2001 
2002   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
2003   LeAudioGroupStateMachine::Get()->ProcessHciNotifOnCigCreate(
2004       group, HCI_SUCCESS, cig_id, conn_handles);
2005 
2006   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
2007   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
2008 }
2009 
TEST_F(StateMachineTest,testStreamCreationError)2010 TEST_F(StateMachineTest, testStreamCreationError) {
2011   /* Device is banded headphones with 1x snk + 0x src ase
2012    * (1xunidirectional CIS) with channel count 2 (for stereo
2013    */
2014   const auto context_type = kContextTypeRingtone;
2015   const int leaudio_group_id = 4;
2016   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
2017                    kLeAudioCodecChannelCountTwoChannel;
2018 
2019   // Prepare fake connected device group
2020   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
2021 
2022   /* Ringtone with channel count 1 for single device and 1 ASE sink will
2023    * end up with 1 Sink ASE being configured.
2024    */
2025   PrepareConfigureCodecHandler(group, 1);
2026   PrepareConfigureQosHandler(group, 1);
2027   PrepareCtpNotificationError(
2028       group, client_parser::ascs::kCtpOpcodeEnable,
2029       client_parser::ascs::kCtpResponseCodeUnspecifiedError,
2030       client_parser::ascs::kCtpResponseNoReason);
2031   PrepareReleaseHandler(group);
2032 
2033   auto* leAudioDevice = group->GetFirstDevice();
2034 
2035   /*
2036    * 1 - Configure ASE
2037    * 2 - QoS ASE
2038    * 3 - Enable ASE
2039    * 4 - Release ASE
2040    */
2041   EXPECT_CALL(gatt_queue,
2042               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
2043                                   GATT_WRITE_NO_RSP, _, _))
2044       .Times(4);
2045 
2046   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2047   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
2048   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
2049   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
2050   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
2051   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
2052 
2053   InjectInitialIdleNotification(group);
2054 
2055   // Validate GroupStreamStatus
2056   EXPECT_CALL(
2057       mock_callbacks_,
2058       StatusReportCb(leaudio_group_id,
2059                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
2060   EXPECT_CALL(mock_callbacks_,
2061               StatusReportCb(leaudio_group_id,
2062                              bluetooth::le_audio::GroupStreamStatus::IDLE));
2063 
2064   // Start the configuration and stream Media content
2065   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2066       group, context_type,
2067       {.sink = types::AudioContexts(context_type),
2068        .source = types::AudioContexts(context_type)}));
2069 
2070   // Check if group has transitioned to a proper state
2071   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
2072   ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
2073 }
2074 
TEST_F(StateMachineTest,testStreamSingle)2075 TEST_F(StateMachineTest, testStreamSingle) {
2076   /* Device is banded headphones with 1x snk + 0x src ase
2077    * (1xunidirectional CIS) with channel count 2 (for stereo
2078    */
2079   const auto context_type = kContextTypeRingtone;
2080   const int leaudio_group_id = 4;
2081   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
2082                    kLeAudioCodecChannelCountTwoChannel;
2083 
2084   // Prepare fake connected device group
2085   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
2086 
2087   /* Ringtone with channel count 1 for single device and 1 ASE sink will
2088    * end up with 1 Sink ASE being configured.
2089    */
2090   PrepareConfigureCodecHandler(group, 1);
2091   PrepareConfigureQosHandler(group, 1);
2092   PrepareEnableHandler(group, 1);
2093 
2094   auto* leAudioDevice = group->GetFirstDevice();
2095   EXPECT_CALL(gatt_queue,
2096               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
2097                                   GATT_WRITE_NO_RSP, _, _))
2098       .Times(3);
2099 
2100   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2101   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
2102   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
2103   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
2104   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
2105   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
2106 
2107   InjectInitialIdleNotification(group);
2108 
2109   // Validate GroupStreamStatus
2110   EXPECT_CALL(
2111       mock_callbacks_,
2112       StatusReportCb(leaudio_group_id,
2113                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
2114 
2115   // Start the configuration and stream Media content
2116   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2117       group, context_type,
2118       {.sink = types::AudioContexts(context_type),
2119        .source = types::AudioContexts(context_type)}));
2120 
2121   // Check if group has transitioned to a proper state
2122   ASSERT_EQ(group->GetState(),
2123             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
2124   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
2125 }
2126 
TEST_F(StateMachineTest,testStreamSingleRetryCisFailure)2127 TEST_F(StateMachineTest, testStreamSingleRetryCisFailure) {
2128   /* Device is banded headphones with 1x snk + 0x src ase
2129    * (1xunidirectional CIS) with channel count 2 (for stereo
2130    */
2131   const auto context_type = kContextTypeRingtone;
2132   const int leaudio_group_id = 4;
2133   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
2134                    kLeAudioCodecChannelCountTwoChannel;
2135 
2136   // Prepare fake connected device group
2137   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
2138 
2139   /* Ringtone with channel count 1 for single device and 1 ASE sink will
2140    * end up with 1 Sink ASE being configured.
2141    */
2142   PrepareConfigureCodecHandler(group, 1);
2143   PrepareConfigureQosHandler(group, 1);
2144   PrepareEnableHandler(group, 1);
2145   PrepareReleaseHandler(group);
2146 
2147   use_cis_retry_cnt_ = true;
2148   retry_cis_established_cnt_ = 4;
2149 
2150   auto* leAudioDevice = group->GetFirstDevice();
2151   EXPECT_CALL(gatt_queue,
2152               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
2153                                   GATT_WRITE_NO_RSP, _, _))
2154       .Times(4);
2155 
2156   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2157   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(3);
2158   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
2159   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
2160   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
2161   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
2162 
2163   InjectInitialIdleNotification(group);
2164 
2165   // Validate GroupStreamStatus
2166   EXPECT_CALL(
2167       mock_callbacks_,
2168       StatusReportCb(leaudio_group_id,
2169                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
2170   EXPECT_CALL(mock_callbacks_,
2171               StatusReportCb(leaudio_group_id,
2172                              bluetooth::le_audio::GroupStreamStatus::IDLE));
2173 
2174   // Start the configuration and stream Media content
2175   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2176       group, context_type,
2177       {.sink = types::AudioContexts(context_type),
2178        .source = types::AudioContexts(context_type)}));
2179 
2180   // Check if group has transitioned to a proper state
2181   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
2182   ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
2183 }
2184 
TEST_F(StateMachineTest,testStreamSingleRetryCisSuccess)2185 TEST_F(StateMachineTest, testStreamSingleRetryCisSuccess) {
2186   /* Device is banded headphones with 1x snk + 0x src ase
2187    * (1xunidirectional CIS) with channel count 2 (for stereo
2188    */
2189   const auto context_type = kContextTypeRingtone;
2190   const int leaudio_group_id = 4;
2191   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
2192                    kLeAudioCodecChannelCountTwoChannel;
2193 
2194   // Prepare fake connected device group
2195   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
2196 
2197   /* Ringtone with channel count 1 for single device and 1 ASE sink will
2198    * end up with 1 Sink ASE being configured.
2199    */
2200   PrepareConfigureCodecHandler(group, 1);
2201   PrepareConfigureQosHandler(group, 1);
2202   PrepareEnableHandler(group, 1);
2203 
2204   use_cis_retry_cnt_ = true;
2205   retry_cis_established_cnt_ = 2;
2206 
2207   auto* leAudioDevice = group->GetFirstDevice();
2208   EXPECT_CALL(gatt_queue,
2209               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
2210                                   GATT_WRITE_NO_RSP, _, _))
2211       .Times(3);
2212 
2213   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2214   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(3);
2215   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
2216   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
2217   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
2218   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
2219 
2220   InjectInitialIdleNotification(group);
2221 
2222   // Validate GroupStreamStatus
2223   EXPECT_CALL(
2224       mock_callbacks_,
2225       StatusReportCb(leaudio_group_id,
2226                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
2227 
2228   // Start the configuration and stream Media content
2229   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2230       group, context_type,
2231       {.sink = types::AudioContexts(context_type),
2232        .source = types::AudioContexts(context_type)}));
2233 
2234   // Check if group has transitioned to a proper state
2235   ASSERT_EQ(group->GetState(),
2236             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
2237   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
2238 }
2239 
TEST_F(StateMachineTest,testStreamSkipEnablingSink)2240 TEST_F(StateMachineTest, testStreamSkipEnablingSink) {
2241   /* Device is banded headphones with 2x snk + none src ase
2242    * (2x unidirectional CIS)
2243    */
2244 
2245   /* Not, that when remote device skip Enabling it is considered as an error and
2246    * group will not be able to go to Streaming state.
2247    * It is because, Android is not creating CISes before all ASEs gets into
2248    * Enabling state, therefore it is impossible to remote device to skip
2249    * Enabling state.
2250    */
2251   const auto context_type = kContextTypeMedia;
2252   const int leaudio_group_id = 4;
2253 
2254   // Prepare fake connected device group
2255   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
2256 
2257   /* For Media context type with channel count 1 and two ASEs,
2258    * there should have be 2 Ases configured configured.
2259    */
2260   PrepareConfigureCodecHandler(group, 2);
2261   PrepareConfigureQosHandler(group, 2);
2262   PrepareEnableHandler(group, 2, false);
2263 
2264   /*
2265    * 1. Configure
2266    * 2. QoS Config
2267    * 3. Enable
2268    * 4. Release
2269    */
2270   auto* leAudioDevice = group->GetFirstDevice();
2271   EXPECT_CALL(gatt_queue,
2272               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
2273                                   GATT_WRITE_NO_RSP, _, _))
2274       .Times(4);
2275 
2276   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2277   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
2278   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
2279   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
2280   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
2281   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
2282 
2283   InjectInitialIdleNotification(group);
2284 
2285   // Validate GroupStreamStatus
2286   EXPECT_CALL(mock_callbacks_,
2287               StatusReportCb(leaudio_group_id,
2288                              bluetooth::le_audio::GroupStreamStatus::STREAMING))
2289       .Times(0);
2290 
2291   EXPECT_CALL(mock_callbacks_,
2292               StatusReportCb(leaudio_group_id,
2293                              bluetooth::le_audio::GroupStreamStatus::RELEASING))
2294       .Times(1);
2295 
2296   // Start the configuration and stream Media content
2297   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2298       group, context_type,
2299       {.sink = types::AudioContexts(context_type),
2300        .source = types::AudioContexts(context_type)}));
2301 
2302   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
2303 }
2304 
TEST_F(StateMachineTest,testStreamSkipEnablingSinkSource)2305 TEST_F(StateMachineTest, testStreamSkipEnablingSinkSource) {
2306   /* Device is banded headphones with 2x snk + 1x src ase
2307    * (1x bidirectional CIS)
2308    */
2309   const auto context_type = kContextTypeConversational;
2310   const int leaudio_group_id = 4;
2311 
2312   additional_snk_ases = 1;
2313 
2314   // Prepare fake connected device group
2315   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
2316 
2317   /* Since we prepared device with Conversional context in mind,
2318    * 2 Sink ASEs and 1 Source ASE should have been configured.
2319    */
2320   PrepareConfigureCodecHandler(group, 3);
2321   PrepareConfigureQosHandler(group, 3);
2322   PrepareEnableHandler(group, 3, false);
2323   PrepareReceiverStartReadyHandler(group, 1);
2324 
2325   /*
2326    * 1. Codec Config
2327    * 2. Qos Config
2328    * 3. Enable
2329    * 4. Release
2330    */
2331   auto* leAudioDevice = group->GetFirstDevice();
2332   EXPECT_CALL(gatt_queue,
2333               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
2334                                   GATT_WRITE_NO_RSP, _, _))
2335       .Times(4);
2336 
2337   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2338   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
2339   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
2340   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
2341   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
2342   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
2343 
2344   InjectInitialIdleNotification(group);
2345 
2346   // Validate GroupStreamStatus
2347   EXPECT_CALL(mock_callbacks_,
2348               StatusReportCb(leaudio_group_id,
2349                              bluetooth::le_audio::GroupStreamStatus::STREAMING))
2350       .Times(0);
2351   EXPECT_CALL(mock_callbacks_,
2352               StatusReportCb(leaudio_group_id,
2353                              bluetooth::le_audio::GroupStreamStatus::RELEASING))
2354       .Times(1);
2355 
2356   // Start the configuration and stream Media content
2357   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2358       group, context_type,
2359       {.sink = types::AudioContexts(context_type),
2360        .source = types::AudioContexts(context_type)}));
2361 
2362   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
2363 }
2364 
TEST_F(StateMachineTest,testStreamMultipleMedia_OneMemberHasNoAses)2365 TEST_F(StateMachineTest, testStreamMultipleMedia_OneMemberHasNoAses) {
2366   const auto context_type = kContextTypeMedia;
2367   const auto leaudio_group_id = 4;
2368   const auto num_devices = 2;
2369 
2370   // Prepare multiple fake connected devices in a group. This time one device
2371   // has 0 Ases
2372   auto* group =
2373       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices,
2374                                    types::AudioContexts(), true);
2375   ASSERT_EQ(group->Size(), num_devices);
2376 
2377   PrepareConfigureCodecHandler(group);
2378   PrepareConfigureQosHandler(group);
2379   PrepareEnableHandler(group);
2380   PrepareReceiverStartReadyHandler(group);
2381 
2382   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2383   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(AtLeast(1));
2384   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
2385   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
2386   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
2387   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
2388 
2389   InjectInitialIdleNotification(group);
2390 
2391   /* Check there are two devices*/
2392   auto* leAudioDevice = group->GetFirstDevice();
2393   LeAudioDevice* lastDevice = nullptr;
2394   /*
2395    * First set member has no ASEs, no operations on control point are expected
2396    * 0
2397    */
2398   EXPECT_CALL(gatt_queue, WriteCharacteristic(leAudioDevice->conn_id_,
2399                                               leAudioDevice->ctp_hdls_.val_hdl,
2400                                               _, GATT_WRITE_NO_RSP, _, _))
2401       .Times(0);
2402 
2403   auto expected_devices_written = 0;
2404   while (leAudioDevice) {
2405     expected_devices_written++;
2406     lastDevice = leAudioDevice;
2407     leAudioDevice = group->GetNextDevice(leAudioDevice);
2408   }
2409   ASSERT_EQ(expected_devices_written, num_devices);
2410 
2411   /*
2412    * Second device will be configured for Streaming. Expecting 3 operations:
2413    * 1. Codec Config
2414    * 2. QoS Config
2415    * 3. Enable
2416    */
2417   EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_,
2418                                               lastDevice->ctp_hdls_.val_hdl, _,
2419                                               GATT_WRITE_NO_RSP, _, _))
2420       .Times(3);
2421 
2422   // Validate GroupStreamStatus
2423   EXPECT_CALL(
2424       mock_callbacks_,
2425       StatusReportCb(leaudio_group_id,
2426                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
2427 
2428   // Start the configuration and stream Media content
2429   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2430       group, context_type,
2431       {.sink = types::AudioContexts(context_type),
2432        .source = types::AudioContexts(context_type)}));
2433 
2434   // Check if group has transitioned to a proper state
2435   ASSERT_EQ(group->GetState(),
2436             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
2437   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
2438 }
2439 
TEST_F(StateMachineTest,testStreamMultipleMedia_OneMemberHasNoAsesAndNotConnected)2440 TEST_F(StateMachineTest,
2441        testStreamMultipleMedia_OneMemberHasNoAsesAndNotConnected) {
2442   const auto context_type = kContextTypeMedia;
2443   const auto leaudio_group_id = 4;
2444   const auto num_devices = 2;
2445 
2446   // Prepare multiple fake connected devices in a group. This time one device
2447   // has 0 Ases
2448   auto* group =
2449       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices,
2450                                    types::AudioContexts(), true);
2451   ASSERT_EQ(group->Size(), num_devices);
2452 
2453   PrepareConfigureCodecHandler(group);
2454   PrepareConfigureQosHandler(group);
2455   PrepareEnableHandler(group);
2456   PrepareReceiverStartReadyHandler(group);
2457 
2458   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2459   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(AtLeast(1));
2460   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
2461   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
2462   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
2463   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
2464 
2465   InjectInitialIdleNotification(group);
2466 
2467   /* Check there are two devices*/
2468   auto* leAudioDevice = group->GetFirstDevice();
2469   LeAudioDevice* lastDevice = nullptr;
2470   /*
2471    * First set member has no ASEs, no operations on control point are expected
2472    * 0
2473    */
2474   EXPECT_CALL(gatt_queue, WriteCharacteristic(leAudioDevice->conn_id_,
2475                                               leAudioDevice->ctp_hdls_.val_hdl,
2476                                               _, GATT_WRITE_NO_RSP, _, _))
2477       .Times(0);
2478 
2479   /* Device with 0 Ases is disconnected */
2480   InjectAclDisconnected(group, leAudioDevice);
2481 
2482   auto expected_devices_written = 0;
2483   while (leAudioDevice) {
2484     expected_devices_written++;
2485     lastDevice = leAudioDevice;
2486     leAudioDevice = group->GetNextDevice(leAudioDevice);
2487   }
2488   ASSERT_EQ(expected_devices_written, num_devices);
2489 
2490   /*
2491    * Second device will be configured for Streaming. Expecting 3 operations:
2492    * 1. Codec Config
2493    * 2. QoS Config
2494    * 3. Enable
2495    */
2496   EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_,
2497                                               lastDevice->ctp_hdls_.val_hdl, _,
2498                                               GATT_WRITE_NO_RSP, _, _))
2499       .Times(3);
2500 
2501   // Validate GroupStreamStatus
2502   EXPECT_CALL(
2503       mock_callbacks_,
2504       StatusReportCb(leaudio_group_id,
2505                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
2506 
2507   // Start the configuration and stream Media content
2508   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2509       group, context_type,
2510       {.sink = types::AudioContexts(context_type),
2511        .source = types::AudioContexts(context_type)}));
2512 
2513   // Check if group has transitioned to a proper state
2514   ASSERT_EQ(group->GetState(),
2515             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
2516   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
2517 }
2518 
TEST_F(StateMachineTest,testStreamMultipleConversational)2519 TEST_F(StateMachineTest, testStreamMultipleConversational) {
2520   const auto context_type = kContextTypeConversational;
2521   const auto leaudio_group_id = 4;
2522   const auto num_devices = 2;
2523 
2524   // Prepare multiple fake connected devices in a group
2525   auto* group =
2526       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
2527   ASSERT_EQ(group->Size(), num_devices);
2528 
2529   PrepareConfigureCodecHandler(group);
2530   PrepareConfigureQosHandler(group);
2531   PrepareEnableHandler(group);
2532   PrepareReceiverStartReadyHandler(group);
2533 
2534   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2535   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(AtLeast(1));
2536   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(4);
2537   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
2538   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
2539   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
2540 
2541   InjectInitialIdleNotification(group);
2542 
2543   auto* leAudioDevice = group->GetFirstDevice();
2544   auto expected_devices_written = 0;
2545   while (leAudioDevice) {
2546     EXPECT_CALL(gatt_queue,
2547                 WriteCharacteristic(leAudioDevice->conn_id_,
2548                                     leAudioDevice->ctp_hdls_.val_hdl, _,
2549                                     GATT_WRITE_NO_RSP, _, _))
2550         .Times(4);
2551     expected_devices_written++;
2552     leAudioDevice = group->GetNextDevice(leAudioDevice);
2553   }
2554   ASSERT_EQ(expected_devices_written, num_devices);
2555 
2556   // Validate GroupStreamStatus
2557   EXPECT_CALL(
2558       mock_callbacks_,
2559       StatusReportCb(leaudio_group_id,
2560                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
2561 
2562   // Start the configuration and stream Media content
2563   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2564       group, context_type,
2565       {.sink = types::AudioContexts(context_type),
2566        .source = types::AudioContexts(context_type)}));
2567 
2568   // Check if group has transitioned to a proper state
2569   ASSERT_EQ(group->GetState(),
2570             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
2571   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
2572 }
2573 
2574 MATCHER_P(dataPathDirIsEq, expected, "") {
2575   return (arg.data_path_dir == expected);
2576 }
2577 
TEST_F(StateMachineTest,testFailedStreamMultipleConversational)2578 TEST_F(StateMachineTest, testFailedStreamMultipleConversational) {
2579   /* Testing here CIS Failed to be established */
2580   const auto context_type = kContextTypeConversational;
2581   const auto leaudio_group_id = 4;
2582   const auto num_devices = 2;
2583   overwrite_cis_status_ = true;
2584 
2585   cis_status_.resize(2);
2586   cis_status_[0] = 0x00;
2587   cis_status_[1] = 0x0e;  // Failed to be established
2588 
2589   // Prepare multiple fake connected devices in a group
2590   auto* group =
2591       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
2592   ASSERT_EQ(group->Size(), num_devices);
2593 
2594   PrepareConfigureCodecHandler(group);
2595   PrepareConfigureQosHandler(group);
2596   PrepareEnableHandler(group);
2597   PrepareReceiverStartReadyHandler(group);
2598   PrepareReleaseHandler(group);
2599 
2600   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2601   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(AtLeast(1));
2602 
2603   /* Bidirectional CIS data path is configured in tw ocalls and removed for both
2604    * directions with a single call.
2605    */
2606   EXPECT_CALL(*mock_iso_manager_,
2607               SetupIsoDataPath(
2608                   _, dataPathDirIsEq(
2609                          bluetooth::hci::iso_manager::kIsoDataPathDirectionIn)))
2610       .Times(1);
2611   EXPECT_CALL(
2612       *mock_iso_manager_,
2613       SetupIsoDataPath(
2614           _, dataPathDirIsEq(
2615                  bluetooth::hci::iso_manager::kIsoDataPathDirectionOut)))
2616       .Times(1);
2617   EXPECT_CALL(
2618       *mock_iso_manager_,
2619       RemoveIsoDataPath(
2620           _, bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionOutput |
2621                  bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionInput))
2622       .Times(1);
2623 
2624   /* This check is the major one in this test, as we want to make sure,
2625    * it will not be called twice but only once (when both bidirectional ASEs are
2626    * not in the STREAMING or ENABLING state)
2627    */
2628   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(1);
2629 
2630   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
2631 
2632   InjectInitialIdleNotification(group);
2633 
2634   auto* leAudioDevice = group->GetFirstDevice();
2635 
2636   /* First device Control Point actions
2637    * Codec Config
2638    * QoS Config
2639    * Enable
2640    * Receiver ready
2641    * Release
2642    */
2643   EXPECT_CALL(gatt_queue, WriteCharacteristic(leAudioDevice->conn_id_,
2644                                               leAudioDevice->ctp_hdls_.val_hdl,
2645                                               _, GATT_WRITE_NO_RSP, _, _))
2646       .Times(5);
2647   leAudioDevice = group->GetNextDevice(leAudioDevice);
2648 
2649   /* Second device Control Point actions
2650    * Codec Config
2651    * QoS Config
2652    * Enable (failed on CIS established - therefore no Receiver Ready)
2653    * Release
2654    */
2655   EXPECT_CALL(gatt_queue, WriteCharacteristic(leAudioDevice->conn_id_,
2656                                               leAudioDevice->ctp_hdls_.val_hdl,
2657                                               _, GATT_WRITE_NO_RSP, _, _))
2658       .Times(4);
2659 
2660   /* Prepare DisconnectCis mock to not symulate CisDisconnection */
2661   ON_CALL(*mock_iso_manager_, DisconnectCis).WillByDefault(Return());
2662 
2663   // Start the configuration and stream Media content
2664   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2665       group, context_type,
2666       {.sink = types::AudioContexts(context_type),
2667        .source = types::AudioContexts(context_type)}));
2668 
2669   // Check if group has transitioned to a proper state
2670   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
2671 
2672   /* Called twice. One when change target state from Streaming to IDLE,
2673    * and second time, when state machine entered IDLE.
2674    */
2675   ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
2676 }
2677 
TEST_F(StateMachineTest,testAttachToStreamWhileFirstDeviceIsStartingStream)2678 TEST_F(StateMachineTest, testAttachToStreamWhileFirstDeviceIsStartingStream) {
2679   /* Testing here CIS Failed to be established */
2680   const auto context_type = kContextTypeConversational;
2681   const auto leaudio_group_id = 4;
2682   const auto num_devices = 2;
2683 
2684   // Prepare multiple fake connected devices in a group
2685   auto* group =
2686       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
2687   ASSERT_EQ(group->Size(), num_devices);
2688 
2689   PrepareConfigureCodecHandler(group);
2690   PrepareConfigureQosHandler(group);
2691   PrepareEnableHandler(group, 0, true /* inject enabling */,
2692                        false /* inject streaming*/);
2693   PrepareReleaseHandler(group);
2694 
2695   InjectInitialIdleNotification(group);
2696   auto firstDevice = group->GetFirstDevice();
2697   auto lastDevice = group->GetNextDevice(firstDevice);
2698 
2699   /* Disconnect first device */
2700   InjectAclDisconnected(group, firstDevice);
2701 
2702   // Start the configuration and stream Media content
2703   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2704       group, context_type,
2705       {.sink = types::AudioContexts(context_type),
2706        .source = types::AudioContexts(context_type)}));
2707 
2708   // Now, group is not yet in the streaming state. Let's simulated the other
2709   // device got connected
2710   firstDevice->conn_id_ = 1;
2711   firstDevice->SetConnectionState(DeviceConnectState::CONNECTED);
2712 
2713   for (auto& ase : lastDevice->ases_) {
2714     std::vector<uint8_t> params{};
2715     if (ase.active) {
2716       InjectAseStateNotification(&ase, lastDevice, group,
2717                                  ascs::kAseStateStreaming, &params);
2718     }
2719   }
2720 
2721   // Check if group has transitioned to a proper state
2722   ASSERT_EQ(group->GetState(),
2723             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
2724 }
2725 
TEST_F(StateMachineTest,testFailedStreamCreation)2726 TEST_F(StateMachineTest, testFailedStreamCreation) {
2727   /* Testing here different error than CIS Failed to be established */
2728   const auto context_type = kContextTypeConversational;
2729   const auto leaudio_group_id = 4;
2730   const auto num_devices = 2;
2731 
2732   // Prepare multiple fake connected devices in a group
2733   auto* group =
2734       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
2735   ASSERT_EQ(group->Size(), num_devices);
2736 
2737   PrepareConfigureCodecHandler(group);
2738   PrepareConfigureQosHandler(group);
2739   PrepareEnableHandler(group, 0, true /* inject enabling */,
2740                        false /* inject streaming*/);
2741   PrepareReleaseHandler(group);
2742 
2743   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2744   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
2745   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
2746   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
2747   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(2);
2748   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
2749 
2750   /* Prepare DisconnectCis mock to not symulate CisDisconnection */
2751   ON_CALL(*mock_iso_manager_, EstablishCis).WillByDefault(Return());
2752 
2753   InjectInitialIdleNotification(group);
2754 
2755   auto* leAudioDevice = group->GetFirstDevice();
2756 
2757   /* First device Control Point actions
2758    * Codec Config
2759    * QoS Config
2760    * Enable
2761    * Release
2762    */
2763   EXPECT_CALL(gatt_queue, WriteCharacteristic(leAudioDevice->conn_id_,
2764                                               leAudioDevice->ctp_hdls_.val_hdl,
2765                                               _, GATT_WRITE_NO_RSP, _, _))
2766       .Times(4);
2767   leAudioDevice = group->GetNextDevice(leAudioDevice);
2768 
2769   /* Second device Control Point actions
2770    * Codec Config
2771    * QoS Config
2772    * Enable (failed on CIS established - therefore no Receiver Ready)
2773    * Release
2774    */
2775   EXPECT_CALL(gatt_queue, WriteCharacteristic(leAudioDevice->conn_id_,
2776                                               leAudioDevice->ctp_hdls_.val_hdl,
2777                                               _, GATT_WRITE_NO_RSP, _, _))
2778       .Times(4);
2779 
2780   // Start the configuration and stream Media content
2781   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2782       group, context_type,
2783       {.sink = types::AudioContexts(context_type),
2784        .source = types::AudioContexts(context_type)}));
2785 
2786   bluetooth::hci::iso_manager::cis_establish_cmpl_evt evt;
2787   evt.status = HCI_ERR_LMP_RESPONSE_TIMEOUT;
2788 
2789   LeAudioGroupStateMachine::Get()->ProcessHciNotifCisEstablished(
2790       group, leAudioDevice, &evt);
2791 
2792   // Check if group has transitioned to a proper state
2793   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
2794 
2795   /* Called twice. One when change target state from Streaming to IDLE,
2796    * and second time, when state machine entered IDLE.
2797    */
2798   ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
2799 }
2800 
TEST_F(StateMachineTest,remoteRejectsEnable)2801 TEST_F(StateMachineTest, remoteRejectsEnable) {
2802   /* Testing here CIS Failed to be established */
2803   const auto context_type = kContextTypeConversational;
2804   const auto leaudio_group_id = 4;
2805   const auto num_devices = 2;
2806 
2807   // Prepare multiple fake connected devices in a group
2808   auto* group =
2809       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
2810   ASSERT_EQ(group->Size(), num_devices);
2811 
2812   PrepareConfigureCodecHandler(group);
2813   PrepareConfigureQosHandler(group);
2814   PrepareCtpNotificationError(
2815       group, client_parser::ascs::kCtpOpcodeEnable,
2816       client_parser::ascs::kCtpResponseCodeUnspecifiedError,
2817       client_parser::ascs::kCtpResponseNoReason);
2818   PrepareReleaseHandler(group);
2819 
2820   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2821   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
2822   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
2823   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
2824   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
2825   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
2826 
2827   InjectInitialIdleNotification(group);
2828 
2829   auto* leAudioDevice = group->GetFirstDevice();
2830 
2831   /* First device Control Point actions
2832    * Codec Config
2833    * QoS Config
2834    * Enable
2835    * Release
2836    */
2837   EXPECT_CALL(gatt_queue, WriteCharacteristic(leAudioDevice->conn_id_,
2838                                               leAudioDevice->ctp_hdls_.val_hdl,
2839                                               _, GATT_WRITE_NO_RSP, _, _))
2840       .Times(4);
2841   leAudioDevice = group->GetNextDevice(leAudioDevice);
2842 
2843   /* Second device Control Point actions
2844    * Codec Config
2845    * QoS Config
2846    * Release
2847    */
2848   EXPECT_CALL(gatt_queue, WriteCharacteristic(leAudioDevice->conn_id_,
2849                                               leAudioDevice->ctp_hdls_.val_hdl,
2850                                               _, GATT_WRITE_NO_RSP, _, _))
2851       .Times(3);
2852 
2853   // Start the configuration and stream Media content
2854   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2855       group, context_type,
2856       {.sink = types::AudioContexts(context_type),
2857        .source = types::AudioContexts(context_type)}));
2858 
2859   // Check if group has transitioned to a proper state
2860   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
2861   ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
2862 }
2863 
TEST_F(StateMachineTest,testStreamMultiple)2864 TEST_F(StateMachineTest, testStreamMultiple) {
2865   const auto context_type = kContextTypeMedia;
2866   const auto leaudio_group_id = 4;
2867   const auto num_devices = 2;
2868 
2869   // Prepare multiple fake connected devices in a group
2870   auto* group =
2871       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
2872   ASSERT_EQ(group->Size(), num_devices);
2873 
2874   PrepareConfigureCodecHandler(group);
2875   PrepareConfigureQosHandler(group);
2876   PrepareEnableHandler(group);
2877 
2878   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2879   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(AtLeast(1));
2880   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
2881   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
2882   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
2883   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
2884 
2885   InjectInitialIdleNotification(group);
2886 
2887   auto* leAudioDevice = group->GetFirstDevice();
2888   auto expected_devices_written = 0;
2889   while (leAudioDevice) {
2890     EXPECT_CALL(gatt_queue,
2891                 WriteCharacteristic(leAudioDevice->conn_id_,
2892                                     leAudioDevice->ctp_hdls_.val_hdl, _,
2893                                     GATT_WRITE_NO_RSP, _, _))
2894         .Times(AtLeast(3));
2895     expected_devices_written++;
2896     leAudioDevice = group->GetNextDevice(leAudioDevice);
2897   }
2898   ASSERT_EQ(expected_devices_written, num_devices);
2899 
2900   // Validate GroupStreamStatus
2901   EXPECT_CALL(
2902       mock_callbacks_,
2903       StatusReportCb(leaudio_group_id,
2904                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
2905 
2906   // Start the configuration and stream Media content
2907   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2908       group, context_type,
2909       {.sink = types::AudioContexts(context_type),
2910        .source = types::AudioContexts(context_type)}));
2911 
2912   // Check if group has transitioned to a proper state
2913   ASSERT_EQ(group->GetState(),
2914             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
2915   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
2916 }
2917 
TEST_F(StateMachineTest,testUpdateMetadataMultiple)2918 TEST_F(StateMachineTest, testUpdateMetadataMultiple) {
2919   const auto context_type = kContextTypeMedia;
2920   const auto leaudio_group_id = 4;
2921   const auto num_devices = 2;
2922 
2923   auto supported_contexts =
2924       types::AudioContexts(kContextTypeMedia | kContextTypeSoundEffects);
2925 
2926   // Prepare multiple fake connected devices in a group
2927   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type,
2928                                              num_devices, supported_contexts);
2929   ASSERT_EQ(group->Size(), num_devices);
2930 
2931   PrepareConfigureCodecHandler(group);
2932   PrepareConfigureQosHandler(group);
2933   PrepareEnableHandler(group);
2934 
2935   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
2936   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(AtLeast(1));
2937   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
2938   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
2939   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
2940   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
2941 
2942   InjectInitialIdleNotification(group);
2943 
2944   auto* leAudioDevice = group->GetFirstDevice();
2945   auto expected_devices_written = 0;
2946   while (leAudioDevice) {
2947     EXPECT_CALL(gatt_queue,
2948                 WriteCharacteristic(leAudioDevice->conn_id_,
2949                                     leAudioDevice->ctp_hdls_.val_hdl, _,
2950                                     GATT_WRITE_NO_RSP, _, _))
2951         .Times(AtLeast(3));
2952     expected_devices_written++;
2953     leAudioDevice = group->GetNextDevice(leAudioDevice);
2954   }
2955   ASSERT_EQ(expected_devices_written, num_devices);
2956 
2957   // Validate GroupStreamStatus
2958   EXPECT_CALL(
2959       mock_callbacks_,
2960       StatusReportCb(leaudio_group_id,
2961                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
2962 
2963   // Start the configuration and stream Media content
2964   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2965       group, context_type,
2966       {.sink = types::AudioContexts(context_type),
2967        .source = types::AudioContexts(context_type)}));
2968 
2969   testing::Mock::VerifyAndClearExpectations(&gatt_queue);
2970 
2971   // Check if group has transitioned to a proper state
2972   ASSERT_EQ(group->GetState(),
2973             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
2974 
2975   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
2976   reset_mock_function_count_map();
2977 
2978   // Make sure all devices get the metadata update
2979   leAudioDevice = group->GetFirstDevice();
2980   expected_devices_written = 0;
2981   while (leAudioDevice) {
2982     EXPECT_CALL(gatt_queue,
2983                 WriteCharacteristic(leAudioDevice->conn_id_,
2984                                     leAudioDevice->ctp_hdls_.val_hdl, _,
2985                                     GATT_WRITE_NO_RSP, _, _))
2986         .Times(1);
2987     expected_devices_written++;
2988     leAudioDevice = group->GetNextDevice(leAudioDevice);
2989   }
2990   ASSERT_EQ(expected_devices_written, num_devices);
2991 
2992   const auto metadata_context_type =
2993       kContextTypeMedia | kContextTypeSoundEffects;
2994   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
2995       group, context_type,
2996       {.sink = metadata_context_type, .source = metadata_context_type}));
2997 
2998   /* This is just update metadata - watchdog is not used */
2999   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
3000 }
3001 
TEST_F(StateMachineTest,testUpdateMetadataMultiple_NoUpdatesOnKeyTouch)3002 TEST_F(StateMachineTest, testUpdateMetadataMultiple_NoUpdatesOnKeyTouch) {
3003   const auto context_type = kContextTypeMedia;
3004   const auto leaudio_group_id = 4;
3005   const auto num_devices = 2;
3006 
3007   /* Only Media is supported and available, */
3008   auto supported_contexts = types::AudioContexts(kContextTypeMedia);
3009 
3010   // Prepare multiple fake connected devices in a group
3011   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type,
3012                                              num_devices, supported_contexts);
3013   ASSERT_EQ(group->Size(), num_devices);
3014 
3015   PrepareConfigureCodecHandler(group);
3016   PrepareConfigureQosHandler(group);
3017   PrepareEnableHandler(group);
3018 
3019   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
3020   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(AtLeast(1));
3021   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
3022   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
3023   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
3024   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
3025 
3026   InjectInitialIdleNotification(group);
3027 
3028   auto* leAudioDevice = group->GetFirstDevice();
3029   auto expected_devices_written = 0;
3030   while (leAudioDevice) {
3031     EXPECT_CALL(gatt_queue,
3032                 WriteCharacteristic(leAudioDevice->conn_id_,
3033                                     leAudioDevice->ctp_hdls_.val_hdl, _,
3034                                     GATT_WRITE_NO_RSP, _, _))
3035         .Times(AtLeast(3));
3036     expected_devices_written++;
3037     leAudioDevice = group->GetNextDevice(leAudioDevice);
3038   }
3039   ASSERT_EQ(expected_devices_written, num_devices);
3040 
3041   // Validate GroupStreamStatus
3042   EXPECT_CALL(
3043       mock_callbacks_,
3044       StatusReportCb(leaudio_group_id,
3045                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
3046 
3047   // Start the configuration and stream Media content
3048   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
3049       group, context_type,
3050       {.sink = types::AudioContexts(context_type),
3051        .source = types::AudioContexts(context_type)}));
3052 
3053   testing::Mock::VerifyAndClearExpectations(&gatt_queue);
3054 
3055   // Check if group has transitioned to a proper state
3056   ASSERT_EQ(group->GetState(),
3057             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
3058 
3059   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3060   reset_mock_function_count_map();
3061 
3062   // Make sure all devices get the metadata update
3063   leAudioDevice = group->GetFirstDevice();
3064   expected_devices_written = 0;
3065   while (leAudioDevice) {
3066     EXPECT_CALL(gatt_queue,
3067                 WriteCharacteristic(leAudioDevice->conn_id_,
3068                                     leAudioDevice->ctp_hdls_.val_hdl, _,
3069                                     GATT_WRITE_NO_RSP, _, _))
3070         .Times(0);
3071     expected_devices_written++;
3072     leAudioDevice = group->GetNextDevice(leAudioDevice);
3073   }
3074   ASSERT_EQ(expected_devices_written, num_devices);
3075 
3076   const auto metadata_context_type =
3077       kContextTypeMedia | kContextTypeSoundEffects;
3078   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
3079       group, context_type,
3080       {.sink = metadata_context_type, .source = metadata_context_type}));
3081 
3082   /* This is just update metadata - watchdog is not used */
3083   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
3084 }
3085 
TEST_F(StateMachineTest,testDisableSingle)3086 TEST_F(StateMachineTest, testDisableSingle) {
3087   /* Device is banded headphones with 2x snk + 0x src ase
3088    * (2xunidirectional CIS)
3089    */
3090   additional_snk_ases = 1;
3091   const auto context_type = kContextTypeRingtone;
3092   const int leaudio_group_id = 4;
3093 
3094   // Prepare fake connected device group
3095   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
3096 
3097   /* Ringtone context plus additional ASE with channel count 1
3098    * gives us 2 ASE which should have been configured.
3099    */
3100   PrepareConfigureCodecHandler(group, 2);
3101   PrepareConfigureQosHandler(group, 2);
3102   PrepareEnableHandler(group, 2);
3103   PrepareDisableHandler(group, 2);
3104 
3105   auto* leAudioDevice = group->GetFirstDevice();
3106   EXPECT_CALL(gatt_queue,
3107               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
3108                                   GATT_WRITE_NO_RSP, _, _))
3109       .Times(4);
3110 
3111   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
3112   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
3113   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
3114   EXPECT_CALL(
3115       *mock_iso_manager_,
3116       RemoveIsoDataPath(
3117           _, bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionInput))
3118       .Times(2);
3119   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(2);
3120   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
3121 
3122   InjectInitialIdleNotification(group);
3123 
3124   EXPECT_CALL(
3125       mock_callbacks_,
3126       StatusReportCb(leaudio_group_id,
3127                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
3128 
3129   // Start the configuration and stream Media content
3130   LeAudioGroupStateMachine::Get()->StartStream(
3131       group, context_type,
3132       {.sink = types::AudioContexts(context_type),
3133        .source = types::AudioContexts(context_type)});
3134 
3135   // Check if group has transitioned to a proper state
3136   ASSERT_EQ(group->GetState(),
3137             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
3138 
3139   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
3140   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3141   reset_mock_function_count_map();
3142 
3143   // Validate GroupStreamStatus
3144   EXPECT_CALL(
3145       mock_callbacks_,
3146       StatusReportCb(leaudio_group_id,
3147                      bluetooth::le_audio::GroupStreamStatus::SUSPENDING));
3148   EXPECT_CALL(
3149       mock_callbacks_,
3150       StatusReportCb(leaudio_group_id,
3151                      bluetooth::le_audio::GroupStreamStatus::SUSPENDED));
3152 
3153   // Suspend the stream
3154   LeAudioGroupStateMachine::Get()->SuspendStream(group);
3155 
3156   // Check if group has transition to a proper state
3157   ASSERT_EQ(group->GetState(),
3158             types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED);
3159 
3160   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
3161   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3162 }
3163 
TEST_F(StateMachineTest,testDisableMultiple)3164 TEST_F(StateMachineTest, testDisableMultiple) {
3165   const auto context_type = kContextTypeMedia;
3166   const auto leaudio_group_id = 4;
3167   const auto num_devices = 2;
3168 
3169   // Prepare multiple fake connected devices in a group
3170   auto* group =
3171       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
3172   ASSERT_EQ(group->Size(), num_devices);
3173 
3174   PrepareConfigureCodecHandler(group);
3175   PrepareConfigureQosHandler(group);
3176   PrepareEnableHandler(group);
3177   PrepareDisableHandler(group);
3178 
3179   auto* leAudioDevice = group->GetFirstDevice();
3180   auto expected_devices_written = 0;
3181   while (leAudioDevice) {
3182     EXPECT_CALL(gatt_queue,
3183                 WriteCharacteristic(leAudioDevice->conn_id_,
3184                                     leAudioDevice->ctp_hdls_.val_hdl, _,
3185                                     GATT_WRITE_NO_RSP, _, _))
3186         .Times(AtLeast(4));
3187     expected_devices_written++;
3188     leAudioDevice = group->GetNextDevice(leAudioDevice);
3189   }
3190   ASSERT_EQ(expected_devices_written, num_devices);
3191 
3192   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
3193   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
3194   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
3195   EXPECT_CALL(
3196       *mock_iso_manager_,
3197       RemoveIsoDataPath(
3198           _, bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionInput))
3199       .Times(2);
3200   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(2);
3201   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
3202 
3203   InjectInitialIdleNotification(group);
3204 
3205   // Start the configuration and stream Media content
3206   LeAudioGroupStateMachine::Get()->StartStream(
3207       group, context_type,
3208       {.sink = types::AudioContexts(context_type),
3209        .source = types::AudioContexts(context_type)});
3210 
3211   // Check if group has transitioned to a proper state
3212   ASSERT_EQ(group->GetState(),
3213             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
3214   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3215   reset_mock_function_count_map();
3216 
3217   // Validate GroupStreamStatus
3218   EXPECT_CALL(
3219       mock_callbacks_,
3220       StatusReportCb(leaudio_group_id,
3221                      bluetooth::le_audio::GroupStreamStatus::SUSPENDING));
3222   EXPECT_CALL(
3223       mock_callbacks_,
3224       StatusReportCb(leaudio_group_id,
3225                      bluetooth::le_audio::GroupStreamStatus::SUSPENDED));
3226 
3227   // Suspend the stream
3228   LeAudioGroupStateMachine::Get()->SuspendStream(group);
3229 
3230   // Check if group has transitioned to a proper state
3231   ASSERT_EQ(group->GetState(),
3232             types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED);
3233   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
3234   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3235 }
3236 
TEST_F(StateMachineTest,testDisableBidirectional)3237 TEST_F(StateMachineTest, testDisableBidirectional) {
3238   /* Device is banded headphones with 2x snk + 1x src ase
3239    * (1x bidirectional + 1xunidirectional CIS)
3240    */
3241   additional_snk_ases = 1;
3242   const auto context_type = kContextTypeConversational;
3243   const int leaudio_group_id = 4;
3244 
3245   // Prepare fake connected device group
3246   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
3247 
3248   /* Since we prepared device with Conversional context in mind, Sink and Source
3249    * ASEs should have been configured.
3250    */
3251   PrepareConfigureCodecHandler(group, 3);
3252   PrepareConfigureQosHandler(group, 3);
3253   PrepareEnableHandler(group, 3);
3254   PrepareDisableHandler(group, 3);
3255   PrepareReceiverStartReadyHandler(group, 1);
3256   PrepareReceiverStopReady(group, 1);
3257 
3258   auto* leAudioDevice = group->GetFirstDevice();
3259   EXPECT_CALL(gatt_queue,
3260               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
3261                                   GATT_WRITE_NO_RSP, _, _))
3262       .Times(AtLeast(4));
3263 
3264   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
3265   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
3266   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(3);
3267   bool removed_bidirectional = false;
3268   bool removed_unidirectional = false;
3269 
3270   /* Check data path removal */
3271   ON_CALL(*mock_iso_manager_, RemoveIsoDataPath)
3272       .WillByDefault(Invoke([&removed_bidirectional, &removed_unidirectional,
3273                              this](uint16_t conn_handle,
3274                                    uint8_t data_path_dir) {
3275         /* Set flags for verification */
3276         if (data_path_dir ==
3277             (bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionInput |
3278              bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionOutput)) {
3279           removed_bidirectional = true;
3280         } else if (data_path_dir == bluetooth::hci::iso_manager::
3281                                         kRemoveIsoDataPathDirectionInput) {
3282           removed_unidirectional = true;
3283         }
3284 
3285         /* Copied from default handler of RemoveIsoDataPath*/
3286         auto dev_it =
3287             std::find_if(le_audio_devices_.begin(), le_audio_devices_.end(),
3288                          [&conn_handle](auto& dev) {
3289                            auto ases = dev->GetAsesByCisConnHdl(conn_handle);
3290                            return (ases.sink || ases.source);
3291                          });
3292         if (dev_it == le_audio_devices_.end()) {
3293           return;
3294         }
3295 
3296         for (auto& kv_pair : le_audio_device_groups_) {
3297           auto& group = kv_pair.second;
3298           if (group->IsDeviceInTheGroup(dev_it->get())) {
3299             LeAudioGroupStateMachine::Get()->ProcessHciNotifRemoveIsoDataPath(
3300                 group.get(), dev_it->get(), 0, conn_handle);
3301             return;
3302           }
3303         }
3304         /* End of copy */
3305       }));
3306 
3307   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(2);
3308   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
3309 
3310   // Start the configuration and stream Media content
3311   LeAudioGroupStateMachine::Get()->StartStream(
3312       group, context_type,
3313       {.sink = types::AudioContexts(context_type),
3314        .source = types::AudioContexts(context_type)});
3315 
3316   // Check if group has transitioned to a proper state
3317   ASSERT_EQ(group->GetState(),
3318             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
3319 
3320   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3321   reset_mock_function_count_map();
3322 
3323   // Validate GroupStreamStatus
3324   EXPECT_CALL(
3325       mock_callbacks_,
3326       StatusReportCb(leaudio_group_id,
3327                      bluetooth::le_audio::GroupStreamStatus::SUSPENDING));
3328   EXPECT_CALL(
3329       mock_callbacks_,
3330       StatusReportCb(leaudio_group_id,
3331                      bluetooth::le_audio::GroupStreamStatus::SUSPENDED));
3332 
3333   // Suspend the stream
3334   LeAudioGroupStateMachine::Get()->SuspendStream(group);
3335 
3336   // Check if group has transitioned to a proper state
3337   ASSERT_EQ(group->GetState(),
3338             types::AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED);
3339   ASSERT_EQ(removed_bidirectional, true);
3340   ASSERT_EQ(removed_unidirectional, true);
3341 
3342   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
3343   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3344 }
3345 
TEST_F(StateMachineTest,testReleaseSingle)3346 TEST_F(StateMachineTest, testReleaseSingle) {
3347   /* Device is banded headphones with 1x snk + 0x src ase
3348    * (1xunidirectional CIS) with channel count 2 (for stereo)
3349    */
3350   const auto context_type = kContextTypeRingtone;
3351   const int leaudio_group_id = 4;
3352   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
3353                    kLeAudioCodecChannelCountTwoChannel;
3354 
3355   // Prepare fake connected device group
3356   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
3357 
3358   /* Since we prepared device with Ringtone context in mind, only one ASE
3359    * should have been configured.
3360    */
3361   PrepareConfigureCodecHandler(group, 1);
3362   PrepareConfigureQosHandler(group, 1);
3363   PrepareEnableHandler(group, 1);
3364   PrepareDisableHandler(group, 1);
3365   PrepareReleaseHandler(group, 1);
3366 
3367   auto* leAudioDevice = group->GetFirstDevice();
3368   EXPECT_CALL(gatt_queue,
3369               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
3370                                   GATT_WRITE_NO_RSP, _, _))
3371       .Times(4);
3372 
3373   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
3374   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
3375   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
3376   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(1);
3377   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(1);
3378   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
3379 
3380   InjectInitialIdleNotification(group);
3381 
3382   // Start the configuration and stream Media content
3383   LeAudioGroupStateMachine::Get()->StartStream(
3384       group, context_type,
3385       {.sink = types::AudioContexts(context_type),
3386        .source = types::AudioContexts(context_type)});
3387 
3388   // Check if group has transitioned to a proper state
3389   ASSERT_EQ(group->GetState(),
3390             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
3391   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3392   reset_mock_function_count_map();
3393   // Validate GroupStreamStatus
3394   EXPECT_CALL(
3395       mock_callbacks_,
3396       StatusReportCb(leaudio_group_id,
3397                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
3398   EXPECT_CALL(mock_callbacks_,
3399               StatusReportCb(leaudio_group_id,
3400                              bluetooth::le_audio::GroupStreamStatus::IDLE));
3401 
3402   // Stop the stream
3403   LeAudioGroupStateMachine::Get()->StopStream(group);
3404 
3405   // Check if group has transitioned to a proper state
3406   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
3407   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3408 }
3409 
TEST_F(StateMachineTest,testReleaseCachingSingle)3410 TEST_F(StateMachineTest, testReleaseCachingSingle) {
3411   /* Device is banded headphones with 1x snk + 0x src ase
3412    * (1xunidirectional CIS)
3413    */
3414   const auto context_type = kContextTypeRingtone;
3415   const int leaudio_group_id = 4;
3416   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
3417                    kLeAudioCodecChannelCountTwoChannel;
3418 
3419   // Prepare fake connected device group
3420   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
3421 
3422   /* Since we prepared device with Ringtone context in mind, only one ASE
3423    * should have been configured.
3424    */
3425   PrepareConfigureCodecHandler(group, 1, true);
3426   PrepareConfigureQosHandler(group, 1);
3427   PrepareEnableHandler(group, 1);
3428   PrepareDisableHandler(group, 1);
3429   PrepareReleaseHandler(group, 1);
3430 
3431   auto* leAudioDevice = group->GetFirstDevice();
3432   EXPECT_CALL(gatt_queue,
3433               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
3434                                   GATT_WRITE_NO_RSP, _, _))
3435       .Times(4);
3436 
3437   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
3438   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
3439   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
3440   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(1);
3441   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(1);
3442   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
3443 
3444   InjectInitialIdleNotification(group);
3445 
3446   // Validate GroupStreamStatus
3447   EXPECT_CALL(
3448       mock_callbacks_,
3449       StatusReportCb(leaudio_group_id,
3450                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
3451 
3452   EXPECT_CALL(
3453       mock_callbacks_,
3454       StatusReportCb(
3455           leaudio_group_id,
3456           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS));
3457   EXPECT_CALL(
3458       mock_callbacks_,
3459       StatusReportCb(leaudio_group_id,
3460                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
3461 
3462   // Start the configuration and stream Media content
3463   LeAudioGroupStateMachine::Get()->StartStream(
3464       group, context_type,
3465       {.sink = types::AudioContexts(context_type),
3466        .source = types::AudioContexts(context_type)});
3467 
3468   // Check if group has transitioned to a proper state
3469   ASSERT_EQ(group->GetState(),
3470             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
3471 
3472   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3473   reset_mock_function_count_map();
3474 
3475   // Stop the stream
3476   LeAudioGroupStateMachine::Get()->StopStream(group);
3477 
3478   // Check if group has transitioned to a proper state
3479   ASSERT_EQ(group->GetState(),
3480             types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
3481 
3482   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3483 }
3484 
TEST_F(StateMachineTest,testStreamCaching_NoReconfigurationNeeded_SingleDevice)3485 TEST_F(StateMachineTest,
3486        testStreamCaching_NoReconfigurationNeeded_SingleDevice) {
3487   const auto context_type = kContextTypeRingtone;
3488   const int leaudio_group_id = 4;
3489   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
3490                    kLeAudioCodecChannelCountTwoChannel;
3491 
3492   additional_snk_ases = 2;
3493   // Prepare fake connected device group
3494   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
3495 
3496   /* Since we prepared device with Ringtone context in mind and with no Source
3497    * ASEs, therefor only one ASE should have been configured.
3498    */
3499   PrepareConfigureCodecHandler(group, 1, true);
3500   PrepareConfigureQosHandler(group, 1, true);
3501   PrepareEnableHandler(group, 1);
3502   PrepareDisableHandler(group, 1);
3503   PrepareReleaseHandler(group, 1);
3504 
3505   /* Ctp messages we expect:
3506    * 1. Codec Config
3507    * 2. QoS Config
3508    * 3. Enable
3509    * 4. Release
3510    * 5. QoS Config (because device stays in Configured state)
3511    * 6. Enable
3512    */
3513   auto* leAudioDevice = group->GetFirstDevice();
3514   EXPECT_CALL(gatt_queue,
3515               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
3516                                   GATT_WRITE_NO_RSP, _, _))
3517       .Times(6);
3518 
3519   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(2);
3520   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(2);
3521   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
3522   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(1);
3523   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(1);
3524   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
3525 
3526   InjectInitialIdleNotification(group);
3527 
3528   // Validate GroupStreamStatus
3529   EXPECT_CALL(
3530       mock_callbacks_,
3531       StatusReportCb(leaudio_group_id,
3532                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
3533 
3534   EXPECT_CALL(
3535       mock_callbacks_,
3536       StatusReportCb(
3537           leaudio_group_id,
3538           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS));
3539 
3540   EXPECT_CALL(mock_callbacks_,
3541               StatusReportCb(leaudio_group_id,
3542                              bluetooth::le_audio::GroupStreamStatus::STREAMING))
3543       .Times(2);
3544 
3545   // Start the configuration and stream Ringtone content
3546   LeAudioGroupStateMachine::Get()->StartStream(
3547       group, context_type,
3548       {.sink = types::AudioContexts(context_type),
3549        .source = types::AudioContexts(context_type)});
3550 
3551   // Check if group has transitioned to a proper state
3552   ASSERT_EQ(group->GetState(),
3553             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
3554 
3555   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3556   reset_mock_function_count_map();
3557 
3558   // Stop the stream
3559   LeAudioGroupStateMachine::Get()->StopStream(group);
3560 
3561   // Check if group has transitioned to a proper state
3562   ASSERT_EQ(group->GetState(),
3563             types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
3564 
3565   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3566   reset_mock_function_count_map();
3567 
3568   // Start the configuration and stream Media content
3569   LeAudioGroupStateMachine::Get()->StartStream(
3570       group, context_type,
3571       {.sink = types::AudioContexts(context_type),
3572        .source = types::AudioContexts(context_type)});
3573 
3574   // Check if group has transitioned to a proper state
3575   ASSERT_EQ(group->GetState(),
3576             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
3577 
3578   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3579   reset_mock_function_count_map();
3580 }
3581 
TEST_F(StateMachineTest,test_StreamCaching_ReconfigureForContextChange_SingleDevice)3582 TEST_F(StateMachineTest,
3583        test_StreamCaching_ReconfigureForContextChange_SingleDevice) {
3584   auto context_type = kContextTypeConversational;
3585   const int leaudio_group_id = 4;
3586   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
3587                    kLeAudioCodecChannelCountTwoChannel;
3588 
3589   additional_snk_ases = 2;
3590   /* Prepare fake connected device group with update of Media and Conversational
3591    * contexts
3592    */
3593   auto* group = PrepareSingleTestDeviceGroup(
3594       leaudio_group_id, context_type, 1,
3595       kContextTypeConversational | kContextTypeMedia);
3596 
3597   /* Don't validate ASE here, as after reconfiguration different ASE number
3598    * will be used.
3599    * For the first configuration (CONVERSTATIONAL) there will be 2 ASEs (Sink
3600    * and Source) After reconfiguration (MEDIA) there will be single ASE.
3601    */
3602   PrepareConfigureCodecHandler(group, 0, true);
3603   PrepareConfigureQosHandler(group, 0, true);
3604   PrepareEnableHandler(group);
3605   PrepareReceiverStartReadyHandler(group);
3606   PrepareReleaseHandler(group);
3607 
3608   /* Ctp messages we expect:
3609    * 1. Codec Config
3610    * 2. QoS Config
3611    * 3. Enable
3612    * 4. Release
3613    * 5. Codec Config
3614    * 6. QoS Config
3615    * 7. Enable
3616    */
3617   auto* leAudioDevice = group->GetFirstDevice();
3618   EXPECT_CALL(gatt_queue,
3619               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
3620                                   GATT_WRITE_NO_RSP, _, _))
3621       .Times(8);
3622 
3623   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(2);
3624   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(2);
3625 
3626   /* 2 times for first configuration (1 Sink, 1 Source), 1 time for second
3627    * configuration (1 Sink)*/
3628   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(3);
3629 
3630   uint8_t value =
3631       bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionOutput |
3632       bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionInput;
3633   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, value)).Times(1);
3634   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(1);
3635   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
3636 
3637   InjectInitialIdleNotification(group);
3638 
3639   // Validate GroupStreamStatus
3640   EXPECT_CALL(
3641       mock_callbacks_,
3642       StatusReportCb(leaudio_group_id,
3643                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
3644 
3645   EXPECT_CALL(
3646       mock_callbacks_,
3647       StatusReportCb(
3648           leaudio_group_id,
3649           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS));
3650 
3651   EXPECT_CALL(mock_callbacks_,
3652               StatusReportCb(leaudio_group_id,
3653                              bluetooth::le_audio::GroupStreamStatus::STREAMING))
3654       .Times(2);
3655 
3656   // Start the configuration and stream Conversational content
3657   LeAudioGroupStateMachine::Get()->StartStream(
3658       group, context_type,
3659       {.sink = types::AudioContexts(context_type),
3660        .source = types::AudioContexts(context_type)});
3661 
3662   // Check if group has transitioned to a proper state
3663   ASSERT_EQ(group->GetState(),
3664             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
3665 
3666   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3667   reset_mock_function_count_map();
3668 
3669   // Stop the stream
3670   LeAudioGroupStateMachine::Get()->StopStream(group);
3671 
3672   // Check if group has transitioned to a proper state
3673   ASSERT_EQ(group->GetState(),
3674             types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
3675 
3676   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3677   reset_mock_function_count_map();
3678 
3679   // Start the configuration and stream Media content
3680   context_type = kContextTypeMedia;
3681   LeAudioGroupStateMachine::Get()->StartStream(
3682       group, context_type,
3683       {.sink = types::AudioContexts(context_type),
3684        .source = types::AudioContexts(context_type)});
3685 
3686   // Check if group has transitioned to a proper state
3687   ASSERT_EQ(group->GetState(),
3688             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
3689   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3690 }
3691 
TEST_F(StateMachineTest,testReleaseMultiple)3692 TEST_F(StateMachineTest, testReleaseMultiple) {
3693   const auto context_type = kContextTypeMedia;
3694   const auto leaudio_group_id = 6;
3695   const auto num_devices = 2;
3696 
3697   // Prepare multiple fake connected devices in a group
3698   auto* group =
3699       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
3700   ASSERT_EQ(group->Size(), num_devices);
3701 
3702   PrepareConfigureCodecHandler(group);
3703   PrepareConfigureQosHandler(group);
3704   PrepareEnableHandler(group);
3705   PrepareDisableHandler(group);
3706   PrepareReleaseHandler(group);
3707 
3708   auto* leAudioDevice = group->GetFirstDevice();
3709   auto expected_devices_written = 0;
3710   while (leAudioDevice) {
3711     EXPECT_CALL(gatt_queue,
3712                 WriteCharacteristic(leAudioDevice->conn_id_,
3713                                     leAudioDevice->ctp_hdls_.val_hdl, _,
3714                                     GATT_WRITE_NO_RSP, _, _))
3715         .Times(AtLeast(4));
3716     expected_devices_written++;
3717     leAudioDevice = group->GetNextDevice(leAudioDevice);
3718   }
3719   ASSERT_EQ(expected_devices_written, num_devices);
3720 
3721   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
3722   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
3723   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
3724   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(2);
3725   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(2);
3726   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
3727 
3728   InjectInitialIdleNotification(group);
3729 
3730   EXPECT_CALL(mock_callbacks_,
3731               StatusReportCb(leaudio_group_id,
3732                              bluetooth::le_audio::GroupStreamStatus::STREAMING))
3733       .Times(1);
3734 
3735   // Start the configuration and stream Media content
3736   LeAudioGroupStateMachine::Get()->StartStream(
3737       group, context_type,
3738       {.sink = types::AudioContexts(context_type),
3739        .source = types::AudioContexts(context_type)});
3740 
3741   // Check if group has transitioned to a proper state
3742   ASSERT_EQ(group->GetState(),
3743             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
3744 
3745   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3746   reset_mock_function_count_map();
3747 
3748   // Validate GroupStreamStatus
3749   EXPECT_CALL(
3750       mock_callbacks_,
3751       StatusReportCb(leaudio_group_id,
3752                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
3753   EXPECT_CALL(mock_callbacks_,
3754               StatusReportCb(leaudio_group_id,
3755                              bluetooth::le_audio::GroupStreamStatus::IDLE));
3756   EXPECT_CALL(mock_callbacks_,
3757               StatusReportCb(leaudio_group_id,
3758                              bluetooth::le_audio::GroupStreamStatus::STREAMING))
3759       .Times(0);
3760 
3761   // Stop the stream
3762   LeAudioGroupStateMachine::Get()->StopStream(group);
3763 
3764   // Check if group has transitioned to a proper state
3765   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
3766   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3767 }
3768 
TEST_F(StateMachineTest,testReleaseMultiple_DeviceDisconnectedDuringRelease)3769 TEST_F(StateMachineTest, testReleaseMultiple_DeviceDisconnectedDuringRelease) {
3770   const auto context_type = kContextTypeMedia;
3771   const auto leaudio_group_id = 6;
3772   const auto num_devices = 2;
3773 
3774   // Prepare multiple fake connected devices in a group
3775   auto* group =
3776       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
3777   ASSERT_EQ(group->Size(), num_devices);
3778 
3779   PrepareConfigureCodecHandler(group);
3780   PrepareConfigureQosHandler(group);
3781   PrepareEnableHandler(group);
3782   PrepareDisableHandler(group);
3783 
3784   /* Here we inject device disconnection during release */
3785   PrepareReleaseHandler(group, 0, true);
3786 
3787   auto* leAudioDevice = group->GetFirstDevice();
3788   auto expected_devices_written = 0;
3789   while (leAudioDevice) {
3790     EXPECT_CALL(gatt_queue,
3791                 WriteCharacteristic(leAudioDevice->conn_id_,
3792                                     leAudioDevice->ctp_hdls_.val_hdl, _,
3793                                     GATT_WRITE_NO_RSP, _, _))
3794         .Times(AtLeast(4));
3795     expected_devices_written++;
3796     leAudioDevice = group->GetNextDevice(leAudioDevice);
3797   }
3798   ASSERT_EQ(expected_devices_written, num_devices);
3799 
3800   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
3801   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
3802   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
3803   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
3804   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
3805 
3806   InjectInitialIdleNotification(group);
3807 
3808   EXPECT_CALL(mock_callbacks_,
3809               StatusReportCb(leaudio_group_id,
3810                              bluetooth::le_audio::GroupStreamStatus::STREAMING))
3811       .Times(1);
3812 
3813   // Start the configuration and stream Media content
3814   LeAudioGroupStateMachine::Get()->StartStream(
3815       group, context_type,
3816       {.sink = types::AudioContexts(context_type),
3817        .source = types::AudioContexts(context_type)});
3818 
3819   // Check if group has transitioned to a proper state
3820   ASSERT_EQ(group->GetState(),
3821             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
3822 
3823   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3824   reset_mock_function_count_map();
3825 
3826   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
3827 
3828   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
3829   // Validate GroupStreamStatus
3830   EXPECT_CALL(
3831       mock_callbacks_,
3832       StatusReportCb(leaudio_group_id,
3833                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
3834   EXPECT_CALL(mock_callbacks_,
3835               StatusReportCb(leaudio_group_id,
3836                              bluetooth::le_audio::GroupStreamStatus::IDLE));
3837   EXPECT_CALL(mock_callbacks_,
3838               StatusReportCb(leaudio_group_id,
3839                              bluetooth::le_audio::GroupStreamStatus::STREAMING))
3840       .Times(0);
3841 
3842   // Stop the stream
3843   LeAudioGroupStateMachine::Get()->StopStream(group);
3844 
3845   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
3846 
3847   // Check if group has transitioned to a proper state
3848   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
3849   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3850 }
3851 
TEST_F(StateMachineTest,testReleaseBidirectional)3852 TEST_F(StateMachineTest, testReleaseBidirectional) {
3853   /* Device is banded headphones with 2x snk + 1x src ase
3854    * (1x bidirectional + 1xunidirectional CIS)
3855    */
3856   additional_snk_ases = 1;
3857   const auto context_type = kContextTypeConversational;
3858   const auto leaudio_group_id = 6;
3859 
3860   // Prepare fake connected device group
3861   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
3862 
3863   /* Since we prepared device with Conversional context in mind, Sink and Source
3864    * ASEs should have been configured.
3865    */
3866   PrepareConfigureCodecHandler(group, 3);
3867   PrepareConfigureQosHandler(group, 3);
3868   PrepareEnableHandler(group, 3);
3869   PrepareDisableHandler(group, 3);
3870   PrepareReceiverStartReadyHandler(group, 1);
3871   PrepareReleaseHandler(group, 3);
3872 
3873   auto* leAudioDevice = group->GetFirstDevice();
3874   EXPECT_CALL(gatt_queue,
3875               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
3876                                   GATT_WRITE_NO_RSP, _, _))
3877       .Times(AtLeast(4));
3878 
3879   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
3880   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
3881   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(3);
3882   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(2);
3883   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(2);
3884   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
3885 
3886   InjectInitialIdleNotification(group);
3887 
3888   // Start the configuration and stream Media content
3889   LeAudioGroupStateMachine::Get()->StartStream(
3890       group, context_type,
3891       {.sink = types::AudioContexts(context_type),
3892        .source = types::AudioContexts(context_type)});
3893 
3894   // Check if group has transitioned to a proper state
3895   ASSERT_EQ(group->GetState(),
3896             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
3897 
3898   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3899   reset_mock_function_count_map();
3900 
3901   // Stop the stream
3902   LeAudioGroupStateMachine::Get()->StopStream(group);
3903 
3904   // Check if group has transitioned to a proper state
3905   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
3906   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
3907   reset_mock_function_count_map();
3908 }
3909 
TEST_F(StateMachineTest,testDisableAndReleaseBidirectional)3910 TEST_F(StateMachineTest, testDisableAndReleaseBidirectional) {
3911   /* Device is banded headphones with 2x snk + 1x src ase
3912    * (1x bidirectional + 1xunidirectional CIS)
3913    */
3914   additional_snk_ases = 1;
3915   const auto context_type = kContextTypeConversational;
3916   const int leaudio_group_id = 4;
3917 
3918   // Prepare fake connected device group
3919   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
3920 
3921   /* Since we prepared device with Conversional context in mind, Sink and Source
3922    * ASEs should have been configured.
3923    */
3924   PrepareConfigureCodecHandler(group, 3);
3925   PrepareConfigureQosHandler(group, 3);
3926   PrepareEnableHandler(group, 3);
3927   PrepareDisableHandler(group, 3);
3928   PrepareReceiverStartReadyHandler(group, 1);
3929   PrepareReceiverStopReady(group, 1);
3930   PrepareReleaseHandler(group, 3);
3931 
3932   auto* leAudioDevice = group->GetFirstDevice();
3933   EXPECT_CALL(gatt_queue,
3934               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
3935                                   GATT_WRITE_NO_RSP, _, _))
3936       .Times(AtLeast(4));
3937 
3938   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
3939   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
3940   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(3);
3941   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(2);
3942   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(2);
3943   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
3944 
3945   // Start the configuration and stream Media content
3946   LeAudioGroupStateMachine::Get()->StartStream(
3947       group, context_type,
3948       {.sink = types::AudioContexts(context_type),
3949        .source = types::AudioContexts(context_type)});
3950 
3951   // Suspend the stream
3952   LeAudioGroupStateMachine::Get()->SuspendStream(group);
3953 
3954   // Stop the stream
3955   LeAudioGroupStateMachine::Get()->StopStream(group);
3956 
3957   // Check if group has transitioned to a proper state
3958   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
3959 }
3960 
TEST_F(StateMachineTest,testAseIdAssignmentIdle)3961 TEST_F(StateMachineTest, testAseIdAssignmentIdle) {
3962   const auto context_type = kContextTypeConversational;
3963   const auto leaudio_group_id = 6;
3964   const auto num_devices = 1;
3965 
3966   // Prepare multiple fake connected devices in a group
3967   auto* group =
3968       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
3969   ASSERT_EQ(group->Size(), num_devices);
3970 
3971   // Should not trigger any action on our side
3972   EXPECT_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _)).Times(0);
3973   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(0);
3974   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
3975   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
3976   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
3977   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
3978   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
3979 
3980   for (auto* device = group->GetFirstDevice(); device != nullptr;
3981        device = group->GetNextDevice(device)) {
3982     for (auto& ase : device->ases_) {
3983       ASSERT_EQ(ase.id, bluetooth::le_audio::types::ase::kAseIdInvalid);
3984       InjectAseStateNotification(&ase, device, group, ascs::kAseStateIdle,
3985                                  nullptr);
3986       ASSERT_EQ(ase.id, ase_id_last_assigned);
3987     }
3988   }
3989 }
3990 
TEST_F(StateMachineTest,testAseIdAssignmentCodecConfigured)3991 TEST_F(StateMachineTest, testAseIdAssignmentCodecConfigured) {
3992   const auto context_type = kContextTypeConversational;
3993   const auto leaudio_group_id = 6;
3994   const auto num_devices = 1;
3995 
3996   // Prepare multiple fake connected devices in a group
3997   auto* group =
3998       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
3999   ASSERT_EQ(group->Size(), num_devices);
4000 
4001   // Should not trigger any action on our side
4002   EXPECT_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _)).Times(0);
4003   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(0);
4004   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
4005   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
4006   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0);
4007   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
4008   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
4009 
4010   for (auto* device = group->GetFirstDevice(); device != nullptr;
4011        device = group->GetNextDevice(device)) {
4012     for (auto& ase : device->ases_) {
4013       client_parser::ascs::ase_codec_configured_state_params
4014           codec_configured_state_params;
4015 
4016       ASSERT_EQ(ase.id, bluetooth::le_audio::types::ase::kAseIdInvalid);
4017       InjectAseStateNotification(&ase, device, group,
4018                                  ascs::kAseStateCodecConfigured,
4019                                  &codec_configured_state_params);
4020       ASSERT_EQ(ase.id, ase_id_last_assigned);
4021     }
4022   }
4023 }
4024 
TEST_F(StateMachineTest,testAseAutonomousRelease)4025 TEST_F(StateMachineTest, testAseAutonomousRelease) {
4026   /* Device is banded headphones with 2x snk + 1x src ase
4027    * (1x bidirectional + 1xunidirectional CIS)
4028    */
4029   additional_snk_ases = 1;
4030   const auto context_type = kContextTypeConversational;
4031   const int leaudio_group_id = 4;
4032 
4033   // Prepare fake connected device group
4034   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
4035 
4036   /* Since we prepared device with Conversional context in mind, Sink and Source
4037    * ASEs should have been configured.
4038    */
4039   PrepareConfigureCodecHandler(group, 3);
4040   PrepareConfigureQosHandler(group, 3);
4041   PrepareEnableHandler(group, 3);
4042   PrepareDisableHandler(group, 3);
4043   PrepareReceiverStartReadyHandler(group, 1);
4044   PrepareReceiverStopReady(group, 1);
4045   PrepareReleaseHandler(group, 3);
4046 
4047   InjectInitialIdleNotification(group);
4048 
4049   // Validate initial GroupStreamStatus
4050   EXPECT_CALL(
4051       mock_callbacks_,
4052       StatusReportCb(leaudio_group_id,
4053                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
4054 
4055   // Start the configuration and stream Media content
4056   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
4057       group, context_type,
4058       {.sink = types::AudioContexts(context_type),
4059        .source = types::AudioContexts(context_type)}));
4060 
4061   // Validate new GroupStreamStatus
4062   EXPECT_CALL(mock_callbacks_,
4063               StatusReportCb(leaudio_group_id,
4064                              bluetooth::le_audio::GroupStreamStatus::IDLE))
4065       .Times(AtLeast(1));
4066 
4067   /* Single disconnect as it is bidirectional Cis*/
4068   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(2);
4069 
4070   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
4071   reset_mock_function_count_map();
4072 
4073   for (auto* device = group->GetFirstDevice(); device != nullptr;
4074        device = group->GetNextDevice(device)) {
4075     for (auto& ase : device->ases_) {
4076       client_parser::ascs::ase_codec_configured_state_params
4077           codec_configured_state_params;
4078 
4079       ASSERT_EQ(ase.state, types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
4080 
4081       // Each one does the autonomous release
4082       InjectAseStateNotification(&ase, device, group, ascs::kAseStateReleasing,
4083                                  &codec_configured_state_params);
4084       InjectAseStateNotification(&ase, device, group, ascs::kAseStateIdle,
4085                                  &codec_configured_state_params);
4086     }
4087   }
4088 
4089   // Verify we've handled the release and updated all states
4090   for (auto* device = group->GetFirstDevice(); device != nullptr;
4091        device = group->GetNextDevice(device)) {
4092     for (auto& ase : device->ases_) {
4093       ASSERT_EQ(ase.state, types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
4094     }
4095   }
4096 
4097   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
4098 }
4099 
TEST_F(StateMachineTest,testAseAutonomousRelease2Devices)4100 TEST_F(StateMachineTest, testAseAutonomousRelease2Devices) {
4101   const auto context_type = kContextTypeConversational;
4102   const int leaudio_group_id = 4;
4103   const int num_of_devices = 2;
4104 
4105   // Prepare fake connected device group
4106   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type,
4107                                              num_of_devices);
4108 
4109   /* Since we prepared device with Conversional context in mind, Sink and Source
4110    * ASEs should have been configured.
4111    */
4112   PrepareConfigureCodecHandler(group);
4113   PrepareConfigureQosHandler(group);
4114   PrepareEnableHandler(group);
4115   PrepareDisableHandler(group);
4116   PrepareReceiverStartReadyHandler(group);
4117   PrepareReceiverStopReady(group);
4118   PrepareReleaseHandler(group);
4119 
4120   InjectInitialIdleNotification(group);
4121 
4122   // Validate initial GroupStreamStatus
4123   EXPECT_CALL(
4124       mock_callbacks_,
4125       StatusReportCb(leaudio_group_id,
4126                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
4127 
4128   // Start the configuration and stream Media content
4129   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
4130       group, context_type,
4131       {.sink = types::AudioContexts(context_type),
4132        .source = types::AudioContexts(context_type)}));
4133 
4134   // Check streaming will continue
4135   EXPECT_CALL(mock_callbacks_,
4136               StatusReportCb(leaudio_group_id,
4137                              bluetooth::le_audio::GroupStreamStatus::IDLE))
4138       .Times(0);
4139 
4140   /* Single disconnect as it is bidirectional Cis*/
4141   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(1);
4142 
4143   auto device = group->GetFirstDevice();
4144   for (auto& ase : device->ases_) {
4145     client_parser::ascs::ase_codec_configured_state_params
4146         codec_configured_state_params;
4147 
4148     ASSERT_EQ(ase.state, types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
4149 
4150     // Simulate autonomus release for one device.
4151     InjectAseStateNotification(&ase, device, group, ascs::kAseStateReleasing,
4152                                &codec_configured_state_params);
4153     InjectAseStateNotification(&ase, device, group, ascs::kAseStateIdle,
4154                                &codec_configured_state_params);
4155   }
4156 }
4157 
TEST_F(StateMachineTest,testHandlingAutonomousCodecConfigStateOnConnection)4158 TEST_F(StateMachineTest, testHandlingAutonomousCodecConfigStateOnConnection) {
4159   /* Scenario
4160    * 1. After connection remote device has different ASE configurations
4161    * 2. Try to start stream and make sure it is configured well.
4162    */
4163 
4164   const auto context_type = kContextTypeConversational;
4165   const int leaudio_group_id = 4;
4166   const int num_of_devices = 2;
4167 
4168   // Prepare fake connected device group
4169   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type,
4170                                              num_of_devices);
4171 
4172   auto* firstDevice = group->GetFirstDevice();
4173   auto* secondDevice = group->GetNextDevice(firstDevice);
4174 
4175   /* Since we prepared device with Conversional context in mind, Sink and Source
4176    * ASEs should have been configured.
4177    */
4178   PrepareConfigureCodecHandler(group, 0, true);
4179   PrepareConfigureQosHandler(group);
4180   PrepareEnableHandler(group);
4181   PrepareDisableHandler(group);
4182   PrepareReceiverStartReadyHandler(group);
4183   PrepareReceiverStopReady(group);
4184 
4185   /* Number of control point calls
4186    * 1. Codec Config
4187    * 2. QoS Config
4188    * 3. Enable
4189    * 4. Receiver Start Ready
4190    */
4191   EXPECT_CALL(gatt_queue, WriteCharacteristic(firstDevice->conn_id_,
4192                                               firstDevice->ctp_hdls_.val_hdl, _,
4193                                               GATT_WRITE_NO_RSP, _, _))
4194       .Times(4);
4195 
4196   EXPECT_CALL(gatt_queue, WriteCharacteristic(secondDevice->conn_id_,
4197                                               secondDevice->ctp_hdls_.val_hdl,
4198                                               _, GATT_WRITE_NO_RSP, _, _))
4199       .Times(4);
4200 
4201   InjectInitialIdleAndConfiguredNotification(group);
4202   // Call it second time to make sure we get into state that current_state_ is
4203   // different then target_state_ even group is not in transition.
4204   InjectInitialIdleAndConfiguredNotification(group);
4205 
4206   ASSERT_TRUE(group->GetTargetState() != group->GetState());
4207   ASSERT_FALSE(group->IsInTransition());
4208 
4209   // Validate initial GroupStreamStatus
4210   EXPECT_CALL(
4211       mock_callbacks_,
4212       StatusReportCb(leaudio_group_id,
4213                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
4214 
4215   // Start the configuration and stream Media content
4216   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
4217       group, context_type,
4218       {.sink = types::AudioContexts(context_type),
4219        .source = types::AudioContexts(context_type)}));
4220 
4221   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
4222 }
4223 
TEST_F(StateMachineTest,testHandlingInvalidRemoteAseStateHandling)4224 TEST_F(StateMachineTest, testHandlingInvalidRemoteAseStateHandling) {
4225   /* Scenario
4226    * 1. After connection remote device has different ASE configurations
4227    * 2. Try to start stream and make sure it is configured well.
4228    */
4229 
4230   const auto context_type = kContextTypeConversational;
4231   const int leaudio_group_id = 4;
4232   const int num_of_devices = 2;
4233 
4234   // Prepare fake connected device group
4235   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type,
4236                                              num_of_devices);
4237 
4238   auto* firstDevice = group->GetFirstDevice();
4239   auto* secondDevice = group->GetNextDevice(firstDevice);
4240 
4241   /* Since we prepared device with Conversional context in mind, Sink and Source
4242    * ASEs should have been configured.
4243    */
4244   PrepareConfigureCodecHandler(group, 0, true);
4245   PrepareConfigureQosHandler(group);
4246   PrepareEnableHandler(group);
4247   PrepareDisableHandler(group);
4248   PrepareReceiverStartReadyHandler(group);
4249   PrepareReceiverStopReady(group);
4250 
4251   /* Number of control point calls
4252    * 1. Codec Config
4253    * 2. QoS Config
4254    * 3. Enable
4255    * 4. Receiver Start Ready
4256    */
4257   EXPECT_CALL(gatt_queue, WriteCharacteristic(firstDevice->conn_id_,
4258                                               firstDevice->ctp_hdls_.val_hdl, _,
4259                                               GATT_WRITE_NO_RSP, _, _))
4260       .Times(4);
4261 
4262   EXPECT_CALL(gatt_queue, WriteCharacteristic(secondDevice->conn_id_,
4263                                               secondDevice->ctp_hdls_.val_hdl,
4264                                               _, GATT_WRITE_NO_RSP, _, _))
4265       .Times(4);
4266 
4267   /* Inject invalid states*/
4268   InjectInitialInvalidNotification(group);
4269 
4270   ASSERT_FALSE(group->IsInTransition());
4271 
4272   // Validate initial GroupStreamStatus
4273   EXPECT_CALL(
4274       mock_callbacks_,
4275       StatusReportCb(leaudio_group_id,
4276                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
4277 
4278   // Start the configuration and stream Media content
4279   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
4280       group, context_type,
4281       {.sink = types::AudioContexts(context_type),
4282        .source = types::AudioContexts(context_type)}));
4283 
4284   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
4285 }
4286 
TEST_F(StateMachineTest,testHandlingCachedCodecConfig2Devices)4287 TEST_F(StateMachineTest, testHandlingCachedCodecConfig2Devices) {
4288   const auto context_type = kContextTypeConversational;
4289   const int leaudio_group_id = 4;
4290   const int num_of_devices = 2;
4291 
4292   // Prepare fake connected device group
4293   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type,
4294                                              num_of_devices);
4295 
4296   auto* firstDevice = group->GetFirstDevice();
4297   auto* secondDevice = group->GetNextDevice(firstDevice);
4298 
4299   /* Since we prepared device with Conversional context in mind, Sink and Source
4300    * ASEs should have been configured.
4301    */
4302   PrepareConfigureCodecHandler(group, 0, true);
4303   PrepareConfigureQosHandler(group);
4304   PrepareEnableHandler(group);
4305   PrepareDisableHandler(group);
4306   PrepareReceiverStartReadyHandler(group);
4307   PrepareReceiverStopReady(group);
4308   PrepareReleaseHandler(group);
4309 
4310   stay_in_releasing_state_ = true;
4311 
4312   /* Number of control point calls
4313    * 1. Codec Config
4314    * 2. QoS Config
4315    * 3. Enable
4316    * 4. Receiver Start Ready
4317    * 5. Release*/
4318   EXPECT_CALL(gatt_queue, WriteCharacteristic(firstDevice->conn_id_,
4319                                               firstDevice->ctp_hdls_.val_hdl, _,
4320                                               GATT_WRITE_NO_RSP, _, _))
4321       .Times(5);
4322 
4323   EXPECT_CALL(gatt_queue, WriteCharacteristic(secondDevice->conn_id_,
4324                                               secondDevice->ctp_hdls_.val_hdl,
4325                                               _, GATT_WRITE_NO_RSP, _, _))
4326       .Times(5);
4327 
4328   InjectInitialIdleNotification(group);
4329 
4330   // Validate initial GroupStreamStatus
4331   EXPECT_CALL(
4332       mock_callbacks_,
4333       StatusReportCb(leaudio_group_id,
4334                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
4335 
4336   // Start the configuration and stream Media content
4337   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
4338       group, context_type,
4339       {.sink = types::AudioContexts(context_type),
4340        .source = types::AudioContexts(context_type)}));
4341 
4342   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
4343 
4344   /* Two disconnect as it is two bidirectional Cises */
4345   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(2);
4346 
4347   // Validate initial GroupStreamStatus
4348   EXPECT_CALL(mock_callbacks_,
4349               StatusReportCb(leaudio_group_id,
4350                              bluetooth::le_audio::GroupStreamStatus::RELEASING))
4351       .Times(1);
4352   EXPECT_CALL(
4353       mock_callbacks_,
4354       StatusReportCb(
4355           leaudio_group_id,
4356           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS))
4357       .Times(0);
4358 
4359   // Stop the stream
4360   LeAudioGroupStateMachine::Get()->StopStream(group);
4361 
4362   for (auto& ase : firstDevice->ases_) {
4363     log::debug("{} , {}, {}", firstDevice->address_, ase.id,
4364                bluetooth::common::ToString(ase.state));
4365     ASSERT_EQ(ase.state, types::AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING);
4366     // Simulate autonomus configured state.
4367     InjectAseStateNotification(&ase, firstDevice, group,
4368                                ascs::kAseStateCodecConfigured,
4369                                &cached_codec_configuration_map_[ase.id]);
4370   }
4371 
4372   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
4373 
4374   /* When ALL devices got inactive, we should got the proper group status */
4375   EXPECT_CALL(
4376       mock_callbacks_,
4377       StatusReportCb(
4378           leaudio_group_id,
4379           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS))
4380       .Times(1);
4381   for (auto& ase : secondDevice->ases_) {
4382     log::debug("{} , {}, {}", firstDevice->address_, ase.id,
4383                bluetooth::common::ToString(ase.state));
4384     ASSERT_EQ(ase.state, types::AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING);
4385     // Simulate autonomus configured state.
4386     InjectAseStateNotification(&ase, secondDevice, group,
4387                                ascs::kAseStateCodecConfigured,
4388                                &cached_codec_configuration_map_[ase.id]);
4389   }
4390 
4391   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
4392 }
4393 
TEST_F(StateMachineTest,testStateTransitionTimeoutOnIdleState)4394 TEST_F(StateMachineTest, testStateTransitionTimeoutOnIdleState) {
4395   const auto context_type = kContextTypeRingtone;
4396   const int leaudio_group_id = 4;
4397   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
4398                    kLeAudioCodecChannelCountTwoChannel;
4399 
4400   // Prepare fake connected device group
4401   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
4402 
4403   auto* leAudioDevice = group->GetFirstDevice();
4404   EXPECT_CALL(gatt_queue,
4405               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
4406                                   GATT_WRITE_NO_RSP, _, _))
4407       .Times(1);
4408 
4409   // Start the configuration and stream Media content
4410   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
4411       group, context_type,
4412       {.sink = types::AudioContexts(context_type),
4413        .source = types::AudioContexts(context_type)}));
4414 
4415   // Disconnect device
4416   // in client.cc before this function is called, state of device is changed.
4417   leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED);
4418   LeAudioGroupStateMachine::Get()->ProcessHciNotifAclDisconnected(
4419       group, leAudioDevice);
4420 
4421   // Make sure timeout is cleared
4422   ASSERT_TRUE(fake_osi_alarm_set_on_mloop_.cb == nullptr);
4423 }
4424 
TEST_F(StateMachineTest,testStateIdleNotifyAclDisconnectedRemoveCig)4425 TEST_F(StateMachineTest, testStateIdleNotifyAclDisconnectedRemoveCig) {
4426   const auto context_type = kContextTypeRingtone;
4427   const int leaudio_group_id = 4;
4428 
4429   // Prepare fake connected device group
4430   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
4431   group->cig.SetState(types::CigState::CREATED);
4432 
4433   // Assert current state
4434   ASSERT_TRUE(group->GetState() ==
4435               types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
4436   ASSERT_FALSE(group->IsInTransition());
4437   ASSERT_TRUE(group->cig.GetState() == types::CigState::CREATED);
4438 
4439   // Expect RemoveCig to be called
4440   EXPECT_CALL(*mock_iso_manager_, RemoveCig(group->group_id_, _)).Times(1);
4441 
4442   // Disconnect device
4443   auto* leAudioDevice = group->GetFirstDevice();
4444   LeAudioGroupStateMachine::Get()->ProcessHciNotifAclDisconnected(
4445       group, leAudioDevice);
4446 
4447   // Assert Cig state transition to NONE after REMOVING
4448   ASSERT_TRUE(group->cig.GetState() == types::CigState::NONE);
4449 }
4450 
TEST_F(StateMachineTest,testStateTransitionTimeout)4451 TEST_F(StateMachineTest, testStateTransitionTimeout) {
4452   const auto context_type = kContextTypeRingtone;
4453   const int leaudio_group_id = 4;
4454   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
4455                    kLeAudioCodecChannelCountTwoChannel;
4456 
4457   // Prepare fake connected device group
4458   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
4459 
4460   /* Since we prepared device with Ringtone context in mind, only one ASE
4461    * should have been configured.
4462    */
4463   PrepareConfigureCodecHandler(group, 1);
4464   PrepareConfigureQosHandler(group, 1);
4465 
4466   auto* leAudioDevice = group->GetFirstDevice();
4467   EXPECT_CALL(gatt_queue,
4468               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
4469                                   GATT_WRITE_NO_RSP, _, _))
4470       .Times(3);
4471 
4472   // Start the configuration and stream Media content
4473   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
4474       group, context_type,
4475       {.sink = types::AudioContexts(context_type),
4476        .source = types::AudioContexts(context_type)}));
4477 
4478   // Check if timeout is fired
4479   EXPECT_CALL(mock_callbacks_, OnStateTransitionTimeout(leaudio_group_id));
4480 
4481   // simulate timeout seconds passed, alarm executing
4482   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
4483   ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
4484 }
4485 
TEST_F(StateMachineTest,testStateTransitionTimeoutAndDisconnectWhenConfigured)4486 TEST_F(StateMachineTest,
4487        testStateTransitionTimeoutAndDisconnectWhenConfigured) {
4488   const auto context_type = kContextTypeMedia;
4489   const int leaudio_group_id = 4;
4490   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
4491                    kLeAudioCodecChannelCountTwoChannel;
4492 
4493   // Prepare fake connected device group
4494   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
4495 
4496   auto* leAudioDevice = group->GetFirstDevice();
4497   EXPECT_CALL(gatt_queue,
4498               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
4499                                   GATT_WRITE_NO_RSP, _, _))
4500       .Times(1);
4501 
4502   InjectInitialConfiguredNotification(group);
4503 
4504   group->PrintDebugState();
4505 
4506   // Start the configuration and stream Media content
4507   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
4508       group, context_type,
4509       {.sink = types::AudioContexts(context_type),
4510        .source = types::AudioContexts(context_type)}));
4511 
4512   group->PrintDebugState();
4513 
4514   // Check if timeout is fired
4515   EXPECT_CALL(mock_callbacks_, OnStateTransitionTimeout(leaudio_group_id));
4516 
4517   // simulate timeout seconds passed, alarm executing
4518   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
4519   ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
4520 
4521   log::info("OnStateTransitionTimeout");
4522 
4523   /* Simulate On State timeout */
4524   group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
4525   group->ClearAllCises();
4526   group->PrintDebugState();
4527 
4528   InjectAclDisconnected(group, leAudioDevice);
4529 
4530   /* Verify that all ASEs are inactive and reconfiguration flag is cleared.*/
4531   for (const auto& ase : leAudioDevice->ases_) {
4532     ASSERT_EQ(ase.state, types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
4533     ASSERT_EQ(ase.cis_state, types::CisState::IDLE);
4534     ASSERT_EQ(ase.data_path_state, types::DataPathState::IDLE);
4535     ASSERT_EQ(ase.reconfigure, 0);
4536   }
4537 }
4538 
TEST_F(StateMachineTest,testStateTransitionTimeoutAndDisconnectWhenQoSConfigured)4539 TEST_F(StateMachineTest,
4540        testStateTransitionTimeoutAndDisconnectWhenQoSConfigured) {
4541   const auto context_type = kContextTypeMedia;
4542   const int leaudio_group_id = 4;
4543   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
4544                    kLeAudioCodecChannelCountTwoChannel;
4545 
4546   // Prepare fake connected device group
4547   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
4548   PrepareConfigureCodecHandler(group, 1);
4549 
4550   auto* leAudioDevice = group->GetFirstDevice();
4551   EXPECT_CALL(gatt_queue,
4552               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
4553                                   GATT_WRITE_NO_RSP, _, _))
4554       .Times(2);
4555 
4556   InjectInitialConfiguredNotification(group);
4557 
4558   group->PrintDebugState();
4559 
4560   // Start the configuration and stream Media content
4561   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
4562       group, context_type,
4563       {.sink = types::AudioContexts(context_type),
4564        .source = types::AudioContexts(context_type)}));
4565 
4566   group->PrintDebugState();
4567 
4568   // Check if timeout is fired
4569   EXPECT_CALL(mock_callbacks_, OnStateTransitionTimeout(leaudio_group_id));
4570 
4571   // simulate timeout seconds passed, alarm executing
4572   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
4573   ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
4574 
4575   log::info("OnStateTransitionTimeout");
4576 
4577   /* Simulate On State timeout */
4578   group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
4579   group->ClearAllCises();
4580   group->PrintDebugState();
4581 
4582   InjectAclDisconnected(group, leAudioDevice);
4583 
4584   /* Verify that all ASEs are inactive and reconfiguration flag is cleared.*/
4585   for (const auto& ase : leAudioDevice->ases_) {
4586     ASSERT_EQ(ase.state, types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
4587     ASSERT_EQ(ase.cis_state, types::CisState::IDLE);
4588     ASSERT_EQ(ase.data_path_state, types::DataPathState::IDLE);
4589     ASSERT_EQ(ase.reconfigure, 0);
4590   }
4591 }
4592 
TEST_F(StateMachineTest,testStateTransitionTimeoutAndDisconnectWhenEnabling)4593 TEST_F(StateMachineTest, testStateTransitionTimeoutAndDisconnectWhenEnabling) {
4594   const auto context_type = kContextTypeMedia;
4595   const int leaudio_group_id = 4;
4596   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
4597                    kLeAudioCodecChannelCountTwoChannel;
4598 
4599   // Prepare fake connected device group
4600   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
4601   PrepareConfigureCodecHandler(group, 1);
4602   PrepareConfigureQosHandler(group, 1);
4603 
4604   auto* leAudioDevice = group->GetFirstDevice();
4605   EXPECT_CALL(gatt_queue,
4606               WriteCharacteristic(1, leAudioDevice->ctp_hdls_.val_hdl, _,
4607                                   GATT_WRITE_NO_RSP, _, _))
4608       .Times(3);
4609 
4610   InjectInitialConfiguredNotification(group);
4611 
4612   group->PrintDebugState();
4613 
4614   // Start the configuration and stream Media content
4615   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
4616       group, context_type,
4617       {.sink = types::AudioContexts(context_type),
4618        .source = types::AudioContexts(context_type)}));
4619 
4620   group->PrintDebugState();
4621 
4622   // Check if timeout is fired
4623   EXPECT_CALL(mock_callbacks_, OnStateTransitionTimeout(leaudio_group_id));
4624 
4625   // simulate timeout seconds passed, alarm executing
4626   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
4627   ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
4628 
4629   log::info("OnStateTransitionTimeout");
4630 
4631   /* Simulate On State timeout */
4632   group->SetTargetState(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
4633   group->ClearAllCises();
4634   group->PrintDebugState();
4635 
4636   InjectAclDisconnected(group, leAudioDevice);
4637 
4638   /* Verify that all ASEs are inactive and reconfiguration flag is cleared.*/
4639   for (const auto& ase : leAudioDevice->ases_) {
4640     ASSERT_EQ(ase.state, types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
4641     ASSERT_EQ(ase.cis_state, types::CisState::IDLE);
4642     ASSERT_EQ(ase.data_path_state, types::DataPathState::IDLE);
4643     ASSERT_EQ(ase.reconfigure, 0);
4644   }
4645 }
4646 
4647 MATCHER_P(dataPathIsEq, expected, "") { return (arg.data_path_id == expected); }
4648 
TEST_F(StateMachineTest,testConfigureDataPathForHost)4649 TEST_F(StateMachineTest, testConfigureDataPathForHost) {
4650   const auto context_type = kContextTypeRingtone;
4651   const int leaudio_group_id = 4;
4652   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
4653                    kLeAudioCodecChannelCountTwoChannel;
4654 
4655   /* Can be called for every context when fetching the configuration
4656    */
4657   EXPECT_CALL(*mock_codec_manager_, GetCodecConfig(_, _)).Times(AtLeast(1));
4658 
4659   // Prepare fake connected device group
4660   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
4661 
4662   /* Since we prepared device with Ringtone context in mind, only one ASE
4663    * should have been configured.
4664    */
4665   PrepareConfigureCodecHandler(group, 1);
4666   PrepareConfigureQosHandler(group, 1);
4667   PrepareEnableHandler(group, 1);
4668 
4669   EXPECT_CALL(
4670       *mock_iso_manager_,
4671       SetupIsoDataPath(
4672           _, dataPathIsEq(bluetooth::hci::iso_manager::kIsoDataPathHci)))
4673       .Times(1);
4674 
4675   InjectInitialIdleNotification(group);
4676 
4677   // Start the configuration and stream Media content
4678   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
4679       group, context_type,
4680       {.sink = types::AudioContexts(context_type),
4681        .source = types::AudioContexts(context_type)}));
4682 }
4683 
TEST_F(StateMachineTestAdsp,testConfigureDataPathForAdsp)4684 TEST_F(StateMachineTestAdsp, testConfigureDataPathForAdsp) {
4685   const auto context_type = kContextTypeRingtone;
4686   const int leaudio_group_id = 4;
4687   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
4688                    kLeAudioCodecChannelCountTwoChannel;
4689 
4690   /* Can be called for every context when fetching the configuration
4691    */
4692   EXPECT_CALL(*mock_codec_manager_, GetCodecConfig(_, _)).Times(AtLeast(1));
4693 
4694   // Prepare fake connected device group
4695   auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type);
4696 
4697   /* Since we prepared device with Ringtone context in mind, only one ASE
4698    * should have been configured.
4699    */
4700   PrepareConfigureCodecHandler(group, 1);
4701   PrepareConfigureQosHandler(group, 1);
4702   PrepareEnableHandler(group, 1);
4703 
4704   EXPECT_CALL(
4705       *mock_iso_manager_,
4706       SetupIsoDataPath(
4707           _, dataPathIsEq(
4708                  bluetooth::hci::iso_manager::kIsoDataPathPlatformDefault)))
4709       .Times(1);
4710 
4711   InjectInitialIdleNotification(group);
4712 
4713   // Start the configuration and stream Media content
4714   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
4715       group, context_type,
4716       {.sink = types::AudioContexts(context_type),
4717        .source = types::AudioContexts(context_type)}));
4718 }
4719 
TEST_F(StateMachineTestAdsp,testStreamConfigurationAdspDownMix)4720 TEST_F(StateMachineTestAdsp, testStreamConfigurationAdspDownMix) {
4721   const auto context_type = kContextTypeConversational;
4722   const int leaudio_group_id = 4;
4723   const int num_devices = 2;
4724 
4725   // Prepare fake connected device group
4726   auto* group = PrepareSingleTestDeviceGroup(
4727       leaudio_group_id, context_type, num_devices,
4728       types::AudioContexts(kContextTypeConversational));
4729 
4730   EXPECT_CALL(
4731       mock_callbacks_,
4732       OnUpdatedCisConfiguration(
4733           group->group_id_, bluetooth::le_audio::types::kLeAudioDirectionSink))
4734       .Times(1);
4735   EXPECT_CALL(mock_callbacks_,
4736               OnUpdatedCisConfiguration(
4737                   group->group_id_,
4738                   bluetooth::le_audio::types::kLeAudioDirectionSource))
4739       .Times(1);
4740 
4741   /* Can be called for every context when fetching the configuration
4742    */
4743   EXPECT_CALL(*mock_codec_manager_, GetCodecConfig(_, _)).Times(AtLeast(1));
4744 
4745   PrepareConfigureCodecHandler(group);
4746   PrepareConfigureQosHandler(group);
4747   PrepareEnableHandler(group);
4748   PrepareReceiverStartReadyHandler(group);
4749 
4750   InjectInitialIdleNotification(group);
4751 
4752   auto* leAudioDevice = group->GetFirstDevice();
4753   InjectAclDisconnected(group, leAudioDevice);
4754 
4755   // Start the configuration and stream Media content
4756   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
4757       group, context_type,
4758       {.sink = types::AudioContexts(context_type),
4759        .source = types::AudioContexts(context_type)}));
4760 
4761   // Check if group has transitioned to a proper state
4762   ASSERT_EQ(group->GetState(),
4763             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
4764 
4765   // Note: The actual channel mixing is verified by the CodecManager unit tests.
4766 }
4767 
InjectCisDisconnected(LeAudioDeviceGroup * group,LeAudioDevice * leAudioDevice,uint8_t reason,bool first_cis_disconnect_only=false)4768 static void InjectCisDisconnected(LeAudioDeviceGroup* group,
4769                                   LeAudioDevice* leAudioDevice, uint8_t reason,
4770                                   bool first_cis_disconnect_only = false) {
4771   bluetooth::hci::iso_manager::cis_disconnected_evt event;
4772 
4773   for (auto const ase : leAudioDevice->ases_) {
4774     if (ase.cis_state != types::CisState::ASSIGNED &&
4775         ase.cis_state != types::CisState::IDLE) {
4776       event.reason = reason;
4777       event.cig_id = group->group_id_;
4778       event.cis_conn_hdl = ase.cis_conn_hdl;
4779       LeAudioGroupStateMachine::Get()->ProcessHciNotifCisDisconnected(
4780           group, leAudioDevice, &event);
4781       if (first_cis_disconnect_only) break;
4782     }
4783   }
4784 }
4785 
TEST_F(StateMachineTest,testAttachDeviceToTheStream)4786 TEST_F(StateMachineTest, testAttachDeviceToTheStream) {
4787   const auto context_type = kContextTypeMedia;
4788   const auto leaudio_group_id = 6;
4789   const auto num_devices = 2;
4790 
4791   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
4792 
4793   // Prepare multiple fake connected devices in a group
4794   auto* group =
4795       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
4796   ASSERT_EQ(group->Size(), num_devices);
4797 
4798   PrepareConfigureCodecHandler(group);
4799   PrepareConfigureQosHandler(group);
4800   PrepareEnableHandler(group);
4801   PrepareDisableHandler(group);
4802   PrepareReleaseHandler(group);
4803 
4804   auto* leAudioDevice = group->GetFirstDevice();
4805   LeAudioDevice* lastDevice;
4806   LeAudioDevice* fistDevice = leAudioDevice;
4807 
4808   auto expected_devices_written = 0;
4809   while (leAudioDevice) {
4810     /* Three Writes:
4811      * 1: Codec Config
4812      * 2: Codec QoS
4813      * 3: Enabling
4814      */
4815     lastDevice = leAudioDevice;
4816     EXPECT_CALL(gatt_queue,
4817                 WriteCharacteristic(leAudioDevice->conn_id_,
4818                                     leAudioDevice->ctp_hdls_.val_hdl, _,
4819                                     GATT_WRITE_NO_RSP, _, _))
4820         .Times(AtLeast(3));
4821     expected_devices_written++;
4822     leAudioDevice = group->GetNextDevice(leAudioDevice);
4823   }
4824   ASSERT_EQ(expected_devices_written, num_devices);
4825 
4826   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
4827   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
4828   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
4829 
4830   InjectInitialIdleNotification(group);
4831 
4832   // Start the configuration and stream Media content
4833   LeAudioGroupStateMachine::Get()->StartStream(
4834       group, context_type,
4835       {.sink = types::AudioContexts(context_type),
4836        .source = types::AudioContexts(context_type)});
4837 
4838   // Check if group has transitioned to a proper state
4839   ASSERT_EQ(group->GetState(),
4840             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
4841   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
4842 
4843   // Inject CIS and ACL disconnection of first device
4844   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
4845   InjectAclDisconnected(group, lastDevice);
4846 
4847   // Check if group keeps streaming
4848   ASSERT_EQ(group->GetState(),
4849             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
4850 
4851   lastDevice->conn_id_ = 3;
4852   lastDevice->SetConnectionState(DeviceConnectState::CONNECTED);
4853 
4854   // Make sure ASE with disconnected CIS are not left in STREAMING
4855   ASSERT_EQ(lastDevice->GetFirstAseWithState(
4856                 ::bluetooth::le_audio::types::kLeAudioDirectionSink,
4857                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
4858             nullptr);
4859   ASSERT_EQ(lastDevice->GetFirstAseWithState(
4860                 ::bluetooth::le_audio::types::kLeAudioDirectionSource,
4861                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
4862             nullptr);
4863 
4864   EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_,
4865                                               lastDevice->ctp_hdls_.val_hdl, _,
4866                                               GATT_WRITE_NO_RSP, _, _))
4867       .Times(AtLeast(3));
4868 
4869   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
4870   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
4871   LeAudioGroupStateMachine::Get()->AttachToStream(
4872       group, lastDevice, {.sink = {media_ccid}, .source = {}});
4873 
4874   // Check if group keeps streaming
4875   ASSERT_EQ(group->GetState(),
4876             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
4877 
4878   // Verify that the joining device receives the right CCID list
4879   auto lastMeta = lastDevice->GetFirstActiveAse()->metadata;
4880   bool parsedOk = false;
4881   auto ltv = bluetooth::le_audio::types::LeAudioLtvMap::Parse(
4882       lastMeta.data(), lastMeta.size(), parsedOk);
4883   ASSERT_TRUE(parsedOk);
4884 
4885   auto ccids =
4886       ltv.Find(bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList);
4887   ASSERT_TRUE(ccids.has_value());
4888   ASSERT_NE(std::find(ccids->begin(), ccids->end(), media_ccid), ccids->end());
4889 
4890   /* Verify that ASE of first device are still good*/
4891   auto ase = fistDevice->GetFirstActiveAse();
4892   ASSERT_NE(ase->qos_config.max_transport_latency, 0);
4893   ASSERT_NE(ase->qos_config.retrans_nb, 0);
4894 }
4895 
TEST_F(StateMachineTest,testAttachDeviceToTheStreamV2)4896 TEST_F(StateMachineTest, testAttachDeviceToTheStreamV2) {
4897   const auto context_type = kContextTypeMedia;
4898   const auto leaudio_group_id = 6;
4899   const auto num_devices = 2;
4900 
4901   /* Scenario
4902    * 1. Both devices streaming
4903    * 2. One device disconnects
4904    * 3. Audio configuration resume and configuration cache is rebuilt
4905    * 4. Device attached
4906    */
4907   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
4908 
4909   // Prepare multiple fake connected devices in a group
4910   auto* group =
4911       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
4912   ASSERT_EQ(group->Size(), num_devices);
4913 
4914   PrepareConfigureCodecHandler(group);
4915   PrepareConfigureQosHandler(group);
4916   PrepareEnableHandler(group);
4917   PrepareDisableHandler(group);
4918   PrepareReleaseHandler(group);
4919 
4920   auto* leAudioDevice = group->GetFirstDevice();
4921   LeAudioDevice* lastDevice;
4922   LeAudioDevice* fistDevice = leAudioDevice;
4923 
4924   auto expected_devices_written = 0;
4925   while (leAudioDevice) {
4926     /* Three Writes:
4927      * 1: Codec Config
4928      * 2: Codec QoS
4929      * 3: Enabling
4930      */
4931     lastDevice = leAudioDevice;
4932     EXPECT_CALL(gatt_queue,
4933                 WriteCharacteristic(leAudioDevice->conn_id_,
4934                                     leAudioDevice->ctp_hdls_.val_hdl, _,
4935                                     GATT_WRITE_NO_RSP, _, _))
4936         .Times(AtLeast(3));
4937     expected_devices_written++;
4938     leAudioDevice = group->GetNextDevice(leAudioDevice);
4939   }
4940   ASSERT_EQ(expected_devices_written, num_devices);
4941 
4942   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
4943   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
4944   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
4945 
4946   InjectInitialIdleNotification(group);
4947 
4948   // Start the configuration and stream Media content
4949   LeAudioGroupStateMachine::Get()->StartStream(
4950       group, context_type,
4951       {.sink = types::AudioContexts(context_type),
4952        .source = types::AudioContexts(context_type)});
4953 
4954   // Check if group has transitioned to a proper state
4955   ASSERT_EQ(group->GetState(),
4956             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
4957   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
4958 
4959   // Inject CIS and ACL disconnection of first device
4960   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
4961   InjectAclDisconnected(group, lastDevice);
4962 
4963   /* Force update configuration which is what happens when stream stops
4964    * and starts while streaming to single dev. This will rebuild cache,
4965    * which is what we need in this test.
4966    */
4967   group->UpdateAudioSetConfigurationCache(context_type);
4968 
4969   // Check if group keeps streaming
4970   ASSERT_EQ(group->GetState(),
4971             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
4972 
4973   lastDevice->conn_id_ = 3;
4974   lastDevice->SetConnectionState(DeviceConnectState::CONNECTED);
4975 
4976   // Make sure ASE with disconnected CIS are not left in STREAMING
4977   ASSERT_EQ(lastDevice->GetFirstAseWithState(
4978                 ::bluetooth::le_audio::types::kLeAudioDirectionSink,
4979                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
4980             nullptr);
4981   ASSERT_EQ(lastDevice->GetFirstAseWithState(
4982                 ::bluetooth::le_audio::types::kLeAudioDirectionSource,
4983                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
4984             nullptr);
4985 
4986   EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_,
4987                                               lastDevice->ctp_hdls_.val_hdl, _,
4988                                               GATT_WRITE_NO_RSP, _, _))
4989       .Times(AtLeast(3));
4990 
4991   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
4992   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
4993   LeAudioGroupStateMachine::Get()->AttachToStream(
4994       group, lastDevice, {.sink = {media_ccid}, .source = {}});
4995 
4996   // Check if group keeps streaming
4997   ASSERT_EQ(group->GetState(),
4998             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
4999 
5000   // Verify that the joining device receives the right CCID list
5001   auto lastMeta = lastDevice->GetFirstActiveAse()->metadata;
5002   bool parsedOk = false;
5003   auto ltv = bluetooth::le_audio::types::LeAudioLtvMap::Parse(
5004       lastMeta.data(), lastMeta.size(), parsedOk);
5005   ASSERT_TRUE(parsedOk);
5006 
5007   auto ccids =
5008       ltv.Find(bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList);
5009   ASSERT_TRUE(ccids.has_value());
5010   ASSERT_NE(std::find(ccids->begin(), ccids->end(), media_ccid), ccids->end());
5011 
5012   /* Verify that ASE of first device are still good*/
5013   auto ase = fistDevice->GetFirstActiveAse();
5014   ASSERT_NE(ase->qos_config.max_transport_latency, 0);
5015   ASSERT_NE(ase->qos_config.retrans_nb, 0);
5016 }
5017 
TEST_F(StateMachineTest,testAttachDeviceToTheStreamDeviceNoAvailableContext)5018 TEST_F(StateMachineTest, testAttachDeviceToTheStreamDeviceNoAvailableContext) {
5019   const auto context_type = kContextTypeMedia;
5020   const auto leaudio_group_id = 6;
5021   const auto num_devices = 2;
5022 
5023   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
5024 
5025   // Prepare multiple fake connected devices in a group
5026   auto* group =
5027       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
5028   ASSERT_EQ(group->Size(), num_devices);
5029 
5030   PrepareConfigureCodecHandler(group);
5031   PrepareConfigureQosHandler(group);
5032   PrepareEnableHandler(group);
5033   PrepareDisableHandler(group);
5034   PrepareReleaseHandler(group);
5035 
5036   auto* leAudioDevice = group->GetFirstDevice();
5037   LeAudioDevice* lastDevice;
5038 
5039   auto expected_devices_written = 0;
5040   while (leAudioDevice) {
5041     /* Three Writes:
5042      * 1: Codec Config
5043      * 2: Codec QoS
5044      * 3: Enabling
5045      */
5046     lastDevice = leAudioDevice;
5047     EXPECT_CALL(gatt_queue,
5048                 WriteCharacteristic(leAudioDevice->conn_id_,
5049                                     leAudioDevice->ctp_hdls_.val_hdl, _,
5050                                     GATT_WRITE_NO_RSP, _, _))
5051         .Times(AtLeast(3));
5052     expected_devices_written++;
5053     leAudioDevice = group->GetNextDevice(leAudioDevice);
5054   }
5055   ASSERT_EQ(expected_devices_written, num_devices);
5056 
5057   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
5058   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5059   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
5060 
5061   InjectInitialIdleNotification(group);
5062 
5063   // Start the configuration and stream Media content
5064   LeAudioGroupStateMachine::Get()->StartStream(
5065       group, context_type,
5066       {.sink = types::AudioContexts(context_type),
5067        .source = types::AudioContexts(context_type)});
5068 
5069   // Check if group has transitioned to a proper state
5070   ASSERT_EQ(group->GetState(),
5071             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5072   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
5073 
5074   // Inject CIS and ACL disconnection of first device
5075   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
5076   InjectAclDisconnected(group, lastDevice);
5077 
5078   // Check if group keeps streaming
5079   ASSERT_EQ(group->GetState(),
5080             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5081 
5082   // Connect the disconnected device BUT remove MEDIA from available Contex
5083   // Types
5084   lastDevice->conn_id_ = 3;
5085   auto test_context_type = kContextTypeUnspecified | kContextTypeConversational;
5086   lastDevice->SetAvailableContexts(
5087       {.sink = test_context_type, .source = test_context_type});
5088   lastDevice->SetConnectionState(DeviceConnectState::CONNECTED);
5089 
5090   // Make sure ASE with disconnected CIS are not left in STREAMING
5091   ASSERT_EQ(lastDevice->GetFirstAseWithState(
5092                 ::bluetooth::le_audio::types::kLeAudioDirectionSink,
5093                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
5094             nullptr);
5095   ASSERT_EQ(lastDevice->GetFirstAseWithState(
5096                 ::bluetooth::le_audio::types::kLeAudioDirectionSource,
5097                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
5098             nullptr);
5099 
5100   EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_,
5101                                               lastDevice->ctp_hdls_.val_hdl, _,
5102                                               GATT_WRITE_NO_RSP, _, _))
5103       .Times(AtLeast(0));
5104 
5105   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
5106   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
5107   ASSERT_EQ(LeAudioGroupStateMachine::Get()->AttachToStream(
5108                 group, lastDevice, {.sink = {media_ccid}, .source = {}}),
5109             false);
5110 
5111   ASSERT_EQ(group->GetState(),
5112             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5113 }
5114 
TEST_F(StateMachineTest,testAutonomousConfiguredAndAttachToStream)5115 TEST_F(StateMachineTest, testAutonomousConfiguredAndAttachToStream) {
5116   const auto context_type = kContextTypeMedia;
5117   const auto leaudio_group_id = 6;
5118   const auto num_devices = 2;
5119 
5120   /* Scenario
5121    * 1. Start streaming
5122    * 2. Stop stream on one device
5123    * 3. Reconnect
5124    * 4. Autonomous Configured state
5125    * 5. Make sure QoS Configure is not send out
5126    * 6. Trigger attach the stream
5127    * 7. Make sure stream is up
5128    */
5129 
5130   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
5131 
5132   // Prepare multiple fake connected devices in a group
5133   auto* group =
5134       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
5135   ASSERT_EQ(group->Size(), num_devices);
5136 
5137   PrepareConfigureCodecHandler(group, 0, true);
5138   PrepareConfigureQosHandler(group);
5139   PrepareEnableHandler(group);
5140   PrepareDisableHandler(group);
5141   PrepareReleaseHandler(group);
5142 
5143   auto* leAudioDevice = group->GetFirstDevice();
5144   LeAudioDevice* lastDevice;
5145   LeAudioDevice* fistDevice = leAudioDevice;
5146 
5147   auto expected_devices_written = 0;
5148   while (leAudioDevice) {
5149     /* Three Writes:
5150      * 1: Codec Config
5151      * 2: Codec QoS
5152      * 3: Enabling
5153      */
5154     lastDevice = leAudioDevice;
5155     EXPECT_CALL(gatt_queue,
5156                 WriteCharacteristic(leAudioDevice->conn_id_,
5157                                     leAudioDevice->ctp_hdls_.val_hdl, _,
5158                                     GATT_WRITE_NO_RSP, _, _))
5159         .Times(AtLeast(3));
5160     expected_devices_written++;
5161     leAudioDevice = group->GetNextDevice(leAudioDevice);
5162   }
5163   ASSERT_EQ(expected_devices_written, num_devices);
5164 
5165   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
5166   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5167   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
5168 
5169   InjectInitialIdleNotification(group);
5170 
5171   // Start the configuration and stream Media content
5172   LeAudioGroupStateMachine::Get()->StartStream(
5173       group, context_type,
5174       {.sink = types::AudioContexts(context_type),
5175        .source = types::AudioContexts(context_type)});
5176 
5177   // Check if group has transitioned to a proper state
5178   ASSERT_EQ(group->GetState(),
5179             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5180   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
5181 
5182   // Inject CIS and ACL disconnection of first device
5183   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
5184   InjectAclDisconnected(group, lastDevice);
5185 
5186   // Check if group keeps streaming
5187   ASSERT_EQ(group->GetState(),
5188             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5189 
5190   /* Set device is getting ready for the connection */
5191   lastDevice->conn_id_ = 3;
5192   lastDevice->SetConnectionState(
5193       DeviceConnectState::CONNECTED_AUTOCONNECT_GETTING_READY);
5194 
5195   // Make sure ASE with disconnected CIS are not left in STREAMING
5196   ASSERT_EQ(lastDevice->GetFirstAseWithState(
5197                 ::bluetooth::le_audio::types::kLeAudioDirectionSink,
5198                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
5199             nullptr);
5200   ASSERT_EQ(lastDevice->GetFirstAseWithState(
5201                 ::bluetooth::le_audio::types::kLeAudioDirectionSource,
5202                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
5203             nullptr);
5204 
5205   // Symulate remote autonomous CONFIGURE state
5206   EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_,
5207                                               lastDevice->ctp_hdls_.val_hdl, _,
5208                                               GATT_WRITE_NO_RSP, _, _))
5209       .Times(0);
5210 
5211   int num_of_notifications = 0;
5212   for (auto& ase : lastDevice->ases_) {
5213     if (ase.id == bluetooth::le_audio::types::ase::kAseIdInvalid) {
5214       continue;
5215     }
5216     log::error("ID : {},  status {}", ase.id,
5217                bluetooth::common::ToString(ase.state));
5218     num_of_notifications++;
5219     InjectAseStateNotification(&ase, lastDevice, group,
5220                                ascs::kAseStateCodecConfigured,
5221                                &cached_codec_configuration_map_[ase.id]);
5222     break;
5223   }
5224   ASSERT_EQ(num_of_notifications, 1);
5225 
5226   testing::Mock::VerifyAndClearExpectations(&gatt_queue);
5227   // Now device is connected. Attach it to the stream
5228 
5229   lastDevice->SetConnectionState(DeviceConnectState::CONNECTED);
5230 
5231   EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_,
5232                                               lastDevice->ctp_hdls_.val_hdl, _,
5233                                               GATT_WRITE_NO_RSP, _, _))
5234       .Times(AtLeast(3));
5235 
5236   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5237   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
5238   LeAudioGroupStateMachine::Get()->AttachToStream(
5239       group, lastDevice, {.sink = {media_ccid}, .source = {}});
5240 
5241   // Check if group keeps streaming
5242   ASSERT_EQ(group->GetState(),
5243             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5244 
5245   // Verify that the joining device receives the right CCID list
5246   auto lastMeta = lastDevice->GetFirstActiveAse()->metadata;
5247   bool parsedOk = false;
5248   auto ltv = bluetooth::le_audio::types::LeAudioLtvMap::Parse(
5249       lastMeta.data(), lastMeta.size(), parsedOk);
5250   ASSERT_TRUE(parsedOk);
5251 
5252   auto ccids =
5253       ltv.Find(bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList);
5254   ASSERT_TRUE(ccids.has_value());
5255   ASSERT_NE(std::find(ccids->begin(), ccids->end(), media_ccid), ccids->end());
5256 
5257   /* Verify that ASE of first device are still good*/
5258   auto ase = fistDevice->GetFirstActiveAse();
5259   ASSERT_NE(ase->qos_config.max_transport_latency, 0);
5260   ASSERT_NE(ase->qos_config.retrans_nb, 0);
5261 }
5262 
TEST_F(StateMachineTest,testAttachDeviceToTheStream_autonomusQoSConfiguredState)5263 TEST_F(StateMachineTest,
5264        testAttachDeviceToTheStream_autonomusQoSConfiguredState) {
5265   const auto context_type = kContextTypeMedia;
5266   const auto leaudio_group_id = 6;
5267   const auto num_devices = 2;
5268 
5269   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
5270 
5271   // Prepare multiple fake connected devices in a group
5272   auto* group =
5273       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
5274   ASSERT_EQ(group->Size(), num_devices);
5275 
5276   PrepareConfigureCodecHandler(group);
5277   PrepareConfigureQosHandler(group);
5278   PrepareEnableHandler(group);
5279   PrepareDisableHandler(group);
5280   PrepareReleaseHandler(group);
5281 
5282   auto* leAudioDevice = group->GetFirstDevice();
5283   LeAudioDevice* lastDevice;
5284   LeAudioDevice* fistDevice = leAudioDevice;
5285 
5286   auto expected_devices_written = 0;
5287   while (leAudioDevice) {
5288     /* Three Writes:
5289      * 1: Codec Config
5290      * 2: Codec QoS
5291      * 3: Enabling
5292      */
5293     lastDevice = leAudioDevice;
5294     EXPECT_CALL(gatt_queue,
5295                 WriteCharacteristic(leAudioDevice->conn_id_,
5296                                     leAudioDevice->ctp_hdls_.val_hdl, _,
5297                                     GATT_WRITE_NO_RSP, _, _))
5298         .Times(AtLeast(3));
5299     expected_devices_written++;
5300     leAudioDevice = group->GetNextDevice(leAudioDevice);
5301   }
5302   ASSERT_EQ(expected_devices_written, num_devices);
5303 
5304   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
5305   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5306   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
5307 
5308   InjectInitialIdleNotification(group);
5309 
5310   // Start the configuration and stream Media content
5311   LeAudioGroupStateMachine::Get()->StartStream(
5312       group, context_type,
5313       {.sink = types::AudioContexts(context_type),
5314        .source = types::AudioContexts(context_type)},
5315       {.sink = std::vector<uint8_t>(1, media_ccid),
5316        .source = std::vector<uint8_t>(1, media_ccid)});
5317 
5318   // Check if group has transitioned to a proper state
5319   ASSERT_EQ(group->GetState(),
5320             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5321   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
5322 
5323   // Inject CIS and ACL disconnection of first device
5324   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
5325 
5326   // Check if group keeps streaming
5327   ASSERT_EQ(group->GetState(),
5328             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5329 
5330   // Make sure ASE with disconnected CIS are not left in STREAMING
5331   ASSERT_EQ(lastDevice->GetFirstAseWithState(
5332                 ::bluetooth::le_audio::types::kLeAudioDirectionSink,
5333                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
5334             nullptr);
5335   ASSERT_EQ(lastDevice->GetFirstAseWithState(
5336                 ::bluetooth::le_audio::types::kLeAudioDirectionSource,
5337                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
5338             nullptr);
5339 
5340   EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_,
5341                                               lastDevice->ctp_hdls_.val_hdl, _,
5342                                               GATT_WRITE_NO_RSP, _, _))
5343       .Times(1);
5344 
5345   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5346   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
5347 
5348   for (auto& ase : lastDevice->ases_) {
5349     if (cached_remote_qos_configuration_for_ase_.count(&ase) > 0) {
5350       InjectAseStateNotification(
5351           &ase, lastDevice, group, ascs::kAseStateQoSConfigured,
5352           &(cached_remote_qos_configuration_for_ase_[&ase]));
5353     }
5354   }
5355 
5356   // Check if group keeps streaming
5357   ASSERT_EQ(group->GetState(),
5358             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5359 
5360   // Verify that the joining device receives the right CCID list
5361   auto lastMeta = lastDevice->GetFirstActiveAse()->metadata;
5362   bool parsedOk = false;
5363   auto ltv = bluetooth::le_audio::types::LeAudioLtvMap::Parse(
5364       lastMeta.data(), lastMeta.size(), parsedOk);
5365   ASSERT_TRUE(parsedOk);
5366 
5367   auto ccids =
5368       ltv.Find(bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList);
5369   ASSERT_TRUE(ccids.has_value());
5370   ASSERT_NE(std::find(ccids->begin(), ccids->end(), media_ccid), ccids->end());
5371 
5372   /* Verify that ASE of first device are still good*/
5373   auto ase = fistDevice->GetFirstActiveAse();
5374   ASSERT_NE(ase->qos_config.max_transport_latency, 0);
5375   ASSERT_NE(ase->qos_config.retrans_nb, 0);
5376 }
5377 
TEST_F(StateMachineTest,testAttachDeviceToTheStreamDoNotAttach)5378 TEST_F(StateMachineTest, testAttachDeviceToTheStreamDoNotAttach) {
5379   const auto context_type = kContextTypeMedia;
5380   const auto leaudio_group_id = 6;
5381   const auto num_devices = 2;
5382 
5383   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
5384 
5385   // Prepare multiple fake connected devices in a group
5386   auto* group =
5387       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
5388   ASSERT_EQ(group->Size(), num_devices);
5389 
5390   PrepareConfigureCodecHandler(group);
5391   PrepareConfigureQosHandler(group);
5392   PrepareEnableHandler(group);
5393 
5394   auto* leAudioDevice = group->GetFirstDevice();
5395   LeAudioDevice* lastDevice;
5396 
5397   while (leAudioDevice) {
5398     lastDevice = leAudioDevice;
5399     leAudioDevice = group->GetNextDevice(leAudioDevice);
5400   }
5401 
5402   InjectInitialIdleNotification(group);
5403 
5404   // Inject CIS and ACL disconnection of first device
5405   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
5406   InjectAclDisconnected(group, lastDevice);
5407 
5408   // Start the configuration and stream Media content
5409   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
5410   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5411   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
5412   LeAudioGroupStateMachine::Get()->StartStream(
5413       group, context_type,
5414       {.sink = types::AudioContexts(context_type),
5415        .source = types::AudioContexts(context_type)});
5416 
5417   // Check if group has transitioned to a proper state
5418   ASSERT_EQ(group->GetState(),
5419             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5420   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
5421 
5422   // Check if group keeps streaming
5423   ASSERT_EQ(group->GetState(),
5424             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5425 
5426   lastDevice->conn_id_ = 3;
5427   lastDevice->SetConnectionState(DeviceConnectState::CONNECTED);
5428 
5429   EXPECT_CALL(
5430       mock_callbacks_,
5431       StatusReportCb(leaudio_group_id,
5432                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
5433   LeAudioGroupStateMachine::Get()->StopStream(group);
5434   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
5435 
5436   ASSERT_FALSE(LeAudioGroupStateMachine::Get()->AttachToStream(
5437       group, lastDevice, {.sink = {}, .source = {}}));
5438 }
5439 
TEST_F(StateMachineTest,testReconfigureAfterLateDeviceAttached)5440 TEST_F(StateMachineTest, testReconfigureAfterLateDeviceAttached) {
5441   const auto context_type = kContextTypeMedia;
5442   const auto leaudio_group_id = 6;
5443   const auto num_devices = 2;
5444 
5445   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
5446 
5447   // Prepare multiple fake connected devices in a group
5448   auto* group =
5449       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
5450   ASSERT_EQ(group->Size(), num_devices);
5451 
5452   PrepareConfigureCodecHandler(group, 0, true);
5453   PrepareConfigureQosHandler(group);
5454   PrepareEnableHandler(group);
5455   PrepareDisableHandler(group);
5456   PrepareReleaseHandler(group);
5457 
5458   auto* leAudioDevice = group->GetFirstDevice();
5459   LeAudioDevice* lastDevice;
5460   LeAudioDevice* fistDevice = leAudioDevice;
5461 
5462   while (leAudioDevice) {
5463     lastDevice = leAudioDevice;
5464     leAudioDevice = group->GetNextDevice(leAudioDevice);
5465   }
5466 
5467   InjectInitialIdleNotification(group);
5468 
5469   // Inject CIS and ACL disconnection of first device
5470   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
5471   InjectAclDisconnected(group, lastDevice);
5472 
5473   /* First device connected. Configure it to stream media */
5474 
5475   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
5476   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5477   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
5478 
5479   types::BidirectionalPair<std::vector<uint8_t>> ccids_list = {
5480       .sink = {media_ccid}, .source = {media_ccid}};
5481 
5482   // Start the configuration and stream Media content
5483   LeAudioGroupStateMachine::Get()->StartStream(
5484       group, context_type,
5485       {.sink = types::AudioContexts(context_type),
5486        .source = types::AudioContexts(context_type)},
5487       ccids_list);
5488 
5489   // Check if group has transitioned to a proper state
5490   ASSERT_EQ(group->GetState(),
5491             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5492   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
5493 
5494   /* Stop  the stream and let first device to stay in configured state (caching
5495    * is on)*/
5496   LeAudioGroupStateMachine::Get()->StopStream(group);
5497   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
5498 
5499   /* Verify state in the configured state */
5500   ASSERT_EQ(group->GetState(),
5501             types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
5502 
5503   /* Now when stream is stopped, connect second device. */
5504   lastDevice->conn_id_ = 3;
5505   lastDevice->SetConnectionState(DeviceConnectState::CONNECTED);
5506 
5507   group->UpdateAudioContextAvailability();
5508   group->UpdateAudioSetConfigurationCache(context_type);
5509 
5510   /* Start stream, make sure 2 devices are started. */
5511 
5512   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
5513   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5514   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
5515 
5516   // Start the configuration and stream Media content
5517   LeAudioGroupStateMachine::Get()->StartStream(
5518       group, context_type,
5519       {.sink = types::AudioContexts(context_type),
5520        .source = types::AudioContexts(context_type)},
5521       ccids_list);
5522 
5523   // Check if group keeps streaming
5524   ASSERT_EQ(group->GetState(),
5525             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5526 
5527   // Verify that both devicse receives the right CCID list and both are
5528   // streaming
5529   auto ase = lastDevice->GetFirstActiveAse();
5530 
5531   // FIXME: No ASE was activated - that's bad
5532   ASSERT_NE(nullptr, ase);
5533   auto lastMeta = ase->metadata;
5534   bool parsedOk = false;
5535   auto ltv = bluetooth::le_audio::types::LeAudioLtvMap::Parse(
5536       lastMeta.data(), lastMeta.size(), parsedOk);
5537   ASSERT_TRUE(parsedOk);
5538 
5539   auto ccids =
5540       ltv.Find(bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList);
5541   ASSERT_TRUE(ccids.has_value());
5542   ASSERT_NE(std::find(ccids->begin(), ccids->end(), media_ccid), ccids->end());
5543 
5544   /* Verify that ASE of first device are still good*/
5545   ase = fistDevice->GetFirstActiveAse();
5546   ASSERT_NE(nullptr, ase);
5547   ASSERT_NE(ase->qos_config.max_transport_latency, 0);
5548   ASSERT_NE(ase->qos_config.retrans_nb, 0);
5549 }
5550 
TEST_F(StateMachineTest,testReconfigureAfterLateDeviceAttachedConversationalSwb)5551 TEST_F(StateMachineTest,
5552        testReconfigureAfterLateDeviceAttachedConversationalSwb) {
5553   const auto context_type = kContextTypeConversational;
5554   const auto leaudio_group_id = 6;
5555   const auto num_devices = 2;
5556 
5557   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
5558 
5559   // Prepare multiple fake connected devices in a group
5560   auto* group =
5561       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
5562   ASSERT_EQ(group->Size(), num_devices);
5563 
5564   PrepareConfigureCodecHandler(group, 0, true);
5565   PrepareConfigureQosHandler(group);
5566   PrepareEnableHandler(group);
5567   PrepareReceiverStartReadyHandler(group);
5568   PrepareDisableHandler(group);
5569   PrepareReleaseHandler(group);
5570 
5571   auto* leAudioDevice = group->GetFirstDevice();
5572   LeAudioDevice* lastDevice;
5573   LeAudioDevice* fistDevice = leAudioDevice;
5574 
5575   while (leAudioDevice) {
5576     lastDevice = leAudioDevice;
5577     leAudioDevice = group->GetNextDevice(leAudioDevice);
5578   }
5579 
5580   InjectInitialIdleNotification(group);
5581 
5582   // Inject CIS and ACL disconnection of first device
5583   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
5584   InjectAclDisconnected(group, lastDevice);
5585 
5586   /* First device connected. Configure it to stream media */
5587   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
5588   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5589   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
5590 
5591   types::BidirectionalPair<std::vector<uint8_t>> ccids_list = {
5592       .sink = {media_ccid}, .source = {media_ccid}};
5593 
5594   // Start the configuration and stream Media content
5595   LeAudioGroupStateMachine::Get()->StartStream(
5596       group, context_type,
5597       {.sink = types::AudioContexts(context_type),
5598        .source = types::AudioContexts(context_type)},
5599       ccids_list);
5600 
5601   auto current_config = group->GetCachedConfiguration(context_type);
5602   ASSERT_NE(nullptr, current_config.get());
5603   // With a single device there will be no dual bidir SWB but a single bidir SWB
5604   ASSERT_TRUE(
5605       AudioSetConfigurationProvider::Get()->CheckConfigurationIsBiDirSwb(
5606           *current_config.get()));
5607   ASSERT_FALSE(
5608       AudioSetConfigurationProvider::Get()->CheckConfigurationIsDualBiDirSwb(
5609           *current_config.get()));
5610 
5611   // Check if group has transitioned to a proper state
5612   ASSERT_EQ(group->GetState(),
5613             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5614   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
5615 
5616   /* Stop  the stream and let first device to stay in configured state (caching
5617    * is on)*/
5618   LeAudioGroupStateMachine::Get()->StopStream(group);
5619   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
5620 
5621   /* Verify state in the configured state */
5622   ASSERT_EQ(group->GetState(),
5623             types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
5624 
5625   /* Now when stream is stopped, connect second device. */
5626   lastDevice->conn_id_ = 3;
5627   lastDevice->SetConnectionState(DeviceConnectState::CONNECTED);
5628 
5629   group->UpdateAudioContextAvailability();
5630   group->UpdateAudioSetConfigurationCache(context_type);
5631 
5632   /* Start stream, make sure 2 devices are started. */
5633   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
5634   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5635   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(4);
5636 
5637   // Start the configuration and stream Media content
5638   LeAudioGroupStateMachine::Get()->StartStream(
5639       group, context_type,
5640       {.sink = types::AudioContexts(context_type),
5641        .source = types::AudioContexts(context_type)},
5642       ccids_list);
5643 
5644   // Check if group keeps streaming
5645   ASSERT_EQ(group->GetState(),
5646             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5647 
5648   // Verify that both devicse receives the right CCID list and both are
5649   // streaming
5650   auto ase = lastDevice->GetFirstActiveAse();
5651 
5652   // No ASE was activated - that's bad
5653   ASSERT_NE(nullptr, ase);
5654   auto lastMeta = ase->metadata;
5655   bool parsedOk = false;
5656   auto ltv = bluetooth::le_audio::types::LeAudioLtvMap::Parse(
5657       lastMeta.data(), lastMeta.size(), parsedOk);
5658   ASSERT_TRUE(parsedOk);
5659 
5660   auto ccids =
5661       ltv.Find(bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList);
5662   ASSERT_TRUE(ccids.has_value());
5663   ASSERT_NE(std::find(ccids->begin(), ccids->end(), media_ccid), ccids->end());
5664 
5665   /* Verify that ASE of first device are still good*/
5666   ase = fistDevice->GetFirstActiveAse();
5667   ASSERT_NE(nullptr, ase);
5668   ASSERT_NE(ase->qos_config.max_transport_latency, 0);
5669   ASSERT_NE(ase->qos_config.retrans_nb, 0);
5670 
5671   // With both devices we should get the dual bidir SWB configuration
5672   current_config = group->GetCachedConfiguration(context_type);
5673   ASSERT_NE(nullptr, current_config.get());
5674   ASSERT_TRUE(
5675       AudioSetConfigurationProvider::Get()->CheckConfigurationIsDualBiDirSwb(
5676           *current_config.get()));
5677 }
5678 
TEST_F(StateMachineTestNoSwb,testReconfigureAfterLateDeviceAttachedConversationalNoSwb)5679 TEST_F(StateMachineTestNoSwb,
5680        testReconfigureAfterLateDeviceAttachedConversationalNoSwb) {
5681   const auto context_type = kContextTypeConversational;
5682   const auto leaudio_group_id = 6;
5683   const auto num_devices = 2;
5684 
5685   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
5686 
5687   // Prepare multiple fake connected devices in a group
5688   auto* group =
5689       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
5690   ASSERT_EQ(group->Size(), num_devices);
5691 
5692   PrepareConfigureCodecHandler(group, 0, true);
5693   PrepareConfigureQosHandler(group);
5694   PrepareEnableHandler(group);
5695   PrepareReceiverStartReadyHandler(group);
5696   PrepareDisableHandler(group);
5697   PrepareReleaseHandler(group);
5698 
5699   auto* leAudioDevice = group->GetFirstDevice();
5700   LeAudioDevice* lastDevice;
5701   LeAudioDevice* fistDevice = leAudioDevice;
5702 
5703   while (leAudioDevice) {
5704     lastDevice = leAudioDevice;
5705     leAudioDevice = group->GetNextDevice(leAudioDevice);
5706   }
5707 
5708   InjectInitialIdleNotification(group);
5709 
5710   // Inject CIS and ACL disconnection of first device
5711   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
5712   InjectAclDisconnected(group, lastDevice);
5713 
5714   /* First device connected. Configure it to stream media */
5715   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
5716   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5717   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
5718 
5719   types::BidirectionalPair<std::vector<uint8_t>> ccids_list = {
5720       .sink = {media_ccid}, .source = {media_ccid}};
5721 
5722   // Start the configuration and stream Media content
5723   LeAudioGroupStateMachine::Get()->StartStream(
5724       group, context_type,
5725       {.sink = types::AudioContexts(context_type),
5726        .source = types::AudioContexts(context_type)},
5727       ccids_list);
5728 
5729   auto current_config = group->GetCachedConfiguration(context_type);
5730   ASSERT_NE(nullptr, current_config.get());
5731   // With a single device there shall be no bidir SWB, as we expect the 2nd
5732   // device to join the stream seamlessly while dual bidir SWB is disabled.
5733   ASSERT_FALSE(
5734       AudioSetConfigurationProvider::Get()->CheckConfigurationIsBiDirSwb(
5735           *current_config.get()));
5736   ASSERT_FALSE(
5737       AudioSetConfigurationProvider::Get()->CheckConfigurationIsDualBiDirSwb(
5738           *current_config.get()));
5739 
5740   // Check if group has transitioned to a proper state
5741   ASSERT_EQ(group->GetState(),
5742             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5743   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
5744 
5745   /* Stop  the stream and let first device to stay in configured state (caching
5746    * is on)*/
5747   LeAudioGroupStateMachine::Get()->StopStream(group);
5748   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
5749 
5750   /* Verify state in the configured state */
5751   ASSERT_EQ(group->GetState(),
5752             types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
5753 
5754   /* Now when stream is stopped, connect second device. */
5755   lastDevice->conn_id_ = 3;
5756   lastDevice->SetConnectionState(DeviceConnectState::CONNECTED);
5757 
5758   group->UpdateAudioContextAvailability();
5759   group->UpdateAudioSetConfigurationCache(context_type);
5760 
5761   /* Start stream, make sure 2 devices are started. */
5762   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
5763   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5764   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(4);
5765 
5766   // Start the configuration and stream Media content
5767   LeAudioGroupStateMachine::Get()->StartStream(
5768       group, context_type,
5769       {.sink = types::AudioContexts(context_type),
5770        .source = types::AudioContexts(context_type)},
5771       ccids_list);
5772 
5773   // Check if group keeps streaming
5774   ASSERT_EQ(group->GetState(),
5775             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5776 
5777   // Verify that both devicse receives the right CCID list and both are
5778   // streaming
5779   auto ase = lastDevice->GetFirstActiveAse();
5780 
5781   // No ASE was activated - that's bad
5782   ASSERT_NE(nullptr, ase);
5783   auto lastMeta = ase->metadata;
5784   bool parsedOk = false;
5785   auto ltv = bluetooth::le_audio::types::LeAudioLtvMap::Parse(
5786       lastMeta.data(), lastMeta.size(), parsedOk);
5787   ASSERT_TRUE(parsedOk);
5788 
5789   auto ccids =
5790       ltv.Find(bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList);
5791   ASSERT_TRUE(ccids.has_value());
5792   ASSERT_NE(std::find(ccids->begin(), ccids->end(), media_ccid), ccids->end());
5793 
5794   /* Verify that ASE of first device are still good*/
5795   ase = fistDevice->GetFirstActiveAse();
5796   ASSERT_NE(nullptr, ase);
5797   ASSERT_NE(ase->qos_config.max_transport_latency, 0);
5798   ASSERT_NE(ase->qos_config.retrans_nb, 0);
5799 
5800   // With both devices we still should not get the dual bidir SWB configuration
5801   // as it is currently disabled.
5802   current_config = group->GetCachedConfiguration(context_type);
5803   ASSERT_NE(nullptr, current_config.get());
5804   ASSERT_FALSE(
5805       AudioSetConfigurationProvider::Get()->CheckConfigurationIsDualBiDirSwb(
5806           *current_config.get()));
5807 }
5808 
TEST_F(StateMachineTest,testStreamToGettingReadyDevice)5809 TEST_F(StateMachineTest, testStreamToGettingReadyDevice) {
5810   const auto context_type = kContextTypeLive;
5811   const auto leaudio_group_id = 666;
5812   const auto num_devices = 2;
5813 
5814   ContentControlIdKeeper::GetInstance()->SetCcid(call_context, call_ccid);
5815 
5816   // Prepare multiple fake connected devices in a group
5817   auto* group =
5818       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
5819 
5820   // Simulate the 2nd device still getting ready
5821   auto* firstDevice = group->GetFirstDevice();
5822   auto* secondDevice = group->GetNextDevice(firstDevice);
5823   secondDevice->SetConnectionState(
5824       DeviceConnectState::CONNECTED_BY_USER_GETTING_READY);
5825 
5826   group->UpdateAudioContextAvailability();
5827   group->UpdateAudioSetConfigurationCache(context_type);
5828 
5829   ASSERT_EQ(group->Size(), num_devices);
5830   ASSERT_EQ(1, group->NumOfConnected());
5831 
5832   PrepareConfigureCodecHandler(group);
5833   PrepareConfigureQosHandler(group);
5834   PrepareEnableHandler(group);
5835   PrepareReceiverStartReadyHandler(group);
5836   PrepareDisableHandler(group);
5837   PrepareReleaseHandler(group);
5838 
5839   /* Three Writes:
5840    * 1: Codec Config
5841    * 2: Codec QoS
5842    * 3: Enabling
5843    */
5844   // Expect actions only on the already prepared device
5845   EXPECT_CALL(gatt_queue, WriteCharacteristic(firstDevice->conn_id_,
5846                                               firstDevice->ctp_hdls_.val_hdl, _,
5847                                               GATT_WRITE_NO_RSP, _, _))
5848       .Times(AtLeast(3));
5849 
5850   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
5851   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5852   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
5853 
5854   InjectInitialIdleNotification(group);
5855 
5856   // Start the configuration and the stream
5857   LeAudioGroupStateMachine::Get()->StartStream(
5858       group, context_type,
5859       {.sink = types::AudioContexts(context_type),
5860        .source = types::AudioContexts(context_type)});
5861 
5862   // Check if group has transitioned to a proper state with one device still
5863   // being in the `CONNECTED_BY_USER_GETTING_READY` state
5864   ASSERT_EQ(group->GetState(),
5865             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5866   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
5867 }
5868 
TEST_F(StateMachineTest,testAttachDeviceToTheConversationalStream)5869 TEST_F(StateMachineTest, testAttachDeviceToTheConversationalStream) {
5870   const auto context_type = kContextTypeConversational;
5871   const auto leaudio_group_id = 6;
5872   const auto num_devices = 2;
5873 
5874   ContentControlIdKeeper::GetInstance()->SetCcid(call_context, call_ccid);
5875 
5876   // Prepare multiple fake connected devices in a group
5877   auto* group =
5878       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
5879   ASSERT_EQ(group->Size(), num_devices);
5880 
5881   PrepareConfigureCodecHandler(group);
5882   PrepareConfigureQosHandler(group);
5883   PrepareEnableHandler(group);
5884   PrepareReceiverStartReadyHandler(group);
5885   PrepareDisableHandler(group);
5886   PrepareReleaseHandler(group);
5887 
5888   auto* leAudioDevice = group->GetFirstDevice();
5889   LeAudioDevice* lastDevice;
5890   LeAudioDevice* firstDevice = leAudioDevice;
5891 
5892   auto expected_devices_written = 0;
5893   while (leAudioDevice) {
5894     /* Three Writes:
5895      * 1: Codec Config
5896      * 2: Codec QoS
5897      * 3: Enabling
5898      */
5899     lastDevice = leAudioDevice;
5900     EXPECT_CALL(gatt_queue,
5901                 WriteCharacteristic(leAudioDevice->conn_id_,
5902                                     leAudioDevice->ctp_hdls_.val_hdl, _,
5903                                     GATT_WRITE_NO_RSP, _, _))
5904         .Times(AtLeast(3));
5905     expected_devices_written++;
5906     leAudioDevice = group->GetNextDevice(leAudioDevice);
5907   }
5908   ASSERT_EQ(expected_devices_written, num_devices);
5909   ASSERT_NE(nullptr, firstDevice);
5910   ASSERT_NE(nullptr, lastDevice);
5911 
5912   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
5913   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5914 
5915   EXPECT_CALL(*mock_iso_manager_,
5916               SetupIsoDataPath(
5917                   _, dataPathDirIsEq(
5918                          bluetooth::hci::iso_manager::kIsoDataPathDirectionIn)))
5919       .Times(2);
5920 
5921   // Make sure the Out data path is set before we declare that we are ready
5922   {
5923     ::testing::InSequence seq;
5924     EXPECT_CALL(*mock_iso_manager_,
5925                 SetupIsoDataPath(
5926                     UNIQUE_CIS_CONN_HANDLE(leaudio_group_id, 0),
5927                     dataPathDirIsEq(
5928                         bluetooth::hci::iso_manager::kIsoDataPathDirectionOut)))
5929         .Times(1);
5930     EXPECT_CALL(ase_ctp_handler,
5931                 AseCtpReceiverStartReadyHandler(firstDevice, _, _, _))
5932         .Times(1);
5933   }
5934   {
5935     ::testing::InSequence seq;
5936     EXPECT_CALL(*mock_iso_manager_,
5937                 SetupIsoDataPath(
5938                     UNIQUE_CIS_CONN_HANDLE(leaudio_group_id, 1),
5939                     dataPathDirIsEq(
5940                         bluetooth::hci::iso_manager::kIsoDataPathDirectionOut)))
5941         .Times(1);
5942     EXPECT_CALL(ase_ctp_handler,
5943                 AseCtpReceiverStartReadyHandler(lastDevice, _, _, _))
5944         .Times(1);
5945   }
5946 
5947   InjectInitialIdleNotification(group);
5948 
5949   // Start the configuration and stream Conversational content
5950   LeAudioGroupStateMachine::Get()->StartStream(
5951       group, context_type,
5952       {.sink = types::AudioContexts(context_type),
5953        .source = types::AudioContexts(context_type)});
5954 
5955   // Check if group has transitioned to a proper state
5956   ASSERT_EQ(group->GetState(),
5957             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5958   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
5959 
5960   // Verify data path removal on the second bidirectional CIS
5961   EXPECT_CALL(
5962       *mock_iso_manager_,
5963       RemoveIsoDataPath(
5964           UNIQUE_CIS_CONN_HANDLE(leaudio_group_id, 1),
5965           bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionOutput |
5966               bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionInput))
5967       .Times(1);
5968 
5969   // Inject CIS and ACL disconnection of first device
5970   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
5971   InjectAclDisconnected(group, lastDevice);
5972   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
5973 
5974   // Check if group keeps streaming
5975   ASSERT_EQ(group->GetState(),
5976             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
5977 
5978   lastDevice->conn_id_ = 3;
5979   lastDevice->SetConnectionState(DeviceConnectState::CONNECTED);
5980 
5981   // Make sure ASE with disconnected CIS are not left in STREAMING
5982   ASSERT_EQ(lastDevice->GetFirstAseWithState(
5983                 ::bluetooth::le_audio::types::kLeAudioDirectionSink,
5984                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
5985             nullptr);
5986   ASSERT_EQ(lastDevice->GetFirstAseWithState(
5987                 ::bluetooth::le_audio::types::kLeAudioDirectionSource,
5988                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
5989             nullptr);
5990 
5991   EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_,
5992                                               lastDevice->ctp_hdls_.val_hdl, _,
5993                                               GATT_WRITE_NO_RSP, _, _))
5994       .Times(AtLeast(3));
5995 
5996   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
5997   EXPECT_CALL(*mock_iso_manager_,
5998               SetupIsoDataPath(
5999                   _, dataPathDirIsEq(
6000                          bluetooth::hci::iso_manager::kIsoDataPathDirectionIn)))
6001       .Times(1);
6002   // Make sure the Out data path is set before we declare that we are ready
6003   {
6004     ::testing::InSequence seq;
6005     EXPECT_CALL(*mock_iso_manager_,
6006                 SetupIsoDataPath(
6007                     UNIQUE_CIS_CONN_HANDLE(leaudio_group_id, 1),
6008                     dataPathDirIsEq(
6009                         bluetooth::hci::iso_manager::kIsoDataPathDirectionOut)))
6010         .Times(1);
6011     EXPECT_CALL(ase_ctp_handler,
6012                 AseCtpReceiverStartReadyHandler(lastDevice, _, _, _))
6013         .Times(1);
6014   }
6015 
6016   LeAudioGroupStateMachine::Get()->AttachToStream(
6017       group, lastDevice, {.sink = {call_ccid}, .source = {call_ccid}});
6018 
6019   // Check if group keeps streaming
6020   ASSERT_EQ(group->GetState(),
6021             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
6022 
6023   // Verify that the joining device receives the right CCID list
6024   auto lastMeta = lastDevice->GetFirstActiveAse()->metadata;
6025   bool parsedOk = false;
6026   auto ltv = bluetooth::le_audio::types::LeAudioLtvMap::Parse(
6027       lastMeta.data(), lastMeta.size(), parsedOk);
6028   ASSERT_TRUE(parsedOk);
6029 
6030   auto ccids =
6031       ltv.Find(bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList);
6032   ASSERT_TRUE(ccids.has_value());
6033   ASSERT_NE(std::find(ccids->begin(), ccids->end(), call_ccid), ccids->end());
6034 
6035   /* Verify that ASE of first device are still good*/
6036   auto ase = firstDevice->GetFirstActiveAse();
6037   ASSERT_NE(ase->qos_config.max_transport_latency, 0);
6038   ASSERT_NE(ase->qos_config.retrans_nb, 0);
6039 
6040   // Make sure ASEs with reconnected CIS are in STREAMING state
6041   ASSERT_TRUE(lastDevice->HaveAllActiveAsesSameState(
6042       types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING));
6043 }
6044 
TEST_F(StateMachineTest,StartStreamAfterConfigure)6045 TEST_F(StateMachineTest, StartStreamAfterConfigure) {
6046   const auto context_type = kContextTypeMedia;
6047   const auto leaudio_group_id = 6;
6048   const auto num_devices = 2;
6049 
6050   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
6051 
6052   // Prepare multiple fake connected devices in a group
6053   auto* group =
6054       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
6055   ASSERT_EQ(group->Size(), num_devices);
6056 
6057   PrepareConfigureCodecHandler(group, 0, true);
6058   PrepareConfigureQosHandler(group);
6059   PrepareEnableHandler(group);
6060   PrepareDisableHandler(group);
6061   PrepareReleaseHandler(group);
6062 
6063   InjectInitialIdleNotification(group);
6064 
6065   auto* leAudioDevice = group->GetFirstDevice();
6066   auto expected_devices_written = 0;
6067   while (leAudioDevice) {
6068     /* Three Writes:
6069      * 1. Codec configure
6070      * 2: Codec QoS
6071      * 3: Enabling
6072      */
6073     EXPECT_CALL(gatt_queue,
6074                 WriteCharacteristic(leAudioDevice->conn_id_,
6075                                     leAudioDevice->ctp_hdls_.val_hdl, _,
6076                                     GATT_WRITE_NO_RSP, _, _))
6077         .Times(3);
6078     expected_devices_written++;
6079     leAudioDevice = group->GetNextDevice(leAudioDevice);
6080   }
6081   ASSERT_EQ(expected_devices_written, num_devices);
6082 
6083   // Validate GroupStreamStatus
6084   EXPECT_CALL(mock_callbacks_,
6085               StatusReportCb(
6086                   leaudio_group_id,
6087                   bluetooth::le_audio::GroupStreamStatus::CONFIGURED_BY_USER));
6088 
6089   // Start the configuration and stream Media content
6090   group->SetPendingConfiguration();
6091   LeAudioGroupStateMachine::Get()->ConfigureStream(
6092       group, context_type,
6093       {.sink = types::AudioContexts(context_type),
6094        .source = types::AudioContexts(context_type)});
6095 
6096   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6097 
6098   group->ClearPendingConfiguration();
6099   // Validate GroupStreamStatus
6100   EXPECT_CALL(
6101       mock_callbacks_,
6102       StatusReportCb(leaudio_group_id,
6103                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
6104 
6105   // Start the configuration and stream Media content
6106   LeAudioGroupStateMachine::Get()->StartStream(
6107       group, context_type,
6108       {.sink = types::AudioContexts(context_type),
6109        .source = types::AudioContexts(context_type)});
6110 
6111   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6112 }
6113 
TEST_F(StateMachineTest,StartStreamCachedConfig)6114 TEST_F(StateMachineTest, StartStreamCachedConfig) {
6115   const auto context_type = kContextTypeMedia;
6116   const auto leaudio_group_id = 6;
6117   const auto num_devices = 2;
6118 
6119   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
6120 
6121   // Prepare multiple fake connected devices in a group
6122   auto* group =
6123       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
6124   ASSERT_EQ(group->Size(), num_devices);
6125 
6126   PrepareConfigureCodecHandler(group, 0, true);
6127   PrepareConfigureQosHandler(group);
6128   PrepareEnableHandler(group);
6129   PrepareDisableHandler(group);
6130   PrepareReleaseHandler(group);
6131 
6132   InjectInitialIdleNotification(group);
6133 
6134   auto* leAudioDevice = group->GetFirstDevice();
6135   auto expected_devices_written = 0;
6136   while (leAudioDevice) {
6137     /* Three Writes:
6138      * 1: Codec config
6139      * 2: Codec QoS (+1 after restart)
6140      * 3: Enabling (+1 after restart)
6141      * 4: Release (1)
6142      */
6143     EXPECT_CALL(gatt_queue,
6144                 WriteCharacteristic(leAudioDevice->conn_id_,
6145                                     leAudioDevice->ctp_hdls_.val_hdl, _,
6146                                     GATT_WRITE_NO_RSP, _, _))
6147         .Times(6);
6148     expected_devices_written++;
6149     leAudioDevice = group->GetNextDevice(leAudioDevice);
6150   }
6151   ASSERT_EQ(expected_devices_written, num_devices);
6152 
6153   // Validate GroupStreamStatus
6154   EXPECT_CALL(
6155       mock_callbacks_,
6156       StatusReportCb(leaudio_group_id,
6157                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
6158 
6159   // Start the configuration and stream Media content
6160   LeAudioGroupStateMachine::Get()->StartStream(
6161       group, context_type,
6162       {.sink = types::AudioContexts(context_type),
6163        .source = types::AudioContexts(context_type)});
6164 
6165   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6166 
6167   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6168   reset_mock_function_count_map();
6169 
6170   // Validate GroupStreamStatus
6171   EXPECT_CALL(
6172       mock_callbacks_,
6173       StatusReportCb(leaudio_group_id,
6174                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
6175 
6176   EXPECT_CALL(
6177       mock_callbacks_,
6178       StatusReportCb(
6179           leaudio_group_id,
6180           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS));
6181   // Start the configuration and stream Media content
6182   LeAudioGroupStateMachine::Get()->StopStream(group);
6183 
6184   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6185 
6186   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6187   reset_mock_function_count_map();
6188 
6189   // Restart stream
6190   EXPECT_CALL(
6191       mock_callbacks_,
6192       StatusReportCb(leaudio_group_id,
6193                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
6194 
6195   // Start the configuration and stream Media content
6196   LeAudioGroupStateMachine::Get()->StartStream(
6197       group, context_type,
6198       {.sink = types::AudioContexts(context_type),
6199        .source = types::AudioContexts(context_type)});
6200 
6201   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6202   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6203 }
6204 
TEST_F(StateMachineTest,StartStreamCachedConfigReconfigInvalidBehavior)6205 TEST_F(StateMachineTest, StartStreamCachedConfigReconfigInvalidBehavior) {
6206   const auto context_type = kContextTypeConversational;
6207   const auto leaudio_group_id = 6;
6208   const auto num_devices = 1;
6209   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
6210                    kLeAudioCodecChannelCountTwoChannel;
6211 
6212   /* Scenario
6213    * 1. Start stream and stop stream so ASEs stays in Configured State
6214    * 2. Reconfigure ASEs localy, so the QoS parameters are zeroed
6215    * 3. Inject one ASE 2 to be in Releasing state
6216    * 4. Start stream and Incject ASE 1 to go into Codec Configured state
6217    * 5. IN such case CIG shall not be created and fallback to Release and
6218    * Configure stream should happen. Before fix CigCreate with invalid
6219    * parameters were called */
6220   ContentControlIdKeeper::GetInstance()->SetCcid(call_context, call_ccid);
6221 
6222   // Prepare multiple fake connected devices in a group
6223   auto* group =
6224       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
6225   ASSERT_EQ(group->Size(), num_devices);
6226 
6227   PrepareConfigureCodecHandler(group, 0, true);
6228   PrepareConfigureQosHandler(group);
6229   PrepareEnableHandler(group);
6230   PrepareDisableHandler(group);
6231   PrepareReceiverStartReadyHandler(group);
6232   PrepareReleaseHandler(group);
6233 
6234   InjectInitialIdleNotification(group);
6235 
6236   // Validate GroupStreamStatus
6237   EXPECT_CALL(
6238       mock_callbacks_,
6239       StatusReportCb(leaudio_group_id,
6240                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
6241 
6242   EXPECT_CALL(*mock_iso_manager_, CreateCig).Times(1);
6243 
6244   // Start the configuration and stream call content
6245   LeAudioGroupStateMachine::Get()->StartStream(
6246       group, context_type,
6247       {.sink = types::AudioContexts(context_type),
6248        .source = types::AudioContexts(context_type)});
6249 
6250   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6251 
6252   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6253   reset_mock_function_count_map();
6254 
6255   // Validate GroupStreamStatus
6256   EXPECT_CALL(
6257       mock_callbacks_,
6258       StatusReportCb(leaudio_group_id,
6259                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
6260 
6261   EXPECT_CALL(
6262       mock_callbacks_,
6263       StatusReportCb(
6264           leaudio_group_id,
6265           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS));
6266   // Start the configuration and stream Media content
6267   LeAudioGroupStateMachine::Get()->StopStream(group);
6268 
6269   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6270   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
6271 
6272   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6273   reset_mock_function_count_map();
6274 
6275   stop_inject_configured_ase_after_first_ase_configured_ = true;
6276 
6277   auto device = group->GetFirstDevice();
6278   int i = 0;
6279   for (auto& ase : device->ases_) {
6280     if (i++ == 0) continue;
6281 
6282     // Simulate autonomus release for one ASE
6283     InjectAseStateNotification(&ase, device, group, ascs::kAseStateReleasing,
6284                                nullptr);
6285   }
6286 
6287   // Restart stream and expect it will not be created.
6288   EXPECT_CALL(mock_callbacks_,
6289               StatusReportCb(leaudio_group_id,
6290                              bluetooth::le_audio::GroupStreamStatus::STREAMING))
6291       .Times(0);
6292   EXPECT_CALL(mock_callbacks_,
6293               StatusReportCb(leaudio_group_id,
6294                              bluetooth::le_audio::GroupStreamStatus::RELEASING))
6295       .Times(0);
6296 
6297   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(0);
6298 
6299   // Block the fallback Release which will happen when CreateCig will fail
6300   stay_in_releasing_state_ = true;
6301 
6302   // Start the configuration and stream Live content
6303   bool result = LeAudioGroupStateMachine::Get()->StartStream(
6304       group, kContextTypeLive,
6305       {.sink = types::AudioContexts(kContextTypeLive),
6306        .source = types::AudioContexts(kContextTypeLive)});
6307 
6308   // Group internally in releasing state. StartStrean should faile.
6309 
6310   ASSERT_FALSE(result);
6311 
6312   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6313   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
6314 }
6315 
TEST_F(StateMachineTest,BoundedHeadphonesConversationalToMediaChannelCount_2)6316 TEST_F(StateMachineTest, BoundedHeadphonesConversationalToMediaChannelCount_2) {
6317   const auto initial_context_type = kContextTypeConversational;
6318   const auto new_context_type = kContextTypeMedia;
6319   const auto leaudio_group_id = 6;
6320   const auto num_devices = 1;
6321   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
6322                    kLeAudioCodecChannelCountTwoChannel;
6323 
6324   sample_freq_ |= codec_specific::kCapSamplingFrequency48000Hz |
6325                   codec_specific::kCapSamplingFrequency32000Hz;
6326   additional_snk_ases = 3;
6327   additional_src_ases = 1;
6328 
6329   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
6330   ContentControlIdKeeper::GetInstance()->SetCcid(call_context, call_ccid);
6331 
6332   // Prepare multiple fake connected devices in a group
6333   auto* group = PrepareSingleTestDeviceGroup(
6334       leaudio_group_id, initial_context_type, num_devices,
6335       kContextTypeConversational | kContextTypeMedia);
6336   ASSERT_EQ(group->Size(), num_devices);
6337 
6338   PrepareConfigureCodecHandler(group, 0, true);
6339   PrepareConfigureQosHandler(group);
6340   PrepareEnableHandler(group);
6341   PrepareDisableHandler(group);
6342   PrepareReleaseHandler(group);
6343   PrepareReceiverStartReadyHandler(group);
6344 
6345   InjectInitialIdleNotification(group);
6346 
6347   auto* leAudioDevice = group->GetFirstDevice();
6348   auto expected_devices_written = 0;
6349   while (leAudioDevice) {
6350     /* 8 Writes:
6351      * 1: Codec config (+1 after reconfig)
6352      * 2: Codec QoS (+1 after reconfig)
6353      * 3: Enabling (+1 after reconfig)
6354      * 4: ReceiverStartReady (only for conversational)
6355      * 5: Release
6356      */
6357     EXPECT_CALL(gatt_queue,
6358                 WriteCharacteristic(leAudioDevice->conn_id_,
6359                                     leAudioDevice->ctp_hdls_.val_hdl, _,
6360                                     GATT_WRITE_NO_RSP, _, _))
6361         .Times(8);
6362     expected_devices_written++;
6363     leAudioDevice = group->GetNextDevice(leAudioDevice);
6364   }
6365   ASSERT_EQ(expected_devices_written, num_devices);
6366 
6367   // Validate GroupStreamStatus
6368   EXPECT_CALL(
6369       mock_callbacks_,
6370       StatusReportCb(leaudio_group_id,
6371                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
6372 
6373   // Start the configuration and stream Media content
6374   LeAudioGroupStateMachine::Get()->StartStream(
6375       group, initial_context_type,
6376       {.sink = types::AudioContexts(initial_context_type),
6377        .source = types::AudioContexts(initial_context_type)});
6378 
6379   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6380 
6381   auto current_config = group->GetCachedConfiguration(initial_context_type);
6382   ASSERT_NE(nullptr, current_config);
6383   ASSERT_EQ(1lu, current_config->confs.sink.size());
6384   ASSERT_EQ(1lu, current_config->confs.source.size());
6385 
6386   // Validate GroupStreamStatus
6387   EXPECT_CALL(
6388       mock_callbacks_,
6389       StatusReportCb(leaudio_group_id,
6390                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
6391 
6392   EXPECT_CALL(
6393       mock_callbacks_,
6394       StatusReportCb(
6395           leaudio_group_id,
6396           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS));
6397   // Start the configuration and stream Media content
6398   LeAudioGroupStateMachine::Get()->StopStream(group);
6399 
6400   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6401 
6402   // Restart stream
6403   EXPECT_CALL(
6404       mock_callbacks_,
6405       StatusReportCb(leaudio_group_id,
6406                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
6407 
6408   // Start the configuration and stream Media content
6409   LeAudioGroupStateMachine::Get()->StartStream(
6410       group, new_context_type,
6411       {.sink = types::AudioContexts(new_context_type),
6412        .source = types::AudioContexts(new_context_type)});
6413 
6414   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6415 
6416   current_config = group->GetCachedConfiguration(new_context_type);
6417   ASSERT_NE(nullptr, current_config);
6418   ASSERT_EQ(1lu, current_config->confs.sink.size());
6419   ASSERT_EQ(0lu, current_config->confs.source.size());
6420 }
6421 
TEST_F(StateMachineTest,BoundedHeadphonesConversationalToMediaChannelCount_1_MonoMic)6422 TEST_F(StateMachineTest,
6423        BoundedHeadphonesConversationalToMediaChannelCount_1_MonoMic) {
6424   const auto initial_context_type = kContextTypeConversational;
6425   const auto new_context_type = kContextTypeMedia;
6426   const auto leaudio_group_id = 6;
6427   const auto num_devices = 1;
6428   // Single audio allocation for the mono source
6429   channel_allocations_source_ =
6430       ::bluetooth::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft;
6431   channel_count_ = kLeAudioCodecChannelCountSingleChannel;
6432 
6433   sample_freq_ |= codec_specific::kCapSamplingFrequency48000Hz |
6434                   codec_specific::kCapSamplingFrequency32000Hz;
6435   additional_snk_ases = 3;
6436   additional_src_ases = 1;
6437 
6438   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
6439   ContentControlIdKeeper::GetInstance()->SetCcid(call_context, call_ccid);
6440 
6441   // Prepare one fake connected devices in a group
6442   auto* group = PrepareSingleTestDeviceGroup(
6443       leaudio_group_id, initial_context_type, num_devices,
6444       kContextTypeConversational | kContextTypeMedia);
6445   ASSERT_EQ(group->Size(), num_devices);
6446 
6447   // Cannot verify here as we will change the number of ases on reconfigure
6448   PrepareConfigureCodecHandler(group, 0, true);
6449   PrepareConfigureQosHandler(group);
6450   PrepareEnableHandler(group);
6451   PrepareDisableHandler(group);
6452   PrepareReleaseHandler(group);
6453   PrepareReceiverStartReadyHandler(group);
6454 
6455   InjectInitialIdleNotification(group);
6456 
6457   auto* leAudioDevice = group->GetFirstDevice();
6458   auto expected_devices_written = 0;
6459   while (leAudioDevice) {
6460     /* 8 Writes:
6461      * 1: Codec config (+1 after reconfig)
6462      * 2: Codec QoS (+1 after reconfig)
6463      * 3: Enabling (+1 after reconfig)
6464      * 4: ReceiverStartReady (only for conversational)
6465      * 5: Release
6466      */
6467     EXPECT_CALL(gatt_queue,
6468                 WriteCharacteristic(leAudioDevice->conn_id_,
6469                                     leAudioDevice->ctp_hdls_.val_hdl, _,
6470                                     GATT_WRITE_NO_RSP, _, _))
6471         .Times(8);
6472     expected_devices_written++;
6473     leAudioDevice = group->GetNextDevice(leAudioDevice);
6474   }
6475   ASSERT_EQ(expected_devices_written, num_devices);
6476 
6477   // Validate GroupStreamStatus
6478   EXPECT_CALL(
6479       mock_callbacks_,
6480       StatusReportCb(leaudio_group_id,
6481                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
6482 
6483   // Start the configuration and stream Media content
6484   LeAudioGroupStateMachine::Get()->StartStream(
6485       group, initial_context_type,
6486       {.sink = types::AudioContexts(initial_context_type),
6487        .source = types::AudioContexts(initial_context_type)});
6488 
6489   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6490 
6491   auto current_config = group->GetCachedConfiguration(initial_context_type);
6492   ASSERT_NE(nullptr, current_config);
6493   // sink has two locations
6494   ASSERT_EQ(2lu, current_config->confs.sink.size());
6495   // source has a single location
6496   ASSERT_EQ(1lu, current_config->confs.source.size());
6497 
6498   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6499   reset_mock_function_count_map();
6500 
6501   // Validate GroupStreamStatus
6502   EXPECT_CALL(
6503       mock_callbacks_,
6504       StatusReportCb(leaudio_group_id,
6505                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
6506 
6507   EXPECT_CALL(
6508       mock_callbacks_,
6509       StatusReportCb(
6510           leaudio_group_id,
6511           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS));
6512   // Start the configuration and stream Media content
6513   LeAudioGroupStateMachine::Get()->StopStream(group);
6514 
6515   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6516   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6517   reset_mock_function_count_map();
6518 
6519   // Restart stream
6520   EXPECT_CALL(
6521       mock_callbacks_,
6522       StatusReportCb(leaudio_group_id,
6523                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
6524 
6525   // Start the configuration and stream Media content
6526   LeAudioGroupStateMachine::Get()->StartStream(
6527       group, new_context_type,
6528       {.sink = types::AudioContexts(new_context_type),
6529        .source = types::AudioContexts(new_context_type)});
6530 
6531   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6532   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6533 
6534   current_config = group->GetCachedConfiguration(new_context_type);
6535   ASSERT_NE(nullptr, current_config);
6536   ASSERT_EQ(2lu, current_config->confs.sink.size());
6537   ASSERT_EQ(0lu, current_config->confs.source.size());
6538 }
6539 
TEST_F(StateMachineTest,DISABLED_BoundedHeadphonesConversationalToMediaChannelCount_1_StereoMic)6540 TEST_F(
6541     StateMachineTest,
6542     DISABLED_BoundedHeadphonesConversationalToMediaChannelCount_1_StereoMic) {
6543   const auto initial_context_type = kContextTypeConversational;
6544   const auto new_context_type = kContextTypeMedia;
6545   const auto leaudio_group_id = 6;
6546   const auto num_devices = 1;
6547   channel_allocations_source_ =
6548       ::bluetooth::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft |
6549       ::bluetooth::le_audio::codec_spec_conf::kLeAudioLocationFrontRight;
6550   channel_count_ = kLeAudioCodecChannelCountSingleChannel;
6551 
6552   sample_freq_ |= codec_specific::kCapSamplingFrequency48000Hz |
6553                   codec_specific::kCapSamplingFrequency32000Hz;
6554   additional_snk_ases = 3;
6555   additional_src_ases = 1;
6556 
6557   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
6558   ContentControlIdKeeper::GetInstance()->SetCcid(call_context, call_ccid);
6559 
6560   // Prepare one fake connected devices in a group
6561   auto* group = PrepareSingleTestDeviceGroup(
6562       leaudio_group_id, initial_context_type, num_devices,
6563       kContextTypeConversational | kContextTypeMedia);
6564   ASSERT_EQ(group->Size(), num_devices);
6565 
6566   // Cannot verify here as we will change the number of ases on reconfigure
6567   PrepareConfigureCodecHandler(group, 0, true);
6568   PrepareConfigureQosHandler(group);
6569   PrepareEnableHandler(group);
6570   PrepareDisableHandler(group);
6571   PrepareReleaseHandler(group);
6572   PrepareReceiverStartReadyHandler(group);
6573 
6574   InjectInitialIdleNotification(group);
6575 
6576   auto* leAudioDevice = group->GetFirstDevice();
6577   auto expected_devices_written = 0;
6578   while (leAudioDevice) {
6579     /* 8 Writes:
6580      * 1: Codec config (+1 after reconfig)
6581      * 2: Codec QoS (+1 after reconfig)
6582      * 3: Enabling (+1 after reconfig)
6583      * 4: ReceiverStartReady (only for conversational)
6584      * 5: Release
6585      */
6586     EXPECT_CALL(gatt_queue,
6587                 WriteCharacteristic(leAudioDevice->conn_id_,
6588                                     leAudioDevice->ctp_hdls_.val_hdl, _,
6589                                     GATT_WRITE_NO_RSP, _, _))
6590         .Times(8);
6591     expected_devices_written++;
6592     leAudioDevice = group->GetNextDevice(leAudioDevice);
6593   }
6594   ASSERT_EQ(expected_devices_written, num_devices);
6595 
6596   // Validate GroupStreamStatus
6597   EXPECT_CALL(
6598       mock_callbacks_,
6599       StatusReportCb(leaudio_group_id,
6600                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
6601 
6602   // Start the configuration and stream Media content
6603   LeAudioGroupStateMachine::Get()->StartStream(
6604       group, initial_context_type,
6605       {.sink = types::AudioContexts(initial_context_type),
6606        .source = types::AudioContexts(initial_context_type)});
6607 
6608   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6609 
6610   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6611   reset_mock_function_count_map();
6612 
6613   auto current_config = group->GetCachedConfiguration(initial_context_type);
6614   ASSERT_NE(nullptr, current_config);
6615   ASSERT_EQ(2lu, current_config->confs.sink.size());
6616   ASSERT_EQ(2lu, current_config->confs.source.size());
6617 
6618   // Validate GroupStreamStatus
6619   EXPECT_CALL(
6620       mock_callbacks_,
6621       StatusReportCb(leaudio_group_id,
6622                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
6623 
6624   EXPECT_CALL(
6625       mock_callbacks_,
6626       StatusReportCb(
6627           leaudio_group_id,
6628           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS));
6629   // Start the configuration and stream Media content
6630   LeAudioGroupStateMachine::Get()->StopStream(group);
6631 
6632   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6633   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6634   reset_mock_function_count_map();
6635 
6636   // Restart stream
6637   EXPECT_CALL(
6638       mock_callbacks_,
6639       StatusReportCb(leaudio_group_id,
6640                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
6641 
6642   // Start the configuration and stream Media content
6643   LeAudioGroupStateMachine::Get()->StartStream(
6644       group, new_context_type,
6645       {.sink = types::AudioContexts(new_context_type),
6646        .source = types::AudioContexts(new_context_type)});
6647 
6648   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6649   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6650 
6651   current_config = group->GetCachedConfiguration(new_context_type);
6652   ASSERT_NE(nullptr, current_config);
6653   ASSERT_EQ(2lu, current_config->confs.sink.size());
6654   ASSERT_EQ(0lu, current_config->confs.source.size());
6655 }
6656 
TEST_F(StateMachineTest,lateCisDisconnectedEvent_DuringReconfiguration)6657 TEST_F(StateMachineTest, lateCisDisconnectedEvent_DuringReconfiguration) {
6658   const auto context_type = kContextTypeMedia;
6659   const auto leaudio_group_id = 6;
6660   const auto num_devices = 1;
6661 
6662   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
6663 
6664   // Prepare multiple fake connected devices in a group
6665   auto* group =
6666       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
6667   ASSERT_EQ(group->Size(), num_devices);
6668 
6669   PrepareConfigureCodecHandler(group, 0, true);
6670   PrepareConfigureQosHandler(group);
6671   PrepareEnableHandler(group);
6672   PrepareDisableHandler(group);
6673   PrepareReleaseHandler(group);
6674 
6675   auto* leAudioDevice = group->GetFirstDevice();
6676   auto expected_devices_written = 0;
6677 
6678   /* Three Writes:
6679    * 1: Codec Config
6680    * 2: Codec QoS
6681    * 3: Enabling
6682    */
6683   EXPECT_CALL(gatt_queue, WriteCharacteristic(leAudioDevice->conn_id_,
6684                                               leAudioDevice->ctp_hdls_.val_hdl,
6685                                               _, GATT_WRITE_NO_RSP, _, _))
6686       .Times(AtLeast(3));
6687   expected_devices_written++;
6688 
6689   ASSERT_EQ(expected_devices_written, num_devices);
6690 
6691   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
6692   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
6693   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
6694 
6695   InjectInitialIdleNotification(group);
6696 
6697   // Start the configuration and stream Media content
6698   LeAudioGroupStateMachine::Get()->StartStream(
6699       group, context_type,
6700       {.sink = types::AudioContexts(context_type),
6701        .source = types::AudioContexts(context_type)});
6702 
6703   // Check if group has transitioned to a proper state
6704   ASSERT_EQ(group->GetState(),
6705             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
6706   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
6707 
6708   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6709   reset_mock_function_count_map();
6710 
6711   /* Prepare DisconnectCis mock to not symulate CisDisconnection */
6712   ON_CALL(*mock_iso_manager_, DisconnectCis).WillByDefault(Return());
6713 
6714   /* Do reconfiguration */
6715   group->SetPendingConfiguration();
6716 
6717   // Validate GroupStreamStatus
6718   EXPECT_CALL(
6719       mock_callbacks_,
6720       StatusReportCb(leaudio_group_id,
6721                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
6722 
6723   EXPECT_CALL(
6724       mock_callbacks_,
6725       StatusReportCb(
6726           leaudio_group_id,
6727           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS))
6728       .Times(0);
6729   LeAudioGroupStateMachine::Get()->StopStream(group);
6730 
6731   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6732 
6733   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
6734 
6735   EXPECT_CALL(
6736       mock_callbacks_,
6737       StatusReportCb(
6738           leaudio_group_id,
6739           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS));
6740 
6741   // Inject CIS and ACL disconnection of first device
6742   InjectCisDisconnected(group, leAudioDevice, HCI_ERR_CONN_CAUSE_LOCAL_HOST);
6743   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6744   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6745 }
6746 
TEST_F(StateMachineTest,lateCisDisconnectedEvent_AutonomousConfigured)6747 TEST_F(StateMachineTest, lateCisDisconnectedEvent_AutonomousConfigured) {
6748   const auto context_type = kContextTypeMedia;
6749   const auto leaudio_group_id = 6;
6750   const auto num_devices = 1;
6751 
6752   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
6753 
6754   // Prepare multiple fake connected devices in a group
6755   auto* group =
6756       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
6757   ASSERT_EQ(group->Size(), num_devices);
6758 
6759   PrepareConfigureCodecHandler(group, 0, true);
6760   PrepareConfigureQosHandler(group);
6761   PrepareEnableHandler(group);
6762   PrepareDisableHandler(group);
6763   PrepareReleaseHandler(group);
6764 
6765   auto* leAudioDevice = group->GetFirstDevice();
6766   auto expected_devices_written = 0;
6767 
6768   /* Three Writes:
6769    * 1: Codec Config
6770    * 2: Codec QoS
6771    * 3: Enabling
6772    */
6773   EXPECT_CALL(gatt_queue, WriteCharacteristic(leAudioDevice->conn_id_,
6774                                               leAudioDevice->ctp_hdls_.val_hdl,
6775                                               _, GATT_WRITE_NO_RSP, _, _))
6776       .Times(AtLeast(3));
6777   expected_devices_written++;
6778 
6779   ASSERT_EQ(expected_devices_written, num_devices);
6780 
6781   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
6782   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
6783   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
6784 
6785   InjectInitialIdleNotification(group);
6786 
6787   // Start the configuration and stream Media content
6788   LeAudioGroupStateMachine::Get()->StartStream(
6789       group, context_type,
6790       {.sink = types::AudioContexts(context_type),
6791        .source = types::AudioContexts(context_type)});
6792 
6793   // Check if group has transitioned to a proper state
6794   ASSERT_EQ(group->GetState(),
6795             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
6796   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
6797 
6798   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6799   reset_mock_function_count_map();
6800 
6801   /* Prepare DisconnectCis mock to not symulate CisDisconnection */
6802   ON_CALL(*mock_iso_manager_, DisconnectCis).WillByDefault(Return());
6803 
6804   // Validate GroupStreamStatus
6805   EXPECT_CALL(
6806       mock_callbacks_,
6807       StatusReportCb(leaudio_group_id,
6808                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
6809 
6810   EXPECT_CALL(
6811       mock_callbacks_,
6812       StatusReportCb(
6813           leaudio_group_id,
6814           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS))
6815       .Times(0);
6816 
6817   // Stop the stream
6818   LeAudioGroupStateMachine::Get()->StopStream(group);
6819 
6820   // Check if group has transitioned to a proper state
6821   ASSERT_EQ(group->GetState(),
6822             types::AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED);
6823 
6824   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6825 
6826   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
6827 
6828   EXPECT_CALL(
6829       mock_callbacks_,
6830       StatusReportCb(
6831           leaudio_group_id,
6832           bluetooth::le_audio::GroupStreamStatus::CONFIGURED_AUTONOMOUS));
6833 
6834   // Inject CIS and ACL disconnection of first device
6835   InjectCisDisconnected(group, leAudioDevice, HCI_ERR_CONN_CAUSE_LOCAL_HOST);
6836   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6837   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6838 }
6839 
TEST_F(StateMachineTest,lateCisDisconnectedEvent_Idle)6840 TEST_F(StateMachineTest, lateCisDisconnectedEvent_Idle) {
6841   const auto context_type = kContextTypeMedia;
6842   const auto leaudio_group_id = 6;
6843   const auto num_devices = 1;
6844 
6845   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
6846 
6847   // Prepare multiple fake connected devices in a group
6848   auto* group =
6849       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
6850   ASSERT_EQ(group->Size(), num_devices);
6851 
6852   PrepareConfigureCodecHandler(group);
6853   PrepareConfigureQosHandler(group);
6854   PrepareEnableHandler(group);
6855   PrepareDisableHandler(group);
6856   PrepareReleaseHandler(group);
6857 
6858   auto* leAudioDevice = group->GetFirstDevice();
6859   auto expected_devices_written = 0;
6860 
6861   /* Three Writes:
6862    * 1: Codec Config
6863    * 2: Codec QoS
6864    * 3: Enabling
6865    */
6866   EXPECT_CALL(gatt_queue, WriteCharacteristic(leAudioDevice->conn_id_,
6867                                               leAudioDevice->ctp_hdls_.val_hdl,
6868                                               _, GATT_WRITE_NO_RSP, _, _))
6869       .Times(AtLeast(3));
6870   expected_devices_written++;
6871 
6872   ASSERT_EQ(expected_devices_written, num_devices);
6873 
6874   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
6875   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
6876   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
6877 
6878   InjectInitialIdleNotification(group);
6879 
6880   // Start the configuration and stream Media content
6881   LeAudioGroupStateMachine::Get()->StartStream(
6882       group, context_type,
6883       {.sink = types::AudioContexts(context_type),
6884        .source = types::AudioContexts(context_type)});
6885 
6886   // Check if group has transitioned to a proper state
6887   ASSERT_EQ(group->GetState(),
6888             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
6889   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
6890 
6891   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6892   reset_mock_function_count_map();
6893   /* Prepare DisconnectCis mock to not symulate CisDisconnection */
6894   ON_CALL(*mock_iso_manager_, DisconnectCis).WillByDefault(Return());
6895 
6896   // Validate GroupStreamStatus
6897   EXPECT_CALL(
6898       mock_callbacks_,
6899       StatusReportCb(leaudio_group_id,
6900                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
6901 
6902   EXPECT_CALL(mock_callbacks_,
6903               StatusReportCb(leaudio_group_id,
6904                              bluetooth::le_audio::GroupStreamStatus::IDLE))
6905       .Times(0);
6906 
6907   // Stop the stream
6908   LeAudioGroupStateMachine::Get()->StopStream(group);
6909 
6910   // Check if group has transitioned to a proper state
6911   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
6912   ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
6913 
6914   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6915 
6916   EXPECT_CALL(mock_callbacks_,
6917               StatusReportCb(leaudio_group_id,
6918                              bluetooth::le_audio::GroupStreamStatus::IDLE));
6919 
6920   // Inject CIS and ACL disconnection of first device
6921   InjectCisDisconnected(group, leAudioDevice, HCI_ERR_CONN_CAUSE_LOCAL_HOST);
6922   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6923   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6924 }
6925 
TEST_F(StateMachineTest,StreamReconfigureAfterCisLostTwoDevices)6926 TEST_F(StateMachineTest, StreamReconfigureAfterCisLostTwoDevices) {
6927   auto context_type = kContextTypeConversational;
6928   const auto leaudio_group_id = 4;
6929   const auto num_devices = 2;
6930 
6931   // Prepare multiple fake connected devices in a group
6932   auto* group = PrepareSingleTestDeviceGroup(
6933       leaudio_group_id, context_type, num_devices,
6934       kContextTypeConversational | kContextTypeMedia);
6935   ASSERT_EQ(group->Size(), num_devices);
6936 
6937   PrepareConfigureCodecHandler(group);
6938   PrepareConfigureQosHandler(group);
6939   PrepareEnableHandler(group);
6940   PrepareReceiverStartReadyHandler(group);
6941 
6942   /* Prepare DisconnectCis mock to not symulate CisDisconnection */
6943   ON_CALL(*mock_iso_manager_, DisconnectCis).WillByDefault(Return());
6944 
6945   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
6946   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
6947   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
6948   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
6949 
6950   InjectInitialIdleNotification(group);
6951 
6952   auto* leAudioDevice = group->GetFirstDevice();
6953   auto expected_devices_written = 0;
6954   while (leAudioDevice) {
6955     EXPECT_CALL(gatt_queue,
6956                 WriteCharacteristic(leAudioDevice->conn_id_,
6957                                     leAudioDevice->ctp_hdls_.val_hdl, _,
6958                                     GATT_WRITE_NO_RSP, _, _))
6959         .Times(3);
6960     expected_devices_written++;
6961     leAudioDevice = group->GetNextDevice(leAudioDevice);
6962   }
6963   ASSERT_EQ(expected_devices_written, num_devices);
6964 
6965   // Validate GroupStreamStatus
6966   EXPECT_CALL(
6967       mock_callbacks_,
6968       StatusReportCb(leaudio_group_id,
6969                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
6970 
6971   // Start the configuration and stream Media content
6972   context_type = kContextTypeMedia;
6973   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
6974       group, context_type,
6975       {.sink = types::AudioContexts(context_type),
6976        .source = types::AudioContexts(context_type)}));
6977 
6978   // Check if group has transitioned to a proper state
6979   ASSERT_EQ(group->GetState(),
6980             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
6981   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
6982   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
6983   testing::Mock::VerifyAndClearExpectations(&gatt_queue);
6984   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
6985 
6986   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
6987   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
6988   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(4);
6989   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(2);
6990   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
6991 
6992   // Device disconnects due to timeout of CIS
6993   leAudioDevice = group->GetFirstDevice();
6994   while (leAudioDevice) {
6995     InjectCisDisconnected(group, leAudioDevice, HCI_ERR_CONN_CAUSE_LOCAL_HOST);
6996     // Disconnect device
6997     LeAudioGroupStateMachine::Get()->ProcessHciNotifAclDisconnected(
6998         group, leAudioDevice);
6999 
7000     leAudioDevice = group->GetNextDevice(leAudioDevice);
7001   }
7002 
7003   group->ReloadAudioLocations();
7004   group->ReloadAudioDirections();
7005 
7006   // Start conversational scenario
7007   leAudioDevice = group->GetFirstDevice();
7008   int device_cnt = num_devices;
7009   while (leAudioDevice) {
7010     leAudioDevice->conn_id_ = device_cnt--;
7011     leAudioDevice->SetConnectionState(DeviceConnectState::CONNECTED);
7012     leAudioDevice = group->GetNextDevice(leAudioDevice);
7013   }
7014 
7015   InjectInitialIdleNotification(group);
7016 
7017   group->ReloadAudioLocations();
7018   group->ReloadAudioDirections();
7019 
7020   leAudioDevice = group->GetFirstDevice();
7021   expected_devices_written = 0;
7022   while (leAudioDevice) {
7023     EXPECT_CALL(gatt_queue,
7024                 WriteCharacteristic(leAudioDevice->conn_id_,
7025                                     leAudioDevice->ctp_hdls_.val_hdl, _,
7026                                     GATT_WRITE_NO_RSP, _, _))
7027         .Times(4);
7028     expected_devices_written++;
7029     leAudioDevice = group->GetNextDevice(leAudioDevice);
7030   }
7031   ASSERT_EQ(expected_devices_written, num_devices);
7032 
7033   // Validate GroupStreamStatus
7034   EXPECT_CALL(
7035       mock_callbacks_,
7036       StatusReportCb(leaudio_group_id,
7037                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
7038 
7039   // Start the configuration and stream Conversational content
7040   context_type = kContextTypeConversational;
7041   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
7042       group, context_type,
7043       {.sink = types::AudioContexts(context_type),
7044        .source = types::AudioContexts(context_type)}));
7045 
7046   // Check if group has transitioned to a proper state
7047   ASSERT_EQ(group->GetState(),
7048             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7049   ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
7050   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
7051   testing::Mock::VerifyAndClearExpectations(&gatt_queue);
7052   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
7053 }
7054 
TEST_F(StateMachineTest,StreamClearAfterReleaseAndConnectionTimeout)7055 TEST_F(StateMachineTest, StreamClearAfterReleaseAndConnectionTimeout) {
7056   auto context_type = kContextTypeMedia;
7057   const auto leaudio_group_id = 4;
7058   const auto num_devices = 2;
7059 
7060   /* Scenario
7061   1. Streaming to 2 device
7062   2. Stream suspend
7063   3. One device got to IDLE
7064   4. Second device Connection Timeout
7065   */
7066 
7067   // Prepare multiple fake connected devices in a group
7068   auto* group = PrepareSingleTestDeviceGroup(
7069       leaudio_group_id, context_type, num_devices,
7070       kContextTypeConversational | kContextTypeMedia);
7071   ASSERT_EQ(group->Size(), num_devices);
7072 
7073   PrepareConfigureCodecHandler(group);
7074   PrepareConfigureQosHandler(group);
7075   PrepareEnableHandler(group);
7076 
7077   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
7078   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
7079   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
7080   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(2);
7081   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(1);
7082   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1);
7083 
7084   InjectInitialIdleNotification(group);
7085 
7086   auto* leAudioDevice = group->GetFirstDevice();
7087   auto* firstDevice = leAudioDevice;
7088   auto* lastDevice = leAudioDevice;
7089 
7090   while (leAudioDevice) {
7091     lastDevice = leAudioDevice;
7092     leAudioDevice = group->GetNextDevice(leAudioDevice);
7093   }
7094 
7095   // Validate GroupStreamStatus
7096   EXPECT_CALL(
7097       mock_callbacks_,
7098       StatusReportCb(leaudio_group_id,
7099                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
7100 
7101   // Start the configuration and stream Media content
7102   context_type = kContextTypeMedia;
7103   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
7104       group, context_type,
7105       {.sink = types::AudioContexts(context_type),
7106        .source = types::AudioContexts(context_type)}));
7107 
7108   // Check if group has transitioned to a proper state
7109   ASSERT_EQ(group->GetState(),
7110             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7111   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
7112   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
7113 
7114   EXPECT_CALL(
7115       mock_callbacks_,
7116       StatusReportCb(leaudio_group_id,
7117                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
7118   EXPECT_CALL(mock_callbacks_,
7119               StatusReportCb(leaudio_group_id,
7120                              bluetooth::le_audio::GroupStreamStatus::IDLE));
7121 
7122   /* Prepare release handler only for first device. */
7123   PrepareReleaseHandler(group, 0, false, firstDevice);
7124   LeAudioGroupStateMachine::Get()->StopStream(group);
7125 
7126   /* Second device will disconnect because of timeout. Do not bother
7127    * with remove data path response from the controller. In test we are doing it
7128    * in a test thread which breaks things. */
7129   ON_CALL(*mock_iso_manager_, RemoveIsoDataPath).WillByDefault(Return());
7130   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
7131   InjectAclDisconnected(group, lastDevice);
7132 
7133   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
7134   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
7135 }
7136 
TEST_F(StateMachineTest,VerifyThereIsNoDoubleDataPathRemoval)7137 TEST_F(StateMachineTest, VerifyThereIsNoDoubleDataPathRemoval) {
7138   auto context_type = kContextTypeConversational;
7139   const auto leaudio_group_id = 4;
7140   const auto num_devices = 1;
7141 
7142   /* Symulate banded headphonse */
7143   channel_count_ = kLeAudioCodecChannelCountSingleChannel |
7144                    kLeAudioCodecChannelCountTwoChannel;
7145 
7146   /* Scenario
7147   1. Phone call to 1 device
7148   2. Stop the stream
7149   3. Get both ASE sink and Source to releasing
7150   4. Verify only 1 RemoveDataPath is called
7151   */
7152 
7153   // Prepare multiple fake connected devices in a group
7154   auto* group = PrepareSingleTestDeviceGroup(
7155       leaudio_group_id, context_type, num_devices,
7156       kContextTypeConversational | kContextTypeMedia);
7157   ASSERT_EQ(group->Size(), num_devices);
7158 
7159   PrepareConfigureCodecHandler(group);
7160   PrepareConfigureQosHandler(group);
7161   PrepareEnableHandler(group);
7162   PrepareReleaseHandler(group);
7163   PrepareReceiverStartReadyHandler(group);
7164 
7165   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
7166   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
7167   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
7168   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(1);
7169 
7170   /*Test ends before full clean*/
7171   EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0);
7172   EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(0);
7173 
7174   InjectInitialIdleNotification(group);
7175 
7176   // Validate GroupStreamStatus
7177   EXPECT_CALL(
7178       mock_callbacks_,
7179       StatusReportCb(leaudio_group_id,
7180                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
7181 
7182   ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream(
7183       group, context_type,
7184       {.sink = types::AudioContexts(context_type),
7185        .source = types::AudioContexts(context_type)}));
7186 
7187   // Check if group has transitioned to a proper state
7188   ASSERT_EQ(group->GetState(),
7189             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7190   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
7191   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
7192 
7193   EXPECT_CALL(
7194       mock_callbacks_,
7195       StatusReportCb(leaudio_group_id,
7196                      bluetooth::le_audio::GroupStreamStatus::RELEASING));
7197 
7198   /* Do not trigger any action on removeIsoData path.*/
7199   ON_CALL(*mock_iso_manager_, RemoveIsoDataPath).WillByDefault(Return());
7200 
7201   LeAudioGroupStateMachine::Get()->StopStream(group);
7202 
7203   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
7204   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
7205 }
7206 
TEST_F(StateMachineTest,StreamStartWithDifferentContextFromConfiguredState)7207 TEST_F(StateMachineTest, StreamStartWithDifferentContextFromConfiguredState) {
7208   auto context_type = kContextTypeConversational;
7209   const auto leaudio_group_id = 6;
7210   const auto num_devices = 2;
7211 
7212   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
7213 
7214   // Prepare multiple fake connected devices in a group
7215   auto* group = PrepareSingleTestDeviceGroup(
7216       leaudio_group_id, context_type, num_devices,
7217       kContextTypeConversational | kContextTypeMedia);
7218   ASSERT_EQ(group->Size(), num_devices);
7219 
7220   PrepareConfigureCodecHandler(group, 0, true);
7221   PrepareConfigureQosHandler(group);
7222   PrepareEnableHandler(group);
7223   PrepareDisableHandler(group);
7224   PrepareReleaseHandler(group);
7225   PrepareReceiverStartReadyHandler(group);
7226 
7227   InjectInitialIdleNotification(group);
7228 
7229   auto* leAudioDevice = group->GetFirstDevice();
7230   auto expected_devices_written = 0;
7231   while (leAudioDevice) {
7232     /* Three Writes:
7233      * 1. Codec configure
7234      * 2: Codec QoS
7235      * 3: Enabling
7236      */
7237     EXPECT_CALL(gatt_queue,
7238                 WriteCharacteristic(leAudioDevice->conn_id_,
7239                                     leAudioDevice->ctp_hdls_.val_hdl, _,
7240                                     GATT_WRITE_NO_RSP, _, _))
7241         .Times(4);
7242     expected_devices_written++;
7243     leAudioDevice = group->GetNextDevice(leAudioDevice);
7244   }
7245   ASSERT_EQ(expected_devices_written, num_devices);
7246 
7247   // Validate GroupStreamStatus
7248   EXPECT_CALL(mock_callbacks_,
7249               StatusReportCb(
7250                   leaudio_group_id,
7251                   bluetooth::le_audio::GroupStreamStatus::CONFIGURED_BY_USER));
7252 
7253   // Start the configuration and stream Media content
7254   group->SetPendingConfiguration();
7255   LeAudioGroupStateMachine::Get()->ConfigureStream(
7256       group, context_type,
7257       {.sink = types::AudioContexts(context_type),
7258        .source = types::AudioContexts(context_type)});
7259 
7260   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
7261 
7262   group->ClearPendingConfiguration();
7263   // Validate GroupStreamStatus
7264   EXPECT_CALL(
7265       mock_callbacks_,
7266       StatusReportCb(leaudio_group_id,
7267                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
7268 
7269   context_type = kContextTypeMedia;
7270   // Start the configuration and stream Media content
7271   LeAudioGroupStateMachine::Get()->StartStream(
7272       group, context_type,
7273       {.sink = types::AudioContexts(context_type),
7274        .source = types::AudioContexts(context_type)});
7275 
7276   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
7277 }
7278 
TEST_F(StateMachineTest,StreamStartWithSameContextFromConfiguredStateButNewMetadata)7279 TEST_F(StateMachineTest,
7280        StreamStartWithSameContextFromConfiguredStateButNewMetadata) {
7281   auto context_type = kContextTypeConversational;
7282   const auto leaudio_group_id = 6;
7283   const auto num_devices = 2;
7284 
7285   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
7286 
7287   // Prepare multiple fake connected devices in a group
7288   auto* group = PrepareSingleTestDeviceGroup(
7289       leaudio_group_id, context_type, num_devices,
7290       kContextTypeConversational | kContextTypeLive);
7291   ASSERT_EQ(group->Size(), num_devices);
7292 
7293   PrepareConfigureCodecHandler(group, 0, true);
7294   PrepareConfigureQosHandler(group);
7295   PrepareEnableHandler(group);
7296   PrepareDisableHandler(group);
7297   PrepareReleaseHandler(group);
7298   PrepareReceiverStartReadyHandler(group);
7299 
7300   InjectInitialIdleNotification(group);
7301 
7302   auto* leAudioDevice = group->GetFirstDevice();
7303   LeAudioDevice* firstActiveDevice = leAudioDevice;
7304   auto expected_devices_written = 0;
7305   while (leAudioDevice) {
7306     /* Three Writes:
7307      * 1. Codec configure
7308      * 2: Codec QoS
7309      * 3: Enabling
7310      */
7311     EXPECT_CALL(gatt_queue,
7312                 WriteCharacteristic(leAudioDevice->conn_id_,
7313                                     leAudioDevice->ctp_hdls_.val_hdl, _,
7314                                     GATT_WRITE_NO_RSP, _, _))
7315         .Times(4);
7316     expected_devices_written++;
7317     leAudioDevice = group->GetNextDevice(leAudioDevice);
7318   }
7319   ASSERT_EQ(expected_devices_written, num_devices);
7320 
7321   // Validate GroupStreamStatus
7322   EXPECT_CALL(mock_callbacks_,
7323               StatusReportCb(
7324                   leaudio_group_id,
7325                   bluetooth::le_audio::GroupStreamStatus::CONFIGURED_BY_USER));
7326 
7327   // Start the configuration and stream Media content
7328   group->SetPendingConfiguration();
7329   LeAudioGroupStateMachine::Get()->ConfigureStream(
7330       group, context_type,
7331       {.sink = types::AudioContexts(context_type),
7332        .source = types::AudioContexts(context_type)});
7333 
7334   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
7335 
7336   group->ClearPendingConfiguration();
7337   // Validate GroupStreamStatus
7338   EXPECT_CALL(
7339       mock_callbacks_,
7340       StatusReportCb(leaudio_group_id,
7341                      bluetooth::le_audio::GroupStreamStatus::STREAMING));
7342 
7343   auto metadata_context_type = kContextTypeLive;
7344   types::BidirectionalPair<std::vector<uint8_t>> ccid_lists = {
7345       .sink = {media_ccid}, .source = {media_ccid}};
7346 
7347   // Start the configuration and stream Media content
7348   LeAudioGroupStateMachine::Get()->StartStream(
7349       group, context_type,
7350       {.sink = types::AudioContexts(metadata_context_type),
7351        .source = types::AudioContexts(metadata_context_type)},
7352       ccid_lists);
7353 
7354   testing::Mock::VerifyAndClearExpectations(&mock_callbacks_);
7355 
7356   // Verify that the joining device receives the right CCID list
7357   auto lastMeta = firstActiveDevice->GetFirstActiveAse()->metadata;
7358   bool parsedOk = false;
7359   auto ltv = bluetooth::le_audio::types::LeAudioLtvMap::Parse(
7360       lastMeta.data(), lastMeta.size(), parsedOk);
7361   ASSERT_TRUE(parsedOk);
7362 
7363   auto ccids =
7364       ltv.Find(bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList);
7365   ASSERT_TRUE(ccids.has_value());
7366   ASSERT_NE(std::find(ccids->begin(), ccids->end(), media_ccid), ccids->end());
7367 }
7368 
TEST_F(StateMachineTest,testAttachDeviceToTheStreamCisFailure)7369 TEST_F(StateMachineTest, testAttachDeviceToTheStreamCisFailure) {
7370   const auto context_type = kContextTypeMedia;
7371   const auto leaudio_group_id = 6;
7372   const auto num_devices = 2;
7373 
7374   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
7375 
7376   // Prepare multiple fake connected devices in a group
7377   auto* group =
7378       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
7379   ASSERT_EQ(group->Size(), num_devices);
7380 
7381   PrepareConfigureCodecHandler(group);
7382   PrepareConfigureQosHandler(group);
7383   PrepareEnableHandler(group);
7384   PrepareDisableHandler(group);
7385   PrepareReleaseHandler(group);
7386 
7387   auto* leAudioDevice = group->GetFirstDevice();
7388   LeAudioDevice* lastDevice;
7389   LeAudioDevice* fistDevice = leAudioDevice;
7390 
7391   auto expected_devices_written = 0;
7392   while (leAudioDevice) {
7393     /* Three Writes:
7394      * 1: Codec Config
7395      * 2: Codec QoS
7396      * 3: Enabling
7397      */
7398     lastDevice = leAudioDevice;
7399     EXPECT_CALL(gatt_queue,
7400                 WriteCharacteristic(leAudioDevice->conn_id_,
7401                                     leAudioDevice->ctp_hdls_.val_hdl, _,
7402                                     GATT_WRITE_NO_RSP, _, _))
7403         .Times(AtLeast(3));
7404     expected_devices_written++;
7405     leAudioDevice = group->GetNextDevice(leAudioDevice);
7406   }
7407   ASSERT_EQ(expected_devices_written, num_devices);
7408 
7409   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
7410   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
7411   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
7412 
7413   InjectInitialIdleNotification(group);
7414 
7415   // Start the configuration and stream Media content
7416   LeAudioGroupStateMachine::Get()->StartStream(
7417       group, context_type,
7418       {.sink = types::AudioContexts(context_type),
7419        .source = types::AudioContexts(context_type)});
7420 
7421   // Check if group has transitioned to a proper state
7422   ASSERT_EQ(group->GetState(),
7423             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7424   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
7425 
7426   // Inject CIS and ACL disconnection of first device
7427   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
7428   InjectAclDisconnected(group, lastDevice);
7429 
7430   // Check if group keeps streaming
7431   ASSERT_EQ(group->GetState(),
7432             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7433 
7434   lastDevice->conn_id_ = 3;
7435   lastDevice->SetConnectionState(DeviceConnectState::CONNECTED);
7436 
7437   // Make sure ASE with disconnected CIS are not left in STREAMING
7438   ASSERT_EQ(lastDevice->GetFirstAseWithState(
7439                 ::bluetooth::le_audio::types::kLeAudioDirectionSink,
7440                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
7441             nullptr);
7442   ASSERT_EQ(lastDevice->GetFirstAseWithState(
7443                 ::bluetooth::le_audio::types::kLeAudioDirectionSource,
7444                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
7445             nullptr);
7446 
7447   EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_,
7448                                               lastDevice->ctp_hdls_.val_hdl, _,
7449                                               GATT_WRITE_NO_RSP, _, _))
7450       .Times(AtLeast(3));
7451 
7452   do_not_send_cis_establish_event_ = true;
7453 
7454   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
7455   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
7456   LeAudioGroupStateMachine::Get()->AttachToStream(
7457       group, lastDevice, {.sink = {media_ccid}, .source = {}});
7458 
7459   // Check if group keeps streaming
7460   ASSERT_EQ(group->GetState(),
7461             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7462 
7463   // Verify that the joining device receives the right CCID list
7464   auto lastMeta = lastDevice->GetFirstActiveAse()->metadata;
7465   bool parsedOk = false;
7466   auto ltv = bluetooth::le_audio::types::LeAudioLtvMap::Parse(
7467       lastMeta.data(), lastMeta.size(), parsedOk);
7468   ASSERT_TRUE(parsedOk);
7469 
7470   auto ccids =
7471       ltv.Find(bluetooth::le_audio::types::kLeAudioMetadataTypeCcidList);
7472   ASSERT_TRUE(ccids.has_value());
7473   ASSERT_NE(std::find(ccids->begin(), ccids->end(), media_ccid), ccids->end());
7474 
7475   /* Verify that ASE of first device are still good*/
7476   auto ase = fistDevice->GetFirstActiveAse();
7477   ASSERT_NE(ase->qos_config.max_transport_latency, 0);
7478   ASSERT_NE(ase->qos_config.retrans_nb, 0);
7479 }
7480 
TEST_F(StateMachineTest,testAttachDeviceWhileSecondDeviceDisconnects)7481 TEST_F(StateMachineTest, testAttachDeviceWhileSecondDeviceDisconnects) {
7482   const auto context_type = kContextTypeMedia;
7483   const auto leaudio_group_id = 6;
7484   const auto num_devices = 2;
7485 
7486   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
7487 
7488   // Prepare multiple fake connected devices in a group
7489   auto* group =
7490       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
7491   ASSERT_EQ(group->Size(), num_devices);
7492 
7493   PrepareConfigureCodecHandler(group);
7494   PrepareConfigureQosHandler(group);
7495   PrepareEnableHandler(group);
7496   PrepareDisableHandler(group);
7497   PrepareReleaseHandler(group);
7498 
7499   auto* leAudioDevice = group->GetFirstDevice();
7500   LeAudioDevice* lastDevice;
7501   LeAudioDevice* firstDevice = leAudioDevice;
7502 
7503   auto expected_devices_written = 0;
7504   while (leAudioDevice) {
7505     /* Three Writes:
7506      * 1: Codec Config
7507      * 2: Codec QoS
7508      * 3: Enable
7509      */
7510     lastDevice = leAudioDevice;
7511     EXPECT_CALL(gatt_queue,
7512                 WriteCharacteristic(leAudioDevice->conn_id_,
7513                                     leAudioDevice->ctp_hdls_.val_hdl, _,
7514                                     GATT_WRITE_NO_RSP, _, _))
7515         .Times(AtLeast(3));
7516     expected_devices_written++;
7517     leAudioDevice = group->GetNextDevice(leAudioDevice);
7518   }
7519   ASSERT_EQ(expected_devices_written, num_devices);
7520 
7521   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
7522   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
7523   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
7524 
7525   InjectInitialIdleNotification(group);
7526 
7527   // Start the configuration and stream Media content
7528   LeAudioGroupStateMachine::Get()->StartStream(
7529       group, context_type,
7530       {.sink = types::AudioContexts(context_type),
7531        .source = types::AudioContexts(context_type)});
7532 
7533   // Check if group has transitioned to a proper state
7534   ASSERT_EQ(group->GetState(),
7535             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7536   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
7537 
7538   // Inject CIS and ACL disconnection of first device
7539   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
7540   InjectAclDisconnected(group, lastDevice);
7541 
7542   log::info(" Device B - Disconnected ");
7543 
7544   // Check if group keeps streaming
7545   ASSERT_EQ(group->GetState(),
7546             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7547 
7548   // Set second device is connected now.
7549   lastDevice->conn_id_ = 3;
7550   lastDevice->SetConnectionState(DeviceConnectState::CONNECTED);
7551 
7552   // Make sure ASE with disconnected CIS are not left in STREAMING
7553   ASSERT_EQ(lastDevice->GetFirstAseWithState(
7554                 ::bluetooth::le_audio::types::kLeAudioDirectionSink,
7555                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
7556             nullptr);
7557   ASSERT_EQ(lastDevice->GetFirstAseWithState(
7558                 ::bluetooth::le_audio::types::kLeAudioDirectionSource,
7559                 types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING),
7560             nullptr);
7561 
7562   // Expect just Codec Configure on ASCS Control Point
7563   EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_,
7564                                               lastDevice->ctp_hdls_.val_hdl, _,
7565                                               GATT_WRITE_NO_RSP, _, _))
7566       .Times(AtLeast(1));
7567 
7568   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0);
7569   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0);
7570 
7571   // Remove Configuration incjection but cache configuration for future
7572   // injection
7573   PrepareConfigureCodecHandler(group, 0, true, false);
7574 
7575   log::info("Device B - Attaching to the stream");
7576 
7577   LeAudioGroupStateMachine::Get()->AttachToStream(
7578       group, lastDevice, {.sink = {media_ccid}, .source = {}});
7579 
7580   // Check if group keeps streaming
7581   ASSERT_EQ(group->GetState(),
7582             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7583 
7584   /* Verify that ASE of first device are still good*/
7585   auto ase = firstDevice->GetFirstActiveAse();
7586   ASSERT_NE(ase->qos_config.max_transport_latency, 0);
7587   ASSERT_NE(ase->qos_config.retrans_nb, 0);
7588 
7589   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
7590   testing::Mock::VerifyAndClearExpectations(&gatt_queue);
7591 
7592   log::info(
7593       "Device A is disconnecting while Device B is attaching to the stream");
7594 
7595   InjectCisDisconnected(group, firstDevice, HCI_ERR_CONNECTION_TOUT);
7596   InjectReleasingAndIdleState(group, firstDevice);
7597 
7598   // Check if group keeps streaming
7599   ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE);
7600   ASSERT_EQ(group->GetTargetState(),
7601             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7602 
7603   ASSERT_EQ(group->cig.GetState(), types::CigState::CREATED);
7604 
7605   log::info("Device B continues configuration and streaming");
7606 
7607   // Expect QoS config and Enable on ASCS Control Point
7608   EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_,
7609                                               lastDevice->ctp_hdls_.val_hdl, _,
7610                                               GATT_WRITE_NO_RSP, _, _))
7611       .Times(AtLeast(2));
7612 
7613   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
7614   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1);
7615 
7616   InjectCachedConfiguratuibForActiveAses(group, lastDevice);
7617 
7618   // Check if group keeps streaming
7619   ASSERT_EQ(group->GetState(),
7620             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7621 
7622   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
7623   testing::Mock::VerifyAndClearExpectations(&gatt_queue);
7624 }
7625 
TEST_F(StateMachineTest,testAclDropWithoutApriorCisDisconnection)7626 TEST_F(StateMachineTest, testAclDropWithoutApriorCisDisconnection) {
7627   const auto context_type = kContextTypeMedia;
7628   const auto leaudio_group_id = 6;
7629   const auto num_devices = 2;
7630 
7631   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
7632 
7633   // Prepare multiple fake connected devices in a group
7634   auto* group =
7635       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
7636   ASSERT_EQ(group->Size(), num_devices);
7637 
7638   PrepareConfigureCodecHandler(group);
7639   PrepareConfigureQosHandler(group);
7640   PrepareEnableHandler(group);
7641   PrepareDisableHandler(group);
7642   PrepareReleaseHandler(group);
7643 
7644   auto* leAudioDevice = group->GetFirstDevice();
7645   LeAudioDevice* firstDevice = leAudioDevice;
7646   LeAudioDevice* lastDevice = leAudioDevice;
7647 
7648   auto expected_devices_written = 0;
7649   while (leAudioDevice) {
7650     /* Three Writes:
7651      * 1: Codec Config
7652      * 2: Codec QoS
7653      * 3: Enabling
7654      */
7655     lastDevice = leAudioDevice;
7656     EXPECT_CALL(gatt_queue,
7657                 WriteCharacteristic(leAudioDevice->conn_id_,
7658                                     leAudioDevice->ctp_hdls_.val_hdl, _,
7659                                     GATT_WRITE_NO_RSP, _, _))
7660         .Times(AtLeast(3));
7661     expected_devices_written++;
7662     leAudioDevice = group->GetNextDevice(leAudioDevice);
7663   }
7664   ASSERT_EQ(expected_devices_written, num_devices);
7665 
7666   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
7667   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
7668   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2);
7669 
7670   InjectInitialIdleNotification(group);
7671 
7672   // Start the configuration and stream Media content
7673   LeAudioGroupStateMachine::Get()->StartStream(
7674       group, context_type,
7675       {.sink = types::AudioContexts(context_type),
7676        .source = types::AudioContexts(context_type)});
7677 
7678   // Check if group has transitioned to a proper state
7679   ASSERT_EQ(group->GetState(),
7680             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7681   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
7682 
7683   /* Separate CIS  for dual CIS device is treated as sink device */
7684   ASSERT_EQ(group->stream_conf.stream_params.sink.num_of_devices, 2);
7685   ASSERT_EQ(group->stream_conf.stream_params.sink.num_of_channels, 2);
7686 
7687   // Inject CIS and ACL disconnection of first device
7688   InjectAclDisconnected(group, firstDevice);
7689 
7690   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONN_CAUSE_LOCAL_HOST);
7691   InjectAclDisconnected(group, lastDevice);
7692 
7693   ASSERT_EQ(group->stream_conf.stream_params.sink.num_of_devices, 0);
7694   ASSERT_EQ(group->stream_conf.stream_params.sink.num_of_channels, 0);
7695 }
7696 
TEST_F(StateMachineTest,testAutonomousDisableTimeout)7697 TEST_F(StateMachineTest, testAutonomousDisableTimeout) {
7698   const auto context_type = kContextTypeConversational;
7699   const auto leaudio_group_id = 6;
7700   const auto num_devices = 2;
7701 
7702   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
7703 
7704   // Prepare multiple fake connected devices in a group
7705   auto* group =
7706       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
7707   ASSERT_EQ(group->Size(), num_devices);
7708 
7709   PrepareConfigureCodecHandler(group);
7710   PrepareConfigureQosHandler(group);
7711   PrepareEnableHandler(group);
7712   PrepareDisableHandler(group);
7713   PrepareReleaseHandler(group);
7714   PrepareReceiverStartReadyHandler(group);
7715 
7716   auto* leAudioDevice = group->GetFirstDevice();
7717   LeAudioDevice* lastDevice;
7718   // LeAudioDevice* fistDevice = leAudioDevice;
7719 
7720   auto expected_devices_written = 0;
7721   while (leAudioDevice) {
7722     /* Three Writes:
7723      * 1: Codec Config
7724      * 2: Codec QoS
7725      * 3: Enabling
7726      */
7727     lastDevice = leAudioDevice;
7728     EXPECT_CALL(gatt_queue,
7729                 WriteCharacteristic(leAudioDevice->conn_id_,
7730                                     leAudioDevice->ctp_hdls_.val_hdl, _,
7731                                     GATT_WRITE_NO_RSP, _, _))
7732         .Times(AtLeast(3));
7733     expected_devices_written++;
7734     leAudioDevice = group->GetNextDevice(leAudioDevice);
7735   }
7736   ASSERT_EQ(expected_devices_written, num_devices);
7737 
7738   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
7739   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
7740   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(4);
7741 
7742   InjectInitialIdleNotification(group);
7743 
7744   // Start the configuration and stream Conversational content
7745   LeAudioGroupStateMachine::Get()->StartStream(
7746       group, context_type,
7747       {.sink = types::AudioContexts(context_type),
7748        .source = types::AudioContexts(context_type)});
7749 
7750   /* First timer started for transition to streaming state */
7751   ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
7752 
7753   // Check if group has transitioned to a proper state
7754   ASSERT_EQ(group->GetState(),
7755             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7756 
7757   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
7758 
7759   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(1);
7760 
7761   /* First timer finished when group achieves streaming state */
7762   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
7763 
7764   /* Remote initiates autonomous Disable operation */
7765   auto ase = lastDevice->GetFirstActiveAseByDirection(
7766       ::bluetooth::le_audio::types::kLeAudioDirectionSink);
7767 
7768   InjectAseStateNotification(ase, lastDevice, group,
7769                              ascs::kAseStateQoSConfigured,
7770                              &cached_qos_configuration_map_[ase->id]);
7771 
7772   /* Second timer started for autonomous transition to disabled state */
7773   ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
7774 
7775   // Inject CIS disconnection of first device
7776   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT);
7777 
7778   // Check if timeout is fired
7779   EXPECT_CALL(mock_callbacks_,
7780               OnDeviceAutonomousStateTransitionTimeout(lastDevice));
7781 
7782   fake_osi_alarm_set_on_mloop_.cb(fake_osi_alarm_set_on_mloop_.data);
7783   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
7784 }
7785 
TEST_F(StateMachineTest,testAutonomousDisableSuccess)7786 TEST_F(StateMachineTest, testAutonomousDisableSuccess) {
7787   const auto context_type = kContextTypeConversational;
7788   const auto leaudio_group_id = 6;
7789   const auto num_devices = 2;
7790 
7791   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
7792 
7793   // Prepare multiple fake connected devices in a group
7794   auto* group =
7795       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
7796   ASSERT_EQ(group->Size(), num_devices);
7797 
7798   PrepareConfigureCodecHandler(group);
7799   PrepareConfigureQosHandler(group);
7800   PrepareEnableHandler(group);
7801   PrepareDisableHandler(group);
7802   PrepareReleaseHandler(group);
7803   PrepareReceiverStartReadyHandler(group);
7804 
7805   auto* leAudioDevice = group->GetFirstDevice();
7806   LeAudioDevice* lastDevice;
7807 
7808   auto expected_devices_written = 0;
7809   while (leAudioDevice) {
7810     /* Three Writes:
7811      * 1: Codec Config
7812      * 2: Codec QoS
7813      * 3: Enabling
7814      */
7815     lastDevice = leAudioDevice;
7816     EXPECT_CALL(gatt_queue,
7817                 WriteCharacteristic(leAudioDevice->conn_id_,
7818                                     leAudioDevice->ctp_hdls_.val_hdl, _,
7819                                     GATT_WRITE_NO_RSP, _, _))
7820         .Times(AtLeast(3));
7821     expected_devices_written++;
7822     leAudioDevice = group->GetNextDevice(leAudioDevice);
7823   }
7824   ASSERT_EQ(expected_devices_written, num_devices);
7825 
7826   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
7827   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
7828   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(4);
7829 
7830   InjectInitialIdleNotification(group);
7831 
7832   // Start the configuration and stream Conversational content
7833   LeAudioGroupStateMachine::Get()->StartStream(
7834       group, context_type,
7835       {.sink = types::AudioContexts(context_type),
7836        .source = types::AudioContexts(context_type)});
7837 
7838   /* First timer started for transition to streaming state */
7839   ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
7840 
7841   // Check if group has transitioned to a proper state
7842   ASSERT_EQ(group->GetState(),
7843             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7844 
7845   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
7846 
7847   EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(1);
7848 
7849   /* Remote initiates autonomous Disable operation */
7850   auto ase_sink = lastDevice->GetFirstActiveAseByDirection(
7851       ::bluetooth::le_audio::types::kLeAudioDirectionSink);
7852 
7853   InjectAseStateNotification(ase_sink, lastDevice, group,
7854                              ascs::kAseStateQoSConfigured,
7855                              &cached_qos_configuration_map_[ase_sink->id]);
7856 
7857   /* Check if autonomous operation timer is not canceled */
7858   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
7859   /* Second timer started for autonomous transition to disabled state */
7860   ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
7861 
7862   auto ase_source = lastDevice->GetFirstActiveAseByDirection(
7863       ::bluetooth::le_audio::types::kLeAudioDirectionSource);
7864 
7865   client_parser::ascs::ase_transient_state_params disabling_params = {
7866       .metadata = {}};
7867   InjectAseStateNotification(ase_source, lastDevice, group,
7868                              ascs::kAseStateDisabling, &disabling_params);
7869   InjectAseStateNotification(ase_source, lastDevice, group,
7870                              ascs::kAseStateQoSConfigured,
7871                              &cached_qos_configuration_map_[ase_source->id]);
7872 
7873   /* Inject CIS disconnection of first device, disconenct only first CIS because
7874    * while processing first disconnection test will try to bring up this ASEs
7875    * to STREAMING state and connect CISes again.
7876    */
7877   InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT, true);
7878   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
7879 
7880   /* Check if autonomous operation timer is freed */
7881   ASSERT_EQ(1, get_func_call_count("alarm_free"));
7882 }
7883 
TEST_F(StateMachineTest,testAutonomousDisableCancelOnDisconnect)7884 TEST_F(StateMachineTest, testAutonomousDisableCancelOnDisconnect) {
7885   const auto context_type = kContextTypeConversational;
7886   const auto leaudio_group_id = 6;
7887   const auto num_devices = 2;
7888 
7889   ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid);
7890 
7891   // Prepare multiple fake connected devices in a group
7892   auto* group =
7893       PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices);
7894   ASSERT_EQ(group->Size(), num_devices);
7895 
7896   PrepareConfigureCodecHandler(group);
7897   PrepareConfigureQosHandler(group);
7898   PrepareEnableHandler(group);
7899   PrepareDisableHandler(group);
7900   PrepareReleaseHandler(group);
7901   PrepareReceiverStartReadyHandler(group);
7902 
7903   auto* leAudioDevice = group->GetFirstDevice();
7904   LeAudioDevice* lastDevice;
7905 
7906   auto expected_devices_written = 0;
7907   while (leAudioDevice) {
7908     /* Three Writes:
7909      * 1: Codec Config
7910      * 2: Codec QoS
7911      * 3: Enabling
7912      */
7913     lastDevice = leAudioDevice;
7914     EXPECT_CALL(gatt_queue,
7915                 WriteCharacteristic(leAudioDevice->conn_id_,
7916                                     leAudioDevice->ctp_hdls_.val_hdl, _,
7917                                     GATT_WRITE_NO_RSP, _, _))
7918         .Times(AtLeast(3));
7919     expected_devices_written++;
7920     leAudioDevice = group->GetNextDevice(leAudioDevice);
7921   }
7922   ASSERT_EQ(expected_devices_written, num_devices);
7923 
7924   EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1);
7925   EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1);
7926   EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(4);
7927 
7928   InjectInitialIdleNotification(group);
7929 
7930   // Start the configuration and stream Conversational content
7931   LeAudioGroupStateMachine::Get()->StartStream(
7932       group, context_type,
7933       {.sink = types::AudioContexts(context_type),
7934        .source = types::AudioContexts(context_type)});
7935 
7936   /* First timer started for transition to streaming state */
7937   ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
7938 
7939   // Check if group has transitioned to a proper state
7940   ASSERT_EQ(group->GetState(),
7941             types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
7942   testing::Mock::VerifyAndClearExpectations(mock_iso_manager_);
7943 
7944   /* First timer finished when group achieves streaming state */
7945   ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
7946 
7947   /* Remote initiates autonomous Disable operation */
7948   auto ase = lastDevice->GetFirstActiveAseByDirection(
7949       ::bluetooth::le_audio::types::kLeAudioDirectionSink);
7950 
7951   InjectAseStateNotification(ase, lastDevice, group,
7952                              ascs::kAseStateQoSConfigured,
7953                              &cached_qos_configuration_map_[ase->id]);
7954 
7955   /* Second timer started for autonomous transition to disabled state */
7956   ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
7957 
7958   // Inject ACL disconnection of first device
7959   InjectAclDisconnected(group, lastDevice);
7960 
7961   /* Check if autonomous operation timer is freed on ASEs deactivation */
7962   ASSERT_EQ(2, get_func_call_count("alarm_free"));
7963 }
7964 
7965 }  // namespace internal
7966 }  // namespace bluetooth::le_audio
7967